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+ @[simp]
32+ theorem toList_shiftString {s : String} {i : Nat} :
33+ (shiftString s i).toList = s.toList.drop (s.length - i) ++ s.toList.take (s.length - i) := by
34+ have := s.splits_nextn_startPos (s.length - i)
35+ simp [shiftString, this.copy_sliceFrom_eq, this.copy_sliceTo_eq]
36+
37+ theorem toList_circularShift {x shift : Nat} : (circularShift x shift).toList =
38+ if shift > x.repr.length then
39+ x.repr.toList.reverse
40+ else
41+ x.repr.toList.drop (x.repr.length - shift) ++ x.repr.toList.take (x.repr.length - shift) := by
42+ simp [circularShift, apply_ite String.toList]
243
3- def circular_shift : Unit :=
4- ()
544
645/-!
746## Prompt
@@ -44,4 +83,4 @@ def check(candidate):
4483 assert candidate(11, 101) == "11", "This prints if this assert fails 2 (also good for debugging!)"
4584
4685```
47- -/
86+ -/
0 commit comments