Erlang lists:filter returns "\n\f" - functional-programming

I'm working on a school project in a functional programming class. The project is about determining if a set of dominos (represented as a list of tuples of two numbers from 1-6) can be put end to end. I'm ok on the problem, but I'm running into an issue where lists:filter is returning the string "\n\f" instead of a list like it says in the documentation.
I couldn't find anything online, and was wondering if any of you had any ideas.
Thanks!
Here is my code. The issue is in the check_dominos() function.
-module(challenge).
-export([test/0, check_dominos/1]).
% If there is an even number of each number, true
% else, false
extract_numbers([]) -> [];
extract_numbers([{First, Second} | T]) -> [First] ++ [Second] ++ extract_numbers(T).
add_matching_numbers(_Previous, []) -> [];
add_matching_numbers(Previous, [First | T]) when Previous =:= First-> [Previous + First | add_matching_numbers(First, T)];
add_matching_numbers(_Previous, [First | T]) -> add_matching_numbers(First, T).
check_dominos(Dominos) ->
All_Numbers = extract_numbers(Dominos),
Sorted_Numbers = lists:sort(All_Numbers),
Accumulated_Numbers = add_matching_numbers(0, Sorted_Numbers) ,
Filter_Lambda = fun(Num) -> Num rem 2 == 0 end,
Result = lists:filter(Filter_Lambda, Accumulated_Numbers),
Result.
% Still working on the logic of this part
%case length(Accumulated_Numbers) =:= length(Result) of
% true -> true;
% _ -> false
%end.
test() ->
Test_1 = [{1, 3}, {3, 2}, {2, 1}], % Already in order
Test_2 = [{5, 2}, {5, 6}, {6, 3}, {1, 4}], % Shouldn't work
Test_3 = [{2, 6}, {3, 5}, {1, 4}, {3, 4}, {6, 1}, {2, 5}], % Should work
true = check_dominos(Test_1),
false = check_dominos(Test_2),
true = check_dominos(Test_3).

Erlang strings are lists of character codes, and by default Erlang shell tries to display lists of integers as strings. To change this behaviour call shell:strings(false). before running your program.

The previous answerer is correct. Any list containing only numbers that correspond to printable characters, will display as a string. The result of your
Accumulated_Numbers = add_matching_numbers(0, Sorted_Numbers)
on Test_2 is "\n\f", but displayed as a list it is [10, 12]. Try typing [10, 12]. in an interactive erlang shell and you will indeed see it displays "\n\f".
Try:
[7].
in an interactive Erlang shell. For me it displays:
[7]
Try:
[8].
Displays:
"\t"
N.B. The numbers 8 through 13 are printable characters, as are (some of?) the numbers 32 to 255. Might be some gaps in there. If you want to see the numeric value of a printable character, use a dollar sign, e.g. $\n. prints 10.
That said, with your current way of going about things, you won't be able to get an answer with add_matching_numbers as it stands. It drops a value whenever it doesn't match the next item in the sorted list, which doesn't tell you if you had any unmatched items. The result of [10,12] on List_2 tells of this: it is a list of even numbers, like the other results.
Good luck on finding your solution.

Related

Prolog: Splitting a number into a sequence of increasing integers

