Generate square from matrix in Prolog - list

I have a matrix of 6x6 numbers and I'm writing a prolog code that gives me the numbers in a certain row, column or square. For instance:
0n 1n 2n 3n 4n 5n
0n [[1,2,3,4,5,6]
1n [2,3,4,5,6,1]
2n [3,4,5,6,1,2]
3n [4,5,6,1,2,3]
4n [5,6,1,2,3,4]
5n [6,1,2,3,4,5]]
I already have code for rows and columns, which is something like:
row(1,[A|_],A).
row(Y,[_|B],X) :-
Y-1 is Y1,
row(Y1,B,X).
But now I'm stuck on how to generate a 3x3 square. I want to work with coordinates, so the first argument should be something like (1,3) and it will give the square of row 1n and column 3n, then the matrix as the second and the numbers in the square as third argument.
Does anyone have any tips? I was thinking I might have to work with a head tail pattern again; getting the first three numbers of the given row/column, then doing this three times, but I don't know how or if this is possible and effective.
Any comments are greatly appreciated!

First of all, your predicate to obtain the row, is not safe:
row(1,[A|_],A).
row(Y,[_|B],X) :-
Y-1 is Y1,
row(Y1,B,X).
In case I query for row(0,[1,4,2,5],X). it will get stuck into an infinite loop immediately, in case i work with row(2,[1,4,2,5]). it will first give me the correct result, but then get into an infinite loop when searching for more answers.
A better approach would be:
row(1,[A|_],A).
row(Y,[_|B],X) :-
Y > 1,
Y-1 is Y1,
row(Y1,B,X).
Since now the Y > 1 guards the fact that you will not perform recursion if Y is less than or equal to 1.
That being said, you do not need to construct this predicate yourself: most Prolog interpreters already have such a predicate: nth1/3:
nth1(?Index, ?List, ?Elem)
Is true when Elem is the Index'th element of List. Counting
starts at 1.
If you can assume that this predicate exists, you can use:
elem(I,J,Matrix,Cell) :-
nth1(I,Matrix,Row),
nth1(J,Row,Cell).
Where I is the number of the row, and J the number of the column we wish to fetch.
In case it does not exists, I suggest renaming your row/3 predicate to nth1/3 since it is equivalent.
In case you want to start counting at 0 (which the top of your question suggests), you can use nth0/3 instead of nth1/3.

Related

How does this GolfScript code print 1000 digits of pi?

