Related
https://wiki.haskell.org/99_questions/1_to_10
regarding the solution to Question 9
pack :: Eq a => [a] -> [[a]] -- problem 9
pack [] = []
pack (x:xs) = (x:first) : pack rest
where
getReps [] = ([], [])
getReps (y:ys)
| y == x = let (f,r) = getReps ys in (y:f, r)
| otherwise = ([], (y:ys))
(first,rest) = getReps xs
--input
pack ['a', 'a', 'a', 'a', 'b', 'c', 'c', 'a','a', 'd', 'e', 'e', 'e', 'e']
--output
["aaaa","b","cc","aa","d","eeee"]
whats going on here: (x:first), i can see that rest is being passed pack, but i don't understand the bit before that.
getReps is a function specific to each iteration of pack, as it closes over the current values of x and xs.
The first call to pack "aaaabccaadeeee" results in a call to getReps "aaabccaadeeee". getReps will return ("aaa", "bccaadeeee"). Effectively, pack self splits off the first 'a' (the value of x), and getReps separates the rest of the 'a's from the value of xs. Thus, the final "value" of pack "aaaabccaadeeee" is ('a':"aaa") : pack "bccaadeeee".
I am trying to compare certain aspects of two linked lists.
The arrays both have format (assume a...p derive Eq):
linkedList1 = [(a, b, c, d), (e, f, g, h)]
linkedList2 = [(a, f, k, l), (a, b, g, m)]
What I hope to accomplish here is as follows:
I want to input an index, to be referenced in each quadruple.
For that index, I want to find out, for each quadruple in linkedList 1, how many times the value at that index is identical to the value at the same index in each of the quadruples in linkedList 2.
For example on the above linked lists, inputting the two linkedlists and the index 1 would return a value of 2 as the second value in the first quadruple of linkedList1 = the second value in the second quadruple of linkedList2.
Inputting the two linkedlists and the index 3, however, will return 0 as none of the 4th letters in the quadruples of the 1st linked list match any of the 4th letters in the suadruples of the 2nd linked list.
Any suggestions how to achieve this/get started? I've been trying to implement a recursive map function but it's been pretty choppy progress.
This is what I came up with:
howManyEqualAtIndex l1 l2 0
=> 2
howManyEqualAtIndex l1 l2 1
=> 2
howManyEqualAtIndex l1 l2 2
=> 1
howManyEqualAtIndex l1 l2 3
=> 0
l1 = [('a', 'b', 'c', 'd'), ('e', 'f', 'g', 'h')]
l2 = [('a', 'f', 'k', 'l'), ('a', 'b', 'g', 'm')]
--List comprehension checking all combinations.
--Predicate that they are equal
howManyEqualAtIndex xs ys idx = length [() | x<-xs, y<-ys, equalAt x y idx]
--Hardcoded for quads, can be extended to other n-tuples,
--or changed to list version commented out below
equalAt (a,_,_,_) (b,_,_,_) 0 = a == b
equalAt (_,a,_,_) (_,b,_,_) 1 = a == b
equalAt (_,_,a,_) (_,_,b,_) 2 = a == b
equalAt (_,_,_,a) (_,_,_,b) 3 = a == b
--equalAt :: (Eq a) => [a] -> [a] -> Int -> Bool
--equalAt xs ys idx = xs !! idx == ys !! idx
The two-dimensional list looks like:
1 | 2 | 3
- - - - -
4 | 5 | 6
- - - - -
7 | 8 | 9
Or in pure haskell
[ [1,2,3], [4,5,6], [7,8,9] ]
The expected output for diagonals [ [1,2,3], [4,5,6], [7,8,9] ] is
[ [1], [4, 2], [7, 5, 3], [8, 6], [9] ]
Writing allDiagonals (to include anti-diagonals) is then trivial:
allDiagonals :: [[a]] -> [[a]]
allDiagonals xss = (diagonals xss) ++ (diagonals (rotate90 xss))
My research on this problem
Similar question here at StackOverflow
Python this question is about the same problem in Python, but Python and Haskell are very different, so the answers to that question are not relevant to me.
Only one This question and answer are in Haskell, but are only about the central diagonal.
Hoogle
Searching for [[a]] -> [[a]] gave me no interesting result.
Independent thinking
I think the the indexing follows a kind of count in base x where x is the number of dimensions in the matrix, look at:
1 | 2
- - -
3 | 4
The diagonals are [ [1], [3, 2], [4] ]
1 can be found at matrix[0][0]
3 can be found at matrix[1][0]
2 can be found at matrix[0][1]
1 can be found at matrix[1][1]
That is similar to counting in base 2 up to 3, that is the matrix size minus one. But this is far too vague to be translated into code.
Starting with universe-base-1.0.2.1, you may simply call the diagonals function:
Data.Universe.Helpers> diagonals [ [1,2,3], [4,5,6], [7,8,9] ]
[[1],[4,2],[7,5,3],[8,6],[9]]
The implementation in full looks like this:
diagonals :: [[a]] -> [[a]]
diagonals = tail . go [] where
-- it is critical for some applications that we start producing answers
-- before inspecting es_
go b es_ = [h | h:_ <- b] : case es_ of
[] -> transpose ts
e:es -> go (e:ts) es
where ts = [t | _:t <- b]
The key idea is that we keep two lists: a rectangular chunk we haven't started inspecting, and a pentagonal chunk (a rectangle with the top left triangle cut out!) that we have. For the pentagonal chunk, picking out the first element from each list gives us another diagonal. Then we can add a fresh row from the rectangular, un-inspected chunk to what's left after we delete that diagonal.
The implementation may look a bit unnatural, but it's intended to be quite efficient and lazy: the only thing we do to lists is destructure them into a head and tail, so this should be O(n) in the total number of elements in the matrix; and we produce elements as soon as we finish the destructuring, so it's quite lazy/friendly to garbage collection. It also works well with infinitely large matrices.
(I pushed this release just for you: the previous closest thing you could get was using diagonal, which would only give you [1,4,2,7,5,3,8,6,9] without the extra structure you want.)
Here is a recursive version, assuming that the input is always well-formed:
diagonals [] = []
diagonals ([]:xss) = xss
diagonals xss = zipWith (++) (map ((:[]) . head) xss ++ repeat [])
([]:(diagonals (map tail xss)))
It works recursively, going from column to column. The values from one column are combined with the diagonals from the matrix reduced by one column, shifted by one row to actually get the diagonals. Hope this explanation makes sense.
For illustration:
diagonals [[1,2,3],[4,5,6],[7,8,9]]
= zipWith (++) [[1],[4],[7],[],[],...] [[],[2],[5,3],[8,6],[9]]
= [[1],[4,2],[7,5,3],[8,6],[9]]
Another version that works on the rows instead of the columns, but based on the same idea:
diagonals [] = repeat []
diagonals (xs:xss) = takeWhile (not . null) $
zipWith (++) (map (:[]) xs ++ repeat [])
([]:diagonals xss)
Compared to the specified result, the resulting diagonals are reversed. This can of course be fixed by applying map reverse.
import Data.List
rotate90 = reverse . transpose
rotate180 = rotate90 . rotate90
diagonals = (++) <$> transpose . zipWith drop [0..]
<*> transpose . zipWith drop [1..] . rotate180
It first gets the main ([1,5,9]) and upper diagonals ([2,6] and [3]); then the lower diagonals: [8,4] and [7].
If you care about ordering (i.e. you think it should say [4,8] instead of [8,4]), insert a map reverse . on the last line.
One another solution:
diagonals = map concat
. transpose
. zipWith (\ns xs -> ns ++ map (:[]) xs)
(iterate ([]:) [])
Basically, we turn
[1, 2, 3]
[4, 5, 6]
[7, 8, 9]
into
[[1], [2], [3]]
[[] , [4], [5], [6]]
[[] , [] , [7], [8], [9]]
then transpose and concat lists. Diagonals are in the reversed order.
But that's not very efficient and doesn't work for infinite lists.
Here is one approach:
f :: [[a]] -> [[a]]
f vals =
let n = length vals
in [[(vals !! y) !! x | x <- [0..(n - 1)],
y <- [0..(n - 1)],
x + y == k]
| k <- [0 .. 2*(n-1)]]
For example, using it in GHCi:
Prelude> let f vals = [ [(vals !! y) !! x | x <- [0..(length vals) - 1], y <- [0..(length vals) - 1], x + y == k] | k <- [0 .. 2*((length vals) - 1)]]
Prelude> f [ [1,2,3], [4,5,6], [7,8,9] ]
[[1],[4,2],[7,5,3],[8,6],[9]]
Assuming a square n x n matrix, there will be n + n - 1 diagonals (this is what k iterates over) and for each diagonal, the invariant is that the row and column index sum to the diagonal value (starting with a zero index for the upper left). You can swap the item access order (swap !! y !! x with !! x !! y) to reverse the raster scanning order over the matrix.
I have a lists of list in Haskell. I want to get all the possibilities when taking one element from each list. What I have currently is
a = [ [1,2], [10,20,30], [-1,-2] ] -- as an example
whatIWant = [ [p,q,r] | p <- a!!0, q <- a!!1, r <- a!!2 ]
This does what I want. However, this is obviously not very good code, and I'm looking for a better way of writing the list comprehension so that no index number (0,1,2) shows up in the code... which is where I'm stuck.
How can I do this?
Using a function (which uses a list comprehension inside), my solution is
combinations :: [[a]] -> [[a]]
combinations [] = []
combinations [l] = map (\ x -> [x]) l
combinations (x:xs) = combine (combinations [x]) (combinations xs)
where combine a b = [ p ++ q | p <- a, q <- b ]
Example:
*Main> combinations [[1, 2, 3], [4, 5, 6]]
[[1,4],[1,5],[1,6],[2,4],[2,5],[2,6],[3,4],[3,5],[3,6]]
*Main> combinations [['a', 'b', 'c'], ['A', 'B', 'C'], ['1', '2']]
["aA1","aA2","aB1","aB2","aC1","aC2","bA1","bA2","bB1",...
"bB2","bC1","bC2","cA1","cA2","cB1","cB2","cC1","cC2"]
Edit: of course you can use the sequence function, as was suggested in the comments:
*Main> sequence [['a', 'b', 'c'], ['A', 'B', 'C'], ['1', '2']]
["aA1","aA2","aB1","aB2","aC1","aC2","bA1","bA2","bB1",...
"bB2","bC1","bC2","cA1","cA2","cB1","cB2","cC1","cC2"]
this is obviously not a good code
This is about the best way you can do it, given your constraint that the input is a list of lists.
If you use a different type, e.g. a triple of lists, then you can index structurally. E.g.
Prelude> let x#(a,b,c) = ( [1,2], [10,20,30], [-1,-2] )
Lets you write:
Prelude> [ (p,q,r) | p <- a , q <- b , r <- c ]
[(1,10,-1),(1,10,-2),(1,20,-1)
,(1,20,-2),(1,30,-1),(1,30,-2)
,(2,10,-1),(2,10,-2),(2,20,-1)
,(2,20,-2),(2,30,-1),(2,30,-2)]
Lesson: to avoid indexing, use a type whose structure captures the invariant you want to hold. Lift the dimension of the data into its type.
I am writing a function in Haskell that takes a Point and a Double that represent the center and side length of a cube, respectively.
A Point is type Point = [Double].
The function signature is getCubeFaces :: Cube -> [Face] where a Face is data Face = Face [Point] and a Cube is data Cube = Cube Point Double.
My question is, how do I go about doing this? I've tried the naive approach of
[ Face [ [-1, 1, 1], [1, 1, 1] ...
and listing all the 6 faces as described by their 8 points - but this is really ugly.
Is there a more intuitive / patterned way to go about this (without having access to a normal vector)?
First let
type Vector = Point
a <+> b = zipWith (+) a b --vector addition
a <*> b = map (*b) a --vector scalar multiplication
Then, I suggest two methods. The cubes are centered at 0, 0, 0, with side length of 2. You can later map (\face -> map (\point -> point <*> sideLength/2 <+> center). First
face :: Vector -> Vector -> Vector -> Face
face x y z = [x <+> (y <*> i) <+> (z <*> j) | i <- [-1, 1], j <- [-1, 1]]
cube :: [Face]
cube = let
axes = [[1, 0, 0], [0, 1, 0], [0, 0, 1]]
directions = zipWith (\ds i -> map (<*>i) ds) (permutations axes) (cycle [1, -1])
in map (\[x, y, z] -> face x y z) directions
And second,
cube' :: [Face]
cube' = let
points = [[x, y, z] | x <- [-1, 1], y <- [-1, 1], z <- [-1, 1]]
pair i = partition (\x -> x !! i > 0) points
in map pair [0..2] >>= (\(a, b) -> [a, b])
While the second is shorter, note that the first allows you more flexibility when you figure out that you actually wanted type Face = [Triangle].