読者です 読者をやめる 読者になる 読者になる

メモ

yukicoderで遊んでいる競プロゆるふわ勢

yukicoder No.113 宝探し

問題はこちら
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