Domanda

I am practicing prolog and all and this one is killing me. Trying to do this:

twice([1,2,3],X).

the output I want is

X = [1,1,2,2,3,3].

Here's my latest attempt:

twice([HD|TL],[HD2|TL2]):-
    twice(TL,[HD,HD2|TL2]).

twice([],[HD|TL]).

//New

twice([],[]).
twice([A|B],Out):- twice([A|B],[A,A|Rest],
                   twice(B,Rest).
È stato utile?

Soluzione

Start with the base case,

twice([], 

"twice of nothing is" ... nothing, right?

          []).

Now, what if there is something there?

twice([A|B], 

then what? do we want the result to start from A? You bet,

              [A,

what next goes there?

                  ...

(fill it in, please). Then, there's the rest:

                       | Rest] ):-

so, we continue. The Rest is taken from B:

      twice(B, ...).

fill this in too, please.

Altri suggerimenti

Let's look at a simpler task first, a predicate where every element in input is not get to the output twice, but only once (input and output are the same, basically).

onlyonce([], []).
onlyonce([Head | Tail], [Head | NewTail]) :-
    onlyonce(Tail, NewTail).

The first clause is obvious.

The second clause means:

  • the first argument (input) is a non-empty list. Name first element of that list "Head", name the rest elements of that list "Tail"
  • the second argument is a non-empty list. The first element of that list is the same as in the first argument list "Head" (i.e. the first element of the input list copied once). Name the rest elements of the list "NewTail"
  • "NewTail" can be obtained from "Tail" (and vice versa) using "onlyonce" predicate.

If you understand how "onlyonce" works, it's very easy to change it to "twice".

Try this:

twice([], []).
twice([A|B], [A,A|Rest]) :- twice(B, Rest).
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top