Difference between revisions of "99 questions/90 to 94"

From HaskellWiki
Jump to navigation Jump to search
m
(→‎Problem 94: added haskell example)
(58 intermediate revisions by 7 users not shown)
Line 1: Line 1:
 
__NOTOC__
 
__NOTOC__
   
  +
This is part of [[H-99:_Ninety-Nine_Haskell_Problems|Ninety-Nine Haskell Problems]], based on [https://prof.ti.bfh.ch/hew1/informatik3/prolog/p-99/ Ninety-Nine Prolog Problems].
These are Haskell translations of [http://www.ic.unicamp.br/~meidanis/courses/mc336/2006s2/funcional/L-99_Ninety-Nine_Lisp_Problems.html Ninety Nine Lisp Problems].
 
   
If you want to work on one of these, put your name in the block so we know someone's working on it. Then, change n in your block to the appropriate problem number, and fill in the <Problem description>,<example in lisp>,<example in Haskell>,<solution in haskell> and <description of implementation> fields.
+
If you want to work on one of these, put your name in the block so we know someone's working on it. Then, change n in your block to the appropriate problem number, and fill in the <Problem description>,<example in Haskell>,<solution in haskell> and <description of implementation> fields.
   
 
== Miscellaneous problems ==
 
== Miscellaneous problems ==
Line 9: Line 9:
 
== Problem 90 ==
 
== Problem 90 ==
   
Eight queens problem
+
(**) Eight queens problem
   
 
This is a classical problem in computer science. The objective is to place eight queens on a chessboard so that no two queens are attacking each other; i.e., no two queens are in the same row, the same column, or on the same diagonal.
 
This is a classical problem in computer science. The objective is to place eight queens on a chessboard so that no two queens are attacking each other; i.e., no two queens are in the same row, the same column, or on the same diagonal.
Line 15: Line 15:
 
Hint: Represent the positions of the queens as a list of numbers 1..N. Example: [4,2,7,3,6,8,5,1] means that the queen in the first column is in row 4, the queen in the second column is in row 2, etc. Use the generate-and-test paradigm.
 
Hint: Represent the positions of the queens as a list of numbers 1..N. Example: [4,2,7,3,6,8,5,1] means that the queen in the first column is in row 4, the queen in the second column is in row 2, etc. Use the generate-and-test paradigm.
   
<pre>
 
 
Example in Haskell:
 
Example in Haskell:
> length queens
 
92
 
> take 1 queens
 
[[3,1,6,2,5,7,4,0]]
 
</pre>
 
   
Solution:
 
 
<haskell>
 
<haskell>
queens = queens' 8
+
> length (queens 8)
  +
92
  +
> head (queens 8)
  +
[1,5,8,6,3,7,2,4]
  +
</haskell>
   
  +
[[99 questions/Solutions/90 | Solutions]]
queens' 0 = [[]]
 
queens' (n+1) = [ try:alreadySet | alreadySet <- queens' n, try <- [1..8], isSafe try alreadySet ]
 
where isSafe try alreadySet = not . any (threatens try alreadySet) $ [1..n]
 
threatens try alreadySet col = let diff = try - alreadySet!!(col-1) in (diff == 0) || (diff == col)
 
</haskell>
 
   
By definition/data representation no two queens can occupy the same column. "diff == 0" checks for a queen in the same row, "abs(diff) == col" checks for a queen in the same diagonal.
 
   
This is a modification of a function I wrote when I was just learning haskell, so there's certainly much to improve here! For one thing there is speedup potential in caching "blocked" rows, columns and diagonals.
 
 
 
== Problem 91 ==
 
== Problem 91 ==
   
  +
(**) Knight's tour
<Problem description>
 
   
  +
Another famous problem is this one: How can a knight jump on an NxN chessboard in such a way that it visits every square exactly once? A set of solutions is given on the [[The_Knights_Tour]] page.
<pre>
 
Example:
 
<example in lisp>
 
   
  +
Hints: Represent the squares by pairs of their coordinates of the form X/Y, where both X and Y are integers between 1 and N. (Note that '/' is just a convenient functor, not division!) Define the relation jump(N,X/Y,U/V) to express the fact that a knight can jump from X/Y to U/V on a NxN chessboard. And finally, represent the solution of our problem as a list of N*N knight positions (the knight's tour).
Example in Haskell:
 
<example in Haskell>
 
</pre>
 
   
  +
There are two variants of this problem:
Solution:
 
  +
# find a tour ending at a particular square
<haskell>
 
  +
# find a circular tour, ending a knight's jump from the start (clearly it doesn't matter where you start, so choose (1,1))
<solution in haskell>
 
</haskell>
 
 
<description of implementation>
 
 
== Problem 92 ==
 
 
<Problem description>
 
 
<pre>
 
Example:
 
<example in lisp>
 
   
 
Example in Haskell:
 
Example in Haskell:
<example in Haskell>
 
</pre>
 
   
Solution:
 
 
<haskell>
 
<haskell>
  +
Knights> head $ knightsTo 8 (1,1)
<solution in haskell>
 
  +
[(2,7),(3,5),(5,6),(4,8),(3,6),(4,4),(6,5),(4,6),
  +
(5,4),(7,5),(6,3),(5,5),(4,3),(2,4),(1,6),(2,8),
  +
(4,7),(6,8),(8,7),(6,6),(4,5),(6,4),(5,2),(7,1),
  +
(8,3),(6,2),(8,1),(7,3),(8,5),(7,7),(5,8),(3,7),
  +
(1,8),(2,6),(3,4),(1,5),(2,3),(3,1),(1,2),(3,3),
  +
(1,4),(2,2),(4,1),(5,3),(7,4),(8,2),(6,1),(4,2),
  +
(2,1),(1,3),(2,5),(1,7),(3,8),(5,7),(7,8),(8,6),
  +
(6,7),(8,8),(7,6),(8,4),(7,2),(5,1),(3,2),(1,1)]
  +
Knights> head $ closedKnights 8
  +
[(1,1),(3,2),(1,3),(2,1),(3,3),(5,4),(6,6),(4,5),
  +
(2,6),(1,8),(3,7),(5,8),(4,6),(2,5),(4,4),(5,6),
  +
(6,4),(8,5),(7,7),(6,5),(5,3),(6,1),(4,2),(6,3),
  +
(8,2),(7,4),(5,5),(3,4),(1,5),(2,7),(4,8),(3,6),
  +
(1,7),(3,8),(5,7),(7,8),(8,6),(6,7),(8,8),(7,6),
  +
(8,4),(7,2),(5,1),(4,3),(3,5),(1,4),(2,2),(4,1),
  +
(6,2),(8,1),(7,3),(5,2),(7,1),(8,3),(7,5),(8,7),
  +
(6,8),(4,7),(2,8),(1,6),(2,4),(1,2),(3,1),(2,3)]
 
</haskell>
 
</haskell>
   
  +
[[99 questions/Solutions/91 | Solutions]]
<description of implementation>
 
 
== Problem 93 ==
 
   
<Problem description>
 
   
  +
== Problem 92 ==
<pre>
 
Example:
 
<example in lisp>
 
   
  +
(***) Von Koch's conjecture
Example in Haskell:
 
<example in Haskell>
 
</pre>
 
   
  +
Several years ago I met a mathematician who was intrigued by a problem for which he didn't know a solution. His name was Von Koch, and I don't know whether the problem has been solved since.
Solution:
 
<haskell>
 
<solution in haskell>
 
</haskell>
 
   
  +
https://prof.ti.bfh.ch/hew1/informatik3/prolog/p-99/p92a.gif
<description of implementation>
 
 
== Problem 94 ==
 
   
  +
Anyway the puzzle goes like this: Given a tree with N nodes (and hence N-1 edges). Find a way to enumerate the nodes from 1 to N and, accordingly, the edges from 1 to N-1 in such a way, that for each edge K the difference of its node numbers equals to K. The conjecture is that this is always possible.
<Problem description>
 
   
  +
For small trees the problem is easy to solve by hand. However, for larger trees, and 14 is already very large, it is extremely difficult to find a solution. And remember, we don't know for sure whether there is always a solution!
<pre>
 
Example:
 
<example in lisp>
 
   
  +
Write a predicate that calculates a numbering scheme for a given tree. What is the solution for the larger tree pictured below?
Example in Haskell:
 
<example in Haskell>
 
</pre>
 
   
  +
https://prof.ti.bfh.ch/hew1/informatik3/prolog/p-99/p92b.gif
Solution:
 
<haskell>
 
<solution in haskell>
 
</haskell>
 
 
<description of implementation>
 
 
== Problem 95 ==
 
 
<Problem description>
 
 
<pre>
 
Example:
 
<example in lisp>
 
   
 
Example in Haskell:
 
Example in Haskell:
<example in Haskell>
 
</pre>
 
   
Solution:
 
 
<haskell>
 
<haskell>
  +
> head $ vonKoch [(1,6),(2,6),(3,6),(4,6),(5,6),(5,7),(5,8),(8,9),(5,10),(10,11),(11,12),(11,13),(13,14)]
<solution in haskell>
 
  +
[6,7,8,9,3,4,10,11,5,12,2,13,14,1]
 
</haskell>
 
</haskell>
   
  +
[[99 questions/Solutions/92 | Solutions]]
<description of implementation>
 
  +
 
 
== Problem 96 ==
+
== Problem 93 ==
   
  +
(***) An arithmetic puzzle
<Problem description>
 
   
  +
Given a list of integer numbers, find a correct way of inserting arithmetic signs (operators) such that the result is a correct equation. Example: With the list of numbers [2,3,5,7,11] we can form the equations 2-3+5+7 = 11 or 2 = (3*5+7)/11 (and ten others!).
<pre>
 
  +
Example:
 
  +
Division should be interpreted as operating on rationals, and division by zero should be avoided.
<example in lisp>
 
   
 
Example in Haskell:
 
Example in Haskell:
<example in Haskell>
 
</pre>
 
   
Solution:
 
 
<haskell>
 
<haskell>
  +
P93> mapM_ putStrLn $ puzzle [2,3,5,7,11]
<solution in haskell>
 
  +
2 = 3-(5+7-11)
  +
2 = 3-5-(7-11)
  +
2 = 3-(5+7)+11
  +
2 = 3-5-7+11
  +
2 = (3*5+7)/11
  +
2*(3-5) = 7-11
  +
2-(3-(5+7)) = 11
  +
2-(3-5-7) = 11
  +
2-(3-5)+7 = 11
  +
2-3+5+7 = 11
 
</haskell>
 
</haskell>
   
  +
The other two solutions alluded to in the problem description are dropped by the Haskell solution as trivial variants:
<description of implementation>
 
 
== Problem 97 ==
 
 
<Problem description>
 
   
 
<pre>
 
<pre>
  +
2 = 3-(5+(7-11))
Example:
 
  +
2-3+(5+7) = 11
<example in lisp>
 
 
Example in Haskell:
 
<example in Haskell>
 
 
</pre>
 
</pre>
   
  +
[[99 questions/Solutions/93 | Solutions]]
Solution:
 
<haskell>
 
<solution in haskell>
 
</haskell>
 
   
<description of implementation>
 
 
== Problem 98 ==
 
   
<Problem description>
+
== Problem 94 ==
   
  +
(***) Generate K-regular simple graphs with N nodes
<pre>
 
Example:
 
<example in lisp>
 
   
  +
In a K-regular graph all nodes have a degree of K; i.e. the number of edges incident in each node is K. How many (non-isomorphic!) 3-regular graphs with 6 nodes are there?
Example in Haskell:
 
<example in Haskell>
 
</pre>
 
   
  +
[https://prof.ti.bfh.ch/hew1/informatik3/prolog/p-99/p94.txt Sample results]
Solution:
 
<haskell>
 
<solution in haskell>
 
</haskell>
 
 
<description of implementation>
 
 
== Problem 99 ==
 
 
<Problem description>
 
 
<pre>
 
Example:
 
<example in lisp>
 
   
 
Example in Haskell:
 
Example in Haskell:
<example in Haskell>
 
</pre>
 
 
Solution:
 
 
<haskell>
 
<haskell>
  +
length $ regular 6 3
<solution in haskell>
 
  +
2
 
</haskell>
 
</haskell>
   
  +
[[99 questions/Solutions/94 | Solutions]]
<description of implementation>
 
 
   
 
[[Category:Tutorials]]
 
[[Category:Tutorials]]

Revision as of 20:38, 22 November 2013


This is part of Ninety-Nine Haskell Problems, based on Ninety-Nine Prolog Problems.

If you want to work on one of these, put your name in the block so we know someone's working on it. Then, change n in your block to the appropriate problem number, and fill in the <Problem description>,<example in Haskell>,<solution in haskell> and <description of implementation> fields.

Miscellaneous problems

Problem 90

(**) Eight queens problem

This is a classical problem in computer science. The objective is to place eight queens on a chessboard so that no two queens are attacking each other; i.e., no two queens are in the same row, the same column, or on the same diagonal.

Hint: Represent the positions of the queens as a list of numbers 1..N. Example: [4,2,7,3,6,8,5,1] means that the queen in the first column is in row 4, the queen in the second column is in row 2, etc. Use the generate-and-test paradigm.

Example in Haskell:

> length (queens 8)
92
> head (queens 8)
[1,5,8,6,3,7,2,4]

Solutions


Problem 91

(**) Knight's tour

Another famous problem is this one: How can a knight jump on an NxN chessboard in such a way that it visits every square exactly once? A set of solutions is given on the The_Knights_Tour page.

Hints: Represent the squares by pairs of their coordinates of the form X/Y, where both X and Y are integers between 1 and N. (Note that '/' is just a convenient functor, not division!) Define the relation jump(N,X/Y,U/V) to express the fact that a knight can jump from X/Y to U/V on a NxN chessboard. And finally, represent the solution of our problem as a list of N*N knight positions (the knight's tour).

There are two variants of this problem:

  1. find a tour ending at a particular square
  2. find a circular tour, ending a knight's jump from the start (clearly it doesn't matter where you start, so choose (1,1))

Example in Haskell:

Knights> head $ knightsTo 8 (1,1)
[(2,7),(3,5),(5,6),(4,8),(3,6),(4,4),(6,5),(4,6),
(5,4),(7,5),(6,3),(5,5),(4,3),(2,4),(1,6),(2,8),
(4,7),(6,8),(8,7),(6,6),(4,5),(6,4),(5,2),(7,1),
(8,3),(6,2),(8,1),(7,3),(8,5),(7,7),(5,8),(3,7),
(1,8),(2,6),(3,4),(1,5),(2,3),(3,1),(1,2),(3,3),
(1,4),(2,2),(4,1),(5,3),(7,4),(8,2),(6,1),(4,2),
(2,1),(1,3),(2,5),(1,7),(3,8),(5,7),(7,8),(8,6),
(6,7),(8,8),(7,6),(8,4),(7,2),(5,1),(3,2),(1,1)]
Knights> head $ closedKnights 8  
[(1,1),(3,2),(1,3),(2,1),(3,3),(5,4),(6,6),(4,5),
(2,6),(1,8),(3,7),(5,8),(4,6),(2,5),(4,4),(5,6),
(6,4),(8,5),(7,7),(6,5),(5,3),(6,1),(4,2),(6,3),
(8,2),(7,4),(5,5),(3,4),(1,5),(2,7),(4,8),(3,6),
(1,7),(3,8),(5,7),(7,8),(8,6),(6,7),(8,8),(7,6),
(8,4),(7,2),(5,1),(4,3),(3,5),(1,4),(2,2),(4,1),
(6,2),(8,1),(7,3),(5,2),(7,1),(8,3),(7,5),(8,7),
(6,8),(4,7),(2,8),(1,6),(2,4),(1,2),(3,1),(2,3)]

Solutions


Problem 92

(***) Von Koch's conjecture

Several years ago I met a mathematician who was intrigued by a problem for which he didn't know a solution. His name was Von Koch, and I don't know whether the problem has been solved since.

p92a.gif

Anyway the puzzle goes like this: Given a tree with N nodes (and hence N-1 edges). Find a way to enumerate the nodes from 1 to N and, accordingly, the edges from 1 to N-1 in such a way, that for each edge K the difference of its node numbers equals to K. The conjecture is that this is always possible.

For small trees the problem is easy to solve by hand. However, for larger trees, and 14 is already very large, it is extremely difficult to find a solution. And remember, we don't know for sure whether there is always a solution!

Write a predicate that calculates a numbering scheme for a given tree. What is the solution for the larger tree pictured below?

p92b.gif

Example in Haskell:

> head $ vonKoch [(1,6),(2,6),(3,6),(4,6),(5,6),(5,7),(5,8),(8,9),(5,10),(10,11),(11,12),(11,13),(13,14)]
[6,7,8,9,3,4,10,11,5,12,2,13,14,1]

Solutions


Problem 93

(***) An arithmetic puzzle

Given a list of integer numbers, find a correct way of inserting arithmetic signs (operators) such that the result is a correct equation. Example: With the list of numbers [2,3,5,7,11] we can form the equations 2-3+5+7 = 11 or 2 = (3*5+7)/11 (and ten others!).

Division should be interpreted as operating on rationals, and division by zero should be avoided.

Example in Haskell:

P93> mapM_ putStrLn $ puzzle [2,3,5,7,11]
2 = 3-(5+7-11)
2 = 3-5-(7-11)
2 = 3-(5+7)+11
2 = 3-5-7+11
2 = (3*5+7)/11
2*(3-5) = 7-11
2-(3-(5+7)) = 11
2-(3-5-7) = 11
2-(3-5)+7 = 11
2-3+5+7 = 11

The other two solutions alluded to in the problem description are dropped by the Haskell solution as trivial variants:

2 = 3-(5+(7-11))
2-3+(5+7) = 11

Solutions


Problem 94

(***) Generate K-regular simple graphs with N nodes

In a K-regular graph all nodes have a degree of K; i.e. the number of edges incident in each node is K. How many (non-isomorphic!) 3-regular graphs with 6 nodes are there?

Sample results

Example in Haskell:

length $ regular 6 3
2

Solutions