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

メモ

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

yukicoder No.446 ゆきこーだーの雨と雪 (1)

問題はこちら
No.446 ゆきこーだーの雨と雪 (1) - yukicoder

0~12345のいずれかと文字列として一致しているかどうかを調べるだけ
c++ならto_string関数なるものがあるらしいが、cにはない
文字列を数値にするならatoiという関数があるのでitoaとかないのかと思いぐぐったところ、非標準ライブラリらしく使えない
代わりにsprintfを使えとwikipediaには書いてあった

int f(char*s){
	char t[10];
	int i;
	for(i=0;i<=12345;i++){
		sprintf(t,"%d",i);
		if(strcmp(s,t)==0)return 1;
	}
	return 0;
}

int main(){
	char a[10],b[10];
	gets(a);
	gets(b);
	puts(f(a)&&f(b)?"OK":"NG");
	return 0;
}

Aに対する処理とBに対する処理が全く同じなので適当に縮めて

f;char s[9],t[9];
main(n){
	for(;gets(s);)for(n=12346;n;f+=!strcmp(s,t))sprintf(t,"%d",--n);
	n=!puts(f-2?"NG":"OK");
}

入力は高々5文字('\0'含め6文字)だから、char型の配列を作らなくてもint型の変数に押し込めそう。
あとはいい感じにループ圧縮をして

n,s;main(f,t){for(;n?sprintf(&t,"%d",--n),f-=!strcmp(&s,&t):(n=gets(&s)?12346:!puts(~f?"NG":"OK")););}

102B

そういえばstrtolとかいう便利関数があったのでこっちの可能性も探る

f;
char*t,s[];
main(){
	for(;gets(s);)f|=strtol(s,&t,0)>12345|*t|(*s==48&&s[1]);
	f=!puts(f?"NG":"OK");
}

よく考えると*s==48は*s<49と書き換えられる。
ここで、&は|よりも優先度が高いことから、次のように縮められる

strtol(s,&t,0)>12345|*t|(*s==48&&s[1])
strtol(s,&t,0)>12345|*t|(*s<49&&s[1])
strtol(s,&t,0)>12345|*t|*s<49&!!s[1]

ということで

f;
char*t,s[];
main(){
	for(;gets(s);)f|=strtol(s,&t,0)>12345|*t|*s<49&!!s[1];
	f=!puts(f?"NG":"OK");
}

96B