XOR と AND の繰り上がりで、+ を使わずに 2 つの整数を足す

+ と - を使わずに、2 つの整数の和を求めます。繰り上がりを無視した和は XOR、繰り上がりは AND を 1 ビット左へずらした値なので、繰り上がりが 0 になるまで 2 つを足し直す練習です。

海外で定番の問題リスト 4 本には入っていません

問題

足し算の回路を作る練習として、整数 a と b の和を返す関数を書いてください。ただし、+ と - の演算子 (+=、++ なども) は使わず、ビット演算で求めます。

  • a と b は -1000000000 以上 1000000000 以下です。和は 32 ビットの符号つき整数 (-2147483648 以上 2147483647 以下) に収まります
  • 負の数は、32 ビットの 2 の補数として扱います

入力と出力の例

例 1

a = 13 b = 29
42

例 2

負の数と正の数の和です。

a = -8 b = 5
-3

例 3

負の数どうしの和です。

a = -6 b = -9
-15

面接での聞かれ方

面接では、計算機の中で足し算がどう行われているかを聞く問題として出されます。

  • 「+ を使わずに 2 つの整数を足してください」
  • 正の数で書けると、「負の数ではどうなりますか?」と続きます
  • Python で書くと、「整数に上の限りが無いと、ループが止まりますか?」と聞かれます

1 ビットの足し算を XOR と AND に分けられるか、そして言語ごとの整数の幅の違いを扱えるかが見られています。

ヒント

まだ開いていません

付箋は 3 枚。下の段ほど答えに近づきます

  1. ヒント 2

  2. ヒント 3答えに近い

アルゴリズムのチートシートの「配列と文字列」に、この型の要点を表とコードでまとめています。

配列と文字列の問題は、全部の組を調べると手間が大きくなる所を、窓や左右の添字で減らす形が多いです。

main.py
def add_without_plus(a: int, b: int) -> int:
    """
    Goal: 何を返すか

    idea1: まず思いつく案
    -> runtime: O(?)  space: O(?)

    idea2: もっと速い案
    -> runtime: O(?)  space: O(?)

    edge case: 空、1 つだけ、など
    """
    # ここに書きます
    pass


# 「実行」を押すと、この行の結果が出ます
print(add_without_plus(13, 29))

できているか「例で確かめる」を押すと、問題の例を全部この関数に渡して、通ったかをここに出します