I'm suppose to write f:N->N
f(0)=2,f(1)=0,f(2)=3
f(n)=3f(n-3)+2f(n-2)-(n-1) for n>=3.
both iteratively and recursively,
This is what I have so far iteratively but i keep getting 3 for N>2
f(0,2).
f(1,0).
f(2,3).
f(N,F) :-
N>2,
N1 is N-1,
N2 is N-2,
N3 is N-3,
f(N1,F1),
f(N2,F2),
f(N3,F3),
F4 is F2*2,
F6 is F3*3,
F5 is F4+F6,
F is F5-F1.
Any help you can give me is greatly appreciated!
Works fine for me!
?- f(5,X).
X = 12 .
?- f(6,X).
X = 3 .
?- f(7,X).
X = 30 .
?- f(8,X).
X = 12 .
Maybe you just tried with a lot values that return 3?
Also, you could have done:
f(N,F) :- N>2, N1 is N-1, N2 is N-2, N3 is N-3,
f(N1,F1), f(N2,F2), f(N3,F3),
F is 3*F3 + 2*F2 - F1.
Related
I have a node type like the following :
type position = float * float
type node = position
I wrote these modules to use nodes as keys in my Map :
module MyMap =
struct
type t = node
let compare n1 n2 =
if n1 = n2 then 1
else 0
end
module Dist = Map.Make(MyMap)
Then I created an empty Map :
let mapTest = Dist.empty;;
let mapTest = Dist.add (1.,1.) 1. mapTest;;
I get the length of the Map like this :
Dist.cardinal mapTest;;
- : int = 1
I try to add another element :
let mapTest = Dist.add (2.,2.) 2. mapTest;;
But then my Map is still of length 1 when I use Dist.cardinal mapTest
More surprising, when I run :
Dist.find (1.,1.) mapTest;;
- : float = 2.
So now I'm left clueless about what's going on or what I've done wrong.
My goal is to be able to use the Map, add bindings etc.
Any ideas?
Thanks
The compare function does not behave as expected : it is expected to return 0 when n1 and n2 are equals, otherwise 1 if n1 is greater than n2, -1 if not.
The following code shall fix the issue :
module MyMap =
struct
type t = node
let compare (a1,b1) (a2,b2) =
if a1 > a2 then 1
else if a1 < a2 then -1
else if b1 > b2 then 1
else if b1 < b2 then -1
else 0
end
let compare n1 n2 =
if n1 = n2 then 1
else 0
It looks like you've misunderstood how compare is supposed to behave. Here's the description of compare from the documentation of OrderedType:
This is a two-argument function f such that f e1 e2 is zero if the keys e1 and e2 are equal, f e1 e2 is strictly negative if e1 is smaller than e2, and f e1 e2 is strictly positive if e1 is greater than e2.
So the way you defined it, n1 would be considered greater than n2 if n1 = n2 and otherwise n1 would be considered equal to n2. This does not follow any of the rules you'd expect from a comparison function: a key isn't considered equal to itself and "n1 is greater than n2" can (and in fact always will) be true at the same time as "n2 is greater than n1". Consequently the map will not behave in a sensible way.
Assuming you want to consider one node equal to another if and only if they contain the same values in the same order, you can just define compare using Stdlib.compare.
That is not how you're supposed to write the compare function.
To quote the manual:
A total ordering function over the keys. This is a two-argument
function f such that f e1 e2 is zero if the keys e1 and e2 are equal,
f e1 e2 is strictly negative if e1 is smaller than e2, and f e1 e2 is
strictly positive if e1 is greater than e2. Example: a suitable
ordering function is the generic structural comparison function
compare.
So your compare function should be:
let compare n1 n2 =
if n1 < n2 then -1
else if n1 > n2 then 1
else 0
Note that on floating point numbers, comparison is weird. First, the rounding makes some numbers that seem equal to not be so. Second and even worse, the standard comparisons are not total (they all always return false on a NaN).
Thankfully, you can trust the standard compare function to solve the latter problem:
let compare (n1:t) n2 = Stdlib.compare n1 n2
I want to get the sum of function f(i) values when i is equal from a to b
= f(a)+f(a+1)+...+f(b-1)+f(b)
So I wrote code like this.
let rec sigma : (int -> int) -> int -> int -> int
= fun f a b ->
if a=b then f a
else f b + sigma f a b-1 ;;
but result is that there is stack overflow during evaluation. Is there a infinite loop? and why?
sigma f a b-1 is parsed as (sigma f a b) - 1 instead of your intention, sigma f a (b-1). Since sigma f a b calls sigma f a b recursively in your code, it never stops.
The best practice is to put white spaces around binary operators like sigma f a b - 1 so that you would not misread what you write.
I'm attempting a prolog question that states the following:
A magic square is a 3× 3 matrix of distinct numbers (between 1 and 9) such that all rows and columns add up to the same total (but not necessarily the diagonals). For example:
2 7 6
9 5 1
4 3 8
is a magic square.
We will represent squares in Prolog as 3 × 3 matrices, i.e. lists of lists [R1, R2, R3] where each R_i is a list of three numbers. For example, the
representation of the above magic square is
[[2,7,6],[9,5,1],[4,3,8]]
Define a predicate magic/1 that tests whether a ground 3 × 3 matrix (i.e.
where all the entries are numbers) is a magic square.
I've done this the following way, and I'm pretty sure it's allowed if I also do it like this in an exam, however to me it seems like sort of a hack:
magic([[A,B,C], [D,E,F], [G,H,I]]) :-
Y is A + B + C,
Y is D + E + F,
Y is G + H + I,
Y is A + D + G,
Y is B + E + H,
Y is C + F + I.
My desired way would be to recurse through each list in the outer list, and sum it up. For each of the lists in outer list, they should sum up to the same value (I think 15 is actually the only possible solution for this "magic" matrix). Likewise, I do the same for the columns (take the first, second and 3rd of each list and add up respectively). However, I'm not entirely sure how to do the latter as I haven't been working with list of lists much. I would appreciate if anybody would give a neat solution on how these sort of computations can be done generally.
Thanks
Note that your solution does not check that A, ..,I values are distinct and in the range 1..9. Here is a solution for NxN squares for N > 2:
magic(L) :-
magic_range(L),
magic_sum(S, L),
magic_line(S, L),
transpose(L, T),
magic_line(S, T).
% S value from https://oeis.org/A006003
magic_sum(S, L) :-
length(L, N),
S is N * (N*N + 1) / 2.
magic_range(L) :-
flatten(L, F),
sort(F, S),
length(L, N),
N2 is N * N,
numlist(1, N2, S).
magic_line(_, []).
magic_line(S, [A | As]) :-
sumlist(A, S),
magic_line(S, As).
% https://github.com/SWI-Prolog/swipl-devel/blob/9452af09962000ebb5157fe06169bbf51af5d5c9/library/clp/clpfd.pl#L6411
transpose(Ls, Ts) :-
must_be(list(list), Ls),
lists_transpose(Ls, Ts).
lists_transpose([], []).
lists_transpose([L|Ls], Ts) :-
foldl(transpose_, L, Ts, [L|Ls], _).
transpose_(_, Fs, Lists0, Lists) :-
maplist(list_first_rest, Lists0, Fs, Lists).
list_first_rest([L|Ls], L, Ls).
Some queries
?- magic([[1,1,1],[1,1,1],[1,1,1]]).
false.
?- magic([[2,7,6],[9,5,1],[4,3,8]]).
true ;
false.
?- magic([[16,3,2,13], [5,10,11,8], [9,6,7,12], [4,15,14,1]]).
true ;
false.
The transpose predicate is the most complicated part. See here for some alternatives.
As the title says I want to write a program that does this.
an example would be:
?- count(member(X,[1,2,3]), N).
N = 3
Yes
But not only for the build in member, but also for some operators like:
?- count(17 =:= 12 + 5, N).
N = 1
Yes
Can someone help me get started?
Try this:
?- findall(., Goal, Ls), length(Ls, L).
Example:
?- findall(., member(X,[1,2,3]), Ls), length(Ls, L).
L = 3,
... .
library(aggregate) has been implemented to provide solutions for your problem, and much more...
?- aggregate(count, X^member(X,[1,2,3]), N).
N = 3.
?- aggregate(count, 17 =:= 12 + 5, N).
N = 1.
Exercise 1.11:
A function f is defined by the rule that f(n) = n if n < 3 and f(n) = f(n - 1) + 2f(n - 2) + 3f(n - 3) if n > 3. Write a procedure that computes f by means of a recursive process. Write a procedure that computes f by means of an iterative process.
Implementing it recursively is simple enough. But I couldn't figure out how to do it iteratively. I tried comparing with the Fibonacci example given, but I didn't know how to use it as an analogy. So I gave up (shame on me) and Googled for an explanation, and I found this:
(define (f n)
(if (< n 3)
n
(f-iter 2 1 0 n)))
(define (f-iter a b c count)
(if (< count 3)
a
(f-iter (+ a (* 2 b) (* 3 c))
a
b
(- count 1))))
After reading it, I understand the code and how it works. But what I don't understand is the process needed to get from the recursive definition of the function to this. I don't get how the code could have formed in someone's head.
Could you explain the thought process needed to arrive at the solution?
You need to capture the state in some accumulators and update the state at each iteration.
If you have experience in an imperative language, imagine writing a while loop and tracking information in variables during each iteration of the loop. What variables would you need? How would you update them? That's exactly what you have to do to make an iterative (tail-recursive) set of calls in Scheme.
In other words, it might help to start thinking of this as a while loop instead of a recursive definition. Eventually you'll be fluent enough with recursive -> iterative transformations that you won't need to extra help to get started.
For this particular example, you have to look closely at the three function calls, because it's not immediately clear how to represent them. However, here's the likely thought process: (in Python pseudo-code to emphasise the imperativeness)
Each recursive step keeps track of three things:
f(n) = f(n - 1) + 2f(n - 2) + 3f(n - 3)
So I need three pieces of state to track the current, the last and the penultimate values of f. (that is, f(n-1), f(n-2) and f(n-3).) Call them a, b, c. I have to update these pieces inside each loop:
for _ in 2..n:
a = NEWVALUE
b = a
c = b
return a
So what's NEWVALUE? Well, now that we have representations of f(n-1), f(n-2) and f(n-3), it's just the recursive equation:
for _ in 2..n:
a = a + 2 * b + 3 * c
b = a
c = b
return a
Now all that's left is to figure out the initial values of a, b and c. But that's easy, since we know that f(n) = n if n < 3.
if n < 3: return n
a = 2 # f(n-1) where n = 3
b = 1 # f(n-2)
c = 0 # f(n-3)
# now start off counting at 3
for _ in 3..n:
a = a + 2 * b + 3 * c
b = a
c = b
return a
That's still a little different from the Scheme iterative version, but I hope you can see the thought process now.
I think you are asking how one might discover the algorithm naturally, outside of a 'design pattern'.
It was helpful for me to look at the expansion of the f(n) at each n value:
f(0) = 0 |
f(1) = 1 | all known values
f(2) = 2 |
f(3) = f(2) + 2f(1) + 3f(0)
f(4) = f(3) + 2f(2) + 3f(1)
f(5) = f(4) + 2f(3) + 3f(2)
f(6) = f(5) + 2f(4) + 3f(3)
Looking closer at f(3), we see that we can calculate it immediately from the known values.
What do we need to calculate f(4)?
We need to at least calculate f(3) + [the rest]. But as we calculate f(3), we calculate f(2) and f(1) as well, which we happen to need for calculating [the rest] of f(4).
f(3) = f(2) + 2f(1) + 3f(0)
↘ ↘
f(4) = f(3) + 2f(2) + 3f(1)
So, for any number n, I can start by calculating f(3), and reuse the values I use to calculate f(3) to calculate f(4)...and the pattern continues...
f(3) = f(2) + 2f(1) + 3f(0)
↘ ↘
f(4) = f(3) + 2f(2) + 3f(1)
↘ ↘
f(5) = f(4) + 2f(3) + 3f(2)
Since we will reuse them, lets give them a name a, b, c. subscripted with the step we are on, and walk through a calculation of f(5):
Step 1: f(3) = f(2) + 2f(1) + 3f(0) or f(3) = a1 + 2b1 +3c1
where
a1 = f(2) = 2,
b1 = f(1) = 1,
c1 = 0
since f(n) = n for n < 3.
Thus:
f(3) = a1 + 2b1 + 3c1 = 4
Step 2: f(4) = f(3) + 2a1 + 3b1
So:
a2 = f(3) = 4 (calculated above in step 1),
b2 = a1 = f(2) = 2,
c2 = b1 = f(1) = 1
Thus:
f(4) = 4 + 2*2 + 3*1 = 11
Step 3: f(5) = f(4) + 2a2 + 3b2
So:
a3 = f(4) = 11 (calculated above in step 2),
b3 = a2 = f(3) = 4,
c3 = b2 = f(2) = 2
Thus:
f(5) = 11 + 2*4 + 3*2 = 25
Throughout the above calculation we capture state in the previous calculation and pass it to the next step,
particularily:
astep = result of step - 1
bstep = astep - 1
cstep = bstep -1
Once I saw this, then coming up with the iterative version was straightforward.
Since the post you linked to describes a lot about the solution, I'll try to only give complementary information.
You're trying to define a tail-recursive function in Scheme here, given a (non-tail) recursive definition.
The base case of the recursion (f(n) = n if n < 3) is handled by both functions. I'm not really sure why the author does this; the first function could simply be:
(define (f n)
(f-iter 2 1 0 n))
The general form would be:
(define (f-iter ... n)
(if (base-case? n)
base-result
(f-iter ...)))
Note I didn't fill in parameters for f-iter yet, because you first need to understand what state needs to be passed from one iteration to another.
Now, let's look at the dependencies of the recursive form of f(n). It references f(n - 1), f(n - 2), and f(n - 3), so we need to keep around these values. And of course we need the value of n itself, so we can stop iterating over it.
So that's how you come up with the tail-recursive call: we compute f(n) to use as f(n - 1), rotate f(n - 1) to f(n - 2) and f(n - 2) to f(n - 3), and decrement count.
If this still doesn't help, please try to ask a more specific question — it's really hard to answer when you write "I don't understand" given a relatively thorough explanation already.
I'm going to come at this in a slightly different approach to the other answers here, focused on how coding style can make the thought process behind an algorithm like this easier to comprehend.
The trouble with Bill's approach, quoted in your question, is that it's not immediately clear what meaning is conveyed by the state variables, a, b, and c. Their names convey no information, and Bill's post does not describe any invariant or other rule that they obey. I find it easier both to formulate and to understand iterative algorithms if the state variables obey some documented rules describing their relationships to each other.
With this in mind, consider this alternative formulation of the exact same algorithm, which differs from Bill's only in having more meaningful variable names for a, b and c and an incrementing counter variable instead of a decrementing one:
(define (f n)
(if (< n 3)
n
(f-iter n 2 0 1 2)))
(define (f-iter n
i
f-of-i-minus-2
f-of-i-minus-1
f-of-i)
(if (= i n)
f-of-i
(f-iter n
(+ i 1)
f-of-i-minus-1
f-of-i
(+ f-of-i
(* 2 f-of-i-minus-1)
(* 3 f-of-i-minus-2)))))
Suddenly the correctness of the algorithm - and the thought process behind its creation - is simple to see and describe. To calculate f(n):
We have a counter variable i that starts at 2 and climbs to n, incrementing by 1 on each call to f-iter.
At each step along the way, we keep track of f(i), f(i-1) and f(i-2), which is sufficient to allow us to calculate f(i+1).
Once i=n, we are done.
What did help me was running the process manually using a pencil and using hint author gave for the fibonacci example
a <- a + b
b <- a
Translating this to new problem is how you push state forward in the process
a <- a + (b * 2) + (c * 3)
b <- a
c <- b
So you need a function with an interface to accept 3 variables: a, b, c. And it needs to call itself using process above.
(define (f-iter a b c)
(f-iter (+ a (* b 2) (* c 3)) a b))
If you run and print each variable for each iteration starting with (f-iter 1 0 0), you'll get something like this (it will run forever of course):
a b c
=========
1 0 0
1 1 0
3 1 1
8 3 1
17 8 3
42 17 8
100 42 17
235 100 42
...
Can you see the answer? You get it by summing columns b and c for each iteration. I must admit I found it by doing some trail and error. Only thing left is having a counter to know when to stop, here is the whole thing:
(define (f n)
(f-iter 1 0 0 n))
(define (f-iter a b c count)
(if (= count 0)
(+ b c)
(f-iter (+ a (* b 2) (* c 3)) a b (- count 1))))
A function f is defined by the rule that f(n) = n, if n<3 and f(n) = f(n - 1) + 2f(n - 2) + 3f(n - 3), if n > 3. Write a procedure that computes f by means of a recursive process.
It is already written:
f(n) = n, (* if *) n < 3
= f(n - 1) + 2f(n - 2) + 3f(n - 3), (* if *) n > 3
Believe it or not, there was once such a language. To write this down in another language is just a matter of syntax. And by the way, the definition as you (mis)quote it has a bug, which is now very apparent and clear.
Write a procedure that computes f by means of an iterative process.
Iteration means going forward (there's your explanation!) as opposed to the recursion's going backwards at first, to the very lowest level, and then going forward calculating the result on the way back up:
f(0) = 0
f(1) = 1
f(2) = 2
f(n) = f(n - 1) + 2f(n - 2) + 3f(n - 3)
= a + 2b + 3c
f(n+1) = f(n ) + 2f(n - 1) + 3f(n - 2)
= a' + 2b' + 3c' where
a' = f(n) = a+2b+3c,
b' = f(n-1) = a,
c' = f(n-2) = b
......
This thus describes the problem's state transitions as
(n, a, b, c) -> (n+1, a+2*b+3*c, a, b)
We could code it as
g (n, a, b, c) = g (n+1, a+2*b+3*c, a, b)
but of course it wouldn't ever stop. So we must instead have
f n = g (2, 2, 1, 0)
where
g (k, a, b, c) = g (k+1, a+2*b+3*c, a, b), (* if *) k < n
g (k, a, b, c) = a, otherwise
and this is already exactly like the code you asked about, up to syntax.
Counting up to n is more natural here, following our paradigm of "going forward", but counting down to 0 as the code you quote does is of course entirely equivalent.
The corner cases and possible off-by-one errors are left out as exercise non-interesting technicalities.