Pregunta

so I've been working on the following question:

Write a 3-place predicate scalarMult whose first argument is an integer, whose second argument is a list of integers, and whose third argument is the result of scalar multiplying the second argument by the first. For example, the query

?-  scalarMult(3,[2,7,4],Result). 

should yield

Result = [6,21,12] 

Do this with the help of an accumulator and a wrapper predicate.

This is what I have done:

scalarMult(I, List1, List2):- scalarMult1(I, List1, [], List2).

scalarMult1(I,[], A, A).
scalarMult1(I,[H|T], A, Result):- H1 is H*I, scalarMult1(I,T,[H1|A],Result).

The only trouble with this is that it's putting the new elements at the head of the accumulator so I kind of end up with a reversed list (so for the example above, I would get Result = [12,21,6]). Is there any way I could work around this? I tried using reverse in my code but all my attempts fails.

Thanks

¿Fue útil?

Solución

using reverse/2 works, actually:

scalarMult(I, List1, List2):- scalarMult1(I, List1, [], T), reverse(T, List2).

but I think the requirement to use an accumulator (really useless here) could be on purpose to verify your level of lists handling.

Otros consejos

Noting Carlo's remark about the use of accumulators being for didactical purposes, no accumulator is required for a straight-forward definition of the scalar_multiplication/3 predicate (renamed from scalarMult/3; camel case is not considered good programming style in Prolog):

% first exchange argument orders to take advantage of the first-argument
% indexing that is provided in most Prolog implementations
scalar_multiplication(Scalar, Numbers, ScaledNumbers) :-
    scalar_multiplication_(Numbers, Scalar, ScaledNumbers).

% base case; either input list was empty or we finished traversing the list
scalar_multiplication_([], _, []).

% recursive case
scalar_multiplication_([Number| Numbers], Scalar, [ScaledNumber| ScaledNumbers]) :-
    ScaledNumber is Number * Scalar,
    scalar_multiplication_(Numbers, Scalar, ScaledNumbers).

This is an instance of a common pattern for processing lists. So common that several Prolog implementations provide a second-order predicate (or meta-predicate), usually named map/3 or maplist/3, to handle it.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top