Skip to content

Commit

Permalink
036, 087, 161 (#37)
Browse files Browse the repository at this point in the history
  • Loading branch information
WeetHet authored Aug 30, 2024
1 parent 2a83537 commit f13de1b
Show file tree
Hide file tree
Showing 5 changed files with 270 additions and 18 deletions.
78 changes: 78 additions & 0 deletions 036-fizz_buzz.dfy
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
method fizz_buzz(n: nat) returns (result: nat)
// post-conditions-start
ensures result == sum(
seq(n, i requires 0 <= i < n => (if i % 11 == 0 || i % 13 == 0 then count7_r(i) else 0))
)
// post-conditions-end
{
// impl-start
ghost var values := [];
result := 0;
var i := 0;
while i < n
// invariants-start
invariant 0 <= i <= n
invariant |values| == i
invariant result == sum(values[..i])
invariant values == seq(i, j requires 0 <= j < i => (if j % 11 == 0 || j % 13 == 0 then count7_r(j) else 0))
// invariants-end
{
ghost var pre := values;
if i % 11 == 0 || i % 13 == 0 {
var cnt := count7(i);
result := result + cnt;
values := values + [cnt];
} else {
values := values + [0];
}
assert values[..i] == pre[..i]; // assert-line
// assert-start
assert sum(values[..i + 1]) == sum(values[..i]) + values[i] by {
assert values[..i+1][..i] == values[..i];
sum_prop(values[..i + 1]);
}
// assert-end
i := i + 1;
}
assert values[..|values|] == values; // assert-line
// impl-end
}

method count7(x: nat) returns (count: nat)
// post-conditions-start
ensures count == count7_r(x)
// post-conditions-end
{
// impl-start
count := 0;
var y := x;
while y > 0
// invariants-start
invariant count + count7_r(y) == count7_r(x)
// invariants-end
{
if y % 10 == 7 {
count := count + 1;
}
y := y / 10;
}
// impl-end
}

function count7_r(x: nat): nat {
var lst := if x % 10 == 7 then 1 else 0;
if x < 10 then lst else lst + count7_r(x / 10)
}

function sum(s: seq<int>) : int {
if |s| == 0 then 0 else s[0] + sum(s[1..])
}

lemma sum_prop(s: seq<int>)
requires |s| > 0
ensures sum(s) == sum(s[..|s| - 1]) + s[ |s| - 1 ]
{
if (|s| > 1) {
assert (s[1..][..|s[1..]| - 1]) == s[1..|s| - 1];
}
}
113 changes: 113 additions & 0 deletions 087-get_row.dfy
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
method get_row(lst: seq<seq<int>>, x: int) returns (pos: seq<(int, int)>)
// post-conditions-start
ensures forall i :: 0 <= i < |pos| ==> (
var (a, b) := pos[i];
0 <= a < |lst| && 0 <= b < |lst[a]| && lst[a][b] == x
)
ensures forall i, j :: 0 <= i < |lst| && 0 <= j < |lst[i]| && lst[i][j] == x ==> (i, j) in pos
ensures forall i, j :: 0 <= i < j < |pos| ==> less_eq(pos[i], pos[j])
// post-conditions-end
{
// impl-start
pos := [];
var i := 0;
while i < |lst|
// invariants-start
invariant 0 <= i <= |lst|
invariant forall j :: 0 <= j < |pos| ==> (
var (a, b) := pos[j];
0 <= a < i && 0 <= b < |lst[a]| && lst[a][b] == x
)
invariant forall j, k :: 0 <= j < i && 0 <= k < |lst[j]| && lst[j][k] == x ==> (j, k) in pos
// invariants-end
{
var j := 0;
var pos_i := [];
ghost var row := lst[i];
while j < |lst[i]|
// invariants-start
invariant 0 <= j <= |lst[i]|
invariant forall k :: 0 <= k < |pos_i| ==> var (a, b) := pos_i[k];
a == i && 0 <= b < |row|
invariant forall k :: 0 <= k < |pos_i| ==> var (a, b) := pos_i[k]; row[b] == x
invariant forall k :: 0 <= k < j && lst[i][k] == x ==> (i, k) in pos_i
// invariants-end
{
if lst[i][j] == x {
pos_i := pos_i + [(i, j)];
}
j := j + 1;
}

pos := pos + pos_i;

i := i + 1;
}
ghost var unsorted := pos;
pos := SortSeq(pos);
// assert-start
assert forall i, j :: 0 <= i < |lst| && 0 <= j < |lst[i]| && lst[i][j] == x ==> (i, j) in pos by {
assert forall i, j :: 0 <= i < |lst| && 0 <= j < |lst[i]| && lst[i][j] == x ==> (i, j) in multiset(pos);
}
// assert-end

// assert-start
assert forall i :: 0 <= i < |pos| ==> (
var (a, b) := pos[i]; 0 <= a < |lst| && 0 <= b < |lst[a]| && lst[a][b] == x
) by {
assert forall i :: 0 <= i < |pos| ==> pos[i] in multiset(unsorted);
}
// assert-end
// impl-end
}

function less(a: (int, int), b: (int, int)): bool {
var (x, y) := a; var (u, v) := b;
x < u || (x == u && y > v)
}

function less_eq(a: (int, int), b: (int, int)): bool {
var (x, y) := a; var (u, v) := b;
(x == u && y == v) || less(a, b)
}

method SortSeq(s: seq<(int, int)>) returns (sorted: seq<(int, int)>)
// post-conditions-start
ensures forall i, j :: 0 <= i < j < |sorted| ==> less_eq(sorted[i], sorted[j])
ensures |sorted| == |s|
ensures multiset(s) == multiset(sorted)
// post-conditions-end
{
// impl-start
sorted := s;
var i := 0;
while i < |sorted|
// invariants-start
invariant 0 <= i <= |sorted|
invariant forall j, k :: 0 <= j < k < i ==> less_eq(sorted[j], sorted[k])
invariant multiset(s) == multiset(sorted)
invariant forall j :: 0 <= j < i ==> forall k :: i <= k < |sorted| ==> less_eq(sorted[j], sorted[k])
invariant |sorted| == |s|
// invariants-end
{
var minIndex := i;
var j := i + 1;
while j < |sorted|
// invariants-start
invariant i <= minIndex < j <= |sorted|
invariant forall k :: i <= k < j ==> less_eq(sorted[minIndex], sorted[k])
// invariants-end
{
if less(sorted[j], sorted[minIndex]) {
minIndex := j;
}
j := j + 1;
}
if minIndex != i {
var temp := sorted[i];
sorted := sorted[i := sorted[minIndex]][minIndex := temp];
}
i := i + 1;
}
// impl-end
}
68 changes: 68 additions & 0 deletions 161-solve.dfy
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
method solve(s: string) returns (t: string)
// post-conditions-start
ensures |s| == |t|
ensures (forall i :: 0 <= i < |s| ==> !is_alpha(s[i])) ==> (forall i :: 0 <= i < |s| ==> s[i] == t[|t| - 1 - i])
ensures (exists i :: 0 <= i < |s| && is_alpha(s[i])) ==>
(forall i :: 0 <= i < |t| ==> if is_alpha(s[i]) then t[i] == flip_case(s[i]) else t[i] == s[i])
// post-conditions-end
{
// impl-start
var flag := false;
t := "";

var i := 0;
while i < |s|
// invariants-start
invariant 0 <= i <= |s|
invariant |t| == i
invariant flag <==> exists j :: 0 <= j < i && is_alpha(s[j])
invariant forall j :: 0 <= j < i ==> t[j] == if is_alpha(s[j]) then flip_case(s[j]) else s[j]
// invariants-end
{
if is_alpha(s[i]) {
t := t + [flip_case(s[i])];
flag := true;
} else {
t := t + [s[i]];
}
i := i + 1;
}

if !flag {
t := reverse(t);
}
// impl-end
}

method reverse(s: string) returns (rev: string)
// pre-conditions-start
ensures |rev| == |s|
ensures forall k :: 0 <= k < |s| ==> rev[k] == s[|s| - 1 - k]
// pre-conditions-end
{
// impl-start
rev := "";
var i := 0;
while (i < |s|)
// invariants-start
invariant i >= 0 && i <= |s|
invariant |rev| == i
invariant forall k :: 0 <= k < i ==> rev[k] == s[|s| - 1 - k]
// invariants-end
{
rev := rev + [s[|s| - i - 1]];
i := i + 1;
}
// impl-end
}

predicate is_alpha(c: char) {
'a' <= c <= 'z' || 'A' <= c <= 'Z'
}

function flip_case(c: char): (flipped: char)
requires is_alpha(c)
ensures is_alpha(flipped)
{
if 'a' <= c <= 'z' then c - 'a' + 'A' else c - 'A' + 'a'
}
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ Current status:
- [x] 33. sort_third
- [x] 34. unique
- [x] 35. max_element
- [ ] 36. fizz_buzz
- [x] 36. fizz_buzz
- [x] 37. sort_even - sorting
- [ ] 38. encode_cyclic
- [ ] 39. ~prime_fib~ -- unbounded loop, probably impossible
Expand Down Expand Up @@ -89,7 +89,7 @@ Current status:
- [x] 84. solve
- [x] 85. add
- [ ] 86. anti_shuffle - complex strings
- [ ] 87. get_row - sorting
- [x] 87. get_row - sorting
- [x] 88. sort_array - sorting
- [x] 89. encrypt
- [ ] 90. next_smallest - nullable
Expand Down Expand Up @@ -122,7 +122,7 @@ Current status:
- [ ] 117. select_words - complex strings
- [x] 118. get_closest_vowel
- [ ] 119. match_parens
- [ ] 120. maximum - sorting
- [x] 120. maximum - sorting
- [x] 121. solution - sum
- [x] 122. add_elements
- [x] 123. get_odd_collatz - sorting
Expand All @@ -147,7 +147,7 @@ Current status:
- [x] 142. sum_squares
- [ ] 143. words_in_sentence - complex strings
- [ ] 144. simplify
- [ ] 145. order_by_points - sorting
- [x] 145. order_by_points - sorting
- [x] 146. specialFilter
- [ ] 147. get_max_triples
- [x] 148. bf
Expand Down
21 changes: 7 additions & 14 deletions REMAINING.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,58 +4,51 @@ Current status:

## Priority
- [ ] 25. factorize
- [ ] 36. fizz_buzz
- [ ] 147. get_max_triples

## Other

- [ ] 32. poly
- [ ] 38. encode_cyclic
- [ ] 44. change_base
- [ ] 47. median
- [ ] 65. circular_shift
- [ ] 79. decimal_to_binary
- [ ] 90. next_smallest - nullable
- [ ] 103. rounded_avg
- [ ] 107. even_odd_palindrome
- [ ] 111. histogram
- [ ] 113. odd_count
- [ ] 119. match_parens
- [ ] 124. valid_date
- [ ] 129. minPath
- [ ] 131. digits
- [ ] 132. is_nested
- [ ] 141. file_name_check
- [ ] 156. int_to_mini_roman
- [ ] 161. solve
- [ ] 162. string_to_md5 - needs hash


## Complex strings
## Strings
- [ ] 15. string_sequence
- [ ] 17. parse_music
- [ ] 18. how_many_times
- [ ] 19. sort_numbers
- [ ] 28. concatenate
- [ ] 44. change_base
- [ ] 56. correct_bracketing
- [ ] 61. correct_bracketing
- [ ] 67. fruit_distribution
- [ ] 86. anti_shuffle
- [ ] 91. is_bored
- [ ] 99. closest_integer
- [ ] 101. words_string
- [ ] 113. odd_count
- [ ] 117. select_words
- [ ] 125. split_words
- [ ] 140. fix_spaces
- [ ] 141. file_name_check
- [ ] 144. simplify
- [ ] 143. words_in_sentence
- [ ] 156. int_to_mini_roman
- [ ] 160. do_algebra
- [ ] 162. string_to_md5 - needs hash

## Ill-typed
- [ ] 22. filter_integers
- [ ] 137. compare_one

## Sorting
- [ ] 87. get_row - sorting
- [ ] 120. maximum - sorting
- [ ] 145. order_by_points - sorting
- [ ] 137. compare_one

0 comments on commit f13de1b

Please sign in to comment.