Related
I am new to prolog and would appreciate any help on the following question:
I need to write a program that accepts two lists and appends the second to first and displays this new list and its length. I know that prolog might have some built in functions to make this all easier...but I do not want to use those.
eg: newlist([a,b,c],[d,e,f],L3,Le). would return L3=[a,b,c,d,e,f] and Le=6
Here is what I have so far:
newlist([],List,List,0)
newlist([Element|List1],List2,[Element|List3],L) :- newlist(List1,List2,List3, LT), L is LT + 1.
This does the appending correctly but I can only get the length of the first list instead of the combined list. Is there a way for me to add the second list's length to the first to get the combined list length?
Thanks, and sorry if this question is rather easy...I am new.
Is there a way for me to add the second list's length to the first to get the combined list length?
You should replace:
newlist([],List,List,0).
with:
newlist([],List,List,X):-length(List,X).
I am a newbie to prolog, till now I am able to read all words of file, displayed them one by one, now I want to store them in a list(one by one, as I soon as I am displaying them). All logic for append given everywhere, append content of two lists in an empty list. For example
append(new_word,word_list,word_List), intially my word_list is empty, so everything fine, but afterwards it says no, and stop at that point.
Need help to be able to store element in list one by one.
You can use difference lists :
file_to_list(W, L) :-
read_word(Word),
append_dl(W, [Word|U]-U, Ws),
!, file_to_list(Ws, L).
file_to_list_1(Ws, Ws).
append_dl(X-Y, Y-Z, X-Z).
You call file_to_list(U-U, L-[]) to get the list of words. There is no slowdown but takes more inferences than CapelliC's code (one per word).
For my C++ assignment, I'm basically trying to search through a chunk of text in a text file (that's streamed to my vector vec) beginning at the second top character on the left. It's for a text maze, where my program in the end is supposed to print out the characters for a path through it.
An example of a maze would be like:
###############
Sbcde####efebyj
####hijk#m#####
#######lmi#####
###############
###############
###############
###############
###############
###############
###############
###############
###############
###############
###############
Where '#' is an unwalkable wall and you always begin on the left at the second top character. Alphabetical characters represent walkable squares. Exit(s) are ALWAYS on the right. The maze is always a 15x15 size in a maze.text file. Alphabetical characters repeat within the same maze, but not directly beside each other.
What I'm trying to do here is: if a square next to the current one has an alphabetical character, add it to the vector vec, and repeat this process until I get to the end of the maze. Eventually I am supposed to make this more complicated by printing to the screen multiple paths that exist in some mazes.
So far I have this for the algorithm itself, which I know is wrong:
void pathcheck()
{
if (isalpha(vec.at(x)) && !(find(visited.begin(), visited.end(), (vec.at(x))) != visited.end()) )
{
path.push_back(vec.at(x));
visited.push_back(vec.at(x));
pathcheck(vec.at(x++));
pathcheck(vec.at(x--));
pathcheck(vec.at(x + 16));
pathcheck(vec.at(x - 16));
}
}
visited is my vector keeping track of the visited squares.
How would I update this so it actually works, and eventually so I can manage more than one path (i.e. if there were 2 paths, the program would print to the screen both of them)? I recall being told that I may need another vector/array that keeps track of squares that I've already visited/checked, but then how would I implement that here exactly?
You're on the right track. When it comes to mazes, the typical method of solving is through either a depth-first search (the most efficient solution for finding some path) or breadth-first search (less efficient, but is guarenteed to find the optimal path). Since you seem to want to do an exhaustive search, these choices are basically interchangeable. I suggest you read up on them:
http://en.wikipedia.org/wiki/Depth-first_search
http://en.wikipedia.org/wiki/Breadth-first_search
Basically, you will need to parse your maze and represent it as a graph (where each non "#" is a node and each link is a walkable path). Then, you keep a list of partial paths (i.e. a list of nodes, in the order you visited them, for example, [S, b, c] is the partial path starting from S and ending at c). The main idea of DFS and BFS is that you have a list of partial paths, and one by one you remove items from the list, generate all possible partial paths leading from that partial path, then place them in the list and repeat. The main difference between DFS and BFS is that DFS implements this list as a stack (i.e. new items have greatest priority) and BFS uses a queue (i.e. new items have lowest priority).
So, for your maze using DFS it would work like this:
Initial node is S, so your initial path is just [S]. Push [S] into your stack ([ [S] ]).
Pop the first item (in this case, [S]).
Make a list of all possible nodes you can reach in 1 move from the current node (in your case, just b).
For each node from step 3, remove any nodes that are part of your current partial path. This will prevent loops. (i.e. for partial path [S, b], from b we can travel to c and to S, but S is already part of our partial path so returning is pointless)
If one of the nodes from step 4 is the goal node, add it to your partial path to create a completed path. Print the path.
For each node from step 4 that IS NOT the goal node, generate a new partial path and push it into the stack (i.e. for [S], we generate [S, b] and push it into the stack, which now should look like [ [S, b] ])
Repeat steps 2 through 6 until the stack is empty, meaning you have traversed every possible path from the starting node.
NOTE: in your example there are duplicate letters (for example, three "e"s). For your case, maybe make a simple "Node" class that includes a variable to hold the letter. That way each "e" will have it's own instance and the pointers will be different values letting you easily tell them apart. I don't know C++ exactly, but in pseudo code:
class Node:
method Constructor(label):
myLabel = label
links = list()
method addLink(node):
links.add(node)
You could read every character in the file and if it is not "#", create a new instance of Node for that character and add all the adjacent nodes.
EDIT: I've spent the last 3 years as a Python developer and I've gotten a bit spoiled. Look at the following code.
s = "foo"
s == "foo"
In Python, that assertion is true. "==" in Python compares the string's content. What I forgot from my days as a Java developer is that in many languages "==" compares the string's pointers. That's why in many languages like Java and C++ the assertion is false because the strings point to different parts of memory.
My point is that because this assertion is not true, you COULD forgo making a Node class and just compare the characters (using ==, NOT using strcmp()!) BUT this code could be a bit confusing to read and must be documented.
Overall, I'd use some sort of Node class just because it's fairly simple to implement and results in more readable code AND only requires parsing your maze once!
Good Luck
I have a dictionary and want to convert it to a list. Then I would like to sort the resulting list consisting of {Key, Value} pairs from min to max depending on the 2nd element(Value).
Is there a built in sort method for Lists to handle this or how does one do this?
Thanks
The function lists:keysort/2 fits like glove for this.
1> lists:keysort(2, [{a,b},{b,a},{b,b}]).
[{b,a},{a,b},{b,b}]
2> lists:keysort(2, [{1,14},{3,10},{2,13}]).
[{3,10},{2,13},{1,14}]
The easiest way to sort by the second element would be to define your own sorting function that could work as follows:
fun({KeyA,ValA}, {KeyB,ValB}) -> {ValA,KeyA} =< {ValB,KeyB} end.
And call it in lists:sort/2:
1> lists:sort(fun({KeyA,ValA}, {KeyB,ValB}) -> {ValA,KeyA} =< {ValB,KeyB} end., [{a,b},{b,a},{b,b}]).
[{b,a},{a,b},{b,b}]
This is because Erlang will always automatically compare tuples from first to last element. This function swaps the first and the second element so the second one acts as the first point of comparison. The Key in your dict will then be used to order entries where values are the same.
I need to build a new list with a "loop". Basically i can't use recursion explicitly, so i am using append to go through lists of list.
I can get the element. Problem is i need to check this element and if something is true it returns another element i need to put back into the list. It does check correctly and it changes correctly.
Problem i am having is how do i create a completely new list.
So, if i had
[[1,1,1],[2,6,2],[3,3,3]]
I go through each element. say i get to the 6 and it changes. So i need to create a new list like so,
[[1,1,1],[2,10,2],[3,3,3]].
Right now my main problem is just creating each row. If i can create each row, i will be able to create a list of lists.
So to break this down a little more, lets just worry about [1,1,1].
I go through each element while appending the new element to a newlist. the new list is now [1,1,1]
I have this:
set(Row,Col,Bin,TheEntry,Bout) :-
append(ListLeft, [R|_], Bin),
append(ListLeft2, [C|_], R),
length(ListLeft, LenR),
length(ListLeft2,LenC),
CurrRow is LenR + 1,
CurrCol is LenC + 1,
getChar(C, Row, Col, CurrRow, CurrCol,TheEntry, NewC),
appendhere?.
I need to create a new list there with the character returned from NewC. Not sure how to do this.
Any clues?
Thanks.
To give you an idea about how to use append/3 to extract an item from a list of lists, consider the following predicate called replace/2:
replace(In, Out) :-
append(LL, [L|RL], In),
append(LE, [E|RE], L),
replaceElement(E, NewE), !,
append(LE, [NewE|RE], NewL),
append(LL, [NewL|RL], Out).
replace(In, In).
This non-recursive predicate takes, as Input, a list of lists, and backtracks to find an element E within an inner list L that can be replaced via replaceElement/2; if so, it is replaced by constructing the inner list first (NewL), then uses this new list in the construction of the new outer list (Out), as the result.
Note that this simply serves to demonstrate how to use append/3 to break apart a list of lists to retrieve individual elements as you need via backtracking, and not recursion, as requested. Once an element E is found to be replaceable by NewE via replaceElement/3, it is used in the construction of the list again using append/3 as shown.
Also note that this suggestion (which is intended to help you, not be your final answer) also happens to replace only a single element within an inner list, if any at all. If you want to do multiple replacements of the input list in a single call to replace/2 or similar using this technique, then you will almost certainly need a recursive definition, or the ability to use the global database via assert. I'm happy to be corrected if someone else can provide a definition as a counterexample.
With this example predicate replace/2, together with, say, the following fact:
replaceElement(6, 10).
Executing the following gives us your required behaviour:
1 ?- replace([[1,1,1],[2,6,2],[3,3,3]], Out).
Out = [[1, 1, 1], [2, 10, 2], [3, 3, 3]] ;
false.
If you cannot use cut (!), it is fine to omit it, but note that the second clause replace(In, In) will cause all calls to replace/2 to backtrack at least once to give you the input list back. If this behaviour is undesirable, omitting this second clause will cause replace/2 to fail outright if there is no replacement to be made.
If you cannot use recursion and have to do it with backtracking you should do something like this:
Assume Bin is a list of lists (each item is a full row)
~ Split input Bin in three parts (a list of 'left' rows, a Row, and a list of remaining rows). This can be done using append/3 with something like append(Left, [Item|Rest], Rows)
~ Now obtain the length of the 'left' rows
~ Test the length using 'is' operator to check wether the left list has Row - 1 items
~ Do the same but now with the Item, i.e. split it in three parts (LeftColums, ColumItem and Rest)
~ Test now the length against the required Column
~ Now you have the Item to change so all you need to do is rebuild a list using two appends (one to rebuild the chosen row and another to rebuild the output list).
So from your code you wouldn't use unnamed variables (_). Instead of that you have to use a named variable to be able to rebuild the new list with the item changed.