Skip to content

Commit

Permalink
reafactor: refactor some function in sort and separate file for slice
Browse files Browse the repository at this point in the history
  • Loading branch information
Lampese committed Mar 25, 2024
1 parent 6036fcb commit 4fcb832
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 58 deletions.
6 changes: 2 additions & 4 deletions array/moon.pkg.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
{
"import": [
"moonbitlang/core/assertion"
]
}
"import": ["moonbitlang/core/assertion", "moonbitlang/core/math"]
}
47 changes: 47 additions & 0 deletions array/slice.mbt
Original file line number Diff line number Diff line change
@@ -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 }
}
63 changes: 9 additions & 54 deletions array/sort.mbt
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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
}
Expand Down Expand Up @@ -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
Expand All @@ -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
}
}
}
Expand Down

0 comments on commit 4fcb832

Please sign in to comment.