Skip to content

Commit

Permalink
050, 093, 109, 112, 121
Browse files Browse the repository at this point in the history
  • Loading branch information
WeetHet committed Aug 28, 2024
1 parent 719cde8 commit 8b9e581
Show file tree
Hide file tree
Showing 7 changed files with 260 additions and 16 deletions.
48 changes: 48 additions & 0 deletions 050-encode_shift.dfy
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
function encode_char(c: char): char
requires 'a' <= c <= 'z'
ensures 'a' <= encode_char(c) <= 'z'
{
((c as int - 'a' as int + 5) % 26 + 'a' as int) as char
}

function decode_char(c: char): char
requires 'a' <= c <= 'z'
ensures 'a' <= decode_char(c) <= 'z'
ensures encode_char(decode_char(c)) == c
{
((c as int - 'a' as int - 5) % 26 + 'a' as int) as char
}

method encode_shift(s: string) returns (t: string)
requires forall i :: 0 <= i < |s| ==> 'a' <= s[i] <= 'z'
ensures |s| == |t|
ensures forall i :: 0 <= i < |s| ==> t[i] == encode_char(s[i])
{
t := "";
var i := 0;
while i < |s|
invariant 0 <= i <= |s|
invariant |t| == i
invariant forall j :: 0 <= j < i ==> t[j] == encode_char(s[j])
{
t := t + [encode_char(s[i])];
i := i + 1;
}
}

method decode_shift(s: string) returns (t: string)
requires forall i :: 0 <= i < |s| ==> 'a' <= s[i] <= 'z'
ensures |s| == |t|
ensures forall i :: 0 <= i < |s| ==> t[i] == decode_char(s[i])
{
t := "";
var i := 0;
while i < |s|
invariant 0 <= i <= |s|
invariant |t| == i
invariant forall j :: 0 <= j < i ==> t[j] == decode_char(s[j])
{
t := t + [decode_char(s[i])];
i := i + 1;
}
}
45 changes: 45 additions & 0 deletions 093-encode.dfy
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
method encode(s: string) returns (t: string)
requires forall i :: 0 <= i < |s| ==> 'a' <= s[i] <= 'z' || 'A' <= s[i] <= 'Z'
ensures |s| == |t|
ensures forall i :: 0 <= i < |s| && is_vowel(s[i]) ==> t[i] == rot2(swap_case(s[i]))
ensures forall i :: 0 <= i < |s| && !is_vowel(s[i]) ==> t[i] == swap_case(s[i])
{
t := "";
var i := 0;
while i < |s|
invariant 0 <= i <= |s|
invariant |t| == i
invariant forall j :: 0 <= j < i && is_vowel(s[j]) ==> t[j] == rot2(swap_case(s[j]))
invariant forall j :: 0 <= j < i && !is_vowel(s[j]) ==> t[j] == swap_case(s[j])
{
if is_vowel(s[i]) {
t := t + [rot2(swap_case(s[i]))];
} else {
t := t + [swap_case(s[i])];
}
i := i + 1;
}
}

function swap_case(c: char): char
requires 'a' <= c <= 'z' || 'A' <= c <= 'Z'
ensures 'a' <= c <= 'z' ==> 'A' <= swap_case(c) <= 'Z'
ensures 'A' <= c <= 'Z' ==> 'a' <= swap_case(c) <= 'z'
ensures is_vowel(swap_case(c)) == is_vowel(c)
{
if 'a' <= c <= 'z' then
'A' + (c - 'a')
else
'a' + (c - 'A')
}

function rot2(c: char): char
requires is_vowel(c)
{
(c as int + 2) as char
}

