Form the route with the endpoints - c++

So let's say we are given the endpoints (A, B), (B, C), (C, D), then we can form the route A -> B -> C.
Note that the order the endpoints are given is random. So (A, B), (C, D), (B, C) would also have yielded the route A -> B -> C.
But in general, if we are given ordered pairs of endpoints, how to construct the route?
I'm not sure what data structure is most helpful here. I'm thinking of storing each coordinates (x,y) into a list as the inputs are read in.
So (A, B), (C, D) would be stored as {A, B, C, D}. Whether each element is x or y coordinates can be determined by the parity of its position in the list (so the 1st entry in the list is x, 2nd entry is y, 3rd is x, etc). Then as each ordered pair is read in, we look up the list to see if either the x or y coordinate is already in the list. If so, we connect.
To demonstrate, suppose we are reading in (A, B), (C, D), (B, C), our list would be {A, B, C, D} after (C, D) is just read. When (B, C) is read, we see that B is already in the list. So we know A -> B -> C. Also C is in the list, and we have A-> B -> C -> D, and then we add (B, C) to the list to form {A, B, C, D, B, C}.
My difficult is: how do we store A -> B -> C? What data structure should I use? How do we keep track of the partial route we have formed as we go?
Thank you!

Construct a graph of directed edges with adjacency list representation. Then use DFS on start point till end point and store previously visited nodes in buffer and as soon as you reach destination the values in the buffer is the path.

Related

Graph representations in Prolog

Consider the following graph
and that it is described by the below Prolog term :
graph([connected(a,[b,c]), connected(b,[a,c]), connected(c,[a,b,d]), connected(d,[c]) ]).
I would like to define a predicate which transforms the above connections into a list of the corresponding pairs. In other words, a predicate which yields
[[a,b],[a,c],[b,c],[c,d]] for the above term-graph.
Could you please advise how to do it ?
My attempt so far is the following :
map 2-neighbor vertex to pairs :
map2ne(adjacent(H,[K|T]),Pair) :-
append([H],[K],L),
append([H],T,M),
append([L],[M],Pair).
This runs ok.
map 3-neighbor vertex to pairs :
map3n(adjacent(H,[K,L|T]),Pair) :-
append([H],[K],A1),
append([H],[L],A2),
append([A1],[A2],Z),
append([H],T,M),
append(Z,[M],Pair).
This also runs ok.
But when I try to extend it to n-neighbor vertex, then it fails :
mapmany(adjacent(H, [K|_]),Pair) :-
append([H],[K],L),
append(L,[],Pair),
mapmany(adjacent(H,[K|_]),M),
append(M,Pair,Pair).
And also the below fails, which was intented to map many n-neighbor vertices to pairs :
mapping(Map,Pairs) :-
select(X,Map,Y),
mapmany(X,PairX),
append([PairX],Pairs),
mapping(Y,Pairs).
If you're going to use a solution based on setof/3, I strongly recommend defining an auxiliary predicate. This predicate should define exactly what we want a set of. When we want to define "the set of all edges in the graph", mathematically we might say something like "Edges is the set of all Edge terms where Edge is an edge in Graph".
We can write this very directly as follows:
graph_edges(Graph, Edges) :-
setof( Edge,
graph_edge(Graph, Edge),
Edges ).
It remains to define graph_edge/2 itself. The core of this can be lifted from slago's solution:
graph_edge(Graph, Edge) :-
member(connected(V, Ns), Graph),
member(W, Ns),
edge(V, W, Edge).
The advantages of having this as a separate predicate are:
the setof call is easier to read
the predicate itself has a nice descriptive name
the predicate can be tested in isolation
the predicate can be reused
no ^ signs anywhere, which have no meaning in Prolog except for complicating setof calls that don't use an auxiliary predicate
no worrying about "existential quantification", which has no meaning in Prolog except for complicating setof calls that don't use an auxiliary predicate
There are too many flaws in your code:
The adjacency list defined by graph/1 is composed of terms of the form connected(Vertex, Neighbors); however, your code deals with an adjacency list of terms of the form adjacent(Vertex, Neighbors).
Predicate append/3 should not be used to create all lists; for example, instead of append([H], [K], L), you should use L = [H, K].
In Prolog, it is more idiomatic to represent a pair of items V and W as V-W, instead of [V,W].
By the answer you expect for the example given (i.e., [a-b,a-c,b-c,c-d]), a single term V-W (i.e., {V,W}) represents both the edges (V,W) and (W,V). So, to avoid redundancy, you must exclusively choose V-W or W-V to put in your answer (without loss of generality, you can choose the term where V precedes W).
To to create an edge, you can do the following:
edge(V, W, Edge) :-
( V #< W
-> Edge = V-W
; Edge = W-V ).
Examples:
?- edge(a, b, Edge).
Edge = a-b.
?- edge(b, a, Edge).
Edge = a-b.
To create all edges connecting a vertex V to its neighbors Ns, without duplicates, just ask:
?- V=a, Ns=[b,c,d], setof(E, W^Ns^(member(W,Ns), edge(V,W,E)), Edges).
V = a,
Ns = [b, c, d],
Edges = [a-b, a-c, a-d].
Notice that the construct Var^Goal tells setof/3 not to bind variable Var in Goal (in other words, indicates that Var is existentially quantified).
Generalizing this idea, we have:
graph_edges(Graph, Edges) :-
setof( Edge,
V^Ns^W^( member(connected(V, Ns), Graph),
member(W, Ns),
edge(V, W, Edge)),
Edges ).
graph([connected(a, [b, c]),
connected(b, [a, c]),
connected(c, [a, b, d]),
connected(d, [c])]).
Example:
?- graph(G), graph_edges(G, E).
G = [connected(a, [b, c]), connected(b, [a, c]), connected(c, [a, b, d]), connected(d, [c])],
E = [a-b, a-c, b-c, c-d].
LIBRARY UGRAPHS
In SWI-Prolog, a trivial solution would be to use the predicate edges/2 from library(ugraphs). Be careful though, because the representation of undirected graphs on which the predicate edge/2 is based is different from the one you are considering (an undirected graph in the library(ugraphs) is represented by a list of vertex pairs where the order of the vertices in these pairs matters). For example:
?- edges([a-[b,c], b-[a,c], c-[a,b,d], d-[c]], E).
E = [a-b, a-c, b-a, b-c, c-a, c-b, c-d, d-c].

