forked from leanprover/human-eval-lean
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathHumanEval119.lean
More file actions
151 lines (131 loc) · 5.6 KB
/
HumanEval119.lean
File metadata and controls
151 lines (131 loc) · 5.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
module
import HumanEvalLean.Common.Brackets
import Std.Tactic.Do
def computeBalance (s : String.Slice) : Int × Int := Id.run do
let mut balance := 0
let mut minBalance := 0
for c in s do
if c == '(' then
balance := balance + 1
minBalance := min minBalance balance
else if c == ')' then
balance := balance - 1
minBalance := min minBalance balance
return (balance, minBalance)
def matchParens (s₁ s₂ : String.Slice) : Bool :=
let (bal₁, minBal₁) := computeBalance s₁
let (bal₂, minBal₂) := computeBalance s₂
bal₁ + bal₂ == 0 && ((minBal₁ == 0 && bal₁ + minBal₂ == 0) || (minBal₂ == 0 && bal₂ + minBal₁ == 0))
example : matchParens "()(" ")" = true := by native_decide
example : matchParens ")" ")" = false := by native_decide
example : matchParens "(()(())" "())())" = false := by native_decide
example : matchParens ")())" "(()()(" = true := by native_decide
example : matchParens "(())))" "(()())((" = true := by native_decide
example : matchParens "()" "())" = false := by native_decide
example : matchParens "(()(" "()))()" = true := by native_decide
example : matchParens "((((" "((())" = false := by native_decide
example : matchParens ")(()" "(()(" = false := by native_decide
example : matchParens ")(" ")(" = false := by native_decide
example : matchParens "(" ")" = true := by native_decide
example : matchParens ")" "(" = true := by native_decide
open Std.Do
set_option mvcgen.warning false
theorem computeBalance_eq {s : String.Slice} :
computeBalance s = (balance (parens '(' ')' s.copy), minBalance (parens '(' ')' s.copy)) := by
generalize hwp : computeBalance s = w
apply Std.Do.Id.of_wp_run_eq hwp
mvcgen
case inv1 => exact (⇓(pos, ⟨bal, minBal⟩) => ⌜∀ (t₁ t₂ : String), pos.Splits t₁ t₂ →
bal = balance (parens '(' ')' t₁) ∧ minBal = minBalance (parens '(' ')' t₁)⌝)
next pos _ hp bal minBal h newBal newMinBal ih =>
simp only [↓Char.isValue, SPred.down_pure] at ⊢ ih
intro t₁ t₂ hsp
obtain ⟨t₁, rfl⟩ := hsp.exists_eq_append_singleton
simp only [↓Char.isValue, beq_iff_eq] at h
simp only [↓Char.isValue, h, String.append_singleton, parens_push, ↓reduceIte,
Option.toList_some, balance_append, balance_cons, Paren.toInt_open, balance_nil, Int.add_zero,
minBalance_append_singleton]
have := ih _ _ hsp.of_next
grind
next pos _ hp bal minBal h₁ h₂ newBal newMinBal ih =>
simp only [↓Char.isValue, SPred.down_pure] at ⊢ ih
intro t₁ t₂ hsp
obtain ⟨t₁, rfl⟩ := hsp.exists_eq_append_singleton
simp only [↓Char.isValue, beq_iff_eq] at h₂
simp only [↓Char.isValue, h₂, String.append_singleton, parens_push, Char.reduceEq, ↓reduceIte,
Option.toList_some, balance_append, balance_cons, Paren.toInt_close, Int.reduceNeg,
balance_nil, Int.add_zero, minBalance_append_singleton]
have := ih _ _ hsp.of_next
grind
next pos _ hp bal minBal h₁ h₂ ih =>
simp only [↓Char.isValue, SPred.down_pure] at ⊢ ih
intro t₁ t₂ hsp
obtain ⟨t₁, rfl⟩ := hsp.exists_eq_append_singleton
simp only [↓Char.isValue, beq_iff_eq] at h₁ h₂
simp only [↓Char.isValue, String.append_singleton, parens_push, h₁, ↓reduceIte, h₂,
Option.toList_none, List.append_nil]
have := ih _ _ hsp.of_next
grind
next => simp
next => simp_all
theorem matchParens_eq_true_iff {s₁ s₂ : String.Slice} :
matchParens s₁ s₂ = true ↔ IsBalanced (parens '(' ')' (s₁.copy ++ s₂.copy)) ∨ IsBalanced (parens '(' ')' (s₂.copy ++ s₁.copy)) := by
simp [matchParens, computeBalance_eq, isBalanced_iff, minBalance_append]
have := minBalance_nonpos (parens '(' ')' s₁.copy)
have := minBalance_nonpos (parens '(' ')' s₂.copy)
have := minBalance_le_balance (parens '(' ')' s₁.copy)
have := minBalance_le_balance (parens '(' ')' s₂.copy)
grind
/-!
## Prompt
```python3
def match_parens(lst):
'''
You are given a list of two strings, both strings consist of open
parentheses '(' or close parentheses ')' only.
Your job is to check if it is possible to concatenate the two strings in
some order, that the resulting string will be good.
A string S is considered to be good if and only if all parentheses in S
are balanced. For example: the string '(())()' is good, while the string
'())' is not.
Return 'Yes' if there's a way to make a good string, and return 'No' otherwise.
Examples:
match_parens(['()(', ')']) == 'Yes'
match_parens([')', ')']) == 'No'
'''
```
## Canonical solution
```python3
def check(s):
val = 0
for i in s:
if i == '(':
val = val + 1
else:
val = val - 1
if val < 0:
return False
return True if val == 0 else False
S1 = lst[0] + lst[1]
S2 = lst[1] + lst[0]
return 'Yes' if check(S1) or check(S2) else 'No'
```
## Tests
```python3
def check(candidate):
# Check some simple cases
assert candidate(['()(', ')']) == 'Yes'
assert candidate([')', ')']) == 'No'
assert candidate(['(()(())', '())())']) == 'No'
assert candidate([')())', '(()()(']) == 'Yes'
assert candidate(['(())))', '(()())((']) == 'Yes'
assert candidate(['()', '())']) == 'No'
assert candidate(['(()(', '()))()']) == 'Yes'
assert candidate(['((((', '((())']) == 'No'
assert candidate([')(()', '(()(']) == 'No'
assert candidate([')(', ')(']) == 'No'
# Check some edge cases that are easy to work out by hand.
assert candidate(['(', ')']) == 'Yes'
assert candidate([')', '(']) == 'Yes'
```
-/