Skip to content

Commit cc8d9c7

Browse files
authored
Add solution to HumanEval102 (#166)
1 parent 3f1553c commit cc8d9c7

File tree

1 file changed

+68
-4
lines changed

1 file changed

+68
-4
lines changed

HumanEvalLean/HumanEval102.lean

Lines changed: 68 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,69 @@
1-
def choose_num : Unit :=
2-
()
1+
def Nat.isEven (n : Nat) : Bool :=
2+
n % 2 = 0
3+
4+
def chooseNum (lo hi : Nat) : Int :=
5+
match compare lo hi, hi.isEven with
6+
| .lt, true | .eq, true => hi
7+
| .lt, false => hi - 1
8+
| _, _ => -1
9+
10+
example : chooseNum 12 15 = 14 := rfl
11+
example : chooseNum 13 12 = -1 := rfl
12+
example : chooseNum 12 15 = 14 := rfl
13+
example : chooseNum 13 12 = -1 := rfl
14+
example : chooseNum 33 12354 = 12354 := rfl
15+
example : chooseNum 5234 5233 = -1 := rfl
16+
example : chooseNum 6 29 = 28 := rfl
17+
example : chooseNum 27 10 = -1 := rfl
18+
example : chooseNum 7 7 = -1 := rfl
19+
example : chooseNum 546 546 = 546 := rfl
20+
21+
macro "chooseNum_cases" lo:ident hi:ident : tactic => `(tactic|(
22+
cases _ : compare $lo $hi <;> cases _ : $(hi).isEven <;> simp only [chooseNum, *] at *
23+
))
24+
25+
macro "chooseNum_trivial" : tactic => `(tactic|(
26+
simp only [(· ∈ ·), Nat.isEven, Nat.compare_eq_eq, Nat.compare_eq_lt, Nat.compare_eq_gt,
27+
decide_eq_false_iff_not, decide_eq_true_eq] at *
28+
omega
29+
))
30+
31+
namespace Std.Range
32+
33+
-- A specification for `m` being the even maximum of range `r`.
34+
structure EvenMax (r : Range) (m : Nat) : Prop where
35+
mem : m ∈ r := by chooseNum_trivial
36+
even : m.isEven := by chooseNum_trivial
37+
max_even : ∀ n ∈ r, n.isEven → n ≤ m := by chooseNum_trivial
38+
39+
namespace EvenMax
40+
41+
theorem unique (h₁ : [lo:hi].EvenMax m₁) (h₂ : [lo:hi].EvenMax m₂) : m₁ = m₂ :=
42+
Nat.le_antisymm (h₂.max_even _ h₁.mem h₁.even) (h₁.max_even _ h₂.mem h₂.even)
43+
44+
theorem to_chooseNum (h : [lo:hi + 1].EvenMax m) : chooseNum lo hi = m := by
45+
have ⟨_, _, _⟩ := h
46+
chooseNum_cases lo hi <;> try chooseNum_trivial
47+
· have : [lo:hi + 1].EvenMax (hi - 1) := { }
48+
simp only [h.unique this, Nat.isEven, decide_eq_true_eq, decide_eq_false_iff_not] at *
49+
omega
50+
· rw [h.unique { : [lo:hi + 1].EvenMax hi }]
51+
52+
-- A given number `m` is the even maximum of the range `{lo, ..., hi}` iff `chooseNum` says so.
53+
theorem iff_chooseNum : [lo:hi + 1].EvenMax m ↔ chooseNum lo hi = m where
54+
mp := EvenMax.to_chooseNum
55+
mpr h := by constructor <;> chooseNum_cases lo hi <;> chooseNum_trivial
56+
57+
-- There does not exist an even maximum of the range `{lo, ..., hi}` iff `chooseNum` returns `-1`.
58+
theorem not_iff_chooseNum : ¬(∃ m, [lo:hi + 1].EvenMax m) ↔ (chooseNum lo hi = -1) where
59+
mpr h := fun ⟨_, ⟨_, _, _⟩⟩ => by chooseNum_cases lo hi <;> chooseNum_trivial
60+
mp h := by
61+
chooseNum_cases lo hi <;> exfalso
62+
· exact h ⟨hi - 1, {}⟩
63+
· exact h ⟨hi, {}⟩
64+
· exact h ⟨hi, {}⟩
65+
66+
end Std.Range.EvenMax
367

468
/-!
569
## Prompt
@@ -8,7 +72,7 @@ def choose_num : Unit :=
872
973
def choose_num(x, y):
1074
"""This function takes two positive numbers x and y and returns the
11-
biggest even integer number that is in the range [x, y] inclusive. If
75+
biggest even integer number that is in the range [x, y] inclusive. If
1276
there's no such number, then the function should return -1.
1377
1478
For example:
@@ -47,4 +111,4 @@ def check(candidate):
47111
assert candidate(546, 546) == 546
48112
49113
```
50-
-/
114+
-/

0 commit comments

Comments
 (0)