• Tidak ada hasil yang ditemukan

Functional Programming Solution, 2013

N/A
N/A
Protected

Academic year: 2024

Membagikan "Functional Programming Solution, 2013"

Copied!
5
0
0

Teks penuh

(1)

Functional Programming Solution, 2013

Tutorial and Practical Topic = FP, PracName=4:map2

The prac we mark out of 40, as follows:

Q1 = 4 marks

Q2 = 10 marks, try to encourage them (via marks) to split the problem into 5 parts for marks like this:

* 2 a generator of the next term from the current one,

* 1 iterating the generator, starting from the initial value * 2 taking the initial elements until the sequence converges * 1 determining the length of the sequence

* 2 getting the table of numbers and corresponding lengths

* 2 some evidence that they looked on the web and engaged with this!

Q3 = 16 marks: parts b=1, c=1, d=3, e=3, f=3, h=5

Q4 = EPW will mark this out of 10.

Practical

1. (Chapter 11.5 exercise 9 from the text) Without using explicit recursion, write a function map2 which applies a binary function to corresponding elements in two lists of arguments. (Assume the function is applied to all elements until one of the input lists becomes exhausted.) For example, (assuming insert is defined as it was in your first practical)

map2 (+) [1..] [4,5,6] [5,7,9]

map2 (:) "joe" ["one","two","three"] ["jone","otwo","ethree"]

map2 insert "joe" ["aou","iou","aeu"] ["ajou","ioou","aeeu"]

One Solution (there are some other interesting ones possible) map2 :: (a -> b -> c) -> [a] -> [b] -> [c]

map2 f xs ys = [ f x y | (x,y) <- zip xs ys ]

2. The Collatz numbers (also called the hailstone numbers, or wonderous numbers, or 3n+1 numbers):

Given a starting value n>0, the next term in its 3n+1 sequence is generated by determining whether it is even or odd. If n is even, divide it by two. If it is odd, multiply it by three and add one. For

example, the sequence generated from a starting value of 13 is 13 40 20 10 5 16 8 4 2 1 4 2 1 4 2 1 … The Collatz conjecture is that all starting values finally end up in the infinite cycle

1 4 2 1 …, but nobody can quite prove whether

i) all starting values must end up in some or other cycle, or ii) whether 1 4 2 1 … is the only cycle they could end up in.

(2)

• Use the iterate function to generate the infinite sequence from a given starting value.

• Use the takeWhile function to produce the 3n+1 sequence which terminates with the first occurrence of 1.

• Use this in a function which calculates the length of the non-cyclic portion of the sequence which starts at any positive value n.

• Use a list comprehension to produce a table of pairs (n, steps needed) for all n up to 200.

• Find at least one interesting fact about this problem on the web. Tell us concisely what you learnt, and give a reference to the URL.

3. Chapter 12.5 Exercise 5: Solve the famous problem for finding a colouring of any planar map such that you need no more than four colours. We've already solved this for you: our Haskell and a couple of other files are all available as a downloadable zip file called fourColours.zip. Your must study, understand all, and explain bits of our code, make some small changes, and encode and solve your own map.

a) Load, inspect and run the program on the test cases, and on the two test maps given in the zip archive. The bigger one, shown here, comes from the Wikipedia description where you can read a bit more about the theorem.

http://en.wikipedia.org/wiki/Four_color_theorem

b) How many distinct solutions are found for the testOne map that is hardwired in the code?

324 solutions

c) How many reductions are needed to find the first legal colouring?

I get 1119, Your Mileage May Vary slightly..

d) In the code we made a simple optimization – when we get down to a single country, we always colour it Green. Remove this "optimization" and create a more sensible base case (so that your algorithm will work correctly even for an empty

map). Now how many distinct colourings should be available for the testOne map? Verify experimentally.

-- one line code change

f [] = [[]] -- was f [x] = [[(x,Green)]]

4 times as many 1296, verified.

