カメヲラボ

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

Number Sequence(1)

ようやく解決

インプットが1,10,100...のように10^nだとうまく出力できなかったが、コードを短くするうちに解決したので、やっと書ける。とは言うもののこれが最短コードなのかチェックしてない、つーかあんまりやる元気がない^^;

というわけで、とりあえずコードを晒しておきます。これで144バイト。もちろんgets()を使っているのでCじゃないとムリっす。


char t['~~~'];
unsigned j,k,n;

main(i){
for(gets();~scanf("%u",&n);printf("%c\n",t[n>k?n-k-1:i-1]))
for(i=j=k=0;n>k+j;)k+=j+=sprintf(t+j,"%d",++i);
}

12345678910111213...という文字列を作って、それが何番目かを計算する。群数列というほどのものでもないかな。ロベールさんにコードを見せてもらったら、なんかカシコそーな方法でunsignedを避けていたので、併せてもうちょっと短くならんかなーと思うのだが・・・。ロベールさんに了解取るの忘れたので、あとで確認してOKなら紹介します。

あ、それからインプットが10^nの場合何がマズかったかというと、n-kが0以下になってしまってランタイムエラーになってしまう。なので、n-kが正の場合と荘じゃない場合に分けてごまかしました。

追記:
ロベールさんの了解を得たので紹介。


char b[' '];
j,s['z$'];

main(i,n){
 for(;i<'z$';++i)
  s[i]=j+=sprintf(b+j,"%d",i);
 for(gets(n);~scanf("%d",&i);printf("%c\n",b[i-1]))
  for(j=0;i>s[++j];i-=s[j]);
}

なるほど、signed intでも収まるように配列を使っているわけですナ。最初に文字列を生成してしまっているのでこれだと高速ですね。