1. [0,2,3] -> 13
  2. [0] -> 1
  3. [0,1,2] -> 7
  4. [3] -> 8
  5. duplicates [1,1,2] -> 6
  6. [10] -> 1024
コース一覧
コンピューターサイエンス入門:理論編
OR / XOR でフラグを操作する

コンピューターサイエンス入門:理論編

2 進数、論理演算、ビット演算、データ構造、計算量、メモリモデルなど、プログラミングの土台となるコンピュータサイエンスの理論知識を学べるコースです。プログラミングを始めたばかりの学習者や、CS の体系的な土台を作りたい現役エンジニアを対象としています。約 13 時間 (1 日 30 分 × 26 日) で 53 レッスンを修了でき、修了後はコードのパフォーマンスや設計判断の根拠を理解した上で実装できるようになります。

1
2進数とビット演算
01. 2進数から10進数への変換5分
02. 10進数から2進数への変換5分
03. ビットAND演算でフラグ判定5分
04. OR / XOR でフラグを操作する5分
05. popcount で 1 のビット数を数える5分
06. シフト演算で 2 倍 / 半分5分
07. 16 進数から 10 進数への変換5分
08. 第 1 章まとめクイズ5分
2
文字コードと真偽値ロジック
01. 文字 → ASCII コード5分
02. コード → 文字5分
03. UTF-8 のバイト長を返す5分
04. AND / OR の真理値表5分
05. NOT / XOR の真理値表5分
06. 含意 (→) を AND/OR/NOT で表現5分
07. ド・モルガンの法則5分
08. 第2章まとめクイズ5分
3
計算量とBig-O
01. forループの実行回数を返す5分
02. 入れ子ループの実行回数5分
03. 線形探索 (O(n))5分
04. 二分探索 (O(log n))5分
05. バブルソート5分
06. 配列の最大と最小5分
07. 累積和で範囲合計5分
08. 第3章まとめクイズ5分
4
データ構造 (基本)
01. スタック (push/pop) を実装する5分
02. キュー (enqueue / dequeue) を実装する5分
03. カッコのバランス判定 (スタック応用)5分
04. set で重複を除去する5分
05. map で出現回数を数える5分
06. 二数の和 (map で O(n))5分
07. アナグラム判定5分
08. 第 4 章クイズ — データ構造 (基本)5分
5
ファイル / メモリ / IO 概念
01. バイト → KB 変換5分
02. ディスクサイズフォーマット5分
03. キャッシュヒット率5分
04. LRU 簡易シミュレーション5分
05. エンディアンの入れ替え (uint32)5分
06. バッファ範囲チェック5分
07. 第5章まとめクイズ5分
6
ネットワークと符号化
01. Base64 エンコード後の長さ計算5分
02. URL エンコード対象文字数5分
03. IPv4 アドレスを 32bit 整数に変換5分
04. 32bit 整数を IPv4 アドレスに変換5分
05. CIDR プレフィックスからネットマスクを作る5分
06. 単純チェックサム5分
07. 第6章まとめクイズ5分
7
設計と DB 基礎
01. 重複データを 1NF に変換 (フラットなリスト化)5分
02. キーで join (map 利用)5分
03. 残高転送のトランザクション風処理5分
04. CAP の availability 模擬5分
05. URL ルーティング5分
06. 疎結合と密結合 — 依存性注入で設計を変える12分
07. コース総まとめクイズ5分

OR / XOR でフラグを操作する

見るだけでは、設定を変えられない

前回、整数に詰め込んだ通知設定を & で読み出しました。読めるようになると、次に困るのは書くほうです。プッシュ通知だけをオンにしたい。SMS だけを今と逆にしたい。ほかの桁は 1 つも触らずに、です。

足し算では駄目です。すでにオンの桁にもう一度足すと繰り上がって、隣の桁を壊します。桁をまたがない演算が要ります。

OR は、消さずに立てる

