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