I am brand new to Prolog. Literally this week. I am looking to write a recursive Prolog predicate that accepts two numbers X, Y as input. It should output to screen a list of all numbers less than or equal to X that are evenly divisible by Y.
I have been looking into this over the last few days and am thouroghly confused. I have started by trying to divide Y into 1, displaying this on screen and then repeating the process. Would anyone have tips on gettingthis working. Once I get that, I will then be trying to ensure these are less than or equal to X.
So far I have the below, which may be completely wrong. Any help is appreciated. Apologies if the formatting comes off badly.
divide(X, Y) :-
S is 1,
Z is Y / S,
S is S + 1,
write(Z),
divide(X, Y).
The numbers less than 20 which divide by 3 start 3, 6, 9, ... i.e. start with the divisor 3 and count up adding 3 each time until you get past the cutoff.
e.g.
countup(X, Y, Counter) :- % if the counter is below the limit,
Counter =< X,
writeln(Counter), % print it.
Next is Counter + Y, % count up by +Y, e.g. +3
countup(X, Y, Next). % loop.
countup(X, _, Counter) :- % if the counter is past the limit,
Counter > X. % stop.
divide(X, Y) :- % start counting from Y, e.g. 3
countup(X, Y, Y).
In your code, this line:
S is S + 1
is you saying "keep going if 2 is 3" and Prolog will say "it's not, case closed, stop here" and end your program. When you do S+1 you need to use a new variable for the result. Only the Prolog system can change variables, you can't (simplification).
This is the shape of an infinite loop:
divide(X, Y) :-
____,
____,
divide(X, Y).
X and Y never change so it's the same call each time; if it got past that S=S+1 then it would go round and round forever.
This shape:
divide(X, Y) :-
S is 1,
____,
divide(X, Y).
If it worked how you are trying, it would reset S back to 1 each time.
Since you need some case to handle looping and some case to handle stopping, and some test for passing the limit and something to pass S on through the loops, and I wanted words as variable names, quickly your short code turns into my much longer code even though it doesn't do much more.
(I didn't start from X and divide down because that would mean X had to be a multiple of Y. I thought you should be able to ask for the numbers less than 10 which are divisible by 9 and get 9 without having to deal with 10/9=1.11...)
Related
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
Hi cant figure out solution for below problem (here is a link to the original problem: Sumita and equal array
). please help?
Sumita is playing with a Array A of size N. she wants to make all the values of A to be equal. she can multiply any number of the values in the array any number of times by X, Y and Z. Your task is to tell her whether she can do it or not. Print "She can" if she can do it else print "She can't" without ""
Input :
First line of the input will contain T (No. of test cases).
For each test case, first line will contain four space separated integers denoting N, X, Y and Z.
Then next line will contain N space separated integers of A
Output :
For every test case, print the required answer in a new line.
Constraints :
1 ≤ T ≤ 5
2 ≤ N ≤ 10^5
X, Y, Z ∈ {2, 3, 5, 7}
1 ≤ Ai ≤ 10^9
SAMPLE INPUT:
2
2 2 2 2
2 4
3 2 3 2
2 6 7
SAMPLE OUTPUT:
She can
She can't
Explanation:
Test case #1: Multiply first value by 2.
Test case #2: Not possible.
My work so far: I find out lcm of X,Y,Z if each element inside that array is divided or can divide by lcm then ans is she can else she can't
Since you give ideas of your own but no code, I will do the same: give some ideas but no code. If you try coding this idea and get stuck, edit your question by showing your code and ask for more help.
You have the right idea of finding the Least Common Multiple (LCM) of the numbers in the given array. For each element of the array, you then can calculate the quotient of the LCM and the element--this quotient is guaranteed to be a positive integer. Then see if there is any prime divisor of that quotient that is not X, Y, or Z. If there is such a divisor, then your task is not possible: "She can't". If there is no such divisor, then this element passes the test. If all elements pass this test, the task is possible: "She can".
For your first array [2, 4] and X, Y, Z values [2, 2, 2], the array's LCM is 4. The first quotient is 4 // 2 = 2, the only prime divisor of that quotient is 2, and that is in the list of X, Y, Z. The second quotient is 4 // 4 = 1, which has no prime divisors, so that element also passes the test. All elements pass the test. so the task is possible.
For your second array [2, 6, 7] and X, Y, Z values [2, 3, 2], the array's LCM is 42. The first quotient is 42 // 2 = 21, which has the prime divisors 3 and 7. The first one (3) is in your list of X, Y, Z, but the last (7) is not, so the task is impossible. There is no need to check the quotients for the other elements of the array.
Can you program that? Note that I used Python's lists rather than arrays. Also note that this algorithm depends on the possible values of X, Y, Z being prime numbers--if they could be composite numbers, the algorithm would need to be adjusted and would be more complicated. To be more precise, the algorithm would need to be changed if any two possible values of X, Y, Z were distinct and were not relatively prime (had a Greatest Common Divisor greater than one).
I could just use division and modulus in a loop, but this is slow for really large integers. The number is stored in base two, and may be as large as 2^8192. I only need to know if it is a power of ten, so I figure there may be a shortcut (other than using a lookup table).
If your number x is a power of ten then
x = 10^y
for some integer y, which means that
x = (2^y)(5^y)
So, shift the integer right until there are no more trailing zeroes (should be a very low cost operation) and count the number of digits shifted (call this k). Now check if the remaining number is 5^k. If it is, then your original number is a power of 10. Otherwise, it's not. Since 2 and 5 are both prime this will always work.
Let's say that X is your input value, and we start with the assumption.
X = 10 ^ Something
Where Something is an Integer.
So we say the following:
log10(X) = Something.
So if X is a power of 10, then Something will be an Integer.
Example
int x = 10000;
double test = Math.log10(x);
if(test == ((int)test))
System.out.println("Is a power of 10");
I'm new to prolog. I'm doing a recursive program the problem is that even though it prints the answer.. it doesn't stop after printing the answer and eventually gives "Out of local stack".
I've read it could be a left recursion issue but as I've already told you I'm new to prolog and I don't really understand what happens...
so.. here's code.
f(X, Y):-
Y is sqrt(1-((X-1)*(X-1))).
sum(SEGMENTS, 1, TOTAL):-
f(2/SEGMENTS*1,H1),
TOTAL is (2/SEGMENTS)*H1.
sum(SEGMENTS, NR, TOTAL):-
N1 is (NR-1),
sum(SEGMENTS, N1, S1),
f(2/SEGMENTS*NR,H1),
f(2/SEGMENTS*N1,H2),
TOTAL is S1 + (2/SEGMENTS)*((H1+H2)/2).
It's supposed to calculate a semicircle area with the trapezoid rule or something similar.
As I've already told you .. it does finishes but after getting to the base case sum(segments, 1, total) it calls the function with the second alternative... :S
Thanks guys!
Also: Here's what I get when I run it
?- sum(3000,3000,TOTAL).
TOTAL = 1.5707983753431007 ;
ERROR: Out of local stack
The problem is that backtracking will attempt the case of NR value of 1 on the second sum clause after the first clause has succeeded. This causes a long recursion process (since NR is being decremented continually for each recursive call, attempting to wrap around through all negative integer values, etc).
A simple way to resolve the problem is in your second sum clause. Since the intention is that it is for the case of NR > 1, put NR > 1 as your first statement:
sum(SEGMENTS, NR, TOTAL) :-
NR > 1,
N1 is (NR-1),
sum(SEGMENTS, N1, S1),
f(2/SEGMENTS*NR,H1),
f(2/SEGMENTS*N1,H2),
TOTAL is S1 + (2/SEGMENTS)*((H1+H2)/2).
Also note that the expression f(2/SEGMENTS*NR, H1) doesn't compute the expression 2/SEGMENTS*NR and pass it to f. It actually passes that expression symbolically. It just happens to work here because f includes it on the right hand side of an is/2 so it is evaluated as desired. If you trace it, you'll see what I mean.
I'm almost embarrased to ask this, because it's probably VERY obvious - but I can't see a way out of this neatly and suspect there is one.
I have a variable which I need to add/subtract values from - but I want to keep it within a range of values, looping around at either end - e.g.
Range is 0-3 so values are 0,1,2,3,0,1,2,3 - and this does that
x = (x + val) MOD 4
When val is negative, however, we should see 0,3,2,1,0,3,2,1 and the solution is FAR less elegant
x = (x + val) MOD 4
if (x < 0) x = 4 + x;
That works, but it's clunky and I can't help thinking there might be a 'one line' solution to this - but I'm damned if I can think of it? :)
prepares for embarrassment
As indicated by TaZ, most "modulo" operators are really remainder operators that only work like a "mathematical modulo" for x+val >= 0.
In c++, as found here (with some modifications), you can define a more "mathematically correct" modulo like so
double mod(double x, double y) { return y!=0 ? x-floor(x/y)*y : x; }
(perhaps also make an integer version), such that
x = mod(x+val,4);
works for both positive and negative x+val.
I'm working my way through How to Design Programs on my own. I haven't quite grasped complex linear recursion, so I need a little help.
The problem:
Define multiply, which consumes two natural numbers, n and x, and produces n * x without using Scheme's *. Eliminate + from this definition, too.
Straightforward with the + sign:
(define (multiply n m)
(cond
[(zero? m) 0]
[else (+ n (multiply n (sub1 m)))]))
(= (multiply 3 3) 9)
I know to use add1, but I can't it the recursion right.
Thanks.
Split the problem in two functions. First, you need a function (add m n) which adds m to n. What is the base case? when n is zero, return m. What is the recursive step? add one to the result of calling add again, but decrementing n. You guessed it, add1 and sub1 will be useful.
The other function, (mul m n) is similar. What is the base case? if either m or n are zero, return 0. What is the recursive step? add (using the previously defined function) m to the result of calling mul again, but decrementing n. And that's it!
Since this is almost certainly a homework-type question, hints only.
How do you add 7 and 2? While most people just come up with 9, is there a more basic way?
How about you increment the first number and decrement the second number until one of them reaches zero?
Then the other one is the answer. Let's try the sample:
7 2
8 1
9 0 <- bingo
This will work fine for natural numbers though you need to be careful if you ever want to apply it to negatives. You can get into the situation (such as with 10 and -2) where both numbers are moving away from zero. Of course, you could check for that before hand and swap the operations.
So now you know can write + in terms of an increment and decrement instruction. It's not fantastic for recursion but, since your multiply-by-recursive-add already suffers the same problem, it's probably acceptable.
Now you just have to find out how to increment and decrement in LISP without using +. I wonder whether there might be some specific instructions for this :-)