問題 49
(中級 🌟🌟) グレイコード。
nビットのグレイコードは、特定の規則に従って構成されるnビット列の列である。例えば、
n = 1: C(1) = ['0','1'].
n = 2: C(2) = ['00','01','11','10'].
n = 3: C(3) = ['000','001','011','010','110','111','101','100'].
この構成規則を見つけ、次の仕様の述語を実装せよ:
% gray(N,C) :- C is the N-bit Gray code
「結果のキャッシュ」手法を使って、繰り返し使う場合により効率的にできるか?
/-- 1ビットを表す型 -/
inductive Digit : Type where
| zero
| one
deriving DecidableEq
/-- グレイコードはDigitのリスト -/
abbrev GrayCode := List Digit
/-- Digitを文字列に変換 -/
def Digit.toString : Digit → String
| .zero => "0"
| .one => "1"
instance : OfNat Digit 0 where
ofNat := Digit.zero
instance : OfNat Digit 1 where
ofNat := Digit.one
instance : ToString Digit where
toString := Digit.toString
def gray (n : Nat) : List GrayCode :=
match n with
| 0 => []
| 1 => [[.zero], [.one]]
| n + 1 =>
let prev := gray n
let revPrev := prev.reverse
(prev.map (fun d => Digit.zero :: d)) ++ (revPrev.map (fun d => Digit.one :: d))
#guard gray 1 = [[0], [1]]
#guard gray 2 = [[0, 0], [0, 1], [1, 1], [1, 0]]
#guard gray 3 = [
[0, 0, 0],
[0, 0, 1],
[0, 1, 1],
[0, 1, 0],
[1, 1, 0],
[1, 1, 1],
[1, 0, 1],
[1, 0, 0]
]