C、262 260
ゴルフコード(デバッグコードと不要な空白が削除されました。stdinを介した入力からコマンドラインを介した入力に変更され、変数iを宣言する機会を利用しました。最新の編集:コードはfor
ループの括弧に移動して2つのセミコロンを保存します。)
t[420],j,l,x,y;f(p,d){int z,q,k;for(k=6;k--;t[q]&!t[p+z]?t[q]=0,f(q,d+1),t[q]=1:0)z="AST?-,"[k]-64,q=p+z*2;l=d>l?d:l;}main(int i,char**s){for(i=840;i--;x>3&y>5&x+y<23|x<13&y<15&x+y>13?i>420?t[i-420]=49-s[1][j++]:t[i]||f(i,0):0)x=i%20,y=i/20%21;printf("%d",l);}
説明
これは、次のような20x21ボードに依存しています。最初は、プログラムの開始時にゼロで埋められます(このASCIIアートは、プログラムの修正バージョンによって生成され、i
ループが下向きにカウントされるため、右下隅にゼロがあります)。
....................
....................
...............#....
..............##....
.............###....
............####....
.......#############
.......############.
.......###########..
.......##########...
.......#########....
......##########....
.....###########....
....############....
...#############....
.......####.........
.......###..........
.......##...........
.......#............
....................
....................
ループi
がこのボードを2回実行し、xとyを使用して、正方形が実際にチェッカーボードに属するかどうかを計算します(これには、xとyに6つの別々の不等式が必要です)。
存在する場合、最初のラウンドで正方形がいっぱいになり0
、1
(占有されている)には1
(偽)、0
(占有されていない)には(真実)が置かれます。すべての境界外の正方形にはすでに0が含まれているため、この反転は重要です。つまり、占有された正方形に似ており、特定のチェックを必要とせずにジャンプできないことは明らかです。
2回目のラウンドでは、正方形が占有されている(0を含む)場合f
、動きを検索する関数を呼び出します。
f
式でエンコードされた+/- 1(水平)、+ /-20(垂直)、+ /-19(対角)でエンコードされた6つの可能な方向で再帰的に検索します"AST?-,"[k]-64
。ヒットを見つけると、再帰的に呼び出す前にそのセルを0(占有)に設定し、関数が返されると1(空)に戻します。セルの値は、そのセルに複数回ホッピングしないように、再帰呼び出しの前に変更する必要があります。
未ゴルフコード
char s[999]; //input string.
t[420],i,j,l,x,y; //t=board. i=board counter, j=input counter. l=length of longest hop found so far.
f(p,d){ //p=position, d= recursion depth.
//printf("%d,%d ",p,d); //debug code: uncomment to show the nodes visited.
int k,z,q; //k=counter,z=displacement,q=destination
for(k=6;k--;) //for each direction
z="AST?-,"[k]-64, //z=direction
q=p+z*2, //q=destination cell
t[q]&!t[p+z]? //if destination cell is empty (and not out of bounds) and intervening cell is full
t[q]=0,f(q,d+1),t[q]=1 //mark destination cell as full, recurse, then mark it as empty again.
:0;
l=d>l?d:l; //if d exceeds the max recorded recursion depth, update l
}
main(){
gets(s); //get input
for(i=840;i--;) //cycle twice through t
x=i%20, //get x
y=i/20%21, //and y coordinates
x>3&y>5&x+y<23|x<13&y<15&x+y>13? //if they are in the bounds of the board
i>420?
t[i-420]=49-s[j++] //first time through the array put 0 for a 1 and a 1 for a 0 ('1'=ASCII49)
:t[i]||f(i,0) //second time, if t[i]=0,call f().
//,puts("") //puts() formats debug output to 1 line per in-bounds cell of the board
:0;
printf("%d",l); //print output
}