predicate is_vowel(c: char) {
(c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u')
|| (c == 'A' || c == 'E' || c == 'I' || c == 'O' || c == 'U')
}
53 changes: 53 additions & 0 deletions 109-move_one_ball.dfy
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
predicate is_sorted(a: seq<int>) {
forall i, j :: 0 <= i < j < |a| ==> a[i] <= a[j]
}

method move_one_ball(a: seq<int>) returns (can: bool)
requires |a| > 0
requires forall i, j :: 0 <= i < |a| && 0 <= j < |a| && i != j ==> a[i] != a[j]
ensures can <==> exists i :: 0 <= i < |a| && is_sorted(a[i..] + a[..i])
{
if |a| <= 1 {
assert is_sorted(a[..0]);
return true;
}
can := false;
var i := 0;
var min_index := 0;
while i < |a|
invariant 0 <= i <= |a|
invariant 0 <= min_index < |a|
invariant forall j :: 0 <= j < i && min_index != j ==> a[min_index] < a[j]
{
if a[i] < a[min_index] {
min_index := i;
}
i := i + 1;
}

assert forall j :: (
0 <= j < |a| && min_index != j
==> (
(forall i :: j <= i < |a| ==> a[j..][i - j] == a[i])
&& (forall i :: 0 <= i < j ==> (a[j..] + a[..j])[|a| - j + i] == a[i])
&& (
if min_index < j then
(a[j..] + a[..j])[|a| - j + min_index] == a[min_index]
else
(a[j..] + a[..j])[min_index - j] == a[min_index]
)
&& (
(exists p :: (
1 <= p < |a[j..] + a[..j]|
&& (a[j..] + a[..j])[p] == a[min_index]
&& (a[j..] + a[..j])[0] > (a[j..] + a[..j])[p]
)) ==> !is_sorted(a[j..] + a[..j])
)
)
);

assert forall j :: 0 <= j < |a| && min_index != j ==> !is_sorted(a[j..] + a[..j]);

var new_a := a[min_index..] + a[..min_index];
can := is_sorted(new_a);
}
50 changes: 50 additions & 0 deletions 112-reverse_delete.dfy
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
method reverse_delete(s: string, chars: string) returns (res: string, is_palindrome: bool)
ensures forall i :: 0 <= i < |res| ==> res[i] !in chars
ensures forall i :: 0 <= i < |res| ==> res[i] in s
ensures forall i :: 0 <= i < |s| && s[i] !in chars ==> s[i] in res
ensures is_palindrome <==> is_palindrome_pred(res)
{
res := "";
var i := 0;
while i < |s|
invariant 0 <= i <= |s|
invariant forall i :: 0 <= i < |res| ==> res[i] !in chars
invariant forall i :: 0 <= i < |res| ==> res[i] in s
invariant forall j :: 0 <= j < i && s[j] !in chars ==> s[j] in res
{
if s[i] !in chars {
res := res + [s[i]];
}
i := i + 1;
}

is_palindrome := check_palindrome(res);
}

method check_palindrome(s: string) returns (result: bool)
ensures result <==> is_palindrome_pred(s)
{
if |s| == 0 {
return true;
}
result := true;
var i := 0;
var j := |s| - 1;
while (i < j)
invariant 0 <= i < |s|
invariant 0 <= j < |s|
invariant j == |s| - i - 1
invariant forall k :: 0 <= k < i ==> s[k] == s[|s| - 1 - k]
{
if (s[i] != s[j]) {
result := false;
break;
}
i := i + 1;
j := j - 1;
}
}

predicate is_palindrome_pred(s : string) {
forall k :: 0 <= k < |s| ==> s[k] == s[|s| - 1 - k]
}
49 changes: 49 additions & 0 deletions 121-solution.dfy
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
method solution(numbers: seq<int>) returns (s: int)
ensures s == sum(numbers, seq(|numbers|, i requires 0 <= i < |numbers| => i % 2 == 0 && numbers[i] % 2 == 1))
{
var i := 0;
s := 0;
ghost var p := [];
while i < |numbers|
invariant 0 <= i <= |numbers|
invariant |p| == i
invariant s == sum(numbers[..i], p[..i])
invariant p == seq(i, j requires 0 <= j < i => j % 2 == 0 && numbers[j] % 2 == 1)
{
ghost var old_p := p;
p := p + [i % 2 == 0 && numbers[i] % 2 == 1];

assert sum(numbers[..i], p[..i]) == sum(numbers[..i], old_p[..i]) by {
assert p[..i] == old_p[..i];
}
assert sum(numbers[..i + 1], p[..i + 1]) == sum(numbers[..i], p[..i]) + (if p[i] then numbers[i] else 0) by {
assert numbers[..i+1][..i] == numbers[..i];
assert p[..i + 1][..i] == p[..i] by {
assert forall j :: 0 <= j < i ==> p[..i + 1][j] == p[..i][j];
}
sum_prop(numbers[..i + 1], p[..i + 1]);
}
s := s + (if i % 2 == 0 && numbers[i] % 2 == 1 then numbers[i] else 0);

i := i + 1;
}
assert numbers[..|numbers|] == numbers;
assert p[..|p|] == p;
}

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

lemma sum_prop(s: seq<int>, p: seq<bool>)
requires |s| > 0
requires |p| == |s|
ensures sum(s, p) == sum(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..][..|p[1..]| - 1]) == p[1..|p| - 1];
}
}
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ Current status:
- [ ] 47. median
- [x] 48. is_palindrome
- [x] 49. modp
- [ ] 50. encode_shift
- [x] 50. encode_shift
- [x] 51. remove_vowels
- [x] 52. below_threshold
- [x] 53. add
Expand Down Expand Up @@ -95,7 +95,7 @@ Current status:
- [ ] 90. next_smallest - nullable
- [ ] 91. is_bored - complex strings
- [x] 92. any_int
- [ ] 93. encode
- [x] 93. encode
- [x] 94. skjkasdkd
- [x] 95. check_dict_case
- [x] 96. count_up_to
Expand All @@ -111,19 +111,19 @@ Current status:
- [x] 106. f
- [ ] 107. even_odd_palindrome
- [x] 108. count_nums
- [ ] 109. move_one_ball
- [x] 109. move_one_ball
- [x] 110. exchange
- [ ] 111. histogram
- [ ] 112. reverse_delete
- [x] 112. reverse_delete
- [ ] 113. odd_count
- [ ] 114. minSubArraySum
- [x] 114. minSubArraySum
- [x] 115. max_fill
- [x] 116. sort_array - sorting
- [ ] 117. select_words - complex strings
- [x] 118. get_closest_vowel
- [ ] 119. match_parens
- [ ] 120. maximum - sorting
- [ ] 121. solution - sum
- [x] 121. solution - sum
- [x] 122. add_elements
- [x] 123. get_odd_collatz - sorting
- [ ] 124. valid_date
Expand Down
19 changes: 9 additions & 10 deletions REMAINING.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,25 @@

