Skip to content

Commit

Permalink
added non_emprt_list and tests
Browse files Browse the repository at this point in the history
  • Loading branch information
schurhammer committed May 26, 2023
1 parent 3f20b05 commit bd54c8e
Show file tree
Hide file tree
Showing 12 changed files with 1,031 additions and 90 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
- uses: erlef/[email protected]
with:
otp-version: "25.2"
gleam-version: "0.25.3"
gleam-version: "0.29.0"
rebar3-version: "3"
# elixir-version: "1.14.2"
- run: gleam format --check src test
Expand Down
139 changes: 69 additions & 70 deletions src/map.gleam
Original file line number Diff line number Diff line change
@@ -1,86 +1,85 @@
import gleam/option.{Option}
import gleam/order
import gleam/order.{Order}
import gleam/list
import structures/red_black_tree as tree
import structures/red_black_tree_kv as tree

type Map(a, b) =
tree.Tree(#(a, b))
type Map(k, v) =
tree.Tree(k, v)

// TODO need a new tree structure designed to compare only keys
// old structure just compares the whole value

pub fn delete(from map: Map(a, b), delete key: a) -> Map(a, b) {
todo
}

pub fn drop(from map: Map(a, b), drop disallowed_keys: List(a)) -> Map(a, b) {
todo
}

pub fn filter(in map: Map(a, b), for property: fn(a, b) -> Bool) -> Map(a, b) {
todo
}

pub fn fold(
over map: Map(a, b),
from initial: c,
with fun: fn(c, a, b) -> c,
) -> c {
todo
}

pub fn from_list(list: List(#(a, b))) -> Map(a, b) {
todo
}

pub fn get(from: Map(a, b), get: a) -> Result(b, Nil) {
todo
pub fn new(compare: fn(k, k) -> Order) -> Map(k, v) {
tree.new(compare)
}

pub fn has_key(map: Map(a, b), key: a) -> Bool {
todo
pub fn insert(into map: Map(k, v), key key: k, value value: v) -> Map(k, v) {
tree.insert(map, key, value)
}

pub fn insert(into map: Map(a, b), for key: a, insert value: b) -> Map(a, b) {
todo
pub fn find(in map: Map(k, v), key key: k) -> Result(#(k, v), Nil) {
tree.find(map, key)
}

pub fn keys(map: Map(a, b)) -> List(a) {
todo
pub fn has_key(in map: Map(k, v), key key: k) -> Bool {
case tree.find(map, key) {
Ok(_) -> True
Error(_) -> False
}
}

pub fn map_values(in map: Map(a, b), with fun: fn(a, b) -> c) -> Map(a, c) {
todo
pub fn delete(from map: Map(k, v), this key: k) -> Map(k, v) {
tree.delete(map, key)
}

pub fn merge(into map: Map(a, b), from new_entries: Map(a, b)) -> Map(a, b) {
todo
pub fn count(map: Map(k, v)) -> Int {
tree.fold(map, 0, fn(a, _, _) { a + 1 })
}

pub fn new() -> Map(a, b) {
todo
}

pub fn count(map: Map(a, b)) -> Int {
todo
}

pub fn take(from map: Map(a, b), keeping desired_keys: List(a)) -> Map(a, b) {
todo
}

pub fn to_list(map: Map(a, b)) -> List(#(a, b)) {
todo
}

pub fn update(
in map: Map(a, b),
update key: a,
with fun: fn(Option(b)) -> b,
) -> Map(a, b) {
todo
}

pub fn values(map: Map(a, b)) -> List(b) {
todo
pub fn fold(
over map: Map(k, v),
from initial: a,
with reducer: fn(a, k, v) -> a,
) -> a {
tree.fold(map, initial, reducer)
}

pub fn filter(in map: Map(k, v), for property: fn(k, v) -> Bool) -> Map(k, v) {
tree.fold(
map,
map,
fn(map, k, v) {
case property(k, v) {
True -> map
False -> tree.delete(map, k)
}
},
)
}

pub fn merge(this first: Map(k, v), and second: Map(k, v)) -> Map(k, v) {
tree.fold(first, second, fn(a, k, v) { tree.insert(a, k, v) })
}

// return the map keeping only keys in the list
pub fn take(from map: Map(k, v), keeping desired: List(k)) -> Map(k, v) {
case desired {
[x, ..xs] ->
case tree.find(map, x) {
Ok(x) -> tree.insert(take(map, xs), x.0, x.1)
Error(_) -> take(map, xs)
}
[] -> tree.clear(map)
}
}

pub fn from_list(
members: List(#(k, v)),
compare: fn(k, k) -> Order,
) -> Map(k, v) {
list.fold(
members,
tree.new(compare),
fn(tree, i) { tree.insert(tree, i.0, i.1) },
)
}

pub fn to_list(map: Map(k, v)) -> List(#(k, v)) {
tree.foldr(map, [], fn(a, k, v) { [#(k, v), ..a] })
}
61 changes: 60 additions & 1 deletion src/non_empty_list.gleam
Original file line number Diff line number Diff line change
@@ -1,4 +1,63 @@
import gleam/list

pub type NonEmptyList(a) {
End(first: a)
Item(first: a, rest: NonEmptyList(a))
Next(first: a, rest: NonEmptyList(a))
}

pub fn fold(
over list: NonEmptyList(a),
from initial: b,
with fun: fn(b, a) -> b,
) -> b {
case list {
End(item) -> fun(initial, item)
Next(x, xs) -> fold(xs, fun(initial, x), fun)
}
}

pub fn count(list: NonEmptyList(a)) -> Int {
fold(list, 0, fn(acc, _) { acc + 1 })
}

pub fn map(list: NonEmptyList(a), transform: fn(a) -> b) -> NonEmptyList(b) {
case list {
End(x) -> End(transform(x))
Next(x, xs) ->
fold(xs, End(transform(x)), fn(acc, item) { Next(transform(item), acc) })
|> reverse
}
}

pub fn filter(list: NonEmptyList(a), predicate: fn(a) -> Bool) -> List(a) {
fold(
list,
[],
fn(acc, item) {
case predicate(item) {
True -> [item, ..acc]
False -> acc
}
},
)
|> list.reverse()
}

pub fn to_list(list: NonEmptyList(a)) -> List(a) {
fold(list, [], fn(acc, item) { [item, ..acc] })
|> list.reverse()
}

pub fn from_list(list: List(a)) -> Result(NonEmptyList(a), Nil) {
case list {
[] -> Error(Nil)
[x, ..xs] -> Ok(list.fold(xs, End(x), fn(acc, item) { Next(item, acc) }))
}
}

pub fn reverse(list: NonEmptyList(a)) -> NonEmptyList(a) {
case list {
End(_) -> list
Next(x, xs) -> fold(xs, End(x), fn(acc, x) { Next(x, acc) })
}
}
4 changes: 2 additions & 2 deletions src/priority_queue.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ pub fn from_list(list: List(a), compare: fn(a, a) -> Order) -> Queue(a) {

pub fn is_empty(queue: Queue(a)) -> Bool {
case heap.find_min(queue) {
Ok(_) -> True
Error(_) -> False
Ok(_) -> False
Error(_) -> True
}
}

Expand Down
11 changes: 10 additions & 1 deletion src/set.gleam
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import gleam/order.{Order}
import gleam/list
import gleam/io
import gleam/string
import structures/red_black_tree as tree

type Set(a) =
Expand Down Expand Up @@ -74,7 +76,14 @@ pub fn take(from set: Set(a), keeping desired: List(a)) -> Set(a) {
}

pub fn to_list(set: Set(a)) -> List(a) {
tree.fold(set, [], fn(a, i) { [i, ..a] })
tree.foldr(
set,
[],
fn(a, i) {
io.println(string.inspect(i))
[i, ..a]
},
)
}

pub fn union(of first: Set(a), and second: Set(a)) -> Set(a) {
Expand Down
26 changes: 18 additions & 8 deletions src/structures/red_black_tree.gleam
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// Based on "Deletion: The curse of the red-black tree" by Germane (2014)

import gleam/order.{Eq, Gt, Lt, Order}
import gleam/io
import gleam/string

type Color {
R
Expand Down Expand Up @@ -34,14 +36,6 @@ pub fn delete(tree: Tree(a), key: a) -> Tree(a) {
Tree(del(redden(tree.root), key, tree.compare), tree.compare)
}

pub fn delete_matching(tree: Tree(a), key: a) -> Tree(a) {
Tree(del(redden(tree.root), key, tree.compare), tree.compare)
}

pub fn delete_match(tree: Tree(a), key: a) -> Tree(a) {
Tree(del(redden(tree.root), key, tree.compare), tree.compare)
}

pub fn find(tree: Tree(a), key: a) -> Result(a, Nil) {
do_find(tree.root, key, tree.compare)
}
Expand All @@ -50,6 +44,10 @@ pub fn fold(tree: Tree(a), acc: b, fun: fn(b, a) -> b) -> b {
do_fold(tree.root, acc, fun)
}

pub fn foldr(tree: Tree(a), acc: b, fun: fn(b, a) -> b) -> b {
do_foldr(tree.root, acc, fun)
}

pub fn draw(tree: Tree(a), to_string: fn(a) -> String) {
do_draw(tree.root, 0, to_string)
}
Expand Down Expand Up @@ -196,6 +194,18 @@ fn do_fold(node, acc, fun) {
}
}

fn do_foldr(node, acc, fun) {
case node {
T(_, r, v, l) -> {
let acc = do_foldr(l, acc, fun)
let acc = fun(acc, v)
let acc = do_foldr(r, acc, fun)
acc
}
_ -> acc
}
}

fn do_indent(acc, i) {
case i {
0 -> acc
Expand Down
Loading

0 comments on commit bd54c8e

Please sign in to comment.