1- def remove_vowels : Unit :=
2- ()
1+ import Std.Data.Iterators.Combinators.FilterMap
2+
3+ def IsSubseq (s₁ : String) (s₂ : String) : Prop :=
4+ List.Sublist s₁.toList s₂.toList
5+
6+ def vowels : List Char := ['a' , 'e' , 'i' , 'o' , 'u' , 'A' , 'E' , 'I' , 'O' , 'U' ]
7+
8+ def NoVowels (s : String) : Prop :=
9+ List.all s.toList (· ∉ vowels)
10+
11+ def MaximalFor [LE α] (P : ι → Prop ) (f : ι → α) (x : ι) : Prop :=
12+ -- Same as MaximalFor in Mathlib
13+ P x ∧ ∀ y : ι, P y → f x ≤ f y → f y ≤ f x
14+
15+ def RemoveVowelsIff (solution : String → String) : Prop :=
16+ (s x : String) → (solution s = x) → MaximalFor (fun i => NoVowels i ∧ IsSubseq i s) (String.length) x
17+
18+ def removeVowels (s : String) : String :=
19+ String.mk (s.toList.filter (· ∉ vowels))
20+
21+ example : removeVowels "abcdef" = "bcdf" := by native_decide
22+ example : removeVowels "abcdef\n ghijklm" = "bcdf\n ghjklm" := by native_decide
23+ example : removeVowels "aaaaa" = "" := by native_decide
24+ example : removeVowels "aaBAA" = "B" := by native_decide
25+ example : removeVowels "zbcd" = "zbcd" := by native_decide
26+
27+ theorem IsSubseq.length_le {s t : String} (hst : IsSubseq s t) :
28+ s.length ≤ t.length :=
29+ List.Sublist.length_le hst
30+
31+ theorem IsSubseq.removeVowels {s t : String} (hst : IsSubseq s t) :
32+ IsSubseq (removeVowels s) (removeVowels t) :=
33+ hst.filter _
34+
35+ theorem removeVowels_eq_self {s : String} :
36+ removeVowels s = s ↔ NoVowels s := by
37+ simp [String.ext_iff, NoVowels, removeVowels]
38+
39+ theorem removeVowels_correct : RemoveVowelsIff removeVowels := by
40+ simp [RemoveVowelsIff]
41+ intro s
42+ constructor
43+ · simp [NoVowels, removeVowels, IsSubseq]
44+ · simp only [and_imp]
45+ intro y hnv hss hle
46+ rw [← removeVowels_eq_self.2 hnv]
47+ exact IsSubseq.length_le (IsSubseq.removeVowels hss)
348
449/-!
550## Prompt
@@ -49,4 +94,4 @@ def check(candidate):
4994 assert candidate('ybcd') == 'ybcd'
5095
5196```
52- -/
97+ -/
0 commit comments