Why does this query not terminate? - prolog

I've written a generator which generates a string of digits given a description of them:
:- use_module(library(clpfd)).
some(_Int, 0) --> [].
some(Int, Count) --> {Count #> 0, Count1 #= Count - 1}, [Int], some(Int, Count1).
many([]) --> [].
many([some(X, N)|Rest]) --> some(X, N), many(Rest).
This works when run forward:
?- phrase(many([some(0, 3), some(1, 2)]), Some).
Some = [0, 0, 0, 1, 1] ;
false.
Well, it leaves a choicepoint, but at least it first gives the correct result. It loops forever when asked to generate a description for a given string of digits:
?- phrase(many([Some|Rest]), [0, 0, 0, 1, 1]).
OOPS
What am I doing wrong?

I'm going to give you a slightly "operational" perspective on what your problem is. Dijkstra forgive me.
The crux of the problem is that there is a way for you to do nothing in many//2 and then again in some//2. Your first clause of many//2 is happy to eat none of the input. But, in your second clause, you sort of assume that some//2 is going to eat some of your input--but it doesn't have to, and then you are recurring back into your first clause of many//2, which still doesn't have to eat any input. So you find yourself in a recursive call to many//2, back in the second clause of many//2 once again, with precisely the same input as when you started. This is your loop!
The solution is to ensure that some//2 definitely does some work: the first clause has to go:
some(Int, 1) --> [Int].
some(Int, Count) --> {Count #> 0, Count1 #= Count - 1}, [Int], some(Int, Count1).
This is not as aggressive as you'd probably like in folding together some/2 structures, but it does work and it terminates:
?- phrase(many([Some|Rest]), [0, 0, 0, 1, 1]).
Some = some(0, 1),
Rest = [some(0, 1), some(0, 1), some(1, 1), some(1, 1)] ;
Some = some(0, 1),
Rest = [some(0, 1), some(0, 1), some(1, 2)] ;
Some = some(0, 1),
Rest = [some(0, 2), some(1, 1), some(1, 1)] ;
Some = some(0, 1),
Rest = [some(0, 2), some(1, 2)] ;
Some = some(0, 2),
Rest = [some(0, 1), some(1, 1), some(1, 1)] ;
Some = some(0, 2),
Rest = [some(0, 1), some(1, 2)] ;
Some = some(0, 3),
Rest = [some(1, 1), some(1, 1)] ;
Some = some(0, 3),
Rest = [some(1, 2)] .

Related

Cartesian product but remove duplicates up to cyclic permutations

Given two integers n and r, I want to generate all possible combinations with the following rules:
There are n distinct numbers to choose from, 1, 2, ..., n;
Each combination should have r elements;
A combination may contain more than one of an element, for instance (1,2,2) is valid;
Order matters, i.e. (1,2,3) and (1,3,2) are considered distinct;
However, two combinations are considered equivalent if one is a cyclic permutation of the other; for instance, (1,2,3) and (2,3,1) are considered duplicates.
Examples:
n=3, r=2
11 distinct combinations
(1,1,1), (1,1,2), (1,1,3), (1,2,2), (1,2,3), (1,3,2), (1,3,3), (2,2,2), (2,2,3), (2,3,3) and (3,3,3)
n=2, r=4
6 distinct combinations
(1,1,1,1), (1,1,1,2), (1,1,2,2), (1,2,1,2), (1,2,2,2), (2,2,2,2)
What is the algorithm for it? And how to implement it in c++?
Thank you in advance for advice.
Here is a naive solution in python:
Generate all combinations from the Cartesian product of {1, 2, ...,n} with itself r times;
Only keep one representative combination for each equivalency class; drop all other combinations that are equivalent to this representative combination.
This means we must have some way to compare combinations, and for instance, only keep the smallest combination of every equivalency class.
from itertools import product
def is_representative(comb):
return all(comb[i:] + comb[:i] >= comb
for i in range(1, len(comb)))
def cartesian_product_up_to_cyclic_permutations(n, r):
return filter(is_representative,
product(range(n), repeat=r))
print(list(cartesian_product_up_to_cyclic_permutations(3, 3)))
# [(0, 0, 0), (0, 0, 1), (0, 0, 2), (0, 1, 1), (0, 1, 2), (0, 2, 1), (0, 2, 2), (1, 1, 1), (1, 1, 2), (1, 2, 2), (2, 2, 2)]
print(list(cartesian_product_up_to_cyclic_permutations(2, 4)))
# [(0, 0, 0, 0), (0, 0, 0, 1), (0, 0, 1, 1), (0, 1, 0, 1), (0, 1, 1, 1), (1, 1, 1, 1)]
You mentioned that you wanted to implement the algorithm in C++. The product function in the python code behaves just like a big for-loop that generates all the combinations in the Cartesian product. See this related question to implement Cartesian product in C++: Is it possible to execute n number of nested "loops(any)" where n is given?.

Combinations sum depth first search solution

Given a list of positive integers and a target value, generate a solution set. For example, if the list is [10, 1, 2, 7, 6, 1, 5] and the target is 8, the solution set is...
[
[1, 7],
[1, 2, 5],
[2, 6]
[1, 1, 6]
[
I know there a multiple solutions to this, such as dp, but I am trying to get my dfs solution working and I believe I am very close, but I simply cannot get the correct result. If possible, I would like it if you didn't change my initial answer too much, if that's not possible, any solution will do.
def combinationSum(self, candidates, target):
candidates.sort()
total = []
self.helper(candidates, 0, target, [], total)
def helper(self, candidates, curr, target, temp, total):
if target == 0:
total.append(temp)
return
if target < 0:
return
for i in range(curr, len(candidates)):
# avoid duplicates
if i > curr and candidates[i] == candidates[i-1]:
continue
temp.append(candidates[i])
self.helper(candidates, i+1, target-candidates[i], temp, total)
# I'm not sure what to do here
This obviously does not give me the right result but I do think I am on the right track towards generating the solution set. I simply do not understand what I need to do after the recursive call to remove unnecessary elements.
I think this is along the lines of what you are trying to do:
def solve(target, sum, candidates, answer):
if sum == target:
print answer
return
if len(candidates) == 0 or sum > target:
return
first = candidates[0]
count = candidates.count(first);
answer.append(first)
solve(target, sum+first, candidates[1:], answer) #using the current number
answer.pop()
solve(target, sum, candidates[count:], answer) #skipping the current number and any duplicates
if __name__ == "__main__":
candidates = [10, 1, 2, 7, 6, 1, 5]
candidates.sort();
solve(8, 0, candidates, [])
The key point is that solve has two recursive calls.
The first recursive call uses the first number in the candidates list. So it
appends the first number to the answer
adds the first number to the sum
removes only the first number from the candidates list that is
passed to the next level
The second recursive call doesn't use the first number in the candidates list. And since it doesn't use the first number, it also doesn't use any duplicates of the first number. That's the reason for the count variable. candidates.count(first) is the number of entries in the list that are equal to first. So in the recursive call candidates[count:] removes the first element and any duplicates. (This assumes that the list is sorted, which should be done once before calling solve).
Here's one possible solution using recursion – I chose a tuple to represent the combinations, but you could've used list for those too
def combinationSum (l, target, sum = 0, comb = ()):
# base case: empty input [l]
if not l:
return []
# inductive case: [l] has at least one element
else:
# [x] is the first sub-problem
# [xs] is the rest of the sub-problems
x, *xs = l
# [x] plus [sum] is bigger than [target]
if x + sum > target:
return \
combinationSum (xs, target, sum, comb)
# [x] plus [sum] is smaller than [target]
elif x + sum < target:
return \
combinationSum (xs, target, sum + x, (x, *comb)) + \
combinationSum (xs, target, sum, comb)
# [x] plus [sum] is equal to [target]
else:
return \
[ (x, *comb) ] + \
combinationSum (xs, target, sum + x, (x, *comb)) + \
combinationSum (xs, target, sum, comb)
data = [10, 1, 2, 7, 6, 1, 5]
print (combinationSum (data, 8))
# [(5, 2, 1), (7, 1), (1, 6, 1), (6, 2), (5, 1, 2), (1, 7)]
If you want combinationSum to allow for duplicate values, you only have to change one part. Note, the program considers eg (5, 1, 1, 1) a solution 3 times because the 1 appears in 3 unique positions. If you only wanted (5, 1, 1, 1) to appear once, you'd have to consider a different approach.
...
elif x + sum < target:
return \
combinationSum (xs, target, sum + x, (x, *comb)) + \
combinationSum (l , target, sum + x, (x, *comb)) + \
combinationSum (xs, target, sum, comb)
...
print (combinationSum (data, 8))
# [ (1, 1, 1, 1, 1, 1, 1, 1)
# , (1, 1, 1, 1, 1, 1, 1, 1)
# , (2, 1, 1, 1, 1, 1, 1)
# , (1, 1, 1, 1, 1, 1, 1, 1)
# , (1, 2, 1, 1, 1, 1, 1)
# , (1, 1, 1, 1, 1, 1, 1, 1)
# , (2, 2, 1, 1, 1, 1)
# , (1, 1, 2, 1, 1, 1, 1)
# , (1, 1, 1, 1, 1, 1, 1, 1)
# , (1, 2, 2, 1, 1, 1)
# , (1, 1, 1, 2, 1, 1, 1)
# , (1, 1, 1, 1, 1, 1, 1, 1)
# , (5, 1, 1, 1)
# , (2, 2, 2, 1, 1)
# , (1, 1, 2, 2, 1, 1)
# , (1, 1, 1, 1, 2, 1, 1)
# , (6, 1, 1)
# , (1, 1, 1, 1, 1, 1, 1, 1)
# , (5, 1, 1, 1)
# , (1, 2, 2, 2, 1)
# , (1, 1, 1, 2, 2, 1)
# , (1, 1, 1, 1, 1, 2, 1)
# , (5, 2, 1)
# , (7, 1)
# , (1, 6, 1)
# , (1, 1, 1, 1, 1, 1, 1, 1)
# , (5, 1, 1, 1)
# , (2, 2, 2, 2)
# , (1, 1, 2, 2, 2)
# , (1, 1, 1, 1, 2, 2)
# , (6, 2)
# , (1, 1, 1, 1, 1, 1, 2)
# , (5, 1, 2)
# , (1, 7)
# , (1, 1, 6)
# , (1, 1, 1, 1, 1, 1, 1, 1)
# , (5, 1, 1, 1)]
# ]

What is prolog query for finding possible values

This is my prolog program:
par(0,0).
par(0,1).
par(0,2).
par(1,0).
par(1,2).
par(1,1).
par(2,1).
par(2,0).
par(2,2).
gp(X,Y):- par(X,Z),par(Z,Y).
ggp(X,Y) :- par(X,Z), par(Z,W), par(W,Y).
What query must be used to obtain he possible set of tuples to satisfy the rules gp and ggp
I tried using gp (X,Y) but doesn't give me the tuples.
Also gp and ggp are not related. The tuples that satisfy ggp does not have to necessarily satisfy the rule gp
You only need to "pack" the X and Y together into a tuple, like:
tuple_gp((X,Y)) :-
gp(X,Y).
tuple_ggp((X,Y)) :-
ggp(X,Y).
This then can answer with:
?- tuple_gp(T).
T = (0, 0) ;
T = (0, 1) ;
T = (0, 2) ;
T = (0, 0) ;
T = (0, 2) ;
T = (0, 1) ;
T = (0, 1) ;
T = (0, 0) ;
T = (0, 2) ;
T = (1, 0) ;
T = (1, 1) ;
T = (1, 2) ;
T = (1, 1) ;
T = (1, 0) ;
T = (1, 2) ;
T = (1, 0) ;
T = (1, 2) ;
T = (1, 1) ;
T = (2, 0) ;
T = (2, 2) ;
T = (2, 1) ;
T = (2, 0) ;
T = (2, 1) ;
T = (2, 2) ;
T = (2, 1) ;
T = (2, 0) ;
T = (2, 2).
If you want to generate a list of all possible tuples, you can use findall/3:
?- findall((X,Y),gp(X,Y),L).
L = [ (0, 0), (0, 1), (0, 2), (0, 0), (0, 2), (0, 1), (0, 1), (0, 0), (..., ...)|...].
?- findall((X,Y),ggp(X,Y),L).
L = [ (0, 0), (0, 1), (0, 2), (0, 0), (0, 2), (0, 1), (0, 1), (0, 0), (..., ...)|...].
If you want only to obtain unique tuples, you can use setof/3:
?- setof((X,Y),X^Y^gp(X,Y),S).
S = [ (0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (..., ...)].

Print all permutations of possible outcomes given N rounds of RPS using a stack

Given n rounds, print all possible permutations to rock paper scissor using a stack as the main strategy.
I use to know how to do this, but I'm stump after not having exercise stacks for a while.
Can someone provide a helpful hint as to how the stack should be populated?
I know there are 3^n outputs for n input.
For n = 1, the expected answer is 3. A possible solution would be:
def rps(n)
stack = []
answer = []
if n > 0
stack.push([r,p,s])
n -= 1
while !stack.isEmpty()
array = stack.pop();
forEach elem in array
// I still can't figure out where to go from here!!
I know in the recursive solution, it'll go r,p,s for n=1
for n=2, the answer gets appended with rr, rp, rs, pr, pp, ps, sr, sp, ss
for n=3, it'll be rrr, rrp, rrs, rpr, etc...
From my understanding, we can start with empty stack, and for each permutation pop out of the stack, we append all possibility to the permutation, and add it back to the stack.
Stack s = new Stack();
s.add("");
ArrayList<String> result;
while(!s.isEmpty()){
String v = s.pop();
if(v.length() == n){//All n rounds finished, add to final result
result.add(v);
continue;
}
//Now, add the result of this round to the current permutation.
s.push(v + "r");
s.push(v + "s");
s.push(v + "p");
}
return result;
I generalize this question to finding all permutations of numbers from 0 to N (in this case N is 3). One way to solve this is using recursion:
def rec(stack, used):
if len(stack) == len(L):
print stack
i = stack.pop(-1)
used[i] = 0
return
for i in range(len(L)):
if used[i] == 0:
stack.append(i)
used[i] = 1
rec(stack,used)
if len(stack):
i = stack.pop(-1)
used [i] = 0
else:
return
N = 3
rec([],[0]*N,N)
What we do is we append the first unused item to our list and call the function again (backtracking). When our list is full print that list. This gives all of the possible permutations:
[0, 1, 2]
[0, 2, 1]
[1, 0, 2]
[1, 2, 0]
[2, 0, 1]
[2, 1, 0]
While this method is using a stack but I doubt that it was in fact the intention of the question.
The main idea of the question is Implement a backtrack method to find all permutations of a list in an iterative method. That's where the stack comes in.
We can simply imitate the recursive function by using a stack:
stack = [(0,1)]
used = [1,0,0]
N = 3
def iterative():
while 1:
if len(stack) == N:
print [x[0] for x in stack]
i,x = stack.pop(-1)
used[i] = 0
continue
top = stack.pop(-1)
index = top[1]
for i in range(index,N):
if used[i] == 0:
stack.append( (top[0],i+1) )
stack.append( (i,0) )
used[i] = 1
break
else:
used[top[0]] = 0
if len(stack)==0:
if top[0]+1 < N:
stack.append((top[0]+1,0))
used[top[0]+1] = 1
else:
break
The only difference is recursive functions have some local variables within them that upon resume of their execution they remember them. We can put these local variables in our stack. In this case in addition to the actual item that we put in the list we remember from what value we shoud resume our checking (this is the variable of the for loop in the recursive function). This is what happens:
#[stack] [used]
[(0, 1)] [1, 0, 0]
[(0, 2), (1, 0)] [1, 1, 0]
[(0, 2), (1, 3), (2, 0)] [1, 1, 1]
A new permutation: [0, 1, 2]
[(0, 2), (1, 3)] [1, 1, 0]
[(0, 2)] [1, 0, 0]
[(0, 3), (2, 0)] [1, 0, 1]
[(0, 3), (2, 2), (1, 0)] [1, 1, 1]
A new permutation: [0, 2, 1]
[(0, 3), (2, 2)] [1, 0, 1]
[(0, 3)] [1, 0, 0]
[(1, 0)] [0, 1, 0]
[(1, 1), (0, 0)] [1, 1, 0]
[(1, 1), (0, 3), (2, 0)] [1, 1, 1]
A new permutation: [1, 0, 2]
[(1, 1), (0, 3)] [1, 1, 0]
[(1, 1)] [0, 1, 0]
[(1, 3), (2, 0)] [0, 1, 1]
[(1, 3), (2, 1), (0, 0)] [1, 1, 1]
A new permutation: [1, 2, 0]
[(1, 3), (2, 1)] [0, 1, 1]
[(1, 3)] [0, 1, 0]
[(2, 0)] [0, 0, 1]
[(2, 1), (0, 0)] [1, 0, 1]
[(2, 1), (0, 2), (1, 0)] [1, 1, 1]
A new permutation: [2, 0, 1]
[(2, 1), (0, 2)] [1, 0, 1]
[(2, 1)] [0, 0, 1]
[(2, 2), (1, 0)] [0, 1, 1]
[(2, 2), (1, 1), (0, 0)] [1, 1, 1]
A new permutation: [2, 1, 0]
[(2, 2), (1, 1)] [0, 1, 1]
[(2, 2)] [0, 0, 1]
Finished

How to efficiently enumerate all points of sphere in n-dimensional grid

Say, we have an N-dimensional grid and some point X in it with coordinates (x1, x2, ..., xN).
For simplicity we can assume that the grid is unbounded.
Let there be a radius R and a sphere of this radius with center in X, that is the set of all points in grid such that their manhattan distance from X is equal to R.
I suspect that their will be 2*N*R such points.
My question is: how do I enumerate them in efficient and simple way? By "enumerate" I mean the algorithm, which, given N, X and R will produce the list of points which form this sphere (where point is the list of it's coordinates).
UPDATE: Initially I called the metric I used "Hamming distance" by mistake. My apologies to all who answered the question. Thanks to Steve Jessop for pointing this out.
Consider the minimal axis-aligned hypercube that bounds the hypersphere and write a procedure to enumerate the grid points inside the hypercube.
Then you only need a simple filter function that allows you to discard the points that are on the cube but not in the hypersphere.
This is a simple and efficient solution for small dimensions. For instance, for 2D, 20% of the points enumerated for the bounding square are discarded; for 6D, almost 90% of the hypercube points are discarded.
For higher dimensions, you will have to use a more complex approach: loop over every dimension (you may need to use a recursive function if the number of dimensions is variable). For every loop you will have to adjust the minimal and maximal values depending on the values of the already calculated grid components. Well, try doing it for 2D, enumerating the points of a circle and once you understand it, generalizing the procedure to higher dimensions would be pretty simple.
update: errh, wait a minute, you want to use the Manhattan distance. Calling the cross polytope "sphere" may be correct but I found it quite confusing! In any case you can use the same approach.
If you only want to enumerate the points on the hyper-surface of the cross polytope, well, the solution is also very similar, you have to loop over every dimension with appropriate limits. For instance:
for (i = 0; i <= n; i++)
for (j = 0; j + i <= n; j++)
...
for (l = 0; l + ...+ j + i <= n; l++) {
m = n - l - ... - j - i;
printf(pat, i, j, ..., l, m);
}
For every point generated that way, then you will have to consider all the variations resulting of negating any of the components to cover all the faces and then displace them with the vector X.
update
Perl implementation for the case where X = 0:
#!/usr/bin/perl
use strict;
use warnings;
sub enumerate {
my ($d, $r) = #_;
if ($d == 1) {
return ($r ? ([-$r], [$r]) : [0])
}
else {
my #r;
for my $i (0..$r) {
for my $s (enumerate($d - 1, $r - $i)) {
for my $j ($i ? (-$i, $i) : 0) {
push #r, [#$s, $j]
}
}
}
return #r;
}
}
#ARGV == 2 or die "Usage:\n $0 dimension radius\n\n";
my ($d, $r) = #ARGV;
my #r = enumerate($d, $r);
print "[", join(',', #$_), "]\n" for #r;
Input: radius R, dimension D
Generate all integer partitions of R with cardinality ≤ D
For each partition, permute it without repetition
For each permutation, twiddle all the signs
For example, code in python:
from itertools import *
# we have to write this function ourselves because python doesn't have it...
def partitions(n, maxSize):
if n==0:
yield []
else:
for p in partitions(n-1, maxSize):
if len(p)<maxSize:
yield [1] + p
if p and (len(p)<2 or p[1]>p[0]):
yield [ p[0]+1 ] + p[1:]
# MAIN CODE
def points(R, D):
for part in partitions(R,D): # e.g. 4->[3,1]
part = part + [0]*(D-len(part)) # e.g. [3,1]->[3,1,0] (padding)
for perm in set(permutations(part)): # e.g. [1,3,0], [1,0,3], ...
for point in product(*[ # e.g. [1,3,0], [-1,3,0], [1,-3,0], [-...
([-x,x] if x!=0 else [0]) for x in perm
]):
yield point
Demo for radius=4, dimension=3:
>>> result = list( points(4,3) )
>>> result
[(-1, -2, -1), (-1, -2, 1), (-1, 2, -1), (-1, 2, 1), (1, -2, -1), (1, -2, 1), (1, 2, -1), (1, 2, 1), (-2, -1, -1), (-2, -1, 1), (-2, 1, -1), (-2, 1, 1), (2, -1, -1), (2, -1, 1), (2, 1, -1), (2, 1, 1), (-1, -1, -2), (-1, -1, 2), (-1, 1, -2), (-1, 1, 2), (1, -1, -2), (1, -1, 2), (1, 1, -2), (1, 1, 2), (0, -2, -2), (0, -2, 2), (0, 2, -2), (0, 2, 2), (-2, 0, -2), (-2, 0, 2), (2, 0, -2), (2, 0, 2), (-2, -2, 0), (-2, 2, 0), (2, -2, 0), (2, 2, 0), (-1, 0, -3), (-1, 0, 3), (1, 0, -3), (1, 0, 3), (-3, -1, 0), (-3, 1, 0), (3, -1, 0), (3, 1, 0), (0, -1, -3), (0, -1, 3), (0, 1, -3), (0, 1, 3), (-1, -3, 0), (-1, 3, 0), (1, -3, 0), (1, 3, 0), (-3, 0, -1), (-3, 0, 1), (3, 0, -1), (3, 0, 1), (0, -3, -1), (0, -3, 1), (0, 3, -1), (0, 3, 1), (0, -4, 0), (0, 4, 0), (0, 0, -4), (0, 0, 4), (-4, 0, 0), (4, 0, 0)]
>>> len(result)
66
(Above I used set(permutations(...)) to get permutations without repetition, which is not efficient in general, but it might not matter here due to the nature of the points. And if efficiency mattered, you could write your own recursive function in your language of choice.)
This method is efficient because it does not scale with the hypervolume, but just scales with the hypersurface, which is what you're trying to enumerate (might not matter much except for very large radii: e.g. will save you roughly a factor of 100x speed if your radius is 100).
You can work your way recursively from the center, counting zero distance once and working on symmetries. This Python implementation works on the lower-dimension "stem" vector and realizes one 1-dimensional slice at a time. One might also do the reverse, but it would imply iterating on the partial hyperspheres. While mathematically the same, the efficiency of both approaches is heavily language-dependent.
If you know beforehand the cardinality of the target space, I would recommend to write an iterative implementation.
The following enumerates the points on a R=16 hyper-LEGO block in six dimensions in about 200 ms on my laptop. Of course, performance rapidly decreases with more dimensions or larger spheres.
def lapp(lst, el):
lst2 = list(lst)
lst2.append(el)
return lst2
def hypersphere(n, r, stem = [ ]):
mystem = lapp(stem, 0)
if 1 == n:
ret = [ mystem ]
for d in range(1, r+1):
ret.append(lapp(stem, d))
ret.append(lapp(stem, -d))
else:
ret = hypersphere(n-1, r, mystem)
for d in range(1, r+1):
mystem[-1] = d
ret.extend(hypersphere(n-1, r-d, mystem))
mystem[-1] = -d
ret.extend(hypersphere(n-1, r-d, mystem))
return ret
(This implementation assumes the hypersphere is centered in the origin. It would be easier to translate all points afterwards than carrying along the coordinates of the center).

Resources