Nil vs List(Nil) in a for with recursion - list

I'm learning Scala and have a quick question: Can someone please explain to me why the following two sets of code yield different results?
def grey0(n: Int): List[List[String]]={
if (n==0) List(Nil)
else for(i<-List("0","1"); j<-grey0(n-1)) yield i :: j
}
versus
def grey1(n: Int): List[List[String]]={
if (n==0) Nil
else for(i<-List("0","1"); j<-grey0(n-1)) yield i :: j
}
The first option yields the result I am looking for. What I don't understand is, why does the second option just return the empty list? I would have thought the other results would cons on to it and if anything, I would get some sort of flat list rather than a List[List[String]] (which is what I want).

In your first version grey0(0) will return a 1-element list that contains the empty list. grey0(1) will, for each element in grey0(0) create two lists, so you get a total of two lists because grey0(0) contains one list. Likewise grey0(2) will contain 4 lists because for each of the two elements in grey0(1) it creates 2 lists.
In your second version grey0(0) will return the empty list. grey0(1) will create two lists for each element in grey0(0). Since grey0(0) has 0 elements, that makes a total of 0*2=0 elements in the result.

In the first example, you create a list containing an empty list. In the second example you create just an empty list. Both can have the same type, because any list can be empty.
Nil just means empty list and it is almost equal to List() (in your example types will be inferred so both are exactly the same). List(Nil) is then like List(List()).

Related

SML counting within a pair of lists

I am trying to write a function in SML that takes in a pair of lists. The first list in the pair is a list of integers and the second list is a list of booleans. Ex: (([3, 5, 9], [true, false, false])). I am having trouble with the proper syntax to return how many times 'true' is found in the second list.
You would want to break this down.
Can you count the number of times a value is found in a list?
Can you pattern match out the second list in the tuple?
The first one can be accomplished by implementing a count function. A basic shell for that would look something like:
fun count (_, []) = ...
| count (v, (x::xs)) =
if ... then ...
else ...
For the second, well, you can see pattern-matching for binding names to the elements of a tuple in the above code.
Doing anything more would be doing your homework for you, and that would be a disservice.

How to write a prolog program that takes List1 and List2 as inputs, and the resulting list is the alternating elements of List1 and List2? [duplicate]

This question already has answers here:
Shuffle in prolog
(2 answers)
Closed 5 years ago.
This is my first attempt at using recursion over lists on a non-sample program so bare with my inexperience!
Expected Valid Queries:
mixElements([],[a,b,c], [a,b,c]).
mixElements([a,b],[],[a,b]).
mixElements([a,b,c],[d,e,f],[a,d,b,e,c,f]).
mixElements([a,b,c],[d,e,f,g,h],[a,d,b,e,c,f,g,h]).
Here I tried to create the base case for when the inputs lists are empty, the Result is simply returned.
/* Base cases */
mixElements([],[],Result).
The logic for my recursive statement is that the input lists must be at least 1 or more elements. Thus they must both be represented by [H|L] respectively for list 1 and 2. Then it will append H1 and H2 to Result to create the alternating pattern of list elements. Finally it will call mixElements with the remainder of the lists, L1 and L2, and the Result list that should now contain the first head elements of both lists.
/* Recursive case where both L1 and L2 are not empty */
mixElements([H1|L1],[H2|L2],Result) :- append(H1,H2,Result), mixElements(L1,L2,Result).
My resulting output is always "no".
When dealing with lists it's usually worthwhile considering DCGs since they yield easily readable code. It further aids readability to choose a descriptive name for the relation, say list_list_interlocked/3. Consider the following code:
list_list_interlocked(L1,L2,I) :-
phrase(interlocked(L1,L2),I).
interlocked([],[]) --> % if both input lists are empty
[]. % the resulting list is also empty
interlocked([],[H2|T2]) --> % if the first input list is empty
[H2], % the head of the second is in the list
interlocked([],T2). % the relation holds for the tail as well
interlocked([H1|T1],[]) --> % if the second input list is empty
[H1], % the head of the first is in the list
interlocked(T1,[]). % the relation holds for the tail as well
interlocked([H1|T1],[H2|T2]) --> % if both lists are non-empty
[H1,H2], % the heads are in the list
interlocked(T1,T2). % the relation holds for the tails as well
Your example queries yield the desired result:
?- list_list_interlocked([],[a,b,c],I).
I = [a,b,c]
?- list_list_interlocked([a,b],[],I).
I = [a,b]
?- list_list_interlocked([a,b,c],[d,e,f],I).
I = [a,d,b,e,c,f]
?- list_list_interlocked([a,b,c],[d,e,f,g,h],I).
I = [a,d,b,e,c,f,g,h]
Basically there are four cases here:
the first list is empty, the second list is empty, in that case the result should be empty:
mixElements([],[],[]).
the first list is empty, the second list is non-empty, in that case, the result is the second list:
mixElements([],[H2|T2],[H2|T2]).
the first list is non-empty, the second list is empty, in that case, the result is the first list:
mixElements([H1|T1],[],[H1|T1]).
finall both lists are non-empty, in that case the two first elements of the result are the heads of the list, followed by mixing the tails of the lists:
mixElements([H1|T1],[H2|T2],[H1,H2|TT]) :-
mixElements(T1,T2,TT).
Now we can put that all together into:
mixElements([],[],[]).
mixElements([],[H2|T2],[H2|T2]).
mixElements([H1|T1],[],[H1|T1]).
mixElements([H1|T1],[H2|T2],[H1,H2|TT]) :-
mixElements(T1,T2,TT).
Now we have created some redundant statements. For instance we can merge the first two statements into one, like:
mixElements([],L,L).
mixElements([H1|T1],[],[H1|T1]).
mixElements([H1|T1],[H2|T2],[H1,H2|TT]) :-
mixElements(T1,T2,TT).
I leave it as an exercise to further improve the predicate. You can for instance use cuts, but this can eliminate the multi-direction of the predicate, which is sometimes very useful.
You're using append/3 where it's not needed. When the pattern is formed by 2 lists of at least one element, you can get the result immediately, then recurse to handle the tails:
mixElements([H1|L1],[H2|L2],[H1,H2|Rest]) :-
!, mixElements(L1,L2,Rest).
mixElements(L1,L2,Rest) :- append(L1,L2,Rest).

