I have three tables X,Y,Z. While X & Y define my grid points the Z depends on every point of X and Y.
x = Table[i, {i, 0, 10, 1}]
y = Table[j, {j, 0, 10, 1}]
z = Table[5*i + j, {i, 0, 10, 1}, {j, 0, 10, 1}]
Now I want the final list to look like this [{x1,y1,z1},{x2,y2,z2}}
I want to create a set of corresponding x,y,z values from the table given above.
In this case you can also produce your combined list with Array as follows:
Array[{##, 5 # + #2} &, {11, 11}, 0]
See Function and Slot. rcollyer has already shown how to "split out" x, y, and z from this.
When starting with unrelated lists x and y you can produce the combined list with Outer:
Outer[{##, 5 # + #2} &, x, y, 1]
Unless you need the the x and y lists, I'd combine this in one Table as follows:
Table[{i, j, 5*i + j}, {i, 0, 10}, {j, 0, 10}]
Note, I removed the step length ({i, 0, 10, 1} -> {i, 0, 10}) as it's implicitly set to 1 if it is not included.
Edit: If you wish to have the x and y lists, also, you could do the following
Table[{i, j, 5*i+j}, {i, x}, {j, y}]
As of v.7, Table accepts lists of values in addition to start and end points. This doesn't address whether you need a separate list for z, also. In that case, I'd start with the first form bit of code, and using Transpose (per your other question) to set the individual lists, as follows:
coords = Table[{i, j, 5*i + j}, {i, 0, 10}, {j, 0, 10}];
{x, y, z} = Transpose # coords;
One way to do it starting from your
x = Table[i, {i, 0, 10, 1}];
y = Table[j, {j, 0, 10, 1}];
z = Table[5*i + j, {i, 0, 10, 1}, {j, 0, 10, 1}];
is
Flatten[
MapThread[{Sequence ## #1, #2} &,
{Outer[{#1, #2} &, x, y], z},
2
],
1
]
(I'd love to see me try to understand this in a week) which gives what you want.
This also works:
p = {};
Do[
Do[
AppendTo[p, {x[[i]], y[[j]], z[[i, j]]}],
{j, 1, Length#y}
],
{i, 1, Length#x}
]
and gives the same answer.
Related
I want to create a function multiples(X, N, R) where R is a list containing all multiples of X from X to X * N.
An example would be: multiples(3, 4, [12, 9, 6, 3]), which should give out true.
My code so far:
multiples(X, N, R) :- X >= 1, N >= 1, Z is X*N, contains(Z, R).
contains(Z, [Z|_]).
contains(Z, [W|V]) :- contains(Z,V), L is Z-X, L >= X, contains(L, V).
The output of the console for multiples(3,4,X). is X = [12|_xxxx] and when I type ; an error occurs.
How do I manage to receive the list that I want?
(Maybe my idea is completely wrong).
I found 4 issues with your code. Here is the fixed code, explanation below:
multiples(X, N, R) :-
X >= 1,
N >= 1,
Z is X*N,
contains(X, Z, R).
contains(X, Z, [Z|V]) :-
L is Z-X,
L >= X,
contains(X, L, V).
contains(_, Z, [Z]).
?- multiples(3,4,X).
X = [12, 9, 6, 3] ;
X = [12, 9, 6] ;
X = [12, 9] ;
X = [12] ;
false.
At first in your contains predicate you access X and W and never state their values. Solve X by adding another attribute to the predicate. Solve W by replacing it with Z.
Another problem is the order of your rules. The larger contains rule should be the "main" rule, only if this one fails the other one should "fire". By placing the default rule on top you get the right result.
Also the rule contains(_, Z, [Z]). marks the end, therefore it the return list has only the element Z in it and does not contain any other (unknown) elements.
The last point is that you don't need two contains calls in the main contains rule.
The example works for the first answer. However you can improve this with a cut (!), which prevents going to the second rule after successfully visiting the first rule:
contains(X, Z, [Z|V]) :-
L is Z-X,
L >= X,
!,
contains(X, L, V).
contains(_, Z, [Z]).
?- multiples(3,4,X).
X = [12, 9, 6, 3].
A slight modification to your code. contains predicate will collect the numbers in a list, and N will keep getting decreased till it satisfies the base predicate.
multiples(X, N, R) :- X >= 1, N >= 1, contains(X,N, R),!.
contains(_,0,[]).
contains(X,N,[Z|List]):-
Z is X*N,
N1 is N-1,
contains(X,N1,List).
Example:
?- multiples(3,4,R).
R = [12, 9, 6, 3]
?- multiples(2,5,R).
R = [10, 8, 6, 4, 2]
?- multiples(25,5,R).
R = [125, 100, 75, 50, 25]
I have problem, because I want to generate permutations of a list (in prolog), which contains n zeros and 24 - n ones without repetitions. I've tried:findall(L, permutation(L,P), Bag) and then sort it to remove repetitions, but it causes stack overflow. Anyone has an efficient way to do this?
Instead of thinking about lists, think about binary numbers. The list will have a length of 24 elements. If all those elements are 1's we have:
?- X is 0b111111111111111111111111.
X = 16777215.
The de fact standard predicate between/3 can be used to generate numbers in the interval [0, 16777215]:
?- between(0, 16777215, N).
N = 0 ;
N = 1 ;
N = 2 ;
...
Only some of these numbers satisfy your condition. Thus, you will need to filter/test them and then convert the numbers that pass into a list representation of its binary equivalent.
Select n random numbers between 0 and 23 in ascending order. These integers give you the indexes of the zeroes and all the configurations are different. The key is generating these list of indexes.
%
% We need N monotonically increasing integer numbers (to be used
% as indexes) from [From,To].
%
need_indexes(N,From,To,Sol) :-
N>0,
!,
Delta is To-From+1,
N=<Delta, % Still have a chance to generate them all
N_less is N-1,
From_plus is From+1,
(
% Case 1: "From" is selected into the collection of index values
(need_indexes(N_less,From_plus,To,SubSol),Sol=[From|SubSol])
;
% Case 2: "From" is not selected, which is only possible if N<Delta
(N<Delta -> need_indexes(N,From_plus,To,Sol))
).
need_indexes(0,_,_,[]).
Now we can get list of indexes picked from the available possible indexes.
For example:
Give me 5 indexes from 0 to 23 (inclusive):
?- need_indexes(5,0,23,Collected).
Collected = [0, 1, 2, 3, 4] ;
Collected = [0, 1, 2, 3, 5] ;
Collected = [0, 1, 2, 3, 6] ;
Collected = [0, 1, 2, 3, 7] ;
...
Give them all:
?- findall(Collected,need_indexes(5,0,23,Collected),L),length(L,LL).
L = [[0, 1, 2, 3, 4], [0, 1, 2, 3, 5], [0, 1, 2, 3, 6], [0, 1, 2, 3, 7], [0, 1, 2, 3|...], [0, 1, 2|...], [0, 1|...], [0|...], [...|...]|...],
LL = 42504.
We are expecting: (24! / ((24-5)! * 5!)) solutions.
Indeed:
?- L is 20*21*22*23*24 / (1*2*3*4*5).
L = 42504.
Now the only problem is transforming every solution like [0, 1, 2, 3, 4] into a string of 0 and 1. This is left as an exercise!
Here is an even simpler answer to generate strings directly. Very direct.
need_list(ZeroCount,OneCount,Sol) :-
length(Zs,ZeroCount),maplist([X]>>(X='0'),Zs),
length(Os,OneCount),maplist([X]>>(X='1'),Os),
compose(Zs,Os,Sol).
compose([Z|Zs],[O|Os],[Z|More]) :- compose(Zs,[O|Os],More).
compose([Z|Zs],[O|Os],[O|More]) :- compose([Z|Zs],Os,More).
compose([],[O|Os],[O|More]) :- !,compose([],Os,More).
compose([Z|Zs],[],[Z|More]) :- !,compose(Zs,[],More).
compose([],[],[]).
rt(ZeroCount,Sol) :-
ZeroCount >= 0,
ZeroCount =< 24,
OneCount is 24-ZeroCount,
need_list(ZeroCount,OneCount,SolList),
atom_chars(Sol,SolList).
?- rt(20,Sol).
Sol = '000000000000000000001111' ;
Sol = '000000000000000000010111' ;
Sol = '000000000000000000011011' ;
Sol = '000000000000000000011101' ;
Sol = '000000000000000000011110' ;
Sol = '000000000000000000100111' ;
Sol = '000000000000000000101011' ;
Sol = '000000000000000000101101' ;
Sol = '000000000000000000101110' ;
Sol = '000000000000000000110011' ;
Sol = '000000000000000000110101' ;
....
?- findall(Collected,rt(5,Collected),L),length(L,LL).
L = ['000001111111111111111111', '000010111111111111111111', '000011011111111111111111', '000011101111111111111111', '000011110111111111111111', '000011111011111111111111', '000011111101111111111111', '000011111110111111111111', '000011111111011111111111'|...],
LL = 42504.
I'm writing a simple code generating a simple list with 5 numbers whose first variable should be positive and I'm trying to understand why this code fails
test([H|T]) :- H > 0, length(T,4).
when I call with
length(X,5), test(X).
it shows me the following error:
ERROR: Arguments are not sufficiently instantiated
When I debug the code, the H variable in test isn't instantiated.
Anyone know why?
The issue here is that your rule for test([H|T]) doesn't describe in Prolog that H is a positive integer. It only tests if H > 0, which fails since H has not instantiation. Just attempting to compare an uninstantiated variable with a number (H > 0 in this case) doesn't cause Prolog to assume you intended H to be a number, and further, doesn't instantiate H.
Further, your rule for test/1 doesn't describe the rest of the list (T) other than to force that it be length 4. Since you're query establishes the rule that the length of the original list be 5, this stipulation is redundant.
You appear to be wanting to define test(L) such that it means L is an arbitrary list of positive integers. This is generally done using CLP(FD):
:- use_module(library(clpfd)).
test(X) :- X ins 1..10000.
This rule says that X is a list whose values are in the range 1 to 10000. The appropriate query to generate the lists of length 5 would then be:
?- length(X, 5), test(X), label(X).
X = [1, 1, 1, 1, 1] ;
X = [1, 1, 1, 1, 2] ;
X = [1, 1, 1, 1, 3] ;
X = [1, 1, 1, 1, 4] ;
X = [1, 1, 1, 1, 5] ;
...
If you want to restrict it further and say that elements need to be unique, you can use all_different/1:
test(X) :- X ins 1..10000, all_different(X).
?- length(X, 5), test(X), label(X).
X = [1, 2, 3, 4, 5] ;
X = [1, 2, 3, 4, 6] ;
X = [1, 2, 3, 4, 7] ;
X = [1, 2, 3, 4, 8] ;
X = [1, 2, 3, 4, 9] ;
X = [1, 2, 3, 4, 10] ;
...
Hi I have a dictionary like the below:
b = {'tat': 0, 'del': 4, 'galadriel': 0, 'sire': 0, 'caulimovirus': 4, 'retrofit': 0, 'tork': 0, 'caulimoviridae_dom2': 0, 'reina': 4, 'oryco': 2, 'cavemovirus': 1, 'soymovrius': 0, 'badnavirus': 0, 'crm': 0, 'athila': 0}
I want to find all keys with the maximum value as a list. However,
max(a, key=a.get)
only gives the first key element, 'del'.
How should I find all the keys with the maximum values? Like the below.
new_list = ['del', 'caulimovirus', 'reina']
maxv = max(b.values())
new_list = [k for k, v in b.items() if v == maxv]
Hello I was trying to modify a decimal to binary conversion function, so that it would display the results in a list. I'm new to prolog and I can't seem to get it to function properly.
dec2bin(0,0).
dec2bin(1,1).
dec2bin(N,L):- N>1,X is N mod 2,Y is N//2, dec2bin(Y,L1), L = [L1|[X]].
Then this is the result:
86 ?- dec2bin(26,L).
L = [[[[1, 1], 0], 1], 0]
Can someone help me understand what it is that I'm doing wrong.
Thanks
if you amend your code
dec2bin(0,[0]).
dec2bin(1,[1]).
dec2bin(N,L):-
N > 1,
X is N mod 2,
Y is N // 2,
dec2bin(Y,L1),
L = [X|L1].
you will get your solution with bits in reverse order:
?- dec2bin(26,L).
L = [0, 1, 0, 1, 1]
Instead of appending each bit, consider a final reverse/2, or invert the order by means of an accumulator
dec2bin(N,L) :- dec2bin(N,[],L).
dec2bin(0,L,[0|L]).
dec2bin(1,L,[1|L]).
dec2bin(N,L,R):-
N > 1,
X is N mod 2,
Y is N // 2,
dec2bin(Y,[X|L],R).
You have to apply some list concatenation, but you are just creating two terms lists and nesting them with L = [L1|[X]] when you consider L1 to be just a number.
If you consider it as a list, you can simply appending to it the newly created X, but to do so you have to rewrite the base cases of your recursion:
dec2bin(0,[0]).
dec2bin(1,[1]).
dec2bin(N,L):-
N > 1,
X is N mod 2,
Y is N // 2,
dec2bin(Y,L1),
append(L1, [X], L).
yielding to:
?- dec2bin(26,L).
L = [1, 1, 0, 1, 0]
where append/3 can be a library predicate or your own implementation.