I'm new to SML and would like some assistance in using the following implementation of a binary tree.
datatype tree = NODE of int * tree * tree | LEAF of int;
I see that the tree is defined by either nodes which has two sub-trees or a LEAF with an integer.
How can I access the subtrees so that I can determine the maximum , the minimum, and if the element is present in the tree?
What is the process of accessing either the left and right sub-trees?
What is the process of accessing either the left and right sub-trees?
You use pattern matching:
fun goLeft (NODE (_, l, _)) = l
| goLeft LEAF = raise Fail "Cannot go left here!"
fun goRight (NODE (_, _, r)) = r
| goRight LEAF = raise Fail "Cannot go right here!"
How can I [...] determine the maximum, the minimum, and if the element is present in the tree?
You build recursive functions that pattern match on sub-trees.
For example, there is no invariant in a binary tree that says that the minimal element has a fixed, known location in the tree. But this invariant is present in a binary search tree, in which all elements in every left sub-tree (including the root) are made sure to be less than or equal to all the elements of their right sub-trees.
The tree
5
/ \
3 8
/ / \
2 7 9
qualifies as a binary search tree because this invariant holds.
Finding the minimal element in such a tree means recursing in such a way that you always pick the left sub-tree until there is no left sub-tree, in which case you have found the minimum. How do you know when to stop recursion?
fun goLeeeft (NODE (_, l, _)) = goLeeeft l
| goLeeeft LEAF = "I've gone all the way left, but I have nothing to show for it."
fun minimum (NODE (x, l, r)) = (* is this the last non-leaf node? *)
| minimum LEAF = raise Empty (* whoops, we recursed too far! *)
When you pattern match one level deep, that is, on NODE (x, l, r), you only know that this is a non-leaf node, but you don't know the exact value located in the node, x, and you don't know anything about the sub-structure of this node's left and right sub-trees.
You could go two ways here: Either make a helper function that tells you when to stop recursing, or pattern match one level deeper into l. Here are two examples of that; they perform the same thing:
(* Using a helper function *)
fun isLeaf (NODE (_, _, _)) = false
| isLeaf LEAF = true
fun minimum (NODE (x, l, _)) =
if isLeaf l
then x
else minimum l
| minimum LEAF = raise Empty
(* Using direct pattern matching *)
fun minimum (NODE (x, LEAF, _)) = x
| minimum (NODE (x, l, _)) = minimum l
| minimum LEAF = raise Empty
Now maximum writes itself.
As a curiosity, you can define generic recursion schemes such as folding on trees: Sml folding a tree
Related
I'm learning Haskell and have some problems with list comprehension.
If I define a function to get a list of the divisors of a given number, I get an error.
check n = [x | x <- [1..(floor (n/2))], mod n x == 0]
I don't get why it's causing an error. If I want to generate a list from 1 to n/2 I can do it with [1..(floor (n/2))], but not if I do it in the list comprehension.
I tried another way but I get also an error (in this code I want to get all so called "perfect numbers")
f n = [1..(floor (n/2))]
main = print $ filter (\t -> foldr (+) 0 (f t) == t) [2..100]
Usually it is better to start writing a signature. While signatures are often not required, it makes it easier to debug a single function.
The signature of your check function is:
check :: (RealFrac a, Integral a) => a -> [a]
The type of input (and output) a thus needs to be both a RealFrac and an Integral. While technically speaking we can make such type, it does not make much sense.
The reason this happens is because of the use of mod :: Integral a => a -> a -> a this requires x and n to be both of the same type, and a should be a member of the Integral typeclass.
Another problem is the use of n/2, since (/) :: Fractional a => a -> a -> a requires that n and 2 have the same type as n / 2, and n should also be of a type that is a member of Fractional. To make matters even worse, we use floor :: (RealFrac a, Integral b) => a -> b which enforces that n (and thus x as well) have a type that is a member of the RealFrac typeclass.
We can prevent the Fractional and RealFrac type constaints by making use of div :: Integral a => a -> a -> a instead. Since mod already required n to have a type that is a member of the Integral typeclass, this thus will not restrict the types further:
check n = [x | x <- [1 .. div n 2], mod n x == 0]
This for example prints:
Prelude> print (check 5)
[1]
Prelude> print (check 17)
[1]
Prelude> print (check 18)
[1,2,3,6,9]
I have a list of commands ([Command]) which looks like [forward 15, left 20, right 10].
I want to add forward 15 to [Command] whenever I see a forward 15 command. I used elem and == to compare whether the element is forward 15 or not but it gives me No instance for (Eq Command) arising error.
Also, in another function, I want to add [left 15, forward 15, forward 15, right 15, right 15, forward 15, forward 15, left 15] to [Command] whenever I see 4 consecutive forward 15 commands.
Thus my question is how to compare functions, because forward is a function and I can't compare it using elem or ==.
Command is defined as a type, not as a data, hence I can't use deriving Eq.
type Command = Funcs -> (Picture, Funcs)
data Funcs = Funcs {pen :: Bool, angle :: Float, point :: Point, penColor :: Color} deriving (Eq, Show)
forward :: Float -> Command
forward x = ....
I recommend making a new data type for commands, and an interpreter into the Command semantic domain. For example:
data ReifiedCommand
= Forward Float
| Backward Float
| Left Float
| Right Float
deriving (Eq, Ord, Read, Show)
interpret :: ReifiedCommand -> Command
interpret (Forward x) = forward x
interpret (Backward x) = backward x
interpret (Left x) = left x
interpret (Right x) = right x
Now you may compare ReifiedCommands for equality and do whatever inspection you need to do to build a suitable [ReifiedCommand], and then all at once at the end you may interpret these into a [Command] (or, more likely I think, even a single Command).
You might be missing a deriving clause in your data definition.
Prelude> data Command = Forward Int | Left Int | Right Int deriving (Eq, Show)
Prelude> Forward 15 == Forward 15
True
If you do not have the deriving clause you will see
No instance for (Eq Command) arising from a use of ‘==’
By the way, while it is true that Forward happens to be a (constructor) function, you want to make sure you are doing == comparisons not on functions themselves (you can't do this in Haskell) but rather on the result of applying the function. So you can never compare
Forward == Forward
because the type of Forward is Int->Command (a function) but you can compare
Forward 15 == Forward 15
as long as you associate the type Command with the Eq typeclass.
I am trying to implement a function here which takes a list of Bool representing binary numbers such as [True, False, False] and convert that into corresponding decimal number according to Horners method.
Function type would be [Bool] -> Int.
Algorithms which i am following is:
Horners Algorithm Visual Explanation:
So far i have implemented the logic in which it says first it will check whether the list is empty or either one element in the list [True], will give 1 and [False] will give 0.
Then in this case binToDecList (x:xs) = binToDecList' x 0 what i did to treat first element whether this is True or False.
binToDecList :: [Bool] -> Int
binToDecList [] = error "Empty List"
binToDecList [True] = 1
binToDecList [False] = 0
binToDecList (x:xs) = binToDecList' x 0
binToDecList' x d | x == True = mul (add d 1)
| otherwise = mul (add d 0)
add :: Int -> Int -> Int
add x y = x + y
mul :: Int -> Int
mul x = x * 2
I want to use the result of binToDecList' in the next iteration calling itself recursively on the next element of the list. How can i store the result and then apply it to next element of the list recursively. Any kind of help would be appreciated.
The type* of foldl tells us how it must work.
foldl :: (b -> a -> b) -> b -> [a] -> b
Clearly [a], the third argument that is a list of something, must be the list of Bool to be handed to Horner’s algorithm. That means the type variable a must be Bool.
The type variable b represents a possibly distinct type. We are trying to convert [Bool] to Int, so Int is a decent guess for b.
foldl works by chewing through a list from the left (i.e., starting with its head) and somehow combining the result so far with the next element from the list. The second argument is typically named z for “zero” or the seed value for the folding process. When foldl reaches the end of the list, it returns the accumulated value.
We can see syntactically that the first argument is some function that performs some operation on items of type b and type a to yield a b. Now, a function that ignores the a item and unconditionally results in whatever the b is would fit but wouldn’t be very interesting.
Think about how Horner’s algorithm proceeds. The numbers at the elbows of the path on your diagram represent the notional “result so far” from the previous paragraph. We know that b is Int and a is Bool, so the function passed to foldl must convert the Bool to Int and combine it with the result.
The first step in Horner’s algorithm seems to be a special case that needs to be handled differently, but foldl uses the same function all the way through. If you imagine “priming the pump” with an invisible horizontal move (i.e., multiplying by two) to begin with, we can make the types fit together like puzzle pieces. It’s fine because two times zero is still zero.
Thus, in terms of foldl, Horner’s algorithm is
horners :: [Bool] -> Int
horners = foldl f 0
where f x b =
let b' = fromEnum b
in 2*x + b'
Notice that 2*x + b' combines subsequent horizontal and vertical moves.
This also suggests how to express it in direct recursion.
horners' :: [Bool] -> Int
horners' [] = 0
horners' l = go 0 l
where -- over then down
go x [] = x
go x (b:bs) =
let b' = fromEnum b
in go (2*x + b') bs
Here the inner go loop is performing the left-fold and combining each next Bool with the result so far in i.
* A pedagogical simplification: the actual type generalizes the list type into Foldable.
I have function 'my_a' in OCaml, which could have a very complicated return type:
exception Backtrack
exception Continue of (* How do I put the type of function 'my_a' here? *)
let my_a arg = try do_stuff (List.hd arg)
with
| Backtrack -> my_a (List.tl arg)
| Continue (found_answer) -> (try my_a (List.tl arg)
with
| Backtrack -> raise Continue(found_answer)
| Continue (other_answer) ->
raise Continue (compare_answer(found_answer,other_answer));;
(* the caller of my_a will handle the Continue exception to catch the found value
if something was found*)
This is my problem: I'm using backtrack to find a solution. When a backtrack exception is raised by do_stuff, there was no solution going that path. However, when it raises an exception of type Continue, it means it found a solution, but, it may not be the best solution there is, that's when I try again with a different path. If there is another exception, I want to return the answer it already had found.
The thing is, to be able to use that feature of OCaml I need to to tell it what data type Continue will be carrying. What the OCaml top level returns when i define my_a:
'a * ('a -> ('a, 'b) symbol list list) ->
'b list -> ('a * ('a, 'b) symbol list) list * 'b list = <fun>
Does anyone have any idea of how to do that, or a different solution to that?
It's hard to tell exactly what you're asking. I think you might be asking how to get the type inside the Two exception to be set to the return type of A without having to specifically declare this type. I can't think of any way to do it.
Things might go better if you used option types instead of exceptions. Or you can just declare the return type of A explicitly. It might be good documentation.
A couple of side comments: (a) function names have to start with a lower case letter (b) this code looks quite convoluted and hard to follow. There might be a simpler way to structure your computation.
You are gaining nothing by using exceptions. Here is a possible solution.
(** There are many ways to implement backtracking in Ocaml. We show here one
possibility. We search for an optimal solution in a search space. The
search space is given by an [initial] state and a function [search] which
takes a state and returns either
- a solution [x] together with a number [a] describing how good [x] is
(larger [a] means better solution), or
- a list of states that need still to be searched.
An example of such a problem: given a number [n], express it as a sum
[n1 + n2 + ... + nk = n] such that the product [n1 * n2 * ... * nk] is
as large as possible. Additionally require that [n1 <= n2 <= ... <= nk].
The state of the search can be expressed as pair [(lst, s, m)] where
[lst] is the list of numbers in the sum, [s] is the sum of numbers in [lst],
and [m] is the next number we will try to add to the list. If [s = n] then
[lst] is a solution. Otherwise, if [s + m <= n] then we branch into two states:
- either we add [m] to the list, so the next state is [(m :: lst, m+s, m)], or
- we do not add [m] to the list, and the next state is [(lst, s, m+1)].
The return type of [search] is described by the following datatype:
*)
type ('a, 'b, 'c) backtrack =
| Solution of ('a * 'b)
| Branches of 'c list
(** The main function accepts an initial state and the search function. *)
let backtrack initial search =
(* Auxiliary function to compare two optional solutions, and return the better one. *)
let cmp x y =
match x, y with
| None, None -> None (* no solution *)
| None, Some _ -> y (* any solution is better than none *)
| Some _, None -> x (* any solution is better than none *)
| Some (_, a), Some (_, b) ->
if a < b then y else x
in
(* Auxiliary function which actually performs the search, note that it is tail-recursive.
The argument [best] is the best (optional) solution found so far, [branches] is the
list of branch points that still needs to be processed. *)
let rec backtrack best branches =
match branches with
| [] -> best (* no more branches, return the best solution found *)
| b :: bs ->
(match search b with
| Solution x ->
let best = cmp best (Some x) in
backtrack best bs
| Branches lst ->
backtrack best (lst # bs))
in
(* initiate the search with no solution in the initial state *)
match backtrack None [initial] with
| None -> None (* nothing was found *)
| Some (x, _) -> Some x (* the best solution found *)
(** Here is the above example encoded. *)
let sum n =
let search (lst, s, m) =
if s = n then
(* solution found, compute the product of [lst] *)
let p = List.fold_left ( * ) 1 lst in
Solution (lst, p)
else
if s + m <= n then
(* split into two states, one that adds [m] to the list and another
that increases [m] *)
Branches [(m::lst, m+s, m); (lst, s, m+1)]
else
(* [m] is too big, no way to proceed, return empty list of branches *)
Branches []
in
backtrack ([], 0, 1) search
;;
(** How to write 10 as a sum of numbers so that their product is as large as possible? *)
sum 10 ;; (* returns Some [3; 3; 2; 2] *)
OCaml happily informs us that the type of backtrack is
'a -> ('a -> ('b, 'c, 'a) backtrack) -> 'b option
This makes sense:
the first argument is the initial state, which has some type 'a
the second argument is the search function, which takes a state of type 'a and
returns either a Solution (x,a) where x has type 'b and a has type 'c,
or Branches lst where lst has type 'a list.
"Suppose you want to build a solid panel out of rows of 4×1 and 6×1 Lego blocks. For structural strength, the spaces between the blocks must never line up in adjacent rows. As an example, the 18×3 panel shown below is not acceptable, because the spaces between the blocks in the top two rows line up.
There are 2 ways to build a 10×1 panel, 2 ways to build a 10×2 panel, 8 ways to build an 18×3 panel, and 7958 ways to build a 36×5 panel.
How many different ways are there to build a 64×10 panel? The answer will fit in a 64-bit signed integer. Write a program to calculate the answer. Your program should run very quickly – certainly, it should not take longer than one minute, even on an older machine. Let us know the value your program computes, how long it took your program to calculate that value, and on what kind of machine you ran it. Include the program’s source code as an attachment.
"
I was recently given a programming puzzle and have been racking my brains trying to solve it. I wrote some code using c++ and I know the number is huge...my program ran for a few hours before I decided just to stop it because the requirement was 1 minute of run time even on a slow computer. Has anyone seen a puzzle similar to this? It has been a few weeks and I can't hand this in anymore, but this has really been bugging me that I couldn't solve it correctly. Any suggestions on algorithms to use? Or maybe possible ways to solve it that are "outside the box". What i resorted to was making a program that built each possible "layer" of 4x1 and 6x1 blocks to make a 64x1 layer. That turned out to be about 3300 different layers. Then I had my program run through and stack them into all possible 10 layer high walls that have no cracks that line up...as you can see this solution would take a long, long, long time. So obviously brute force does not seem to be effective in solving this within the time constraint. Any suggestions/insight would be greatly appreciated.
The main insight is this: when determining what's in row 3, you don't care about what's in row 1, just what's in row 2.
So let's call how to build a 64x1 layer a "row scenario". You say that there are about 3300 row scenarios. That's not so bad.
Let's compute a function:
f(s, r) = the number of ways to put row scenario number "s" into row "r", and legally fill all the rows above "r".
(I'm counting with row "1" at the top, and row "10" at the bottom)
STOP READING NOW IF YOU WANT TO AVOID SPOILERS.
Now clearly (numbering our rows from 1 to 10):
f(s, 1) = 1
for all values of "s".
Also, and this is where the insight comes in, (Using Mathematica-ish notation)
f(s, r) = Sum[ f(i, r-1) * fits(s, i) , {i, 1, 3328} ]
where "fits" is a function that takes two scenario numbers and returns "1" if you can legally stack those two rows on top of each other and "0" if you can't. This uses the insight because the number of legal ways to place scenario depends only on the number of ways to place scenarios above it that are compatible according to "fits".
Now, fits can be precomputed and stored in a 3328 by 3328 array of bytes. That's only about 10 Meg of memory. (Less if you get fancy and store it as a bit array)
The answer then is obviously just
Sum[ f(i, 10) , {i, 1, 3328} ]
Here is my answer. It's Haskell, among other things, you get bignums for free.
EDIT: It now actually solves the problem in a reasonable amount of time.
MORE EDITS: With a sparse matrix it takes a half a second on my computer.
You compute each possible way to tile a row. Let's say there are N ways to tile a row. Make an NxN matrix. Element i,j is 1 if row i can appear next to row j, 0 otherwise. Start with a vector containing N 1s. Multiply the matrix by the vector a number of times equal to the height of the wall minus 1, then sum the resulting vector.
module Main where
import Data.Array.Unboxed
import Data.List
import System.Environment
import Text.Printf
import qualified Data.Foldable as F
import Data.Word
import Data.Bits
-- This records the index of the holes in a bit field
type Row = Word64
-- This generates the possible rows for given block sizes and row length
genRows :: [Int] -> Int -> [Row]
genRows xs n = map (permToRow 0 1) $ concatMap comboPerms $ combos xs n
where
combos [] 0 = return []
combos [] _ = [] -- failure
combos (x:xs) n =
do c <- [0..(n `div` x)]
rest <- combos xs (n - x*c)
return (if c > 0 then (x, c):rest else rest)
comboPerms [] = return []
comboPerms bs =
do (b, brest) <- choose bs
rest <- comboPerms brest
return (b:rest)
choose bs = map (\(x, _) -> (x, remove x bs)) bs
remove x (bc#(y, c):bs) =
if x == y
then if c > 1
then (x, c - 1):bs
else bs
else bc:(remove x bs)
remove _ [] = error "no item to remove"
permToRow a _ [] = a
permToRow a _ [_] = a
permToRow a n (c:cs) =
permToRow (a .|. m) m cs where m = n `shiftL` c
-- Test if two rows of blocks are compatible
-- i.e. they do not have a hole in common
rowCompat :: Row -> Row -> Bool
rowCompat x y = x .&. y == 0
-- It's a sparse matrix with boolean entries
type Matrix = Array Int [Int]
type Vector = UArray Int Word64
-- Creates a matrix of row compatibilities
compatMatrix :: [Row] -> Matrix
compatMatrix rows = listArray (1, n) $ map elts [1..n] where
elts :: Int -> [Int]
elts i = [j | j <- [1..n], rowCompat (arows ! i) (arows ! j)]
arows = listArray (1, n) rows :: UArray Int Row
n = length rows
-- Multiply matrix by vector, O(N^2)
mulMatVec :: Matrix -> Vector -> Vector
mulMatVec m v = array (bounds v)
[(i, sum [v ! j | j <- m ! i]) | i <- [1..n]]
where n = snd $ bounds v
initVec :: Int -> Vector
initVec n = array (1, n) $ zip [1..n] (repeat 1)
main = do
args <- getArgs
if length args < 3
then putStrLn "usage: blocks WIDTH HEIGHT [BLOCKSIZE...]"
else do
let (width:height:sizes) = map read args :: [Int]
printf "Width: %i\nHeight %i\nBlock lengths: %s\n" width height
$ intercalate ", " $ map show sizes
let rows = genRows sizes width
let rowc = length rows
printf "Row tilings: %i\n" rowc
if null rows
then return ()
else do
let m = compatMatrix rows
printf "Matrix density: %i/%i\n"
(sum (map length (elems m))) (rowc^2)
printf "Wall tilings: %i\n" $ sum $ elems
$ iterate (mulMatVec m) (initVec (length rows))
!! (height - 1)
And the results...
$ time ./a.out 64 10 4 6
Width: 64
Height 10
Block lengths: 4, 6
Row tilings: 3329
Matrix density: 37120/11082241
Wall tilings: 806844323190414
real 0m0.451s
user 0m0.423s
sys 0m0.012s
Okay, 500 ms, I can live with that.
I solved a similar problem for a programming contest tiling a long hallway with tiles of various shapes. I used dynamic programming: given any panel, there is a way to construct it by laying down one row at a time. Each row can have finitely many shapes at its end. So for each number of rows, for each shape, I compute how many ways there are to make that row. (For the bottom row, there is exactly one way to make each shape.) Then the shape of each row determines the number of shapes that the next row can take (i.e. never line up the spaces). This number is finite for each row and in fact because you have only two sizes of bricks, it is going to be small. So you wind up spending constant time per row and the program finishes quickly.
To represent a shape I would just make a list of 4's and 6's, then use this list as a key in a table to store the number of ways to make that shape in row i, for each i.