-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Somehow I made an oopsies by overwriting the init file for linkedlist…
… to its test file...
- Loading branch information
1 parent
72a79a9
commit 5762dbe
Showing
2 changed files
with
174 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,169 @@ | ||
local testkit = require("../../testkit") | ||
local linkedlist = require("linkedlist") | ||
--!native | ||
|
||
local TEST, CASE, CHECK, FINISH = testkit.test() | ||
-- linked list | ||
-- a doubly-linked list impl in luau, easily inserts and deletes arbitrarily without reordering. | ||
-- a reference to the entry to insert or delete at is required. References to the front and back of | ||
-- the list always exist. | ||
-- originally made by last talon, uh heavily modified by me (kalrnlo) because im a nitpicker | ||
-- w a changed up api to directly expose the nodes and also not create a new closure | ||
-- for every node created | ||
-- og: https://github.com/LastTalon/linked-list | ||
|
||
TEST("linked list", function() | ||
type NodePrototype<V> = { | ||
__call: (self: Node<V>) -> V, | ||
} | ||
|
||
end) | ||
export type Node<V> = typeof(setmetatable({} :: { | ||
next: Node<V>?, | ||
prev: Node<V>?, | ||
value: V, | ||
}, {} :: NodePrototype<V>)) | ||
|
||
|
||
export type LinkedList<V> = { | ||
front: Node<V>?, | ||
back: Node<V>?, | ||
len: number, | ||
} | ||
|
||
local function remove_node<V>(list: LinkedList<V>, node: Node<V>): V | ||
local prev_node = node.prev | ||
local next_node = node.next | ||
|
||
if prev_node then | ||
prev_node.next = next_node | ||
else | ||
list.front = next_node | ||
end | ||
|
||
if next_node then | ||
next_node.prev = prev_node | ||
else | ||
list.back = prev_node | ||
end | ||
list.len -= 1 | ||
return node.value | ||
end | ||
|
||
local node_mt = table.freeze({ | ||
__call = function<V>(node: Node<V>): V | ||
return node.value | ||
end, | ||
}) | ||
|
||
local function create_node<V>(value: V): Node<V> | ||
return setmetatable({ | ||
value = value, | ||
next = nil, | ||
prev = nil | ||
}, node_mt) :: any | ||
end | ||
|
||
local linkedlist = {} | ||
|
||
function linkedlist.push<V>(list: LinkedList<V>, value: V) | ||
local node = create_node(value) | ||
local back = list.back | ||
|
||
node.prev = back | ||
|
||
if back then | ||
back.next = node | ||
else | ||
list.front = node | ||
end | ||
list.back = node | ||
list.len += 1 | ||
|
||
return node | ||
end | ||
|
||
function linkedlist.unshift<V>(list: LinkedList<V>, value: V): Node<V> | ||
local node = create_node(value) | ||
local front = list.front | ||
|
||
node.next = front | ||
|
||
if front then | ||
front.prev = node | ||
else | ||
list.back = node | ||
end | ||
list.front = node | ||
|
||
return node | ||
end | ||
|
||
function linkedlist.shift<V>(list: LinkedList<V>): Node<V>? | ||
local node = list.front | ||
|
||
if node then | ||
remove_node(list, node) | ||
return node | ||
else | ||
return nil | ||
end | ||
end | ||
|
||
function linkedlist.pop<V>(list: LinkedList<V>): Node<V>? | ||
local node = list.back | ||
|
||
if node then | ||
remove_node(list, node) | ||
return node | ||
else | ||
return nil | ||
end | ||
end | ||
|
||
function linkedlist.iter<V>(list: LinkedList<V>): () -> (number, Node<V>) | ||
local node = list.front | ||
local index = 0 | ||
|
||
return function() | ||
if not node then | ||
return nil :: any, nil :: any | ||
end | ||
|
||
local current_node = node | ||
node = node.next | ||
index += 1 | ||
return index, current_node | ||
end | ||
end | ||
|
||
function linkedlist.reverse_iter<V>(list: LinkedList<V>): () -> (number, Node<V>) | ||
local node = list.back | ||
local index = list.len + 1 | ||
|
||
return function() | ||
if not node then | ||
return nil :: any, nil :: any | ||
end | ||
|
||
local current = node | ||
node = node.prev | ||
index -= 1 | ||
return index, current | ||
end | ||
end | ||
|
||
function linkedlist.clear<V>(list: LinkedList<V>) | ||
list.front = nil | ||
list.back = nil | ||
list.len = 0 | ||
end | ||
|
||
linkedlist.remove = remove_node | ||
|
||
local list_mt = { | ||
__call = function<S, V>(self: S): LinkedList<V> | ||
return { | ||
front = nil, | ||
back = nil, | ||
len = 0, | ||
} | ||
end | ||
} | ||
|
||
return table.freeze(setmetatable(linkedlist, table.freeze(list_mt))) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
local testkit = require("../../testkit") | ||
local linkedlist = require("init") | ||
|
||
local TEST, CASE, CHECK, FINISH = testkit.test() | ||
|
||
TEST("linked list", function() | ||
|
||
end) |