After doing some Prolog in uni and doing some exercises I decided to go along somewhat further although I got to admit I don't understand recursion that well, I get the concept and idea but how to code it, is still a question for me. So that's why I was curious if anyone knows how to help tackle this problem.
The idea is given a number e.g. 45, check whether it is possible to make a list starting with 1 going n+1 into the list and if the sum of the list is the same as the given number.
So for 45, [1,2,3,4,5,6,7,8,9] would be correct.
So far I tried looking at the [sum_list/2][1] implemented in Prolog itself but that only checks whether a list is the same as the number it follows.
So given a predicate lijstSom(L,S) (dutch for listSum), given
?- lijstSom(L, 45)
L = [1,2,3,4,5,6,7,8,9];
False
My Idea was something along the line of for example if S = 45, doing steps of the numbers (increasing by 1) and subtracting it of S, if 0 is the remainder, return the list, else return false.
But for that you need counters and I find it rather hard to grasp that in recursion.
EDIT:
Steps in recursion.
Base case empty list, 0 (counter nr, that is minus S), 45 (S, the remainder)
[1], 1, 44
[1,2], 2, 42
[1,2,3], 3, 39
I'm not sure how to read the example
?- lijstSom(L, 45)
L = [1,2,3,4,5,6,7,8,9],
False
...but think of the predicate lijstSom(List, Sum) as relating certain lists of integers to their sum, as opposed to computing the sum of lists of integers. Why "certain lists"? Because we have the constraint that the integers in the list of integers must be monotonically increasing in increments of 1, starting from 1.
You can thus ask the Prolog Processor the following:
"Say something about the relationship between the first argument of lijstSom/2 and the second argument lijstSom/2 (assuming the first is a list of monotonically increasing integers, and the second an integer):
lijstSom([1,2,3], Sum)
... should return true (because yes, there is at least one solution) and give Sum = 6 (because it constructs the solution, too ... we are some corner of Construtivism here.
lijstSom(L, 6)
... should return true (because yes, there is at least one solution) and give the solution [1,2,3].
lijstSom([1,2,3], 6)
... should return true (because yes, [1,2,3] has a sum 6); no further information is needed.
lijstSom(L, S)
... should an infinite series of true and pairs of solution ("generate the solutions").
L = [1], S = 1;
L = [1,2], S = 3;
L = [1,2,3], S = 6;
...
lijstSom([1,2,3], 7)
...should return false ("fail") because 7 is not in a relation lijstSom with [1,2,3] as 7 =/= 1+2+3.
One might even want things to have Prolog Processor say something interesting about:
lijstSom([1,2,X], 6)
X = 3
or even
lijstSom([1,2,X], S)
X = 3
S = 6
In fact, lijstSom/2 as near to mathematically magical as physically possible, which is to say:
Have unrestricted access to the full table of list<->sum relationships floating somewhere in Platonic Math Space.
Be able to find the correct entry in seriously less than infinite number of steps.
And output it.
Of course we are restricted to polynomial algorithms of low exponent and finite number of dstinguishable symbols for eminently practical reasons. Sucks!
So, first define lijstSom(L,S) using an inductive definition:
lijstSom([a list with final value N],S) ... is true if ... lijstSom([a list],S-N and
lijstSom([],0) because the empty list has sum 0.
This is nice because it gives the recipe to reduce a list of arbitrary length down to a list of size 0 eventually while keeping full knowledge its sum!
Prolog is not good at working with the tail of lists, but good with working with the head, so we cheat & change our definition of lijstSom/2 to state that the list is given in reverse order:
lijstSom([3,2,1], 6)
Now some code.
#= is the "constain to be equal" operator from library(clpfd). To employ it, we need to issue use_module(library(clpfd)). command first.
lijstSom([],0).
lijstSom([K|Rest],N) :- lijstSom([Rest],T), T+K #= N.
The above follows the mathematical desiderate of lijstSom and allows the Prolog Processor to perform its computation: in the second clause, it can compute the values for a list of size A from the values of a list of size A-1, "falling down" the staircase of always decreasing list length until it reaches the terminating case of lijstSom([],0)..
But we haven't said anything about the monotonically decreasing-by-1 list.
Let's be more precise:
lijstSom([],0) :- !.
lijstSom([1],1) :- ! .
lijstSom([K,V|Rest],N) :- K #= V+1, T+K #= N, lijstSom([V|Rest],T).
Better!
(We have also added '!' to tell the Prolog Processor to not look for alternate solutions past this point, because we know more about the algorithm than it will ever do. Additionally, the 3rd line works, but only because I got it right after running the tests below and having them pass.)
If the checks fail, the Prolog Processor will says "false" - no solution for your input. This is exactly what we want.
But does it work? How far can we go in the "mathematic-ness" of this eminently physical machine?
Load library(clpfd) for constraints and use library(plunit) for unit tests:
Put this into a file x.pl that you can load with [x] alias consult('x') or reload with make on the Prolog REPL:
:- use_module(library(clpfd)).
lijstSom([],0) :-
format("Hit case ([],0)\n"),!.
lijstSom([1],1) :-
format("Hit case ([1],1)\n"),!.
lijstSom([K,V|Rest],N) :-
format("Called with K=~w, V=~w, Rest=~w, N=~w\n", [K,V,Rest,N]),
K #= V+1,
T+K #= N,
T #> 0, V #> 0, % needed to avoid infinite descent
lijstSom([V|Rest],T).
:- begin_tests(listsom).
test("0 verify") :- lijstSom([],0).
test("1 verify") :- lijstSom([1],1).
test("3 verify") :- lijstSom([2,1],3).
test("6 verify") :- lijstSom([3,2,1],6).
test("0 construct") :- lijstSom(L,0) , L = [].
test("1 construct") :- lijstSom(L,1) , L = [1].
test("3 construct") :- lijstSom(L,3) , L = [2,1].
test("6 construct") :- lijstSom(L,6) , L = [3,2,1].
test("0 sum") :- lijstSom([],S) , S = 0.
test("1 sum") :- lijstSom([1],S) , S = 1.
test("3 sum") :- lijstSom([2,1],S) , S = 3.
test("6 sum") :- lijstSom([3,2,1],S) , S = 6.
test("1 partial") :- lijstSom([X],1) , X = 1.
test("3 partial") :- lijstSom([X,1],3) , X = 2.
test("6 partial") :- lijstSom([X,2,1],6) , X = 3.
test("1 extreme partial") :- lijstSom([X],S) , X = 1, S = 1.
test("3 extreme partial") :- lijstSom([X,1],S) , X = 2, S = 3.
test("6 extreme partial") :- lijstSom([X,2,1],S) , X = 3, S = 6.
test("6 partial list") :- lijstSom([X|L],6) , X = 3, L = [2,1].
% Important to test the NOPES
test("bad list", fail) :- lijstSom([3,1],_).
test("bad sum", fail) :- lijstSom([3,2,1],5).
test("reversed list", fail) :- lijstSom([1,2,3],6).
test("infinite descent from 2", fail) :- lijstSom(_,2).
test("infinite descent from 9", fail) :- lijstSom(_,9).
:- end_tests(listsom).
Then
?- run_tests(listsom).
% PL-Unit: listsom ...................... done
% All 22 tests passed
What would Dijkstra say? Yeah, he would probably bitch about something.

How should I map over Maybe List?

I came away from Professor Frisby's Mostly Adequate Guide to Functional Programming with what seems to be a misconception about Maybe.
I believe:
map(add1, Just [1, 2, 3])
// => Just [2, 3, 4]
My feeling coming away from the aforementioned guide is that Maybe.map should try to call Array.map on the array, essentially returning Just(map(add1, [1, 2, 3]).
When I tried this using Sanctuary's Maybe type, and more recently Elm's Maybe type, I was disappointed to discover that neither of them support this (or, perhaps, I don't understand how they support this).
In Sanctuary,
> S.map(S.add(1), S.Just([1, 2, 3]))
! Invalid value
add :: FiniteNumber -> FiniteNumber -> FiniteNumber
^^^^^^^^^^^^
1
1) [1, 2, 3] :: Array Number, Array FiniteNumber, Array NonZeroFiniteNumber, Array Integer, Array ValidNumber
The value at position 1 is not a member of ‘FiniteNumber’.
In Elm,
> Maybe.map sqrt (Just [1, 2, 3])
-- TYPE MISMATCH --------------------------------------------- repl-temp-000.elm
The 2nd argument to function `map` is causing a mismatch.
4| Maybe.map sqrt (Just [1, 2, 3])
^^^^^^^^^^^^^^
Function `map` is expecting the 2nd argument to be:
Maybe Float
But it is:
Maybe (List number)
Similarly, I feel like I should be able to treat a Just(Just(1)) as a Just(1). On the other hand, my intuition about [[1]] is completely the opposite. Clearly, map(add1, [[1]]) should return [NaN] and not [[2]] or any other thing.
In Elm I was able to do the following:
> Maybe.map (List.map (add 1)) (Just [1, 2, 3])
Just [2,3,4] : Maybe.Maybe (List number)
Which is what I want to do, but not how I want to do it.
How should one map over Maybe List?
You have two functors to deal with: Maybe and List. What you're looking for is some way to combine them. You can simplify the Elm example you've posted by function composition:
> (Maybe.map << List.map) add1 (Just [1, 2, 3])
Just [2,3,4] : Maybe.Maybe (List number)
This is really just a short-hand of the example you posted which you said was not how you wanted to do it.
Sanctuary has a compose function, so the above would be represented as:
> S.compose(S.map, S.map)(S.add(1))(S.Just([1, 2, 3]))
Just([2, 3, 4])
Similarly, I feel like I should be able to treat a Just(Just(1)) as a Just(1)
This can be done using the join from the elm-community/maybe-extra package.
join (Just (Just 1)) == Just 1
join (Just Nothing) == Nothing
join Nothing == Nothing
Sanctuary has a join function as well, so you can do the following:
S.join(S.Just(S.Just(1))) == Just(1)
S.join(S.Just(S.Nothing)) == Nothing
S.join(S.Nothing) == Nothing
As Chad mentioned, you want to transform values nested within two functors.
Let's start by mapping over each individually to get comfortable:
> S.map(S.toUpper, ['foo', 'bar', 'baz'])
['FOO', 'BAR', 'BAZ']
> S.map(Math.sqrt, S.Just(64))
Just(8)
Let's consider the general type of map:
map :: Functor f => (a -> b) -> f a -> f b
Now, let's specialize this type for the two uses above:
map :: (String -> String) -> Array String -> Array String
map :: (Number -> Number) -> Maybe Number -> Maybe Number
So far so good. But in your case we want to map over a value of type Maybe (Array Number). We need a function with this type:
:: Maybe (Array Number) -> Maybe (Array Number)
If we map over S.Just([1, 2, 3]) we'll need to provide a function which takes [1, 2, 3]—the inner value—as an argument. So the function we provide to S.map must be a function of type Array (Number) -> Array (Number). S.map(S.add(1)) is such a function. Bringing this all together we arrive at:
> S.map(S.map(S.add(1)), S.Just([1, 2, 3]))
Just([2, 3, 4])

Return the index for a list from a list in Erlang

I've been practicing using recursion to define the index in Erlang. Here I need to implement a function to return the index for a list from a list.
eg.
([2, 4, 4], [1, 1, 2, 4, 4, 3, 4 ]) ----> 2
([1, 3], [5, 2, 2, 3, 1, 3, 5]) ----> 4
([1], [3, 2, a, {1, 1}, 1] ----> 4
Here is my code:
-module(project).
-export([index/2]).
index([X|XS],[_]) -> index([X|XS],[_],1).
index(_,[],_) -> [];
index([X|XS],[X|_], ACC) -> ACC;
index([X|XS],[_|rest],ACC) ->index([X|XS],rest,ACC+1).
I modified and coded logically but it still can not being compiled. I hope someone who can help me with it. Thanks!
Just for fun, here is an implementation that is not written a very clean way, but illustrates the techniques I think you are looking for. Note there are two basic states: "checking" and "matching".
-module(sublistmatch).
-export([check/2]).
check(Segment, List) ->
SegLen = length(Segment),
ListLen = length(List),
Index = 1,
check(Segment, List, SegLen, ListLen, Index).
check(S, S, _, _, I) ->
{ok, I};
check(_, _, SL, LL, _) when SL >= LL ->
nomatch;
check(S = [H|Ss], [H|Ls], SL, LL, I) ->
case matches(Ss, Ls) of
true -> {ok, I};
false -> check(S, Ls, SL, LL - 1, I + 1)
end;
check(S, [_|L], SL, LL, I) ->
check(S, L, SL, LL - 1, I + 1).
matches([H|S], [H|L]) -> matches(S, L);
matches([], _) -> true;
matches(_, _) -> false.
Note that this depends on knowing the lengths of both the segment you are checking for, and the current length of the remaining list to check. Consider why this is necessary. Also consider how using the utility function matches/2 gives us a natural place to explore whether an option matches, and backtracks if it does not.
In real programs you would use the standard library functions such as lists:prefix/2, lists:suffix/2, or sets:is_subset/2, or maybe some key or member operation over a gb_tree, dict, map or array depending on the situation.
To Compile the code you have to change it to:
-module(project).
-export([index/2]).
%%index([X|XS],[_]) -> index([X|XS],[_],1).
index([X|XS],List) -> index([X|XS],List,1).
%% you shuld not pass '_' as parameter it's will be marked as unbound
index(_,[],_) -> [];
index([X|XS],[X|_], ACC) -> ACC;
%%index([X|XS],[_|rest],ACC) ->index([X|XS],rest,ACC+1).
index([X|XS],[_|Rest],ACC) ->index([X|XS],Rest,ACC+1).
%% rest is an atom, it's not the case you need to use here.
%%Variables should start with upper case letter.
This code will compiled but wrong results as some cases.

Correct User Defined Version of Map Function in Mathematica?

I'm trying to create a user defined version of the Map[] function in Mathematica and I'm running into a few problems.
Here is what I have so far:
map[x_, s_List] := mapAux[x, s, {}];
mapAux[x, s, {}] := Append[{}, First[s]];
mapAux[x, Rest[s], {}];
I'm trying to use it as
map[# + 1 &, {3, 6, 8}]
but this gives a mysterious error beside the output:
Rest::normal: Nonatomic expression expected at position 1 in Rest[s].
mapAux[#1 + 1 &, {3, 6, 8}, {}]
The ideal result would be {4,7,9}. I researched the "Nonatomic expression" error and I'm not sure what it means. I'm passing a list to it, but it's just exploding!
You're not passing s or x as variables, so it's just seeing s (which is an atomic expression) rather than a list. You're definition needs to be mapAux[x_, s_, {}]:=..., which will make x and s take the values of the passed parameters.

Mathematica GraphPlot with images

I am trying to use GraphPlot function to build a Graph, where each node is an image. I wanted to display the image as my vertex. Does anybody know how to do this?
I tried something like this:
GraphPlot[ Map[If[# > 2.0 , 0, 1] &,
imgDistT, {2}],
VertexRenderingFunction -> (Inset[imgs[[#2]], #1, Center] &) ]
But this does not work.
imgs is my list of images corresponding to each vertex number.
As a sanity check, if i do this:
GraphPlot[
Map[If[# > 2.0 , 0, 1] &, imgDistT, {2}],
VertexRenderingFunction -> (Inset[Text[#2], #1, Center] &) ]
then that works and it shows me the vertex number at each node.
imgs = ExampleData /# ExampleData["TestImage"];
GraphPlot[{1 -> 4, 1 -> 5, 2 -> 3, 2 -> 4, 2 -> 5, 3 -> 4, 3 -> 5},
VertexRenderingFunction -> (Inset[Image[imgs[[#2]], ImageSize -> 100], #1] &)]
Edit
-- Infix notation joke removed --
Two possible issues:
It looks like your graph, Map[If[# > 2.0 , 0, 1] &, imgDistT, {2}], will contain zeroes and ones—but zeroes are invalid indices for the imgs array
The images may not appear properly due to scaling issues—for example, they might be really big only the white portion might be visible. Try specifying an explicit image size.
What is the output of
GraphPlot[Map[If[# > 2.0 , 0, 1] &, imgDistT, {2}],
VertexRenderingFunction -> (Module[{tmp =
Inset[Image[imgs[[#2]], ImageSize -> 10], #1, Center]},
Print[tmp]; tmp] &)]
?

Resources