diff --git a/array/moon.pkg.json b/array/moon.pkg.json index e45419ab0..ab16d6b1e 100644 --- a/array/moon.pkg.json +++ b/array/moon.pkg.json @@ -1,5 +1,3 @@ { - "import": [ - "moonbitlang/core/assertion" - ] -} \ No newline at end of file + "import": ["moonbitlang/core/assertion", "moonbitlang/core/math"] +} diff --git a/array/slice.mbt b/array/slice.mbt new file mode 100644 index 000000000..4f970d9af --- /dev/null +++ b/array/slice.mbt @@ -0,0 +1,47 @@ +// Copyright 2024 International Digital Economy Academy +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +priv struct ArraySlice[T] { + array : Array[T] + start : Int + end : Int +} + +fn length[T](self : ArraySlice[T]) -> Int { + self.end - self.start +} + +fn op_get[T](self : ArraySlice[T], index : Int) -> T { + self.array[self.start + index] +} + +fn op_set[T](self : ArraySlice[T], index : Int, value : T) -> Unit { + self.array[self.start + index] = value +} + +fn swap[T](self : ArraySlice[T], a : Int, b : Int) -> Unit { + self.array.swap(self.start + a, self.start + b) +} + +fn reverse[T](self : ArraySlice[T]) -> Unit { + let mid_len = self.length() / 2 + for i = 0; i < mid_len; i = i + 1 { + let j = self.length() - i - 1 + self.swap(i, j) + } +} + +fn slice[T](self : ArraySlice[T], start : Int, end : Int) -> ArraySlice[T] { + { array: self.array, start: self.start + start, end: self.start + end } +} diff --git a/array/sort.mbt b/array/sort.mbt index 440d9a11a..351233f08 100644 --- a/array/sort.mbt +++ b/array/sort.mbt @@ -12,40 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -struct ArraySlice[T] { - array : Array[T] - start : Int - end : Int -} - -fn length[T](self : ArraySlice[T]) -> Int { - self.end - self.start -} - -fn op_get[T](self : ArraySlice[T], index : Int) -> T { - self.array[self.start + index] -} - -fn op_set[T](self : ArraySlice[T], index : Int, value : T) -> Unit { - self.array[self.start + index] = value -} - -fn swap[T](self : ArraySlice[T], a : Int, b : Int) -> Unit { - self.array.swap(self.start + a, self.start + b) -} - -fn reverse[T](self : ArraySlice[T]) -> Unit { - let mid_len = self.length() / 2 - for i = 0; i < mid_len; i = i + 1 { - let j = self.length() - i - 1 - self.swap(i, j) - } -} - -fn slice[T](self : ArraySlice[T], start : Int, end : Int) -> ArraySlice[T] { - { array: self.array, start: self.start + start, end: self.start + end } -} - /// Sorts the array /// /// It's an in-place, unstable sort(it will reorder equal elements). The time complexity is O(n log n) in the worst case. @@ -141,7 +107,7 @@ fn quick_sort[T]( } let (pivot, partitioned) = partition(arr, cmp, pivot_index) was_partitioned = partitioned - balanced = min(pivot, len - pivot) >= len / 8 + balanced = @math.minimum(pivot, len - pivot) >= len / 8 if not(balanced) { limit -= 1 } @@ -183,29 +149,22 @@ fn get_limit(len : Int) -> Int { limit } -fn min[T : Compare](a : T, b : T) -> T { - if a < b { - a - } else { - b - } -} - /// Try to sort the array with bubble sort. /// /// It will only tolerate at most 8 unsorted elements. The time complexity is O(n). /// /// Returns whether the array is sorted. -fn try_bubble_sort[T](arr : ArraySlice[T], cmp : (T, T) -> Int) -> Bool { - let max_tries = 8 +fn try_bubble_sort[T]( + arr : ArraySlice[T], + cmp : (T, T) -> Int, + ~max_tries : Int = 8 +) -> Bool { let mut tries = 0 for i = 1; i < arr.length(); i = i + 1 { - let mut j = i let mut sorted = true - while j > 0 && cmp(arr[j - 1], arr[j]) > 0 { + for j = i; j > 0 && cmp(arr[j - 1], arr[j]) > 0; j = j - 1 { sorted = false arr.swap(j, j - 1) - j = j - 1 } if not(sorted) { tries += 1 @@ -224,12 +183,8 @@ fn try_bubble_sort[T](arr : ArraySlice[T], cmp : (T, T) -> Int) -> Bool { /// Returns whether the array is sorted. fn bubble_sort[T](arr : ArraySlice[T], cmp : (T, T) -> Int) -> Unit { for i = 1; i < arr.length(); i = i + 1 { - let mut j = i - let mut sorted = true - while j > 0 && cmp(arr[j - 1], arr[j]) > 0 { - sorted = false + for j = i; j > 0 && cmp(arr[j - 1], arr[j]) > 0; j = j - 1 { arr.swap(j, j - 1) - j = j - 1 } } } diff --git a/priority_queue/priority_queue.mbt b/priority_queue/priority_queue.mbt index 97ea42f97..e2783e88a 100644 --- a/priority_queue/priority_queue.mbt +++ b/priority_queue/priority_queue.mbt @@ -12,22 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -struct Cont[T] { - content : T - mut sibling : Node[T] - mut child : Node[T] -} - -enum Node[T] { - Nil - Cons(Cont[T]) -} -struct PriorityQueue[T] { - min : Bool - mut len : Int - mut top : Node[T] -} /// Creates a new empty priority queue. /// @@ -66,11 +51,15 @@ pub fn PriorityQueue::from_array[T : Compare]( arr : Array[T], ~min : Bool = false ) -> PriorityQueue[T] { - for i = 0, acc = (Nil : Node[T]); i < arr.length(); { - continue i + 1, - meld(acc, Cons({ content: arr[i], sibling: Nil, child: Nil }), min) - } else { - { min, len: arr.length(), top: acc } + // CR: bad formatting + let len = arr.length() + for i = 0, acc = Node::Nil { + if i < len { + continue i + 1, + meld(acc, Cons({ content: arr[i], sibling: Nil, child: Nil }), min) + } else { + break { min, len, top: acc } + } } } @@ -84,11 +73,12 @@ fn meld[T : Compare](x : Node[T], y : Node[T], min : Bool) -> Node[T] { (Nil, _) => y (_, Nil) => x (Cons(x_top), Cons(y_top)) => - if if min { + // CR: bad formatting + if (if min { x_top.content < y_top.content } else { x_top.content > y_top.content - } { + }) { y_top.sibling = x_top.child x_top.child = y x @@ -277,10 +267,7 @@ test "clear" { /// let is_empty = queue.is_empty() // true /// ``` pub fn is_empty[T](self : PriorityQueue[T]) -> Bool { - match self.top { - Nil => true - _ => false - } + self.len == 0 } test "is_empty" { diff --git a/priority_queue/types.mbt b/priority_queue/types.mbt new file mode 100644 index 000000000..84f1df77b --- /dev/null +++ b/priority_queue/types.mbt @@ -0,0 +1,26 @@ +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +priv struct Cont[T] { + content : T + mut sibling : Node[T] + mut child : Node[T] +} + +priv enum Node[T] { + Nil + Cons(Cont[T]) +} + +struct PriorityQueue[T] { + min : Bool + mut len : Int + mut top : Node[T] +} diff --git a/vec/vec.mbt b/vec/vec.mbt index 0f8dc366d..ac5ef1335 100644 --- a/vec/vec.mbt +++ b/vec/vec.mbt @@ -35,13 +35,12 @@ pub fn to_string[T : Show](self : Vec[T]) -> String { return "Vec::[]" } let first = self.buf[0] - for i = 1, init = "Vec::[\(first)"; ; { - if i < self.len { - let cur = self.buf[i] - continue i + 1, "\(init),\(cur)" - } else { + for i = 1, init = "Vec::[\(first)" { + if i >= self.len { break "\(init)]" } + let cur = self.buf[i] + continue i + 1, "\(init),\(cur)" } }