Generate a list representing a doorbell system - list
I'm trying to generate a list from two Ints and another list of tuples to represent a doorbell system for an apartment building. The first number is the number of floors, the second number is the floor that "doesn't exist"/we jump, and the list is the distribution of the apartments for floor. For example:
geneList 10 4 [("Rgt", 10), ("Lft", 8), ("Cent", 3)]
(In this example, we will have 10 floors and the 4th doesn't exist. Only the first three have 'Cent' 'Rgt' and 'Lft' apartments. Floors from fifth to ninth only have 'Rgt' and 'Left' apartments. Floors from 10 to 11 only have 'Rght' apartments.)
The return value must be:
["1Rgt","1Lft","1Cent","2Rgt","2Lft","2Cent","3Rgt","3Lft","3Cent","5Rgt","5Lft","6Rgt","6Lft","7Rgt","7Lft","8Rgt","8Lft","9Rgt","9Lft","10Rgt","11Rgt"]
I have tried different ways, but I never managed to reach the result.
My last attempt was:
geneList :: Int -> Int -> [(Char, Int)] -> [Char]
geneList 0 _ _ = []
geneList x y xs = [a++b | a <- [1..x+1], b <- xs, (\=) a y]
Can anybody help me please?
First let’s work out the number to write for a floor:
floorNum skip n = if n < skip then n else n + 1
Now let’s get the apartment names for a floor name
apartments :: [(String, Int)] -> Int -> Int -> [String]
apartments spec skip floor = [f ++ name | (name, max) <- spec, floor <= max]
where f = show $ floorNum skip floor
And we can collect these for all the floors:
geneList floors skip spec = [name | floor <- [1..floors], name <- apartments spec skip floor]
These are the problems in your code:
The type of "Rgt" is String (a.k.a. [Char]), not Char.
The not-equal comparison operator is written /=, not \=. (read the documentation carefully!)
You didn't make sure that the current floor is at most the height of each apartment.
When you write b <- xs, b is a (String, Int) tuple. You should write (apartment_name, apartment_height) <- xs instead.
Related
How do I combine consectuive numbers in a list into a range in Haskell?
I'm trying to grapple my head around Haskell and I'm having a hard time pinning down the general procedure/algorithm for this specific task. What I want to do is basically give Haskell a list [1,2,3,5,6,9,16,17,18,19] and have it give me back [1-3, 5, 6, 9, 16-19] so essentially turning three or more consecutive numbers into a range in the style of lowestnumber - highestnumber. What I have issue with it I suppose is the all too common difficulty grappling with with the functional paradigm of Haskell. So I would really appreciate a general algorithm or an insight into how to view this from an "Haskellian" point of view. Thanks in advance.
If I understand the question correctly, the idea is to break up the input lists in chunks, where a chunk is either a single input element or a range of at least three consecutive elements. So, let's start by defining a datatype for representing such chunks: data Chunk a = Single a | Range a a As you can see, the type is parametric in the type of input elements. Next, we define a function chunks to actually construct a list of chunks from a list of input elements. For this, we require the ability to compare input elements and to obtain the immediate consecutive for a given input element (that is, its successor). Hence, the type of the function reads chunks :: (Eq a, Enum a) => [a] -> [Chunk a] Implementation is relatively straightforward: chunks = foldr go [] where go x (Single y : Single z : cs) | y == succ x && z == succ y = Range x z : cs go x (Range y z : cs) | y == succ x = Range x z : cs go x cs = Single x : cs We traverse the list from right to left, generating chunks as we go. We generate a range if an input element precedes its two immediate consecutive elements (the first case of the helper function go) or if it precedes a range that starts with its immediate consecutive (the second case). Otherwise, we generate a single element (the final case). To arrange for pretty output, we declare applications of the type constructor Chunk to be instances of the class Show (given that the type of input elements is in Show): instance Show a => Show (Chunk a) where show (Single x ) = show x show (Range x y) = show x ++ "-" ++ show y Returning to the example from the question, we then have: > chunks [1,2,3,5,6,9,16,17,18,19] [1-3,5,6,9,16-19] Unfortunately, things are slightly more complicated if we need to account for bounded element types; such types have a largest element for which succ is undefined: > chunks [maxBound, 1, 2, 3] :: [Chunk Int] *** Exception: Prelude.Enum.succ{Int}: tried to take `succ' of maxBound This suggests that we should abstract from the specific approach for determining whether one elements succeeds another: chunksBy :: (a -> a -> Bool) -> [a] -> [Chunk a] chunksBy succeeds = foldr go [] where go x (Single y : Single z : cs) | y `succeeds` x && z `succeeds` y = Range x z : cs go x (Range y z : cs) | y `succeeds` x = Range x z : cs go x cs = Single x : cs Now, the version of chunks that was given above, can be expressed in terms of chunksBy simply by writing chunks :: (Eq a, Enum a) => [a] -> [Chunk a] chunks = chunksBy (\y x -> y == succ x) Moreover, we can now also implement a version for bounded input types as well: chunks' :: (Eq a, Enum a, Bounded a) => [a] -> [Chunk a] chunks' = chunksBy (\y x -> x /= maxBound && y == succ x) That merrily gives us: > chunks' [maxBound, 1, 2, 3] :: [Chunk Int] [9223372036854775807,1-3]
First, all elements of a list must be of the same type. Your resulting list has two different types. Ranges (for what ever that means) and Ints. We should convert one single digit into a range with lowest and highest been the same. Been said so, You should define the Range data type and fold your list of Int into a list of Range data Range = Range {from :: Int , to :: Int} intsToRange :: [Int] -> [Range] intsToRange [] = [] intsToRange [x] = [Range x x] intsToRange (x:y:xs) = ... -- hint: you can use and auxiliar acc which holds the lowest value and keep recursion till find a y - x differece greater than 1. You can also use fold, etc... to get a very haskelly point of view
Use recursion. Recursion is a leap of faith. It is imagining you've already written your definition and so can ("recursively") call it on a sub-problem of your full problem, and combine the (recursively calculated) sub-result with the left-over part to get the full solution -- easy: ranges xs = let (leftovers, subproblem) = split xs subresult = ranges subproblem result = combine leftovers subresult in result where split xs = .... combine as rs = .... Now, we know the type of rs in combine (i.e. subresult in ranges) -- it is what ranges returns: ranges :: [a] -> rngs So, how do we split our input list xs? The type-oriented design philosophy says, follow the type. xs is a list [a] of as. This type has two cases: [] or x:ys with x :: a and ys :: [a]. So the easiest way to split a list into a smaller list and some leftover part is split (x:xs) = (x, ys) split [] = *error* "no way to do this" -- intentionally invalid code Taking note of the last case, we'll have to tweak the overall design to take that into account. But first things first, what's the rngs type could be? Going by your example data, it's a list of rngs, naturally, rngs ~ [rng]. A rng type though, we have a considerable degree of freedom to make it to be whatever we want. The cases we have to account for are pairs and singletons: data Rng a = Single a | Pair a a .... and now we need to fit the jagged pieces together into one picture. Combining a number with a range which starts from consecutive number is obvious. Combining a number with a single number will have two obvious cases, for whether those numbers are consecutive or not. I think / hope you can proceed from here.
How do I map each value from one list to another? (Haskell)
This is the code I have so far: data Suit = Diamond | Club | Heart | Spade deriving (Read, Enum, Eq, Bounded) data Rank = Two | Three | Four | Five | Six | Seven | Eight | Nine | Ten | Jack | Queen | King | Ace deriving (Read, Enum, Eq, Ord, Bounded) and I am trying to map each value, either Rank or Suit to a unique prime number. primeMapper :: Either Rank Suit -> Int should be the final function and I want to iterate over each Suit and set it to the first four primes: primeMapper [Diamond .. Spade] = [2,3,5,7] and each Rank equal to the rest of the primes up until the 17th: primeMapper [Two .. Ace] = drop 4 . take 17 $ primes assuming I have a generating function called primes. This code, however throws errors obviously because it generates a list from a list. How can I achieve what I am trying to do? Let me know if I can explain it better. The ultimate goal is to have a hash table that gives unique IDs to each cards based on prime factors, and then generate prime factorization and use modulo to quickly compare poker hands.
Ultimately I solved what I am trying to do by hand as so: primeMapper :: Either Suit Rank -> Int primeMapper x = case x of Left Diamond -> 2 Left Club -> 3 Left Heart -> 5 Left Spade -> 7 Right Two -> 11 Right Three -> 13 Right Four -> 17 Right Five -> 19 Right Six -> 23 Right Seven -> 29 Right Eight -> 31 Right Nine -> 37 Right Ten -> 41 Right Jack -> 43 Right Queen -> 47 Right King -> 53 Right Ace -> 59 ... was there a more concise way to do this rather than write each case out by hand?
Your solution using pattern matching is best, though I would prefer primeMapper :: Either Suit Rank -> Int primeMapper (Left Diamond) = 2 primeMapper (Left Club) = 3 ... rather than your long case expression. However you could also use lookup :: Eq a => a -> [(a, b)] -> Maybe b import Data.Maybe (fromJust) primeMapper :: Either Suit Rank -> Int primeMapper = fromJust . flip lookup zippedPrimes where zippedPrimes = zip suitranks primes suitranks = fmap Left suits ++ fmap Right ranks :: [Either Suit Rank] suits = fromEnum minBound ranks = fromEnum minBound
Depending on what you plan to use this for, you may not need to use primes or prime factorizations at all; you can get fast conversion to and from plain numbers just by picking one or the other of the suit or rank for a base conversion. Here I'll pick suit -- there are four suits, so take the first digit in base 4 as the suit and the remaining digits as the rank. encode :: (Suit, Rank) -> Int encode (s, r) = fromEnum s + 4 * fromEnum r decode :: Int -> (Suit, Rank) decode n = (toEnum s, toEnum r) where (r, s) = n `quotRem` 4 You can verify in ghci that this gives a unique number to each card: > [encode (s, r) | r <- [minBound .. maxBound], s <- [minBound .. maxBound]] [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51] And that they decode appropriately: > map decode [0..51] == [(s, r) | r <- [minBound .. maxBound], s <- [minBound .. maxBound]] True
You can adapt some of this I hope. no2s3s5s = \n -> take n $ scanl (\b a -> a+b) 11 $ cycle [2,4,2,4,6,2,6,4] rnk = filter (/=49) $ no2s3s5s 14 stv = [2,3,5,7] _deck = [ b*v | b <- stv, v <- rnk] _Dia = take 13.drop (0*13) $ _deck _Clb = take 13.drop (1*13) $ _deck _Hrt = take 13.drop (2*13) $ _deck _Spd = take 13.drop (3*13) $ _deck _Dia [22,26,34,38,46,58,62,74,82,86,94,106,118] _Clb [33,39,51,57,69,87,93,111,123,129,141,159,177] _Hrt [55,65,85,95,115,145,155,185,205,215,235,265,295] _Spd [77,91,119,133,161,203,217,259,287,301,329,371,413] _deck [22,26,34,38,46,58,62,74,82,86,94,106,118,33,39,51,57,69,87,93,111,123,129,141,159,177,55,65,85,95,115,145,155,185,205,215,235,265,295,77,91,119,133,161,203,217,259,287,301,329,371,413] length _deck 52 Your multiples (_deck) are all unique. I normally use no2s3s5s with a computed (limited) factor list and the mod function to generate a long prime list.
How can I fold with state in Haskell?
I have a simple function (used for some problems of project Euler, in fact). It turns a list of digits into a decimal number. fromDigits :: [Int] -> Integer fromDigits [x] = toInteger x fromDigits (x:xs) = (toInteger x) * 10 ^ length xs + fromDigits xs I realized that the type [Int] is not ideal. fromDigits should be able to take other inputs like e.g. sequences, maybe even foldables ... My first idea was to replace the above code with sort of a "fold with state". What is the correct (= minimal) Haskell-category for the above function?
First, folding is already about carrying some state around. Foldable is precisely what you're looking for, there is no need for State or other monads. Second, it'd be more natural to have the base case defined on empty lists and then the case for non-empty lists. The way it is now, the function is undefined on empty lists (while it'd be perfectly valid). And notice that [x] is just a shorthand for x : []. In the current form the function would be almost expressible using foldr. However within foldl the list or its parts aren't available, so you can't compute length xs. (Computing length xs at every step also makes the whole function unnecessarily O(n^2).) But this can be easily avoided, if you re-thing the procedure to consume the list the other way around. The new structure of the function could look like this: fromDigits' :: [Int] -> Integer fromDigits' = f 0 where f s [] = s f s (x:xs) = f (s + ...) xs After that, try using foldl to express f and finally replace it with Foldable.foldl.
You should avoid the use of length and write your function using foldl (or foldl'): fromDigits :: [Int] -> Integer fromDigits ds = foldl (\s d -> s*10 + (fromIntegral d)) 0 ds From this a generalization to any Foldable should be clear.
A better way to solve this is to build up a list of your powers of 10. This is quite simple using iterate: powersOf :: Num a => a -> [a] powersOf n = iterate (*n) 1 Then you just need to multiply these powers of 10 by their respective values in the list of digits. This is easily accomplished with zipWith (*), but you have to make sure it's in the right order first. This basically just means that you should re-order your digits so that they're in descending order of magnitude instead of ascending: zipWith (*) (powersOf 10) $ reverse xs But we want it to return an Integer, not Int, so let's through a map fromIntegral in there zipWith (*) (powersOf 10) $ map fromIntegral $ reverse xs And all that's left is to sum them up fromDigits :: [Int] -> Integer fromDigits xs = sum $ zipWith (*) (powersOf 10) $ map fromIntegral $ reverse xs Or for the point-free fans fromDigits = sum . zipWith (*) (powersOf 10) . map fromIntegral . reverse Now, you can also use a fold, which is basically just a pure for loop where the function is your loop body, the initial value is, well, the initial state, and the list you provide it is the values you're looping over. In this case, your state is a sum and what power you're on. We could make our own data type to represent this, or we could just use a tuple with the first element being the current total and the second element being the current power: fromDigits xs = fst $ foldr go (0, 1) xs where go digit (s, power) = (s + digit * power, power * 10) This is roughly equivalent to the Python code def fromDigits(digits): def go(digit, acc): s, power = acc return (s + digit * power, power * 10) state = (0, 1) for digit in digits: state = go(digit, state) return state[0]
Such a simple function can carry all its state in its bare arguments. Carry around an accumulator argument, and the operation becomes trivial. fromDigits :: [Int] -> Integer fromDigits xs = fromDigitsA xs 0 # 0 is the current accumulator value fromDigitsA [] acc = acc fromDigitsA (x:xs) acc = fromDigitsA xs (acc * 10 + toInteger x)
If you're really determined to use a right fold for this, you can combine calculating length xs with the calculation like this (taking the liberty of defining fromDigits [] = 0): fromDigits xn = let (x, _) = fromDigits' xn in x where fromDigits' [] = (0, 0) fromDigits' (x:xn) = (toInteger x * 10 ^ l + y, l + 1) where (y, l) = fromDigits' xn Now it should be obvious that this is equivalent to fromDigits xn = fst $ foldr (\ x (y, l) -> (toInteger x * 10^l + y, l + 1)) (0, 0) xn The pattern of adding an extra component or result to your accumulator, and discarding it once the fold returns, is a very general one when you're re-writing recursive functions using folds. Having said that, a foldr with a function that is always strict in its second parameter is a really, really bad idea (excessive stack usage, maybe a stack overflow on long lists) and you really should write fromDigits as a foldl as some of the other answers have suggested.
If you want to "fold with state", probably Traversable is the abstraction you're looking for. One of the methods defined in Traversable class is traverse :: Applicative f => (a -> f b) -> t a -> f (t b) Basically, traverse takes a "stateful function" of type a -> f b and applies it to every function in the container t a, resulting in a container f (t b). Here, f can be State, and you can use traverse with function of type Int -> State Integer (). It would build an useless data structure (list of units in your case), but you can just discard it. Here's a solution to your problem using Traversable: import Control.Monad.State import Data.Traversable sumDigits :: Traversable t => t Int -> Integer sumDigits cont = snd $ runState (traverse action cont) 0 where action x = modify ((+ (fromIntegral x)) . (* 10)) test1 = sumDigits [1, 4, 5, 6] However, if you really don't like building discarded data structure, you can just use Foldable with somewhat tricky Monoid implementation: store not only computed result, but also 10^n, where n is count of digits converted to this value. This additional information gives you an ability to combine two values: import Data.Foldable import Data.Monoid data Digits = Digits { value :: Integer , power :: Integer } instance Monoid Digits where mempty = Digits 0 1 (Digits d1 p1) `mappend` (Digits d2 p2) = Digits (d1 * p2 + d2) (p1 * p2) sumDigitsF :: Foldable f => f Int -> Integer sumDigitsF cont = value $ foldMap (\x -> Digits (fromIntegral x) 10) cont test2 = sumDigitsF [0, 4, 5, 0, 3] I'd stick with first implementation. Although it builds unnecessary data structure, it's shorter and simpler to understand (as far as a reader understands Traversable).
Recursion using lists - Haskell
I am trying to write a recursive function that will take a list containing a list of integers as an input and return a tuple of type ([Int],Int). ([Int],Int) This is for a "board game" where you are supplied with a board: [[5,4,3,8,6], [0,2,1,0,7], [0,1,9,4,3], [2,3,4,0,9]] This would be a board with 4 rows and 5 columns. The numbers inside the list are "coin values". The objective of this board game would be to go from the top of the list to the bottom collecting the coins. You are able to start in any position from the top row and to move down, you can go straight down, or diagonally to left or right. You would want the path that will give you the largest total coin values. I've created a first function where you input a list of paths [([Int],Int)] and it returns the path ([Int],Int) with maximum coin value. Now I need to create a function to actually generate the list of paths that I will input into the first function. I know that I will have to use recursion. I will input the board (like one above) and a starting column. I will have to take the column number and then create a list of all possible paths. If I start with a column number, my next possible steps are positions (in the next row)- same column number, column num -1 and column num +1. I would need to recursively call this until I reach the bottom. How would I be able to store these path steps as I go and then store the final - list of all possible paths? ([Int],Int) - [Int] is the position in list / column numbers or the rows and the Int is the coin value. I'm new to haskell and while I understand what I have to do, it's really difficult to write the code.
You don't "store" intermediate values in some variable in idiomatic functional code. Rather, you keep them as an accumulating parameter which you pass along using a function such as foldr. http://hackage.haskell.org/packages/archive/base/latest/doc/html/Prelude.html#v:foldr
I guess I am now in a position to (easily) adapt my answer for another question to this one. I listed the allowed index combinations and mapped the board to them. (pat's comment helped me improve index_combinations) *Main> :load "new1.hs" [1 of 1] Compiling Main ( new1.hs, interpreted ) Ok, modules loaded: Main. *Main> result ([8,7,4,9],28) *Main> path [3,4,3,4] import Data.List import Data.Ord import Data.Maybe r = [[5,4,3,8,6], [0,2,1,0,7], [0,1,9,4,3], [2,3,4,0,9]] r1 = r !! 0 r2 = r !! 1 r3 = r !! 2 r4 = r !! 3 index_combinations = [[a,b,c,d] | a <- [0..4], b <- [max 0 (a-1)..min 4 (a+1)], c <- [max 0 (b-1)..min 4 (b+1)], d <- [max 0 (c-1)..min 4 (c+1)]] mapR xs = [r1 !! (xs !! 0), r2 !! (xs !! 1), r3 !! (xs !! 2), r4 !! (xs !! 3)] r_combinations = map mapR index_combinations r_combinations_summed = zip r_combinations $ map (foldr (+) 0) r_combinations result = maximumBy (comparing snd) r_combinations_summed path = index_combinations !! fromJust (elemIndex result r_combinations_summed)
If you're interested in using my package grid (userguide) here as an example to get you started. (And if you don't want to use it, you may find some of the source code helpful.) Create a grid with 4 rows and 5 columns. λ> :m + Math.Geometry.Grid λ> let g = rectSquareGrid 4 5 λ> indices g [(0,0),(0,1),(0,2),(0,3),(1,0),(1,1),(1,2),(1,3),(2,0),(2,1),(2,2),(2,3),(3,0),(3,1),(3,2),(3,3),(4,0),(4,1),(4,2),(4,3)] We want to be able to map "coin values" to grid positions, so we'll create a GridMap. λ> :m + Math.Geometry.GridMap λ> let m = lazyGridMap g [5,4,3,8,6,0,2,1,0,7,0,1,9,4,3,2,3,4,0,9] λ> m lazyGridMap (rectSquareGrid 4 5) [5,4,3,8,6,0,2,1,0,7,0,1,9,4,3,2,3,4,0,9] λ> toList m [((0,0),5),((0,1),4),((0,2),3),((0,3),8),((1,0),6),((1,1),0),((1,2),2),((1,3),1),((2,0),0),((2,1),7),((2,2),0),((2,3),1),((3,0),9),((3,1),4),((3,2),3),((3,3),2),((4,0),3),((4,1),4),((4,2),0),((4,3),9)] We can find out the neighbours of any cell in the grid, but for your application, we run into a bit of a problem: my RectSquareGrid type doesn't allow diagonal moves. λ> neighbours (1,2) m [(0,2),(1,3),(2,2),(1,1)] Now, I'd be happy to create a new type of Grid that would meet your needs. Alternatively, you could write your own function which would include diagonal neighbours: λ> let neighbours2 (x, y) g = filter (`inGrid` g) [(x-1,y-1), (x-1,y), (x-1,y+1), (x,y-1), (x,y+1), (x+1,y-1), (x+1,y), (x+1,y+1)] λ> neighbours2 (1,2) m [(0,1),(0,2),(0,3),(1,1),(1,3),(2,1),(2,2),(2,3)] But you're only interested in allowing downward moves, either straight down or diagonal, so here's a more useful function: λ> let allowedMoves (x, y) g = filter (`inGrid` g) [(x+1,y-1), (x+1,y), (x+1,y+1)] λ> allowedMoves (1,2) m [(2,1),(2,2),(2,3)] So now we can write a function that gives you all possible paths from a given index to the bottom row of the grid. allPathsFrom a g | fst a == fst (size g) = [[a]] | otherwise = Prelude.map (a:) xs where xs = concatMap (\x -> allPathsFrom x g) ys ys = allowedMoves a g For example: λ> allPathsFrom (0,1) m [[(0,1),(1,0),(2,0),(3,0),(4,0)],[(0,1),(1,0),(2,0),(3,0),(4,1)],[(0,1),(1,0),(2,0),(3,1),(4,0)],[(0,1),(1,0),(2,0),(3,1),(4,1)],[(0,1),(1,0),(2,0),(3,1),(4,2)],[(0,1),(1,0),(2,1),(3,0),(4,0)],[(0,1),(1,0),(2,1),(3,0),(4,1)],[(0,1),(1,0),(2,1),(3,1),(4,0)],[(0,1),(1,0),(2,1),(3,1),(4,1)],[(0,1),(1,0),(2,1),(3,1),(4,2)],[(0,1),(1,0),(2,1),(3,2),(4,1)],[(0,1),(1,0),(2,1),(3,2),(4,2)],[(0,1),(1,0),(2,1),(3,2),(4,3)],[(0,1),(1,1),(2,0),(3,0),(4,0)],[(0,1),(1,1),(2,0),(3,0),(4,1)],[(0,1),(1,1),(2,0),(3,1),(4,0)],[(0,1),(1,1),(2,0),(3,1),(4,1)],[(0,1),(1,1),(2,0),(3,1),(4,2)],[(0,1),(1,1),(2,1),(3,0),(4,0)],[(0,1),(1,1),(2,1),(3,0),(4,1)],[(0,1),(1,1),(2,1),(3,1),(4,0)],[(0,1),(1,1),(2,1),(3,1),(4,1)],[(0,1),(1,1),(2,1),(3,1),(4,2)],[(0,1),(1,1),(2,1),(3,2),(4,1)],[(0,1),(1,1),(2,1),(3,2),(4,2)],[(0,1),(1,1),(2,1),(3,2),(4,3)],[(0,1),(1,1),(2,2),(3,1),(4,0)],[(0,1),(1,1),(2,2),(3,1),(4,1)],[(0,1),(1,1),(2,2),(3,1),(4,2)],[(0,1),(1,1),(2,2),(3,2),(4,1)],[(0,1),(1,1),(2,2),(3,2),(4,2)],[(0,1),(1,1),(2,2),(3,2),(4,3)],[(0,1),(1,1),(2,2),(3,3),(4,2)],[(0,1),(1,1),(2,2),(3,3),(4,3)],[(0,1),(1,2),(2,1),(3,0),(4,0)],[(0,1),(1,2),(2,1),(3,0),(4,1)],[(0,1),(1,2),(2,1),(3,1),(4,0)],[(0,1),(1,2),(2,1),(3,1),(4,1)],[(0,1),(1,2),(2,1),(3,1),(4,2)],[(0,1),(1,2),(2,1),(3,2),(4,1)],[(0,1),(1,2),(2,1),(3,2),(4,2)],[(0,1),(1,2),(2,1),(3,2),(4,3)],[(0,1),(1,2),(2,2),(3,1),(4,0)],[(0,1),(1,2),(2,2),(3,1),(4,1)],[(0,1),(1,2),(2,2),(3,1),(4,2)],[(0,1),(1,2),(2,2),(3,2),(4,1)],[(0,1),(1,2),(2,2),(3,2),(4,2)],[(0,1),(1,2),(2,2),(3,2),(4,3)],[(0,1),(1,2),(2,2),(3,3),(4,2)],[(0,1),(1,2),(2,2),(3,3),(4,3)],[(0,1),(1,2),(2,3),(3,2),(4,1)],[(0,1),(1,2),(2,3),(3,2),(4,2)],[(0,1),(1,2),(2,3),(3,2),(4,3)],[(0,1),(1,2),(2,3),(3,3),(4,2)],[(0,1),(1,2),(2,3),(3,3),(4,3)]] Note that since GridMaps are also Grids, we can invoke all of the above functions on m or g. λ> allPathsFrom (0,1) m Let me know (amy at nualeargais dot ie) if you would like me to add a grid allowing diagonal moves to my grid package.
Convert list of Integers into one Int (like concat) in haskell
Pretty much what the title says. I have a list of Integers like so: [1,2,3]. I want to change this in to the Integer 123. My first thought was concat but that doesn't work because it's of the wrong type, I've tried various things but usually I just end up returning the same list. Any help greatly appreciated. Also I have found a way to print the right thing (putStr) except I want the type to be Integer and putStr doesn't do that.
You can use foldl to combine all the elements of a list: fromDigits = foldl addDigit 0 where addDigit num d = 10*num + d The addDigit function is called by foldl to add the digits, one after another, starting from the leftmost one. *Main> fromDigits [1,2,3] 123 Edit: foldl walks through the list from left to right, adding the elements to accumulate some value. The second argument of foldl, 0 in this case, is the starting value of the process. In the first step, that starting value is combined with 1, the first element of the list, by calling addDigit 0 1. This results in 10*0+1 = 1. In the next step this 1 is combined with the second element of the list, by addDigit 1 2, giving 10*1+2 = 12. Then this is combined with the third element of the list, by addDigit 12 3, resulting in 10*12+3 = 123. So pointlessly multiplying by zero is just the first step, in the following steps the multiplication is actually needed to add the new digits "to the end" of the number getting accumulated.
You could concat the string representations of the numbers, and then read them back, like so: joiner :: [Integer] -> Integer joiner = read . concatMap show
This worked pretty well for me. read (concat (map show (x:xs))) :: Int How function reads: Step 1 - convert each int in the list to a string (map show (x:xs)) Step 2 - combine each of those strings together (concat (step 1)) Step 3 - read the string as the type of int read (step 2) :: Int
Use read and also intToDigit: joinInt :: [Int] -> Int joinInt l = read $ map intToDigit l Has the advantage (or disadvantage) of puking on multi-digit numbers.
Another idea would be to say: the last digit counts for 1, the next-to last counts for 10, the digit before that counts for 100, etcetera. So to convert a list of digits to a number, you need to reverse it (in order to start at the back), multiply the digits together with the corresponding powers of ten, and add the result together. To reverse a list, use reverse, to get the powers of ten you can use iterate (*10) 1 (try it in GHCi or Hugs!), to multiply corresponding digits of two lists use zipWith (*) and to add everything together, use sum - it really helps to know a few library functions! Putting the bits together, you get fromDigits xs = sum (zipWith (*) (reverse xs) (iterate (*10) 1)) Example of evaluation: fromDigits [1,2,3,4] ==> sum (zipWith (*) (reverse [1,2,3,4]) [1,10,100,1000, ....] ==> sum (zipWith (*) [4,3,2,1] [1,10,100,1000, ....]) ==> sum [4 * 1, 3 * 10, 2 * 100, 1 * 1000] ==> 4 + 30 + 200 + 1000 ==> 1234 However, this solution is slower than the ones with foldl, due to the call to reverse and since you're building up those powers of ten only to use them directly again. On the plus side, this way of building numbers is closer to the way people usually think (at least I do!), while the foldl-solutions in essence use Horner's rule.
join :: Integral a => [a] -> a join [x] = x join (x:xs) = (x * (10 ^ long)) + join(xs) where long = length(x:xs) We can define the function called join, that given a list of Integral numbers it can return another Integral number. We are using recursion to separate the head of the given list with the rest of the list and we use pattern matching to define an edge condition so that the recursion can end.
As for how to print the number, instead of putStr n just try putStr (show n) The reasoning is that putStr can only print strings. So you need to convert the number to a string before passing it in. You may also want to try the print function from Prelude. This one can print anything that is "showable" (any instance of class Show), not only Strings. But be aware that print n corresponds (roughly) to putStrLn (show n), not putStr (show n).
I'm no expert in Haskell, but this is the easiest way I can think of for a solution to this problem that doesn't involve using any other external functions. concatDigits :: [Int] -> Int concatDigits [] = 0 concatDigits xs = concatReversed (reverseDigits xs) 1 reverseDigits :: [Int] -> [Int] reverseDigits [] = [] reverseDigits (x:xs) = (reverseDigits xs) ++ [x] concatReversed :: [Int] -> Int -> Int concatReversed [] d = 0 concatReversed (x:xs) d = (x*d) + concatReversed xs (d*10) As you can see, I've assumed you're trying to concat a list of digits. If by any chance this is not your case, I'm pretty sure this won't work. :( In my solution, first of all I've defined a function called reverseDigits, which reverses the original list. For example [1,2,3] to [3,2,1] After that, I use a concatReversed function which takes a list of digits and number d, which is the result of ten power the first digit on the list position. If the list is empty it returns 0, and if not, it returns the first digit on the list times d, plus the call to concatReversed passing the rest of the list and d times 10. Hope the code speaks for itself, because I think my poor English explanation wasn't very helpful. Edit After a long time, I see my solution is very messy, as it requires reversing the list in order to be able to multiply each digit by 10 power the index of the digit in the list, from right to left. Now knowing tuples, I see that a much better approach is to have a function that receives both the accumulated converted part, and the remainder of the list, so in each invocation in multiplies the accumulated part by 10, and then adds the current digit. concatDigits :: [Int] -> Int concatDigits xs = aggregate (xs, 0) where aggregate :: ([Int], Int) -> Int aggregate ([], acc) = acc aggregate (x:xs, acc) = aggregate (xs, (acc * 10 + x))