Current status:

## Priority
- [ ] 25. factorize
- [ ] 28. concatenate
- [ ] 32. poly
- [ ] 36. fizz_buzz

## Other

- [ ] 32. poly
- [ ] 38. encode_cyclic
- [ ] 44. change_base
- [ ] 47. median
- [ ] 50. encode_shift
- [ ] 56. correct_bracketing
- [ ] 61. correct_bracketing
- [ ] 65. circular_shift
- [ ] 79. decimal_to_binary
- [ ] 84. solve
- [ ] 90. next_smallest - nullable
- [ ] 93. encode
- [ ] 103. rounded_avg
- [ ] 107. even_odd_palindrome
- [ ] 109. move_one_ball
- [ ] 111. histogram
- [ ] 112. reverse_delete
- [ ] 113. odd_count
- [ ] 114. minSubArraySum
- [ ] 119. match_parens
- [ ] 121. solution - sum
- [ ] 124. valid_date
- [ ] 129. minPath
- [ ] 131. digits
Expand All @@ -38,11 +33,15 @@ Current status:
- [ ] 161. solve
- [ ] 162. string_to_md5 - needs hash


## Complex strings
- [ ] 15. string_sequence
- [ ] 17. parse_music
- [ ] 18. how_many_times
- [ ] 19. sort_numbers
- [ ] 28. concatenate
- [ ] 56. correct_bracketing
- [ ] 61. correct_bracketing
- [ ] 67. fruit_distribution
- [ ] 86. anti_shuffle
- [ ] 91. is_bored
Expand Down

0 comments on commit 8b9e581

Please sign in to comment.