Skip to content

Commit

Permalink
Merge pull request #84 from moonbitlang/update_examples
Browse files Browse the repository at this point in the history
Update examples for new print and println
  • Loading branch information
liweijian authored Sep 20, 2023
2 parents 979ae38 + 9173f0b commit 8b90a0d
Show file tree
Hide file tree
Showing 11 changed files with 67 additions and 150 deletions.
144 changes: 44 additions & 100 deletions examples/avl_tree/lib/avl.mbt
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
// https://en.wikipedia.org/wiki/AVL_tree
// https://zhuanlan.zhihu.com/p/430867594

// Empty represents an empty node in the AVL tree
Expand All @@ -8,47 +7,32 @@ pub enum T[U] {
Node (T[U], U, T[U], Int)
}

/// Calculate the height of a tree-like structure using pattern matching.
/// `height[U](self: T[U])`
///
/// This function calculates the height of a tree-like structure represented by the
/// user-defined enum 'T[U]' using pattern matching. The height of an empty tree is 0,
/// and the height of a non-empty tree node is determined by its stored height value.
///
/// @param {T[U]} self - A user-defined enum representing the tree-like structure.
/// @return {Int} The height of the tree-like structure.
/// Calculate the height of a tree-like structure.
pub func height[U](self: T[U]) -> Int {
match self {
Empty => 0
Node(_, _, _, h) => h
}
}

/// Create a new node with the given left and right subtrees, along with a value of type 'U'.
///
/// This function constructs a new node of the user-defined enum type 'T[U]' using the provided left subtree 'l',
/// value 'v', and right subtree 'r'. The height of the node is determined by the maximum height between
/// the left and right subtrees, incremented by one.
/// `create[U](l: T[U], v: U, r: T[U])`
///
/// @param {T[U]} l - The left subtree of the node.
/// @param {U} v - The value to be stored in the node.
/// @param {T[U]} r - The right subtree of the node.
/// @return {T[U]} - A new node of type 'T[U]' with the specified left subtree, value, and right subtree.
/// Create a new node with the given left and right subtrees, along with a value of type `U`.
func create[U](l: T[U], v: U, r: T[U]) -> T[U] {
let hl = l.height()
let hr = r.height()
Node(l, v, r, if hl >= hr { hl + 1 } else { hr + 1 })
}

/// `bal[U](l: T[U], v: U, r: T[U])`
///
/// Perform balancing operation on a avl tree node.
///
/// This function performs a balancing operation on a avl tree node based on the heights
/// of its left and right subtrees. It ensures that the heights of the subtrees are balanced
/// and returns a new avl tree node with appropriate restructuring if necessary.
///
/// @param {T[U]} l - The left subtree of the node.
/// @param {U} v - The value of the node.
/// @param {T[U]} r - The right subtree of the node.
/// @return {T[U]} - A new avl tree node after balancing.
func bal[U](l: T[U], v: U, r: T[U]) -> T[U] {
let hl = l.height()
let hr = r.height()
Expand Down Expand Up @@ -92,15 +76,9 @@ func bal[U](l: T[U], v: U, r: T[U]) -> T[U] {
}
}