Haskell function to work on integer tuple

I'm have just started learning Haskell and am trying to create a function that performs several checks on a tuple containing 6 integers.
These checks include:
all digits are different;
alternate digits are even and odd, or odd and even;
alternate digits differ by more than two;
the first and middle pairs of digits form numbers that are both multiples of the last
The problem is that I can attempt this and have some working functions like
contains e [] = False
contains e (x:xs)
| x == e = True
| otherwise = contains e xs
unique :: [Int] -> Bool
unique [] = True
unique (x:xs)
| contains x xs = False
| otherwise = unique xs
for the first requirement, but as you can see this relies on using a list rather than a tuple.
I would appreciate it if someone could help me with how to create these functions for tuples instead, as well as any code efficiency suggestions.
You can convert a 6-tuple to a list, with:
tuple6ToList :: (a, a, a, a, a, a) -> [a]
tuple6ToList (a, b, c, d, e, f) = [a, b, c, d, e, f]
and then run the checks on the list for example. This is likely simpler, since one can then recurse on the list, whereas for a tuple it would mean that you "unwind" the checks into individual checks on the elements.

How to look up a value inside a list in a predicate, in PROLOG

So far I've done my fair amount of research and I've tried different methods, however even after reading multiple stack overflow answers and even a PDF from Addison Wesley, I can't find the way to do it. Here is the code
use_module(library(func)).
% importing library "func"
scale([c, d, e, f, g, a, b]).
scale(c, major, [c, d, e, f, g, a, b]).
scale(c, minor, [c, d, e_b, f, g, a_b, b_b]).
%1st attempt
search(note, scale):- scale(note, scale).
%2nd attempt
scaleOf(note, type_scale):- scale(note, type_scale).
on(item,[item|rest]).
on(item,[disregardHead|tail]):-
scale(tail),
on(item, tail).
%3rd attempt
fatherOf(father,type, son):- scale(father, type, sons), search(son, type, sons).
search(son, type, []):- !, fail.
search(son, type, [son|l]):- !, true.
search(son, type, [c|l]):- search(son, type, l).
What am I attempting? Simple, something that can iterate through the predicate scale(c, [c, d, e, f, g, a, b]). But I can't get it right.
Edit: I have multiple predicates because someone else suggested creating a predicate that would differentiate one scale from the other. I thought I could cram it inside any algorithm but I guess PROLOG is not that lenient :p
You can do that with member/2 [swi-doc]. This can be used to search, unify with a member, or generate a list.
So you can search with:
search(Note, Scale, Item) :-
scale(Note, Scale, Items),
member(Item, Items).
It is important that Note, Scale, Item and Items start with an Uppercase, since identifiers with a lower case are constants or functors. Identifiers with an uppercase are variables.
This will thus unify Item with the items in the list, for the given sample data we for example obtain:
?- search(c, minor, Item).
Item = c ;
Item = d ;
Item = e_b ;
Item = f ;
Item = g ;
Item = a_b ;
Item = b_b.

Interleaving in OCaml

