aboutsummaryrefslogtreecommitdiff
path: root/aoc2017-gleam/src/helpers/state.gleam
diff options
context:
space:
mode:
authorH.J <thechairman@thechairman.info>2024-06-17 15:10:31 -0400
committerH.J <thechairman@thechairman.info>2024-06-17 15:10:31 -0400
commit413891726756aed407a2cfbceb4cf0e14bbcc982 (patch)
tree4b970eb97a54bcf84e01eea225a62f4ead7b621c /aoc2017-gleam/src/helpers/state.gleam
parent70fda8e4513d6de7d1a2cc6c701b7ae36cd83850 (diff)
downloadgleam_aoc-413891726756aed407a2cfbceb4cf0e14bbcc982.tar.gz
gleam_aoc-413891726756aed407a2cfbceb4cf0e14bbcc982.zip
gleam 2017 day 14 complete
Diffstat (limited to 'aoc2017-gleam/src/helpers/state.gleam')
-rw-r--r--aoc2017-gleam/src/helpers/state.gleam55
1 files changed, 55 insertions, 0 deletions
diff --git a/aoc2017-gleam/src/helpers/state.gleam b/aoc2017-gleam/src/helpers/state.gleam
new file mode 100644
index 0000000..cbbad81
--- /dev/null
+++ b/aoc2017-gleam/src/helpers/state.gleam
@@ -0,0 +1,55 @@
+import gleam/erlang/process.{type Subject, Normal}
+import gleam/option.{None}
+import gleam/otp/actor.{type Next, Continue, Stop}
+import gleam/set.{type Set}
+
+const timeout = 1000
+
+pub type Message(k) {
+ Shutdown
+ Check(key: k, client: Subject(Bool))
+ Add(key: k)
+ Drop(key: k)
+ Pop(client: Subject(Result(k, Nil)))
+}
+
+fn handle_message(message: Message(k), set: Set(k)) -> Next(Message(k), Set(k)) {
+ case message {
+ Shutdown -> Stop(Normal)
+ Check(key, client) -> {
+ process.send(client, set.contains(set, key))
+ Continue(set, None)
+ }
+ Add(key) -> Continue(set.insert(set, key), None)
+ Drop(key) -> Continue(set.delete(set, key), None)
+ Pop(client) -> {
+ case set.to_list(set) {
+ [next, ..] -> {
+ process.send(client, Ok(next))
+ Continue(set.delete(set, next), None)
+ }
+ [] -> {
+ process.send(client, Error(Nil))
+ Stop(Normal)
+ }
+ }
+ }
+ }
+}
+
+pub fn start_actor(with: Set(a)) {
+ let assert Ok(actor) = actor.start(with, handle_message)
+ actor
+}
+
+pub fn pop(actor) {
+ process.call(actor, Pop, timeout)
+}
+
+pub fn check(actor, value) {
+ process.call(actor, Check(value, _), timeout)
+}
+
+pub fn drop(actor, value) {
+ process.send(actor, Drop(value))
+}