Javascript(ES6)-651バイト
G=s=>{Q='\\';S=[[]];n=L=1;s.split(N='\n').map(t=>{j=S[L++]=[];l=t.length;n=n>l?n:l;k=1;t.split('').map(T=>{j[k++]=T})});S[O=L++]=[];n++;for(r=0;r<L;r++)for(c=0;c<=n;c++){v=S[r][c];if(!v)S[r][c]=' ';if(v=='.'){x=c;y=r}if(v=='o'){X=c;Y=r}}f=M=>{J=M?'.':'o';K=M?'o':'.';R=0;for(D=0;1;D++){R=D&4;D=D&3;c=e=D;g=M?X:x;h=M?Y:y;while(c!=K){c=S[h+=[-1,0,1,0][e]][g+=[0,1,0,-1][e]];e=c=='/'?(B=c,e^1):c==Q?(B=c,3-e):e;E=h*(h-O)?g*(g-n)?0:2:1;if(R&&c==' '){S[h][g]=Q;R=D=0;c=K}if(c==J||E){E&&(S[h][g]=(E+M)%2?Q:'/');H=M?E?H:(e+2)&3:D;return}}}};f(0);f(1);S[0][0]=S[O][n]='/';S[0][n]=S[O][0]=Q;return['up','right','down','left'][H]+N+S.map(t=>t.join('')).join(N)}
G入力として文字列(ゴルフコース)を受け入れ、要求されたパッティングソリューションを返す関数を作成します。入力文字列には、先頭の行、末尾の行、末尾の空白が含まれる場合と含まれない場合があります。出力には、先頭または末尾の空白はありません。
拡張コードは次のとおりです。
G = s => {
Q = '\\';
S = [[]];
n = L = 1;
s.split( N = '\n' ).map( t => {
j = S[L++] = [];
l = t.length;
n = n > l ? n : l;
k = 1;
t.split('').map( T => {
j[k++] = T;
} );
} );
S[O = L++] = [];
n++;
for( r = 0; r < L; r++ )
for( c = 0; c <= n; c++ ) {
v = S[r][c];
if( !v )
S[r][c] = ' ';
if( v == '.' ) {
x = c;
y = r;
}
if( v == 'o' ) {
X = c;
Y = r;
}
}
f = M => {
J = M ? '.' : 'o';
K = M ? 'o' : '.';
R = 0;
for( D = 0; 1; D++ ) {
R = D & 4;
D = D & 3;
c = e = D;
g = M ? X : x;
h = M ? Y : y;
while( c != K ) {
c = S[h += [-1,0,1,0][e]][g += [0,1,0,-1][e]];
e = c == '/' ? (B=c,e^1) : c == Q ? (B=c,3-e) : e;
E = h*(h-O) ? g*(g-n) ? 0 : 2 : 1;
if( R && c == ' ' ) {
S[h][g] = B;
R = D = 0;
c = K;
}
if( c == J || E ) {
E && (S[h][g] = (E+M)%2 ? Q : '/');
H = M ? E ? H : (e+2)&3 : D;
return;
}
}
}
};
f(0);
f(1);
S[0][0] = S[O][n] = '/';
S[0][n] = S[O][0] = Q;
return ['up','right','down','left'][H] + N + S.map( t => t.join('') ).join( N );
}
ソルバーは、ボール(穴)からのパスが次のいずれかになることを前提に動作します。
- 再びボール(穴)に戻る
- 穴(ボール)につながる
- コースを出る
4つの方向すべてでボールの経路をトレースします。ケース3が見つかった場合、問題は解決されます。ケース2が見つかった場合、ボールの出口位置をマークします。4つの方向すべてがケース1になる場合、任意の軌道に沿った最初の非バンパー空間をバンパーに変換し(問題が解決可能な場合、そのような空間は常に存在することが保証されます)、再試行します。変換後のバンパーは、軌跡が最後に遭遇したバンパーと同じタイプになります*。ボールがまだループ内に残っている場合は、必要な回数だけプロセスを繰り返します。問題が解決可能な場合、この手順は最終的に結果2または3につながることが保証されています。
(*単純に固定バンパーに変換する場合[たとえば、\]、非常に不自然ですが、それでも解決策が存在する可能性のあるケースが存在しますが、それを見つけられないことに注意してください。)
穴から同様のトレースを実行し、結果2または結果3のいずれかを導きます。
ボールトレースとホールトレースの両方が結果2になる場合、2つの出口点をリンクするコースの周辺にバンパーを配置します(実際、これらの周辺バンパーは、トレースの結果に関係なく、コードを短縮するために配置されます)。これでソリューションは完了です。
テストケースと出力
に
/ \ / \ /\
\\ / \ \
/ / o /
/ \ /
\ . \ \ \\
/ / \ \
\ /
\ /
\ /\ / \/ //\
でる
right
/ / \
/ \ / \ /\
\\ / \ \
/ / o /
/ \ /
\ . \ \ \\
/ / \ \
\ / /
\ /
\ /\ / \/ //\
\ /
に
/ \ / / / \ / \ / \\ /
\ \ / \ // \ \ / /\ \
/ \ // \ // \ \ \ / / \\ \
\ / \ / \ \ / / \\ / / //
/ / /\ \\ // / \ / \ / \\ \ \
\ \ \ \ // \ / / \ \ / / /
/ \ / / / \ / \ /\ / \ /
\ /\ //\ .\ \ \ //\ / \ / \ /
/ \/ \ /\ //\ / \ / o// \ / \
/ / \ / \ / \\ / \ / \ \ \
/ / / \ / \ // \ / \/ /\/
/ \ / \ / \\ / \ /\ / \
/ \/ \ / \/ \ / \ /\\
/ /\\ //\ / \ /\ /\ / / \ / \/
でる
left
/ \
/ \ / / / \ / \ / \\ /
\ \ / \ // \ \ / /\ \
/ \ // \ // \ \ \ / / \\ \
\ / \ / \ \ / / \\ / / //
/ / /\ \\ // / \ / \ / \\ \ \
\ \ \ \ // \ / / \ \ / / /
/ \ / / / \ / \ /\ / \ /
\ /\ //\ .\ \ \ //\ / \ / \ /
/ \/ \ /\ //\ / \ / o// \ / \
/ / \ / \ / \\ / \ / \ \ \
/ / / \ / \ // \ / \/ /\/
/ \ / \ / \\ / \ /\ / \
/ \/ \ / \/ \ / \ /\\
/ /\\ //\ / \ /\ /\ / / \ / \/
\ \ /
に
/\/ \
\ \ \
\ \\ \ o
\ .\ \
\ / /
\ /
でる
down
/ \ /\
/\/\\
\ \\ \
\ \\ \ o
\ .\ \
\ / /
\ /
\ /
right、#3例1はdown、#3例2はである必要がありますup。しかし、興味深い挑戦です!