# Difference between revisions of "99 questions/31 to 41"

m (unify ghci prompts) |
|||

(40 intermediate revisions by 15 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. |
||

− | |||

− | |||

== Problem 31 == |
== Problem 31 == |
||

− | Determine whether a given integer number is prime. |
+ | (**) Determine whether a given integer number is prime. |

− | <pre> |
||

Example: |
Example: |
||

+ | |||

+ | <pre> |
||

* (is-prime 7) |
* (is-prime 7) |
||

T |
T |
||

+ | </pre> |
||

Example in Haskell: |
Example in Haskell: |
||

− | P31> isPrime 7 |
||

− | True |
||

− | </pre> |
||

− | Solution: |
||

<haskell> |
<haskell> |
||

+ | λ> isPrime 7 |
||

− | isPrime :: Integral a => a -> Bool |
||

+ | True |
||

− | isPrime p = all (\n -> p `mod` n /= 0 ) $ takeWhile (\n -> n*n <= x) [2..] |
||

</haskell> |
</haskell> |
||

+ | [[99 questions/Solutions/31 | Solutions]] |
||

− | Well, a natural number p is a prime number iff no natural number n with n >= 2 and n^2 <= p is a divisor of p. That's exactly what is implemented: we take the list of all integral numbers starting with 2 as long as their square is at most p and check that for all these n there is a remainder concerning the division of p by n. |
||

+ | |||

== Problem 32 == |
== Problem 32 == |
||

− | (**) Determine the greatest common divisor of two positive integer numbers. |
+ | (**) Determine the greatest common divisor of two positive integer numbers. Use [http://en.wikipedia.org/wiki/Euclidean_algorithm Euclid's algorithm]. |

− | Use Euclid's algorithm. |
||

− | <pre> |
||

Example: |
Example: |
||

+ | |||

+ | <pre> |
||

* (gcd 36 63) |
* (gcd 36 63) |
||

9 |
9 |
||

+ | </pre> |
||

Example in Haskell: |
Example in Haskell: |
||

− | [myGCD 36 63, myGCD (-3) (-6), myGCD (-3) 6] |
||

− | [9,3,3] |
||

− | </pre> |
||

− | Solution: |
||

<haskell> |
<haskell> |
||

+ | λ> [myGCD 36 63, myGCD (-3) (-6), myGCD (-3) 6] |
||

− | gcd' 0 y = y |
||

+ | [9,3,3] |
||

− | gcd' x y = gcd' (y `mod` x) x |
||

− | myGCD x y | x < 0 = myGCD (-x) y |
||

− | | y < 0 = myGCD x (-y) |
||

− | | y < x = gcd' y x |
||

− | | otherwise = gcd' x y |
||

</haskell> |
</haskell> |
||

+ | [[99 questions/Solutions/32 | Solutions]] |
||

− | The Prelude includes a gcd function, so we have to choose another name for ours. The function gcd' is a straightforward implementation of Euler's algorithm, and myGCD is just a wrapper that makes sure the arguments are positive and in increasing order. |
||

== Problem 33 == |
== Problem 33 == |
||

− | (*) Determine whether two positive integer numbers are coprime. |
+ | (*) Determine whether two positive integer numbers are coprime. Two numbers are coprime if their greatest common divisor equals 1. |

− | Two numbers are coprime if their greatest common divisor equals 1. |
||

− | |||

Example: |
Example: |
||

+ | |||

<pre> |
<pre> |
||

* (coprime 35 64) |
* (coprime 35 64) |
||

Line 68: | Line 56: | ||

Example in Haskell: |
Example in Haskell: |
||

− | <pre> |
||

− | * coprime 35 64 |
||

− | True |
||

− | </pre> |
||

− | Solution: |
||

<haskell> |
<haskell> |
||

− | coprime |
+ | λ> coprime 35 64 |

+ | True |
||

</haskell> |
</haskell> |
||

+ | [[99 questions/Solutions/33 | Solutions]] |
||

− | Here we use the prelude function for computing gcd's along with a test of the results equality to one. It's written in point-free style, though maybe it would be a little more readable using formal parameters. |
||

+ | |||

== Problem 34 == |
== Problem 34 == |
||

+ | (**) Calculate Euler's totient function phi(m). |
||

− | <Problem description> |
||

+ | |||

+ | Euler's so-called totient function phi(m) is defined as the number of positive integers r (1 <= r < m) that are coprime to m. |
||

+ | |||

+ | Example: m = 10: r = 1,3,7,9; thus phi(m) = 4. Note the special case: phi(1) = 1. |
||

− | <pre> |
||

Example: |
Example: |
||

− | <example in lisp> |
||

+ | <pre> |
||

− | Example in Haskell: |
||

+ | * (totient-phi 10) |
||

− | <example in Haskell> |
||

+ | 4 |
||

</pre> |
</pre> |
||

+ | Example in Haskell: |
||

− | Solution: |
||

+ | |||

<haskell> |
<haskell> |
||

+ | λ> totient 10 |
||

− | <solution in haskell> |
||

+ | 4 |
||

</haskell> |
</haskell> |
||

+ | [[99 questions/Solutions/34 | Solutions]] |
||

− | <description of implementation> |
||

+ | |||

− | |||

+ | |||

== Problem 35 == |
== Problem 35 == |
||

+ | (**) Determine the prime factors of a given positive integer. Construct a flat list containing the prime factors in ascending order. |
||

− | <Problem description> |
||

− | <pre> |
||

Example: |
Example: |
||

− | <example in lisp> |
||

+ | <pre> |
||

− | Example in Haskell: |
||

+ | * (prime-factors 315) |
||

− | <example in Haskell> |
||

+ | (3 3 5 7) |
||

</pre> |
</pre> |
||

+ | Example in Haskell: |
||

− | Solution: |
||

+ | |||

<haskell> |
<haskell> |
||

+ | λ> primeFactors 315 |
||

− | <solution in haskell> |
||

+ | [3, 3, 5, 7] |
||

</haskell> |
</haskell> |
||

+ | [[99 questions/Solutions/35 | Solutions]] |
||

− | <description of implementation> |
||

+ | |||

== Problem 36 == |
== Problem 36 == |
||

+ | (**) Determine the prime factors of a given positive integer. |
||

− | <Problem description> |
||

+ | |||

+ | Construct a list containing the prime factors and their multiplicity. |
||

− | <pre> |
||

Example: |
Example: |
||

− | <example in lisp> |
||

+ | <pre> |
||

− | Example in Haskell: |
||

+ | * (prime-factors-mult 315) |
||

− | <example in Haskell> |
||

+ | ((3 2) (5 1) (7 1)) |
||

</pre> |
</pre> |
||

+ | Example in Haskell: |
||

− | Solution: |
||

+ | |||

<haskell> |
<haskell> |
||

+ | λ> prime_factors_mult 315 |
||

− | <solution in haskell> |
||

+ | [(3,2),(5,1),(7,1)] |
||

</haskell> |
</haskell> |
||

+ | [[99 questions/Solutions/36 | Solutions]] |
||

− | <description of implementation> |
||

+ | |||

== Problem 37 == |
== Problem 37 == |
||

+ | (**) Calculate Euler's totient function phi(m) (improved). |
||

− | <Problem description> |
||

+ | |||

+ | See problem 34 for the definition of Euler's totient function. If the list of the prime factors of a number m is known in the form of problem 36 then the function phi(m) can be efficiently calculated as follows: Let ((p1 m1) (p2 m2) (p3 m3) ...) be the list of prime factors (and their multiplicities) of a given number m. Then phi(m) can be calculated with the following formula: |
||

<pre> |
<pre> |
||

+ | phi(m) = (p1 - 1) * p1 ** (m1 - 1) * |
||

− | Example: |
||

+ | (p2 - 1) * p2 ** (m2 - 1) * |
||

− | <example in lisp> |
||

+ | (p3 - 1) * p3 ** (m3 - 1) * ... |
||

− | |||

− | Example in Haskell: |
||

− | <example in Haskell> |
||

</pre> |
</pre> |
||

+ | Note that a ** b stands for the b'th power of a. |
||

− | Solution: |
||

+ | |||

− | <haskell> |
||

+ | [[99 questions/Solutions/37 | Solutions]] |
||

− | <solution in haskell> |
||

− | </haskell> |
||

− | <description of implementation> |
||

− | |||

== Problem 38 == |
== Problem 38 == |
||

+ | (*) Compare the two methods of calculating Euler's totient function. |
||

− | <Problem description> |
||

+ | Use the solutions of problems 34 and 37 to compare the algorithms. Take the number of reductions as a measure for efficiency. Try to calculate phi(10090) as an example. |
||

− | <pre> |
||

− | Example: |
||

− | <example in lisp> |
||

+ | (no solution required) |
||

− | Example in Haskell: |
||

− | <example in Haskell> |
||

− | </pre> |
||

− | Solution: |
||

− | <haskell> |
||

− | <solution in haskell> |
||

− | </haskell> |
||

− | |||

− | <description of implementation> |
||

== Problem 39 == |
== Problem 39 == |
||

− | A list of prime numbers. |
+ | (*) A list of prime numbers. |

Given a range of integers by its lower and upper limit, construct a list of all prime numbers in that range. |
Given a range of integers by its lower and upper limit, construct a list of all prime numbers in that range. |
||

− | <pre> |
||

Example in Haskell: |
Example in Haskell: |
||

+ | |||

− | P29> primesR 10 20 |
||

+ | <haskell> |
||

+ | λ> primesR 10 20 |
||

[11,13,17,19] |
[11,13,17,19] |
||

+ | </haskell> |
||

+ | |||

+ | [[99 questions/Solutions/39 | Solutions]] |
||

+ | |||

+ | |||

+ | == Problem 40 == |
||

+ | |||

+ | (**) Goldbach's conjecture. |
||

+ | |||

+ | Goldbach's conjecture says that every positive even number greater than 2 is the sum of two prime numbers. Example: 28 = 5 + 23. It is one of the most famous facts in number theory that has not been proved to be correct in the general case. It has been numerically confirmed up to very large numbers (much larger than we can go with our Prolog system). Write a predicate to find the two prime numbers that sum up to a given even integer. |
||

+ | |||

+ | Example: |
||

+ | |||

+ | <pre> |
||

+ | * (goldbach 28) |
||

+ | (5 23) |
||

</pre> |
</pre> |
||

+ | Example in Haskell: |
||

− | Solution 1: |
||

+ | |||

<haskell> |
<haskell> |
||

+ | λ> goldbach 28 |
||

− | primesR :: Integral a => a -> a -> [a] |
||

+ | (5, 23) |
||

− | primesR a b = filter isPrime [a..b] |
||

</haskell> |
</haskell> |
||

+ | [[99 questions/Solutions/40 | Solutions]] |
||

− | If we are challenged to give all primes in the range between a and b we simply take all number from a up to b and filter the primes out. |
||

− | Solution 2: |
||

− | <haskell> |
||

− | primes :: Integral a => [a] |
||

− | primes = let sieve (n:ns) = n:sieve [ m | m <- ns, m `mod` n /= 0 ] in sieve [2..] |
||

+ | == Problem 41 == |
||

− | primesR :: Integral a => a -> a -> [a] |
||

− | primesR a b = takeWhile (<= b) $ dropWhile (< a) primes |
||

− | </haskell> |
||

+ | (**) Given a range of integers by its lower and upper limit, print a list of all even numbers and their Goldbach composition. |
||

− | Another way to compute the claimed list is done by using the ''Sieve of Eratosthenes''. The <hask>primes</hask> function generates a list of all (!) prime numbers using this algorithm and <hask>primesR</hask> filter the relevant range out. [But this way is very slow and I only presented it because I wanted to show how nice the ''Sieve of Eratosthenes'' can be implemented in Haskell :)] |
||

− | |||

− | == Problem 40 == |
||

+ | In most cases, if an even number is written as the sum of two prime numbers, one of them is very small. Very rarely, the primes are both bigger than say 50. Try to find out how many such cases there are in the range 2..3000. |
||

− | <Problem description> |
||

− | <pre> |
||

Example: |
Example: |
||

− | <example in lisp> |
||

+ | <pre> |
||

− | Example in Haskell: |
||

+ | * (goldbach-list 9 20) |
||

− | <example in Haskell> |
||

+ | 10 = 3 + 7 |
||

+ | 12 = 5 + 7 |
||

+ | 14 = 3 + 11 |
||

+ | 16 = 3 + 13 |
||

+ | 18 = 5 + 13 |
||

+ | 20 = 3 + 17 |
||

+ | * (goldbach-list 1 2000 50) |
||

+ | 992 = 73 + 919 |
||

+ | 1382 = 61 + 1321 |
||

+ | 1856 = 67 + 1789 |
||

+ | 1928 = 61 + 1867 |
||

</pre> |
</pre> |
||

+ | Example in Haskell: |
||

− | Solution: |
||

+ | |||

<haskell> |
<haskell> |
||

+ | λ> goldbachList 9 20 |
||

− | <solution in haskell> |
||

+ | [(3,7),(5,7),(3,11),(3,13),(5,13),(3,17)] |
||

+ | λ> goldbachList' 4 2000 50 |
||

+ | [(73,919),(61,1321),(67,1789),(61,1867)] |
||

</haskell> |
</haskell> |
||

+ | [[99 questions/Solutions/41 | Solutions]] |
||

− | <description of implementation> |
||

+ | |||

− | |||

[[Category:Tutorials]] |
[[Category:Tutorials]] |

## Latest revision as of 09:15, 9 February 2019

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

## Problem 31

(**) Determine whether a given integer number is prime.

Example:

* (is-prime 7) T

Example in Haskell:

```
λ> isPrime 7
True
```

## Problem 32

(**) Determine the greatest common divisor of two positive integer numbers. Use Euclid's algorithm.

Example:

* (gcd 36 63) 9

Example in Haskell:

```
λ> [myGCD 36 63, myGCD (-3) (-6), myGCD (-3) 6]
[9,3,3]
```

## Problem 33

(*) Determine whether two positive integer numbers are coprime. Two numbers are coprime if their greatest common divisor equals 1.

Example:

* (coprime 35 64) T

Example in Haskell:

```
λ> coprime 35 64
True
```

## Problem 34

(**) Calculate Euler's totient function phi(m).

Euler's so-called totient function phi(m) is defined as the number of positive integers r (1 <= r < m) that are coprime to m.

Example: m = 10: r = 1,3,7,9; thus phi(m) = 4. Note the special case: phi(1) = 1.

Example:

* (totient-phi 10) 4

Example in Haskell:

```
λ> totient 10
4
```

## Problem 35

(**) Determine the prime factors of a given positive integer. Construct a flat list containing the prime factors in ascending order.

Example:

* (prime-factors 315) (3 3 5 7)

Example in Haskell:

```
λ> primeFactors 315
[3, 3, 5, 7]
```

## Problem 36

(**) Determine the prime factors of a given positive integer.

Construct a list containing the prime factors and their multiplicity.

Example:

* (prime-factors-mult 315) ((3 2) (5 1) (7 1))

Example in Haskell:

```
λ> prime_factors_mult 315
[(3,2),(5,1),(7,1)]
```

## Problem 37

(**) Calculate Euler's totient function phi(m) (improved).

See problem 34 for the definition of Euler's totient function. If the list of the prime factors of a number m is known in the form of problem 36 then the function phi(m) can be efficiently calculated as follows: Let ((p1 m1) (p2 m2) (p3 m3) ...) be the list of prime factors (and their multiplicities) of a given number m. Then phi(m) can be calculated with the following formula:

phi(m) = (p1 - 1) * p1 ** (m1 - 1) * (p2 - 1) * p2 ** (m2 - 1) * (p3 - 1) * p3 ** (m3 - 1) * ...

Note that a ** b stands for the b'th power of a.

## Problem 38

(*) Compare the two methods of calculating Euler's totient function.

Use the solutions of problems 34 and 37 to compare the algorithms. Take the number of reductions as a measure for efficiency. Try to calculate phi(10090) as an example.

(no solution required)

## Problem 39

(*) A list of prime numbers.

Given a range of integers by its lower and upper limit, construct a list of all prime numbers in that range.

Example in Haskell:

```
λ> primesR 10 20
[11,13,17,19]
```

## Problem 40

(**) Goldbach's conjecture.

Goldbach's conjecture says that every positive even number greater than 2 is the sum of two prime numbers. Example: 28 = 5 + 23. It is one of the most famous facts in number theory that has not been proved to be correct in the general case. It has been numerically confirmed up to very large numbers (much larger than we can go with our Prolog system). Write a predicate to find the two prime numbers that sum up to a given even integer.

Example:

* (goldbach 28) (5 23)

Example in Haskell:

```
λ> goldbach 28
(5, 23)
```

## Problem 41

(**) Given a range of integers by its lower and upper limit, print a list of all even numbers and their Goldbach composition.

In most cases, if an even number is written as the sum of two prime numbers, one of them is very small. Very rarely, the primes are both bigger than say 50. Try to find out how many such cases there are in the range 2..3000.

Example:

* (goldbach-list 9 20) 10 = 3 + 7 12 = 5 + 7 14 = 3 + 11 16 = 3 + 13 18 = 5 + 13 20 = 3 + 17 * (goldbach-list 1 2000 50) 992 = 73 + 919 1382 = 61 + 1321 1856 = 67 + 1789 1928 = 61 + 1867

Example in Haskell:

```
λ> goldbachList 9 20
[(3,7),(5,7),(3,11),(3,13),(5,13),(3,17)]
λ> goldbachList' 4 2000 50
[(73,919),(61,1321),(67,1789),(61,1867)]
```