diff --git a/060-sum_to_n.dfy b/060-sum_to_n.dfy new file mode 100644 index 0000000..63568d5 --- /dev/null +++ b/060-sum_to_n.dfy @@ -0,0 +1,40 @@ +function sum(s: seq) : int + { + if |s| == 0 then 0 else s[0] + sum(s[1..]) + } + +lemma sum_prop(s: seq) + 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]; + } +} + +function number_seq(n: int) : (r : seq) + requires n >= 0 + ensures |r| == n + { + seq(n, i => i + 1) + } + +method sum_squares(n: int) returns (r : int) + requires n >= 1 + ensures r == sum(number_seq(n)) + { + r := 0; + var k := 0; + ghost var v := number_seq(n); + while(k < n) + invariant 0 <= k <= |v| + invariant r == sum(v[..k]) + { + assert v[..k + 1][..k] == v[..k]; + r := r + (k + 1); + k := k + 1; + assert sum(v[..k]) == r by { sum_prop(v[..k]); } + } + assert v[..k] == v; + return r; + } \ No newline at end of file diff --git a/085-add.dfy b/085-add.dfy new file mode 100644 index 0000000..c5cee80 --- /dev/null +++ b/085-add.dfy @@ -0,0 +1,45 @@ +function sumc(s: seq, p: seq) : int + requires |s| == |p| + { + if |s| == 0 then 0 else (if p[0] then s[0] else 0) + sumc(s[1..], p[1..]) + } + +lemma sum_prop(s: seq, p: seq) + requires |s| > 0 + requires |s| == |p| + ensures sumc(s, p) == sumc(s[..|s| - 1], p[..|s| - 1]) + (if p[ |s| - 1 ] then s[ |s| - 1 ] else 0) +{ + if (|s| > 1) { + assert (s[1..][..|s[1..]| - 1]) == s[1..|s| - 1]; + assert (p[1..][..|s[1..]| - 1]) == p[1..|s| - 1]; + } +} + +function add_conditon(lst: seq) : (p : seq) + ensures |lst| == |p| + { + seq(|lst|, i requires 0 <= i < |lst| => i % 2 == 1 && lst[i] % 2 == 0) + } + +method add(v: seq) returns (r : int) + ensures r == sumc(v, add_conditon(v)) + { + r := 0; + var k := 0; + var p := add_conditon(v); + while(k < |v|) + invariant 0 <= k <= |v| + invariant r == sumc(v[..k], p[..k]) + { + assert v[..k + 1][..k] == v[..k]; + assert p[..k + 1][..k] == p[..k]; + r := r + if p[k] then v[k] else 0; + k := k + 1; + assert sumc(v[..k], p[..k]) == r by { + sum_prop(v[..k], p[..k]); + } + } + assert v[..k] == v; + assert p[..k] == p; + return r; + } \ No newline at end of file diff --git a/133-sum_squares.dfy b/133-sum_squares.dfy new file mode 100644 index 0000000..5fcd025 --- /dev/null +++ b/133-sum_squares.dfy @@ -0,0 +1,43 @@ +function sum(s: seq) : int + { + if |s| == 0 then 0 else s[0] + sum(s[1..]) + } + +lemma sum_prop(s: seq) + 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]; + } +} + +function ceil(f: real) : (c : int) + { + (f + 1.0).Floor + } + +function square_seq(lst: seq) : (sq : seq) + ensures |sq| == |lst| + { + seq(|lst|, i requires 0 <= i < |lst| => ceil(lst[i]) * ceil(lst[i])) + } + +method sum_squares(lst: seq) returns (r : int) + ensures r == sum(square_seq(lst)) + { + r := 0; + var k := 0; + var v := square_seq(lst); + while(k < |lst|) + invariant 0 <= k <= |lst| + invariant r == sum(v[..k]) + { + assert v[..k + 1][..k] == v[..k]; + r := r + v[k]; + k := k + 1; + assert sum(v[..k]) == r by { sum_prop(v[..k]); } + } + assert v[..k] == v; + return r; + } \ No newline at end of file diff --git a/142-sum_squares.dfy b/142-sum_squares.dfy index 3279e79..398cde1 100644 --- a/142-sum_squares.dfy +++ b/142-sum_squares.dfy @@ -1,23 +1,38 @@ -method sum_squares(a : seq) returns (result : seq) - ensures |result| == |a| - ensures forall i : int :: i >= 0 && i < |result| && i % 3 == 0 ==> result[i] == a[i] * a[i] - ensures forall i : int :: i >= 0 && i < |result| && i % 4 == 0 && i % 3 != 0 ==> result[i] == a[i] * a[i] * a[i] +function sum(s: seq) : int + { + if |s| == 0 then 0 else s[0] + sum(s[1..]) + } + +lemma sum_prop(s: seq) + requires |s| > 0 + ensures sum(s) == sum(s[..|s| - 1]) + s[ |s| - 1 ] { - result := []; - var i := 0; - while i < |a| - invariant i >= 0 && i <= |a| - invariant |result| == i - invariant forall j : int :: j >= 0 && j < |result| && j % 3 == 0 ==> result[j] == a[j] * a[j] - invariant forall j : int :: j >= 0 && j < |result| && j % 4 == 0 && j % 3 != 0 ==> result[j] == a[j] * a[j] * a[j] - { - if i % 3 == 0 { - result := result + [a[i] * a[i]]; - } else if i % 4 == 0 && i % 3 != 0 { - result := result + [a[i] * a[i] * a[i]]; - } else { - result := result + [a[i]]; + if (|s| > 1) { + assert (s[1..][..|s[1..]| - 1]) == s[1..|s| - 1]; } - i := i + 1; - } } + +function square_seq(lst: seq) : (sq : seq) + ensures |sq| == |lst| + { + seq(|lst|, i requires 0 <= i < |lst| => if i % 3 == 0 then lst[i] * lst[i] else (if i % 4 == 0 then lst[i] * lst[i] * lst[i] else lst[i])) + } + +method sum_squares(lst: seq) returns (r : int) + ensures r == sum(square_seq(lst)) + { + r := 0; + var k := 0; + var v := square_seq(lst); + while(k < |lst|) + invariant 0 <= k <= |lst| + invariant r == sum(v[..k]) + { + assert v[..k + 1][..k] == v[..k]; + r := r + v[k]; + k := k + 1; + assert sum(v[..k]) == r by { sum_prop(v[..k]); } + } + assert v[..k] == v; + return r; + } \ No newline at end of file diff --git a/151-double_the_difference.dfy b/151-double_the_difference.dfy new file mode 100644 index 0000000..7dc93e7 --- /dev/null +++ b/151-double_the_difference.dfy @@ -0,0 +1,53 @@ +function sumc(s: seq, p: seq) : int + requires |s| == |p| + { + if |s| == 0 then 0 else (if p[0] then s[0] else 0) + sumc(s[1..], p[1..]) + } + +lemma sum_prop(s: seq, p: seq) + requires |s| > 0 + requires |s| == |p| + ensures sumc(s, p) == sumc(s[..|s| - 1], p[..|s| - 1]) + (if p[ |s| - 1 ] then s[ |s| - 1 ] else 0) +{ + if (|s| > 1) { + assert (s[1..][..|s[1..]| - 1]) == s[1..|s| - 1]; + assert (p[1..][..|s[1..]| - 1]) == p[1..|s| - 1]; + } +} + +function add_conditon(lst: seq) : (p : seq) + ensures |lst| == |p| + { + seq(|lst|, i requires 0 <= i < |lst| => lst[i] >= 0 && lst[i] % 2 == 1) + } + +function square_seq(lst: seq) : (sq : seq) + ensures |sq| == |lst| + ensures forall i :: 0 <= i < |lst| ==> sq[i] == lst[i] * lst[i] + { + seq(|lst|, i requires 0 <= i < |lst| => lst[i] * lst[i]) + } + +method double_the_difference(lst: seq) returns (r : int) + ensures r == sumc(square_seq(lst), add_conditon(lst)) + { + r := 0; + var k := 0; + var v := square_seq(lst); + var p := add_conditon(lst); + while(k < |lst|) + invariant 0 <= k <= |lst| + invariant r == sumc(v[..k], p[..k]) + { + assert v[..k + 1][..k] == v[..k]; + assert p[..k + 1][..k] == p[..k]; + r := r + if p[k] then v[k] else 0; + k := k + 1; + assert sumc(v[..k], p[..k]) == r by { + sum_prop(v[..k], p[..k]); + } + } + assert v[..k] == v; + assert p[..k] == p; + return r; + } \ No newline at end of file diff --git a/README.md b/README.md index 270a212..9c85065 100644 --- a/README.md +++ b/README.md @@ -10,11 +10,7 @@ Current status: - [x] 5. intersperse - [x] 6. parse_nested_parens - [x] 7. filter_by_substring -<<<<<<< HEAD - [x] 8. sum_product -======= -- [*] 8. sum_product ->>>>>>> 8f13a4d (2, 3, 8, 20, 21, 23, 24) - [x] 9. rolling_max - [x] 10. is_palindrome - [x] 11. string_xor @@ -66,7 +62,7 @@ Current status: - [ ] 57. monotonic - [x] 58. common - [x] 59. largest_prime_factor -- [ ] 60. sum_to_n +- [x] 60. sum_to_n - [ ] 61. correct_bracketing - [ ] 62. derivative - [ ] 63. fibfib @@ -91,7 +87,7 @@ Current status: - [ ] 82. prime_length - [ ] 83. starts_one_ends - [ ] 84. solve -- [ ] 85. add +- [x] 85. add - [ ] 86. anti_shuffle - [ ] 87. get_row - [ ] 88. sort_array @@ -139,7 +135,7 @@ Current status: - [x] 130. tri - [ ] 131. digits - [ ] 132. is_nested -- [ ] 133. sum_squares +- [x] 133. sum_squares - [ ] 134. check_if_last_char_is_a_letter - [ ] 135. can_arrange - [ ] 136. largest_smallest_integers @@ -148,7 +144,7 @@ Current status: - [x] 139. special_factorial - [ ] 140. fix_spaces - [ ] 141. file_name_check -- [ ] 142. sum_squares +- [x] 142. sum_squares - [ ] 143. words_in_sentence - [ ] 144. simplify - [ ] 145. order_by_points @@ -157,7 +153,7 @@ Current status: - [x] 148. bf - [ ] 149. sorted_list_sum - [x] 150. x_or_y -- [ ] 151. double_the_difference +- [x] 151. double_the_difference - [x] 152. compare - [x] 153. Strongest_Extension - [x] 154. cycpattern_check