メモ

yukicoderでゆるふわgolf

yukicoder No.227 簡単ポーカー

問題はこちら
No.227 簡単ポーカー - yukicoder

まず各カードが何枚あるか調べ、2枚組み・3枚組みが何組あるか調べる

int main(){
	int i,d=0,t=0,a[14]={};
	for(i=0;i<5;i++){
		scanf("%d",&p);
		a[p]++;
	}
	//カードiがa[i]枚ある
	for(i=1;i<=13;i++){
		if(a[i]==2)d++;
		else if(a[i]==3)t++;
	}
	//ペアがd組、トリプルがt組ある
	if(t==1)puts(d==1?"FULL HOUSE":"THREE CARD");
	else puts(d==2?"TWO PAIR":d==1?"ONE PAIR":"NO HAND");
	return 0;
}

sという配列をとりn枚組みが何組あるかをs[n]に保存することにして

s[6],a[14],i;
main(j){
	for(;~scanf("%d",&i);a[i]++);
	for(;j<14;s[a[j++]]++);
	i=!puts(s[3]?s[2]?"FULL HOUSE":"THREE CARD":s[2]?s[2]-1?"TWO PAIR":"ONE PAIR":"NO HAND");
}

ループ圧縮、sのindexずらし、配列サイズのごまかし、メモリ違反の対処、諸々を詰め込んで

a[30],s[],i;
main(j){
	for(;!~scanf("%d",&i)?++s[a[j]-2],++j<14:++a[i];);
	i=!puts(s[1]?*s?"FULL HOUSE":"THREE CARD":*s?*s-1?"TWO PAIR":"ONE PAIR":"NO HAND");
}

154B

2016/06/09追記
出力部分の場合分けをちょっと考えた

a[30],s[],i;
main(j){
	for(;!~scanf("%d",&i)?++s[a[j]-2],++j<14:++a[i];);
	i=!puts("NO HAND\0*THREE CARD\0ONE PAIR\0FULL HOUSE\0TWO PAIR"+s[1]*9+*s*20);
}

148B
ペアやスリーカード検出がもう少し短くかけないかな……?

2016/12/03追記
sって配列で保存する必要ないじゃん

//やるべきことはこれ
s+=a[j]-2?a[j]-3?0:9:20;
//ぐっと睨むと次のように変形できる
s+=a[j]&2?42-a[j]*11:0;

ということでこう

a[30],s,i;
main(j){
	for(;!~scanf("%d",&i)?s+=a[j]&2?42-a[j]*11:0,++j<14:++a[i];);
	i=!puts("NO HAND\0*THREE CARD\0ONE PAIR\0FULL HOUSE\0TWO PAIR"+s);
}

146B


2017/07/29追記
sの代わりに*aを使う(±0B、波及効果まで含めて特に短縮効果はなし)
読み込みが終わってからではなく読み込みながら*aを計算すれば良い
1のとき0、2のとき20、3のとき-9、4のとき-11、5のとき0を足せば良い
頑張ってぐっと睨むことで次の式を得る

a[30],i;
main(j){
	for(;~scanf("%d",&j);*a-=11-i*2-i/2*7-i/3*18)i=(++a[j]+1)%4;
	puts("NO HAND\0*THREE CARD\0ONE PAIR\0FULL HOUSE\0TWO PAIR"+*a);
}

141B
文字列の部分の順序を変更して"NO HAND\0***ONE PAIR\0**TWO PAIR\0**THREE CARD\0FULL HOUSE"とする。
パディングが増えて+6Bとなるが、*aの計算式が綺麗にまとまり、一時変数iも不要となるので全体としては-5Bとなる

a[30];
main(j){
	for(;~scanf("%d",&j);*a+=a[j]++%4*(a[j]-4?11:-11));
	puts("NO HAND\0***ONE PAIR\0**TWO PAIR\0**THREE CARD\0FULL HOUSE"+*a);
}

136B