JavaScript(ES6)、251 264 ... 244 240バイト
オオカミとニワトリの数を取得し(w, c)
、最適な解決策の1つを返します(解決策undefined
がない場合)。
(w,c,v={},B=1/0,S)=>(r=(s,w,c,W=0,C=0,d=1,N=0,k=w+'|'+c+d)=>v[k]|c*w>c*c|C*W>C*C|w<0|c<0|W<0|C<0?0:w|c?[v[k]=1,2,4,8,5].map(n=>r(s+'C'.repeat(b=n>>2)+'W'.repeat(a=n&3)+' ',w-d*a,c-d*b,W+d*a,C+d*b,-d,N+1))&(v[k]=0):N<B&&(B=N,S=s))('',w,c)||S
書式設定およびコメント化
ラッパー関数:
( // given:
w, // - w : # of wolves
c, // - c : # of chickens
v = {}, // - v : object keeping track of visited nodes
B = 1 / 0, // - B : length of best solution
S // - S : best solution
) => ( //
r = (...) => ... // process recursive calls (see below)
)('', w, c) || S // return the best solution
主な再帰関数:
r = ( // given:
s, // - s : current solution (as text)
w, c, // - w/c : # of chickens/wolves on the left side
W = 0, C = 0, // - W/C : # of chickens/wolves on the right side
d = 1, // - d : direction (1:left to right, -1:right to left)
N = 0, // - N : length of current solution
k = w + '|' + c + d // - k : key identifying the current node
) => //
v[k] | // abort if this node was already visited
c * w > c * c | C * W > C * C | // or there are more wolves than chickens somewhere
w < 0 | c < 0 | W < 0 | C < 0 ? // or we have created antimatter animals
0 //
: // else:
w | c ? // if there are still animals on the left side:
[v[k] = 1, 2, 4, 8, 5].map(n => // set node as visited and do a recursive call
r( // for each combination: W, WW, C, CC and CW
s + 'C'.repeat(b = n >> 2) + // append used combination to current solution
'W'.repeat(a = n & 3) + ' ', // wolves = bits 0-1 of n / chickens = bits 2-3
w - d * a, // update wolves on the left side
c - d * b, // update chickens on the left side
W + d * a, // update wolves on the right side
C + d * b, // update chickens on the right side
-d, // use opposite direction for the next turn
N + 1 // increment length of current solution
) //
) & // once we're done,
(v[k] = 0) // set this node back to 'not visited'
: // else:
N < B && // save this solution if it's shorter than the
(B = N, S = s) // best solution encountered so far
テストケース
let f =
(w,c,v={},B=1/0,S)=>(r=(s,w,c,W=0,C=0,d=1,N=0,k=w+'|'+c+d)=>v[k]|c*w>c*c|C*W>C*C|w<0|c<0|W<0|C<0?0:w|c?[v[k]=1,2,4,8,5].map(n=>r(s+'C'.repeat(b=n>>2)+'W'.repeat(a=n&3)+' ',w-d*a,c-d*b,W+d*a,C+d*b,-d,N+1))&(v[k]=0):N<B&&(B=N,S=s))('',w,c)||S
console.log(f(1, 1));
console.log(f(2, 2));
console.log(f(1, 2));
console.log(f(0, 10));
console.log(f(3, 2));