11module
2+ import Std
3+
4+ def reverse (s : String) : String :=
5+ s.revChars.fold (init := "" ) String.push
6+
7+ def shiftString (s : String) (i : Nat) : String :=
8+ let p := s.startPos.nextn (s.length - i)
9+ (s.sliceFrom p).copy ++ s.sliceTo p
10+
11+ def circularShift (x shift : Nat) : String :=
12+ let str := x.repr
13+ if shift > str.length then
14+ reverse str
15+ else
16+ shiftString str shift
17+
18+ example : circularShift 12 1 = "21" := by native_decide
19+ example : circularShift 12 2 = "12" := by native_decide
20+ example : circularShift 100 2 = "001" := by native_decide
21+ example : circularShift 97 8 = "79" := by native_decide
22+
23+ @[simp]
24+ theorem toList_reverse {s : String} : (reverse s).toList = s.toList.reverse := by
25+ simp only [reverse, ne_eq, ← Std.Iter.foldl_toList, String.toList_revChars, List.foldl_reverse]
26+ suffices ∀ (t : String), (s.toList.foldr (fun c s => s.push c) t).toList = t.toList ++ s.toList.reverse by
27+ simpa using this ""
28+ intro t
29+ induction s.toList generalizing t with simp_all
30+
31+ theorem String.splits_nextn_startPos (s : String) (n : Nat) :
32+ (s.startPos.nextn n).Splits (String.ofList (s.toList.take n)) (String.ofList (s.toList.drop n)) :=
33+ sorry -- https://github.com/leanprover/lean4/pull/13106
34+
35+ @[simp]
36+ theorem toList_shiftString {s : String} {i : Nat} :
37+ (shiftString s i).toList = s.toList.drop (s.length - i) ++ s.toList.take (s.length - i) := by
38+ have := s.splits_nextn_startPos (s.length - i)
39+ simp [shiftString, this.copy_sliceFrom_eq, this.copy_sliceTo_eq]
40+
41+ theorem toList_circularShift {x shift : Nat} : (circularShift x shift).toList =
42+ if shift > x.repr.length then
43+ x.repr.toList.reverse
44+ else
45+ x.repr.toList.drop (x.repr.length - shift) ++ x.repr.toList.take (x.repr.length - shift) := by
46+ simp [circularShift, apply_ite String.toList]
247
3- def circular_shift : Unit :=
4- ()
548
649/-!
750## Prompt
@@ -44,4 +87,4 @@ def check(candidate):
4487 assert candidate(11, 101) == "11", "This prints if this assert fails 2 (also good for debugging!)"
4588
4689```
47- -/
90+ -/
0 commit comments