From 9903fc95bb8a0a2828cb23aeedc845741291c211 Mon Sep 17 00:00:00 2001 From: Lampese Date: Mon, 25 Mar 2024 14:14:40 +0800 Subject: [PATCH 1/7] reafactor: refactor some function in sort and separate file for slice --- array/moon.pkg.json | 6 ++--- array/slice.mbt | 47 +++++++++++++++++++++++++++++++++ array/sort.mbt | 63 +++++++-------------------------------------- 3 files changed, 58 insertions(+), 58 deletions(-) create mode 100644 array/slice.mbt 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 } } } From 904cc9fa6b3ae13582a392ed7d03fd680d6d3b24 Mon Sep 17 00:00:00 2001 From: Lampese Date: Mon, 25 Mar 2024 14:41:33 +0800 Subject: [PATCH 2/7] perf: use div --- array/sort.mbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/array/sort.mbt b/array/sort.mbt index eb5682b3a..351233f08 100644 --- a/array/sort.mbt +++ b/array/sort.mbt @@ -143,7 +143,7 @@ fn get_limit(len : Int) -> Int { let mut len = len let mut limit = 0 while len > 0 { - len = len.land(len - 1) + len = len / 2 limit += 1 } limit From 37e08f52d28c5349dce4095f3b5403aaae4401e1 Mon Sep 17 00:00:00 2001 From: Lampese Date: Mon, 25 Mar 2024 15:12:00 +0800 Subject: [PATCH 3/7] refactor: private ArraySlice --- array/slice.mbt | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/array/slice.mbt b/array/slice.mbt index 9471aa1f8..4f970d9af 100644 --- a/array/slice.mbt +++ b/array/slice.mbt @@ -12,29 +12,29 @@ // See the License for the specific language governing permissions and // limitations under the License. -struct ArraySlice[T] { +priv struct ArraySlice[T] { array : Array[T] start : Int end : Int } -pub fn length[T](self : ArraySlice[T]) -> Int { +fn length[T](self : ArraySlice[T]) -> Int { self.end - self.start } -pub fn op_get[T](self : ArraySlice[T], index : Int) -> T { +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 { +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 { +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 { +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 @@ -42,6 +42,6 @@ pub fn reverse[T](self : ArraySlice[T]) -> Unit { } } -pub fn slice[T](self : ArraySlice[T], start : Int, end : Int) -> ArraySlice[T] { +fn slice[T](self : ArraySlice[T], start : Int, end : Int) -> ArraySlice[T] { { array: self.array, start: self.start + start, end: self.start + end } } From bbd1092865c54fc84430d9a265a61c6899e92665 Mon Sep 17 00:00:00 2001 From: "bob.hongbo.zhang" Date: Sun, 24 Mar 2024 19:59:51 +0800 Subject: [PATCH 4/7] tweak from_array --- priority_queue/priority_queue.mbt | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/priority_queue/priority_queue.mbt b/priority_queue/priority_queue.mbt index 97ea42f97..0fef740c4 100644 --- a/priority_queue/priority_queue.mbt +++ b/priority_queue/priority_queue.mbt @@ -66,11 +66,13 @@ 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 } + for i = 0, acc = Node::Nil { + if i < arr.length() { + continue i + 1, + meld(acc, Cons({ content: arr[i], sibling: Nil, child: Nil }), min) + } else { + break { min, len: arr.length(), top: acc } + } } } From 3436b23db3df586226afb3625b55635f75f8c223 Mon Sep 17 00:00:00 2001 From: "bob.hongbo.zhang" Date: Sun, 24 Mar 2024 20:06:02 +0800 Subject: [PATCH 5/7] split types into a separate file and export less --- priority_queue/priority_queue.mbt | 15 --------------- priority_queue/types.mbt | 26 ++++++++++++++++++++++++++ 2 files changed, 26 insertions(+), 15 deletions(-) create mode 100644 priority_queue/types.mbt diff --git a/priority_queue/priority_queue.mbt b/priority_queue/priority_queue.mbt index 0fef740c4..387e2b81f 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. /// diff --git a/priority_queue/types.mbt b/priority_queue/types.mbt new file mode 100644 index 000000000..91278f331 --- /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] +} \ No newline at end of file From 34b23175f05b2494333ce85152ca89cf23d69510 Mon Sep 17 00:00:00 2001 From: "bob.hongbo.zhang" Date: Sun, 24 Mar 2024 20:12:57 +0800 Subject: [PATCH 6/7] tweak --- priority_queue/priority_queue.mbt | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/priority_queue/priority_queue.mbt b/priority_queue/priority_queue.mbt index 387e2b81f..38b65968e 100644 --- a/priority_queue/priority_queue.mbt +++ b/priority_queue/priority_queue.mbt @@ -51,12 +51,14 @@ pub fn PriorityQueue::from_array[T : Compare]( arr : Array[T], ~min : Bool = false ) -> PriorityQueue[T] { + // CR: bad formatting + let len = arr.length() for i = 0, acc = Node::Nil { - if i < arr.length() { + if i < len { continue i + 1, meld(acc, Cons({ content: arr[i], sibling: Nil, child: Nil }), min) } else { - break { min, len: arr.length(), top: acc } + break { min, len, top: acc } } } } @@ -71,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 @@ -264,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" { From 605f4a57da61bd7ea06acdcf734296f1bbe00a78 Mon Sep 17 00:00:00 2001 From: HongboZhang Date: Mon, 25 Mar 2024 23:10:42 +0800 Subject: [PATCH 7/7] Fix formatting in priority_queue.mbt and vec.mbt --- priority_queue/priority_queue.mbt | 2 +- priority_queue/types.mbt | 2 +- vec/vec.mbt | 9 ++++----- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/priority_queue/priority_queue.mbt b/priority_queue/priority_queue.mbt index 38b65968e..e2783e88a 100644 --- a/priority_queue/priority_queue.mbt +++ b/priority_queue/priority_queue.mbt @@ -267,7 +267,7 @@ test "clear" { /// let is_empty = queue.is_empty() // true /// ``` pub fn is_empty[T](self : PriorityQueue[T]) -> Bool { - self.len == 0 + self.len == 0 } test "is_empty" { diff --git a/priority_queue/types.mbt b/priority_queue/types.mbt index 91278f331..84f1df77b 100644 --- a/priority_queue/types.mbt +++ b/priority_queue/types.mbt @@ -23,4 +23,4 @@ struct PriorityQueue[T] { min : Bool mut len : Int mut top : Node[T] -} \ No newline at end of file +} 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)" } }