How does this code work?
;''
6666,-2%{2+.2/#*\/10.3??2*+}*
`1000<~\;
It seem to use an array #* and a cycle {/**/}, but what is 6666? what is \/?
The first three characters; ;'', are unneeded for the program to function. They simply discard all input and replace it with an empty string, in case your compiler needs an input necessarily.
6666, prints out an array 6666 elements long, each of which are the numbers 0-6665.
-2% is a mapping function. It reverses the function and deletes every two elements. You now you have an array that is 3333 elements long, and it goes [6665 6663 6661 … 5 3 1]
{foo}* is a folding block call. For every element, do the following to the combination of elements. For example, 5,{+}* would add together the numbers 0-4.
So, let's see what we're doing in this folding block call.
2+ add two to the element.
. duplicate the element.
2/ halve it. Your sub-stack looks like this; (n+2),((n+2)/2)
# pulls the third element to the top.
This is the first function we cannot do, since our original stack is only two tall. We'll get back to this later.
*\/ will be skipped for now, we'll get back to it once we discuss folding more.
10.3?? Duplicate 10, then push a 3. [10 10 3]. ? is exponentiation, so we have [10 1000], then again gives us a 1 with 1000 zeroes afterwards.
2* Multiply it by two. So now we have a 2 with 1000 zeroes after.
+ Adds the rest of our math to 2e(1e3)
So, let's go back to that pesky #.
#*\/ will grab the third element and bring it to the top, then multiply it by the next top element ((n+2)/2), then we divide n by this number.
This is an expansion of the Leibniz Series.
\`1000< turns the int into a string, then throws a decimal after the 3.
~ dumps the string into a number again.
\; deleted the rest of the stack.
To answer your specific questions;
6666 was chosen, since half is 3333 (length of array), and we want more than pi times the number of digits of accuracy we want. We could make it smaller if we wanted, but 6666 is a cute number to use.
\/ Is the "inverse division" pair. Take a, take b, then calculate b/a. This is because the \ changes the order of the top two elements in the array, and / divides them.

How to read a file creating a list

I have some code, looks like this:
main :-
open('input.txt', read, Input),
repeat,
read_line_to_codes(Input, Line),
maplist(my_representation, Line, FinalLine),
( Line \= end_of_file -> writeln(FinalLine), fail ; true ),
close(Input).
FinalLine is a list of integers, including some underscores (based on the input file). Since this loops, I am wondering how to dynamically, each iteration of the loop, add the FinalLine list to another list. Basically this will create a list of lists.
And since I know the specifications of my input file, I know it loops 16 times, therefore I want a list of 16 lists. So although I don't know how to do this, I am pretty sure the best way would be to make a predicate that I call, instead of the output I am doing now (writeln(FinalLine)), to dynamically create this list of lists.
Hope this makes sense. Would appreciate any help, thanks!
While historically I/O in Prolog was often presented in terms of repeat/fail loops, recursion is often (almost always?) the superior way to implement iteration. Especially if you need to remember data from one iteration to the next; failing causes backtracking, which unbinds your variables from the previously computed data. On backtracking you lose any data you had not saved away using yet more impure constructs. Recursion is simpler.
Recursion forces you to decompose the program into more than one predicate, but that is a good idea anyway. For example, separating opening the stream from reading it makes your program more reusable and more testable, because streams may be constructed from things other than files.
% dummy
my_representation(Codes, Result) :-
atom_codes(Result, Codes).
stream_representations(Input, Lines) :-
read_line_to_codes(Input, Line),
( Line == end_of_file
-> Lines = []
; my_representation(Line, FinalLine),
Lines = [FinalLine | FurtherLines],
stream_representations(Input, FurtherLines) ).
main :-
open('input.txt', read, Input),
stream_representations(Input, Lines),
close(Input),
writeln(Lines).
Test input file:
hello
world
hello, world!
this file ends here
Test run:
?- main.
[hello,world,hello, world!,this file ends here]
true.
A 2-dimensional list of lists is a matrix, and the easiest way to visualize it in your head is a table consisting of rows and columns. Here's a piece of example code to clarify the concept.
This code generates a matrix based on the maximum amounts of columns you want as MaxX, and the maximum amount of rows you want as MaxY. Each position in the matrix has a cell(point(X,Y)) coordinate to visualize the output more easily.
%If the MaxY has been reached for the Y axis, step back
generate_matrix([],_,_,MaxY,MaxY) :- !.
%If MaxX has been reached, new row
generate_matrix([Row|Tp],X,MaxX,Y,MaxY):-
generate_row(Row, X, MaxX, Y),
Y1 is Y+1,
generate_matrix(Tp,0,MaxX,Y1,MaxY).
%If the MaxX has been reached for the X axis, step back
generate_row([], MaxX,MaxX,_) :- !.
generate_row([cell(point(X,Y))|T], X, MaxX, Y) :-
XNew is X + 1,
generate_row(T, XNew, MaxX, Y).
You could easily replace cell(point(X,Y) with something you want to place there instead. I hope this clarifies the concept for you, be sure to ask for clarification if it doesn't.
Testquery to generate a 10 by 10 matrix/grid/table/2-dimensional list of lists:
%generate_matrix(Matrix, 0, MaxX, 0, MaxY)
generate_matrix(Matrix, 0, 10, 0, 10).
You can add dimensions to represent more complex structures. Adding a Z-axis gives you a 3D-cube.

get the number of overlapping intervals, given two lists of intervals

I recently came across an interesting problem:
Given two lists of intervals, find the total number of overlapping intervals from the two lists.
Example
L1: ([1,2][2,3][4,5][6,7])
L2: ([1,5][2,3][4,7][5,7])
[1,5] overlaps [1,2] [2,3] [4,5]
[2,3] overlaps [1,2] [2,3]
[4,7] overlaps [4,5] [6,7]
[5,7] overlaps [4,5] [6,7]
total = 3+2+2+2 = 9
Obviously the brute force approach works, but it's too slow (I need something better than O(n^2)).
I also fond a similar problem here. But it's not exactly the same...
Any help is appreciated
Make two sorted lists with pairs (value; +1 or -1 for start and end of interval).
Two counters - Count1 and Count2 which show number of active intervals in the first and the second lists.
Walk through both lists in merge manner.
When you get pair from the first list with +1 - increment Count1
When you get pair from the first list with -1 - decrement Count1 and add Count2 to the result
The same for pairs from the second list
Pseudocode for the last stage
CntA = 0
CntB = 0
Res = 0
ia = 0
ib = 0
while (ia < A.Length) and (ib < B.Length)
if Compare(A[ia], B[ib]) <= 0
CntA = CntA + A[ia].Flag
if (A[ia].Flag < 0)
Res = Res + CntB
ia++
else
CntB = CntB + B[ib].Flag
if B[ib].Flag < 0
Res = Res + CntA
ib++
Subtle moment - comparison if Compare(A[ia], B[ib]) <= 0
We should here take into account also flags - to correctly treat situations when endpoints only touch like [1..2][2..3] (you consider this situation as intersection). So both sorting and merge comparator should take synthetic value like this: 3 * A[ia].Value - A[ia].Flag. With such comparing start of interval is treated before end of interval with the same coordinate.
P.S. Made quick test in Delphi. Works for given data set and pair of others.
Delphi code (ideone FPC doesn't compile it due to generics)
Try to look for sweep line algorithms, it will give you the fastest solution.
You can check short description at TopCoder site or watch video from Robert Sedgwick. These describe a bit more hard problem but should give you an approach how to solve yours.
Actually the main idea is to walk over sorted list of begins and ends of your segments each time updating the lists of segments in the special intersecting list.
For this task you will have two intersections lists for each original list respectively. At the start both intersection lists are empty. On coming over begin of the segment you add it to the appropriate intersection list and it obviously intersects all the segments in the other intersection list. When coming to an end of the segment just remove it from the intersection list.
This algorithm will give you O(n log(n)) speed and in worst case O(n) memory.
You may be able to use std::set_intersection in a loop over the second array to match it with each item in the first array. But I am not sure if the performance will match your requirements.
I recently stumbled upon the Interval Tree ADT when tackling a similar question - I suspect it'll be useful for you, whether you implement it or not.
It is basically a ternary tree, and I built it with nodes containing:
Left sub-tree containing intervals less than current node
Right sub-tree containing intervals more than current node
List of overlapping intervals
Interval value encompassing all overlapping intervals
After building the tree in O(n*log(n)), a query function - to check overlapping intervals - should be O(log(n) + m) where m is the number of overlapping intervals reported.
Note that on creation, sorting by end value in the interval and splitting the list should help keep things balanced.

Prolog - Lotto Machine

This is my first post. I have been teaching myself Prolog for a university project and I am tasked with generating a program that simulates the lotto and compares the random numbers (6 in this case) with the numbers that the user has. If they all match then you are deemed the winner if not, then it returns 'hard luck'.
All I have been able to do so far is generate one random number in the range of 1-50. I don't know how to do much else after that.
:- use_module(library(random)).
?- random(1,50,Out).
I understand I have to add the random number to a list, but I'm not sure how to implement it. And to then have another list of numbers (user_numbers) in the database or fact-base. Then use SWI-Prolog to check if they're equal.
It is a really tough program for me to try and do in Prolog, especially seeing as I am teaching it to myself. If anybody could give me some pointers on how to approach it I would be very grateful.
pick_number(N) :- random(1, 50, N).
We need to pick a list of 6 numbers
lotto_numbers(Ns) :-
length(Ns, 6), % The length of our list is 6, now we have a list of 6 free variables.
select_numbers(Ns). % We need to select our numbers, binding them to our free variables.
select_numbers([]). % An empty list needs no picking
select_numbers([N|Ns]) :-
pick_number(N), % We pick the first number (bind the free variable to a random number)
select_numbers(Ns). % Then we pick the rest of the numbers.
We need to check if the ticket holder has winning numbers. Does it matter what order the numbers are in? If so, then we can check if the two lists unify: LottoNumbers = LottoTicketNumbers. If we don't care about order, then we need a slightly more complex solution:
numbers_match([], []). % if both lists are empty, then they must have all matched.
numbers_match([N|Ns], Ms) :-
select(N, Ms, NewMs), % remove N from Ms (if N matches an element in Ms), leaving NewMs
numbers_match(Ns, NewMs). % remove the rest of Ns from NewMs.
If both lists don't empty at the same time, then they didn't all match up.
Supposing we have some loto ticket in the database,
lotto_ticket(Ns) :- lotto_numbers(Ns).
With all the above definitions in our program, we can generate a lotto ticket, and generate some lotto numbers (actually the same process, but named differently for illustrative purposes), and see if they have all and only the same numbers:
?- lotto_ticket(T), lotto_numbers(L), numbers_match(T, L).
false.
Ah. No surprise that we lost...
That's all fine and good, but we can save a lot of steps by using a higher-order
predicate and some common library predicates:
alt_lotto_numbers(Ns) :-
length(Ns, 6),
maplist(random(1,50), Ns). % `maplist/2` is just a way of calling a predicate on every member of a list.
alt_numbers_match(Ns, Ms) :-
same_length(Ns, Ms),
subset(Ns, Ms).

Prolog IntList definition

hill(+IntList) succeeds if IntList consists of monotonically increasing >integers followed by monotonically decreasing integers. For example, >[1,2,5,8,11,6,3,-1] is a hill, but [1,2,5,8,11,6,9,3,-1] and [1,2,3,4,5,6] are >not hills. You may assume that IntList contains only integers.
This is what I have done so far:
hill(List) :-
increasing(List), decreasing(List).
increasing([H|Tail]) :-
sm(H,Tail),
increasing(Tail).
increasing([]).
decreasing([H|Tail]) :-
gr(H,Tail),
decreasing(Tail).
decreasing([]).
hill([]).
gr(X,[H|Tail]) :- X>H.
gr(X,[]).
sm(X,[H|Tail]) :- X<H.
sm(X,[]).
But this doesn't work. The logic is: A list of numbers is hill IF it is increasing and then decreasing. How do I say that? This code does increasing and decreasing, but no list can be both increasing and decreasing.
Any ideas?
I don't want to give a complete, working solution to a homework problem, but I'll describe in words how I would proceed from the code you've got right now. Right now your increasing and decreasing predicates test the entire list. By your definition, though, a hill is neither entirely increasing nor entirely decreasing. I would modify these predicates to have two arguments instead of one. The additional argument would be bound to the tail of the list which is not does not satisfy the increasing/decreasing criteria. Then, I'd modify hill slightly to use the new argument of increasing to test decreasingness not of the entire list, but of the portion after the initial increasing subsequence. Finally, I would use the new argument of decreasing to verify that there are no non-decreasing elements after the decreasing subsequence.
If you need better hints, or if I seem to be talking nonsense (quite possible as I'm not that good with Prolog), just let me know and I'll try to clarify more.
Edit based on OP's comments: Alright, let's try something else. L is a hill if and only if L is a list of at least two monotone increasing elements ending with some element M, followed by a list of at least one monotone decreasing element starting with some element N, where N < M. Can you translate that description to Prolog clauses?
Edit take two (SPOILER WARNING):
In your revised code, drop these three predicates: increasing([])., hill([])., and hill(List) :- decreasing(List).. This will almost give you a solution, but it will still fail, e.g. on [3, 2, 1]. Fixing this should be fairly easy, though.
Use clpfd!
:- use_module(library(clpfd)).
We don't need to worry about getting recursion right if we use append/3 and chain/2 like this:
hill(Zs) :-
Ascending0 = [_|_],
Descending = [M,_|_],
append(Ascending0,Descending,Zs),
append(Ascending0,[M],Ascending),
chain(Ascending ,#<),
chain(Descending,#>).
Let's run the queries the OP gave!
?- hill([1,2,5,8,11,6,3,-1]).
true % as expected
; false.
?- hill([1,2,5,8,11,6,9,3,-1]).
false. % as expected
?- hill([1,2,3,4,5,6]).
false. % as expected
hill(L1) :- concatenate(L2,L3,L1), inc(L2), dec(L3).
dec([X|[Y|[]]]) :- X > Y.
dec([X|[Y|L]]) :- X > Y, dec([Y|L]).
inc([X|[Y|[]]]) :- Y > X.
inc([X|[Y|L]]) :- Y > X, inc([Y|L]).
concatenate([],L2,L2).
concatenate([X|L1],L2,[X|L3]) :- concatenate(L1,L2,L3).
This works :)