I am trying to create a function which interleaves a pair of triples such as ((6, 3, 2), ( 4, 5 ,1)) and create a 6-tuple out of this interleaving.
I made some research but could understand how interleaving is supposed to work so I tried something on my own end ended up with a code that is creating a 6-tuple but not in the right interleaved way. This is my code
let interleave ((a, b, c), (a', b', c')) =
let sort2 (a, b) = if a > b then (a, b) else (b, a) in
let sort3 (a, b, c) =
let (a, b) = sort2 (a, b) in
let (b, c) = sort2 (b, c) in
let (a, b) = sort2 (a, b) in
(a, b, c) in
let touch ((x), (y)) =
let (x) = sort3 (x) in
let (y) = sort3 (y) in
((x),(y)) in
let ((a, b, c), (a', b', c')) = touch ((a, b, c), (a', b', c')) in
(a, b', a', b, c, c');;
Can someone please explain to me how with what functions I can achieve a proper form of interleaving. I haven't learned about recursions and lists in case you would ask why I am trying to do it this way.
Thank you already.
The problem statement uses the word "max" without defining it. If you use the built-in compare function of OCaml as your definition, it uses lexicographic order. So you want the largest value (of the 6 values) in the first position in the 6-tuple, the second largest value next, and so on.
This should be pretty easy given your previously established skill with the sorting of tuples.
For what it's worth, there doesn't seem to be much value in preserving the identities of the two 3-tuples. Once inside the outermost function you can just work with the 6 values as a 6-tuple. Or so it would seem to me.
Update
From your example (should probably have given it at the beginning :-) it's pretty clear what you're being asked to do. You want to end up with a sequence in which the elements of the original tuples are in their original order, but they can be interleaved arbitrarily. This is often called a "shuffle" (or a merge). You have to find the shuffle that has the maximum value lexicographically.
If you reason this out, it amounts to taking whichever value is largest from the front of the two tuples and putting it next in the output.
This is much easier to do with lists.
Now that I understand what your end-goal is . . .
Since tuples of n elements are different types for different n's, you need to define helper functions for manipulating different sizes of tuples.
One approach, that basically mimics a recursive function over lists (but requires many extra functions because of tuples all having different types), is to have two sets of helper functions:
functions that prepend a value to an existing tuple: prepend_to_2, up through prepend_to_5. For example,
let prepend_to_3 (a, (b, c, d)) = (a, b, c, d)
functions that interleave two tuples of each possible size up to 3: interleave_1_1, interleave_1_2, interleave_1_3, interleave_2_2, interleave_2_3, and interleave_3_3. (Note that we don't need e.g. interleave_2_1, because we can just call interleave_1_2 with the arguments in the opposite order.) For example,
let interleave_2_2 ((a, b), (a', b')) =
if a > a'
then prepend_to_3 (a, interleave_1_2 (b, (a', b')))
else prepend_to_3 (a', interleave_1_2 (b', (a, b)))
(Do you see how that works?)
Then interleave is just interleave_3_3.
With lists and recursion this would be much simpler, since a single function can operate on lists of any length, so you don't need multiple different copies of the same logic.

Maxima: how to roll (or shift) a list

What is the simplest way to roll a list ?
Consider the following list :
myList : [0,1,4,6,3]
I am looking for a roll() function that would do :
(%i0) roll(myList,1)
(%o0) [3,0,1,4,6]
(%i1) roll(myList,-1)
(%o1) [1,4,6,3,0]
I can achieve the same result by calling :
myItem : pop(myList)
myList : append(myList,myItem)
Problem is that this works in one direction only (there is no pop_back() function to my knowledge (?)) and that it is a two liner. Any better way to do that ?
Well, there isn't a built-in function for that. But I think you can use rest to get the effect you want.
(%i10) rotate (e, n) :=
if atom(e) then e
else block ([a : args(e)],
apply (op(e),
append (rest (a, length(a) - n), rest (a, -n)))) $
(%i11) foo : [a, b, c, d, e, f, g];
(%o11) [a, b, c, d, e, f, g]
(%i12) rotate (foo, 2);
(%o12) [f, g, a, b, c, d, e]
(%i13) rotate (foo, 7);
(%o13) [a, b, c, d, e, f, g]
This works for all expressions, not just lists.
(%i16) rotate (f(1,2,3), 2);
(%o16) f(2, 3, 1)
This implementation doesn't take negative n or n greater than the number of arguments, although I think it would be easy to handle that.
I've assumed that rotate moves elements at lesser indices into greater indices. Again, if you want the default to go in the other direction, I think it would be easy to do that.
EDIT: Actually it isn't necessary to separate out op(e) and args(e). You can call rest(e, ...) when e is not a list and it does the right thing. So a more concise version is:
rotate (e, n) :=
if atom(e) then e
else append (rest (e, length(e) - n), rest (e, -n)) $