11module
2-
3- def decode_cyclic : Unit :=
4- ()
2+ import Std.Tactic.Do
3+ import Std
4+ import all Init.Data.Range.Polymorphic.UpwardEnumerable -- UpwardEnumerable.least not exposed
5+
6+ open Std Std.Do
7+
8+ def encodeVector {n : Nat} (arr : Vector α n) : Vector α n := Id.run do
9+ let mut vec : Vector α n := arr
10+
11+ for h : i in (*...n / 3 ) do
12+ let tmp := vec[3 * i]
13+ vec := vec.set (3 * i) vec[3 * i + 1 ]
14+ vec := vec.set (3 * i + 1 ) vec[3 * i + 2 ]
15+ vec := vec.set (3 * i + 2 ) tmp
16+
17+ return vec
18+
19+ def encodeArray (arr : Array α) : Array α :=
20+ (encodeVector arr.toVector).toArray
21+
22+ def encodeCyclic (s : String) : String :=
23+ String.ofList (encodeArray s.toList.toArray).toList
24+
25+ def decodeCyclic (s : String) : String :=
26+ String.ofList (encodeArray (encodeArray s.toList.toArray)).toList
27+
28+ theorem List.Cursor.length_prefix_le {l : List α} (c : l.Cursor) : c.prefix.length ≤ l.length := by
29+ have := congrArg List.length c.property
30+ simp at this
31+ omega
32+
33+ theorem Nat.eq_add_of_toList_rio_eq_append_cons {a : Nat} {pref cur suff}
34+ (h : (*...a).toList = pref ++ cur :: suff) :
35+ cur = pref.length := by
36+ have := Rio.eq_succMany?_of_toList_eq_append_cons h
37+ simpa [PRange.UpwardEnumerable.least, PRange.least?] using this
38+
39+ set_option mvcgen.warning false in
40+ theorem getElem_encodeVector {arr : Vector α n} {i : Nat} {hi} :
41+ (encodeVector arr)[i]'hi =
42+ if h : i < 3 * (arr.size / 3 ) then
43+ if hmod : i % 3 = 2 then
44+ arr[i - 2 ]
45+ else
46+ arr[i + 1 ]
47+ else
48+ arr[i]'(by simp_all) := by
49+ generalize hwp : encodeVector arr = wp
50+ apply Id.of_wp_run_eq hwp
51+ mvcgen invariants
52+ · ⇓⟨xs, vec⟩ =>
53+ ⌜∀ (i : Nat) (hi : i < n), vec[i] =
54+ have : xs.prefix.length ≤ n / 3 := by simpa using xs.length_prefix_le
55+ if h : i < 3 * xs.prefix.length then
56+ if hmod : i % 3 = 2 then
57+ arr[i - 2 ]
58+ else
59+ arr[i + 1 ]
60+ else
61+ arr[i]'(by simp_all)⌝
62+ with
63+ grind [Nat.eq_add_of_toList_rio_eq_append_cons, Rio.length_toList, Nat.size_rio]
64+
65+ @[simp]
66+ theorem encodeVector_encodeVector_encodeVector {arr : Vector α n} :
67+ encodeVector (encodeVector (encodeVector arr)) = arr := by
68+ grind [getElem_encodeVector]
69+
70+ @[simp]
71+ theorem encodeArray_encodeArray_encodeArray {arr : Array α} :
72+ encodeArray (encodeArray (encodeArray arr)) = arr := by
73+ ext
74+ · simp [encodeArray]
75+ · simp only [encodeArray, Vector.getElem_toArray, getElem_encodeVector, Vector.size_toArray,
76+ Vector.getElem_mk, Nat.reduceSubDiff]
77+ grind
78+
79+ theorem decodeCyclic_encodeCyclic {s : String} : decodeCyclic (encodeCyclic s) = s := by
80+ simp [decodeCyclic, encodeCyclic]
581
682/-!
783## Prompt
@@ -51,4 +127,4 @@ def check(candidate):
51127 assert candidate(encoded_str) == str
52128
53129```
54- -/
130+ -/
0 commit comments