/// Adds a value to a tree node and performs balancing.
/// `add[U:Compare](self: T[U], x: U)`
///
/// This function adds a value 'x' to the given tree node 'self' of type 'T[U]'. The tree
/// node is expected to be of an enumerated type 'T', and the value type 'U' should implement
/// the 'Compare' interface for comparison.
///
/// @param {T[U]} self - The tree node of type 'T[U]' to which the value will be added.
/// @param {U} x - The value of type 'U' to be added to the tree node.
/// @return {T[U]} A balanced tree node of type 'T[U]' after adding the value.
/// Add a value to a tree-like structure.
pub func add[U:Compare](self: T[U], x: U) -> T[U] {
match self {
Empty => Node(Empty, x, Empty, 1)
Expand All @@ -113,15 +91,9 @@ pub func add[U:Compare](self: T[U], x: U) -> T[U] {
}
}

/// Find the minimum element in a tree-like data structure.
///
/// This function operates on a tree-like data structure of type 'T[U]', where 'U' is a type parameter representing
/// the element type. The function recursively
/// navigates the tree using pattern matching to find the minimum element.
/// `min_elt[U](self: T[U], default: U)`
///
/// @param {T[U]} 'self' - The tree-like data structure on which to find the minimum element.
/// @param {U} 'default' - The default value to return if the tree is empty.
/// @return {U} The minimum element found in the tree, or the 'default' value if the tree is empty.
/// Find the minimum element in a tree-like data structure.
func min_elt[U](self: T[U], default: U) -> U {
match self {
Empty => default
Expand All @@ -130,32 +102,19 @@ func min_elt[U](self: T[U], default: U) -> U {
}
}

/// Remove the minimum element from a avl tree and rebalance the tree.
///
/// This function takes a avl tree 'l' of type 'T[U]', an element 'v' of type 'U' to be removed,
/// and another avl tree 'r' of type 'T[U]'. It removes the minimum element from the tree 'l',
/// and then rebalances the resulting tree using the 'bal' function.
/// `remove_min_elt[U](l: T[U], v: U, r: T[U])`
///
/// @param {T[U]} l - A avl tree from which the minimum element is to be removed.
/// @param {U} v - An element of type 'U' to be removed from the tree.
/// @param {T[U]} r - Another avl tree to be combined with the modified 'l' after removal.
/// @return {T[U]} A avl tree resulting from the removal of the minimum element and rebalancing.
/// Remove the minimum element from a avl tree and rebalance the tree.
func remove_min_elt[U](l: T[U], v: U, r: T[U]) -> T[U] {
match l {
Empty => r
Node(ll, lv, lr, _) => bal(remove_min_elt(ll, lv, lr), v, r)
}
}

/// Merge two AVL trees of the same user-defined type 'U' into a new AVL tree.
///
/// This function takes two AVL trees 'self' and 'other' of type 'T[U]' and merges them into a new AVL tree.
/// The result of the merge is a balanced AVL tree that contains all the elements from both input trees while
/// maintaining the AVL tree properties.
/// `internal_merge[U](self: T[U], other: T[U])`
///
/// @param {T[U]} self - The first AVL tree to merge.
/// @param {T[U]} other - The second AVL tree to merge.
/// @return {T[U]} A new AVL tree containing elements from both input trees, balanced to maintain AVL properties.
/// Merge two AVL trees of the same user-defined type `U` into a new AVL tree.
func internal_merge[U](self: T[U], other: T[U]) -> T[U] {
match (self, other) {
(Empty, t) => t
Expand All @@ -165,15 +124,9 @@ func internal_merge[U](self: T[U], other: T[U]) -> T[U] {
}
}

/// Removes a value from the AVL tree while maintaining balance.
///
/// This function removes a value from the AVL tree while ensuring that the resulting tree
/// remains balanced according to the AVL tree balancing rules. The type 'U' represents
/// the type of values in the tree and must implement the 'Compare' interface for comparison.
/// `remove[U:Compare](self: T[U], x: U)`
///
/// @param {T[U]} self - The AVL tree from which to remove the value.
/// @param {U} x - The value to be removed from the AVL tree.
/// @return {T[U]} - A new AVL tree with the specified value removed, maintaining balance.
/// Removes a value from the AVL tree while maintaining balance
pub func remove[U:Compare](self: T[U], x: U) -> T[U] {
match self {
Empty => Empty
Expand All @@ -186,14 +139,31 @@ pub func remove[U:Compare](self: T[U], x: U) -> T[U] {
}
}

/// Repeat a given string a specified number of times.
/// `to_string[U:Show](self: T[U]) -> String`
///
/// This function takes a string 's' and an integer 'n' as input and returns a new string
/// containing the original string repeated 'n' times.
/// convert the AVL tree to string.
pub func to_string[U : Show](self : T[U]) -> String {
match self {
Empty => "()"
Node(Empty, v, Empty, _) => v.to_string()
Node(l, v, r, _) => "(\(l), \(v), \(r))"
}
}

/// `mem[U:Compare](self: T[U], x: U)`
///
/// @param {String} s - The string to be repeated.
/// @param {Int} n - The number of times to repeat the string.
/// @return {String} A new string containing 's' repeated 'n' times.
/// Check if a given element exists in an AVL tree.
pub func mem[U:Compare](self: T[U], x: U) -> Bool {
match self {
Empty => false
Node(l, v, r, _) => {
let c = x.compare(v)
let tree = if c < 0 { l } else { r }
c == 0 || tree.mem(x)
}
}
}

func repeat_str(s: String, n: Int) -> String {
var result = ""
var i = 0
Expand All @@ -204,47 +174,21 @@ func repeat_str(s: String, n: Int) -> String {
result
}

/// Print the AVL tree
///
/// This function prints the AVL tree by traversing it in an in-order manner and displaying
/// the nodes at each level with appropriate indentation.
/// `print_tree[U:Show](self: T[U])`
///
/// The value type 'U' should implement the 'to_string' interface for 'Show'.
///
/// @param {T[U]} self - The AVL tree to be printed.
/// Print the AVL tree
pub func print_tree[U:Show](self: T[U]) {
fn helper(node: T[U], level: Int) {
match node {
Empty => ()
Node(l, v, r, _) => {
helper(l, level + 1)
let indent = repeat_str(" ", level)
(indent + v.to_string()).print()
print(indent + v.to_string())
helper(r, level + 1)
}
}
"\n".print()
println("")
}
helper(self, 0)
}

/// Check if a given element exists in an AVL tree.
///
/// This function checks whether a specified element 'x' exists in the AVL tree.
/// Type 'U' must implement the 'Compare' interface. The function
/// recursively searches the tree's nodes for the given element.
///
/// @param {T[U]} self - An AVL tree of type 'T' with elements of type 'U'.
/// @param {U} x - The element to search for in the AVL tree.
/// @return {Bool} - 'true' if the element exists in the tree, 'false' otherwise.
pub func mem[U:Compare](self: T[U], x: U) -> Bool {
match self {
Empty => false
Node(l, v, r, _) => {
let c = x.compare(v)
let tree = if c < 0 { l } else { r }
c == 0 || tree.mem(x)
}
}
}

}
12 changes: 5 additions & 7 deletions examples/avl_tree/main/main.mbt
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,15 @@ func init {
}

let height = v.height()
"height of the tree: \(height)".print()
println("height of the tree: \(height)")

v.print_tree()

// Check values from 0 to iter-1 in the AVL tree
var j = 0
while j < iter {
if not(v.mem(j)) {
"impossible".print()
println("impossible")
}
j = j + 1
}
Expand All @@ -28,14 +28,12 @@ func init {
while k < iter {
v = v.remove(k)
k = k + 1
}

"\n".print()
}

// Tree is empty, removal successful
match v {
Empty => "success".print()
Node(_) => "impossible".print()
Empty => print("success")
Node(_) => print("impossible")
}
}

9 changes: 4 additions & 5 deletions examples/buffer/lib/buffer.mbt
Original file line number Diff line number Diff line change
Expand Up @@ -77,16 +77,15 @@ pub func reset[T : Default](self : Buffer[T], capacity : Int) {

pub func println[T : Show](self : Buffer[T]) {
var index = 0
'['.print()
print('[')
while index < self.len {
self.data[index].to_string().print()
print(self.data[index].to_string())
index = index + 1
if index < self.len {
','.print()
print(',')
}
}
']'.print()
'\n'.print()
println(']')
}

func init {
Expand Down
6 changes: 2 additions & 4 deletions examples/docstring-demo/lib/hello.mbt
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
/// Generate a friendly greeting message.
/// `hello()`
///
/// This function return the string "Hello, world!" followed by a newline character.
///
/// @return {String} A string containing the greeting message.
/// Return a string containing the greeting message.
pub func hello() -> String {
"Hello, world!\n"
}
4 changes: 1 addition & 3 deletions examples/docstring-demo/main/main.mbt
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@


func init {
@lib.hello().print()
print(@lib.hello())
}
15 changes: 2 additions & 13 deletions examples/multidimensional_arrays/lib/arrays.mbt
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,9 @@ func min(a : Int, b : Int) -> Int {
}
}

/// Calculate the minimum path sum through a triangle of integers.
///
/// Given a triangle represented as a list of lists of integers, where each list
/// corresponds to a row of the triangle, this function calculates the minimum
/// path sum from the top to the bottom of the triangle by moving only to adjacent
/// numbers on the row below.
/// `minPathSum(triangle : Array[Array[Int]])`
///
/// @param {Array[Array[Int]]} triangle - A 2D array representing the triangle of integers.
/// @return {Int} - The minimum path sum through the triangle.
///
/// The function uses a recursive approach with dynamic programming to calculate
/// the minimum path sum. It starts from the top of the triangle and recursively
/// calculates the minimum path sum for each possible path from the current position
/// to the bottom row. The `helper` function is used for the recursive calculation.
/// Calculate the minimum path sum through a triangle of integers.
pub func minPathSum(triangle : Array[Array[Int]]) -> Int {
fn helper(row : Int, col : Int) -> Int {
if row == triangle.length() {
Expand Down
2 changes: 1 addition & 1 deletion examples/multidimensional_arrays/main/main.mbt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
func init {
let triangle = [[2], [3, 4], [6, 5, 7], [4, 1, 8, 3]]
let result = @lib.minPathSum(triangle)
result.print() // prints 11
print(result) // prints 11
}
4 changes: 2 additions & 2 deletions examples/number/main/main.mbt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
func init {
println(@lib.pi)
print_float(@lib.pi)
println(@lib.max(4, 2)) // 4
println(@lib.min(1.2, 1.21)) // 1.2
print_float(@lib.min(1.2, 1.21)) // 1.2
println(@lib.int_max) // 2147483647
println(@lib.int_min) // -2147483648
// 214_748
Expand Down
7 changes: 0 additions & 7 deletions examples/palindrome_string/lib/str_iter.mbt
Original file line number Diff line number Diff line change
@@ -1,10 +1,3 @@
/// Check if a given string is a palindrome.
///
/// This function takes a string as input and checks whether it is a palindrome or not.
/// A palindrome is a string that reads the same forwards and backwards.
///
/// @param {String} chars - The input string to be checked for palindrome.
/// @return {Bool} Returns `true` if the input string is a palindrome, otherwise `false`.
pub func is_palindrome(chars : String) -> Bool {
let n = chars.length()
var i = 0
Expand Down
4 changes: 2 additions & 2 deletions examples/palindrome_string/main/main.mbt
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ func init {
let a = @lib.is_palindrome(test1)
let b = @lib.is_palindrome(test2)
if a {
test1.print() // not print
print(test1) // not print
}
if b {
test2.print() // print "aba"
print(test2) // print "aba"
}
}

Loading

0 comments on commit 8b90a0d

Please sign in to comment.