naiの日記

ソフトウェアエンジニアから放射線科診断医にジョブチェンジしました。趣味のことを書きます。

1029. Bijective base 10 add

問題文:anarchy golf - Bijective base 10 add

問題概要

Base-10 bijective numeration同士の足し算を実装せよ.

ここで,Base-10 bijective numerationとは,各桁に 0, 1, ..., 9 ではなく 1, 2, ..., A を用いる記法らしい.

私の解法

104B@C

c;
main(b,p,a){
  ~scanf("%x%Lx"-c,&a,&b)
    &&main(b/16,c?p<<8|48+(c%10?:17):puts(&p),a/16,c+=a%16+b%16-c*.9);
}

解説

  • 入力の2数を16進数で ab に取得し,16で割りながら加算を行っていく.
  • c は最下位の桁の和+キャリーを保持する.
  • 計算結果はビットシフトしながら p に保持しておき,最後に puts(&p) で一度に出力している.

工夫した点

  • 最初のscanfで,2つ目の入力に %Lx を用いている.ここで8バイト分の入力を読み込むため,メモリ上で b の隣にある p がゼロクリアされる.
  • 浮動小数点誤差のため, c が10の倍数のとき c*.9 はcの10分の9倍よりわずかに大きい値となる. c+=a%16+b%16-c*.9 の部分はこれを利用しており,cが11以上のとき1が,21以上のとき2がキャリーとして加算される仕組みになっている.

感想

関数定義&再帰呼び出し→2重forループ→1重forループ→main再帰と解法が目まぐるしく変化しました.最終的にはすっきりしたmain再帰となり,満足いく結果となりました.

浮動小数点誤差を利用して1バイト減らしているところがおしゃれ.