e) How many reductions are needed to find the first legal colouring? Explain why c) and e) give similar answers, even though the number of different colourings is different in the two cases.

(3)

I get 1137, YMMV. Important here is the explanation. Although we "pick" the first solution off the (conceptually) long list of solutions, they have to realize that the multiple solution list has NOT actually been built yet – because of lazy evaluation. So whether we're working with the case that could produce 1296 solutions or only 324, the amount of work to find just the first one is about the same. The one with the bigger number of solutions essentially saves more work because of the lazy nature of execution.

f) Explain what the functions nub (around line 19), and words (around line 48) do.

nub eliminates duplicates, words breaks a string into a list of space-separated words.

g) Run the main program to see how we can read the description of the map from a file. Notice that the map in the file testmap1.txt is the same map as the testOne map hardwired into the code. Ensure that you understand how testmap2.txt encodes the sample shown here.

h) Put the encoded data for this map into a file, and run the

program to find a 4-colouring for it. Record the encoding, the colour assignment, the number of solutions and the number of reductions. Now delete country K, and solve again. Explain why the number of possible colourings increases. What about the number of reductions? (This map is in the zip file too, in case you want to print it and colour it in with your crayons!)

My two maps are

AB AK BC BD BI BJ BK CD CE CI DE DF DJ DK EF EG EH EI FG FJ GH GJ HI HJ IJ JK and

AB BC BD BI BJ CD CE CI DE DF DJ EF EG EH EI FG FJ GH GJ HI HJ IJ

Using the fixed colour at the base case (otherwise you'll see 4 times as mmany solutions), I get

Main> :main givenmap_sln.txt First solution:

[('A',Red),('B',Yellow),('C',Green),('D',Blue),('E',Red),('F',Green),('G',Blue),('H',G reen),('I',Blue),('J',Red),('K',Green)]

Number of solutions = 108

(207683 reductions, 270032 cells)

Main> :main givenmap_no_k_sln.txt First solution:

[('A',Red),('B',Yellow),('C',Blue),('D',Red),('E',Green),('F',Blue),('G',Red),('H',Blu e),('I',Red),('J',Green)]

Number of solutions = 162

(4)

(87389 reductions, 115122 cells)

When country K is removed there are less countries, less work, so reductions is less than half. BUT, importantly, there are also less constraints. K touches A, B, D, J.

If K already has a colour, the colouring possibilities on those four contries is

reduced. So saying "don't worry about K" increases the "degrees of freedom" available in the rest of the map, hence more solutions are possible.

4. Complete the exercises in Week 4 of Fixing the World.

(5)

BONUS MAP COLOURING: My solution import System

import List

-- In the most simple representation, if we assume every country must -- have a neighbour, then all we need is the list of adjacencies.

-- we can pull the list of country names from this list.

type Country = Char type Adjacency = String type MyMap = [Adjacency]

data Colour = Red | Green | Blue | Yellow deriving (Show, Eq, Enum) type Assignment = (Char, Colour)

type Colouring = [Assignment]

testmap1 :: MyMap

testmap1 = ["ab","ac","ad", "bc", "be", "bf", "af", "ag" ]

countryNames mp = nub ([c | [c,_] <- mp] ++ [d | [_,d] <- mp])

neighboursOf mp c = [v | [u,v] <- mp, u==c] ++

[u | [u,v] <- mp, v==c]

solve :: MyMap -> [Colouring]

solve mp = s'(countryNames mp) where

s' [x] = [[(x,Green)]]

s' (c:cs) = [ (c,k): subColourings | subColourings <- s' cs, let nns = neighboursOf mp c,

let inuse = [ colr | (c,colr) <- subColourings, elem c nns], k <- ([Red .. Yellow] \\ inuse)

]

test1 = countryNames testmap1 test2 = neighboursOf testmap1 'b' test3 = solve testmap1

main = do

[filename] <- getArgs

contents <- (readFile filename) let slns = solve (words contents) putStrLn (show (head slns))

Referensi

Dokumen terkait