1- def make_a_pile : Unit :=
2- ()
1+ module
2+
3+ import Std.Data.Iterators
4+
5+ /-!
6+ ## Implementation
7+ -/
8+
9+ @ [grind =]
10+ def makeAPile₁ (n : Nat) : List Nat :=
11+ (*...n).iter.map (n + 2 * ·) |>.toList
12+
13+ /-- An implementation that does not build up an intermediate array. -/
14+ @ [grind =]
15+ def makeAPile₂ (n : Nat) : List Nat :=
16+ (*...n).iter.map (fun i => n + 2 * (n - 1 - i)) |>.toListRev
17+
18+ /-!
19+ ## Tests
20+ -/
21+
22+ example : makeAPile₁ 0 = [] := by native_decide
23+ example : makeAPile₁ 1 = [1 ] := by native_decide
24+ example : makeAPile₁ 2 = [2 , 4 ] := by native_decide
25+ example : makeAPile₁ 3 = [3 , 5 , 7 ] := by native_decide
26+ example : makeAPile₁ 4 = [4 , 6 , 8 , 10 ] := by native_decide
27+ example : makeAPile₁ 5 = [5 , 7 , 9 , 11 , 13 ] := by native_decide
28+ example : makeAPile₁ 6 = [6 , 8 , 10 , 12 , 14 , 16 ] := by native_decide
29+ example : makeAPile₁ 8 = [8 , 10 , 12 , 14 , 16 , 18 , 20 , 22 ] := by native_decide
30+
31+ example : makeAPile₂ 0 = [] := by native_decide
32+ example : makeAPile₂ 1 = [1 ] := by native_decide
33+ example : makeAPile₂ 2 = [2 , 4 ] := by native_decide
34+ example : makeAPile₂ 3 = [3 , 5 , 7 ] := by native_decide
35+ example : makeAPile₂ 4 = [4 , 6 , 8 , 10 ] := by native_decide
36+ example : makeAPile₂ 5 = [5 , 7 , 9 , 11 , 13 ] := by native_decide
37+ example : makeAPile₂ 6 = [6 , 8 , 10 , 12 , 14 , 16 ] := by native_decide
38+ example : makeAPile₂ 8 = [8 , 10 , 12 , 14 , 16 , 18 , 20 , 22 ] := by native_decide
39+
40+ /-!
41+ ## Verification
42+ -/
43+
44+ @ [simp, grind =]
45+ theorem length_makeAPile₁ {n : Nat} :
46+ (makeAPile₁ n).length = n := by
47+ simp [makeAPile₁]
48+
49+ @ [grind =]
50+ theorem geetElem_makeAPile₁ {n i : Nat} (h : i < n) :
51+ (makeAPile₁ n)[i]'(by grind) = n + 2 * i := by
52+ simp [makeAPile₁]
53+
54+ theorem getElem_zero_makeAPile₁ {n : Nat} (h : 0 < n) :
55+ (makeAPile₁ n)[0 ]'(by grind) = n := by
56+ grind
57+
58+ theorem getElem_makeAPile₁_mod_two {n i : Nat} (h : i < n) :
59+ (makeAPile₁ n)[i]'(by grind) % 2 = n % 2 := by
60+ grind
61+
62+ theorem getElem_succ_makeAPile₁ {n i : Nat} (h : i + 1 < n) :
63+ (makeAPile₁ n)[i + 1 ]'(by grind) = (makeAPile₁ n)[i]'(by grind) + 2 := by
64+ grind
65+
66+ @ [simp, grind =]
67+ theorem length_makeAPile₂ {n : Nat} :
68+ (makeAPile₂ n).length = n := by
69+ simp [makeAPile₂]
70+
71+ @ [grind =]
72+ theorem geetElem_makeAPile₂ {n i : Nat} (h : i < n) :
73+ (makeAPile₂ n)[i]'(by grind) = n + 2 * i := by
74+ grind [makeAPile₂, Std.Iter.toListRev_eq, Std.Iter.toList_map, Std.Rio.toList_iter,
75+ Nat.getElem_toList_rio, Nat.length_toList_rio]
76+
77+ theorem getElem_zero_makeAPile₂ {n : Nat} (h : 0 < n) :
78+ (makeAPile₂ n)[0 ]'(by grind) = n := by
79+ grind
80+
81+ theorem getElem_makeAPile₂_mod_two {n i : Nat} (h : i < n) :
82+ (makeAPile₂ n)[i]'(by grind) % 2 = n % 2 := by
83+ grind
84+
85+ theorem getElem_succ_makeAPile₂ {n i : Nat} (h : i + 1 < n) :
86+ (makeAPile₂ n)[i + 1 ]'(by grind) = (makeAPile₂ n)[i]'(by grind) + 2 := by
87+ grind
388
489/-!
590## Prompt
@@ -44,4 +129,4 @@ def check(candidate):
44129 assert True, "This prints if this assert fails 2 (also good for debugging!)"
45130
46131```
47- -/
132+ -/
0 commit comments