プロローグ、284バイト
e(S,[0|X]):-e(S,X).
e([A|S],[A|X]):-S=X;e(S,X).
v(X/Y,76,Y/Z):-Z is -X.
v(X/Y,82,Z/X):-Z is -Y.
v(D,0,D).
c([],0/0-0/1,[0/0]).
c([H|T],K/L-D/E,[K/L|C]):-c(T,I/J-X/Y,C),v(X/Y,H,D/E),K is I+X,L is J+Y,\+member(K/L,C).
n(X):-X=0;n(Y),X#=Y+1.
p(S,L):-n(L),length(X,L),e([0|S],X),c(X,_,_).
これはアルゴリズムの非常に簡単なステートメントであり、かなり非効率的です(ほとんどのテストケースは実行されましたが、すべてのテストケースが妥当な時間内に実行されたわけではありません)。これは、出力の可能な長さをすべて1以上から生成することで機能します(n
); 入力と一致する、その長さの左/前/右のすべての可能なシーケンスを生成します(で実装されe
ます。新しいパスはと呼ばれますX
)。次にc
、有効な最初のパスをチェックします(は、v
左と右の影響を処理するためにを呼び出して、xデルタとyデルタをオンにします)。戻り長は、で見られる最初の出力です。L
。(+2に戻るときに、関数が他の長さの可能な出力を返さないようにしたい場合は、+ 2のペナルティ。Prologの特異関数がどのように返されるかを数える必要があるかどうかは明確ではありません。)
ここではゴルフのトリックの方法はあまりありませんが、いくつかあります。n
パーサーを混乱させることなく、より多くの空白を削除できるため、制約ソルバーで実装されました。これには、GNU Prologを使用する必要があるかもしれません。(c
負の数を処理する必要があるため、同じことを行うことはできませんでした。)の実装はe
、複数の方法でリストを照合することにより、必要とするよりもかなり効率が良くありません。より効率的なのe([],[]).
は6バイト長くなります(S=X;
オンライン2を削除することはできますが、10の損失と比較して4の利得にすぎません)。座標や方向を全体または一部だけX/Y
に一致させるために、それらを(つまり、一致する可能性のある未評価のAST として)表現し、中置記法を使用できるようにします。
Prolog、256バイト、非効率すぎて簡単にテストできない
もちろん、これはPrologであるため、関数の多くは可逆的であり、たとえばc
、原点から特定の座標ペアへのすべてのパスを生成するために使用できます。また、c
自然に最短から最長まで生成します。つまり、最小の長さを明示的に要求する代わりに、どこにでも行くすべてのパスc
を生成して、入力と一致する最初のパスを探すことができます。
e(S,[0|X]):-e(S,X).
e([A|S],[A|X]):-S=X;e(S,X).
v(X/Y,76,Y/Z):-Z is -X.
v(X/Y,82,Z/X):-Z is -Y.
v(D,0,D).
c([],0/0-0/1,[0/0]).
c([H|T],K/L-D/E,[K/L|C]):-c(T,I/J-X/Y,C),v(X/Y,H,D/E),K is I+X,L is J+Y,\+member(K/L,C).
p(S,L):-c(X,_,_),length(X,L),e([0|S],X).
これには指数関数的なパフォーマンスがあります(O(3 n)、nは出力)。しかし、私はいくつかの小さなテストでそれを検証することに成功しました(私のコンピューターでは、出力14に約7秒、出力15に約20秒かかります)。