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)
49+ := by
50+ generalize hwp : encodeVector arr = wp
51+ apply Id.of_wp_run_eq hwp
52+ mvcgen invariants
53+ · ⇓⟨xs, vec⟩ =>
54+ ⌜∀ (i : Nat) (hi : i < n), vec[i] =
55+ have : xs.prefix.length ≤ n / 3 := by simpa using xs.length_prefix_le
56+ if h : i < 3 * xs.prefix.length then
57+ if hmod : i % 3 = 2 then
58+ arr[i - 2 ]
59+ else
60+ arr[i + 1 ]
61+ else
62+ arr[i]'(by simp_all)⌝
63+ with
64+ grind [Nat.eq_add_of_toList_rio_eq_append_cons, Rio.length_toList, Nat.size_rio]
65+
66+ @[simp]
67+ theorem encodeVector_encodeVector_encodeVector {arr : Vector α n} :
68+ encodeVector (encodeVector (encodeVector arr)) = arr := by
69+ grind [getElem_encodeVector]
70+
71+ @[simp]
72+ theorem encodeArray_encodeArray_encodeArray {arr : Array α} :
73+ encodeArray (encodeArray (encodeArray arr)) = arr := by
74+ ext
75+ · simp [encodeArray]
76+ · simp only [encodeArray, Vector.getElem_toArray, getElem_encodeVector, Vector.size_toArray,
77+ Vector.getElem_mk, Nat.reduceSubDiff]
78+ grind
79+
80+ theorem decodeCyclic_encodeCyclic {s : String} : decodeCyclic (encodeCyclic s) = s := by
81+ simp [decodeCyclic, encodeCyclic]
582
683/-!
784## Prompt
@@ -51,4 +128,4 @@ def check(candidate):
51128 assert candidate(encoded_str) == str
52129
53130```
54- -/
131+ -/
0 commit comments