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..9471aa1f8 --- /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. + +struct ArraySlice[T] { + array : Array[T] + start : Int + end : Int +} + +pub fn length[T](self : ArraySlice[T]) -> Int { + self.end - self.start +} + +pub fn op_get[T](self : ArraySlice[T], index : Int) -> T { + self.array[self.start + index] +} + +pub fn op_set[T](self : ArraySlice[T], index : Int, value : T) -> Unit { + self.array[self.start + index] = value +} + +pub fn swap[T](self : ArraySlice[T], a : Int, b : Int) -> Unit { + self.array.swap(self.start + a, self.start + b) +} + +pub 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) + } +} + +pub 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..eb5682b3a 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 } @@ -177,35 +143,28 @@ fn get_limit(len : Int) -> Int { let mut len = len let mut limit = 0 while len > 0 { - len = len / 2 + len = len.land(len - 1) limit += 1 } 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 } } }