問題文:anarchy golf - Bijective base 10 add
問題概要
Base-10 bijective numeration同士の足し算を実装せよ.
ここで,Base-10 bijective numerationとは,各桁に 0, 1, ..., 9
ではなく 1, 2, ..., A
を用いる記法らしい.
私の解法
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進数で
a
とb
に取得し,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バイト減らしているところがおしゃれ.