Reputation: 13
There is an initial list always consists of '1' (e.g.: [1,1,1], [1,1,1,1]), and the initial list will be given in the question. Then there are some people want to switch the list. The first person will switch every '1' to '0'. The second person follow the first one, and he want to switch the every second number to another(if he meets '0', he switch it to '1';if he meets '1', he switch it to '0'). The third person follow the first one, and he want to switch the every third number to another. Of course, the number of people will be given in the question. Please give the result of final statement of the list.
Write a program 'switch(1,N,Initial,Final). N is the count of people.
For example :
switch(1,2,[1,1],Final). Final=[0,1].
switch(1,3,[1,1,1],Final). Final=[0,1,1].
Upvotes: 0
Views: 121
Reputation: 773
:- [library(plunit)] .
switch(_one_,_two_,_source_,_target_) :-
switch('induce',_one_,_two_,_source_,_target_,1) .
switch('swap',false,0,0) .
switch('swap',false,1,1) .
switch('swap',true,0,1) .
switch('swap',true,1,0) .
switch('induce',_one_,_two_,_source_,_target_,_nth_) :-
_source_ = [] ,
_target_ = [] ;
_source_ = [_car_|_cdr_] ,
_target_ = [_CAR_|_CDR_] ,
_NTH_ is _nth_ + 1 ,
switch('induce',_one_,_two_,_cdr_,_CDR_,_NTH_) ,
switch('deduce',_one_,_two_,_car_,_CAR_,_nth_) .
switch('deduce',_one_,_two_,_car_,_CAR_,_nth_) :-
_one_ = _nth_ ,
switch('swap',true,_car_,_CAR_) ;
_one_ \= _nth_ ,
_two_ = _nth_ ,
switch('swap',true,_car_,_CAR_) ;
_one_ \= _nth_ ,
_two_ \= _nth_ ,
switch('swap',false,_car_,_CAR_) .
%
:- begin_tests(switch).
test(switch,[nondet,true(Final == [0,0])]) :- switch(1,2,[1,1],Final) .
test(switch,[nondet,true(Final == [0,1,0])]) :- switch(1,3,[1,1,1],Final) .
test(switch,[nondet,true(Final == [0,1,1,0])]) :- switch(1,4,[1,1,1,1],Final) .
test(switch,[nondet,true(Final == [0,1,1,1,0])]) :- switch(1,5,[1,1,1,1,1],Final) .
test(switch,[nondet,true(Final == [1,1,1,1,1])]) :- switch(1,5,[0,1,1,1,0],Final) .
:- end_tests(switch).
%
/*
$ yap -f stackoverflow_switch_list.prolog -g 'run_tests' ;
YAP 6.2.2 (i686-linux): Sat Aug 17 14:01:16 UTC 2019
% PL-Unit: switch ..... done
% All 5 tests passed
yes
?-
*/
Upvotes: 0
Reputation: 2403
So we've got a bunch of people who, with nothing better to do in their lives, want to sequentially switch some numbers in a list. Someone needs to introduce them to Prolog, they could make better use of their time. But this is our initial recursion and base case:
switch(N, N, In, Out) :-
person_switch(N, 1, In, Out), !.
switch(P, N, In, Out) :-
person_switch(P, 1, In, Done),
succ(P, Q),
switch(Q, N, Done, Out).
So we can make our people do their switch sequentially via the first argument, which we increment until we reach the base case.
Next up, we'd better teach these people how to do their jobs of switching 0's and 1's.
person_switch(_, _, [], []). % Base case
person_switch(P, P, [1|In], [0|Out]) :- % switch 1 to a 0 on their turn
person_switch(P, 1, In, Out). % Recurse
person_switch(P, P, [0|In], [1|Out]) :- % switch 0 to a 1 on their turn
person_switch(P, 1, In, Out). % Recurse
person_switch(P, C, [H|In], [H|Out]) :- % don't switch, unify
C < P, % don't not switch when they should, C is a counter along the list
succ(C, D), % increment
person_switch(P, D, In, Out). % Recurse
Good luck learning Prolog.
Upvotes: 1