Difference between revisions of "99 questions/21 to 28"

From HaskellWiki
Jump to navigation Jump to search
(Remark about enumFromTo)
(P21 solved.)
Line 8: Line 8:
 
== Problem 21 ==
 
== Problem 21 ==
   
  +
Insert an element at a given position into a list.
<Problem description>
 
   
 
<pre>
 
<pre>
 
Example:
 
Example:
  +
* (insert-at 'alfa '(a b c d) 2)
<example in lisp>
 
  +
(A ALFA B C D)
 
 
Example in Haskell:
 
Example in Haskell:
  +
P21> insertAt 'X' "abcd" 2
<example in Haskell>
 
  +
"aXbcd"
 
</pre>
 
</pre>
   
 
Solution:
 
Solution:
 
<haskell>
 
<haskell>
  +
insertAt :: a -> [a] -> Int -> [a]
<solution in haskell>
 
  +
insertAt x xs (n+1) = let (ys,zs) = split xs n in ys++x:zs
 
</haskell>
  +
or
  +
<haskell>
  +
insertAt :: a -> [a] -> Int -> [a]
  +
insertAt x ys 1 = x:ys
  +
insertAt x (y:ys) n = y:insertAt x ys (n-1)
 
</haskell>
 
</haskell>
   
  +
There are two possible simple solutions. First we can use <hask>split</hask> from problem 17 (or even <hask>splitAt</hask> from the Prelude) to split the list and insert the element. Second we can define a recursive solution on our own.
<description of implementation>
 
 
 
 
== Problem 22 ==
 
== Problem 22 ==
Line 31: Line 39:
 
<pre>
 
<pre>
 
Example:
 
Example:
  +
* (range 4 9)
Example:
 
* (range 4 9)
+
(4 5 6 7 8 9)
(4 5 6 7 8 9)
 
   
 
Example in Haskell:
 
Example in Haskell:
Line 46: Line 53:
 
</haskell>
 
</haskell>
   
Since there's already syntactic sugar for ranges, there's usually no reason to define a function like 'range' in Haskell. In fact, the syntactic surgar is implemented using the enumFromTo function, which is exactly what 'range' should be.
+
Since there's already syntactic sugar for ranges, there's usually no reason to define a function like 'range' in Haskell. In fact, the syntactic sugar is implemented using the enumFromTo function, which is exactly what 'range' should be.
 
 
 
== Problem 23 ==
 
== Problem 23 ==

Revision as of 13:13, 12 December 2006


These are Haskell translations of 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.


Problem 21

Insert an element at a given position into a list.

Example:
* (insert-at 'alfa '(a b c d) 2)
(A ALFA B C D)
Example in Haskell:
P21> insertAt 'X' "abcd" 2
"aXbcd"

Solution:

insertAt :: a -> [a] -> Int -> [a]
insertAt x xs (n+1) = let (ys,zs) = split xs n in ys++x:zs

or

insertAt :: a -> [a] -> Int -> [a]
insertAt x ys     1 = x:ys
insertAt x (y:ys) n = y:insertAt x ys (n-1)

There are two possible simple solutions. First we can use split from problem 17 (or even splitAt from the Prelude) to split the list and insert the element. Second we can define a recursive solution on our own.

Problem 22

Create a list containing all integers within a given range.

Example:
* (range 4 9)
(4 5 6 7 8 9)

Example in Haskell:
Prelude> [4..9]
[4,5,6,7,8,9]

Solution:

range x y = [x..y]
range = enumFromTo

Since there's already syntactic sugar for ranges, there's usually no reason to define a function like 'range' in Haskell. In fact, the syntactic sugar is implemented using the enumFromTo function, which is exactly what 'range' should be.

Problem 23

<Problem description>

Example:
<example in lisp>

Example in Haskell:
<example in Haskell>

Solution:

<solution in haskell>

<description of implementation>

Problem 24

<Problem description>

Example:
<example in lisp>

Example in Haskell:
<example in Haskell>

Solution:

<solution in haskell>

<description of implementation>

Problem 25

<Problem description>

Example:
<example in lisp>

Example in Haskell:
<example in Haskell>

Solution:

<solution in haskell>

<description of implementation>

Problem 26

(**) Generate the combinations of K distinct objects chosen from the N elements of a list In how many ways can a committee of 3 be chosen from a group of 12 people? We all know that there are C(12,3) = 220 possibilities (C(N,K) denotes the well-known binomial coefficients). For pure mathematicians, this result may be great. But we want to really generate all the possibilities in a list.

Example:
* (combinations 3 '(a b c d e f))
((A B C) (A B D) (A B E) ... )

Example in Haskell:
> combinations 3 "abcdef"
["abc","abd","abe",...]

Solution:

-- Import the 'tails' function
--   > tails [0,1,2,3]
--   [[0,1,2,3],[1,2,3],[2,3],[3],[]]
import Data.List (tails)

-- The implementation first checks if there's no more elements to select,
-- if so, there's only one possible combination, the empty one,
-- otherwise we need to select 'n' elements. Since we don't want to
-- select an element twice, and we want to select elements in order, to
-- avoid combinations which only differ in ordering, we skip some
-- unspecified initial elements with 'tails', and select the next element,
-- also recursively selecting the next 'n-1' element from the rest of the
-- tail, finally consing them together

-- Using list comprehensions
combinations :: Int -> [a] -> [[a]]
combinations 0 _  = [ [] ]
combinations n xs = [ y:ys | y:xs' <- tails xs
                           , ys <- combinations (n-1) xs']

-- Alternate syntax, using 'do'-notation 
combinations :: Int -> [a] -> [[a]]
combinations 0 _  = do return []
combinations n xs = do y:xs' <- tails xs
                       ys <- combinations (n-1) xs'
                       return (y:ys)

Problem 27

<Problem description>

Example:
<example in lisp>

Example in Haskell:
<example in Haskell>

Solution:

<solution in haskell>

<description of implementation>

Problem 28

<Problem description>

Example:
<example in lisp>

Example in Haskell:
<example in Haskell>

Solution:

<solution in haskell>

<description of implementation>

Problem 29

<Problem description>

Example:
<example in lisp>

Example in Haskell:
<example in Haskell>

Solution:

<solution in haskell>

<description of implementation>

Problem 30

<Problem description>

Example:
<example in lisp>

Example in Haskell:
<example in Haskell>

Solution:

<solution in haskell>

<description of implementation>