How to read each element within a tuple from a list

I want to write a program which will read in a list of tuples, and in the tuple it will contain two elements. The first element can be an Object, and the second element will be the quantity of that Object. Just like: Mylist([{Object1,Numbers},{Object2, Numbers}]).
Then I want to read in the Numbers and print the related Object Numbers times and then store them in a list.
So if Mylist([{lol, 3},{lmao, 2}]), then I should get [lol, lol, lol, lmao, lmao] as the final result.
My thought is to first unzip those tuples (imagine if there are more than 2) into two tuples which the first one contains the Objects while the second one contains the quantity numbers.
After that read the numbers in second tuples and then print the related Object in first tuple with the exact times. But I don't know how to do this. THanks for any help!
A list comprehension can do that:
lists:flatten([lists:duplicate(N,A) || {A, N} <- L]).
If you really want printing too, use recursion:
p([]) -> [];
p([{A,N}|T]) ->
FmtString = string:join(lists:duplicate(N,"~p"), " ")++"\n",
D = lists:duplicate(N,A),
io:format(FmtString, D),
D++p(T).
This code creates a format string for io:format/2 using lists:duplicate/2 to replicate the "~p" format specifier N times, joins them with a space with string:join/2, and adds a newline. It then uses lists:duplicate/2 again to get a list of N copies of A, prints those N items using the format string, and then combines the list with the result of a recursive call to create the function result.

difference between [] and list() in python3

I thought that [] and list() were two equal ways to create a list. But if you want a list with dictionnary keys,
var = [a_dict.keys()]
doesn't work since type(var) is [dict_keys], correct syntax is :
var = list(a_dict.keys())
I couldn't find an good explanation on this behaviour. Do you have one ?
TL;DR:
list() is the same as []
list(obj) is not the same as [obj]
a_dict.keys() is a dictionary view object, it returns an object which can be iterated to yield the keys of a_dict. So this line:
[a_dict.keys()]
is saying in python "I'm making a list with one element in it" and that one element is the dict keys iterator. It's a list literal in the syntax.
Now this line:
list(a_dict.keys())
is a call to the list builtin function. This function list attempts to iterate the argument and produce a list. It's a function call in the grammar.
The equivalent list literal (actually list comprehension) would be instead:
[key for key in a_dict.keys()]
Finally, note that dictionary objects iterate by keys anyway,
list(a_dict.keys()) would usually be written more simply as as list(a_dict) instead.
Hope this helps.
[a_dict.keys()]
This one puts a single element in the list. Just as if you were to write [1]. In this case that one element is going to be a list.
list(a_dict.keys())
The constructor accepts a sequence and will add all elements of the sequence to the container.

How to check and change the value of a list?

I would like to check all list values in a list and change them if necessary.
p.e.
I want to check the next lists if there are values higher or lower then the next values:
min-value = 6
max-value = 22
mylist = ['4-8','25','16-19','21-32']
if one of the list values is below the min-value or higher then the max-value, the list values must be changed to the min-value and max-value. p.e. in example, the new list must be:
mylist = ['6-8','22','16-19','21-22']
if the entire value of the list item is below the min-value or higher then the max-value the list item can be removed.
How can I check my list values and change them?
There are two approaches. In the procedural one, you iterate over the list items and modify or skip the element:
let newlist = []
for element in mylist
" Parse element.
if ! OutsideBounds(element)
call add(newlist, AdjustBounds(element))
endif
endfor
In the functional programming approach, you use the built-in map() to modify elements (i.e. adjust the bounds), but that one cannot remove elements. So just empty those elements and then do a second pass with filter() to remove them. Note that both functions modify the original lists, so use copy() if you need to keep the original.
call filter(map(mylist, 'AdjustBounds(v:val)'), '! OutsideBounds(v:val)')
I hope I don't need to tell you how to write the AdjustBounds() and OutsideBounds() functions...