Skip to content

Commit fdc8d22

Browse files
committed
complete task 073
1 parent 9ba1d3f commit fdc8d22

File tree

1 file changed

+36
-1
lines changed

1 file changed

+36
-1
lines changed

tasks/human_eval_073.rs

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,42 @@ use vstd::prelude::*;
99

1010
verus! {
1111

12-
// TODO: Put your solution (the specification, implementation, and proof) to the task here
12+
spec fn zip_halves<T>(v: Seq<T>) -> (ret: Seq<(T, T)>)
13+
{
14+
v.take((v.len() / 2) as int).zip_with(v.skip(((v.len() + 1) / 2) as int).reverse())
15+
}
16+
17+
spec fn diff(s: Seq<(i32, i32)>) -> int {
18+
s.fold_left(0, |acc: int, x: (i32, i32)| if (x.0 != x.1) { acc + 1 } else { acc })
19+
}
20+
21+
fn smallest_change(v: Vec<i32>) -> (change: usize)
22+
requires
23+
v@.len() < usize::MAX,
24+
ensures
25+
change == diff(zip_halves(v@)),
26+
{
27+
let mut ans: usize = 0;
28+
let ghost zipped = Seq::<(i32, i32)>::empty();
29+
for i in 0..v.len() / 2
30+
invariant
31+
ans <= i <= v@.len() / 2 < usize::MAX,
32+
ans == diff(zipped),
33+
zipped =~= zip_halves(v@).take(i as int),
34+
{
35+
proof {
36+
let ghost pair = (v[i as int], v[v.len() - i - 1]);
37+
let ghost zipped_old = zipped;
38+
zipped = zipped.push(pair);
39+
assert(zipped.drop_last() =~= zipped_old);
40+
}
41+
if v[i] != v[v.len() - i - 1] {
42+
ans += 1;
43+
}
44+
}
45+
assert(zip_halves(v@).take((v@.len() / 2) as int) =~= zip_halves(v@));
46+
ans
47+
}
1348

1449
} // verus!
1550
fn main() {}

0 commit comments

Comments
 (0)