First, hat tip to this answer and the author, @brebs.
首先,向这个答案和作者致敬,@brebs。
I looked at marquee_/3
... and append/3
looked back at me—with shuffled arguments.
我看着字幕_/3...Append/3回头看着我--带着杂乱无章的论点。
So here's the minimally updated version of marquee/2
:
下面是Marquee/2的最低更新版本:
marquee(L,M) :-
append(L,R,LD),
append(R,M,LD). % was: marquee_(LD,R,M)
Sample queries:
示例查询:
?- marquee("prolog",Xs).
Xs = "prolog"
; Xs = "rologp"
; Xs = "ologpr"
; Xs = "logpro"
; Xs = "ogprol"
; Xs = "gprolo"
; Xs = "prolog"
; Xs = "rologp"
; ... .
?- marquee("",Xs).
Xs = []
; Xs = []
; ... .
this is an alternative solution (updated after a suggestion in the comments), hope this solves the task
这是一个替代的解决方案(在评论中的建议之后更新),希望这能解决任务
marquee(String,String).
marquee([H|T],R):-
append(T,[H],NewEl),
marquee(NewEl,R).
?- marquee("Prolog is marquee ready! ", M).
M = ['P', r, o, l, o, g, ' ', i, s, ' ', m, a, r, q, u, e, e, ' ', r, e, a, d, y, !, ' '];
M = [r, o, l, o, g, ' ', i, s, ' ', m, a, r, q, u, e, e, ' ', r, e, a, d, y, !, ' ', 'P'];
...
?- M=[m|_],marquee("Prolog is marquee ready! ",M).
M = [m, a, r, q, u, e, e, ' ', r, e, a, d, y, !, ' ', 'P', r, o, l, o, g, ' ', i, s, ' '];
M = [m, a, r, q, u, e, e, ' ', r, e, a, d, y, !, ' ', 'P', r, o, l, o, g, ' ', i, s, ' '];
...
Im not sure this satisfy all your requisites, hope so
我不能肯定这能满足你所有的要求,希望如此
marquee(Ls, M):-
length(Ls, Len),
Max is Len-1,
between(0, Max, Roll),
roll(Ls, M, Roll).
lis_pos_elem(Lis, Pos, Elem) :- nth1(Pos, Lis, Elem).
new_index(Shift, Max, I1, I2):-
I is I1 - Shift,
(
I < 1,
I2 is Max + I
;
I2 = I
), !.
roll(L,L,0).
roll(L1,L2,R):-
R > 0,
length(L1, Len),
numlist(1, Len, Index),
maplist(new_index(R, Len), Index, ShiftedIndexes),
maplist(lis_pos_elem(L1), ShiftedIndexes, L2).
?-
marquee("Prolog is marquee ready! ", M); true.
M = ['P', r, o, l, o, g, ' ', i, s, ' ', m, a, r, q, u, e, e, ' ', r, e, a, d, y, !, ' '] ;
M = [' ', 'P', r, o, l, o, g, ' ', i, s, ' ', m, a, r, q, u, e, e, ' ', r, e, a, d, y, !] ;
M = [!, ' ', 'P', r, o, l, o, g, ' ', i, s, ' ', m, a, r, q, u, e, e, ' ', r, e, a, d, y] ;
M = [y, !, ' ', 'P', r, o, l, o, g, ' ', i, s, ' ', m, a, r, q, u, e, e, ' ', r, e, a, d] ;
M = [d, y, !, ' ', 'P', r, o, l, o, g, ' ', i, s, ' ', m, a, r, q, u, e, e, ' ', r, e, a] ;
M = [a, d, y, !, ' ', 'P', r, o, l, o, g, ' ', i, s, ' ', m, a, r, q, u, e, e, ' ', r, e] ;
M = [e, a, d, y, !, ' ', 'P', r, o, l, o, g, ' ', i, s, ' ', m, a, r, q, u, e, e, ' ', r] ;
M = [r, e, a, d, y, !, ' ', 'P', r, o, l, o, g, ' ', i, s, ' ', m, a, r, q, u, e, e, ' '] ;
M = [' ', r, e, a, d, y, !, ' ', 'P', r, o, l, o, g, ' ', i, s, ' ', m, a, r, q, u, e, e] ;
M = [e, ' ', r, e, a, d, y, !, ' ', 'P', r, o, l, o, g, ' ', i, s, ' ', m, a, r, q, u, e] ;
M = [e, e, ' ', r, e, a, d, y, !, ' ', 'P', r, o, l, o, g, ' ', i, s, ' ', m, a, r, q, u] ;
M = [u, e, e, ' ', r, e, a, d, y, !, ' ', 'P', r, o, l, o, g, ' ', i, s, ' ', m, a, r, q] ;
M = [q, u, e, e, ' ', r, e, a, d, y, !, ' ', 'P', r, o, l, o, g, ' ', i, s, ' ', m, a, r] ;
M = [r, q, u, e, e, ' ', r, e, a, d, y, !, ' ', 'P', r, o, l, o, g, ' ', i, s, ' ', m, a] ;
M = [a, r, q, u, e, e, ' ', r, e, a, d, y, !, ' ', 'P', r, o, l, o, g, ' ', i, s, ' ', m] ;
M = [m, a, r, q, u, e, e, ' ', r, e, a, d, y, !, ' ', 'P', r, o, l, o, g, ' ', i, s, ' '] ;
M = [' ', m, a, r, q, u, e, e, ' ', r, e, a, d, y, !, ' ', 'P', r, o, l, o, g, ' ', i, s] ;
M = [s, ' ', m, a, r, q, u, e, e, ' ', r, e, a, d, y, !, ' ', 'P', r, o, l, o, g, ' ', i] ;
M = [i, s, ' ', m, a, r, q, u, e, e, ' ', r, e, a, d, y, !, ' ', 'P', r, o, l, o, g, ' '] ;
M = [' ', i, s, ' ', m, a, r, q, u, e, e, ' ', r, e, a, d, y, !, ' ', 'P', r, o, l, o, g] ;
M = [g, ' ', i, s, ' ', m, a, r, q, u, e, e, ' ', r, e, a, d, y, !, ' ', 'P', r, o, l, o] ;
M = [o, g, ' ', i, s, ' ', m, a, r, q, u, e, e, ' ', r, e, a, d, y, !, ' ', 'P', r, o, l] ;
M = [l, o, g, ' ', i, s, ' ', m, a, r, q, u, e, e, ' ', r, e, a, d, y, !, ' ', 'P', r, o] ;
M = [o, l, o, g, ' ', i, s, ' ', m, a, r, q, u, e, e, ' ', r, e, a, d, y, !, ' ', 'P', r] ;
M = [r, o, l, o, g, ' ', i, s, ' ', m, a, r, q, u, e, e, ' ', r, e, a, d, y, !, ' ', 'P'] ;
true.
This feels fairly intuitive, but not super-short:
这感觉相当直观,但不是太短:
marquee(L, M) :-
% Convert to List-Remainder difference list
append(L, R, LD),
marquee_(LD, R, M).
marquee_(M, [], M).
% Move from head to tail
marquee_([H|T], [H|R], M) :-
marquee_(T, R, M).
Result in swi-prolog:
SWI-PROLOG的结果:
?- marquee([a,b,c,d], L).
L = [a, b, c, d] ;
L = [b, c, d, a] ;
L = [c, d, a, b] ;
L = [d, a, b, c] ;
L = [a, b, c, d] ;
L = [b, c, d, a] ;
...
I suspect there's a trick to convert that into a short DCG that I'm missing...
我怀疑有一个诀窍可以把它转换成我错过的短DCG...
This is my updated answer:
这是我的最新答案:
marquee_right(S0, M):-
length(S0, Len),
length(_, Roll),
Shift is Len - (Roll mod Len),
length(P1, Shift),
append(P1, P2, S0),
append(P2, P1, M).
marquee_left(S0, M):-
length(S0, Len),
length(_, Roll),
Shift is Roll mod Len,
length(P1, Shift),
append(P1, P2, S0),
append(P2, P1, M).
@damianodamiano answer seems really good and declarative, maybe my answer follow more a procedural style.
Comments and notes are appreciated.
@DamianoDamiano的回答看起来真的很好,很有说服力,也许我的回答更像是程序化的风格。欢迎提出意见和备注。
Rolling rolling rolling ...
滚动..。
marquee([],[]) :- repeat, true.
marquee([H|T],X) :- m(T,R,[H|R],X).
m([H|T],[H|R],Y,X) :- m(T,R,Y,X).
m([],[],Y,Y).
m([],[H|Z],[H|R],X) :- m([],Z,R,X).
Testing:
测试:
8 ?- marquee([],X).
X = [] ;
X = [] ;
X = [] ;
X = [] ;
X = [] ;
X = []
......
9 ?- marquee([1,2,3,4],X).
X = [1, 2, 3, 4] ;
X = [2, 3, 4, 1] ;
X = [3, 4, 1, 2] ;
X = [4, 1, 2, 3] ;
X = [1, 2, 3, 4] ;
X = [2, 3, 4, 1] ;
X = [3, 4, 1, 2] ;
X = [4, 1, 2, 3] ;
X = [1, 2, 3, 4] ;
X = [2, 3, 4, 1] ;
X = [3, 4, 1, 2] ;
X = [4, 1, 2, 3]
......
更多回答
How/why does this guarantee the right order or results?
这如何/为什么保证正确的顺序或结果?
Perfect! Yet, its size ... And what is the purpose of the goal nth0(0,[H|T],E1)
?
太棒了!然而,它的规模..。目标nth0(0,[H|T],e1)的目的是什么?
Absolutely useless. I've updated my answer
完全没用。我已经更新了我的答案
I said perfect, but then ?- marquee(non_marqueeable, M). M = non_marqueeable.
我说完美,但然后呢?-选取框(不可选取,M)。M=不可选取。
This is a good start! But the idea is that it produces infinitely many such solutions. Also, maybe you could reduce (in another answer) the size of the program significantly.
这是一个很好的开始!但其想法是,它产生了无限多的这样的解决方案。此外,也许您可以(在另一个答案中)显著减少程序的大小。
... just one thing is that you use numlist/3
which is not part of the Prolog prologue.
..。只有一件事是您使用了NumList/3,它不是序言的一部分。
And now I see answers are enumerated in the other direction.
现在我看到答案被列举在另一个方向上。
Updated to prevent excluding empty list.
已更新以防止排除空列表。
While nice, it could be much shorter. Please try in another answer!
虽然很好,但它可以短得多。请尝试其他答案!
I suspect there's a trick: you are soo close! No DCG, just...
我怀疑有一个诡计:你太接近了!没有DCG,只是...
I was thinking that there was phrase/3
involved next, rather than another append
:-)
我在想接下来涉及的是短语/3,而不是另一个附加词:-)
You could always replace a goal append(A,B,C)
by phrase(seq(A),C,B)
. And (with a lot of pain...) you could replace the first append(L,R,LD)
by phrase(L,LD,R)
although that really hurts (as it includes now many unwanted solutions...)
你总是可以用短语(seq(A),C,B)替换目标的附加部分(A,B,C)。还有(带着很大的痛苦……)你可以用短语(L,LD,R)替换第一个附加部分(L,LD,R),尽管这真的很糟糕(因为它现在包括了许多不需要的解决方案……)
Oh, better rename marquee_left/2
... Otherwise flawless as to its declarative nature. Still, the size ... six goals. Can't you narrow it down?
哦,最好改名为marquee_Left/2..。否则,它的陈述性质就完美无缺了。尽管如此,它的大小..。六个进球。你不能缩小范围吗?
Nice, but quite large.
不错,但很大。
我是一名优秀的程序员,十分优秀!