Skip to content

Commit

Permalink
120, 145 (#26)
Browse files Browse the repository at this point in the history
  • Loading branch information
WeetHet authored Aug 20, 2024
1 parent 5035c18 commit fe55003
Show file tree
Hide file tree
Showing 2 changed files with 104 additions and 0 deletions.
62 changes: 62 additions & 0 deletions 120-maximum.dfy
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
method maximum(s: seq<int>, k: int) returns (result: seq<int>)
requires 1 <= k <= |s|
requires 1 <= |s| <= 1000
requires forall x :: x in s ==> -1000 <= x <= 1000
ensures |result| == k
ensures forall i, j :: 0 <= i < j < k ==> result[i] <= result[j]
ensures forall x :: x in result ==> x in s
{
var sorted := SortSeq(s);
assert forall x :: x in sorted ==> x in s;

result := sorted[|s| - k..];

// I can't make this a postcondition because it relies on an internal variable
assert forall i, j :: 0 <= i < |s| - k && 0 <= j < k ==> sorted[i] <= result[j];
}

method SortSeq(s: seq<int>) returns (sorted: seq<int>)
ensures forall i, j :: 0 <= i < j < |sorted| ==> sorted[i] <= sorted[j]
ensures |sorted| == |s|
ensures multiset(s) == multiset(sorted)
ensures forall i :: 0 <= i < |s| ==> exists j :: 0 <= j < |sorted| && s[i] == sorted[j]
ensures forall x :: x in s ==> x in sorted
ensures forall i :: 0 <= i < |s| ==> exists j :: 0 <= j < |sorted| && sorted[i] == s[j]
ensures forall x :: x in sorted ==> x in s
{
sorted := s;
var i := 0;
while i < |sorted|
invariant 0 <= i <= |sorted|
invariant forall j, k :: 0 <= j < k < i ==> sorted[j] <= sorted[k]
invariant multiset(s) == multiset(sorted)
invariant forall j :: 0 <= j < i ==> forall k :: i <= k < |sorted| ==> sorted[j] <= sorted[k]
invariant |sorted| == |s|
{
var minIndex := i;
var j := i + 1;
while j < |sorted|
invariant i <= minIndex < j <= |sorted|
invariant forall k :: i <= k < j ==> sorted[minIndex] <= sorted[k]
{
if 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;
}

assert forall i :: 0 <= i < |s| ==> exists j :: 0 <= j < |sorted| && s[i] == sorted[j] by {
assert forall i :: 0 <= i < |s| ==> s[i] in multiset(sorted);
}
assert forall x :: x in s ==> x in sorted;
assert forall i :: 0 <= i < |s| ==> exists j :: 0 <= j < |sorted| && sorted[i] == s[j] by {
assert forall i :: 0 <= i < |s| ==> sorted[i] in multiset(s);
}
assert forall x :: x in sorted ==> x in s;
}
42 changes: 42 additions & 0 deletions 145-order_by_points.dfy
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
function digits_sum_pos(n: int): int
requires n >= 0
{
if n < 10 then n else digits_sum_pos(n / 10) + n % 10
}

function digits_sum(n: int): int {
if n < 0 then digits_sum_pos(-n) else digits_sum_pos(n)
}

method order_by_points(s: seq<int>) returns (sorted: seq<int>)
ensures forall i, j :: 0 <= i < j < |sorted| ==> digits_sum(sorted[i]) <= digits_sum(sorted[j])
ensures |sorted| == |s|
ensures multiset(s) == multiset(sorted)
{
sorted := s;
var i := 0;
while i < |sorted|
invariant 0 <= i <= |sorted|
invariant forall j, k :: 0 <= j < k < i ==> digits_sum(sorted[j]) <= digits_sum(sorted[k])
invariant multiset(s) == multiset(sorted)
invariant forall j :: 0 <= j < i ==> forall k :: i <= k < |sorted| ==> digits_sum(sorted[j]) <= digits_sum(sorted[k])
invariant |sorted| == |s|
{
var minIndex := i;
var j := i + 1;
while j < |sorted|
invariant i <= minIndex < j <= |sorted|
invariant forall k :: i <= k < j ==> digits_sum(sorted[minIndex]) <= digits_sum(sorted[k])
{
if digits_sum(sorted[j]) < digits_sum(sorted[minIndex]) {
minIndex := j;
}
j := j + 1;
}
if minIndex != i {
var temp := sorted[i];
sorted := sorted[i := sorted[minIndex]][minIndex := temp];
}
i := i + 1;
}
}

0 comments on commit fe55003

Please sign in to comment.