mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
all: replace generic <>
with []
- part 2 (#16536)
This commit is contained in:
@ -14,7 +14,7 @@ your actual elements. For example:
|
||||
```v
|
||||
import datatypes
|
||||
|
||||
mut stack := datatypes.Stack<int>{}
|
||||
mut stack := datatypes.Stack[int]{}
|
||||
stack.push(1)
|
||||
println(stack)
|
||||
```
|
||||
|
@ -2,36 +2,36 @@ module datatypes
|
||||
|
||||
/// Internal rapresentation of the tree node
|
||||
[heap]
|
||||
struct BSTreeNode<T> {
|
||||
struct BSTreeNode[T] {
|
||||
mut:
|
||||
// Mark a node as initialized
|
||||
is_init bool
|
||||
// Value of the node
|
||||
value T
|
||||
// The parent of the node
|
||||
parent &BSTreeNode<T> = unsafe { 0 }
|
||||
parent &BSTreeNode[T] = unsafe { 0 }
|
||||
// The left side with value less than the
|
||||
// value of this node
|
||||
left &BSTreeNode<T> = unsafe { 0 }
|
||||
left &BSTreeNode[T] = unsafe { 0 }
|
||||
// The right side with value grater than the
|
||||
// value of thiss node
|
||||
right &BSTreeNode<T> = unsafe { 0 }
|
||||
right &BSTreeNode[T] = unsafe { 0 }
|
||||
}
|
||||
|
||||
// Create new root bst node
|
||||
fn new_root_node<T>(value T) &BSTreeNode<T> {
|
||||
return &BSTreeNode<T>{
|
||||
fn new_root_node[T](value T) &BSTreeNode[T] {
|
||||
return &BSTreeNode[T]{
|
||||
is_init: true
|
||||
value: value
|
||||
parent: new_none_node<T>(true)
|
||||
left: new_none_node<T>(false)
|
||||
right: new_none_node<T>(false)
|
||||
parent: new_none_node[T](true)
|
||||
left: new_none_node[T](false)
|
||||
right: new_none_node[T](false)
|
||||
}
|
||||
}
|
||||
|
||||
// new_node creates a new bst node with a parent reference.
|
||||
fn new_node<T>(parent &BSTreeNode<T>, value T) &BSTreeNode<T> {
|
||||
return &BSTreeNode<T>{
|
||||
fn new_node[T](parent &BSTreeNode[T], value T) &BSTreeNode[T] {
|
||||
return &BSTreeNode[T]{
|
||||
is_init: true
|
||||
value: value
|
||||
parent: parent
|
||||
@ -39,19 +39,19 @@ fn new_node<T>(parent &BSTreeNode<T>, value T) &BSTreeNode<T> {
|
||||
}
|
||||
|
||||
// new_none_node creates a dummy node.
|
||||
fn new_none_node<T>(init bool) &BSTreeNode<T> {
|
||||
return &BSTreeNode<T>{
|
||||
fn new_none_node[T](init bool) &BSTreeNode[T] {
|
||||
return &BSTreeNode[T]{
|
||||
is_init: init
|
||||
}
|
||||
}
|
||||
|
||||
// bind to an actual instance of a node.
|
||||
fn (mut node BSTreeNode<T>) bind(mut to_bind BSTreeNode<T>, left bool) {
|
||||
fn (mut node BSTreeNode[T]) bind(mut to_bind BSTreeNode[T], left bool) {
|
||||
node.left = to_bind.left
|
||||
node.right = to_bind.right
|
||||
node.value = to_bind.value
|
||||
node.is_init = to_bind.is_init
|
||||
to_bind = new_none_node<T>(false)
|
||||
to_bind = new_none_node[T](false)
|
||||
}
|
||||
|
||||
// Pure Binary Seach Tree implementation
|
||||
@ -59,13 +59,13 @@ fn (mut node BSTreeNode<T>) bind(mut to_bind BSTreeNode<T>, left bool) {
|
||||
// Pure V implementation of the Binary Search Tree
|
||||
// Time complexity of main operation O(log N)
|
||||
// Space complexity O(N)
|
||||
pub struct BSTree<T> {
|
||||
pub struct BSTree[T] {
|
||||
mut:
|
||||
root &BSTreeNode<T> = unsafe { 0 }
|
||||
root &BSTreeNode[T] = unsafe { 0 }
|
||||
}
|
||||
|
||||
// insert give the possibility to insert an element in the BST.
|
||||
pub fn (mut bst BSTree<T>) insert(value T) bool {
|
||||
pub fn (mut bst BSTree[T]) insert(value T) bool {
|
||||
if bst.is_empty() {
|
||||
bst.root = new_root_node(value)
|
||||
return true
|
||||
@ -74,7 +74,7 @@ pub fn (mut bst BSTree<T>) insert(value T) bool {
|
||||
}
|
||||
|
||||
// insert_helper walks the tree and inserts the given node.
|
||||
fn (mut bst BSTree<T>) insert_helper(mut node BSTreeNode<T>, value T) bool {
|
||||
fn (mut bst BSTree[T]) insert_helper(mut node BSTreeNode[T], value T) bool {
|
||||
if node.value < value {
|
||||
if unsafe { node.right != 0 } && node.right.is_init {
|
||||
return bst.insert_helper(mut node.right, value)
|
||||
@ -92,13 +92,13 @@ fn (mut bst BSTree<T>) insert_helper(mut node BSTreeNode<T>, value T) bool {
|
||||
}
|
||||
|
||||
// contains checks if an element with a given `value` is inside the BST.
|
||||
pub fn (bst &BSTree<T>) contains(value T) bool {
|
||||
pub fn (bst &BSTree[T]) contains(value T) bool {
|
||||
return bst.contains_helper(bst.root, value)
|
||||
}
|
||||
|
||||
// contains_helper is a helper function to walk the tree, and return
|
||||
// the absence or presence of the `value`.
|
||||
fn (bst &BSTree<T>) contains_helper(node &BSTreeNode<T>, value T) bool {
|
||||
fn (bst &BSTree[T]) contains_helper(node &BSTreeNode[T], value T) bool {
|
||||
if unsafe { node == 0 } || !node.is_init {
|
||||
return false
|
||||
}
|
||||
@ -112,14 +112,14 @@ fn (bst &BSTree<T>) contains_helper(node &BSTreeNode<T>, value T) bool {
|
||||
}
|
||||
|
||||
// remove removes an element with `value` from the BST.
|
||||
pub fn (mut bst BSTree<T>) remove(value T) bool {
|
||||
pub fn (mut bst BSTree[T]) remove(value T) bool {
|
||||
if bst.is_empty() {
|
||||
return false
|
||||
}
|
||||
return bst.remove_helper(mut bst.root, value, false)
|
||||
}
|
||||
|
||||
fn (mut bst BSTree<T>) remove_helper(mut node BSTreeNode<T>, value T, left bool) bool {
|
||||
fn (mut bst BSTree[T]) remove_helper(mut node BSTreeNode[T], value T, left bool) bool {
|
||||
if !node.is_init {
|
||||
return false
|
||||
}
|
||||
@ -136,11 +136,11 @@ fn (mut bst BSTree<T>) remove_helper(mut node BSTreeNode<T>, value T, left bool)
|
||||
} else {
|
||||
mut parent := node.parent
|
||||
if left {
|
||||
parent.left = new_none_node<T>(false)
|
||||
parent.left = new_none_node[T](false)
|
||||
} else {
|
||||
parent.right = new_none_node<T>(false)
|
||||
parent.right = new_none_node[T](false)
|
||||
}
|
||||
node = new_none_node<T>(false)
|
||||
node = new_none_node[T](false)
|
||||
}
|
||||
return true
|
||||
}
|
||||
@ -152,9 +152,9 @@ fn (mut bst BSTree<T>) remove_helper(mut node BSTreeNode<T>, value T, left bool)
|
||||
}
|
||||
|
||||
// get_max_from_right returns the max element of the BST following the right branch.
|
||||
fn (bst &BSTree<T>) get_max_from_right(node &BSTreeNode<T>) &BSTreeNode<T> {
|
||||
fn (bst &BSTree[T]) get_max_from_right(node &BSTreeNode[T]) &BSTreeNode[T] {
|
||||
if unsafe { node == 0 } {
|
||||
return new_none_node<T>(false)
|
||||
return new_none_node[T](false)
|
||||
}
|
||||
right_node := node.right
|
||||
if unsafe { right_node == 0 } || !right_node.is_init {
|
||||
@ -164,9 +164,9 @@ fn (bst &BSTree<T>) get_max_from_right(node &BSTreeNode<T>) &BSTreeNode<T> {
|
||||
}
|
||||
|
||||
// get_min_from_left returns the min element of the BST by following the left branch.
|
||||
fn (bst &BSTree<T>) get_min_from_left(node &BSTreeNode<T>) &BSTreeNode<T> {
|
||||
fn (bst &BSTree[T]) get_min_from_left(node &BSTreeNode[T]) &BSTreeNode[T] {
|
||||
if unsafe { node == 0 } {
|
||||
return new_none_node<T>(false)
|
||||
return new_none_node[T](false)
|
||||
}
|
||||
left_node := node.left
|
||||
if unsafe { left_node == 0 } || !left_node.is_init {
|
||||
@ -176,19 +176,19 @@ fn (bst &BSTree<T>) get_min_from_left(node &BSTreeNode<T>) &BSTreeNode<T> {
|
||||
}
|
||||
|
||||
// is_empty checks if the BST is empty
|
||||
pub fn (bst &BSTree<T>) is_empty() bool {
|
||||
pub fn (bst &BSTree[T]) is_empty() bool {
|
||||
return unsafe { bst.root == 0 }
|
||||
}
|
||||
|
||||
// in_order_traversal traverses the BST in order, and returns the result as an array.
|
||||
pub fn (bst &BSTree<T>) in_order_traversal() []T {
|
||||
pub fn (bst &BSTree[T]) in_order_traversal() []T {
|
||||
mut result := []T{}
|
||||
bst.in_order_traversal_helper(bst.root, mut result)
|
||||
return result
|
||||
}
|
||||
|
||||
// in_order_traversal_helper helps traverse the BST, and accumulates the result in the `result` array.
|
||||
fn (bst &BSTree<T>) in_order_traversal_helper(node &BSTreeNode<T>, mut result []T) {
|
||||
fn (bst &BSTree[T]) in_order_traversal_helper(node &BSTreeNode[T], mut result []T) {
|
||||
if unsafe { node == 0 } || !node.is_init {
|
||||
return
|
||||
}
|
||||
@ -198,7 +198,7 @@ fn (bst &BSTree<T>) in_order_traversal_helper(node &BSTreeNode<T>, mut result []
|
||||
}
|
||||
|
||||
// post_order_traversal traverses the BST in post order, and returns the result in an array.
|
||||
pub fn (bst &BSTree<T>) post_order_traversal() []T {
|
||||
pub fn (bst &BSTree[T]) post_order_traversal() []T {
|
||||
mut result := []T{}
|
||||
bst.post_order_traversal_helper(bst.root, mut result)
|
||||
return result
|
||||
@ -206,7 +206,7 @@ pub fn (bst &BSTree<T>) post_order_traversal() []T {
|
||||
|
||||
// post_order_traversal_helper is a helper function that traverses the BST in post order,
|
||||
// accumulating the result in an array.
|
||||
fn (bst &BSTree<T>) post_order_traversal_helper(node &BSTreeNode<T>, mut result []T) {
|
||||
fn (bst &BSTree[T]) post_order_traversal_helper(node &BSTreeNode[T], mut result []T) {
|
||||
if unsafe { node == 0 } || !node.is_init {
|
||||
return
|
||||
}
|
||||
@ -217,7 +217,7 @@ fn (bst &BSTree<T>) post_order_traversal_helper(node &BSTreeNode<T>, mut result
|
||||
}
|
||||
|
||||
// pre_order_traversal traverses the BST in pre order, and returns the result as an array.
|
||||
pub fn (bst &BSTree<T>) pre_order_traversal() []T {
|
||||
pub fn (bst &BSTree[T]) pre_order_traversal() []T {
|
||||
mut result := []T{}
|
||||
bst.pre_order_traversal_helper(bst.root, mut result)
|
||||
return result
|
||||
@ -225,7 +225,7 @@ pub fn (bst &BSTree<T>) pre_order_traversal() []T {
|
||||
|
||||
// pre_order_traversal_helper is a helper function to traverse the BST
|
||||
// in pre order and accumulates the results in an array.
|
||||
fn (bst &BSTree<T>) pre_order_traversal_helper(node &BSTreeNode<T>, mut result []T) {
|
||||
fn (bst &BSTree[T]) pre_order_traversal_helper(node &BSTreeNode[T], mut result []T) {
|
||||
if unsafe { node == 0 } || !node.is_init {
|
||||
return
|
||||
}
|
||||
@ -235,9 +235,9 @@ fn (bst &BSTree<T>) pre_order_traversal_helper(node &BSTreeNode<T>, mut result [
|
||||
}
|
||||
|
||||
// get_node is a helper method to ge the internal rapresentation of the node with the `value`.
|
||||
fn (bst &BSTree<T>) get_node(node &BSTreeNode<T>, value T) &BSTreeNode<T> {
|
||||
fn (bst &BSTree[T]) get_node(node &BSTreeNode[T], value T) &BSTreeNode[T] {
|
||||
if unsafe { node == 0 } || !node.is_init {
|
||||
return new_none_node<T>(false)
|
||||
return new_none_node[T](false)
|
||||
}
|
||||
if node.value == value {
|
||||
return node
|
||||
@ -256,7 +256,7 @@ fn (bst &BSTree<T>) get_node(node &BSTreeNode<T>, value T) &BSTreeNode<T> {
|
||||
//```v
|
||||
// left_value, exist := bst.to_left(10)
|
||||
//```
|
||||
pub fn (bst &BSTree<T>) to_left(value T) ?T {
|
||||
pub fn (bst &BSTree[T]) to_left(value T) ?T {
|
||||
if bst.is_empty() {
|
||||
return none
|
||||
}
|
||||
@ -275,7 +275,7 @@ pub fn (bst &BSTree<T>) to_left(value T) ?T {
|
||||
//```v
|
||||
// left_value, exist := bst.to_right(10)
|
||||
//```
|
||||
pub fn (bst &BSTree<T>) to_right(value T) ?T {
|
||||
pub fn (bst &BSTree[T]) to_right(value T) ?T {
|
||||
if bst.is_empty() {
|
||||
return none
|
||||
}
|
||||
@ -289,7 +289,7 @@ pub fn (bst &BSTree<T>) to_right(value T) ?T {
|
||||
|
||||
// max return the max element inside the BST.
|
||||
// Time complexity O(N) if the BST is not balanced
|
||||
pub fn (bst &BSTree<T>) max() ?T {
|
||||
pub fn (bst &BSTree[T]) max() ?T {
|
||||
if bst.is_empty() {
|
||||
return none
|
||||
}
|
||||
@ -302,7 +302,7 @@ pub fn (bst &BSTree<T>) max() ?T {
|
||||
|
||||
// min return the minimum element in the BST.
|
||||
// Time complexity O(N) if the BST is not balanced.
|
||||
pub fn (bst &BSTree<T>) min() ?T {
|
||||
pub fn (bst &BSTree[T]) min() ?T {
|
||||
if bst.is_empty() {
|
||||
return none
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ module datatypes
|
||||
// Make an insert of one element and check if
|
||||
// the bst is able to fin it.
|
||||
fn test_insert_into_bst_one() {
|
||||
mut bst := BSTree<int>{}
|
||||
mut bst := BSTree[int]{}
|
||||
assert bst.insert(10) == true
|
||||
assert bst.contains(10) == true
|
||||
assert bst.contains(20) == false
|
||||
@ -12,7 +12,7 @@ fn test_insert_into_bst_one() {
|
||||
// Make the insert of more element inside the BST
|
||||
// and check if the BST is able to find all the values
|
||||
fn test_insert_into_bst_two() {
|
||||
mut bst := BSTree<int>{}
|
||||
mut bst := BSTree[int]{}
|
||||
assert bst.insert(10)
|
||||
assert bst.insert(20)
|
||||
assert bst.insert(9)
|
||||
@ -26,7 +26,7 @@ fn test_insert_into_bst_two() {
|
||||
// Test if the in_order_traversals list return the correct
|
||||
// result array
|
||||
fn test_in_order_bst_visit_one() {
|
||||
mut bst := BSTree<int>{}
|
||||
mut bst := BSTree[int]{}
|
||||
assert bst.insert(10)
|
||||
assert bst.insert(20)
|
||||
assert bst.insert(21)
|
||||
@ -38,7 +38,7 @@ fn test_in_order_bst_visit_one() {
|
||||
// Test if the post_order_bst_visit return the correct
|
||||
// result array
|
||||
fn test_post_order_bst_visit_one() {
|
||||
mut bst := BSTree<int>{}
|
||||
mut bst := BSTree[int]{}
|
||||
assert bst.insert(10)
|
||||
assert bst.insert(20)
|
||||
assert bst.insert(21)
|
||||
@ -49,7 +49,7 @@ fn test_post_order_bst_visit_one() {
|
||||
|
||||
// Test if the pre_order_traversal return the correct result array
|
||||
fn test_pre_order_bst_visit_one() {
|
||||
mut bst := BSTree<int>{}
|
||||
mut bst := BSTree[int]{}
|
||||
assert bst.insert(10)
|
||||
assert bst.insert(20)
|
||||
assert bst.insert(21)
|
||||
@ -61,7 +61,7 @@ fn test_pre_order_bst_visit_one() {
|
||||
// After many insert check if we are abe to get the correct
|
||||
// right and left value of the root.
|
||||
fn test_get_left_root() {
|
||||
mut bst := BSTree<int>{}
|
||||
mut bst := BSTree[int]{}
|
||||
assert bst.insert(10)
|
||||
assert bst.insert(20)
|
||||
assert bst.insert(21)
|
||||
@ -76,7 +76,7 @@ fn test_get_left_root() {
|
||||
|
||||
// Check if BST panic if we call some operation on an empty BST.
|
||||
fn test_get_left_on_empty_bst() {
|
||||
mut bst := BSTree<int>{}
|
||||
mut bst := BSTree[int]{}
|
||||
|
||||
left_val := bst.to_left(10) or { -1 }
|
||||
assert left_val == -1
|
||||
@ -88,7 +88,7 @@ fn test_get_left_on_empty_bst() {
|
||||
// Check the remove operation if it is able to remove
|
||||
// all elements required, and mantains the BST propriety.
|
||||
fn test_remove_from_bst_one() {
|
||||
mut bst := BSTree<int>{}
|
||||
mut bst := BSTree[int]{}
|
||||
assert bst.insert(10)
|
||||
assert bst.insert(20)
|
||||
assert bst.insert(21)
|
||||
@ -102,7 +102,7 @@ fn test_remove_from_bst_one() {
|
||||
// Another test n the remove BST, this remove an intermidia node
|
||||
// that it is a triky operation.
|
||||
fn test_remove_from_bst_two() {
|
||||
mut bst := BSTree<int>{}
|
||||
mut bst := BSTree[int]{}
|
||||
assert bst.insert(10)
|
||||
assert bst.insert(20)
|
||||
assert bst.insert(21)
|
||||
@ -115,7 +115,7 @@ fn test_remove_from_bst_two() {
|
||||
|
||||
// check if we are able to get the max from the BST.
|
||||
fn test_get_max_in_bst() {
|
||||
mut bst := BSTree<int>{}
|
||||
mut bst := BSTree[int]{}
|
||||
assert (bst.max() or { -1 }) == -1
|
||||
assert bst.insert(10)
|
||||
assert bst.insert(20)
|
||||
@ -127,7 +127,7 @@ fn test_get_max_in_bst() {
|
||||
|
||||
// check if we are able to get the min from the BST.
|
||||
fn test_get_min_in_bst() {
|
||||
mut bst := BSTree<int>{}
|
||||
mut bst := BSTree[int]{}
|
||||
assert (bst.min() or { -1 }) == -1
|
||||
assert bst.insert(10)
|
||||
assert bst.insert(20)
|
||||
|
@ -1,36 +1,36 @@
|
||||
module datatypes
|
||||
|
||||
struct DoublyListNode<T> {
|
||||
struct DoublyListNode[T] {
|
||||
mut:
|
||||
data T
|
||||
next &DoublyListNode<T> = unsafe { 0 }
|
||||
prev &DoublyListNode<T> = unsafe { 0 }
|
||||
next &DoublyListNode[T] = unsafe { 0 }
|
||||
prev &DoublyListNode[T] = unsafe { 0 }
|
||||
}
|
||||
|
||||
// DoublyLinkedList<T> represents a generic doubly linked list of elements, each of type T.
|
||||
pub struct DoublyLinkedList<T> {
|
||||
pub struct DoublyLinkedList[T] {
|
||||
mut:
|
||||
head &DoublyListNode<T> = unsafe { 0 }
|
||||
tail &DoublyListNode<T> = unsafe { 0 }
|
||||
head &DoublyListNode[T] = unsafe { 0 }
|
||||
tail &DoublyListNode[T] = unsafe { 0 }
|
||||
// Internal iter pointer for allowing safe modification
|
||||
// of the list while iterating. TODO: use an option
|
||||
// instead of a pointer to determine it is initialized.
|
||||
iter &DoublyListIter<T> = unsafe { 0 }
|
||||
iter &DoublyListIter[T] = unsafe { 0 }
|
||||
len int
|
||||
}
|
||||
|
||||
// is_empty checks if the linked list is empty
|
||||
pub fn (list DoublyLinkedList<T>) is_empty() bool {
|
||||
pub fn (list DoublyLinkedList[T]) is_empty() bool {
|
||||
return list.len == 0
|
||||
}
|
||||
|
||||
// len returns the length of the linked list
|
||||
pub fn (list DoublyLinkedList<T>) len() int {
|
||||
pub fn (list DoublyLinkedList[T]) len() int {
|
||||
return list.len
|
||||
}
|
||||
|
||||
// first returns the first element of the linked list
|
||||
pub fn (list DoublyLinkedList<T>) first() ?T {
|
||||
pub fn (list DoublyLinkedList[T]) first() ?T {
|
||||
if list.is_empty() {
|
||||
return error('Linked list is empty')
|
||||
}
|
||||
@ -38,7 +38,7 @@ pub fn (list DoublyLinkedList<T>) first() ?T {
|
||||
}
|
||||
|
||||
// last returns the last element of the linked list
|
||||
pub fn (list DoublyLinkedList<T>) last() ?T {
|
||||
pub fn (list DoublyLinkedList[T]) last() ?T {
|
||||
if list.is_empty() {
|
||||
return error('Linked list is empty')
|
||||
}
|
||||
@ -46,8 +46,8 @@ pub fn (list DoublyLinkedList<T>) last() ?T {
|
||||
}
|
||||
|
||||
// push_back adds an element to the end of the linked list
|
||||
pub fn (mut list DoublyLinkedList<T>) push_back(item T) {
|
||||
mut new_node := &DoublyListNode<T>{
|
||||
pub fn (mut list DoublyLinkedList[T]) push_back(item T) {
|
||||
mut new_node := &DoublyListNode[T]{
|
||||
data: item
|
||||
}
|
||||
if list.is_empty() {
|
||||
@ -63,8 +63,8 @@ pub fn (mut list DoublyLinkedList<T>) push_back(item T) {
|
||||
}
|
||||
|
||||
// push_front adds an element to the beginning of the linked list
|
||||
pub fn (mut list DoublyLinkedList<T>) push_front(item T) {
|
||||
mut new_node := &DoublyListNode<T>{
|
||||
pub fn (mut list DoublyLinkedList[T]) push_front(item T) {
|
||||
mut new_node := &DoublyListNode[T]{
|
||||
data: item
|
||||
}
|
||||
if list.is_empty() {
|
||||
@ -80,7 +80,7 @@ pub fn (mut list DoublyLinkedList<T>) push_front(item T) {
|
||||
}
|
||||
|
||||
// pop_back removes the last element of the linked list
|
||||
pub fn (mut list DoublyLinkedList<T>) pop_back() ?T {
|
||||
pub fn (mut list DoublyLinkedList[T]) pop_back() ?T {
|
||||
if list.is_empty() {
|
||||
return error('Linked list is empty')
|
||||
}
|
||||
@ -101,7 +101,7 @@ pub fn (mut list DoublyLinkedList<T>) pop_back() ?T {
|
||||
}
|
||||
|
||||
// pop_front removes the last element of the linked list
|
||||
pub fn (mut list DoublyLinkedList<T>) pop_front() ?T {
|
||||
pub fn (mut list DoublyLinkedList[T]) pop_front() ?T {
|
||||
if list.is_empty() {
|
||||
return error('Linked list is empty')
|
||||
}
|
||||
@ -122,7 +122,7 @@ pub fn (mut list DoublyLinkedList<T>) pop_front() ?T {
|
||||
}
|
||||
|
||||
// insert adds an element to the linked list at the given index
|
||||
pub fn (mut list DoublyLinkedList<T>) insert(idx int, item T) ? {
|
||||
pub fn (mut list DoublyLinkedList[T]) insert(idx int, item T) ? {
|
||||
if idx < 0 || idx > list.len {
|
||||
return error('Index ${idx} out of bounds [0..${list.len}]')
|
||||
} else if idx == 0 {
|
||||
@ -142,7 +142,7 @@ pub fn (mut list DoublyLinkedList<T>) insert(idx int, item T) ? {
|
||||
// (determined from the forward index). This function should be called
|
||||
// when idx > list.len/2. This helper function assumes idx bounds have
|
||||
// already been checked and idx is not at the edges.
|
||||
fn (mut list DoublyLinkedList<T>) insert_back(idx int, item T) {
|
||||
fn (mut list DoublyLinkedList[T]) insert_back(idx int, item T) {
|
||||
mut node := list.node(idx + 1)
|
||||
mut prev := node.prev
|
||||
// prev node
|
||||
@ -150,7 +150,7 @@ fn (mut list DoublyLinkedList<T>) insert_back(idx int, item T) {
|
||||
// |next|---->|next|
|
||||
// |prev|<----|prev|
|
||||
// ------ ------
|
||||
new := &DoublyListNode<T>{
|
||||
new := &DoublyListNode[T]{
|
||||
data: item
|
||||
next: node
|
||||
prev: prev
|
||||
@ -169,7 +169,7 @@ fn (mut list DoublyLinkedList<T>) insert_back(idx int, item T) {
|
||||
// (determined from the forward index). This function should be called
|
||||
// when idx <= list.len/2. This helper function assumes idx bounds have
|
||||
// already been checked and idx is not at the edges.
|
||||
fn (mut list DoublyLinkedList<T>) insert_front(idx int, item T) {
|
||||
fn (mut list DoublyLinkedList[T]) insert_front(idx int, item T) {
|
||||
mut node := list.node(idx - 1)
|
||||
mut next := node.next
|
||||
// node next
|
||||
@ -177,7 +177,7 @@ fn (mut list DoublyLinkedList<T>) insert_front(idx int, item T) {
|
||||
// |next|---->|next|
|
||||
// |prev|<----|prev|
|
||||
// ------ ------
|
||||
new := &DoublyListNode<T>{
|
||||
new := &DoublyListNode[T]{
|
||||
data: item
|
||||
next: next
|
||||
prev: node
|
||||
@ -195,7 +195,7 @@ fn (mut list DoublyLinkedList<T>) insert_front(idx int, item T) {
|
||||
// node walks from the head or tail and finds the node at index idx.
|
||||
// This helper function assumes the list is not empty and idx is in
|
||||
// bounds.
|
||||
fn (list &DoublyLinkedList<T>) node(idx int) &DoublyListNode<T> {
|
||||
fn (list &DoublyLinkedList[T]) node(idx int) &DoublyListNode[T] {
|
||||
if idx <= list.len / 2 {
|
||||
mut node := list.head
|
||||
for h := 0; h < idx; h += 1 {
|
||||
@ -212,7 +212,7 @@ fn (list &DoublyLinkedList<T>) node(idx int) &DoublyListNode<T> {
|
||||
|
||||
// index searches the linked list for item and returns the forward index
|
||||
// or none if not found.
|
||||
pub fn (list &DoublyLinkedList<T>) index(item T) ?int {
|
||||
pub fn (list &DoublyLinkedList[T]) index(item T) ?int {
|
||||
mut hn := list.head
|
||||
mut tn := list.tail
|
||||
for h, t := 0, list.len - 1; h <= t; {
|
||||
@ -231,7 +231,7 @@ pub fn (list &DoublyLinkedList<T>) index(item T) ?int {
|
||||
|
||||
// delete removes index idx from the linked list and is safe to call
|
||||
// for any idx.
|
||||
pub fn (mut list DoublyLinkedList<T>) delete(idx int) {
|
||||
pub fn (mut list DoublyLinkedList[T]) delete(idx int) {
|
||||
if idx < 0 || idx >= list.len {
|
||||
return
|
||||
} else if idx == 0 {
|
||||
@ -249,12 +249,12 @@ pub fn (mut list DoublyLinkedList<T>) delete(idx int) {
|
||||
}
|
||||
|
||||
// str returns a string representation of the linked list
|
||||
pub fn (list DoublyLinkedList<T>) str() string {
|
||||
pub fn (list DoublyLinkedList[T]) str() string {
|
||||
return list.array().str()
|
||||
}
|
||||
|
||||
// array returns a array representation of the linked list
|
||||
pub fn (list DoublyLinkedList<T>) array() []T {
|
||||
pub fn (list DoublyLinkedList[T]) array() []T {
|
||||
mut result_array := []T{cap: list.len}
|
||||
mut node := list.head
|
||||
for unsafe { node != 0 } {
|
||||
@ -266,10 +266,10 @@ pub fn (list DoublyLinkedList<T>) array() []T {
|
||||
|
||||
// next implements the iter interface to use DoublyLinkedList with
|
||||
// V's `for x in list {` loop syntax.
|
||||
pub fn (mut list DoublyLinkedList<T>) next() ?T {
|
||||
pub fn (mut list DoublyLinkedList[T]) next() ?T {
|
||||
if list.iter == unsafe { nil } {
|
||||
// initialize new iter object
|
||||
list.iter = &DoublyListIter<T>{
|
||||
list.iter = &DoublyListIter[T]{
|
||||
node: list.head
|
||||
}
|
||||
return list.next()
|
||||
@ -285,15 +285,15 @@ pub fn (mut list DoublyLinkedList<T>) next() ?T {
|
||||
}
|
||||
|
||||
// iterator returns a new iterator instance for the `list`.
|
||||
pub fn (mut list DoublyLinkedList<T>) iterator() DoublyListIter<T> {
|
||||
return DoublyListIter<T>{
|
||||
pub fn (mut list DoublyLinkedList[T]) iterator() DoublyListIter[T] {
|
||||
return DoublyListIter[T]{
|
||||
node: list.head
|
||||
}
|
||||
}
|
||||
|
||||
// back_iterator returns a new backwards iterator instance for the `list`.
|
||||
pub fn (mut list DoublyLinkedList<T>) back_iterator() DoublyListIterBack<T> {
|
||||
return DoublyListIterBack<T>{
|
||||
pub fn (mut list DoublyLinkedList[T]) back_iterator() DoublyListIterBack[T] {
|
||||
return DoublyListIterBack[T]{
|
||||
node: list.tail
|
||||
}
|
||||
}
|
||||
@ -303,14 +303,14 @@ pub fn (mut list DoublyLinkedList<T>) back_iterator() DoublyListIterBack<T> {
|
||||
// It can be used with V's `for x in iter {` construct.
|
||||
// One list can have multiple independent iterators, pointing to different positions/places in the list.
|
||||
// A DoublyListIter iterator instance always traverses the list from *start to finish*.
|
||||
pub struct DoublyListIter<T> {
|
||||
pub struct DoublyListIter[T] {
|
||||
mut:
|
||||
node &DoublyListNode<T> = unsafe { 0 }
|
||||
node &DoublyListNode[T] = unsafe { 0 }
|
||||
}
|
||||
|
||||
// next returns *the next* element of the list, or `none` when the end of the list is reached.
|
||||
// It is called by V's `for x in iter{` on each iteration.
|
||||
pub fn (mut iter DoublyListIter<T>) next() ?T {
|
||||
pub fn (mut iter DoublyListIter[T]) next() ?T {
|
||||
if iter.node == unsafe { nil } {
|
||||
return none
|
||||
}
|
||||
@ -324,14 +324,14 @@ pub fn (mut iter DoublyListIter<T>) next() ?T {
|
||||
// It can be used with V's `for x in iter {` construct.
|
||||
// One list can have multiple independent iterators, pointing to different positions/places in the list.
|
||||
// A DoublyListIterBack iterator instance always traverses the list from *finish to start*.
|
||||
pub struct DoublyListIterBack<T> {
|
||||
pub struct DoublyListIterBack[T] {
|
||||
mut:
|
||||
node &DoublyListNode<T> = unsafe { 0 }
|
||||
node &DoublyListNode[T] = unsafe { 0 }
|
||||
}
|
||||
|
||||
// next returns *the previous* element of the list, or `none` when the start of the list is reached.
|
||||
// It is called by V's `for x in iter{` on each iteration.
|
||||
pub fn (mut iter DoublyListIterBack<T>) next() ?T {
|
||||
pub fn (mut iter DoublyListIterBack[T]) next() ?T {
|
||||
if iter.node == unsafe { nil } {
|
||||
return none
|
||||
}
|
||||
|
@ -1,14 +1,14 @@
|
||||
module datatypes
|
||||
|
||||
fn test_is_empty() {
|
||||
mut list := DoublyLinkedList<int>{}
|
||||
mut list := DoublyLinkedList[int]{}
|
||||
assert list.is_empty() == true
|
||||
list.push_back(1)
|
||||
assert list.is_empty() == false
|
||||
}
|
||||
|
||||
fn test_len() ? {
|
||||
mut list := DoublyLinkedList<int>{}
|
||||
mut list := DoublyLinkedList[int]{}
|
||||
assert list.len() == 0
|
||||
list.push_back(1)
|
||||
assert list.len() == 1
|
||||
@ -17,29 +17,29 @@ fn test_len() ? {
|
||||
}
|
||||
|
||||
fn test_first() ? {
|
||||
mut list := DoublyLinkedList<int>{}
|
||||
mut list := DoublyLinkedList[int]{}
|
||||
list.push_back(1)
|
||||
assert list.first()? == 1
|
||||
list.push_back(2)
|
||||
assert list.first()? == 1
|
||||
list = DoublyLinkedList<int>{}
|
||||
list = DoublyLinkedList[int]{}
|
||||
list.first() or { return }
|
||||
assert false
|
||||
}
|
||||
|
||||
fn test_last() ? {
|
||||
mut list := DoublyLinkedList<int>{}
|
||||
mut list := DoublyLinkedList[int]{}
|
||||
list.push_back(1)
|
||||
assert list.last()? == 1
|
||||
list.push_back(2)
|
||||
assert list.last()? == 2
|
||||
list = DoublyLinkedList<int>{}
|
||||
list = DoublyLinkedList[int]{}
|
||||
list.last() or { return }
|
||||
assert false
|
||||
}
|
||||
|
||||
fn test_push() ? {
|
||||
mut list := DoublyLinkedList<int>{}
|
||||
mut list := DoublyLinkedList[int]{}
|
||||
list.push_back(1)
|
||||
assert list.last()? == 1
|
||||
list.push_back(2)
|
||||
@ -49,7 +49,7 @@ fn test_push() ? {
|
||||
}
|
||||
|
||||
fn test_pop() ? {
|
||||
mut list := DoublyLinkedList<int>{}
|
||||
mut list := DoublyLinkedList[int]{}
|
||||
list.push_back(1)
|
||||
list.push_back(2)
|
||||
list.push_back(3)
|
||||
@ -57,13 +57,13 @@ fn test_pop() ? {
|
||||
list.push_back(4)
|
||||
assert list.pop_back()? == 4
|
||||
assert list.pop_back()? == 2
|
||||
list = DoublyLinkedList<int>{}
|
||||
list = DoublyLinkedList[int]{}
|
||||
list.pop_back() or { return }
|
||||
assert false
|
||||
}
|
||||
|
||||
fn test_pop_front() ? {
|
||||
mut list := DoublyLinkedList<int>{}
|
||||
mut list := DoublyLinkedList[int]{}
|
||||
list.push_back(1)
|
||||
list.push_back(2)
|
||||
list.push_back(3)
|
||||
@ -71,13 +71,13 @@ fn test_pop_front() ? {
|
||||
list.push_back(4)
|
||||
assert list.pop_front()? == 2
|
||||
assert list.pop_front()? == 3
|
||||
list = DoublyLinkedList<int>{}
|
||||
list = DoublyLinkedList[int]{}
|
||||
list.pop_front() or { return }
|
||||
assert false
|
||||
}
|
||||
|
||||
fn test_insert() ? {
|
||||
mut list := DoublyLinkedList<int>{}
|
||||
mut list := DoublyLinkedList[int]{}
|
||||
list.push_back(1)
|
||||
list.push_back(2)
|
||||
list.push_back(3)
|
||||
@ -93,7 +93,7 @@ fn test_insert() ? {
|
||||
}
|
||||
|
||||
fn test_push_front() ? {
|
||||
mut list := DoublyLinkedList<int>{}
|
||||
mut list := DoublyLinkedList[int]{}
|
||||
list.push_back(1)
|
||||
list.push_back(2)
|
||||
list.push_back(3)
|
||||
@ -102,7 +102,7 @@ fn test_push_front() ? {
|
||||
}
|
||||
|
||||
fn test_delete() ? {
|
||||
mut list := DoublyLinkedList<int>{}
|
||||
mut list := DoublyLinkedList[int]{}
|
||||
list.push_back(0)
|
||||
list.push_back(1)
|
||||
list.push_back(2)
|
||||
@ -119,7 +119,7 @@ fn test_delete() ? {
|
||||
}
|
||||
|
||||
fn test_iter() ? {
|
||||
mut list := DoublyLinkedList<int>{}
|
||||
mut list := DoublyLinkedList[int]{}
|
||||
for i := 0; i < 10; i++ {
|
||||
list.push_back(i * 10)
|
||||
}
|
||||
@ -141,7 +141,7 @@ fn test_iter() ? {
|
||||
}
|
||||
|
||||
fn test_index() ? {
|
||||
mut list := DoublyLinkedList<int>{}
|
||||
mut list := DoublyLinkedList[int]{}
|
||||
for i := 0; i < 10; i++ {
|
||||
list.push_back(i * 10)
|
||||
}
|
||||
@ -152,7 +152,7 @@ fn test_index() ? {
|
||||
}
|
||||
|
||||
fn test_str() ? {
|
||||
mut list := DoublyLinkedList<int>{}
|
||||
mut list := DoublyLinkedList[int]{}
|
||||
list.push_back(1)
|
||||
list.push_back(2)
|
||||
list.push_back(3)
|
||||
@ -160,7 +160,7 @@ fn test_str() ? {
|
||||
}
|
||||
|
||||
fn test_array() ? {
|
||||
mut list := DoublyLinkedList<int>{}
|
||||
mut list := DoublyLinkedList[int]{}
|
||||
list.push_back(1)
|
||||
list.push_back(2)
|
||||
list.push_back(3)
|
||||
@ -168,7 +168,7 @@ fn test_array() ? {
|
||||
}
|
||||
|
||||
fn test_string_array() ? {
|
||||
mut list := DoublyLinkedList<[]string>{}
|
||||
mut list := DoublyLinkedList[[]string]{}
|
||||
list.push_back(['a'])
|
||||
list.push_back(['b'])
|
||||
list.push_back(['c'])
|
||||
@ -176,7 +176,7 @@ fn test_string_array() ? {
|
||||
}
|
||||
|
||||
fn test_iteration_with_for() ? {
|
||||
mut list := DoublyLinkedList<int>{}
|
||||
mut list := DoublyLinkedList[int]{}
|
||||
list.push_back(1)
|
||||
list.push_back(2)
|
||||
list.push_back(3)
|
||||
@ -188,7 +188,7 @@ fn test_iteration_with_for() ? {
|
||||
}
|
||||
|
||||
fn test_iterator() ? {
|
||||
mut list := DoublyLinkedList<int>{}
|
||||
mut list := DoublyLinkedList[int]{}
|
||||
list.push_back(1)
|
||||
list.push_back(2)
|
||||
list.push_back(3)
|
||||
@ -201,7 +201,7 @@ fn test_iterator() ? {
|
||||
}
|
||||
|
||||
fn test_back_iterator() ? {
|
||||
mut list := DoublyLinkedList<int>{}
|
||||
mut list := DoublyLinkedList[int]{}
|
||||
list.push_back(1)
|
||||
list.push_back(2)
|
||||
list.push_back(3)
|
||||
|
@ -1,13 +1,13 @@
|
||||
module datatypes
|
||||
|
||||
// MinHeap is a binary minimum heap data structure.
|
||||
pub struct MinHeap<T> {
|
||||
pub struct MinHeap[T] {
|
||||
mut:
|
||||
data []T
|
||||
}
|
||||
|
||||
// insert adds an element to the heap.
|
||||
pub fn (mut heap MinHeap<T>) insert(item T) {
|
||||
pub fn (mut heap MinHeap[T]) insert(item T) {
|
||||
// push item to the end of the array
|
||||
heap.data << item
|
||||
// swap the new node with its parent until the heap is in order
|
||||
@ -21,7 +21,7 @@ pub fn (mut heap MinHeap<T>) insert(item T) {
|
||||
}
|
||||
|
||||
// pop removes the top-most element from the heap.
|
||||
pub fn (mut heap MinHeap<T>) pop() ?T {
|
||||
pub fn (mut heap MinHeap[T]) pop() ?T {
|
||||
if heap.data.len == 0 {
|
||||
return none
|
||||
} else if heap.data.len == 1 {
|
||||
@ -46,7 +46,7 @@ pub fn (mut heap MinHeap<T>) pop() ?T {
|
||||
}
|
||||
|
||||
// peek gets the top-most element from the heap without removing it.
|
||||
pub fn (heap MinHeap<T>) peek() ?T {
|
||||
pub fn (heap MinHeap[T]) peek() ?T {
|
||||
if heap.data.len == 0 {
|
||||
return none
|
||||
}
|
||||
@ -54,13 +54,13 @@ pub fn (heap MinHeap<T>) peek() ?T {
|
||||
}
|
||||
|
||||
// len returns the number of elements in the heap.
|
||||
pub fn (heap MinHeap<T>) len() int {
|
||||
pub fn (heap MinHeap[T]) len() int {
|
||||
return heap.data.len
|
||||
}
|
||||
|
||||
// left_child is a helper function that returns the index of the left
|
||||
// child given a parent idx, or none if there is no left child.
|
||||
fn (heap MinHeap<T>) left_child(idx int) ?int {
|
||||
fn (heap MinHeap[T]) left_child(idx int) ?int {
|
||||
child := 2 * idx + 1
|
||||
if child >= heap.data.len {
|
||||
return none
|
||||
@ -70,7 +70,7 @@ fn (heap MinHeap<T>) left_child(idx int) ?int {
|
||||
|
||||
// right_child is a helper function that returns the index of the right
|
||||
// child given a parent idx, or none if there is no right child.
|
||||
fn (heap MinHeap<T>) right_child(idx int) ?int {
|
||||
fn (heap MinHeap[T]) right_child(idx int) ?int {
|
||||
child := 2 * idx + 2
|
||||
if child >= heap.data.len {
|
||||
return none
|
||||
@ -79,6 +79,6 @@ fn (heap MinHeap<T>) right_child(idx int) ?int {
|
||||
}
|
||||
|
||||
// parent is a helper function that returns the parent index of the child.
|
||||
fn (heap MinHeap<T>) parent(idx int) int {
|
||||
fn (heap MinHeap[T]) parent(idx int) int {
|
||||
return (idx - 1) / 2
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
module datatypes
|
||||
|
||||
fn test_min_heap() ? {
|
||||
mut heap := MinHeap<int>{}
|
||||
mut heap := MinHeap[int]{}
|
||||
heap.insert(2)
|
||||
heap.insert(0)
|
||||
heap.insert(8)
|
||||
@ -28,7 +28,7 @@ fn (lhs Item) < (rhs Item) bool {
|
||||
}
|
||||
|
||||
fn test_min_heap_custom() ? {
|
||||
mut heap := MinHeap<Item>{}
|
||||
mut heap := MinHeap[Item]{}
|
||||
heap.insert(Item{'buz', 10})
|
||||
heap.insert(Item{'qux', 0})
|
||||
heap.insert(Item{'baz', 50})
|
||||
@ -46,7 +46,7 @@ fn test_min_heap_custom() ? {
|
||||
}
|
||||
|
||||
fn test_heap_len() ? {
|
||||
mut heap := MinHeap<int>{}
|
||||
mut heap := MinHeap[int]{}
|
||||
heap.insert(2)
|
||||
assert heap.len() == 1
|
||||
heap.insert(0)
|
||||
|
@ -1,38 +1,38 @@
|
||||
module datatypes
|
||||
|
||||
pub struct ListNode<T> {
|
||||
pub struct ListNode[T] {
|
||||
mut:
|
||||
data T
|
||||
next &ListNode<T> = unsafe { 0 }
|
||||
next &ListNode[T] = unsafe { 0 }
|
||||
}
|
||||
|
||||
pub struct LinkedList<T> {
|
||||
pub struct LinkedList[T] {
|
||||
mut:
|
||||
head &ListNode<T> = unsafe { 0 }
|
||||
head &ListNode[T] = unsafe { 0 }
|
||||
len int
|
||||
// Internal iter pointer for allowing safe modification
|
||||
// of the list while iterating. TODO: use an option
|
||||
// instead of a pointer to determine if it is initialized.
|
||||
iter &ListIter<T> = unsafe { 0 }
|
||||
iter &ListIter[T] = unsafe { 0 }
|
||||
}
|
||||
|
||||
// is_empty checks if the linked list is empty
|
||||
pub fn (list LinkedList<T>) is_empty() bool {
|
||||
pub fn (list LinkedList[T]) is_empty() bool {
|
||||
return list.len == 0
|
||||
}
|
||||
|
||||
// len returns the length of the linked list
|
||||
pub fn (list LinkedList<T>) len() int {
|
||||
pub fn (list LinkedList[T]) len() int {
|
||||
return list.len
|
||||
}
|
||||
|
||||
// first returns the first element of the linked list
|
||||
pub fn (list LinkedList<T>) first() ?T {
|
||||
pub fn (list LinkedList[T]) first() ?T {
|
||||
return if !list.is_empty() { list.head.data } else { error('Linked list is empty') }
|
||||
}
|
||||
|
||||
// last returns the last element of the linked list
|
||||
pub fn (list LinkedList<T>) last() ?T {
|
||||
pub fn (list LinkedList[T]) last() ?T {
|
||||
if unsafe { list.head == 0 } {
|
||||
return error('Linked list is empty')
|
||||
} else {
|
||||
@ -45,7 +45,7 @@ pub fn (list LinkedList<T>) last() ?T {
|
||||
}
|
||||
|
||||
// index returns the element at the given index of the linked list
|
||||
pub fn (list LinkedList<T>) index(idx int) ?T {
|
||||
pub fn (list LinkedList[T]) index(idx int) ?T {
|
||||
if unsafe { list.head == 0 } {
|
||||
return error('Linked list is empty')
|
||||
} else {
|
||||
@ -64,8 +64,8 @@ pub fn (list LinkedList<T>) index(idx int) ?T {
|
||||
}
|
||||
|
||||
// push adds an element to the end of the linked list
|
||||
pub fn (mut list LinkedList<T>) push(item T) {
|
||||
new_node := &ListNode<T>{
|
||||
pub fn (mut list LinkedList[T]) push(item T) {
|
||||
new_node := &ListNode[T]{
|
||||
data: item
|
||||
}
|
||||
if unsafe { list.head == 0 } {
|
||||
@ -82,7 +82,7 @@ pub fn (mut list LinkedList<T>) push(item T) {
|
||||
}
|
||||
|
||||
// pop removes the last element of the linked list
|
||||
pub fn (mut list LinkedList<T>) pop() ?T {
|
||||
pub fn (mut list LinkedList[T]) pop() ?T {
|
||||
if unsafe { list.head == 0 } {
|
||||
return error('Linked list is empty')
|
||||
}
|
||||
@ -105,7 +105,7 @@ pub fn (mut list LinkedList<T>) pop() ?T {
|
||||
}
|
||||
|
||||
// shift removes the first element of the linked list
|
||||
pub fn (mut list LinkedList<T>) shift() ?T {
|
||||
pub fn (mut list LinkedList[T]) shift() ?T {
|
||||
if unsafe { list.head == 0 } {
|
||||
return error('Linked list is empty')
|
||||
} else {
|
||||
@ -117,7 +117,7 @@ pub fn (mut list LinkedList<T>) shift() ?T {
|
||||
}
|
||||
|
||||
// insert adds an element to the linked list at the given index
|
||||
pub fn (mut list LinkedList<T>) insert(idx int, item T) ? {
|
||||
pub fn (mut list LinkedList[T]) insert(idx int, item T) ? {
|
||||
if idx < 0 || idx > list.len {
|
||||
return error('Index ${idx} out of bounds [0..${list.len}]')
|
||||
} else if list.len == 0 {
|
||||
@ -128,7 +128,7 @@ pub fn (mut list LinkedList<T>) insert(idx int, item T) ? {
|
||||
|
||||
if idx == 0 {
|
||||
// first node case
|
||||
list.head = &ListNode<T>{
|
||||
list.head = &ListNode[T]{
|
||||
data: item
|
||||
next: node
|
||||
}
|
||||
@ -136,7 +136,7 @@ pub fn (mut list LinkedList<T>) insert(idx int, item T) ? {
|
||||
for i := 0; i < idx - 1; i++ {
|
||||
node = node.next
|
||||
}
|
||||
node.next = &ListNode<T>{
|
||||
node.next = &ListNode[T]{
|
||||
data: item
|
||||
next: node.next
|
||||
}
|
||||
@ -145,17 +145,17 @@ pub fn (mut list LinkedList<T>) insert(idx int, item T) ? {
|
||||
}
|
||||
|
||||
// prepend adds an element to the beginning of the linked list (equivalent to insert(0, item))
|
||||
pub fn (mut list LinkedList<T>) prepend(item T) {
|
||||
pub fn (mut list LinkedList[T]) prepend(item T) {
|
||||
list.insert(0, item) or {}
|
||||
}
|
||||
|
||||
// str returns a string representation of the linked list
|
||||
pub fn (list LinkedList<T>) str() string {
|
||||
pub fn (list LinkedList[T]) str() string {
|
||||
return list.array().str()
|
||||
}
|
||||
|
||||
// array returns a array representation of the linked list
|
||||
pub fn (list LinkedList<T>) array() []T {
|
||||
pub fn (list LinkedList[T]) array() []T {
|
||||
mut result_array := []T{cap: list.len}
|
||||
mut node := list.head
|
||||
for unsafe { node != 0 } {
|
||||
@ -167,10 +167,10 @@ pub fn (list LinkedList<T>) array() []T {
|
||||
|
||||
// next implements the iteration interface to use LinkedList
|
||||
// with V's `for` loop syntax.
|
||||
pub fn (mut list LinkedList<T>) next() ?T {
|
||||
pub fn (mut list LinkedList[T]) next() ?T {
|
||||
if list.iter == unsafe { nil } {
|
||||
// initialize new iter object
|
||||
list.iter = &ListIter<T>{
|
||||
list.iter = &ListIter[T]{
|
||||
node: list.head
|
||||
}
|
||||
return list.next()
|
||||
@ -186,8 +186,8 @@ pub fn (mut list LinkedList<T>) next() ?T {
|
||||
}
|
||||
|
||||
// iterator returns a new iterator instance for the `list`.
|
||||
pub fn (mut list LinkedList<T>) iterator() ListIter<T> {
|
||||
return ListIter<T>{
|
||||
pub fn (mut list LinkedList[T]) iterator() ListIter[T] {
|
||||
return ListIter[T]{
|
||||
node: list.head
|
||||
}
|
||||
}
|
||||
@ -196,14 +196,14 @@ pub fn (mut list LinkedList<T>) iterator() ListIter<T> {
|
||||
// It can be used with V's `for x in iter {` construct.
|
||||
// One list can have multiple independent iterators, pointing to different positions/places in the list.
|
||||
// An iterator instance always traverses the list from start to finish.
|
||||
pub struct ListIter<T> {
|
||||
pub struct ListIter[T] {
|
||||
mut:
|
||||
node &ListNode<T> = unsafe { 0 }
|
||||
node &ListNode[T] = unsafe { 0 }
|
||||
}
|
||||
|
||||
// next returns the next element of the list, or `none` when the end of the list is reached.
|
||||
// It is called by V's `for x in iter{` on each iteration.
|
||||
pub fn (mut iter ListIter<T>) next() ?T {
|
||||
pub fn (mut iter ListIter[T]) next() ?T {
|
||||
if iter.node == unsafe { nil } {
|
||||
return none
|
||||
}
|
||||
|
@ -1,14 +1,14 @@
|
||||
module datatypes
|
||||
|
||||
fn test_is_empty() {
|
||||
mut list := LinkedList<int>{}
|
||||
mut list := LinkedList[int]{}
|
||||
assert list.is_empty() == true
|
||||
list.push(1)
|
||||
assert list.is_empty() == false
|
||||
}
|
||||
|
||||
fn test_len() ? {
|
||||
mut list := LinkedList<int>{}
|
||||
mut list := LinkedList[int]{}
|
||||
assert list.len() == 0
|
||||
list.push(1)
|
||||
assert list.len() == 1
|
||||
@ -17,29 +17,29 @@ fn test_len() ? {
|
||||
}
|
||||
|
||||
fn test_first() ? {
|
||||
mut list := LinkedList<int>{}
|
||||
mut list := LinkedList[int]{}
|
||||
list.push(1)
|
||||
assert list.first()? == 1
|
||||
list.push(2)
|
||||
assert list.first()? == 1
|
||||
list = LinkedList<int>{}
|
||||
list = LinkedList[int]{}
|
||||
list.first() or { return }
|
||||
assert false
|
||||
}
|
||||
|
||||
fn test_last() ? {
|
||||
mut list := LinkedList<int>{}
|
||||
mut list := LinkedList[int]{}
|
||||
list.push(1)
|
||||
assert list.last()? == 1
|
||||
list.push(2)
|
||||
assert list.last()? == 2
|
||||
list = LinkedList<int>{}
|
||||
list = LinkedList[int]{}
|
||||
list.last() or { return }
|
||||
assert false
|
||||
}
|
||||
|
||||
fn test_index() ? {
|
||||
mut list := LinkedList<int>{}
|
||||
mut list := LinkedList[int]{}
|
||||
list.push(1)
|
||||
assert list.index(0)? == 1
|
||||
list.push(2)
|
||||
@ -50,7 +50,7 @@ fn test_index() ? {
|
||||
}
|
||||
|
||||
fn test_push() ? {
|
||||
mut list := LinkedList<int>{}
|
||||
mut list := LinkedList[int]{}
|
||||
list.push(1)
|
||||
assert list.last()? == 1
|
||||
list.push(2)
|
||||
@ -60,7 +60,7 @@ fn test_push() ? {
|
||||
}
|
||||
|
||||
fn test_pop() ? {
|
||||
mut list := LinkedList<int>{}
|
||||
mut list := LinkedList[int]{}
|
||||
list.push(1)
|
||||
list.push(2)
|
||||
list.push(3)
|
||||
@ -68,13 +68,13 @@ fn test_pop() ? {
|
||||
list.push(4)
|
||||
assert list.pop()? == 4
|
||||
assert list.pop()? == 2
|
||||
list = LinkedList<int>{}
|
||||
list = LinkedList[int]{}
|
||||
list.pop() or { return }
|
||||
assert false
|
||||
}
|
||||
|
||||
fn test_shift() ? {
|
||||
mut list := LinkedList<int>{}
|
||||
mut list := LinkedList[int]{}
|
||||
list.push(1)
|
||||
list.push(2)
|
||||
list.push(3)
|
||||
@ -82,13 +82,13 @@ fn test_shift() ? {
|
||||
list.push(4)
|
||||
assert list.shift()? == 2
|
||||
assert list.shift()? == 3
|
||||
list = LinkedList<int>{}
|
||||
list = LinkedList[int]{}
|
||||
list.shift() or { return }
|
||||
assert false
|
||||
}
|
||||
|
||||
fn test_insert() ? {
|
||||
mut list := LinkedList<int>{}
|
||||
mut list := LinkedList[int]{}
|
||||
list.push(1)
|
||||
list.push(2)
|
||||
list.push(3)
|
||||
@ -97,7 +97,7 @@ fn test_insert() ? {
|
||||
}
|
||||
|
||||
fn test_prepend() ? {
|
||||
mut list := LinkedList<int>{}
|
||||
mut list := LinkedList[int]{}
|
||||
list.push(1)
|
||||
list.push(2)
|
||||
list.push(3)
|
||||
@ -106,7 +106,7 @@ fn test_prepend() ? {
|
||||
}
|
||||
|
||||
fn test_str() ? {
|
||||
mut list := LinkedList<int>{}
|
||||
mut list := LinkedList[int]{}
|
||||
list.push(1)
|
||||
list.push(2)
|
||||
list.push(3)
|
||||
@ -114,7 +114,7 @@ fn test_str() ? {
|
||||
}
|
||||
|
||||
fn test_array() ? {
|
||||
mut list := LinkedList<int>{}
|
||||
mut list := LinkedList[int]{}
|
||||
list.push(1)
|
||||
list.push(2)
|
||||
list.push(3)
|
||||
@ -122,7 +122,7 @@ fn test_array() ? {
|
||||
}
|
||||
|
||||
fn test_linked_list_iterating_with_for() ? {
|
||||
mut list := LinkedList<int>{}
|
||||
mut list := LinkedList[int]{}
|
||||
list.push(1)
|
||||
list.push(2)
|
||||
list.push(3)
|
||||
@ -134,7 +134,7 @@ fn test_linked_list_iterating_with_for() ? {
|
||||
}
|
||||
|
||||
fn test_linked_list_separate_iterators() ? {
|
||||
mut list := LinkedList<int>{}
|
||||
mut list := LinkedList[int]{}
|
||||
list.push(1)
|
||||
list.push(2)
|
||||
list.push(3)
|
||||
|
@ -1,51 +1,51 @@
|
||||
module datatypes
|
||||
|
||||
pub struct Queue<T> {
|
||||
pub struct Queue[T] {
|
||||
mut:
|
||||
elements LinkedList<T>
|
||||
elements LinkedList[T]
|
||||
}
|
||||
|
||||
// is_empty checks if the queue is empty
|
||||
pub fn (queue Queue<T>) is_empty() bool {
|
||||
pub fn (queue Queue[T]) is_empty() bool {
|
||||
return queue.elements.is_empty()
|
||||
}
|
||||
|
||||
// len returns the length of the queue
|
||||
pub fn (queue Queue<T>) len() int {
|
||||
pub fn (queue Queue[T]) len() int {
|
||||
return queue.elements.len()
|
||||
}
|
||||
|
||||
// peek returns the head of the queue (first element added)
|
||||
pub fn (queue Queue<T>) peek() ?T {
|
||||
pub fn (queue Queue[T]) peek() ?T {
|
||||
return queue.elements.first()
|
||||
}
|
||||
|
||||
// last returns the tail of the queue (last element added)
|
||||
pub fn (queue Queue<T>) last() ?T {
|
||||
pub fn (queue Queue[T]) last() ?T {
|
||||
return queue.elements.last()
|
||||
}
|
||||
|
||||
// index returns the element at the given index of the queue
|
||||
pub fn (queue Queue<T>) index(idx int) ?T {
|
||||
pub fn (queue Queue[T]) index(idx int) ?T {
|
||||
return queue.elements.index(idx)
|
||||
}
|
||||
|
||||
// push adds an element to the tail of the queue
|
||||
pub fn (mut queue Queue<T>) push(item T) {
|
||||
pub fn (mut queue Queue[T]) push(item T) {
|
||||
queue.elements.push(item)
|
||||
}
|
||||
|
||||
// pop removes the element at the head of the queue and returns it
|
||||
pub fn (mut queue Queue<T>) pop() ?T {
|
||||
pub fn (mut queue Queue[T]) pop() ?T {
|
||||
return queue.elements.shift()
|
||||
}
|
||||
|
||||
// str returns a string representation of the queue
|
||||
pub fn (queue Queue<T>) str() string {
|
||||
pub fn (queue Queue[T]) str() string {
|
||||
return queue.elements.str()
|
||||
}
|
||||
|
||||
// array returns a array representation of the queue
|
||||
pub fn (queue Queue<T>) array() []T {
|
||||
pub fn (queue Queue[T]) array() []T {
|
||||
return queue.elements.array()
|
||||
}
|
||||
|
@ -1,14 +1,14 @@
|
||||
module datatypes
|
||||
|
||||
fn test_is_empty() {
|
||||
mut queue := Queue<int>{}
|
||||
mut queue := Queue[int]{}
|
||||
assert queue.is_empty() == true
|
||||
queue.push(1)
|
||||
assert queue.is_empty() == false
|
||||
}
|
||||
|
||||
fn test_len() ? {
|
||||
mut queue := Queue<int>{}
|
||||
mut queue := Queue[int]{}
|
||||
assert queue.len() == 0
|
||||
queue.push(1)
|
||||
assert queue.len() == 1
|
||||
@ -17,29 +17,29 @@ fn test_len() ? {
|
||||
}
|
||||
|
||||
fn test_peek() ? {
|
||||
mut queue := Queue<int>{}
|
||||
mut queue := Queue[int]{}
|
||||
queue.push(1)
|
||||
assert queue.peek()? == 1
|
||||
queue.push(2)
|
||||
assert queue.peek()? == 1
|
||||
queue = Queue<int>{}
|
||||
queue = Queue[int]{}
|
||||
queue.peek() or { return }
|
||||
assert false
|
||||
}
|
||||
|
||||
fn test_last() ? {
|
||||
mut queue := Queue<int>{}
|
||||
mut queue := Queue[int]{}
|
||||
queue.push(1)
|
||||
assert queue.last()? == 1
|
||||
queue.push(2)
|
||||
assert queue.last()? == 2
|
||||
queue = Queue<int>{}
|
||||
queue = Queue[int]{}
|
||||
queue.last() or { return }
|
||||
assert false
|
||||
}
|
||||
|
||||
fn test_index() ? {
|
||||
mut queue := Queue<int>{}
|
||||
mut queue := Queue[int]{}
|
||||
queue.push(1)
|
||||
assert queue.index(0)? == 1
|
||||
queue.push(2)
|
||||
@ -50,14 +50,14 @@ fn test_index() ? {
|
||||
}
|
||||
|
||||
fn test_push() ? {
|
||||
mut queue := Queue<int>{}
|
||||
mut queue := Queue[int]{}
|
||||
queue.push(1)
|
||||
queue.push(2)
|
||||
assert queue.peek()? == 1
|
||||
}
|
||||
|
||||
fn test_pop() ? {
|
||||
mut queue := Queue<int>{}
|
||||
mut queue := Queue[int]{}
|
||||
queue.push(1)
|
||||
queue.push(2)
|
||||
queue.push(3)
|
||||
@ -65,13 +65,13 @@ fn test_pop() ? {
|
||||
queue.push(4)
|
||||
assert queue.pop()? == 2
|
||||
assert queue.pop()? == 3
|
||||
queue = Queue<int>{}
|
||||
queue = Queue[int]{}
|
||||
queue.pop() or { return }
|
||||
assert false
|
||||
}
|
||||
|
||||
fn test_array() ? {
|
||||
mut queue := Queue<int>{}
|
||||
mut queue := Queue[int]{}
|
||||
queue.push(1)
|
||||
queue.push(2)
|
||||
assert queue.array() == [1, 2]
|
||||
|
@ -3,7 +3,7 @@
|
||||
module datatypes
|
||||
|
||||
// RingBuffer - public struct that represents the ringbuffer
|
||||
pub struct RingBuffer<T> {
|
||||
pub struct RingBuffer[T] {
|
||||
mut:
|
||||
reader int // index of the tail where data is going to be read
|
||||
writer int // index of the head where data is going to be written
|
||||
@ -11,14 +11,14 @@ mut:
|
||||
}
|
||||
|
||||
// new_ringbuffer - creates an empty ringbuffer
|
||||
pub fn new_ringbuffer<T>(s int) RingBuffer<T> {
|
||||
return RingBuffer<T>{
|
||||
pub fn new_ringbuffer[T](s int) RingBuffer[T] {
|
||||
return RingBuffer[T]{
|
||||
content: []T{len: s + 1, cap: s + 1}
|
||||
} // increasing custom set size by one element in order to make ring flow possible, so that writer cannot equal reader before reader-index has been read.
|
||||
}
|
||||
|
||||
// push - adds an element to the ringbuffer
|
||||
pub fn (mut rb RingBuffer<T>) push(element T) ? {
|
||||
pub fn (mut rb RingBuffer[T]) push(element T) ? {
|
||||
if rb.is_full() {
|
||||
return error('Buffer overflow')
|
||||
} else {
|
||||
@ -28,7 +28,7 @@ pub fn (mut rb RingBuffer<T>) push(element T) ? {
|
||||
}
|
||||
|
||||
// pop - returns the oldest element of the buffer
|
||||
pub fn (mut rb RingBuffer<T>) pop() ?T {
|
||||
pub fn (mut rb RingBuffer[T]) pop() ?T {
|
||||
mut v := rb.content[rb.reader]
|
||||
if rb.is_empty() {
|
||||
return error('Buffer is empty')
|
||||
@ -39,14 +39,14 @@ pub fn (mut rb RingBuffer<T>) pop() ?T {
|
||||
}
|
||||
|
||||
// push_many - pushes an array to the buffer
|
||||
pub fn (mut rb RingBuffer<T>) push_many(elements []T) ? {
|
||||
pub fn (mut rb RingBuffer[T]) push_many(elements []T) ? {
|
||||
for v in elements {
|
||||
rb.push(v) or { return err }
|
||||
}
|
||||
}
|
||||
|
||||
// pop_many - returns a given number(n) of elements of the buffer starting with the oldest one
|
||||
pub fn (mut rb RingBuffer<T>) pop_many(n u64) ?[]T {
|
||||
pub fn (mut rb RingBuffer[T]) pop_many(n u64) ?[]T {
|
||||
mut elements := []T{}
|
||||
for _ in 0 .. n {
|
||||
elements << rb.pop() or { return err }
|
||||
@ -55,12 +55,12 @@ pub fn (mut rb RingBuffer<T>) pop_many(n u64) ?[]T {
|
||||
}
|
||||
|
||||
// is_empty - checks if the ringbuffer is empty
|
||||
pub fn (rb RingBuffer<T>) is_empty() bool {
|
||||
pub fn (rb RingBuffer[T]) is_empty() bool {
|
||||
return rb.reader == rb.writer // if reader equals writer it means that no value to read has been written before. It follows that the buffer is empty.
|
||||
}
|
||||
|
||||
// is_full - checks if the ringbuffer is full
|
||||
pub fn (rb RingBuffer<T>) is_full() bool {
|
||||
pub fn (rb RingBuffer[T]) is_full() bool {
|
||||
if rb.writer + 1 == rb.reader {
|
||||
return true
|
||||
} else if rb.writer == rb.content.len - 1 && rb.reader == 0 {
|
||||
@ -71,19 +71,19 @@ pub fn (rb RingBuffer<T>) is_full() bool {
|
||||
}
|
||||
|
||||
// capacity - returns the capacity of the ringbuffer
|
||||
pub fn (rb RingBuffer<T>) capacity() int {
|
||||
pub fn (rb RingBuffer[T]) capacity() int {
|
||||
return rb.content.cap - 1 // reduce by one because of the extra element explained in function `new_ringbuffer()`
|
||||
}
|
||||
|
||||
// clear - emptys the ringbuffer and all pushed elements
|
||||
pub fn (mut rb RingBuffer<T>) clear() {
|
||||
rb = RingBuffer<T>{
|
||||
pub fn (mut rb RingBuffer[T]) clear() {
|
||||
rb = RingBuffer[T]{
|
||||
content: []T{len: rb.content.len, cap: rb.content.cap}
|
||||
}
|
||||
}
|
||||
|
||||
// occupied - returns occupied capacity of the buffer.
|
||||
pub fn (rb RingBuffer<T>) occupied() int {
|
||||
pub fn (rb RingBuffer[T]) occupied() int {
|
||||
mut reader := rb.reader
|
||||
mut v := 0
|
||||
if rb.is_empty() {
|
||||
@ -103,20 +103,20 @@ pub fn (rb RingBuffer<T>) occupied() int {
|
||||
}
|
||||
|
||||
// remaining - returns remaining capacity of the buffer
|
||||
pub fn (rb RingBuffer<T>) remaining() int {
|
||||
pub fn (rb RingBuffer[T]) remaining() int {
|
||||
return rb.capacity() - rb.occupied()
|
||||
}
|
||||
|
||||
// head an tail-pointer move methods
|
||||
// these methods are not public, they are just an eneasement for handling the pointer-movement process.
|
||||
fn (mut rb RingBuffer<T>) move_reader() {
|
||||
fn (mut rb RingBuffer[T]) move_reader() {
|
||||
rb.reader++
|
||||
if rb.reader > rb.content.len - 1 {
|
||||
rb.reader = 0
|
||||
}
|
||||
}
|
||||
|
||||
fn (mut rb RingBuffer<T>) move_writer() {
|
||||
fn (mut rb RingBuffer[T]) move_writer() {
|
||||
rb.writer++
|
||||
if rb.writer > rb.content.len - 1 {
|
||||
rb.writer = 0
|
||||
|
@ -1,7 +1,7 @@
|
||||
import datatypes
|
||||
|
||||
fn test_push_and_pop() {
|
||||
mut r := datatypes.new_ringbuffer<int>(2)
|
||||
mut r := datatypes.new_ringbuffer[int](2)
|
||||
|
||||
r.push(3) or { panic(err) }
|
||||
r.push(4) or { panic(err) }
|
||||
@ -18,7 +18,7 @@ fn test_push_and_pop() {
|
||||
}
|
||||
|
||||
fn test_clear_and_empty() {
|
||||
mut r := datatypes.new_ringbuffer<int>(4)
|
||||
mut r := datatypes.new_ringbuffer[int](4)
|
||||
r.push(3) or { panic(err) }
|
||||
r.push(4) or { panic(err) }
|
||||
|
||||
@ -31,7 +31,7 @@ fn test_clear_and_empty() {
|
||||
}
|
||||
|
||||
fn test_capacity_and_is_full() {
|
||||
mut r := datatypes.new_ringbuffer<int>(4)
|
||||
mut r := datatypes.new_ringbuffer[int](4)
|
||||
|
||||
assert r.capacity() == 4
|
||||
|
||||
@ -44,7 +44,7 @@ fn test_capacity_and_is_full() {
|
||||
}
|
||||
|
||||
fn test_occupied_and_remaining() {
|
||||
mut r := datatypes.new_ringbuffer<int>(4)
|
||||
mut r := datatypes.new_ringbuffer[int](4)
|
||||
|
||||
r.push(3) or { panic(err) }
|
||||
r.push(4) or { panic(err) }
|
||||
@ -53,7 +53,7 @@ fn test_occupied_and_remaining() {
|
||||
}
|
||||
|
||||
fn test_push_and_pop_many() {
|
||||
mut r := datatypes.new_ringbuffer<int>(4)
|
||||
mut r := datatypes.new_ringbuffer[int](4)
|
||||
a := [1, 2, 3, 4]
|
||||
r.push_many(a) or { panic(err) }
|
||||
|
||||
|
@ -1,27 +1,27 @@
|
||||
module datatypes
|
||||
|
||||
pub struct Set<T> {
|
||||
pub struct Set[T] {
|
||||
mut:
|
||||
elements map[T]u8
|
||||
}
|
||||
|
||||
// checks the element is exists.
|
||||
pub fn (set Set<T>) exists(element T) bool {
|
||||
pub fn (set Set[T]) exists(element T) bool {
|
||||
return element in set.elements
|
||||
}
|
||||
|
||||
// adds the element to set, if it is not present already.
|
||||
pub fn (mut set Set<T>) add(element T) {
|
||||
pub fn (mut set Set[T]) add(element T) {
|
||||
set.elements[element] = 1
|
||||
}
|
||||
|
||||
// removes the element from set.
|
||||
pub fn (mut set Set<T>) remove(element T) {
|
||||
pub fn (mut set Set[T]) remove(element T) {
|
||||
set.elements.delete(element)
|
||||
}
|
||||
|
||||
// pick returns an arbitrary element of set, if set is not empty.
|
||||
pub fn (set Set<T>) pick() ?T {
|
||||
pub fn (set Set[T]) pick() ?T {
|
||||
for k, _ in set.elements {
|
||||
return k
|
||||
}
|
||||
@ -29,31 +29,31 @@ pub fn (set Set<T>) pick() ?T {
|
||||
}
|
||||
|
||||
// rest returns the set consisting of all elements except for the arbitrary element.
|
||||
pub fn (mut set Set<T>) rest() ?[]T {
|
||||
pub fn (mut set Set[T]) rest() ?[]T {
|
||||
element := set.pick()?
|
||||
return set.elements.keys().filter(it != element)
|
||||
}
|
||||
|
||||
// pop returns an arbitrary element and deleting it from set.
|
||||
pub fn (mut set Set<T>) pop() ?T {
|
||||
pub fn (mut set Set[T]) pop() ?T {
|
||||
element := set.pick()?
|
||||
set.elements.delete(element)
|
||||
return element
|
||||
}
|
||||
|
||||
// delete all elements of set.
|
||||
pub fn (mut set Set<T>) clear() {
|
||||
pub fn (mut set Set[T]) clear() {
|
||||
set.elements = map[T]u8{}
|
||||
}
|
||||
|
||||
// equal checks whether the two given sets are equal (i.e. contain all and only the same elements).
|
||||
[deprecated: 'use set1<T> == set2<T> instead']
|
||||
pub fn (l Set<T>) equal(r Set<T>) bool {
|
||||
pub fn (l Set[T]) equal(r Set[T]) bool {
|
||||
return l == r
|
||||
}
|
||||
|
||||
// == checks whether the two given sets are equal (i.e. contain all and only the same elements).
|
||||
pub fn (l Set<T>) == (r Set<T>) bool {
|
||||
pub fn (l Set[T]) == (r Set[T]) bool {
|
||||
if l.elements.len != r.elements.len {
|
||||
return false
|
||||
}
|
||||
@ -66,31 +66,31 @@ pub fn (l Set<T>) == (r Set<T>) bool {
|
||||
}
|
||||
|
||||
// is_empty checks whether the set is empty or not.
|
||||
pub fn (set Set<T>) is_empty() bool {
|
||||
pub fn (set Set[T]) is_empty() bool {
|
||||
return set.size() == 0
|
||||
}
|
||||
|
||||
// size returns the number of elements in the set.
|
||||
pub fn (set Set<T>) size() int {
|
||||
pub fn (set Set[T]) size() int {
|
||||
return set.elements.len
|
||||
}
|
||||
|
||||
// copy returns a copy of all the elements in the set.
|
||||
pub fn (set Set<T>) copy() Set<T> {
|
||||
return Set<T>{
|
||||
pub fn (set Set[T]) copy() Set[T] {
|
||||
return Set[T]{
|
||||
elements: set.elements.clone()
|
||||
}
|
||||
}
|
||||
|
||||
// add_all adds the whole `elements` array to the set
|
||||
pub fn (mut set Set<T>) add_all(elements []T) {
|
||||
pub fn (mut set Set[T]) add_all(elements []T) {
|
||||
for element in elements {
|
||||
set.add(element)
|
||||
}
|
||||
}
|
||||
|
||||
// @union returns the union of the two sets.
|
||||
pub fn (l Set<T>) @union(r Set<T>) Set<T> {
|
||||
pub fn (l Set[T]) @union(r Set[T]) Set[T] {
|
||||
mut set := l
|
||||
for e, _ in r.elements {
|
||||
set.add(e)
|
||||
@ -99,7 +99,7 @@ pub fn (l Set<T>) @union(r Set<T>) Set<T> {
|
||||
}
|
||||
|
||||
// intersection returns the intersection of sets.
|
||||
pub fn (l Set<T>) intersection(r Set<T>) Set<T> {
|
||||
pub fn (l Set[T]) intersection(r Set[T]) Set[T] {
|
||||
mut set := l
|
||||
for e, _ in l.elements {
|
||||
if !r.exists(e) {
|
||||
@ -116,12 +116,12 @@ pub fn (l Set<T>) intersection(r Set<T>) Set<T> {
|
||||
|
||||
// difference returns the difference of sets.
|
||||
[deprecated: 'use set1<T> - set2<T> instead']
|
||||
pub fn (l Set<T>) difference(r Set<T>) Set<T> {
|
||||
pub fn (l Set[T]) difference(r Set[T]) Set[T] {
|
||||
return l - r
|
||||
}
|
||||
|
||||
// - returns the difference of sets.
|
||||
pub fn (l Set<T>) - (r Set<T>) Set<T> {
|
||||
pub fn (l Set[T]) - (r Set[T]) Set[T] {
|
||||
mut set := l
|
||||
for e, _ in l.elements {
|
||||
if r.exists(e) {
|
||||
@ -132,7 +132,7 @@ pub fn (l Set<T>) - (r Set<T>) Set<T> {
|
||||
}
|
||||
|
||||
// subset returns true if the set `r` is a subset of the set `l`.
|
||||
pub fn (l Set<T>) subset(r Set<T>) bool {
|
||||
pub fn (l Set[T]) subset(r Set[T]) bool {
|
||||
for e, _ in r.elements {
|
||||
if e !in l.elements {
|
||||
return false
|
||||
|
@ -1,14 +1,14 @@
|
||||
module datatypes
|
||||
|
||||
fn test_exists() {
|
||||
mut set := Set<string>{}
|
||||
mut set := Set[string]{}
|
||||
set.add('foo')
|
||||
assert set.exists('foo')
|
||||
assert set.exists('bar') == false
|
||||
}
|
||||
|
||||
fn test_remove() {
|
||||
mut set := Set<string>{}
|
||||
mut set := Set[string]{}
|
||||
set.remove('foo')
|
||||
set.add('foo')
|
||||
assert set.exists('foo')
|
||||
@ -17,28 +17,28 @@ fn test_remove() {
|
||||
}
|
||||
|
||||
fn test_size() {
|
||||
mut set := Set<string>{}
|
||||
mut set := Set[string]{}
|
||||
set.add('foo')
|
||||
set.add('foo')
|
||||
assert set.size() == 1
|
||||
}
|
||||
|
||||
fn test_pop() {
|
||||
mut set := Set<string>{}
|
||||
mut set := Set[string]{}
|
||||
set.add('foo')
|
||||
set.pop() or { return }
|
||||
assert set.exists('foo') == false
|
||||
}
|
||||
|
||||
fn test_clear() {
|
||||
mut set := Set<string>{}
|
||||
mut set := Set[string]{}
|
||||
set.add('foo')
|
||||
set.clear()
|
||||
assert set.size() == 0
|
||||
}
|
||||
|
||||
fn test_rest() {
|
||||
mut set := Set<string>{}
|
||||
mut set := Set[string]{}
|
||||
set.add('foo')
|
||||
set.add('bar')
|
||||
array := set.rest() or { return }
|
||||
@ -46,8 +46,8 @@ fn test_rest() {
|
||||
}
|
||||
|
||||
fn test_equal() {
|
||||
mut first_set := Set<string>{}
|
||||
mut second_set := Set<string>{}
|
||||
mut first_set := Set[string]{}
|
||||
mut second_set := Set[string]{}
|
||||
first_set.add('foo')
|
||||
assert second_set != first_set
|
||||
second_set.add('foo')
|
||||
@ -55,15 +55,15 @@ fn test_equal() {
|
||||
}
|
||||
|
||||
fn test_is_empty() {
|
||||
mut set := Set<string>{}
|
||||
mut set := Set[string]{}
|
||||
assert set.is_empty()
|
||||
set.add('foo')
|
||||
assert set.is_empty() == false
|
||||
}
|
||||
|
||||
fn test_union() {
|
||||
mut first_set := Set<string>{}
|
||||
mut second_set := Set<string>{}
|
||||
mut first_set := Set[string]{}
|
||||
mut second_set := Set[string]{}
|
||||
first_set.add_all(['b', 'c', 'd'])
|
||||
second_set.add_all(['a', 'e'])
|
||||
mut third_set := first_set.@union(second_set)
|
||||
@ -75,9 +75,9 @@ fn test_union() {
|
||||
}
|
||||
|
||||
fn test_intersection() {
|
||||
mut first_set := Set<string>{}
|
||||
mut first_set := Set[string]{}
|
||||
first_set.add_all(['foo', 'bar', 'baz'])
|
||||
mut second_set := Set<string>{}
|
||||
mut second_set := Set[string]{}
|
||||
second_set.add_all(['bar', 'baz', 'boo'])
|
||||
mut third_set := first_set.intersection(second_set)
|
||||
assert third_set.exists('foo') == false
|
||||
@ -87,8 +87,8 @@ fn test_intersection() {
|
||||
}
|
||||
|
||||
fn test_difference() {
|
||||
mut first_set := Set<string>{}
|
||||
mut second_set := Set<string>{}
|
||||
mut first_set := Set[string]{}
|
||||
mut second_set := Set[string]{}
|
||||
first_set.add_all(['foo', 'bar', 'baz'])
|
||||
second_set.add_all(['bar', 'baz', 'boo'])
|
||||
mut third_set := first_set - second_set
|
||||
@ -109,9 +109,9 @@ fn test_difference() {
|
||||
}
|
||||
|
||||
fn test_subset() {
|
||||
mut set := Set<string>{}
|
||||
mut set := Set[string]{}
|
||||
set.add_all(['a', 'b', 'c'])
|
||||
mut subset := Set<string>{}
|
||||
mut subset := Set[string]{}
|
||||
subset.add_all(['b', 'c'])
|
||||
assert set.subset(subset)
|
||||
}
|
||||
|
@ -1,41 +1,41 @@
|
||||
module datatypes
|
||||
|
||||
pub struct Stack<T> {
|
||||
pub struct Stack[T] {
|
||||
mut:
|
||||
elements []T
|
||||
}
|
||||
|
||||
// is_empty checks if the stack is empty
|
||||
pub fn (stack Stack<T>) is_empty() bool {
|
||||
pub fn (stack Stack[T]) is_empty() bool {
|
||||
return stack.elements.len == 0
|
||||
}
|
||||
|
||||
// len returns the length of the stack
|
||||
pub fn (stack Stack<T>) len() int {
|
||||
pub fn (stack Stack[T]) len() int {
|
||||
return stack.elements.len
|
||||
}
|
||||
|
||||
// peek returns the top of the stack
|
||||
pub fn (stack Stack<T>) peek() ?T {
|
||||
pub fn (stack Stack[T]) peek() ?T {
|
||||
return if !stack.is_empty() { stack.elements.last() } else { error('Stack is empty') }
|
||||
}
|
||||
|
||||
// push adds an element to the top of the stack
|
||||
pub fn (mut stack Stack<T>) push(item T) {
|
||||
pub fn (mut stack Stack[T]) push(item T) {
|
||||
stack.elements << item
|
||||
}
|
||||
|
||||
// pop removes the element at the top of the stack and returns it
|
||||
pub fn (mut stack Stack<T>) pop() ?T {
|
||||
pub fn (mut stack Stack[T]) pop() ?T {
|
||||
return if !stack.is_empty() { stack.elements.pop() } else { error('Stack is empty') }
|
||||
}
|
||||
|
||||
// str returns a string representation of the stack
|
||||
pub fn (stack Stack<T>) str() string {
|
||||
pub fn (stack Stack[T]) str() string {
|
||||
return stack.elements.str()
|
||||
}
|
||||
|
||||
// array returns a array representation of the stack
|
||||
pub fn (stack Stack<T>) array() []T {
|
||||
pub fn (stack Stack[T]) array() []T {
|
||||
return stack.elements
|
||||
}
|
||||
|
@ -1,14 +1,14 @@
|
||||
import datatypes as dt
|
||||
|
||||
fn test_is_empty() {
|
||||
mut stack := dt.Stack<int>{}
|
||||
mut stack := dt.Stack[int]{}
|
||||
assert stack.is_empty() == true
|
||||
stack.push(1)
|
||||
assert stack.is_empty() == false
|
||||
}
|
||||
|
||||
fn test_len() ? {
|
||||
mut stack := dt.Stack<int>{}
|
||||
mut stack := dt.Stack[int]{}
|
||||
assert stack.len() == 0
|
||||
stack.push(1)
|
||||
assert stack.len() == 1
|
||||
@ -17,18 +17,18 @@ fn test_len() ? {
|
||||
}
|
||||
|
||||
fn test_peek() ? {
|
||||
mut stack := dt.Stack<int>{}
|
||||
mut stack := dt.Stack[int]{}
|
||||
stack.push(1)
|
||||
assert stack.peek()? == 1
|
||||
stack.push(2)
|
||||
assert stack.peek()? == 2
|
||||
stack = dt.Stack<int>{}
|
||||
stack = dt.Stack[int]{}
|
||||
stack.peek() or { return }
|
||||
assert false
|
||||
}
|
||||
|
||||
fn test_push() ? {
|
||||
mut stack := dt.Stack<int>{}
|
||||
mut stack := dt.Stack[int]{}
|
||||
stack.push(1)
|
||||
assert stack.peek()? == 1
|
||||
stack.push(2)
|
||||
@ -38,7 +38,7 @@ fn test_push() ? {
|
||||
}
|
||||
|
||||
fn test_pop() ? {
|
||||
mut stack := dt.Stack<int>{}
|
||||
mut stack := dt.Stack[int]{}
|
||||
stack.push(1)
|
||||
stack.push(2)
|
||||
stack.push(3)
|
||||
@ -46,13 +46,13 @@ fn test_pop() ? {
|
||||
stack.push(4)
|
||||
assert stack.pop()? == 4
|
||||
assert stack.pop()? == 2
|
||||
stack = dt.Stack<int>{}
|
||||
stack = dt.Stack[int]{}
|
||||
stack.pop() or { return }
|
||||
assert false
|
||||
}
|
||||
|
||||
fn test_array() ? {
|
||||
mut stack := dt.Stack<int>{}
|
||||
mut stack := dt.Stack[int]{}
|
||||
stack.push(1)
|
||||
stack.push(2)
|
||||
assert stack.array() == [1, 2]
|
||||
|
Reference in New Issue
Block a user