| は、どちらかが 1 なら 1 を返します。両方が 0 のときだけ 0 です。

プレーンテキスト

0 | 0 = 0 0 | 1 = 1 1 | 0 = 1 1 | 1 = 1

立てたい桁だけ 1 のマスクと | を取ると、その桁が 1 になります。もともと 1 だった桁は 1 のまま、マスクが 0 の桁も手つかずです。何度繰り返しても結果が変わらないので、二重にオンにしてしまう心配がありません。

Python

PUSH = 0b010 settings = 0b101 # メールと SMS settings = settings | PUSH print(settings) # 7 3 つとも立った settings = settings | PUSH print(settings) # 7 何度やっても同じ

XOR は、押すたびに入れ替わる

^ は、2 つが違うときだけ 1 を返します。同じなら 0 です。

プレーンテキスト

0 ^ 0 = 0 0 ^ 1 = 1 1 ^ 0 = 1 1 ^ 1 = 0

マスクの 1 が立っている桁は、0 なら 1 に、1 なら 0 に変わります。マスクが 0 の桁は動きません。つまり ^ は「その桁のスイッチを押す」操作です。

Python

SMS = 0b100 settings = 0b111 settings = settings ^ SMS print(settings) # 3 SMS が消えた settings = settings ^ SMS print(settings) # 7 戻ってきた

同じマスクを 2 回当てると元に戻ります。オンとオフを行き来するトグルボタンが、この 1 行で書けます。

| と || は別物

Python なら | と or、JavaScript なら | と || です。字面は似ていますが、前者は桁ごとの計算、後者は式全体を真偽値として見る演算です。

フラグを組み立てているところで or を書くと、桁ごとの計算をしてくれません。0b101 or 0b010 は 0b111 ではなく、左が真なので 0b101 がそのまま返ります。エラーにならず、それらしい数が返ってくるのがたちの悪いところです。

要件

  1. bits は 0 以上の整数のリスト (同じ値が複数回含まれてもよい)
  2. ビット OR 演算 (|) を使うこと
  3. 空配列の場合は 0 を返すこと

入出力例

flagsToInt([0,2,3]) → 13 flagsToInt([0]) → 1 flagsToInt([0,1,2]) → 7 flagsToInt([3]) → 8 flagsToInt([1,1,2]) → 6 flagsToInt([10]) → 1024

ヒント

result = 0 から始めて、各 k について result = result | (1 << k) を繰り返す

1 << k がそのビットだけ立ったマスク。k = 3 ならマスクは 0b1000 = 8

同じビットを何度 OR してもそのビットは 1 のまま (冪等) なので、重複は気にしなくて良い

生田 陸人
監修生田 陸人
ゆめさくエンジニア / 現役ソフトウェアエンジニア監修者プロフィールを見る →
編集 ゆめさく編集部·公開 2026/05/19·更新 2026/08/26

関連レッスン

  • popcount で 1 のビット数を数える

    整数を 2 進数で表したときに含まれる 1 の個数 (popcount) を求める関数を実装する。

  • シフト演算で 2 倍 / 半分

    左シフトと右シフトで 2 のべき乗倍 / 除算を高速に行う仕組みを学び、シフト演算による倍率変換を実装する。

  • 16 進数から 10 進数への変換

    16 進数 (hexadecimal) の文字列を 10 進数の整数に変換する関数を実装し、4 ビット = 1 桁の関係を理解する。

  • 第 1 章まとめクイズ

    2 進数とビット演算の理解度を確認するまとめクイズ。

このレッスンに出てくる用語

意味があいまいなまま進んだ語は、ここから読み直せます。

  • JavaScriptWeb で動的な振る舞いを担う言語
  • リスト順序付きで複数の値を扱うデータ構造
  • ビット2進数の1桁。0 か 1 のどちらか
  • 配列サイズ固定の同型データの集まり
main.py
学習モード
エディタを読み込んでいます

メモ

OR / XOR でフラグを操作する

⌘S で保存