Skip to content

Commit 421bb6e

Browse files
authored
77 (#283)
This PR solves problem 77.
1 parent 6033497 commit 421bb6e

File tree

1 file changed

+140
-4
lines changed

1 file changed

+140
-4
lines changed

HumanEvalLean/HumanEval77.lean

Lines changed: 140 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,143 @@
11
module
22

3-
def iscube : Unit :=
4-
()
3+
public section
4+
5+
open Std
6+
7+
/-! ## Implementation -/
8+
9+
def isCubeOfRange (x : Int) (lower : Int) (upper : Int) : Bool :=
10+
if upper ≤ lower + 1 then
11+
lower ^ 3 = x
12+
else
13+
let mid := (lower + upper) / 2
14+
isCubeOfRange x lower mid || isCubeOfRange x mid upper
15+
termination_by (upper - lower).toNat
16+
17+
def isCube (x : Int) : Bool :=
18+
isCubeOfRange x (- Int.natAbs x) (Int.natAbs x + 1)
19+
20+
/-! ## Tests -/
21+
22+
example : isCube 1 = true := by native_decide
23+
example : isCube 2 = false := by native_decide
24+
example : isCube (-1) = true := by native_decide
25+
example : isCube 64 = true := by native_decide
26+
example : isCube 180 = false := by native_decide
27+
example : isCube 1000 = true := by native_decide
28+
example : isCube 0 = true := by native_decide
29+
example : isCube 1729 = false := by native_decide
30+
31+
/-! ## Missing API -/
32+
33+
theorem Int.natAbs_le_iff {x y : Int} :
34+
x.natAbs ≤ y ↔ x ≤ y ∧ -x ≤ y := by
35+
grind
36+
37+
theorem Int.le_pow {x : Int} (h : 0 ≤ x) (hn : 0 < n) :
38+
x ≤ x ^ n := by
39+
have : x.toNat ≤ x.toNat ^ n := Nat.le_pow (by grind)
40+
grind
41+
42+
protected theorem Int.mul_le_mul_iff_of_pos_left {a b c : Int} (ha : 0 < a) : a * b ≤ a * c ↔ b ≤ c :=
43+
⟨(le_of_mul_le_mul_left · ha), (Int.mul_le_mul_of_nonneg_left · (Int.le_of_lt ha))⟩
44+
45+
protected theorem Int.mul_nonneg_iff_of_pos_left {a b : Int} (ha : 0 < a) : 0 ≤ a * b ↔ 0 ≤ b := by
46+
simpa using (Int.mul_le_mul_iff_of_pos_left ha : a * 0 ≤ a * b ↔ 0 ≤ b)
47+
48+
protected theorem Int.mul_nonneg_iff {a b : Int} :
49+
0 ≤ a * b ↔ 0 ≤ a ∧ 0 ≤ b ∨ a ≤ 0 ∧ b ≤ 0 := by
50+
constructor
51+
· intro h
52+
cases hcmp : compare 0 a
53+
· rw [Int.mul_nonneg_iff_of_pos_left (by grind)] at h
54+
grind
55+
· grind
56+
· let a' := -a
57+
let b' := -b
58+
replace h : 0 ≤ a' * b' := by grind
59+
have : 0 < a' := by grind
60+
rw [Int.mul_nonneg_iff_of_pos_left (by grind)] at h
61+
grind
62+
· rintro (h | h)
63+
· exact Int.mul_nonneg (by grind) (by grind)
64+
· exact Int.mul_nonneg_of_nonpos_of_nonpos (by grind) (by grind)
65+
66+
protected theorem Int.mul_pos_iff {a b : Int} :
67+
0 < a * b ↔ 0 < a ∧ 0 < b ∨ a < 0 ∧ b < 0 := by
68+
let a' := -a
69+
suffices ¬ 0 ≤ a' * b ↔ a' < 00 < b ∨ 0 < a' ∧ b < 0 by grind
70+
rw [Int.mul_nonneg_iff]
71+
grind
72+
73+
protected theorem Int.mul_neg_iff_of_neg_right {a b : Int} (hb : b < 0) : a * b < 00 < a := by
74+
suffices ¬ 0 ≤ a * b ↔ 0 < a by grind
75+
rw [Int.mul_nonneg_iff]
76+
grind
77+
78+
protected theorem Int.mul_self_nonneg {a : Int} :
79+
0 ≤ a * a := by
80+
rw [Int.mul_nonneg_iff]
81+
grind
82+
83+
protected theorem Int.mul_self_pos {a : Int} (h : a ≠ 0) :
84+
0 < a * a := by
85+
rw [Int.mul_pos_iff]
86+
grind
87+
88+
/-! ## Verification -/
89+
90+
private theorem isCubeOfRange_iff (h : lower < upper) :
91+
isCubeOfRange x lower upper ↔ ∃ y ∈ lower...upper, y ^ 3 = x := by
92+
fun_induction isCubeOfRange x lower upper <;> grind [Rco.mem_iff]
93+
94+
private theorem Int.pow_three_lt_pow_three {x y : Int} (h : x < y) :
95+
x ^ 3 < y ^ 3 := by
96+
simp only [show ∀ x : Int, x ^ 3 = x * x * x by grind]
97+
by_cases 0 ≤ x
98+
· apply Int.mul_lt_mul'
99+
· apply Int.mul_self_le_mul_self (by grind) (by grind)
100+
· grind
101+
· grind
102+
· have : 0 < y := by grind
103+
apply Int.mul_pos (by grind) (by grind)
104+
· by_cases 0 ≤ y
105+
· have : x * x * x < 0 := by
106+
rw [Int.mul_neg_iff_of_neg_right]
107+
· apply Int.mul_self_pos (by grind)
108+
· grind
109+
have : 0 ≤ y * y * y := by
110+
apply Int.mul_nonneg
111+
· apply Int.mul_self_nonneg
112+
· assumption
113+
grind
114+
· let x' := -x
115+
let y' := -y
116+
suffices y' * y' * y' < x' * x' * x' by grind
117+
apply Int.mul_lt_mul'
118+
· apply Int.mul_self_le_mul_self (by grind) (by grind)
119+
· grind
120+
· grind
121+
· have : 0 < x' := by grind
122+
apply Int.mul_pos (by grind) (by grind)
123+
124+
private theorem Int.pow_three_le_pow_three_iff {x y : Int} :
125+
x ^ 3 ≤ y ^ 3 ↔ x ≤ y := by
126+
have := Int.pow_three_lt_pow_three (x := x) (y := y)
127+
have := Int.pow_three_lt_pow_three (x := y) (y := x)
128+
cases hcmp : compare x y <;> grind
129+
130+
theorem isCube_iff :
131+
isCube x ↔ ∃ y, y ^ 3 = x := by
132+
rw [isCube, isCubeOfRange_iff]
133+
· constructor
134+
· grind
135+
· rintro ⟨y, hy⟩
136+
refine ⟨y, ?_, hy⟩
137+
simp only [Rco.mem_iff, ← hy, Int.natAbs_pow, Int.natCast_pow, Int.lt_add_one_iff,
138+
Int.neg_le_iff, and_comm, ← Int.natAbs_le_iff]
139+
exact Int.le_pow (by grind) (by grind)
140+
· grind
5141

6142
/-!
7143
## Prompt
@@ -10,7 +146,7 @@ def iscube : Unit :=
10146
11147
def iscube(a):
12148
'''
13-
Write a function that takes an integer a and returns True
149+
Write a function that takes an integer a and returns True
14150
if this ingeger is a cube of some integer number.
15151
Note: you may assume the input is always valid.
16152
Examples:
@@ -49,4 +185,4 @@ def check(candidate):
49185
assert candidate(1729) == False, "2nd edge test error: " + str(candidate(1728))
50186
51187
```
52-
-/
188+
-/

0 commit comments

Comments
 (0)