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

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

<Problem description>

```Example:
<example in lisp>

```

Solution:

```<solution in haskell>
```

<description of implementation>

## Problem 22

Create a list containing all integers within a given range.

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

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 surgar is implemented using the enumFromTo function, which is exactly what 'range' should be.

## Problem 23

<Problem description>

```Example:
<example in lisp>

```

Solution:

```<solution in haskell>
```

<description of implementation>

## Problem 24

<Problem description>

```Example:
<example in lisp>

```

Solution:

```<solution in haskell>
```

<description of implementation>

## Problem 25

<Problem description>

```Example:
<example in lisp>

```

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) ... )

> 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],,[]]
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>

```

Solution:

```<solution in haskell>
```

<description of implementation>

## Problem 28

<Problem description>

```Example:
<example in lisp>

```

Solution:

```<solution in haskell>
```

<description of implementation>

## Problem 29

<Problem description>

```Example:
<example in lisp>

```

Solution:

```<solution in haskell>
```

<description of implementation>

## Problem 30

<Problem description>

```Example:
<example in lisp>

```<solution in haskell>