First of all, I cannot remember the name of this repetition of list.
I have a list:
myList = [0, 1, 2]
I want to repeat list of list:
[[0,1,2],[1,2,0],...]
I know that I can do permutations myList
But it won't cover the repeated parts such as [[0,0,0],[1,1,1],[1,1,0],...]
So, my questions are what is the name given for such kind of list.
It is not permutations and it definitely is not combinations
In logic, we call it truth table, I believe.
And is there a builtin function for that in haskell?
GHCi, version 7.10.2: http://www.haskell.org/ghc/ :? for help
Prelude> :m +Control.Monad
Prelude Control.Monad> replicateM 3 [0,1,2]
[[0,0,0],[0,0,1],[0,0,2],[0,1,0],[0,1,1],[0,1,2],[0,2,0],[0,2,1],[0,2,2],[1,0,0],[1,0,1],[1,0,2],[1,1,0],[1,1,1],[1,1,2],[1,2,0],[1,2,1],[1,2,2],[2,0,0],[2,0,1],[2,0,2],[2,1,0],[2,1,1],[2,1,2],[2,2,0],[2,2,1],[2,2,2]]
Note that basically, the length of the list of permitted values needs in no way be connected to the length of each list of choices.
with list comprehension
x = [0,1,2]
[[a,b,c] | a<-x, b<-x, c<-x]
[[0,0,0],[0,0,1],[0,0,2],[0,1,0],[0,1,1],[0,1,2],[0,2,0],[0,2,1],[0,2,2],
[1,0,0],[1,0,1],[1,0,2],[1,1,0],[1,1,1],[1,1,2],[1,2,0],[1,2,1],[1,2,2],
[2,0,0],[2,0,1],[2,0,2],[2,1,0],[2,1,1],[2,1,2],[2,2,0],[2,2,1],[2,2,2]]
Related
I'm trying to learn OCaml since I'm new to the language and I stumbled across this problem where I can't seem to find a way to see, in a function where I need to merge 2 kinds of these lists, if there is already an element with a key, and if so how to join the elements that come after. Would appreciate any guidance.
For example if I have:
l1: [(k, [e]); (ka, [])]
l2: [(k, [f; g])]
How can I end up with:
fl: [(k, [e; f; g]); (ka, [])]
Basically, how can I filter the key k from both lists while making their elements combine.
There are functions in the standard OCaml library for dealing with lists of pairs where the first element of each pair is a key. You will find them described here: https://ocaml.org/releases/4.12/api/List.html under Association lists.
I will repeat what #ivg says. This is not how you want to solve your problem if you have more than just a few pairs to work with.
First of all, using lists as mappings is a bad idea. It is much better to use dedicated data structures such as maps and hash tables.
Answering your question directly, you can concatenate two lists using the (#) operator, e.g.,
# [1;2;3] # [4;5;6];;
- : int list = [1; 2; 3; 4; 5; 6]
If you don't want repetitive elements when you merge then, and I feel like I repeat myself, it is bad to use lists for sets, it is better to use dedicated data structures such as sets and hash sets. But if you want to continue, then you can merge two lists without repetitions by checking if an element is already in the list before prepending to it. Easy to implement but hard to run, in a sense that it takes quadratic time to merge two lists this way.
If you still want to stick with the list of pairs, then you will find that the List.assoc function is useful, as it finds a value by key. The overall algorithm would be, given two lists, xs and ys, fold over elements of ys using xs as the initial value acc, and for each (ky,y) in ys if ky is already in acc, find the associated with ky value x and remove (List.remove_assoc) it, then merge x and y and prepend the merged value with the acc list, otherwise (if it is not in acc) just prepend (ky,y) to acc`. Note that this algorithm doesn't preserve order, so if it matters you need something more complex. Also, if your keys are sorted you can make it a little bit more efficient and easier to implement.
I guess you're doing this to practice with list.
What I would do is store the already found keys in an accumulator
let mergePairs yourList =
let rec aux accKeys = function
| [] -> []
| x :: xs -> let k,v = x in if (* k in accKeys *) then aux accKeys xs (*we suppress already
existing keys*)
else (k, v # (* get all the list of the other pairs with key = k in xs*))
:: aux (k::accKeys) xs
in aux [] yourList;;
I have a list of (String, Int) pairs and am struggling to figure out how to sort the list by the snd field (Int). I am not allowed to use higher order functions or recursion which makes it more difficult.
For example, I have
[("aaaaa", 5),("bghdfe", 6),("dddr",4)]
and would like to sort it into
[("dddr",4),("aaaaa", 5),("bghdfe", 6)].
Edit:
I understand that the sort may not be possible without higher order functions, what I really need is to find the element with the minimum length (the snd field), so is there a way to find the minimum number and then take the fst field of the list's element at that index? If that way works better I am unsure about how to find the index of that minimum number however.
The task seems to be impossible, since you can't write a sort without recursion in Haskell. This means, you must use sort, which is usually something like sortBy compare and thus you have it.
But if you are allowed to use sort you can do it by first reversing all tuples, sorting the resulting list and reversing the tuples in the result again. This should be possible to do in a few nested list comprehension, so technically no higher order functions are needed.
After you have given more details, I'd do
homework list = snd (minimum [ (s,f) | (f,s) <- list ])
Without higher order functions or recursion all you have left, technically, is list comprehensions. Thus we define
-- sortBy (comparing snd) >>> take 1 >>> listToMaybe >>> fmap fst
-- ~= minimumBy (comparing snd) >>> fst
foo :: Ord b => [(a,b)] -> Maybe a
foo xs = case [ a | (a,b) <- xs
, null [ () | (_c,d) <- xs, d < b]]
of (a:_) -> Just a
[] -> Nothing
I am answering question seven of Haskell's 99 questions. However, I have come to the point where they define the type
data NestedList a = Elem a | List [NestedList a]
and it, from my understanding, will not handle empty lists (ie. []).
But in their example tests they show
*Main> flatten (List [])
[]
Does this type cover empty lists? If so, why?
If it does not, and is a mistake of the websites, how would one write a nested list type that handles empty lists?
The datatype NestedList a contains either elements of type Elem a, or elements of type List [NestedList a].
The first of these, you already seem to understand. The second one, though, has as its argument a list (the normal sort) of NestedList a's. This can be any list, including []. Thus, List [] is a valid NestedList, as would be List[Elem 5], or List [Elem 5, List [Elem 3, Elem 2] ].
I have two lists of numbers. In each are the numbers [1,2,3,4] but in one there is an extra fifth number eg.
list1 = [1,2,3,4]
list2 = [1,2,3,4,5]
I need to enforce that list2 is the same as list1, by either removing the 5th number from list2 or replacing list2 with another copy of list1?
Can this be done?
This question is worded a bit strangely. If you're looking to mutate one of the lists, then the answer is no: that is not possible. Otherwise, you can of course just use list1 instead of list2 anywhere you need it.
Data.List provides the intersect method, which seems exactly what's being requested.
The most easy and performant way to enforce that list2 is the same as list1 would be to say
let list2 = list1 in .......
This would not even require that the list elements are comparable.
[ x | x <- list1, x `elem` list2 ]
and here's another one though I like Louis_Wasserman's solution most
filter (`elem` [1..4]) [1..12]
>>> [1,2,3,4]
or
filter (flip elem [1..4]) [1..12]
>>> [1,2,3,4]
fliter (\x ->x `elem` [1..4]) [1..12]
>>> [1,2,3,4]
if list two is irrelevant why do you use it in the first place ??
and another one came to my mind:
const [1..4] list2
>>> [1,2,3,4]
the last one just ignores the second list and fills in the first.
Is there a straight-forward combination of standard higher-order functions to count the unique elements in a list?
For example the result for
[1, 1, 4, 0, 4, 4]
would be something like
[(1,2), (4,3), (0,1)]
Using Data.Map and tuple sections:
count = Map.fromListWith (+) . map (, 1)
(Add Map.toList if you need a list.)
If order is not important this works:
map (\xs#(x:_) -> (x, length xs)) . group . sort
group . sort will give you a list of lists where all elements that are equal to each other are grouped into the same sublist (without sort, only consecutive equal elements would be grouped together). The map then turns each sublist into a (element, lengthOfSublist)-tuple.
If you want to order the result by first occurrence, you can use zip before the sort to add an index to each element, then, after grouping, sort again by that index and then remove the index.
The simplest thing would be to sort the items into order, use "group" to put them into sub-lists of equal elements, and then count the items in each sub-list.
map (\xs -> (head xs, length xs)) . group . sort
If the list contains only integers, you could also use
import qualified Data.IntMap as I
countElems1 :: [Int] -> [(Int, Int)]
countElems1 = I.toList . foldr (\k -> I.insertWith (+) k 1) I.empty
(Remember to compile with optimization though, otherwise this will be 2x slower than the group . sort method. With -O2 it is slightly faster by 14%.)
You could also use one of the multiset packages which makes the function as simple as
import qualified Math.Combinatorics.Multiset as S
countElems4 = S.toCounts . S.fromList
but being less efficient.
All of the above solutions ignore the original order.
What your talking about is just run length encoding on sorted data: the free online book Real World Haskell has a great example of this. You will want to sort the list before you put it through the runLengthEncoder.