問題はこちら
No.113 宝探し - yukicoder
1文字ずつ処理するだけ
int main(){ int a=0,b=0,i; char s[110]; gets(s); for(i=0;s[i];i++){ if(s[i]=='E')a++; else if(s[i]=='W')a--; else if(s[i]=='N')b++; else b--; } printf("%f",hypot(a,b)); return 0; }
すぐに思いつく圧縮
a,b;main(x){ for(;x=getchar()-10;x-68?x-73?x-59?b--:b++:a--:a++); a=!printf("%f",hypot(a,b)); }
さてENSWの4文字をどうにかして判別する方法はないか考える
getchar()-10も~getcharにできたらいいな
N | 78 | 01111000 |
S | 83 | 10000011 |
E | 69 | 01101001 |
W | 87 | 10000111 |
うんダメそう
1桁で剰余をとってもダメなことが確かめられるので、2桁でやってみる。とりあえず69とか
N | -10 | 11110110 |
S | -15 | 11110001 |
E | -1 | 11111111 |
W | -19 | 11101101 |
下から2bit目と4bit目を見ればうまくいくみたい。
最後の改行は-11で11110101だからSと同じモノとして扱われるのでそこに注意すると
a[9]; main(x){ for(;x=~getchar()%69;a[x&8]+=(x&2)-1); *a=!printf("%f",hypot(++*a,a[8])); }
とできる。でも++*aをどうにかしたい…
getcharの引数に投げ込んでやれば、最初の1回でxが1の時に実行されるから、それでうまく相殺できるようにならない?
そのままだと1のときはSと同じに扱われてしまう
よく見ると'E'<'N'<'S'<'W'なので大小関係でどうにかなりそうなので、2bit目を見るのをやめてx/(何か)を考えてみる
すると次でうまい具合に噛みあう
a[9]; main(x){ for(;x=~getchar(a[x&8]+=x/11*2+1)%69;); *a=!printf("%f",hypot(*a,a[8])); }
最後の出力を工夫しつつ配列の宣言をごまかすと完成
a[],x;main(){for(;x=~getchar(a[x&8]+=x/11*2+1)%69?:!printf("%f",hypot(*a,a[8])););}
83B