fix: Reworked some api functions
Some checks failed
test / test (push) Has been cancelled

This commit is contained in:
2025-10-19 22:51:33 +01:00
parent a5efb0ae8d
commit f9aa688f5d

View File

@@ -11,7 +11,7 @@ pub opaque type Node(a) {
pub type DLList(a) { pub type DLList(a) {
DLList(counter: Int, current: Int, mem: dict.Dict(Int, Node(a))) DLList(counter: Int, current: Int, mem: dict.Dict(Int, Node(a)))
// CyclicList(counter: Int, current: Int, mem: dict.Dict(Int, Node(a))) CyclicList(counter: Int, current: Int, mem: dict.Dict(Int, Node(a)))
} }
pub fn main() { pub fn main() {
@@ -39,23 +39,35 @@ pub fn main() {
l1 |> echo l1 |> echo
let l1t = take(l1, 5) let l1t = take(l1, 5)
l1t |> echo l1t |> echo
let l2 = insert(l1, 2) let l2 = insert(l1, 2) |> move_left
l2 |> echo l2 |> echo
let l2t = take(l2, 5) let l2t = take(l2, 5)
l2t |> echo l2t |> echo
let l3 = insert(l2, 3) let l3 = insert(l2, 3)
l3 |> echo l3 |> echo
let l3t = take(l3, 7) to_list(l3) |> echo
l3t |> echo // let l3t = take(l3, 7)
let l3t2 = take_rev(l3, 7) // l3t |> echo
l3t2 |> echo // let l3t2 = take_rev(l3, 7)
// l3t2 |> echo
} }
pub fn new() -> DLList(a) { pub fn new() -> DLList(a) {
DLList(1, 0, dict.new()) DLList(1, 0, dict.new())
} }
pub fn new_cyclic() -> DLList(a) {
CyclicList(1, 0, dict.new())
}
fn clear(list: DLList(a)) -> DLList(a) {
case list {
DLList(_, _, _) -> DLList(1, 0, dict.new())
CyclicList(_, _, _) -> CyclicList(1, 0, dict.new())
}
}
fn get_curr_node(list: DLList(a)) -> Result(Node(a), Nil) { fn get_curr_node(list: DLList(a)) -> Result(Node(a), Nil) {
dict.get(list.mem, list.current) dict.get(list.mem, list.current)
} }
@@ -70,9 +82,13 @@ pub fn is_empty(list: DLList(a)) -> Bool {
pub fn insert(list: DLList(a), val: a) -> DLList(a) { pub fn insert(list: DLList(a), val: a) -> DLList(a) {
let ref = list.counter let ref = list.counter
let new_entry_ref = case list {
DLList(_, _, _) -> 0
CyclicList(_, _, _) -> ref
}
case is_empty(list) { case is_empty(list) {
True -> { True -> {
let node = Node(val, ref, ref) let node = Node(val, new_entry_ref, new_entry_ref)
DLList(ref + 1, ref, dict.insert(list.mem, ref, node)) DLList(ref + 1, ref, dict.insert(list.mem, ref, node))
} }
False -> { False -> {
@@ -104,6 +120,17 @@ pub fn insert(list: DLList(a), val: a) -> DLList(a) {
} }
} }
fn update_record(
list: DLList(a),
current: Int,
mem: dict.Dict(Int, Node(a)),
) -> DLList(a) {
case list {
DLList(_, _, _) -> DLList(..list, current:, mem:)
CyclicList(_, _, _) -> CyclicList(..list, current:, mem:)
}
}
pub fn delete(list: DLList(a)) -> DLList(a) { pub fn delete(list: DLList(a)) -> DLList(a) {
let #(mem, curr_node) = remove_lookup(list, list.current) let #(mem, curr_node) = remove_lookup(list, list.current)
case curr_node { case curr_node {
@@ -112,52 +139,50 @@ pub fn delete(list: DLList(a)) -> DLList(a) {
let l = curr_node.left let l = curr_node.left
let r = curr_node.right let r = curr_node.right
case l, r { case l, r {
0, 0 -> new() 0, 0 -> clear(list)
0, n if n == list.current -> new() 0, n if n == list.current -> clear(list)
n, 0 if n == list.current -> new() n, 0 if n == list.current -> clear(list)
n, m if n == list.current && m == list.current -> new() n, m if n == list.current && m == list.current -> clear(list)
_, 0 -> { _, 0 -> {
DLList( update_record(
..list, list,
current: l, l,
mem: update_dict_entry(mem, l, fn(n) { Node(..n, right: r) }), update_dict_entry(mem, l, fn(n) { Node(..n, right: r) }),
) )
} }
_, r if r == list.current -> { _, r if r == list.current -> {
DLList( update_record(
..list, list,
current: l, l,
mem: update_dict_entry(mem, l, fn(n) { Node(..n, right: l) }), update_dict_entry(mem, l, fn(n) { Node(..n, right: l) }),
) )
} }
0, _ -> { 0, _ -> {
DLList( update_record(
..list, list,
current: r, r,
mem: update_dict_entry(mem, r, fn(n) { Node(..n, left: l) }), update_dict_entry(mem, r, fn(n) { Node(..n, left: l) }),
) )
} }
l, _ if l == list.current -> { l, _ if l == list.current -> {
DLList( update_record(
..list, list,
current: r, r,
mem: update_dict_entry(mem, r, fn(n) { Node(..n, left: r) }), update_dict_entry(mem, r, fn(n) { Node(..n, left: r) }),
) )
} }
l, r if l == r -> { l, r if l == r -> {
DLList( update_record(
..list, list,
current: r, r,
mem: update_dict_entry(mem, r, fn(n) { update_dict_entry(mem, r, fn(n) { Node(..n, left: r, right: r) }),
Node(..n, left: r, right: r)
}),
) )
} }
_, _ -> { _, _ -> {
DLList( update_record(
..list, list,
current: r, r,
mem: update_dict_entry(mem, r, fn(n) { Node(..n, left: l) }) update_dict_entry(mem, r, fn(n) { Node(..n, left: l) })
|> update_dict_entry(l, fn(n) { Node(..n, right: r) }), |> update_dict_entry(l, fn(n) { Node(..n, right: r) }),
) )
} }
@@ -174,9 +199,10 @@ fn do_move_right(list: DLList(a)) -> Result(DLList(a), Nil) {
case get_curr_node(list) { case get_curr_node(list) {
Error(_) -> Error(Nil) Error(_) -> Error(Nil)
Ok(node) -> { Ok(node) -> {
case node.right { case node.right, list {
0 -> Ok(list) 0, _ -> Error(Nil)
r -> Ok(DLList(..list, current: r)) r, DLList(_, _, _) -> Ok(DLList(..list, current: r))
r, CyclicList(_, _, _) -> Ok(CyclicList(..list, current: r))
} }
} }
} }
@@ -191,9 +217,10 @@ fn do_move_left(list: DLList(a)) -> Result(DLList(a), Nil) {
case get_curr_node(list) { case get_curr_node(list) {
Error(_) -> Error(Nil) Error(_) -> Error(Nil)
Ok(node) -> { Ok(node) -> {
case node.left { case node.left, list {
0 -> Ok(list) 0, _ -> Error(Nil)
l -> Ok(DLList(..list, current: l)) l, DLList(_, _, _) -> Ok(DLList(..list, current: l))
l, CyclicList(_, _, _) -> Ok(CyclicList(..list, current: l))
} }
} }
} }
@@ -208,13 +235,19 @@ pub fn take(list: DLList(a), n_times: Int) -> List(a) {
} }
fn take_loop(list: DLList(a), n_times: Int, acc: List(a)) -> List(a) { fn take_loop(list: DLList(a), n_times: Int, acc: List(a)) -> List(a) {
list |> echo
use <- bool.guard(when: is_empty(list), return: []) use <- bool.guard(when: is_empty(list), return: [])
case n_times { case n_times {
0 -> list.reverse(acc) 0 -> list.reverse(acc)
n -> { n -> {
case get(list) { case get(list) {
Error(_) -> [] Error(_) -> []
Ok(item) -> take_rev_loop(move_right(list), n - 1, [item, ..acc]) Ok(item) -> {
case move_right(list) {
r if r != list -> take_loop(r, n - 1, [item, ..acc])
_ -> list.reverse([item, ..acc])
}
}
} }
} }
} }
@@ -231,32 +264,36 @@ fn take_rev_loop(list: DLList(a), n_times: Int, acc: List(a)) -> List(a) {
n -> { n -> {
case get(list) { case get(list) {
Error(_) -> [] Error(_) -> []
Ok(item) -> take_rev_loop(move_left(list), n - 1, [item, ..acc]) Ok(item) -> {
case move_left(list) {
l if l != list -> take_rev_loop(l, n - 1, [item, ..acc])
_ -> list.reverse([item, ..acc])
}
}
} }
} }
} }
} }
pub fn to_list(list: DLList(a)) -> List(a) { pub fn to_list(list: DLList(a)) -> List(a) {
case is_empty(list) { let list = case list {
True -> [] DLList(_, _, _) -> DLList(..list, current: 1)
False -> { CyclicList(_, _, _) -> list
case get(list) {
Error(_) -> []
Ok(val) -> [val, ..to_list_loop(do_move_right(list), list.current)]
}
}
} }
to_list_loop(Ok(list), list.current, [])
} }
fn to_list_loop(list: Result(DLList(a), Nil), start_ref: Int) -> List(a) { fn to_list_loop(
list: Result(DLList(a), Nil),
start_ref: Int,
acc: List(a),
) -> List(a) {
case list { case list {
Error(_) -> [] Error(_) -> list.reverse(acc)
Ok(DLList(_, current, _)) if current == start_ref -> []
Ok(list) -> { Ok(list) -> {
case get(list) { case get(list) {
Error(_) -> [] Error(_) -> []
Ok(val) -> [val, ..to_list_loop(do_move_right(list), start_ref)] Ok(val) -> to_list_loop(do_move_right(list), start_ref, [val, ..acc])
} }
} }
} }
@@ -264,9 +301,9 @@ fn to_list_loop(list: Result(DLList(a), Nil), start_ref: Int) -> List(a) {
pub fn update(list: DLList(a), value: a) -> Result(DLList(a), Nil) { pub fn update(list: DLList(a), value: a) -> Result(DLList(a), Nil) {
use <- bool.guard(when: is_empty(list), return: Error(Nil)) use <- bool.guard(when: is_empty(list), return: Error(Nil))
case get_curr_node(list) { case get_curr_node(list), list {
Error(_) -> Error(Nil) Error(_), _ -> Error(Nil)
Ok(curr_node) -> Ok(curr_node), DLList(_, _, _) ->
Ok( Ok(
DLList( DLList(
..list, ..list,
@@ -277,6 +314,17 @@ pub fn update(list: DLList(a), value: a) -> Result(DLList(a), Nil) {
), ),
), ),
) )
Ok(curr_node), CyclicList(_, _, _) ->
Ok(
CyclicList(
..list,
mem: dict.insert(
list.mem,
list.current,
Node(..curr_node, val: value),
),
),
)
} }
} }