2010-06-05 4 views
0

문제를 해결하기 위해 프롤로그 프로그램을 작성 중입니다. 문제는 입력으로 세 개의리스트를 취합니다 프롤로그 : 세 개의리스트를 같은 길이로 만드는 방법 (앞에 0을 추가)

solve([L|Lr] , [R|Rr] , [S|Sr]) :- 

불행하게도 목록의 모든 프로그램이 작동하려면 동일한 길이해야합니다.

그래서 이러한 작업 :

?- solve([A, B, C, D] , [1, 3, 5, 6], [E, F, G, H]). 
?- solve([1] , [2], [3]). 

그러나이 그렇지는 (?) 내가하고 싶은 무엇

?- solve([A, B, C, D], [1], [B, I, T]). 
?- solve([A], [1, 2], [4, 5]). 

는 술어를 쓰기 패드로 이어지는와 작은 목록입니다 0. 그래서 :

solve([A, B, C, D], [1], [B, I, T]) 

이 될 것이 좋지 않을까 수행하는 방법에 대한

solve([A, B, C, D], [0, 0, 0, 1], [0, B, I, T]) 

어떤 점. 나는 기능적 배경에서 왔으므로 고군분투하고 있습니다. 목록의 길이를 말하는 방법이 있습니까? 나는 재귀 적으로 그렇게 할 수 있다고 생각하지만 고통스러운 것처럼 보인다.

답변

1

길이 (List, Length) 조건자는 목록의 길이를 가져 오는 데 사용됩니다. 나는 앞자리에 0을 넣는 작은 프로그램을 만들었다.

addZeros(L, 0, L). 
addZeros(L, 1, [0|L]). 
addZeros(L, N, [0|FL]) :- 
     N2 is N - 1, 
     addZeros(L, N2, FL). 

compZeros(_, 0, []). 
compZeros(L, N, FL) :- 
     length(L, S), 
     S < N, 
     N2 is N - S, 
     addZeros(L, N2, FL). 
compZeros(L, _, L). 

최종 목록의 목록과 크기를 전달하기 만하면됩니다.

?- compZeros([1], 4, L). 
L = [0, 0, 0, 1] 

?- compZeros([1, 2, 3], 4, L). 
L = [0, 1, 2, 3] 

?- compZeros([1, 2, 3, 4], 4, L). 
L = [1, 2, 3, 4]. 
+0

브릴리언트, 감사 에드, 나는 그것을 개념화 힘든 시간을 보내고 있었다. 그러나 추가 제로에 대한 두 번째 기본 사례는 중복 된 것으로 생각합니다. – sixtyfootersdude

0

통일만을 사용한 또 다른 변형입니다.

padZerosPrep(L, [], L). 
padZerosPrep(L, [_|T], [0|R]):- padZerosPrep(L, T, R). 

padZerosWalk([], [], La, Lb, La, Lb). 
padZerosWalk([], [_|_], La, Lb, La, Lb). 
padZerosWalk([_|_], [], La, Lb, La, Lb). 
padZerosWalk([_|La0], [_|Lb0], [_|La1], [_|Lb1], La, Lb):- 
    padZerosWalk(La0, Lb0, La1, Lb1, La, Lb). 

padZeros(La0, Lb0, La, Lb):- 
    padZerosPrep(La0, Lb0, La1), 
    padZerosPrep(Lb0, La0, Lb1), 
    padZerosWalk(La0, Lb0, La1, Lb1, La, Lb). 

그냥 두 목록을 전달하고 목록의 두 번째 쌍은 같은 길이있을 것이라는 점을 기억하십시오

?- padZeros([1,2,3],[4,5,6],A,B). 
A = [1, 2, 3], 
B = [4, 5, 6] 

?- padZeros([1,2,3],[4,5],A,B). 
A = [1, 2, 3], 
B = [0, 4, 5] 

?- padZeros([2,3],[4,5,6],A,B). 
A = [0, 2, 3], 
B = [4, 5, 6] 

?- La=[A,B,C,D], Lb = [1], Lc=[B,I,T], padZeros(La, Lb, La1, Lb1), padZeros(La1, Lc, La2, Lc2), padZeros(Lb1, Lc, Lb2, Lc2). 
La = [A, B, C, D], 
Lb = [1], 
Lc = [B, I, T], 
La1 = [A, B, C, D], 
Lb1 = [0, 0, 0, 1], 
La2 = [A, B, C, D], 
Lc2 = [0, B, I, T], 
Lb2 = [0, 0, 0, 1] 

?- Lc=[A,B,C,D], Lb = [1], La=[B,I,T], padZeros(La, Lb, La1, Lb1), padZeros(La1, Lc, La2, Lc2), padZeros(Lb1, Lc, Lb2, Lc2). 
Lc = [A, B, C, D], 
Lb = [1], 
La = [B, I, T], 
La1 = [B, I, T], 
Lb1 = [0, 0, 1], 
La2 = [0, B, I, T], 
Lc2 = [A, B, C, D], 
Lb2 = [0, 0, 0, 1] 

P.S.을 이 술어를 역순으로 사용하지 마십시오. 하스켈
같은 변형 :

padZeros :: (Num a, Num b) => [a] -> [b] -> ([a], [b]) 
padZeros a b = walk (zip a b) pa pb where 
    pa = map (const 0) b ++ a 
    pb = map (const 0) a ++ b 
    walk [] a' b' = (a', b') 
    walk (_:xs) (_:a') (_:b') = walk xs a' b' 
관련 문제