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 );
}
解算器在以下前提下运行:从球(洞)到任何路径都将
- 再次回到球(洞)
- 导致洞(球)
- 退出课程
我们在所有四个方向上跟踪球的路径。如果找到情况3,问题就解决了。如果找到情况2,则标记球的出口位置。如果所有四个方向都导致情况1,我们将沿任意轨迹的第一个非保险杠空间转换为保险杠(如果问题可以解决,则始终保证存在该空间),然后重试。我们转换为的保险杠与我们遇到的最后一个保险杠具有相同的类型*。如果球仍然卡在一个循环中,我们将根据需要重复此过程多次。如果问题可以解决,则可以确保此过程最终导致结果2或3。
(*请注意,如果我们简单地转换为固定的保险杠[例如\
],则存在极度人为的但仍然可能存在解决方案的情况,但我们将找不到它。)
我们从洞中执行类似的跟踪,导致结果2或结果3。
如果球迹和孔迹都导致结果2,我们在连接两个出口点的路线外围放置保险杠(实际上,不管迹线结果如何,都放置了这些外围保险杠,以缩短代码)。这样就完成了解决方案。
测试用例和输出
在
/ \ / \ /\
\\ / \ \
/ / o /
/ \ /
\ . \ \ \\
/ / \ \
\ /
\ /
\ /\ / \/ //\
出
right
/ / \
/ \ / \ /\
\\ / \ \
/ / o /
/ \ /
\ . \ \ \\
/ / \ \
\ / /
\ /
\ /\ / \/ //\
\ /
在
/ \ / / / \ / \ / \\ /
\ \ / \ // \ \ / /\ \
/ \ // \ // \ \ \ / / \\ \
\ / \ / \ \ / / \\ / / //
/ / /\ \\ // / \ / \ / \\ \ \
\ \ \ \ // \ / / \ \ / / /
/ \ / / / \ / \ /\ / \ /
\ /\ //\ .\ \ \ //\ / \ / \ /
/ \/ \ /\ //\ / \ / o// \ / \
/ / \ / \ / \\ / \ / \ \ \
/ / / \ / \ // \ / \/ /\/
/ \ / \ / \\ / \ /\ / \
/ \/ \ / \/ \ / \ /\\
/ /\\ //\ / \ /\ /\ / / \ / \/
出
left
/ \
/ \ / / / \ / \ / \\ /
\ \ / \ // \ \ / /\ \
/ \ // \ // \ \ \ / / \\ \
\ / \ / \ \ / / \\ / / //
/ / /\ \\ // / \ / \ / \\ \ \
\ \ \ \ // \ / / \ \ / / /
/ \ / / / \ / \ /\ / \ /
\ /\ //\ .\ \ \ //\ / \ / \ /
/ \/ \ /\ //\ / \ / o// \ / \
/ / \ / \ / \\ / \ / \ \ \
/ / / \ / \ // \ / \/ /\/
/ \ / \ / \\ / \ /\ / \
/ \/ \ / \/ \ / \ /\\
/ /\\ //\ / \ /\ /\ / / \ / \/
\ \ /
在
/\/ \
\ \ \
\ \\ \ o
\ .\ \
\ / /
\ /
出
down
/ \ /\
/\/\\
\ \\ \
\ \\ \ o
\ .\ \
\ / /
\ /
\ /
right
,#3示例1应该是down
,#3示例2应该是up
。有趣的挑战!