カメヲラボ

主にプログラミングとお勉強全般について書いてます

Parliament(7)

  • 超絶テクニック(短縮その3)

前回までのテクニックを使うと、このように90バイトのコードができる。

i,m;
main(t){
  for(scanf("%d",&t);t-m>1;)t+=~++m;
  for(;i<m;)
    printf("%d ",t/m-~++i+(i+t%m>m));
}

これでも十分短いが、


③for文は一回で出来ないだろうか。
コイツがまだ残っている。これだけ短くなっていると、意外にfor文を一つにまとめるのは難しくない。プログラム自体の終了判定を二つ目のループに書いてある

i<m

とする。ただし、そのままでは0<0が偽になりいきなり終了してしまうので、

!i|i<m

のように書いておく。ループ中は3項演算子を使い

t-m>1?t+=~++m:printf("%d ",t/m-~++i+(i+t%m>m));

のように書くだけで良い。これでコードは87バイト

i,m;
main(t){
  for(scanf("%d",&t);!i|i<m;)
    t-m>1?t+=~++m:printf("%d ",t/m-~++i+(i+t%m>m));
}

これで終わりのようにも見えるが、まだ縮む。

t-m>1

の部分。この不等式の両辺に-1をかけると、
m-t<-1になるが、この"-1"の部分にscanfを持ってくる。この問題は数値を一つ読み出すだけなので、最初の1回で十分なのだが、さらにscanfしようとするとEOF(-1)が返って来ることを利用しようというわけだ。まったく、酷いコードである。しかしこれで86バイト。変態的なコードが完成したのだ。

i,m;
main(t){
  for(;!i|i<m;)
    m-t<scanf("%d",&t)?t+=~++m:printf("%d ",t/m-~++i+(i+t%m>m));
}