Related
Hi I have the following code:
let f n (xs) = if n < 0 then f (n-1) (n:xs) else xs
f (-3) [] !! 1
and I expect it to print -4
But it does not print anything and keeps calculation in background.
What is wrong with my code?
Let's step through the evaluation:
f (-3) []
f (-4) [-3]
f (-5) [-4, -3]
f (-6) [-5, -4, -3]
f (-7) [-6, -5, -4, -3]
...
Considering this, what do you expect f (-3) [] !! 1 to be? The value in the index 1 changes each iteration, so there's no way Haskell can know what it is until it reaches the non-recursive case at n >= 0, which never happens.
If you build the list in the other direction, it will work as you expect:
let f n = if n < 0 then n : f (n - 1) else []
> f (-3) !! 1
-4
So here's a pretend integer type:
data Int2 = ... -- 2 bit signed integers [-2, -1, 0, 1]
deriving (Num, Ord, Eq, ...)
Let's imagine that your function was defined on Int2 values:
f :: Int2 -> [Int2] -> [Int2]
f n (xs) = if n < 0 then f (n-1) (n:xs) else xs
This makes it fairly easy to work out what one evaluation step looks like for f n xs:
f 1 xs = xs
f 0 xs = xs
f (-1) xs = f (-2) (-1 : xs)
f (-2) xs = f 1 (-2 : xs) -- because finite signed arithmetic wraps around
and from there we can work out the full value of f n []:
f 1 [] = []
f 0 [] = []
f (-1) [] = f (-2) [-1] = f 1 [-2, -1] = [-2, -1]
f (-2) [] = f 1 [-2] = [-2]
Each computed a value, but note how it took 3 evaluation steps before we got a list out of f (-1) [].
Now see if you can work out how many steps it would take to compute f (-1) [] if it were defined on 4-bit numbers. 8-bit? 32-bit? 64-bit? What if it were using Integer which has no lower bound?
At no point does laziness help you because there's no partial result, only a recursive call. That's the difference between:
lazyReplicate 0 _ = []
lazyReplicate n x = x : lazyReplicate (n - 1) x
and
strictReplicate n x = helper [] n x where
helper xs 0 _ = xs
helper xs n x = helper (x : xs) n x
I'm starting to code in python and I came across this code snippet:
for [x, y] in L:
for ix in range(-1, 2):
for iy in range(-1, 2):
cir = pylab.Circle((x + ix, y + iy), radius=sigma, fc='r')
pylab.gca().add_patch(cir)
at the line 1 I can not understand what is happening because I had never seen anything like it in another programming language. How this works?
for [x, y] in L:
[x, y] is a list? i dont know.
L must be a sequence of lists (or tuples) with two elements, which can be iterated over. So whenever for [x,y] in L: is executed, it picks each item in th sequence one by one and enters into the loop.
let the sequence be L = [[2,3], [4,5], ['Jeff', 7]]
Now here what will happen when for [x,y] in L: will be executed is :- first list in the sequence [2,3] will be picked up and assigned as x and y respectively. And in the next iteration x and y will get the value 4 & 5 respectively. Like wise in third iteration x will be Jeff and y will be 7.
L = [[2,3], [4,5], ['Jeff', 7]]
count = 0
for [x,y] in L:
count += 1
print " Iteration :- %d, \t x :- %s, \t y:- %s" %(count, str(x), str(y))
Yes, [x, y] is a list with two elements. For your loop to work, L must be a list (or other iterable data structure) that contains a bunch of lists with two elements. Each time through the loop one of those lists is copied into [x, y], then the individual values of x and y are used in the body of the loop.
Try this and see if it makes sense:
L = [ [1, 2], [3, 4] ]
for [x, y] in L:
print x
print y
count([], 0, 0).
count([X|T], M, N) :- 1 is X, count(T, MRec, NRec),
M is MRec, N is NRec+1.
count([X|T], M, N) :- 0 is X, count(T, MRec, NRec),
M is MRec+1, N is NRec.
control_number(L) :- count_digit(L, M, N), 2 is M, 3 is N.
?- control_number([1,1,0,0,1]).
ERROR: count_number/3: Undefined procedure: count/3
Hello everybody, I need help. This code must provide the count of two separate number recursively. However, I cannot provide recursion
with 2 parameters. I guess MRec and NRec is not valid in any way.
Any help will be appreciated. Thanks now...
Here is a more idiomatic rewrite:
count_digits([], 0, 0).
count_digits([1|T], M, N) :-
count_digits(T, M, NRec),
N is NRec+1.
count_digits([0|T], M, N) :-
count_digits(T, MRec, N),
M is MRec+1.
control_number(L) :-
count_digits(L, 2, 3).
This can be improved a lot by using library(clpfd). Maybe someone else will answer.
As already pointed out by #false this predicate is quite a candidate for clpfd. Besides that I added constraints (marked as % <-) to ensure that M and N are greater than 0 in the recursive cases, so Prolog does not continue to search for further solutions once those variables have been reduced to 0.
:- use_module(library(clpfd)).
count_digits([], 0, 0).
count_digits([1|T], M, N) :-
N #> 0, % <-
NRec #= N-1,
count_digits(T, M, NRec).
count_digits([0|T], M, N) :-
M #> 0, % <-
MRec #= M-1,
count_digits(T, MRec, N).
With these minor modifications you can already use count_digits/3 in several ways. For example to ask for all lists with 2 0's and 3 1's:
?- count_digits(L,2,3).
L = [1,1,1,0,0] ? ;
L = [1,1,0,1,0] ? ;
L = [1,1,0,0,1] ? ;
L = [1,0,1,1,0] ? ;
L = [1,0,1,0,1] ? ;
L = [1,0,0,1,1] ? ;
L = [0,1,1,1,0] ? ;
L = [0,1,1,0,1] ? ;
L = [0,1,0,1,1] ? ;
L = [0,0,1,1,1] ? ;
no
Or count the occurrences of 0's and 1's in a given list:
?- count_digits([1,1,0,0,1],M,N).
M = 2,
N = 3
% 1
Or even ask for the number of 0's and 1's in a list containing variables:
?- count_digits([1,0,X,Y],M,N).
M = X = Y = 1,
N = 3 ? ;
M = N = 2,
X = 1,
Y = 0 ? ;
M = N = 2,
X = 0,
Y = 1 ? ;
M = 3,
N = 1,
X = Y = 0
This is quite nice already and one might be content with the predicate as is. It certainly is fine if you intend to use it with control_number/1 as suggested by #false. However it might be worth the time to fool around a little with some other queries. For example the most general query: What lists are there with M 0's and N 1's?
?- count_digits(L,M,N).
L = [],
M = N = 0 ? ;
L = [1],
M = 0,
N = 1 ? ;
L = [1,1],
M = 0,
N = 2 ? ;
L = [1,1,1],
M = 0,
N = 3 ?
...
It is only producing lists that consist of 1's exclusively. That is because the first recursive rule is the one describing the case with the 1 as the first element of the list. So the solutions are coming in an unfair order. What happens with the following query is maybe even somewhat less intuitive: What lists are there with the same (but not fixed) number of 0's and 1's:
?- count_digits(L,M,M).
L = [],
M = 0 ? ;
There is an answer and then the predicate loops. That's not exactly a desirable property. An interesting observation about this query: If one uses it on lists with fixed length the result is actually as expected:
?- length(L,_), count_digits(L,M,M).
L = [],
M = 0 ? ;
L = [1,0],
M = 1 ? ;
L = [0,1],
M = 1 ? ;
L = [1,1,0,0],
M = 2 ? ;
L = [1,0,1,0],
M = 2 ? ;
...
Applying this idea to the previous query yields a fair ordering of the results:
?- length(L,_), count_digits(L,M,N).
L = [],
M = N = 0 ? ;
L = [1],
M = 0,
N = 1 ? ;
L = [0],
M = 1,
N = 0 ? ;
L = [1,1],
M = 0,
N = 2 ? ;
L = [1,0],
M = N = 1 ? ;
...
It certainly would be nice to get these results without having to prefix an auxiliary goal. And looking a little closer at the relation described by count_digits/3 another observation meets the eye: If there are M 0's and N 1's the length of the list is actually fixed, namely to M+N. To put these observations to work one could rename count_digits/3 to list_0s_1s/3 and redefine count_digits/3 to be the calling predicate with the following constraints:
:- use_module(library(clpfd)).
count_digits(L,M,N) :-
X #= M+N,
length(L,X), % L is of length M+N
list_0s_1s(L,M,N).
list_0s_1s([], 0, 0).
list_0s_1s([1|T], M, N) :-
N #> 0,
NRec #= N-1,
list_0s_1s(T, M, NRec).
list_0s_1s([0|T], M, N) :-
M #> 0,
MRec #= M-1,
list_0s_1s(T, MRec, N).
The first three queries above yield the same results as before but these two are now producing results in a fair order without looping:
?- count_digits(L,M,N).
L = [],
M = N = 0 ? ;
L = [1],
M = 0,
N = 1 ? ;
L = [0],
M = 1,
N = 0 ? ;
L = [1,1],
M = 0,
N = 2 ? ;
L = [1,0],
M = N = 1 ?
...
?- count_digits(L,M,M).
L = [],
M = 0 ? ;
L = [1,0],
M = 1 ? ;
L = [0,1],
M = 1 ? ;
L = [1,1,0,0],
M = 2 ? ;
L = [1,0,1,0],
M = 2 ?
...
Two last notes on your predicate control_number/1: Firstly, if you are using is/2 make sure to use it like so:
?- M is 2.
M = 2
% 1
instead of (as used in your definition of control_number/1):
?- 2 is M.
ERROR!!
INSTANTIATION ERROR- in arithmetic: expected bound value
% 1
And secondly, if you intend to use a predicate like control_number/1 to call count_digits/3, don't put goals like M is 2 and N is 3 after the actual call of count_digits/3. That way you are asking for all solutions of count_digits(L,M,N), of which there are infinitely many, and in the subsequent goals you are then filtering out the ones that satisfy your constraints (M is 2 and N is 3). With this ordering of the goals you make sure that control_number/1 does not terminate after producing the finite number of solutions, since infinitely many solution-candidates are produced by the first goal that subsequently fail according to your constraints. Instead, place such constraints first or put them directly as arguments into the goal as posted by #false.
Accumulation parameters is the way to go (you need an auxiliary predicate in order to initialize those parameters):
count(List,C0,C1) :-
count_aux(List,C0,C1,0,0).
count_aux([],C0,C1,C0,C1).
count_aux([0|Rest],C0,C1,PartialC0,PartialC1) :-
IncC0 is PartialC0+1,
!,
count_aux(Rest,C0,C1,IncC0,PartialC1).
count_aux([1|Rest],C0,C1,PartialC0,PartialC1) :-
IncC1 is PartialC1+1,
!,
count_aux(Rest,C0,C1,PartialC0,IncC1).
count_aux([_|Rest],C0,C1,PartialC0,PartialC1) :-
count_aux(Rest,C0,C1,PartialC0,PartialC1).
Note:
You should call count/3, not count_aux/5.
Last two parameters to count_aux/5 are accumulation parameters
initialized to zero.
First clause to count_aux/5 is the base case, where accumulated
parameters are returned.
Last clause to count_aux/5 prevents predicate failure if list items
are not 0 nor 1.
Example:
?- count([1,1,0,0,0,k],A,B).
A = 3,
B = 2.
Lets say I have the list below:
list1=[1,2,4,6,8,3,2,5,8,4,2]
I want to return the integer, 2, because 8 is the maximum value and there are two 8s in the list. How can I do this? Edit: I also want to assume that the maximum number in the list can be any negative or non-negative number including zero.
Well you can use something like this:
list1=[1,2,4,6,8,3,2,5,8,4,2]
print list1.count(max(list1))
ans = 0
mx = 0
for x in list1:
if x > mx:
mx = x
ans = 1
elif x == mx :
ans += 1
print ans
assume max number is bigger than 0, otherwise you should initial mx with the negative infinity
>>> list1=[1,2,4,6,8,3,2,5,8,4,2]
>>> x = max(list1)
>>> l = []
>>> for i in list1:
if i == x:
l.append(i)
>>> l
[8, 8]
>>> len(l)
2
OR
>>> list1=[1,2,4,6,8,3,2,5,8,4,2]
>>> x = max(list1)
>>> result = len(filter(lambda i: i == x, list1))
>>> result
2
I'm still new to SWI-Prolog and I'm not sure how to do this two questions.
Write a predicate sum_composite(Numbers, Sum) that sum ONLY COMPOSITE NUMBERS of a list of non-negative whole numbers. Example:
?- sumList([1,3,5,2,4,6,8,7],Sum).
Sum=18.
true
Write a predicate maxPrime(List, Min) that given a list of numbers, returns the maximum prime element in the list. Example:
?- maxPrime([1, -4, 7, 4, 7, 9, -2, 3], Max).
Max = 7
true
This is what I have so far:
sum_list([],0). //empty list.
sum_list([First|Tail],Sum) :-
sumlist(Tail, SumTail).
As nearly always in Prolog, you can write predicates on lists using two clauses.
foo(L,R) :-
foo(L,I,R).
foo([],F,F).
foo([H|T],F,R) :-
F2 is f(F,H),
foo(T,F2,R).
With F the current result, F2 the updated result, H the head of the list that far, T the tail of the list, I the initial value, and R the result.
Such patterns use tail recursion with an accumulator (in this case F), this patterns are considered one of the most efficient in Prolog. (middle-recursion or return accumulators increase the call stack and require more bookkeeping).
In case of a sum, this is tranformed into:
sum(L,R) :-
sum(L,0,R).
sum([],F,F).
sum([H|T],F,R) :-
F2 is F+H,
sum(T,F2,R).
I will leave the maxPrime as an exercise, but it fits "nicely" into the above described pattern.
question
Write a predicate composites_sum(NUMBERs, SUM) that sums ONLY COMPOSITE NUMBERS of a list of non-negative whole numbers .
(ed: a "composite" number is an number that is not an "prime" number) .
Example :
?- composites_sum([1,3,5,2,4,6,8,7],Sum) .
Sum = 18 .
true
answer
./src/parts/composites_sum.prolog
composites_sum(NUMBERs0,SUM)
:-
composites(NUMBERs0,NUMBERs) ,
sum(NUMBERs,SUM)
.
./demos/parts/composites_sum.prolog.console
?- composites_sum([1,3,5,2,4,6,8,7],SUM) .
SUM = 18 .
?- composites_sum([1,2,3],SUM) .
SUM = 0 .
?- sum([1,2,3],SUM) .
SUM = 6 .
?- sum([1,2,3,4],SUM) .
SUM = 10 .
?- composites_sum([1,2,3,4],SUM) .
SUM = 4 .
?- composites_sum([],SUM) .
SUM = 0 .
./src/parts/prime.prolog
%! prime(N0)
%
% true if `N0` is an prime number ;
% false if `N0` is not an prime number .
%
% this predicate can be used to generate prime numbers ;
% see the demos for the example using `between` .
/*
If an number is divisible by any other number less than it's sqrt then
the number is not prime ; otherwise it is prime .
*/
:- op(1,'xfy','prime_') .
prime(N0) :- [start] prime_ (N0) .
[start] prime_ (N0)
:-
[init] prime_ (N0)
.
[init] prime_ (N0)
:-
K is floor(sqrt(N0)) ,
[while] prime_ (N0,K)
.
[while] prime_ (_N0,K0)
:-
K0 = 1 ,
! ,
[finish] prime_ (true)
.
[while] prime_ (N0,K0)
:-
0 is mod(N0,K0) , % true if K0 multiplied by some value is N0 .
! ,
[finish] prime_ (false)
.
[while] prime_ (N0,K0)
:-
! ,
K is K0 - 1 ,
[while] prime_ (N0,K)
.
[finish] prime_ (true) .
[finish] prime_ (false) :- false .
./demos/parts/prime__1.prolog.console
?- prime(1) .
true
?- prime(2) .
true
?- prime(3) .
true
?- prime(4) .
false
?- prime(5) .
true
?- prime(7) .
true
./demos/parts/prime__2.prolog.console
?- between(1,1000,N) , prime(N) .
N = 1 ? ;
N = 2 ? ;
N = 3 ? ;
N = 5 ? ;
N = 7 ? ;
N = 11 ? ;
N = 13 ? ;
N = 17 ? ;
N = 19 ? ;
N = 23 ? ;
N = 29 ? ;
N = 31 ? ;
N = 37 ? ;
N = 41 ? ;
N = 43 ? ;
N = 47 ? ;
N = 53 ? ;
N = 59 ? ;
N = 61 ? ;
N = 67 ? ;
N = 71 ? %etcetera.
./src/parts/composites.prolog
%! composites(Xs0,Ys)
%
% `Ys` is those elements of `Xs0` that are not prime .
composites([],[]) :- ! .
composites([X0|Xs],[X0|Ys])
:-
+ prime(X0) ,
! ,
composites(Xs,Ys)
.
composites([_X0|Xs],Ys0)
:-
! ,
composites(Xs,Ys0)
.
./demos/parts/composites.prolog.console
?- composites([1,2,3,4,5,6,7,8,9,10,11,12],Cs) .
Cs = [4,6,8,9,10,12] .
?- composites([1],Cs) .
Cs = [] .
?- composites([],Cs) .
Cs = [] .
./src/parts/sum.prolog
%! sum(Xs,SUM)
%
% calculate the total sum of the items of list `Xs` .
sum(Xs,SUM)
:-
sum(Xs,0,SUM)
.
sum([],SUM0,SUM0) .
sum([X0|Xs],SUM0,SUM)
:-
SUM1 is SUM0 + X0 ,
sum(Xs,SUM1,SUM)
.
./demos/parts/sum.prolog.console
?- sum([1,2,3,4],SUM).
SUM = 10.
?- sum([1,2],SUM).
SUM = 3.
?- sum([1,2,-1],SUM).
SUM = 2.
?- sum([-1],SUM).
SUM = -1.
?- sum([],SUM).
SUM = 0.