diff --git a/tasks/human_eval_007.rs b/tasks/human_eval_007.rs
index b8ba40c..3922afa 100644
--- a/tasks/human_eval_007.rs
+++ b/tasks/human_eval_007.rs
@@ -9,7 +9,87 @@ use vstd::prelude::*;
 
 verus! {
 
-// TODO: Put your solution (the specification, implementation, and proof) to the task here
+fn string_eq(s1: &str, s2: &str) -> (result: bool)
+    ensures
+        result <==> s1@ == s2@,
+{
+    let s1_len = s1.unicode_len();
+    let s2_len = s2.unicode_len();
+    if s1_len != s2_len {
+        return false;
+    }
+    for i in 0..s1_len
+        invariant
+            s1@.subrange(0, i as int) =~= s2@.subrange(0, i as int),
+            i <= s1_len == s2_len == s1@.len() == s2@.len(),
+    {
+        let c = s1.get_char(i);
+        if c != s2.get_char(i) {
+            return false;
+        }
+        assert(s1@.subrange(0, i + 1) == s1@.subrange(0, i as int).push(c));
+        assert(s1@.subrange(0, i as int).push(c) == s2@.subrange(0, i as int).push(c));
+        assert(s2@.subrange(0, i as int).push(c) == s2@.subrange(0, i + 1));
+    }
+    assert(s1@ == s1@.subrange(0, s1_len as int));
+    assert(s2@ == s2@.subrange(0, s2_len as int));
+    true
+}
+
+spec fn is_subseq_of(s: Seq, sub: Seq) -> bool {
+    exists|i: int| 0 <= i <= s.len() - sub.len() && s.subrange(i, #[trigger] (i + sub.len())) == sub
+}
+
+fn check_substring(s: &str, sub: &str) -> (result: bool)
+    ensures
+        result <==> is_subseq_of(s@, sub@),
+{
+    let s_len = s.unicode_len();
+    let sub_len = sub.unicode_len();
+    if (s_len < sub_len) {
+        return false;
+    }
+    if sub_len == 0 {
+        assert(s@.subrange(0, (0 + sub@.len()) as int) == sub@);
+        return true;
+    }
+    for i in 0..s_len - sub_len + 1
+        invariant
+            forall|j: int| 0 <= j < i ==> s@.subrange(j, #[trigger] (j + sub@.len())) != sub@,
+            i <= s_len - sub_len + 1,
+            sub_len == sub@.len() <= s_len == s@.len(),
+            sub_len > 0,
+    {
+        if string_eq(sub, s.substring_char(i, i + sub_len)) {
+            assert(0 <= i <= s@.len() - sub@.len());
+            assert(s@.subrange(i as int, i + sub@.len()) == sub@);
+            return true;
+        }
+    }
+    false
+}
+
+fn filter_by_sub<'a>(strings: &Vec<&'a str>, sub: &str) -> (res: Vec<&'a str>)
+    ensures
+        strings@.filter(|s: &str| is_subseq_of(s@, sub@)) == res@,
+{
+    let mut res = Vec::new();
+    assert(res@ == Seq::<&str>::empty());
+    let mut n = 0;
+    for n in 0..strings.len()
+        invariant
+            strings@.subrange(0, n as int).filter(|s: &str| is_subseq_of(s@, sub@)) == res@,
+            n <= strings.len(),
+    {
+        reveal(Seq::filter);
+        assert(strings@.subrange(0, n as int + 1).drop_last() == strings@.subrange(0, n as int));
+        if check_substring(strings[n], sub) {
+            res.push(strings[n]);
+        }
+    }
+    assert(strings@.subrange(0, strings@.len() as int) == strings@);
+    res
+}
 
 } // verus!
 fn main() {}
diff --git a/tasks/human_eval_012.rs b/tasks/human_eval_012.rs
index 4a6722d..57ee646 100644
--- a/tasks/human_eval_012.rs
+++ b/tasks/human_eval_012.rs
@@ -9,7 +9,41 @@ use vstd::prelude::*;
 
 verus! {
 
-// TODO: Put your solution (the specification, implementation, and proof) to the task here
+fn longest(strings: &Vec>) -> (result: Option<&Vec>)
+    ensures
+        match result {
+            None => strings.len() == 0,
+            Some(s) => {
+                (forall|i: int| #![auto] 0 <= i < strings.len() ==> s.len() >= strings[i].len())
+                    && (exists|i: int|
+                    #![auto]
+                    (0 <= i < strings.len() && s == strings[i] && (forall|j: int|
+                        #![auto]
+                        0 <= j < i ==> strings[j].len() < s.len())))
+            },
+        },
+{
+    if strings.len() == 0 {
+        return None;
+    }
+    let mut result: &Vec = &strings[0];
+    let mut pos = 0;
+
+    for i in 1..strings.len()
+        invariant
+            0 <= pos < i,
+            result == &strings[pos as int],
+            exists|i: int| 0 <= i < strings.len() && strings[i] == result,
+            forall|j: int| #![auto] 0 <= j < i ==> strings[j].len() <= result.len(),
+            forall|j: int| #![auto] 0 <= j < pos ==> strings[j].len() < result.len(),
+    {
+        if result.len() < strings[i].len() {
+            result = &strings[i];
+            pos = i;
+        }
+    }
+    Some(result)
+}
 
 } // verus!
 fn main() {}
diff --git a/tasks/human_eval_014.rs b/tasks/human_eval_014.rs
index 9d5d1e5..ae23a14 100644
--- a/tasks/human_eval_014.rs
+++ b/tasks/human_eval_014.rs
@@ -9,7 +9,53 @@ use vstd::prelude::*;
 
 verus! {
 
-// TODO: Put your solution (the specification, implementation, and proof) to the task here
+fn all_prefixes(s: &Vec) -> (prefixes: Vec>)
+    ensures
+        prefixes.len() == s.len(),
+        forall|i: int| #![auto] 0 <= i < s.len() ==> prefixes[i]@ == s@.subrange(0, i + 1),
+{
+    let mut prefixes: Vec> = vec![];
+    let mut prefix = vec![];
+    assert(forall|i: int|
+        #![auto]
+        0 <= i < prefix.len() ==> prefix@.index(i) == prefix@.subrange(
+            0,
+            prefix.len() as int,
+        ).index(i));
+
+    assert(prefix@ == prefix@.subrange(0, 0));
+    assert(forall|i: int|
+        #![auto]
+        0 <= i < prefix.len() ==> prefix@.index(i) == s@.subrange(0, prefix.len() as int).index(i));
+    assert(prefix@ == s@.subrange(0, 0));
+    for i in 0..s.len()
+        invariant
+            prefixes.len() == i,
+            prefix.len() == i,
+            forall|j: int| #![auto] 0 <= j < i ==> prefixes[j]@ == s@.subrange(0, j + 1),
+            prefix@ == s@.subrange(0, i as int),
+            prefix@ == prefix@.subrange(0, i as int),
+    {
+        let ghost pre_prefix = prefix;
+        prefix.push(s[i]);
+        assert(pre_prefix@.subrange(0, i as int) == pre_prefix@ && prefix@.subrange(0, i as int)
+            == pre_prefix@.subrange(0, i as int));
+        assert(prefix@.subrange(0, i as int) == s@.subrange(0, i as int));
+        assert(prefix[i as int] == s@.subrange(0, i + 1).index(i as int));
+
+        assert(forall|j: int|
+            #![auto]
+            0 <= j < i + 1 ==> prefix@.index(j) == prefix@.subrange(0, (i + 1) as int).index(j));
+        assert(prefix@ == prefix@.subrange(0, (i + 1) as int));
+        assert(forall|j: int|
+            #![auto]
+            0 <= j < i + 1 ==> prefix@.index(j) == s@.subrange(0, (i + 1) as int).index(j));
+        assert(prefix@ == s@.subrange(0, (i + 1) as int));
+
+        prefixes.push(prefix.clone());
+    }
+    return prefixes;
+}
 
 } // verus!
 fn main() {}
diff --git a/tasks/human_eval_034.rs b/tasks/human_eval_034.rs
index a7c6bdb..9d96386 100644
--- a/tasks/human_eval_034.rs
+++ b/tasks/human_eval_034.rs
@@ -5,11 +5,190 @@ HumanEval/34
 /*
 ### VERUS BEGIN
 */
+use vstd::calc;
 use vstd::prelude::*;
+use vstd::seq_lib::lemma_multiset_commutative;
+use vstd::seq_lib::lemma_seq_contains_after_push;
 
 verus! {
 
-// TODO: Put your solution (the specification, implementation, and proof) to the task here
+proof fn swap_preserves_multiset_helper(s: Seq, i: int, j: int)
+    requires
+        0 <= i < j < s.len(),
+    ensures
+        (s.take(j + 1)).to_multiset() =~= s.take(i).to_multiset().add(
+            s.subrange(i + 1, j).to_multiset(),
+        ).insert(s.index(j)).insert(s.index(i)),
+{
+    let fst = s.take(i);
+    let snd = s.subrange(i + 1, j);
+
+    assert((s.take(j + 1)).to_multiset() =~= fst.to_multiset().insert(s.index(i)).add(
+        snd.to_multiset().insert(s.index(j)),
+    )) by {
+        assert(s.take(i + 1).to_multiset() =~= fst.to_multiset().insert(s.index(i))) by {
+            fst.to_multiset_ensures();
+            assert(fst.push(s.index(i)) =~= s.take(i + 1));
+        }
+        assert(s.subrange(i + 1, j + 1).to_multiset() =~= snd.to_multiset().insert(s.index(j))) by {
+            snd.to_multiset_ensures();
+            assert(snd.push(s.index(j)) =~= s.subrange(i + 1, j + 1));
+        }
+        lemma_multiset_commutative(s.take(i + 1), s.subrange(i + 1, j + 1));
+        assert(s.take(i + 1) + s.subrange(i + 1, j + 1) =~= s.take(j + 1));
+    }
+}
+
+// Helper lemma to prove that swapping two elements doesn't change the multiset
+proof fn swap_preserves_multiset(s1: Seq, s2: Seq, i: int, j: int)
+    requires
+        0 <= i < j < s1.len() == s2.len(),
+        forall|x: int| 0 <= x < s1.len() && x != i && x != j ==> s1.index(x) == s2.index(x),
+        s1.index(i) == s2.index(j),
+        s1.index(j) == s2.index(i),
+    ensures
+        s1.to_multiset() == s2.to_multiset(),
+{
+    calc! {
+        (==)
+        s1.to_multiset(); {
+            lemma_multiset_commutative(s1.take(j + 1), s1.skip(j + 1));
+            assert(s1 =~= s1.take(j + 1) + s1.skip(j + 1));
+        }
+        s1.take(j + 1).to_multiset().add(s1.skip(j + 1).to_multiset()); {
+            assert(s1.take(j + 1).to_multiset() =~= s2.take(j + 1).to_multiset()) by {
+                assert(s1.take(i) == s2.take(i));
+                assert(s1.subrange(i + 1, j) =~= (s2.subrange(i + 1, j)));
+                swap_preserves_multiset_helper(s1, i, j);
+                swap_preserves_multiset_helper(s2, i, j);
+            }
+            assert(s1.skip(j + 1).to_multiset() =~= s2.skip(j + 1).to_multiset()) by {
+                assert(s1.skip(j + 1) =~= s2.skip(j + 1));
+            }
+        }
+        s2.take(j + 1).to_multiset().add(s2.skip(j + 1).to_multiset()); {
+            lemma_multiset_commutative(s2.take(j + 1), s2.skip(j + 1));
+            assert(s2 =~= s2.take(j + 1) + s2.skip(j + 1));
+        }
+        s2.to_multiset();
+    }
+}
+
+fn sort_seq(s: &Vec) -> (ret: Vec)
+    ensures
+        forall|i: int, j: int| 0 <= i < j < ret@.len() ==> ret@.index(i) <= ret@.index(j),
+        ret@.len() == s@.len(),
+        s@.to_multiset() == ret@.to_multiset(),
+{
+    let mut sorted = s.clone();
+    let mut i: usize = 0;
+    while i < sorted.len()
+        invariant
+            i <= sorted.len(),
+            forall|j: int, k: int| 0 <= j < k < i ==> sorted@.index(j) <= sorted@.index(k),
+            s@.to_multiset() == sorted@.to_multiset(),
+            forall|j: int, k: int|
+                0 <= j < i <= k < sorted@.len() ==> sorted@.index(j) <= sorted@.index(k),
+            sorted@.len() == s@.len(),
+        decreases (sorted.len() - i),
+    {
+        let mut min_index: usize = i;
+        let mut j: usize = i + 1;
+        while j < sorted.len()
+            invariant
+                i <= min_index < j <= sorted.len(),
+                forall|k: int| i <= k < j ==> sorted@.index(min_index as int) <= sorted@.index(k),
+            decreases (sorted.len() - j),
+        {
+            if sorted[j] < sorted[min_index] {
+                min_index = j;
+            }
+            j += 1;
+        }
+        if min_index != i {
+            let ghost old_sorted = sorted@;
+            let curr_val = sorted[i];
+            let min_val = sorted[min_index];
+            sorted.set(i, min_val);
+
+            sorted.set(min_index, curr_val);
+
+            proof {
+                swap_preserves_multiset(old_sorted, sorted@, i as int, min_index as int);
+                assert(old_sorted.to_multiset() =~= sorted@.to_multiset());
+            }
+        }
+        i += 1;
+    }
+    sorted
+}
+
+fn unique_sorted(s: Vec) -> (result: Vec)
+    requires
+        forall|i: int, j: int| 0 <= i < j < s.len() ==> s[i] <= s[j],
+    ensures
+        forall|i: int, j: int| 0 <= i < j < result.len() ==> result[i] < result[j],
+        forall|i: int| #![auto] 0 <= i < result.len() ==> s@.contains(result[i]),
+        forall|i: int| #![trigger s[i]] 0 <= i < s.len() ==> result@.contains(s[i]),
+{
+    let mut result: Vec = vec![];
+    for i in 0..s.len()
+        invariant
+            forall|i: int, j: int| 0 <= i < j < s.len() ==> s[i] <= s[j],
+            forall|k: int, l: int| 0 <= k < l < result.len() ==> result[k] < result[l],
+            forall|k: int|
+                #![trigger result[k]]
+                0 <= k < result.len() ==> (exists|m: int| 0 <= m < i && result[k] == s[m]),
+            forall|m: int| #![trigger s[m]] 0 <= m < i ==> result@.contains(s[m]),
+    {
+        let ghost pre = result;
+        if result.len() == 0 || result[result.len() - 1] != s[i] {
+            assert(result.len() == 0 || result[result.len() - 1] < s[i as int]);
+            result.push(s[i]);
+            assert forall|m: int| #![trigger s[m]] 0 <= m < i implies result@.contains(s[m]) by {
+                assert(pre@.contains(s@[m]));
+                lemma_seq_contains_after_push(pre@, s@[i as int], s@[m]);
+            };
+        }
+        assert(forall|m: int|
+            #![trigger result@[m], pre@[m]]
+            0 <= m < pre.len() ==> pre@.contains(result@[m]) ==> result@.contains(pre@[m])) by {
+            assert(forall|m: int| 0 <= m < pre.len() ==> result@[m] == pre@[m]);
+        }
+        assert(result@.contains(s[i as int])) by {
+            assert(result[result.len() - 1] == s[i as int]);
+        }
+    }
+    result
+}
+
+fn unique(s: Vec) -> (result: Vec)
+    ensures
+        forall|i: int, j: int| 0 <= i < j < result.len() ==> result[i] < result[j],
+        forall|i: int| #![auto] 0 <= i < result.len() ==> s@.contains(result[i]),
+        forall|i: int| #![trigger s[i]] 0 <= i < s.len() ==> result@.contains(s[i]),
+{
+    let sorted = sort_seq(&s);
+    assert(forall|i: int| #![auto] 0 <= i < sorted.len() ==> s@.contains(sorted[i])) by {
+        assert(forall|i: int|
+            #![auto]
+            0 <= i < sorted.len() ==> sorted@.to_multiset().contains(sorted[i])) by {
+            sorted@.to_multiset_ensures();
+        }
+        assert(forall|i: int|
+            #![auto]
+            0 <= i < sorted.len() ==> s@.to_multiset().contains(sorted[i]));
+        s@.to_multiset_ensures();
+    }
+    assert(forall|i: int| #![trigger s[i]] 0 <= i < s.len() ==> sorted@.contains(s[i])) by {
+        assert(forall|i: int| #![auto] 0 <= i < s.len() ==> s@.to_multiset().contains(s[i])) by {
+            s@.to_multiset_ensures();
+        }
+        assert(forall|i: int| #![auto] 0 <= i < s.len() ==> sorted@.to_multiset().contains(s[i]));
+        sorted@.to_multiset_ensures();
+    }
+    unique_sorted(sorted)
+}
 
 } // verus!
 fn main() {}
diff --git a/tasks/human_eval_035.rs b/tasks/human_eval_035.rs
index db151d6..5b4a5d9 100644
--- a/tasks/human_eval_035.rs
+++ b/tasks/human_eval_035.rs
@@ -9,7 +9,25 @@ use vstd::prelude::*;
 
 verus! {
 
-// TODO: Put your solution (the specification, implementation, and proof) to the task here
+fn max_element(a: &Vec) -> (max: i32)
+    requires
+        a.len() > 0,
+    ensures
+        forall|i: int| 0 <= i < a.len() ==> a[i] <= max,
+        exists|i: int| 0 <= i < a.len() && a[i] == max,
+{
+    let mut max = a[0];
+    for i in 1..a.len()
+        invariant
+            forall|j: int| 0 <= j < i ==> a[j] <= max,
+            exists|j: int| 0 <= j < i && a[j] == max,
+    {
+        if a[i] > max {
+            max = a[i];
+        }
+    }
+    max
+}
 
 } // verus!
 fn main() {}
diff --git a/tasks/human_eval_037.rs b/tasks/human_eval_037.rs
index 99af6b8..f438baa 100644
--- a/tasks/human_eval_037.rs
+++ b/tasks/human_eval_037.rs
@@ -9,7 +9,159 @@ use vstd::prelude::*;
 
 verus! {
 
-// TODO: Put your solution (the specification, implementation, and proof) to the task here
+// code taken from sort_third (033)
+spec fn count(s: Seq, x: T) -> int
+    decreases s.len(),
+{
+    if s.len() == 0 {
+        0
+    } else {
+        count(s.skip(1), x) + if s[0] == x {
+            1int
+        } else {
+            0int
+        }
+    }
+}
+
+// This function defines what it means for two sequences to be
+// permutations of each other: for every value `x`, each of the two
+// sequences has the same number of instances of `x`.
+spec fn permutes(s1: Seq, s2: Seq) -> bool {
+    forall|x: T| count(s1, x) == count(s2, x)
+}
+
+// This lemma establishes the effect of an `update` operation on the
+// result of a `count`. That is, it gives a closed-form
+// (non-recursive) description of what happens to `count(s, x)` when
+// `s` is updated to `s.update(i, v)`.
+proof fn lemma_update_effect_on_count(s: Seq, i: int, v: T, x: T)
+    requires
+        0 <= i < s.len(),
+    ensures
+        count(s.update(i, v), x) == if v == x && s[i] != x {
+            count(s, x) + 1
+        } else if v != x && s[i] == x {
+            count(s, x) - 1
+        } else {
+            count(s, x)
+        },
+    decreases s.len(),
+{
+    if s.len() == 0 {
+        return ;
+    }
+    if i == 0 {
+        assert(s.update(i, v) =~= seq![v] + s.skip(1));
+        assert(s.update(i, v).skip(1) =~= s.skip(1));
+    } else {
+        assert(s.update(i, v) =~= seq![s[0]] + s.skip(1).update(i - 1, v));
+        assert(s.update(i, v).skip(1) =~= s.skip(1).update(i - 1, v));
+        lemma_update_effect_on_count(s.skip(1), i - 1, v, x);
+    }
+}
+
+// This lemma proves that if you swap elements `i` and `j` of sequence `s`,
+// you get a permutation of `s`.
+proof fn lemma_swapping_produces_a_permutation(s: Seq, i: int, j: int)
+    requires
+        0 <= i < s.len(),
+        0 <= j < s.len(),
+    ensures
+        permutes(s.update(i, s[j]).update(j, s[i]), s),
+{
+    assert forall|x: T| #[trigger] count(s.update(i, s[j]).update(j, s[i]), x) == count(s, x) by {
+        lemma_update_effect_on_count(s, i, s[j], x);
+        lemma_update_effect_on_count(s.update(i, s[j]), j, s[i], x);
+    }
+}
+
+#[verifier::loop_isolation(false)]
+fn sort_pred(l: Vec, p: Vec) -> (l_prime: Vec)
+    requires
+        l.len() == p.len(),
+    ensures
+        l_prime.len() == l.len(),
+        forall|i: int| 0 <= i < l.len() && !p[i] ==> l_prime[i] == l[i],
+        forall|i: int, j: int|
+            #![auto]
+            0 <= i < j < l.len() && p[i] && p[j] ==> l_prime[i] <= l_prime[j],
+        permutes(l_prime@, l@),
+{
+    let ghost old_l = l@;
+    let l_len = l.len();
+    let mut pos_replace: usize = 0;
+    let mut l_prime: Vec = l;
+    while pos_replace < l_len
+        invariant
+            l_len == l.len() == l_prime.len(),
+            forall|i: int| 0 <= i < l_len && !p[i] ==> l_prime[i] == l[i],
+            permutes(l_prime@, l@),
+            forall|i: int, j: int|
+                #![auto]
+                0 <= i < pos_replace && i < j < l_len && p[i] && p[j] ==> l_prime[i] <= l_prime[j],
+    {
+        if p[pos_replace] {
+            let mut pos_cur: usize = pos_replace;
+            let mut pos: usize = pos_replace;
+            while pos < l_len
+                invariant
+                    l_len == l.len() == l_prime.len(),
+                    pos_replace <= pos,
+                    pos_replace <= pos_cur < l_len,
+                    p[pos_replace as int],
+                    p[pos_cur as int],
+                    forall|i: int| 0 <= i < l_len && !p[i] ==> l_prime[i] == l[i],
+                    permutes(l_prime@, l@),
+                    forall|i: int|
+                        #![auto]
+                        pos_replace <= i < pos && p[i] ==> l_prime[pos_cur as int] <= l_prime[i],
+                    forall|i: int, j: int|
+                        #![auto]
+                        0 <= i < pos_replace && i < j < l_len && p[i] && p[j] ==> l_prime[i]
+                            <= l_prime[j],
+            {
+                if p[pos] && l_prime[pos] < l_prime[pos_cur] {
+                    pos_cur = pos;
+                }
+                pos = pos + 1;
+            }
+            proof {
+                lemma_swapping_produces_a_permutation(l_prime@, pos_replace as int, pos_cur as int);
+            }
+            let v1 = l_prime[pos_replace];
+            let v2 = l_prime[pos_cur];
+            l_prime.set(pos_replace, v2);
+            l_prime.set(pos_cur, v1);
+        }
+        pos_replace = pos_replace + 1;
+    }
+    l_prime
+}
+
+#[verifier::loop_isolation(false)]
+fn sort_even(l: Vec) -> (result: Vec)
+    ensures
+        l.len() == result.len(),
+        permutes(result@, l@),
+        forall|i: int| 0 <= i < l.len() && i % 2 == 1 ==> result[i] == l[i],
+        forall|i: int, j: int|
+            #![auto]
+            0 <= i < j < l.len() && i % 2 == 0 && j % 2 == 0 ==> result[i] <= result[j],
+{
+    let mut p: Vec = vec![];
+    for i in 0..l.len()
+        invariant
+            p.len() == i,
+            forall|j: int| 0 <= j < i ==> p[j] == (j % 2 == 0),
+    {
+        p.push(i % 2 == 0);
+    }
+    assert(forall|i: int, j: int|
+        #![auto]
+        0 <= i < j < l.len() && i % 2 == 0 && j % 2 == 0 ==> p[i] && p[j]);
+    sort_pred(l, p)
+}
 
 } // verus!
 fn main() {}
diff --git a/tasks/human_eval_043.rs b/tasks/human_eval_043.rs
index 37830cc..e32fc3b 100644
--- a/tasks/human_eval_043.rs
+++ b/tasks/human_eval_043.rs
@@ -9,7 +9,42 @@ use vstd::prelude::*;
 
 verus! {
 
-// TODO: Put your solution (the specification, implementation, and proof) to the task here
+#[verifier::loop_isolation(false)]
+fn pairs_sum_to_zero(nums: &[i32], target: i32) -> (found: bool)
+    requires
+        nums.len() >= 2,
+        forall|i: int, j: int|
+            0 <= i < j < nums.len() ==> nums[i] + nums[j] <= i32::MAX && nums[i] + nums[j]
+                >= i32::MIN,
+    ensures
+        found <==> exists|i: int, j: int| 0 <= i < j < nums.len() && nums[i] + nums[j] == target,
+{
+    let mut i = 0;
+
+    while i < nums.len()
+        invariant
+            0 <= i <= nums.len(),
+            forall|u: int, v: int| 0 <= u < v < nums.len() && u < i ==> nums[u] + nums[v] != target,
+        decreases nums.len() - i,
+    {
+        let mut j = i + 1;
+        while j < nums.len()
+            invariant
+                0 <= i < j <= nums.len(),
+                forall|u: int, v: int|
+                    0 <= u < v < nums.len() && u < i ==> nums[u] + nums[v] != target,
+                forall|u: int| i < u < j ==> nums[i as int] + nums[u] != target,
+            decreases nums.len() - j,
+        {
+            if nums[i] + nums[j] == target {
+                return true;
+            }
+            j = j + 1;
+        }
+        i = i + 1;
+    }
+    false
+}
 
 } // verus!
 fn main() {}
diff --git a/tasks/human_eval_049.rs b/tasks/human_eval_049.rs
index 3756e13..81321d9 100644
--- a/tasks/human_eval_049.rs
+++ b/tasks/human_eval_049.rs
@@ -9,7 +9,43 @@ use vstd::prelude::*;
 
 verus! {
 
-// TODO: Put your solution (the specification, implementation, and proof) to the task here
+spec fn modp_rec(n: nat, p: nat) -> nat
+    decreases n,
+{
+    if n == 0 {
+        1nat % p
+    } else {
+        (modp_rec((n - 1) as nat, p) * 2) % p
+    }
+}
+
+fn modmul(a: u32, b: u32, p: u32) -> (mul: u32)
+    by (nonlinear_arith)
+    requires
+        p > 0,
+    ensures
+        mul == ((a as int) * (b as int)) % (p as int),
+{
+    (((a as u64) * (b as u64)) % (p as u64)) as u32
+}
+
+#[verifier::loop_isolation(false)]
+fn modp(n: u32, p: u32) -> (r: u32)
+    by (nonlinear_arith)
+    requires
+        p > 0,
+    ensures
+        r == modp_rec(n as nat, p as nat),
+{
+    let mut r = 1u32 % p;
+    for i in 0..n
+        invariant
+            r == modp_rec(i as nat, p as nat),
+    {
+        r = modmul(r, 2, p);
+    }
+    r
+}
 
 } // verus!
 fn main() {}
diff --git a/tasks/human_eval_050.rs b/tasks/human_eval_050.rs
index 71023ab..c97fca3 100644
--- a/tasks/human_eval_050.rs
+++ b/tasks/human_eval_050.rs
@@ -9,7 +9,96 @@ use vstd::prelude::*;
 
 verus! {
 
-// TODO: Put your solution (the specification, implementation, and proof) to the task here
+spec fn encode_char_spec(c: int) -> int
+    recommends
+        65 <= c <= 90,
+{
+    (c - 65 + 5) % 26 + 65
+}
+
+fn encode_char(c: u8) -> (r: u8)
+    requires
+        65 <= c <= 90,
+    ensures
+        r == encode_char_spec(c as int),
+        65 <= r <= 90,
+{
+    (c - 65 + 5) % 26 + 65
+}
+
+spec fn decode_char_spec(c: int) -> int
+    recommends
+        65 <= c <= 90,
+{
+    (c - 65 + 26 - 5) % 26 + 65
+}
+
+fn decode_char(c: u8) -> (r: u8)
+    requires
+        65 <= c <= 90,
+    ensures
+        r == decode_char_spec(c as int),
+        65 <= r <= 90,
+{
+    (c - 65 + 26 - 5) % 26 + 65
+}
+
+proof fn opposite_encode_decode(c: int)
+    requires
+        65 <= c <= 90,
+    ensures
+        encode_char_spec(decode_char_spec(c)) == c,
+        decode_char_spec(encode_char_spec(c)) == c,
+{
+}
+
+#[verifier::loop_isolation(false)]
+fn encode_shift(s: &Vec) -> (t: Vec)
+    requires
+        forall|i: int| #![trigger s[i]] 0 <= i < s.len() ==> 65 <= s[i] <= 90,
+    ensures
+        s.len() == t.len(),
+        forall|i: int| #![auto] 0 <= i < t.len() ==> t[i] == encode_char_spec(s[i] as int),
+        forall|i: int| #![auto] 0 <= i < t.len() ==> decode_char_spec(t[i] as int) == s[i],
+{
+    let mut t: Vec = vec![];
+    for i in 0..s.len()
+        invariant
+            t.len() == i,
+            forall|j: int| #![auto] 0 <= j < i ==> t[j] == encode_char_spec(s[j] as int),
+            forall|j: int| #![auto] 0 <= j < i ==> decode_char_spec(t[j] as int) == s[j],
+    {
+        t.push(encode_char(s[i]));
+        proof {
+            opposite_encode_decode(s[i as int] as int);
+        }
+    }
+    t
+}
+
+#[verifier::loop_isolation(false)]
+fn decode_shift(s: &Vec) -> (t: Vec)
+    requires
+        forall|i: int| #![trigger s[i]] 0 <= i < s.len() ==> 65 <= s[i] <= 90,
+    ensures
+        s.len() == t.len(),
+        forall|i: int| #![auto] 0 <= i < t.len() ==> t[i] == decode_char_spec(s[i] as int),
+        forall|i: int| #![auto] 0 <= i < t.len() ==> encode_char_spec(t[i] as int) == s[i],
+{
+    let mut t: Vec = vec![];
+    for i in 0..s.len()
+        invariant
+            t.len() == i,
+            forall|j: int| #![auto] 0 <= j < i ==> t[j] == decode_char_spec(s[j] as int),
+            forall|j: int| #![auto] 0 <= j < i ==> encode_char_spec(t[j] as int) == s[j],
+    {
+        t.push(decode_char(s[i]));
+        proof {
+            opposite_encode_decode(s[i as int] as int);
+        }
+    }
+    t
+}
 
 } // verus!
 fn main() {}
diff --git a/tasks/human_eval_054.rs b/tasks/human_eval_054.rs
index 1c44e12..e894030 100644
--- a/tasks/human_eval_054.rs
+++ b/tasks/human_eval_054.rs
@@ -5,11 +5,92 @@ HumanEval/54
 /*
 ### VERUS BEGIN
 */
+use vstd::hash_set::HashSetWithView;
 use vstd::prelude::*;
+use vstd::std_specs::hash::axiom_u8_obeys_hash_table_key_model;
 
 verus! {
 
-// TODO: Put your solution (the specification, implementation, and proof) to the task here
+broadcast use axiom_u8_obeys_hash_table_key_model;
+
+fn hash_set_from(s: &Vec) -> (res: HashSetWithView)
+    ensures
+        forall|i: int| #![auto] 0 <= i < s.len() ==> res@.contains(s[i]),
+        forall|x: int|
+            0 <= x < 256 ==> #[trigger] res@.contains(x as u8) ==> #[trigger] s@.contains(x as u8),
+{
+    let mut res: HashSetWithView = HashSetWithView::new();
+    for i in 0..s.len()
+        invariant
+            forall|j: int| #![auto] 0 <= j < i ==> res@.contains(s[j]),
+            forall|x: int|
+                0 <= x < 256 ==> #[trigger] res@.contains(x as u8) ==> (exists|j: int|
+                    0 <= j < i && s[j] == x),
+    {
+        res.insert(s[i]);
+    }
+    res
+}
+
+proof fn implies_contains(s0: Seq, s1: Seq, hs1: Set)
+    requires
+        forall|i: int| #![trigger s0[i]] 0 <= i < s0.len() ==> 0 <= s0[i] < 256,
+        forall|x: int|
+            0 <= x < 256 ==> #[trigger] hs1.contains(x as u8) ==> #[trigger] s1.contains(x as u8),
+    ensures
+        forall|i: int|
+            #![auto]
+            0 <= i < s0.len() && 0 <= s0[i] < 256 && hs1.contains(s0[i]) ==> s1.contains(s0[i]),
+{
+    assert forall|i: int|
+        #![auto]
+        0 <= i < s0.len() && 0 <= s0[i] < 256 && hs1.contains(s0[i]) implies s1.contains(s0[i]) by {
+        let x = s0[i];
+        assert(0 <= x < 256);
+        assert(hs1.contains(x as u8));
+        assert(s1.contains(x as u8));
+    };
+}
+
+#[verifier::loop_isolation(false)]
+fn same_chars(s0: &Vec, s1: &Vec) -> (same: bool)
+    ensures
+        same <==> (forall|i: int| #![auto] 0 <= i < s0.len() ==> s1@.contains(s0[i])) && (forall|
+            i: int,
+        |
+            #![auto]
+            0 <= i < s1.len() ==> s0@.contains(s1[i])),
+{
+    let hs0 = hash_set_from(s0);
+    let hs1 = hash_set_from(s1);
+
+    proof {
+        implies_contains(s0@, s1@, hs1@);
+        implies_contains(s1@, s0@, hs0@);
+    }
+
+    let mut contains_s0 = true;
+    for i in 0..s0.len()
+        invariant
+            contains_s0 <==> forall|j: int| #![auto] 0 <= j < i ==> s1@.contains(s0[j]),
+    {
+        if !hs1.contains(&s0[i]) {
+            contains_s0 = false;
+            assert(!s1@.contains(s0[i as int]));
+        }
+    }
+    let mut contains_s1 = true;
+    for i in 0..s1.len()
+        invariant
+            contains_s1 <==> forall|j: int| #![auto] 0 <= j < i ==> s0@.contains(s1[j]),
+    {
+        if !hs0.contains(&s1[i]) {
+            contains_s1 = false;
+            assert(!s0@.contains(s1[i as int]));
+        }
+    }
+    contains_s0 && contains_s1
+}
 
 } // verus!
 fn main() {}
diff --git a/tasks/human_eval_068.rs b/tasks/human_eval_068.rs
index b6b971f..d2e3e58 100644
--- a/tasks/human_eval_068.rs
+++ b/tasks/human_eval_068.rs
@@ -9,7 +9,54 @@ use vstd::prelude::*;
 
 verus! {
 
-// TODO: Put your solution (the specification, implementation, and proof) to the task here
+fn pluck_smallest_even(nodes: &Vec) -> (result: Vec)
+    requires
+        nodes@.len() <= u32::MAX,
+    ensures
+        result@.len() == 0 || result@.len() == 2,
+        result@.len() == 0 ==> forall|i: int| 0 <= i < nodes@.len() ==> nodes@[i] % 2 != 0,
+        result@.len() == 2 ==> {
+            let node = result@[0];
+            let index = result@[1];
+            &&& 0 <= index < nodes@.len()
+            &&& nodes@[index as int] == node
+            &&& node % 2 == 0
+            &&& forall|i: int|
+                0 <= i < nodes@.len() && nodes@[i] % 2 == 0 ==> node <= nodes@[i] && forall|i: int|
+                    0 <= i < result@[1] ==> nodes@[i] % 2 != 0 || nodes@[i] > node
+        },
+{
+    let mut smallest_even: Option = None;
+    let mut smallest_index: Option = None;
+
+    for i in 0..nodes.len()
+        invariant
+            0 <= i <= nodes@.len(),
+            nodes@.len() <= u32::MAX,
+            smallest_even.is_none() == smallest_index.is_none(),
+            smallest_index.is_none() ==> forall|j: int| 0 <= j < i ==> nodes@[j] % 2 != 0,
+            smallest_index.is_some() ==> {
+                &&& 0 <= smallest_index.unwrap() < i as int
+                &&& nodes@[smallest_index.unwrap() as int] == smallest_even.unwrap()
+                &&& smallest_even.unwrap() % 2 == 0
+                &&& forall|j: int|
+                    0 <= j < i ==> nodes@[j] % 2 == 0 ==> smallest_even.unwrap() <= nodes@[j]
+                &&& forall|j: int|
+                    0 <= j < smallest_index.unwrap() ==> nodes@[j] % 2 != 0 || nodes@[j]
+                        > smallest_even.unwrap()
+            },
+    {
+        if nodes[i] % 2 == 0 && (smallest_even.is_none() || nodes[i] < smallest_even.unwrap()) {
+            smallest_even = Some(nodes[i]);
+            smallest_index = Some((i as u32));
+        }
+    }
+    if smallest_index.is_none() {
+        Vec::new()
+    } else {
+        vec![smallest_even.unwrap(), smallest_index.unwrap()]
+    }
+}
 
 } // verus!
 fn main() {}
diff --git a/tasks/human_eval_070.rs b/tasks/human_eval_070.rs
index 21b837c..3e5db36 100644
--- a/tasks/human_eval_070.rs
+++ b/tasks/human_eval_070.rs
@@ -5,11 +5,167 @@ HumanEval/70
 /*
 ### VERUS BEGIN
 */
+use vstd::calc;
 use vstd::prelude::*;
+use vstd::seq_lib::lemma_multiset_commutative;
 
 verus! {
 
-// TODO: Put your solution (the specification, implementation, and proof) to the task here
+proof fn swap_preserves_multiset_helper(s: Seq, i: int, j: int)
+    requires
+        0 <= i < j < s.len(),
+    ensures
+        (s.take(j + 1)).to_multiset() =~= s.take(i).to_multiset().add(
+            s.subrange(i + 1, j).to_multiset(),
+        ).insert(s.index(j)).insert(s.index(i)),
+{
+    let fst = s.take(i);
+    let snd = s.subrange(i + 1, j);
+
+    assert((s.take(j + 1)).to_multiset() =~= fst.to_multiset().insert(s.index(i)).add(
+        snd.to_multiset().insert(s.index(j)),
+    )) by {
+        assert(s.take(i + 1).to_multiset() =~= fst.to_multiset().insert(s.index(i))) by {
+            fst.to_multiset_ensures();
+            assert(fst.push(s.index(i)) =~= s.take(i + 1));
+        }
+        assert(s.subrange(i + 1, j + 1).to_multiset() =~= snd.to_multiset().insert(s.index(j))) by {
+            snd.to_multiset_ensures();
+            assert(snd.push(s.index(j)) =~= s.subrange(i + 1, j + 1));
+        }
+        lemma_multiset_commutative(s.take(i + 1), s.subrange(i + 1, j + 1));
+        assert(s.take(i + 1) + s.subrange(i + 1, j + 1) =~= s.take(j + 1));
+    }
+}
+
+// Helper lemma to prove that swapping two elements doesn't change the multiset
+proof fn swap_preserves_multiset(s1: Seq, s2: Seq, i: int, j: int)
+    requires
+        0 <= i < j < s1.len() == s2.len(),
+        forall|x: int| 0 <= x < s1.len() && x != i && x != j ==> s1.index(x) == s2.index(x),
+        s1.index(i) == s2.index(j),
+        s1.index(j) == s2.index(i),
+    ensures
+        s1.to_multiset() == s2.to_multiset(),
+{
+    calc! {
+        (==)
+        s1.to_multiset(); {
+            lemma_multiset_commutative(s1.take(j + 1), s1.skip(j + 1));
+            assert(s1 =~= s1.take(j + 1) + s1.skip(j + 1));
+        }
+        s1.take(j + 1).to_multiset().add(s1.skip(j + 1).to_multiset()); {
+            assert(s1.take(j + 1).to_multiset() =~= s2.take(j + 1).to_multiset()) by {
+                assert(s1.take(i) == s2.take(i));
+                assert(s1.subrange(i + 1, j) =~= (s2.subrange(i + 1, j)));
+                swap_preserves_multiset_helper(s1, i, j);
+                swap_preserves_multiset_helper(s2, i, j);
+            }
+            assert(s1.skip(j + 1).to_multiset() =~= s2.skip(j + 1).to_multiset()) by {
+                assert(s1.skip(j + 1) =~= s2.skip(j + 1));
+            }
+        }
+        s2.take(j + 1).to_multiset().add(s2.skip(j + 1).to_multiset()); {
+            lemma_multiset_commutative(s2.take(j + 1), s2.skip(j + 1));
+            assert(s2 =~= s2.take(j + 1) + s2.skip(j + 1));
+        }
+        s2.to_multiset();
+    }
+}
+
+fn sort_seq(s: &Vec) -> (ret: Vec)
+    ensures
+        forall|i: int, j: int| 0 <= i < j < ret@.len() ==> ret@.index(i) <= ret@.index(j),
+        ret@.len() == s@.len(),
+        s@.to_multiset() == ret@.to_multiset(),
+{
+    let mut sorted = s.clone();
+    let mut i: usize = 0;
+    while i < sorted.len()
+        invariant
+            i <= sorted.len(),
+            forall|j: int, k: int| 0 <= j < k < i ==> sorted@.index(j) <= sorted@.index(k),
+            s@.to_multiset() == sorted@.to_multiset(),
+            forall|j: int, k: int|
+                0 <= j < i <= k < sorted@.len() ==> sorted@.index(j) <= sorted@.index(k),
+            sorted@.len() == s@.len(),
+        decreases sorted.len() - i,
+    {
+        let mut min_index: usize = i;
+        let mut j: usize = i + 1;
+        while j < sorted.len()
+            invariant
+                i <= min_index < j <= sorted.len(),
+                forall|k: int| i <= k < j ==> sorted@.index(min_index as int) <= sorted@.index(k),
+            decreases sorted.len() - j,
+        {
+            if sorted[j] < sorted[min_index] {
+                min_index = j;
+            }
+            j += 1;
+        }
+        if min_index != i {
+            let ghost old_sorted = sorted@;
+            let curr_val = sorted[i];
+            let min_val = sorted[min_index];
+            sorted.set(i, min_val);
+
+            sorted.set(min_index, curr_val);
+
+            proof {
+                swap_preserves_multiset(old_sorted, sorted@, i as int, min_index as int);
+                assert(old_sorted.to_multiset() =~= sorted@.to_multiset());
+            }
+        }
+        i += 1;
+    }
+    sorted
+}
+
+// returns (sorted, strange). Also returning sorted solely to have access to it for writing postcondition
+fn strange_sort_list_helper(s: &Vec) -> (ret: (Vec, Vec))
+    ensures
+        s@.to_multiset() == (ret.0)@.to_multiset(),
+        s@.len() == (ret.0)@.len() == (ret.1)@.len(),
+        forall|i: int|
+            0 <= i < s@.len() && i % 2 == 0 ==> (ret.1)@.index(i) == (ret.0)@.index(i / 2),
+        forall|i: int|
+            0 <= i < s@.len() && i % 2 == 1 ==> (ret.1)@.index(i) == (ret.0)@.index(
+                s@.len() - (i - 1) / 2 - 1,
+            ),
+{
+    let sorted = sort_seq(s);
+    let mut strange = Vec::new();
+    let mut i: usize = 0;
+    while i < sorted.len()
+        invariant
+            i <= sorted.len() == s@.len(),
+            strange@.len() == i,
+            forall|j: int| 0 <= j < i && j % 2 == 0 ==> strange@.index(j) == sorted@.index(j / 2),
+            forall|j: int|
+                0 < j < i && j % 2 == 1 ==> strange@.index(j) == sorted@.index(
+                    sorted@.len() - (j / 2) - 1,
+                ),
+        decreases sorted.len() - i,
+    {
+        if i % 2 == 0 {
+            strange.push(sorted[i / 2]);
+        } else {
+            let r = (i - 1) / 2;
+            strange.push(sorted[s.len() - r - 1]);
+        }
+        i += 1;
+    }
+    (sorted, strange)
+}
+
+fn strange_sort_list(s: &Vec) -> (ret: Vec)
+    ensures
+        s@.len() == ret@.len(),
+{
+    let (_, strange) = strange_sort_list_helper(s);
+    strange
+}
 
 } // verus!
 fn main() {}
diff --git a/tasks/human_eval_072.rs b/tasks/human_eval_072.rs
index 921035d..1429940 100644
--- a/tasks/human_eval_072.rs
+++ b/tasks/human_eval_072.rs
@@ -9,7 +9,126 @@ use vstd::prelude::*;
 
 verus! {
 
-// TODO: Put your solution (the specification, implementation, and proof) to the task here
+// i and j are ends of the subrange - exclusive
+proof fn lemma_increasing_sum_params(s: Seq, i: int, j: int)
+    requires
+        0 <= i <= j <= s.len(),
+    ensures
+        spec_sum(s.subrange(0, i)) <= spec_sum(s.subrange(0, j)),
+    decreases j - i,
+{
+    if (i < j) {
+        assert(spec_sum(s.subrange(0, j - 1)) <= spec_sum(s.subrange(0, j))) by {
+            assert(s.subrange(0, j).drop_last() == s.subrange(0, j - 1));
+        }
+        lemma_increasing_sum_params(s, i, j - 1);
+    }
+}
+
+proof fn lemma_increasing_sum(s: Seq)
+    ensures
+        forall|i: int, j: int|
+            #![trigger spec_sum(s.subrange(0, i)), spec_sum(s.subrange(0, j))]
+            0 <= i <= j <= s.len() ==> spec_sum(s.subrange(0, i)) <= spec_sum(s.subrange(0, j)),
+{
+    assert forall|i: int, j: int|
+        #![trigger spec_sum(s.subrange(0, i)), spec_sum(s.subrange(0, j))]
+        0 <= i <= j <= s.len() ==> spec_sum(s.subrange(0, i)) <= spec_sum(s.subrange(0, j)) by {
+        if (0 <= i <= j <= s.len()) {
+            lemma_increasing_sum_params(s, i, j);
+        }
+    }
+}
+
+spec fn spec_sum(s: Seq) -> int {
+    s.fold_left(0, |x: int, y| x + y)
+}
+
+fn sum_lesser_than_limit(qs: &Vec, w: u32) -> (ret: bool)
+    ensures
+        ret <==> spec_sum(qs@) <= w,
+{
+    let mut sum: u32 = 0;
+    for i in 0..qs.len()
+        invariant
+            sum == spec_sum(qs@.subrange(0, i as int)),
+            i <= qs.len(),
+            sum <= w,
+    {
+        proof {
+            assert(spec_sum(qs@.subrange(0, i + 1)) <= spec_sum(qs@)) by {
+                assert(qs@ == qs@.subrange(0, qs@.len() as int));
+                lemma_increasing_sum(qs@);
+            }
+            assert(spec_sum(qs@.subrange(0, i as int)) + qs[i as int] == spec_sum(
+                qs@.subrange(0, i + 1),
+            )) by {
+                assert(qs@.subrange(0, i + 1).drop_last() == qs@.subrange(0, i as int));
+            }
+        }
+        let sum_opt = sum.checked_add(qs[i]);
+        if sum_opt.is_none() {
+            assert(spec_sum(qs@.subrange(0, i + 1)) > u32::MAX >= w);
+            return false;
+        } else {
+            sum = sum_opt.unwrap();
+            if sum > w {
+                assert(spec_sum(qs@.subrange(0, i + 1)) > w);
+                return false;
+            }
+        }
+    }
+    assume(sum == spec_sum(qs@));
+    true
+}
+
+fn palindrome(qs: &Vec) -> (ret: bool)
+    ensures
+        ret <==> qs@ =~= qs@.reverse(),
+{
+    let mut ret = true;
+    let mut i: usize = 0;
+    while i < qs.len() / 2
+        invariant
+            i <= qs@.len() / 2,
+            ret <==> qs@.subrange(0, i as int) =~= qs@.subrange(
+                qs@.len() - i,
+                qs@.len() as int,
+            ).reverse(),
+    {
+        // reveal_with_fuel(Seq::reverse, 5); // VERUS BUG on uncomment. file issue
+        assert(qs@.subrange(qs@.len() - (i + 1), qs@.len() as int).reverse().drop_last()
+            =~= qs@.subrange(qs@.len() - i, qs@.len() as int).reverse());
+        assert(qs@.subrange(qs@.len() - (i + 1), qs@.len() as int).reverse() =~= qs@.subrange(
+            qs@.len() - i,
+            qs@.len() as int,
+        ).reverse().push(qs@.index(qs@.len() - (i + 1))));
+        if qs[i] != qs[qs.len() - i - 1] {
+            ret = false;
+        }
+        i += 1;
+    }
+    let ghost fst_half = qs@.subrange(0, (qs@.len() / 2) as int);
+    let ghost snd_half = qs@.subrange(qs@.len() - qs@.len() / 2, qs@.len() as int);
+    proof {
+        if (qs.len() % 2) == 1 {
+            assert(qs@ =~= fst_half + qs@.subrange(
+                (qs@.len() / 2) as int,
+                qs@.len() - qs@.len() / 2,
+            ) + snd_half);
+        } else {
+            assert(qs@ =~= fst_half + snd_half);
+        }
+    }
+    ret
+}
+
+fn will_it_fly(qs: &Vec, w: u32) -> (ret: bool)
+    ensures
+        ret <==> qs@ =~= qs@.reverse() && spec_sum(qs@) <= w,
+{
+    palindrome(qs) && sum_lesser_than_limit(qs, w)
+}
 
 } // verus!
 fn main() {}
diff --git a/tasks/human_eval_073.rs b/tasks/human_eval_073.rs
index ba70ee6..59c2166 100644
--- a/tasks/human_eval_073.rs
+++ b/tasks/human_eval_073.rs
@@ -9,7 +9,49 @@ use vstd::prelude::*;
 
 verus! {
 
-// TODO: Put your solution (the specification, implementation, and proof) to the task here
+spec fn zip_halves(v: Seq) -> (ret: Seq<(T, T)>) {
+    v.take((v.len() / 2) as int).zip_with(v.skip(((v.len() + 1) / 2) as int).reverse())
+}
+
+spec fn diff(s: Seq<(i32, i32)>) -> int {
+    s.fold_left(
+        0,
+        |acc: int, x: (i32, i32)|
+            if (x.0 != x.1) {
+                acc + 1
+            } else {
+                acc
+            },
+    )
+}
+
+fn smallest_change(v: Vec) -> (change: usize)
+    requires
+        v@.len() < usize::MAX,
+    ensures
+        change == diff(zip_halves(v@)),
+{
+    let mut ans: usize = 0;
+    let ghost zipped = Seq::<(i32, i32)>::empty();
+    for i in 0..v.len() / 2
+        invariant
+            ans <= i <= v@.len() / 2 < usize::MAX,
+            ans == diff(zipped),
+            zipped =~= zip_halves(v@).take(i as int),
+    {
+        proof {
+            let ghost pair = (v[i as int], v[v.len() - i - 1]);
+            let ghost zipped_old = zipped;
+            zipped = zipped.push(pair);
+            assert(zipped.drop_last() =~= zipped_old);
+        }
+        if v[i] != v[v.len() - i - 1] {
+            ans += 1;
+        }
+    }
+    assert(zip_halves(v@).take((v@.len() / 2) as int) =~= zip_halves(v@));
+    ans
+}
 
 } // verus!
 fn main() {}
diff --git a/tasks/human_eval_074.rs b/tasks/human_eval_074.rs
index eeaaecf..3e5c3f7 100644
--- a/tasks/human_eval_074.rs
+++ b/tasks/human_eval_074.rs
@@ -9,7 +9,88 @@ use vstd::prelude::*;
 
 verus! {
 
-// TODO: Put your solution (the specification, implementation, and proof) to the task here
+spec fn spec_sum(s: Seq) -> int {
+    s.fold_left(0, |x: int, y| x + y)
+}
+
+// i and j are ends of the subrange - exclusive
+proof fn lemma_increasing_sum(s: Seq, i: int, j: int)
+    requires
+        0 <= i <= j <= s.len(),
+    ensures
+        spec_sum(s.subrange(0, i)) <= spec_sum(s.subrange(0, j)),
+    decreases j - i,
+{
+    if (i < j) {
+        assert(spec_sum(s.subrange(0, j - 1)) <= spec_sum(s.subrange(0, j))) by {
+            assert(s.subrange(0, j).drop_last() == s.subrange(0, j - 1));
+        }
+        lemma_increasing_sum(s, i, j - 1);
+    }
+}
+
+spec fn total_str_len(strings: Seq<&str>) -> int {
+    spec_sum(strings.map_values(|s: &str| s@.len()))
+}
+
+fn checked_total_str_len(lst: &Vec<&str>) -> (ret: Option)
+    ensures
+        ret.is_some() <==> total_str_len(lst@) <= usize::MAX,
+        ret.is_some() <==> ret.unwrap() == total_str_len(lst@),
+{
+    let ghost lens = Seq::::empty();
+    let mut sum: usize = 0;
+    for i in 0..lst.len()
+        invariant
+            sum == lst@.subrange(0, i as int).map_values(|s: &str| s@.len()).fold_left(
+                0,
+                |x: int, y| x + y,
+            ),
+            spec_sum(lens) == sum,
+            lens =~= lst@.map_values(|s: &str| s@.len()).take(i as int),
+            lens =~= lst@.take(i as int).map_values(|s: &str| s@.len()),
+    {
+        let x = lst[i].unicode_len();
+        proof {
+            assert(lens.push(x as nat).drop_last() == lens);
+            lens = lens.push(x as nat);
+            assert(lens =~= lst@.map_values(|s: &str| s@.len()).take(i + 1));
+
+            lemma_increasing_sum(lst@.map_values(|s: &str| s@.len()), i + 1, lst@.len() as int);
+            assert(total_str_len(lst@) >= spec_sum(lens)) by {
+                assert(lst@.map_values(|s: &str| s@.len()) =~= lst@.map_values(
+                    |s: &str| s@.len(),
+                ).take(lst@.len() as int));
+            }
+            if x + sum > usize::MAX {
+                assert(sum.checked_add(x).is_none());
+                assert(total_str_len(lst@) > usize::MAX);
+            }
+        }
+        sum = sum.checked_add(x)?;
+        assert(lst@.take(i + 1).map_values(|s: &str| s@.len()).drop_last() == lst@.take(
+            i as int,
+        ).map_values(|s: &str| s@.len()));
+    }
+    assert(lst@ == lst@.subrange(0, lst.len() as int));
+    return Some(sum);
+}
+
+fn total_match<'a>(lst1: Vec<&'a str>, lst2: Vec<&'a str>) -> (ret: Option>)
+    ensures
+        ret.is_some() <== total_str_len(lst1@) <= usize::MAX && total_str_len(lst2@) <= usize::MAX,
+        ret.is_some() ==> ret.unwrap() == if total_str_len(lst1@) <= total_str_len(lst2@) {
+            lst1
+        } else {
+            lst2
+        },
+{
+    if checked_total_str_len(&lst1)? <= checked_total_str_len(&lst2)? {
+        Some(lst1)
+    } else {
+        Some(lst2)
+    }
+}
 
 } // verus!
 fn main() {}
diff --git a/tasks/human_eval_075.rs b/tasks/human_eval_075.rs
index 4bf4540..dcbb5d6 100644
--- a/tasks/human_eval_075.rs
+++ b/tasks/human_eval_075.rs
@@ -5,11 +5,130 @@ HumanEval/75
 /*
 ### VERUS BEGIN
 */
+use vstd::arithmetic::mul::*;
 use vstd::prelude::*;
 
 verus! {
 
-// TODO: Put your solution (the specification, implementation, and proof) to the task here
+spec fn spec_prime(p: int) -> bool {
+    p > 1 && forall|k: int| 1 < k < p ==> #[trigger] (p % k) != 0
+}
+
+fn prime(p: u32) -> (ret: bool)
+    ensures
+        ret <==> spec_prime(p as int),
+{
+    if p <= 1 {
+        return false;
+    }
+    for k in 2..p
+        invariant
+            forall|j: int| 1 < j < k ==> #[trigger] (p as int % j) != 0,
+            k <= p,
+    {
+        if p % k == 0 {
+            return false;
+        }
+    }
+    true
+}
+
+fn checked_mul_thrice(x: u32, y: u32, z: u32) -> (ret: Option)
+    ensures
+        ret.is_some() ==> ret.unwrap() == x * y * z,
+        ret.is_none() ==> x * y * z > u32::MAX,
+{
+    // x,y,z == 0 done separately to invoke lemma_mul_increases which requires x > 0
+    if (x == 0 || y == 0 || z == 0) {
+        assert(0 == x * y * z);
+        return Some(0);
+    }
+    assert(x > 0 && y > 0 && z > 0);
+    let prod2 = x.checked_mul(y);
+    if prod2.is_some() {
+        let prod3 = prod2.unwrap().checked_mul(z);
+        if prod3.is_some() {
+            let ans = prod3.unwrap();
+            assert(ans == x * y * z);
+            Some(ans)
+        } else {
+            assert(x * y * z > u32::MAX);
+            None
+        }
+    } else {
+        broadcast use group_mul_properties;
+
+        assert(x * y * z >= y * z);
+        None
+    }
+}
+
+fn is_multiply_prime(x: u32) -> (ans: bool)
+    requires
+        x > 1,
+    ensures
+        ans <==> exists|a: int, b: int, c: int|
+            spec_prime(a) && spec_prime(b) && spec_prime(c) && x == a * b * c,
+{
+    let mut a = 1;
+    while a < x
+        invariant
+            forall|i: int, j: int, k: int|
+                (spec_prime(i) && spec_prime(j) && spec_prime(k) && i <= a && j <= x && k <= x)
+                    ==> x != i * j * k,
+            a <= x,
+        decreases x - a,
+    {
+        a += 1;
+        if prime(a) {
+            let mut b = 1;
+            while b < x
+                invariant
+                    forall|j: int, k: int|
+                        (spec_prime(j) && spec_prime(k) && j <= b && k <= x) ==> x != (a as int) * j
+                            * k,
+                    spec_prime(a as int),
+                    a <= x,
+                    b <= x,
+                decreases x - b,
+            {
+                b += 1;
+                if prime(b) {
+                    let mut c = 1;
+                    while c < x
+                        invariant
+                            forall|k: int| (spec_prime(k) && k <= c as int) ==> x != a * b * k,
+                            spec_prime(a as int),
+                            spec_prime(b as int),
+                            a <= x,
+                            b <= x,
+                            c <= x,
+                        decreases x - c,
+                    {
+                        c += 1;
+                        let prod = checked_mul_thrice(a, b, c);
+                        if prime(c) && prod.is_some() && x == prod.unwrap() {
+                            return true;
+                        }
+                    }
+                }
+            }
+        }
+    }
+    assert(forall|i: int, j: int, k: int|
+        i <= x && j <= x && k <= x && spec_prime(i) && spec_prime(j) && spec_prime(k) ==> x != i * j
+            * k);
+    // prove that that even if the factors are not in the range [2, x], the product is still not equal to x
+    assert forall|i: int, j: int, k: int|
+        spec_prime(i) && spec_prime(j) && spec_prime(k) ==> x != i * j * k by {
+        if (i > 1 && j > 1 && k > 1 && (i > x || j > x || k > x)) {
+            broadcast use group_mul_properties;
+
+            assert(i * j * k > x);
+        }
+    }
+    false
+}
 
 } // verus!
 fn main() {}
diff --git a/tasks/human_eval_076.rs b/tasks/human_eval_076.rs
index 3a5559e..3d5ad48 100644
--- a/tasks/human_eval_076.rs
+++ b/tasks/human_eval_076.rs
@@ -5,11 +5,42 @@ HumanEval/76
 /*
 ### VERUS BEGIN
 */
+use vstd::arithmetic::logarithm::log;
+use vstd::arithmetic::power::pow;
 use vstd::prelude::*;
-
 verus! {
 
-// TODO: Put your solution (the specification, implementation, and proof) to the task here
+// note that the order of paramters is reverse in exec fn ilog and spec fn log
+#[verifier::external_fn_specification]
+pub fn ex_ilog(x: u32, base: u32) -> (ret: u32)
+    requires
+        x > 0,
+        base > 1,
+    ensures
+        ret == log(base as int, x as int),
+{
+    x.ilog(base)
+}
+
+#[verifier::external_fn_specification]
+pub fn ex_checked_pow(x: u32, exp: u32) -> (ret: Option)
+    ensures
+        ret.is_some() <==> ret.unwrap() == pow(x as int, exp as nat),
+        ret.is_none() <==> pow(x as int, exp as nat) > u32::MAX,
+{
+    x.checked_pow(exp)
+}
+
+fn is_simple_power(x: u32, n: u32) -> (ret: bool)
+    requires
+        x > 0,
+        n > 1,
+    ensures
+        ret <==> x == pow(n as int, log(n as int, x as int) as nat),
+{
+    let maybe_x = n.checked_pow(x.ilog(n));
+    return maybe_x.is_some() && maybe_x.unwrap() == x;
+}
 
 } // verus!
 fn main() {}
diff --git a/tasks/human_eval_077.rs b/tasks/human_eval_077.rs
index 957a9bb..bcb8d8a 100644
--- a/tasks/human_eval_077.rs
+++ b/tasks/human_eval_077.rs
@@ -5,11 +5,139 @@ HumanEval/77
 /*
 ### VERUS BEGIN
 */
+use vstd::arithmetic::mul::*;
+use vstd::math::abs;
 use vstd::prelude::*;
 
 verus! {
 
-// TODO: Put your solution (the specification, implementation, and proof) to the task here
+proof fn lemma_cube_increases_helper(i: int)
+    ensures
+        i >= 0 ==> (i * i * i) <= (i + 1) * (i + 1) * (i + 1),
+{
+    broadcast use group_mul_properties;
+
+    if (i > 0) {
+        assert((i + 1) * (i + 1) * (i + 1) == i * i * i + 3 * i * i + 3 * i + 1);
+        assert(i * i * i + 3 * i * i + 3 * i + 1 > i * i * i);
+    }
+}
+
+proof fn lemma_cube_increases_params(i: int, j: int)
+    ensures
+        0 <= i <= j ==> (i * i * i) <= (j * j * j),
+    decreases j - i,
+{
+    // base case
+    if (i == j) {
+    }
+    // inductive case
+     else if (i < j) {
+        lemma_cube_increases_params(i, j - 1);
+        lemma_cube_increases_helper(j - 1);
+
+    }
+}
+
+proof fn lemma_cube_increases()
+    ensures
+        forall|i: int, j: int| 0 <= i <= j ==> #[trigger] (i * i * i) <= #[trigger] (j * j * j),
+{
+    assert forall|i: int, j: int|
+        0 <= i <= j ==> #[trigger] (i * i * i) <= #[trigger] (j * j * j) by {
+        lemma_cube_increases_params(i, j);
+    }
+}
+
+fn checked_cube(x: i32) -> (ret: Option)
+    requires
+        x >= 0,
+    ensures
+        ret.is_some() ==> ret.unwrap() == x * x * x,
+        ret.is_none() ==> x * x * x > i32::MAX,
+{
+    //x == 0 done separately to invoke lemma_mul_increases which requires x > 0
+    if x == 0 {
+        return Some(0);
+    }
+    let sqr = x.checked_mul(x);
+    if sqr.is_some() {
+        let cube = sqr.unwrap().checked_mul(x);
+        if cube.is_some() {
+            let ans = cube.unwrap();
+            assert(ans == x * x * x);
+            Some(ans)
+        } else {
+            assert(x * x * x > i32::MAX);
+            None
+        }
+    } else {
+        assert(x > 0);
+        assert(x * x > i32::MAX);
+        proof {
+            lemma_mul_increases(x as int, x * x);
+        }
+        assert(x * x * x >= x * x);
+        None
+    }
+}
+
+#[verifier::external_fn_specification]
+pub fn ex_abs(x: i32) -> (ret: i32)
+    requires
+        x != i32::MIN,  // avoid overflow: -(i32::MIN) == (i32::MAX) + 1
+
+    ensures
+        ret == abs(x as int),
+{
+    x.abs()
+}
+
+fn is_cube(x: i32) -> (ret: bool)
+    requires
+        x != i32::MIN,  // avoid overflow: -(i32::MIN) == (i32::MAX) + 1
+
+    ensures
+        ret <==> exists|i: int| 0 <= i && abs(x as int) == #[trigger] (i * i * i),
+{
+    let x_abs = x.abs();
+
+    // dealing with cases where the the cube is not greater than the number
+    if x_abs == 0 {
+        assert(abs(x as int) == 0 * 0 * 0);
+        return true;
+    } else if (x_abs == 1) {
+        assert(abs(x as int) == 1 * 1 * 1);
+        return true;
+    }
+    assert(-1 > x || x > 1);
+    let mut i = 2;
+    while i < x_abs
+        invariant
+            forall|j: int| 2 <= j < i ==> abs(x as int) != #[trigger] (j * j * j),
+            2 <= i <= abs(x as int) == x_abs,
+    {
+        let prod = checked_cube(i);
+        if prod.is_some() && prod.unwrap() == x.abs() {
+            return true;
+        }
+        i += 1;
+    }
+    assert(forall|j: int| 2 <= j ==> abs(x as int) != #[trigger] (j * j * j)) by {
+        assert(forall|j: int| 2 <= j < i ==> abs(x as int) != #[trigger] (j * j * j));
+
+        assert(forall|j: int| i <= j ==> abs(x as int) < #[trigger] (j * j * j)) by {
+            assert(abs(x as int) < #[trigger] (i * i * i)) by {
+                broadcast use group_mul_properties;
+
+                assert(i <= i * i <= i * i * i);
+            }
+            lemma_cube_increases();
+            assert(forall|j: int| i <= j ==> (i * i * i) <= #[trigger] (j * j * j));
+        }
+    }
+    false
+}
 
 } // verus!
 fn main() {}
diff --git a/tasks/human_eval_080.rs b/tasks/human_eval_080.rs
index 0185958..cdae840 100644
--- a/tasks/human_eval_080.rs
+++ b/tasks/human_eval_080.rs
@@ -9,7 +9,44 @@ use vstd::prelude::*;
 
 verus! {
 
-// TODO: Put your solution (the specification, implementation, and proof) to the task here
+spec fn three_distinct_spec(s: Seq, i: int) -> bool
+    recommends
+        0 < i && i + 1 < s.len(),
+{
+    (s[i - 1] != s[i]) && (s[i] != s[i + 1]) && (s[i] != s[i + 1])
+}
+
+fn three_distinct(s: &Vec, i: usize) -> (is: bool)
+    requires
+        0 < i && i + 1 < s.len(),
+    ensures
+        is <==> three_distinct_spec(s@, i as int),
+{
+    (s[i - 1] != s[i]) && (s[i] != s[i + 1]) && (s[i] != s[i + 1])
+}
+
+spec fn happy_spec(s: Seq) -> bool {
+    s.len() >= 3 && (forall|i: int| 0 < i && i + 1 < s.len() ==> three_distinct_spec(s, i))
+}
+
+#[verifier::loop_isolation(false)]
+fn is_happy(s: &Vec) -> (happy: bool)
+    ensures
+        happy <==> happy_spec(s@),
+{
+    if s.len() < 3 {
+        return false;
+    }
+    for i in 1..(s.len() - 1)
+        invariant
+            forall|j: int| 0 < j < i ==> three_distinct_spec(s@, j),
+    {
+        if !three_distinct(s, i) {
+            return false;
+        }
+    }
+    return true;
+}
 
 } // verus!
 fn main() {}
diff --git a/tasks/human_eval_134.rs b/tasks/human_eval_134.rs
index f0a371a..727ff34 100644
--- a/tasks/human_eval_134.rs
+++ b/tasks/human_eval_134.rs
@@ -9,7 +9,39 @@ use vstd::prelude::*;
 
 verus! {
 
-// TODO: Put your solution (the specification, implementation, and proof) to the task here
+pub uninterp spec fn is_alphabetic(c: char) -> (result: bool);
+
+#[verifier::external_fn_specification]
+#[verifier::when_used_as_spec(is_alphabetic)]
+pub fn ex_is_alphabetic(c: char) -> (result: bool)
+    ensures
+        result <==> (c.is_alphabetic()),
+{
+    c.is_alphabetic()
+}
+
+pub uninterp spec fn is_whitespace(c: char) -> (result: bool);
+
+#[verifier::external_fn_specification]
+#[verifier::when_used_as_spec(is_whitespace)]
+pub fn ex_is_whitespace(c: char) -> (result: bool)
+    ensures
+        result <==> (c.is_whitespace()),
+{
+    c.is_whitespace()
+}
+
+fn check_if_last_char_is_a_letter(txt: &str) -> (result: bool)
+    ensures
+        result <==> (txt@.len() > 0 && txt@.last().is_alphabetic() && (txt@.len() == 1
+            || txt@.index(txt@.len() - 2).is_whitespace())),
+{
+    let len = txt.unicode_len();
+    if len == 0 {
+        return false;
+    }
+    txt.get_char(len - 1).is_alphabetic() && (len == 1 || txt.get_char(len - 2).is_whitespace())
+}
 
 } // verus!
 fn main() {}
diff --git a/tasks/human_eval_136.rs b/tasks/human_eval_136.rs
index 04fda7e..cd5c489 100644
--- a/tasks/human_eval_136.rs
+++ b/tasks/human_eval_136.rs
@@ -9,7 +9,46 @@ use vstd::prelude::*;
 
 verus! {
 
-// TODO: Put your solution (the specification, implementation, and proof) to the task here
+fn largest_smallest_integers(arr: &Vec) -> (res: (Option, Option))
+    ensures
+        ({
+            let a = res.0;
+            let b = res.1;
+            &&& a.is_none() ==> forall|i: int| 0 <= i < arr@.len() ==> arr@[i] >= 0
+            &&& a.is_some() ==> arr@.contains(a.unwrap()) && a.unwrap() < 0
+            &&& a.is_some() ==> forall|i: int|
+                0 <= i < arr@.len() && arr@[i] < 0 ==> arr@[i] <= a.unwrap()
+            &&& b.is_none() ==> forall|i: int| 0 <= i < arr@.len() ==> arr@[i] <= 0
+            &&& b.is_some() ==> arr@.contains(b.unwrap()) && b.unwrap() > 0
+            &&& b.is_some() ==> forall|i: int|
+                0 <= i < arr@.len() && arr@[i] > 0 ==> arr@[i] >= b.unwrap()
+        }),
+{
+    let mut i: usize = 0;
+    let mut a = None;
+    let mut b = None;
+
+    while i < arr.len()
+        invariant
+            0 <= i <= arr@.len(),
+            a.is_none() ==> forall|j: int| 0 <= j < i ==> arr@[j] >= 0,
+            a.is_some() ==> arr@.contains(a.unwrap()) && a.unwrap() < 0,
+            a.is_some() ==> forall|j: int| 0 <= j < i && arr@[j] < 0 ==> arr@[j] <= a.unwrap(),
+            b.is_none() ==> forall|j: int| 0 <= j < i ==> arr@[j] <= 0,
+            b.is_some() ==> arr@.contains(b.unwrap()) && b.unwrap() > 0,
+            b.is_some() ==> forall|j: int| 0 <= j < i && arr@[j] > 0 ==> arr@[j] >= b.unwrap(),
+        decreases arr.len() - i,
+    {
+        if arr[i] < 0 && (a.is_none() || arr[i] >= a.unwrap()) {
+            a = Some(arr[i]);
+        }
+        if arr[i] > 0 && (b.is_none() || arr[i] <= b.unwrap()) {
+            b = Some(arr[i]);
+        }
+        i = i + 1;
+    }
+    (a, b)
+}
 
 } // verus!
 fn main() {}