aboutsummaryrefslogtreecommitdiff
path: root/aoc2023/build/packages/gleam_stdlib/src
diff options
context:
space:
mode:
Diffstat (limited to 'aoc2023/build/packages/gleam_stdlib/src')
-rw-r--r--aoc2023/build/packages/gleam_stdlib/src/dict.mjs957
-rw-r--r--aoc2023/build/packages/gleam_stdlib/src/gleam/base.gleam21
-rw-r--r--aoc2023/build/packages/gleam_stdlib/src/gleam/bit_array.gleam157
-rw-r--r--aoc2023/build/packages/gleam_stdlib/src/gleam/bit_builder.gleam80
-rw-r--r--aoc2023/build/packages/gleam_stdlib/src/gleam/bit_string.gleam43
-rw-r--r--aoc2023/build/packages/gleam_stdlib/src/gleam/bool.gleam428
-rw-r--r--aoc2023/build/packages/gleam_stdlib/src/gleam/bytes_builder.gleam197
-rw-r--r--aoc2023/build/packages/gleam_stdlib/src/gleam/dict.gleam544
-rw-r--r--aoc2023/build/packages/gleam_stdlib/src/gleam/dynamic.gleam1508
-rw-r--r--aoc2023/build/packages/gleam_stdlib/src/gleam/float.gleam546
-rw-r--r--aoc2023/build/packages/gleam_stdlib/src/gleam/function.gleam162
-rw-r--r--aoc2023/build/packages/gleam_stdlib/src/gleam/int.gleam874
-rw-r--r--aoc2023/build/packages/gleam_stdlib/src/gleam/io.gleam117
-rw-r--r--aoc2023/build/packages/gleam_stdlib/src/gleam/iterator.gleam1530
-rw-r--r--aoc2023/build/packages/gleam_stdlib/src/gleam/list.gleam2154
-rw-r--r--aoc2023/build/packages/gleam_stdlib/src/gleam/map.gleam127
-rw-r--r--aoc2023/build/packages/gleam_stdlib/src/gleam/option.gleam346
-rw-r--r--aoc2023/build/packages/gleam_stdlib/src/gleam/order.gleam133
-rw-r--r--aoc2023/build/packages/gleam_stdlib/src/gleam/pair.gleam85
-rw-r--r--aoc2023/build/packages/gleam_stdlib/src/gleam/queue.gleam292
-rw-r--r--aoc2023/build/packages/gleam_stdlib/src/gleam/regex.gleam214
-rw-r--r--aoc2023/build/packages/gleam_stdlib/src/gleam/result.gleam482
-rw-r--r--aoc2023/build/packages/gleam_stdlib/src/gleam/set.gleam264
-rw-r--r--aoc2023/build/packages/gleam_stdlib/src/gleam/string.gleam906
-rw-r--r--aoc2023/build/packages/gleam_stdlib/src/gleam/string_builder.gleam298
-rw-r--r--aoc2023/build/packages/gleam_stdlib/src/gleam/uri.gleam462
-rw-r--r--aoc2023/build/packages/gleam_stdlib/src/gleam@base.erl20
-rw-r--r--aoc2023/build/packages/gleam_stdlib/src/gleam@bit_array.erl102
-rw-r--r--aoc2023/build/packages/gleam_stdlib/src/gleam@bit_builder.erl66
-rw-r--r--aoc2023/build/packages/gleam_stdlib/src/gleam@bit_string.erl33
-rw-r--r--aoc2023/build/packages/gleam_stdlib/src/gleam@bool.erl162
-rw-r--r--aoc2023/build/packages/gleam_stdlib/src/gleam@bytes_builder.erl87
-rw-r--r--aoc2023/build/packages/gleam_stdlib/src/gleam@dict.erl97
-rw-r--r--aoc2023/build/packages/gleam_stdlib/src/gleam@dynamic.erl808
-rw-r--r--aoc2023/build/packages/gleam_stdlib/src/gleam@float.erl181
-rw-r--r--aoc2023/build/packages/gleam_stdlib/src/gleam@function.erl67
-rw-r--r--aoc2023/build/packages/gleam_stdlib/src/gleam@int.erl332
-rw-r--r--aoc2023/build/packages/gleam_stdlib/src/gleam@io.erl27
-rw-r--r--aoc2023/build/packages/gleam_stdlib/src/gleam@iterator.erl744
-rw-r--r--aoc2023/build/packages/gleam_stdlib/src/gleam@list.erl1129
-rw-r--r--aoc2023/build/packages/gleam_stdlib/src/gleam@map.erl76
-rw-r--r--aoc2023/build/packages/gleam_stdlib/src/gleam@option.erl147
-rw-r--r--aoc2023/build/packages/gleam_stdlib/src/gleam@order.erl79
-rw-r--r--aoc2023/build/packages/gleam_stdlib/src/gleam@pair.erl33
-rw-r--r--aoc2023/build/packages/gleam_stdlib/src/gleam@queue.erl121
-rw-r--r--aoc2023/build/packages/gleam_stdlib/src/gleam@regex.erl33
-rw-r--r--aoc2023/build/packages/gleam_stdlib/src/gleam@result.erl201
-rw-r--r--aoc2023/build/packages/gleam_stdlib/src/gleam@set.erl85
-rw-r--r--aoc2023/build/packages/gleam_stdlib/src/gleam@string.erl352
-rw-r--r--aoc2023/build/packages/gleam_stdlib/src/gleam@string_builder.erl91
-rw-r--r--aoc2023/build/packages/gleam_stdlib/src/gleam@uri.erl252
-rw-r--r--aoc2023/build/packages/gleam_stdlib/src/gleam_stdlib.app.src31
-rw-r--r--aoc2023/build/packages/gleam_stdlib/src/gleam_stdlib.erl529
-rw-r--r--aoc2023/build/packages/gleam_stdlib/src/gleam_stdlib.mjs875
54 files changed, 0 insertions, 19687 deletions
diff --git a/aoc2023/build/packages/gleam_stdlib/src/dict.mjs b/aoc2023/build/packages/gleam_stdlib/src/dict.mjs
deleted file mode 100644
index a8309e0..0000000
--- a/aoc2023/build/packages/gleam_stdlib/src/dict.mjs
+++ /dev/null
@@ -1,957 +0,0 @@
-/**
- * This file uses jsdoc to annotate types.
- * These types can be checked using the typescript compiler with "checkjs" option.
- */
-
-import { isEqual } from "./gleam.mjs";
-
-const referenceMap = new WeakMap();
-const tempDataView = new DataView(new ArrayBuffer(8));
-let referenceUID = 0;
-/**
- * hash the object by reference using a weak map and incrementing uid
- * @param {any} o
- * @returns {number}
- */
-function hashByReference(o) {
- const known = referenceMap.get(o);
- if (known !== undefined) {
- return known;
- }
- const hash = referenceUID++;
- if (referenceUID === 0x7fffffff) {
- referenceUID = 0;
- }
- referenceMap.set(o, hash);
- return hash;
-}
-/**
- * merge two hashes in an order sensitive way
- * @param {number} a
- * @param {number} b
- * @returns {number}
- */
-function hashMerge(a, b) {
- return (a ^ (b + 0x9e3779b9 + (a << 6) + (a >> 2))) | 0;
-}
-/**
- * standard string hash popularised by java
- * @param {string} s
- * @returns {number}
- */
-function hashString(s) {
- let hash = 0;
- const len = s.length;
- for (let i = 0; i < len; i++) {
- hash = (Math.imul(31, hash) + s.charCodeAt(i)) | 0;
- }
- return hash;
-}
-/**
- * hash a number by converting to two integers and do some jumbling
- * @param {number} n
- * @returns {number}
- */
-function hashNumber(n) {
- tempDataView.setFloat64(0, n);
- const i = tempDataView.getInt32(0);
- const j = tempDataView.getInt32(4);
- return Math.imul(0x45d9f3b, (i >> 16) ^ i) ^ j;
-}
-/**
- * hash a BigInt by converting it to a string and hashing that
- * @param {BigInt} n
- * @returns {number}
- */
-function hashBigInt(n) {
- return hashString(n.toString());
-}
-/**
- * hash any js object
- * @param {any} o
- * @returns {number}
- */
-function hashObject(o) {
- const proto = Object.getPrototypeOf(o);
- if (proto !== null && typeof proto.hashCode === "function") {
- try {
- const code = o.hashCode(o);
- if (typeof code === "number") {
- return code;
- }
- } catch {}
- }
- if (o instanceof Promise || o instanceof WeakSet || o instanceof WeakMap) {
- return hashByReference(o);
- }
- if (o instanceof Date) {
- return hashNumber(o.getTime());
- }
- let h = 0;
- if (o instanceof ArrayBuffer) {
- o = new Uint8Array(o);
- }
- if (Array.isArray(o) || o instanceof Uint8Array) {
- for (let i = 0; i < o.length; i++) {
- h = (Math.imul(31, h) + getHash(o[i])) | 0;
- }
- } else if (o instanceof Set) {
- o.forEach((v) => {
- h = (h + getHash(v)) | 0;
- });
- } else if (o instanceof Map) {
- o.forEach((v, k) => {
- h = (h + hashMerge(getHash(v), getHash(k))) | 0;
- });
- } else {
- const keys = Object.keys(o);
- for (let i = 0; i < keys.length; i++) {
- const k = keys[i];
- const v = o[k];
- h = (h + hashMerge(getHash(v), hashString(k))) | 0;
- }
- }
- return h;
-}
-/**
- * hash any js value
- * @param {any} u
- * @returns {number}
- */
-export function getHash(u) {
- if (u === null) return 0x42108422;
- if (u === undefined) return 0x42108423;
- if (u === true) return 0x42108421;
- if (u === false) return 0x42108420;
- switch (typeof u) {
- case "number":
- return hashNumber(u);
- case "string":
- return hashString(u);
- case "bigint":
- return hashBigInt(u);
- case "object":
- return hashObject(u);
- case "symbol":
- return hashByReference(u);
- case "function":
- return hashByReference(u);
- default:
- return 0; // should be unreachable
- }
-}
-/**
- * @template K,V
- * @typedef {ArrayNode<K,V> | IndexNode<K,V> | CollisionNode<K,V>} Node
- */
-/**
- * @template K,V
- * @typedef {{ type: typeof ENTRY, k: K, v: V }} Entry
- */
-/**
- * @template K,V
- * @typedef {{ type: typeof ARRAY_NODE, size: number, array: (undefined | Entry<K,V> | Node<K,V>)[] }} ArrayNode
- */
-/**
- * @template K,V
- * @typedef {{ type: typeof INDEX_NODE, bitmap: number, array: (Entry<K,V> | Node<K,V>)[] }} IndexNode
- */
-/**
- * @template K,V
- * @typedef {{ type: typeof COLLISION_NODE, hash: number, array: Entry<K, V>[] }} CollisionNode
- */
-/**
- * @typedef {{ val: boolean }} Flag
- */
-const SHIFT = 5; // number of bits you need to shift by to get the next bucket
-const BUCKET_SIZE = Math.pow(2, SHIFT);
-const MASK = BUCKET_SIZE - 1; // used to zero out all bits not in the bucket
-const MAX_INDEX_NODE = BUCKET_SIZE / 2; // when does index node grow into array node
-const MIN_ARRAY_NODE = BUCKET_SIZE / 4; // when does array node shrink to index node
-const ENTRY = 0;
-const ARRAY_NODE = 1;
-const INDEX_NODE = 2;
-const COLLISION_NODE = 3;
-/** @type {IndexNode<any,any>} */
-const EMPTY = {
- type: INDEX_NODE,
- bitmap: 0,
- array: [],
-};
-/**
- * Mask the hash to get only the bucket corresponding to shift
- * @param {number} hash
- * @param {number} shift
- * @returns {number}
- */
-function mask(hash, shift) {
- return (hash >>> shift) & MASK;
-}
-/**
- * Set only the Nth bit where N is the masked hash
- * @param {number} hash
- * @param {number} shift
- * @returns {number}
- */
-function bitpos(hash, shift) {
- return 1 << mask(hash, shift);
-}
-/**
- * Count the number of 1 bits in a number
- * @param {number} x
- * @returns {number}
- */
-function bitcount(x) {
- x -= (x >> 1) & 0x55555555;
- x = (x & 0x33333333) + ((x >> 2) & 0x33333333);
- x = (x + (x >> 4)) & 0x0f0f0f0f;
- x += x >> 8;
- x += x >> 16;
- return x & 0x7f;
-}
-/**
- * Calculate the array index of an item in a bitmap index node
- * @param {number} bitmap
- * @param {number} bit
- * @returns {number}
- */
-function index(bitmap, bit) {
- return bitcount(bitmap & (bit - 1));
-}
-/**
- * Efficiently copy an array and set one value at an index
- * @template T
- * @param {T[]} arr
- * @param {number} at
- * @param {T} val
- * @returns {T[]}
- */
-function cloneAndSet(arr, at, val) {
- const len = arr.length;
- const out = new Array(len);
- for (let i = 0; i < len; ++i) {
- out[i] = arr[i];
- }
- out[at] = val;
- return out;
-}
-/**
- * Efficiently copy an array and insert one value at an index
- * @template T
- * @param {T[]} arr
- * @param {number} at
- * @param {T} val
- * @returns {T[]}
- */
-function spliceIn(arr, at, val) {
- const len = arr.length;
- const out = new Array(len + 1);
- let i = 0;
- let g = 0;
- while (i < at) {
- out[g++] = arr[i++];
- }
- out[g++] = val;
- while (i < len) {
- out[g++] = arr[i++];
- }
- return out;
-}
-/**
- * Efficiently copy an array and remove one value at an index
- * @template T
- * @param {T[]} arr
- * @param {number} at
- * @returns {T[]}
- */
-function spliceOut(arr, at) {
- const len = arr.length;
- const out = new Array(len - 1);
- let i = 0;
- let g = 0;
- while (i < at) {
- out[g++] = arr[i++];
- }
- ++i;
- while (i < len) {
- out[g++] = arr[i++];
- }
- return out;
-}
-/**
- * Create a new node containing two entries
- * @template K,V
- * @param {number} shift
- * @param {K} key1
- * @param {V} val1
- * @param {number} key2hash
- * @param {K} key2
- * @param {V} val2
- * @returns {Node<K,V>}
- */
-function createNode(shift, key1, val1, key2hash, key2, val2) {
- const key1hash = getHash(key1);
- if (key1hash === key2hash) {
- return {
- type: COLLISION_NODE,
- hash: key1hash,
- array: [
- { type: ENTRY, k: key1, v: val1 },
- { type: ENTRY, k: key2, v: val2 },
- ],
- };
- }
- const addedLeaf = { val: false };
- return assoc(
- assocIndex(EMPTY, shift, key1hash, key1, val1, addedLeaf),
- shift,
- key2hash,
- key2,
- val2,
- addedLeaf
- );
-}
-/**
- * @template T,K,V
- * @callback AssocFunction
- * @param {T} root
- * @param {number} shift
- * @param {number} hash
- * @param {K} key
- * @param {V} val
- * @param {Flag} addedLeaf
- * @returns {Node<K,V>}
- */
-/**
- * Associate a node with a new entry, creating a new node
- * @template T,K,V
- * @type {AssocFunction<Node<K,V>,K,V>}
- */
-function assoc(root, shift, hash, key, val, addedLeaf) {
- switch (root.type) {
- case ARRAY_NODE:
- return assocArray(root, shift, hash, key, val, addedLeaf);
- case INDEX_NODE:
- return assocIndex(root, shift, hash, key, val, addedLeaf);
- case COLLISION_NODE:
- return assocCollision(root, shift, hash, key, val, addedLeaf);
- }
-}
-/**
- * @template T,K,V
- * @type {AssocFunction<ArrayNode<K,V>,K,V>}
- */
-function assocArray(root, shift, hash, key, val, addedLeaf) {
- const idx = mask(hash, shift);
- const node = root.array[idx];
- // if the corresponding index is empty set the index to a newly created node
- if (node === undefined) {
- addedLeaf.val = true;
- return {
- type: ARRAY_NODE,
- size: root.size + 1,
- array: cloneAndSet(root.array, idx, { type: ENTRY, k: key, v: val }),
- };
- }
- if (node.type === ENTRY) {
- // if keys are equal replace the entry
- if (isEqual(key, node.k)) {
- if (val === node.v) {
- return root;
- }
- return {
- type: ARRAY_NODE,
- size: root.size,
- array: cloneAndSet(root.array, idx, {
- type: ENTRY,
- k: key,
- v: val,
- }),
- };
- }
- // otherwise upgrade the entry to a node and insert
- addedLeaf.val = true;
- return {
- type: ARRAY_NODE,
- size: root.size,
- array: cloneAndSet(
- root.array,
- idx,
- createNode(shift + SHIFT, node.k, node.v, hash, key, val)
- ),
- };
- }
- // otherwise call assoc on the child node
- const n = assoc(node, shift + SHIFT, hash, key, val, addedLeaf);
- // if the child node hasn't changed just return the old root
- if (n === node) {
- return root;
- }
- // otherwise set the index to the new node
- return {
- type: ARRAY_NODE,
- size: root.size,
- array: cloneAndSet(root.array, idx, n),
- };
-}
-/**
- * @template T,K,V
- * @type {AssocFunction<IndexNode<K,V>,K,V>}
- */
-function assocIndex(root, shift, hash, key, val, addedLeaf) {
- const bit = bitpos(hash, shift);
- const idx = index(root.bitmap, bit);
- // if there is already a item at this hash index..
- if ((root.bitmap & bit) !== 0) {
- // if there is a node at the index (not an entry), call assoc on the child node
- const node = root.array[idx];
- if (node.type !== ENTRY) {
- const n = assoc(node, shift + SHIFT, hash, key, val, addedLeaf);
- if (n === node) {
- return root;
- }
- return {
- type: INDEX_NODE,
- bitmap: root.bitmap,
- array: cloneAndSet(root.array, idx, n),
- };
- }
- // otherwise there is an entry at the index
- // if the keys are equal replace the entry with the updated value
- const nodeKey = node.k;
- if (isEqual(key, nodeKey)) {
- if (val === node.v) {
- return root;
- }
- return {
- type: INDEX_NODE,
- bitmap: root.bitmap,
- array: cloneAndSet(root.array, idx, {
- type: ENTRY,
- k: key,
- v: val,
- }),
- };
- }
- // if the keys are not equal, replace the entry with a new child node
- addedLeaf.val = true;
- return {
- type: INDEX_NODE,
- bitmap: root.bitmap,
- array: cloneAndSet(
- root.array,
- idx,
- createNode(shift + SHIFT, nodeKey, node.v, hash, key, val)
- ),
- };
- } else {
- // else there is currently no item at the hash index
- const n = root.array.length;
- // if the number of nodes is at the maximum, expand this node into an array node
- if (n >= MAX_INDEX_NODE) {
- // create a 32 length array for the new array node (one for each bit in the hash)
- const nodes = new Array(32);
- // create and insert a node for the new entry
- const jdx = mask(hash, shift);
- nodes[jdx] = assocIndex(EMPTY, shift + SHIFT, hash, key, val, addedLeaf);
- let j = 0;
- let bitmap = root.bitmap;
- // place each item in the index node into the correct spot in the array node
- // loop through all 32 bits / array positions
- for (let i = 0; i < 32; i++) {
- if ((bitmap & 1) !== 0) {
- const node = root.array[j++];
- nodes[i] = node;
- }
- // shift the bitmap to process the next bit
- bitmap = bitmap >>> 1;
- }
- return {
- type: ARRAY_NODE,
- size: n + 1,
- array: nodes,
- };
- } else {
- // else there is still space in this index node
- // simply insert a new entry at the hash index
- const newArray = spliceIn(root.array, idx, {
- type: ENTRY,
- k: key,
- v: val,
- });
- addedLeaf.val = true;
- return {
- type: INDEX_NODE,
- bitmap: root.bitmap | bit,
- array: newArray,
- };
- }
- }
-}
-/**
- * @template T,K,V
- * @type {AssocFunction<CollisionNode<K,V>,K,V>}
- */
-function assocCollision(root, shift, hash, key, val, addedLeaf) {
- // if there is a hash collision
- if (hash === root.hash) {
- const idx = collisionIndexOf(root, key);
- // if this key already exists replace the entry with the new value
- if (idx !== -1) {
- const entry = root.array[idx];
- if (entry.v === val) {
- return root;
- }
- return {
- type: COLLISION_NODE,
- hash: hash,
- array: cloneAndSet(root.array, idx, { type: ENTRY, k: key, v: val }),
- };
- }
- // otherwise insert the entry at the end of the array
- const size = root.array.length;
- addedLeaf.val = true;
- return {
- type: COLLISION_NODE,
- hash: hash,
- array: cloneAndSet(root.array, size, { type: ENTRY, k: key, v: val }),
- };
- }
- // if there is no hash collision, upgrade to an index node
- return assoc(
- {
- type: INDEX_NODE,
- bitmap: bitpos(root.hash, shift),
- array: [root],
- },
- shift,
- hash,
- key,
- val,
- addedLeaf
- );
-}
-/**
- * Find the index of a key in the collision node's array
- * @template K,V
- * @param {CollisionNode<K,V>} root
- * @param {K} key
- * @returns {number}
- */
-function collisionIndexOf(root, key) {
- const size = root.array.length;
- for (let i = 0; i < size; i++) {
- if (isEqual(key, root.array[i].k)) {
- return i;
- }
- }
- return -1;
-}
-/**
- * @template T,K,V
- * @callback FindFunction
- * @param {T} root
- * @param {number} shift
- * @param {number} hash
- * @param {K} key
- * @returns {undefined | Entry<K,V>}
- */
-/**
- * Return the found entry or undefined if not present in the root
- * @template K,V
- * @type {FindFunction<Node<K,V>,K,V>}
- */
-function find(root, shift, hash, key) {
- switch (root.type) {
- case ARRAY_NODE:
- return findArray(root, shift, hash, key);
- case INDEX_NODE:
- return findIndex(root, shift, hash, key);
- case COLLISION_NODE:
- return findCollision(root, key);
- }
-}
-/**
- * @template K,V
- * @type {FindFunction<ArrayNode<K,V>,K,V>}
- */
-function findArray(root, shift, hash, key) {
- const idx = mask(hash, shift);
- const node = root.array[idx];
- if (node === undefined) {
- return undefined;
- }
- if (node.type !== ENTRY) {
- return find(node, shift + SHIFT, hash, key);
- }
- if (isEqual(key, node.k)) {
- return node;
- }
- return undefined;
-}
-/**
- * @template K,V
- * @type {FindFunction<IndexNode<K,V>,K,V>}
- */
-function findIndex(root, shift, hash, key) {
- const bit = bitpos(hash, shift);
- if ((root.bitmap & bit) === 0) {
- return undefined;
- }
- const idx = index(root.bitmap, bit);
- const node = root.array[idx];
- if (node.type !== ENTRY) {
- return find(node, shift + SHIFT, hash, key);
- }
- if (isEqual(key, node.k)) {
- return node;
- }
- return undefined;
-}
-/**
- * @template K,V
- * @param {CollisionNode<K,V>} root
- * @param {K} key
- * @returns {undefined | Entry<K,V>}
- */
-function findCollision(root, key) {
- const idx = collisionIndexOf(root, key);
- if (idx < 0) {
- return undefined;
- }
- return root.array[idx];
-}
-/**
- * @template T,K,V
- * @callback WithoutFunction
- * @param {T} root
- * @param {number} shift
- * @param {number} hash
- * @param {K} key
- * @returns {undefined | Node<K,V>}
- */
-/**
- * Remove an entry from the root, returning the updated root.
- * Returns undefined if the node should be removed from the parent.
- * @template K,V
- * @type {WithoutFunction<Node<K,V>,K,V>}
- * */
-function without(root, shift, hash, key) {
- switch (root.type) {
- case ARRAY_NODE:
- return withoutArray(root, shift, hash, key);
- case INDEX_NODE:
- return withoutIndex(root, shift, hash, key);
- case COLLISION_NODE:
- return withoutCollision(root, key);
- }
-}
-/**
- * @template K,V
- * @type {WithoutFunction<ArrayNode<K,V>,K,V>}
- */
-function withoutArray(root, shift, hash, key) {
- const idx = mask(hash, shift);
- const node = root.array[idx];
- if (node === undefined) {
- return root; // already empty
- }
- let n = undefined;
- // if node is an entry and the keys are not equal there is nothing to remove
- // if node is not an entry do a recursive call
- if (node.type === ENTRY) {
- if (!isEqual(node.k, key)) {
- return root; // no changes
- }
- } else {
- n = without(node, shift + SHIFT, hash, key);
- if (n === node) {
- return root; // no changes
- }
- }
- // if the recursive call returned undefined the node should be removed
- if (n === undefined) {
- // if the number of child nodes is at the minimum, pack into an index node
- if (root.size <= MIN_ARRAY_NODE) {
- const arr = root.array;
- const out = new Array(root.size - 1);
- let i = 0;
- let j = 0;
- let bitmap = 0;
- while (i < idx) {
- const nv = arr[i];
- if (nv !== undefined) {
- out[j] = nv;
- bitmap |= 1 << i;
- ++j;
- }
- ++i;
- }
- ++i; // skip copying the removed node
- while (i < arr.length) {
- const nv = arr[i];
- if (nv !== undefined) {
- out[j] = nv;
- bitmap |= 1 << i;
- ++j;
- }
- ++i;
- }
- return {
- type: INDEX_NODE,
- bitmap: bitmap,
- array: out,
- };
- }
- return {
- type: ARRAY_NODE,
- size: root.size - 1,
- array: cloneAndSet(root.array, idx, n),
- };
- }
- return {
- type: ARRAY_NODE,
- size: root.size,
- array: cloneAndSet(root.array, idx, n),
- };
-}
-/**
- * @template K,V
- * @type {WithoutFunction<IndexNode<K,V>,K,V>}
- */
-function withoutIndex(root, shift, hash, key) {
- const bit = bitpos(hash, shift);
- if ((root.bitmap & bit) === 0) {
- return root; // already empty
- }
- const idx = index(root.bitmap, bit);
- const node = root.array[idx];
- // if the item is not an entry
- if (node.type !== ENTRY) {
- const n = without(node, shift + SHIFT, hash, key);
- if (n === node) {
- return root; // no changes
- }
- // if not undefined, the child node still has items, so update it
- if (n !== undefined) {
- return {
- type: INDEX_NODE,
- bitmap: root.bitmap,
- array: cloneAndSet(root.array, idx, n),
- };
- }
- // otherwise the child node should be removed
- // if it was the only child node, remove this node from the parent
- if (root.bitmap === bit) {
- return undefined;
- }
- // otherwise just remove the child node
- return {
- type: INDEX_NODE,
- bitmap: root.bitmap ^ bit,
- array: spliceOut(root.array, idx),
- };
- }
- // otherwise the item is an entry, remove it if the key matches
- if (isEqual(key, node.k)) {
- if (root.bitmap === bit) {
- return undefined;
- }
- return {
- type: INDEX_NODE,
- bitmap: root.bitmap ^ bit,
- array: spliceOut(root.array, idx),
- };
- }
- return root;
-}
-/**
- * @template K,V
- * @param {CollisionNode<K,V>} root
- * @param {K} key
- * @returns {undefined | Node<K,V>}
- */
-function withoutCollision(root, key) {
- const idx = collisionIndexOf(root, key);
- // if the key not found, no changes
- if (idx < 0) {
- return root;
- }
- // otherwise the entry was found, remove it
- // if it was the only entry in this node, remove the whole node
- if (root.array.length === 1) {
- return undefined;
- }
- // otherwise just remove the entry
- return {
- type: COLLISION_NODE,
- hash: root.hash,
- array: spliceOut(root.array, idx),
- };
-}
-/**
- * @template K,V
- * @param {undefined | Node<K,V>} root
- * @param {(value:V,key:K)=>void} fn
- * @returns {void}
- */
-function forEach(root, fn) {
- if (root === undefined) {
- return;
- }
- const items = root.array;
- const size = items.length;
- for (let i = 0; i < size; i++) {
- const item = items[i];
- if (item === undefined) {
- continue;
- }
- if (item.type === ENTRY) {
- fn(item.v, item.k);
- continue;
- }
- forEach(item, fn);
- }
-}
-/**
- * Extra wrapper to keep track of Dict size and clean up the API
- * @template K,V
- */
-export default class Dict {
- /**
- * @template V
- * @param {Record<string,V>} o
- * @returns {Dict<string,V>}
- */
- static fromObject(o) {
- const keys = Object.keys(o);
- /** @type Dict<string,V> */
- let m = Dict.new();
- for (let i = 0; i < keys.length; i++) {
- const k = keys[i];
- m = m.set(k, o[k]);
- }
- return m;
- }
- /**
- * @template K,V
- * @param {Map<K,V>} o
- * @returns {Dict<K,V>}
- */
- static fromMap(o) {
- /** @type Dict<K,V> */
- let m = Dict.new();
- o.forEach((v, k) => {
- m = m.set(k, v);
- });
- return m;
- }
- static new() {
- return new Dict(undefined, 0);
- }
- /**
- * @param {undefined | Node<K,V>} root
- * @param {number} size
- */
- constructor(root, size) {
- this.root = root;
- this.size = size;
- }
- /**
- * @template NotFound
- * @param {K} key
- * @param {NotFound} notFound
- * @returns {NotFound | V}
- */
- get(key, notFound) {
- if (this.root === undefined) {
- return notFound;
- }
- const found = find(this.root, 0, getHash(key), key);
- if (found === undefined) {
- return notFound;
- }
- return found.v;
- }
- /**
- * @param {K} key
- * @param {V} val
- * @returns {Dict<K,V>}
- */
- set(key, val) {
- const addedLeaf = { val: false };
- const root = this.root === undefined ? EMPTY : this.root;
- const newRoot = assoc(root, 0, getHash(key), key, val, addedLeaf);
- if (newRoot === this.root) {
- return this;
- }
- return new Dict(newRoot, addedLeaf.val ? this.size + 1 : this.size);
- }
- /**
- * @param {K} key
- * @returns {Dict<K,V>}
- */
- delete(key) {
- if (this.root === undefined) {
- return this;
- }
- const newRoot = without(this.root, 0, getHash(key), key);
- if (newRoot === this.root) {
- return this;
- }
- if (newRoot === undefined) {
- return Dict.new();
- }
- return new Dict(newRoot, this.size - 1);
- }
- /**
- * @param {K} key
- * @returns {boolean}
- */
- has(key) {
- if (this.root === undefined) {
- return false;
- }
- return find(this.root, 0, getHash(key), key) !== undefined;
- }
- /**
- * @returns {[K,V][]}
- */
- entries() {
- if (this.root === undefined) {
- return [];
- }
- /** @type [K,V][] */
- const result = [];
- this.forEach((v, k) => result.push([k, v]));
- return result;
- }
- /**
- *
- * @param {(val:V,key:K)=>void} fn
- */
- forEach(fn) {
- forEach(this.root, fn);
- }
- hashCode() {
- let h = 0;
- this.forEach((v, k) => {
- h = (h + hashMerge(getHash(v), getHash(k))) | 0;
- });
- return h;
- }
- /**
- * @param {unknown} o
- * @returns {boolean}
- */
- equals(o) {
- if (!(o instanceof Dict) || this.size !== o.size) {
- return false;
- }
- let equal = true;
- this.forEach((v, k) => {
- equal = equal && isEqual(o.get(k, !v), v);
- });
- return equal;
- }
-}
diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam/base.gleam b/aoc2023/build/packages/gleam_stdlib/src/gleam/base.gleam
deleted file mode 100644
index eab2f0b..0000000
--- a/aoc2023/build/packages/gleam_stdlib/src/gleam/base.gleam
+++ /dev/null
@@ -1,21 +0,0 @@
-import gleam/bit_array
-
-@deprecated("Please use `base64_encode` in the `gleam/bit_array` module instead.")
-pub fn encode64(input: BitArray, padding: Bool) -> String {
- bit_array.base64_encode(input, padding)
-}
-
-@deprecated("Please use `base64_decode` in the `gleam/bit_array` module instead.")
-pub fn decode64(encoded: String) -> Result(BitArray, Nil) {
- bit_array.base64_decode(encoded)
-}
-
-@deprecated("Please use `base64_url_encode` in the `gleam/bit_array` module instead.")
-pub fn url_encode64(input: BitArray, padding: Bool) -> String {
- bit_array.base64_url_encode(input, padding)
-}
-
-@deprecated("Please use `base64_url_decode` in the `gleam/bit_array` module instead.")
-pub fn url_decode64(encoded: String) -> Result(BitArray, Nil) {
- bit_array.base64_url_decode(encoded)
-}
diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam/bit_array.gleam b/aoc2023/build/packages/gleam_stdlib/src/gleam/bit_array.gleam
deleted file mode 100644
index 79860e9..0000000
--- a/aoc2023/build/packages/gleam_stdlib/src/gleam/bit_array.gleam
+++ /dev/null
@@ -1,157 +0,0 @@
-//// BitArrays are a sequence of binary data of any length.
-
-import gleam/string
-
-/// Converts a UTF-8 `String` type into a `BitArray`.
-///
-@external(erlang, "gleam_stdlib", "identity")
-@external(javascript, "../gleam_stdlib.mjs", "bit_array_from_string")
-pub fn from_string(x: String) -> BitArray
-
-/// Returns an integer which is the number of bytes in the bit array.
-///
-@external(erlang, "erlang", "byte_size")
-@external(javascript, "../gleam_stdlib.mjs", "length")
-pub fn byte_size(x: BitArray) -> Int
-
-/// Creates a new bit array by joining two bit arrays.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > append(to: from_string("butter"), suffix: from_string("fly"))
-/// from_string("butterfly")
-/// ```
-///
-pub fn append(to first: BitArray, suffix second: BitArray) -> BitArray {
- concat([first, second])
-}
-
-/// Extracts a sub-section of a bit array.
-///
-/// The slice will start at given position and continue up to specified
-/// length.
-/// A negative length can be used to extract bytes at the end of a bit array.
-///
-/// This function runs in constant time.
-///
-@external(erlang, "gleam_stdlib", "bit_array_slice")
-@external(javascript, "../gleam_stdlib.mjs", "bit_array_slice")
-pub fn slice(
- from string: BitArray,
- at position: Int,
- take length: Int,
-) -> Result(BitArray, Nil)
-
-/// Tests to see whether a bit array is valid UTF-8.
-///
-pub fn is_utf8(bits: BitArray) -> Bool {
- do_is_utf8(bits)
-}
-
-@target(erlang)
-fn do_is_utf8(bits: BitArray) -> Bool {
- case bits {
- <<>> -> True
- <<_:utf8, rest:bytes>> -> do_is_utf8(rest)
- _ -> False
- }
-}
-
-@target(javascript)
-fn do_is_utf8(bits: BitArray) -> Bool {
- case to_string(bits) {
- Ok(_) -> True
- _ -> False
- }
-}
-
-/// Converts a bit array to a string.
-///
-/// Returns an error if the bit array is invalid UTF-8 data.
-///
-pub fn to_string(bits: BitArray) -> Result(String, Nil) {
- do_to_string(bits)
-}
-
-@target(erlang)
-@external(erlang, "gleam_stdlib", "identity")
-fn unsafe_to_string(a: BitArray) -> String
-
-@target(erlang)
-fn do_to_string(bits: BitArray) -> Result(String, Nil) {
- case is_utf8(bits) {
- True -> Ok(unsafe_to_string(bits))
- False -> Error(Nil)
- }
-}
-
-@target(javascript)
-@external(javascript, "../gleam_stdlib.mjs", "bit_array_to_string")
-fn do_to_string(a: BitArray) -> Result(String, Nil)
-
-/// Creates a new bit array by joining multiple binaries.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > concat([from_string("butter"), from_string("fly")])
-/// from_string("butterfly")
-/// ```
-///
-@external(erlang, "gleam_stdlib", "bit_array_concat")
-@external(javascript, "../gleam_stdlib.mjs", "bit_array_concat")
-pub fn concat(bit_arrays: List(BitArray)) -> BitArray
-
-/// Encodes a BitArray into a base 64 encoded string.
-///
-pub fn base64_encode(input: BitArray, padding: Bool) -> String {
- let encoded = encode64(input)
- case padding {
- True -> encoded
- False -> string.replace(encoded, "=", "")
- }
-}
-
-@external(erlang, "base64", "encode")
-@external(javascript, "../gleam_stdlib.mjs", "encode64")
-fn encode64(a: BitArray) -> String
-
-/// Decodes a base 64 encoded string into a `BitArray`.
-///
-pub fn base64_decode(encoded: String) -> Result(BitArray, Nil) {
- let padded = case byte_size(from_string(encoded)) % 4 {
- 0 -> encoded
- n -> string.append(encoded, string.repeat("=", 4 - n))
- }
- decode64(padded)
-}
-
-@external(erlang, "gleam_stdlib", "base_decode64")
-@external(javascript, "../gleam_stdlib.mjs", "decode64")
-fn decode64(a: String) -> Result(BitArray, Nil)
-
-/// Encodes a `BitArray` into a base 64 encoded string with URL and filename safe alphabet.
-///
-pub fn base64_url_encode(input: BitArray, padding: Bool) -> String {
- base64_encode(input, padding)
- |> string.replace("+", "-")
- |> string.replace("/", "_")
-}
-
-/// Decodes a base 64 encoded string with URL and filename safe alphabet into a `BitArray`.
-///
-pub fn base64_url_decode(encoded: String) -> Result(BitArray, Nil) {
- encoded
- |> string.replace("-", "+")
- |> string.replace("_", "/")
- |> base64_decode()
-}
-
-@external(erlang, "binary", "encode_hex")
-@external(javascript, "../gleam_stdlib.mjs", "base16_encode")
-pub fn base16_encode(input: BitArray) -> String
-
-@external(erlang, "gleam_stdlib", "base16_decode")
-@external(javascript, "../gleam_stdlib.mjs", "base16_decode")
-pub fn base16_decode(input: String) -> Result(BitArray, Nil)
diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam/bit_builder.gleam b/aoc2023/build/packages/gleam_stdlib/src/gleam/bit_builder.gleam
deleted file mode 100644
index ce6fe52..0000000
--- a/aoc2023/build/packages/gleam_stdlib/src/gleam/bit_builder.gleam
+++ /dev/null
@@ -1,80 +0,0 @@
-//// This module has been deprecated in favour of `gleam/bytes_builder`.
-
-import gleam/bytes_builder
-import gleam/string_builder.{type StringBuilder}
-
-pub type BitBuilder =
- bytes_builder.BytesBuilder
-
-@deprecated("Please use the `gleam/bytes_builder` module instead.")
-pub fn new() -> BitBuilder {
- bytes_builder.new()
-}
-
-@deprecated("Please use the `gleam/bytes_builder` module instead.")
-pub fn prepend(to: BitBuilder, prefix: BitArray) -> BitBuilder {
- bytes_builder.prepend(to, prefix)
-}
-
-@deprecated("Please use the `gleam/bytes_builder` module instead.")
-pub fn append(to: BitBuilder, suffix: BitArray) -> BitBuilder {
- bytes_builder.append(to, suffix)
-}
-
-@deprecated("Please use the `gleam/bytes_builder` module instead.")
-pub fn prepend_builder(to: BitBuilder, prefix: BitBuilder) -> BitBuilder {
- bytes_builder.prepend_builder(to, prefix)
-}
-
-@deprecated("Please use the `gleam/bytes_builder` module instead.")
-pub fn append_builder(
- to first: BitBuilder,
- suffix second: BitBuilder,
-) -> BitBuilder {
- bytes_builder.append_builder(first, second)
-}
-
-@deprecated("Please use the `gleam/bytes_builder` module instead.")
-pub fn prepend_string(to: BitBuilder, prefix: String) -> BitBuilder {
- bytes_builder.prepend_string(to, prefix)
-}
-
-@deprecated("Please use the `gleam/bytes_builder` module instead.")
-pub fn append_string(to: BitBuilder, suffix: String) -> BitBuilder {
- bytes_builder.append_string(to, suffix)
-}
-
-@deprecated("Please use the `gleam/bytes_builder` module instead.")
-pub fn concat(builders: List(BitBuilder)) -> BitBuilder {
- bytes_builder.concat(builders)
-}
-
-@deprecated("Please use the `gleam/bytes_builder` module instead.")
-pub fn concat_bit_strings(bits: List(BitArray)) -> BitBuilder {
- bytes_builder.concat_bit_arrays(bits)
-}
-
-@deprecated("Please use the `gleam/bytes_builder` module instead.")
-pub fn from_string(string: String) -> BitBuilder {
- bytes_builder.from_string(string)
-}
-
-@deprecated("Please use the `gleam/bytes_builder` module instead.")
-pub fn from_string_builder(builder: StringBuilder) -> BitBuilder {
- bytes_builder.from_string_builder(builder)
-}
-
-@deprecated("Please use the `gleam/bytes_builder` module instead.")
-pub fn from_bit_string(bits: BitArray) -> BitBuilder {
- bytes_builder.from_bit_array(bits)
-}
-
-@deprecated("Please use the `gleam/bytes_builder` module instead.")
-pub fn to_bit_string(builder: BitBuilder) -> BitArray {
- bytes_builder.to_bit_array(builder)
-}
-
-@deprecated("Please use the `gleam/bytes_builder` module instead.")
-pub fn byte_size(builder: BitBuilder) -> Int {
- bytes_builder.byte_size(builder)
-}
diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam/bit_string.gleam b/aoc2023/build/packages/gleam_stdlib/src/gleam/bit_string.gleam
deleted file mode 100644
index b703da0..0000000
--- a/aoc2023/build/packages/gleam_stdlib/src/gleam/bit_string.gleam
+++ /dev/null
@@ -1,43 +0,0 @@
-//// This module has been deprecated. Please use the `gleam/bit_array` module
-//// instead.
-
-import gleam/bit_array
-
-@deprecated("Please use the `gleam/bit_array` module instead.")
-pub fn from_string(x: String) -> BitArray {
- bit_array.from_string(x)
-}
-
-@deprecated("Please use the `gleam/bit_array` module instead.")
-pub fn byte_size(x: BitArray) -> Int {
- bit_array.byte_size(x)
-}
-
-@deprecated("Please use the `gleam/bit_array` module instead.")
-pub fn append(to first: BitArray, suffix second: BitArray) -> BitArray {
- bit_array.append(first, second)
-}
-
-@deprecated("Please use the `gleam/bit_array` module instead.")
-pub fn slice(
- from string: BitArray,
- at position: Int,
- take length: Int,
-) -> Result(BitArray, Nil) {
- bit_array.slice(string, position, length)
-}
-
-@deprecated("Please use the `gleam/bit_array` module instead.")
-pub fn is_utf8(bits: BitArray) -> Bool {
- bit_array.is_utf8(bits)
-}
-
-@deprecated("Please use the `gleam/bit_array` module instead.")
-pub fn to_string(bits: BitArray) -> Result(String, Nil) {
- bit_array.to_string(bits)
-}
-
-@deprecated("Please use the `gleam/bit_array` module instead.")
-pub fn concat(bit_strings: List(BitArray)) -> BitArray {
- bit_array.concat(bit_strings)
-}
diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam/bool.gleam b/aoc2023/build/packages/gleam_stdlib/src/gleam/bool.gleam
deleted file mode 100644
index 91bd6b7..0000000
--- a/aoc2023/build/packages/gleam_stdlib/src/gleam/bool.gleam
+++ /dev/null
@@ -1,428 +0,0 @@
-//// A type with two possible values, `True` and `False`. Used to indicate whether
-//// things are... true or false!
-////
-//// Often is it clearer and offers more type safety to define a custom type
-//// than to use `Bool`. For example, rather than having a `is_teacher: Bool`
-//// field consider having a `role: SchoolRole` field where `SchoolRole` is a custom
-//// type that can be either `Student` or `Teacher`.
-
-import gleam/order.{type Order}
-
-/// Returns the and of two bools, but it evaluates both arguments.
-///
-/// It's the function equivalent of the `&&` operator.
-/// This function is useful in higher order functions or pipes.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > and(True, True)
-/// True
-/// ```
-///
-/// ```gleam
-/// > and(False, True)
-/// False
-/// ```
-///
-/// ```gleam
-/// > False |> and(True)
-/// False
-/// ```
-///
-pub fn and(a: Bool, b: Bool) -> Bool {
- a && b
-}
-
-/// Returns the or of two bools, but it evaluates both arguments.
-///
-/// It's the function equivalent of the `||` operator.
-/// This function is useful in higher order functions or pipes.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > or(True, True)
-/// True
-/// ```
-///
-/// ```gleam
-/// > or(False, True)
-/// True
-/// ```
-///
-/// ```gleam
-/// > False |> or(True)
-/// True
-/// ```
-///
-pub fn or(a: Bool, b: Bool) -> Bool {
- a || b
-}
-
-/// Returns the opposite bool value.
-///
-/// This is the same as the `!` or `not` operators in some other languages.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > negate(True)
-/// False
-/// ```
-///
-/// ```gleam
-/// > negate(False)
-/// True
-/// ```
-///
-pub fn negate(bool: Bool) -> Bool {
- case bool {
- True -> False
- False -> True
- }
-}
-
-/// Returns the nor of two bools.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > nor(False, False)
-/// True
-/// ```
-///
-/// ```gleam
-/// > nor(False, True)
-/// False
-/// ```
-///
-/// ```gleam
-/// > nor(True, False)
-/// False
-/// ```
-///
-/// ```gleam
-/// > nor(True, True)
-/// False
-/// ```
-///
-pub fn nor(a: Bool, b: Bool) -> Bool {
- case a, b {
- False, False -> True
- False, True -> False
- True, False -> False
- True, True -> False
- }
-}
-
-/// Returns the nand of two bools.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > nand(False, False)
-/// True
-/// ```
-///
-/// ```gleam
-/// > nand(False, True)
-/// True
-/// ```
-///
-/// ```gleam
-/// > nand(True, False)
-/// True
-/// ```
-///
-/// ```gleam
-/// > nand(True, True)
-/// False
-/// ```
-///
-pub fn nand(a: Bool, b: Bool) -> Bool {
- case a, b {
- False, False -> True
- False, True -> True
- True, False -> True
- True, True -> False
- }
-}
-
-/// Returns the exclusive or of two bools.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > exclusive_or(False, False)
-/// False
-/// ```
-///
-/// ```gleam
-/// > exclusive_or(False, True)
-/// True
-/// ```
-///
-/// ```gleam
-/// > exclusive_or(True, False)
-/// True
-/// ```
-///
-/// ```gleam
-/// > exclusive_or(True, True)
-/// False
-/// ```
-///
-pub fn exclusive_or(a: Bool, b: Bool) -> Bool {
- case a, b {
- False, False -> False
- False, True -> True
- True, False -> True
- True, True -> False
- }
-}
-
-/// Returns the exclusive nor of two bools.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > exclusive_nor(False, False)
-/// True
-/// ```
-///
-/// ```gleam
-/// > exclusive_nor(False, True)
-/// False
-/// ```
-///
-/// ```gleam
-/// > exclusive_nor(True, False)
-/// False
-/// ```
-///
-/// ```gleam
-/// > exclusive_nor(True, True)
-/// True
-/// ```
-///
-pub fn exclusive_nor(a: Bool, b: Bool) -> Bool {
- case a, b {
- False, False -> True
- False, True -> False
- True, False -> False
- True, True -> True
- }
-}
-
-/// Compares two bools and returns the first value's `Order` to the second.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > import gleam/order
-/// > compare(True, False)
-/// order.Gt
-/// ```
-///
-pub fn compare(a: Bool, with b: Bool) -> Order {
- case a, b {
- True, True -> order.Eq
- True, False -> order.Gt
- False, False -> order.Eq
- False, True -> order.Lt
- }
-}
-
-/// Returns `True` if either argument's value is `True`.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > max(True, False)
-/// True
-/// ```
-///
-/// ```gleam
-/// > max(False, True)
-/// True
-/// ```
-///
-/// ```gleam
-/// > max(False, False)
-/// False
-/// ```
-///
-pub fn max(a: Bool, b: Bool) -> Bool {
- case a {
- True -> True
- False -> b
- }
-}
-
-/// Returns `False` if either bool value is `False`.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > min(True, False)
-/// False
-/// ```
-///
-/// ```gleam
-/// > min(False, True)
-/// False
-///
-/// > min(False, False)
-/// False
-/// ```
-///
-pub fn min(a: Bool, b: Bool) -> Bool {
- case a {
- False -> False
- True -> b
- }
-}
-
-/// Returns a numeric representation of the given bool.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > to_int(True)
-/// 1
-///
-/// > to_int(False)
-/// 0
-/// ```
-///
-pub fn to_int(bool: Bool) -> Int {
- case bool {
- False -> 0
- True -> 1
- }
-}
-
-/// Returns a string representation of the given bool.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > to_string(True)
-/// "True"
-/// ```
-///
-/// ```gleam
-/// > to_string(False)
-/// "False"
-/// ```
-///
-pub fn to_string(bool: Bool) -> String {
- case bool {
- False -> "False"
- True -> "True"
- }
-}
-
-/// Run a callback function if the given bool is `False`, otherwise return a
-/// default value.
-///
-/// With a `use` expression this function can simulate the early-return pattern
-/// found in some other programming languages.
-///
-/// In a procedural language:
-///
-/// ```js
-/// if (predicate) return value;
-/// // ...
-/// ```
-///
-/// In Gleam with a `use` expression:
-///
-/// ```gleam
-/// use <- guard(when: predicate, return: value)
-/// // ...
-/// ```
-///
-/// Like everything in Gleam `use` is an expression, so it short circuits the
-/// current block, not the entire function. As a result you can assign the value
-/// to a variable:
-///
-/// ```gleam
-/// let x = {
-/// use <- guard(when: predicate, return: value)
-/// // ...
-/// }
-/// ```
-///
-/// Note that unlike in procedural languages the `return` value is evaluated
-/// even when the predicate is `False`, so it is advisable not to perform
-/// expensive computation there.
-///
-///
-/// ## Examples
-///
-/// ```gleam
-/// > let name = ""
-/// > use <- guard(when: name == "", return: "Welcome!")
-/// > "Hello, " <> name
-/// "Welcome!"
-/// ```
-///
-/// ```gleam
-/// > let name = "Kamaka"
-/// > use <- guard(when: name == "", return: "Welcome!")
-/// > "Hello, " <> name
-/// "Hello, Kamaka"
-/// ```
-///
-pub fn guard(
- when requirement: Bool,
- return consequence: t,
- otherwise alternative: fn() -> t,
-) -> t {
- case requirement {
- True -> consequence
- False -> alternative()
- }
-}
-
-/// Runs a callback function if the given bool is `True`, otherwise runs an
-/// alternative callback function.
-///
-/// Useful when further computation should be delayed regardless of the given
-/// bool's value.
-///
-/// See [`guard`](#guard) for more info.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > let name = "Kamaka"
-/// > let inquiry = fn() { "How may we address you?" }
-/// > use <- lazy_guard(when: name == "", return: inquiry)
-/// > "Hello, " <> name
-/// "Hello, Kamaka"
-/// ```
-///
-/// ```gleam
-/// > import gleam/int
-/// > let name = ""
-/// > let greeting = fn() { "Hello, " <> name }
-/// > use <- lazy_guard(when: name == "", otherwise: greeting)
-/// > let number = int.random(1, 99)
-/// > let name = "User " <> int.to_string(number)
-/// > "Welcome, " <> name
-/// "Welcome, User 54"
-/// ```
-///
-pub fn lazy_guard(
- when requirement: Bool,
- return consequence: fn() -> a,
- otherwise alternative: fn() -> a,
-) -> a {
- case requirement {
- True -> consequence()
- False -> alternative()
- }
-}
diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam/bytes_builder.gleam b/aoc2023/build/packages/gleam_stdlib/src/gleam/bytes_builder.gleam
deleted file mode 100644
index 20c145d..0000000
--- a/aoc2023/build/packages/gleam_stdlib/src/gleam/bytes_builder.gleam
+++ /dev/null
@@ -1,197 +0,0 @@
-//// BytesBuilder is a type used for efficiently concatenating bytes together
-//// without copying.
-////
-//// If we append one bit array to another the bit arrays must be copied to a
-//// new location in memory so that they can sit together. This behaviour
-//// enables efficient reading of the string but copying can be expensive,
-//// especially if we want to join many bit arrays together.
-////
-//// BytesBuilder is different in that it can be joined together in constant
-//// time using minimal memory, and then can be efficiently converted to a
-//// bit array using the `to_bit_array` function.
-////
-//// Byte builders are always byte aligned, so that a number of bits that is not
-//// divisible by 8 will be padded with 0s.
-////
-//// On Erlang this type is compatible with Erlang's iolists.
-
-// TODO: pad bit arrays to byte boundaries when adding to a builder.
-import gleam/string_builder.{type StringBuilder}
-import gleam/list
-import gleam/bit_array
-
-pub opaque type BytesBuilder {
- Bytes(BitArray)
- Text(StringBuilder)
- Many(List(BytesBuilder))
-}
-
-/// Create an empty `BytesBuilder`. Useful as the start of a pipe chaining many
-/// builders together.
-///
-pub fn new() -> BytesBuilder {
- concat([])
-}
-
-/// Prepends a bit array to the start of a builder.
-///
-/// Runs in constant time.
-///
-pub fn prepend(to second: BytesBuilder, prefix first: BitArray) -> BytesBuilder {
- append_builder(from_bit_array(first), second)
-}
-
-/// Appends a bit array to the end of a builder.
-///
-/// Runs in constant time.
-///
-pub fn append(to first: BytesBuilder, suffix second: BitArray) -> BytesBuilder {
- append_builder(first, from_bit_array(second))
-}
-
-/// Prepends a builder onto the start of another.
-///
-/// Runs in constant time.
-///
-pub fn prepend_builder(
- to second: BytesBuilder,
- prefix first: BytesBuilder,
-) -> BytesBuilder {
- append_builder(first, second)
-}
-
-/// Appends a builder onto the end of another.
-///
-/// Runs in constant time.
-///
-@external(erlang, "gleam_stdlib", "iodata_append")
-pub fn append_builder(
- to first: BytesBuilder,
- suffix second: BytesBuilder,
-) -> BytesBuilder {
- case second {
- Many(builders) -> Many([first, ..builders])
- _ -> Many([first, second])
- }
-}
-
-/// Prepends a string onto the start of a builder.
-///
-/// Runs in constant time when running on Erlang.
-/// Runs in linear time with the length of the string otherwise.
-///
-pub fn prepend_string(
- to second: BytesBuilder,
- prefix first: String,
-) -> BytesBuilder {
- append_builder(from_string(first), second)
-}
-
-/// Appends a string onto the end of a builder.
-///
-/// Runs in constant time when running on Erlang.
-/// Runs in linear time with the length of the string otherwise.
-///
-pub fn append_string(
- to first: BytesBuilder,
- suffix second: String,
-) -> BytesBuilder {
- append_builder(first, from_string(second))
-}
-
-/// Joins a list of builders into a single builder.
-///
-/// Runs in constant time.
-///
-@external(erlang, "gleam_stdlib", "identity")
-pub fn concat(builders: List(BytesBuilder)) -> BytesBuilder {
- Many(builders)
-}
-
-/// Joins a list of bit arrays into a single builder.
-///
-/// Runs in constant time.
-///
-@external(erlang, "gleam_stdlib", "identity")
-pub fn concat_bit_arrays(bits: List(BitArray)) -> BytesBuilder {
- bits
- |> list.map(fn(b) { from_bit_array(b) })
- |> concat()
-}
-
-/// Creates a new builder from a string.
-///
-/// Runs in constant time when running on Erlang.
-/// Runs in linear time otherwise.
-///
-@external(erlang, "gleam_stdlib", "wrap_list")
-pub fn from_string(string: String) -> BytesBuilder {
- Text(string_builder.from_string(string))
-}
-
-/// Creates a new builder from a string builder.
-///
-/// Runs in constant time when running on Erlang.
-/// Runs in linear time otherwise.
-///
-@external(erlang, "gleam_stdlib", "wrap_list")
-pub fn from_string_builder(builder: StringBuilder) -> BytesBuilder {
- Text(builder)
-}
-
-/// Creates a new builder from a bit array.
-///
-/// Runs in constant time.
-///
-@external(erlang, "gleam_stdlib", "wrap_list")
-pub fn from_bit_array(bits: BitArray) -> BytesBuilder {
- Bytes(bits)
-}
-
-/// Turns an builder into a bit array.
-///
-/// Runs in linear time.
-///
-/// When running on Erlang this function is implemented natively by the
-/// virtual machine and is highly optimised.
-///
-@external(erlang, "erlang", "list_to_bitstring")
-pub fn to_bit_array(builder: BytesBuilder) -> BitArray {
- [[builder]]
- |> to_list([])
- |> list.reverse
- |> bit_array.concat
-}
-
-fn to_list(
- stack: List(List(BytesBuilder)),
- acc: List(BitArray),
-) -> List(BitArray) {
- case stack {
- [] -> acc
-
- [[], ..remaining_stack] -> to_list(remaining_stack, acc)
-
- [[Bytes(bits), ..rest], ..remaining_stack] ->
- to_list([rest, ..remaining_stack], [bits, ..acc])
-
- [[Text(builder), ..rest], ..remaining_stack] -> {
- let bits = bit_array.from_string(string_builder.to_string(builder))
- to_list([rest, ..remaining_stack], [bits, ..acc])
- }
-
- [[Many(builders), ..rest], ..remaining_stack] ->
- to_list([builders, rest, ..remaining_stack], acc)
- }
-}
-
-/// Returns the size of the builder's content in bytes.
-///
-/// Runs in linear time.
-///
-@external(erlang, "erlang", "iolist_size")
-pub fn byte_size(builder: BytesBuilder) -> Int {
- [[builder]]
- |> to_list([])
- |> list.fold(0, fn(acc, builder) { bit_array.byte_size(builder) + acc })
-}
diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam/dict.gleam b/aoc2023/build/packages/gleam_stdlib/src/gleam/dict.gleam
deleted file mode 100644
index 280bf9d..0000000
--- a/aoc2023/build/packages/gleam_stdlib/src/gleam/dict.gleam
+++ /dev/null
@@ -1,544 +0,0 @@
-import gleam/option.{type Option}
-
-/// A dictionary of keys and values.
-///
-/// Any type can be used for the keys and values of a dict, but all the keys
-/// must be of the same type and all the values must be of the same type.
-///
-/// Each key can only be present in a dict once.
-///
-/// Dicts are not ordered in any way, and any unintentional ordering is not to
-/// be relied upon in your code as it may change in future versions of Erlang
-/// or Gleam.
-///
-/// See [the Erlang map module](https://erlang.org/doc/man/maps.html) for more
-/// information.
-///
-pub type Dict(key, value)
-
-/// Determines the number of key-value pairs in the dict.
-/// This function runs in constant time and does not need to iterate the dict.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > new() |> size()
-/// 0
-/// ```
-///
-/// ```gleam
-/// > new() |> insert("key", "value") |> size()
-/// 1
-/// ```
-///
-pub fn size(dict: Dict(k, v)) -> Int {
- do_size(dict)
-}
-
-@external(erlang, "maps", "size")
-@external(javascript, "../gleam_stdlib.mjs", "map_size")
-fn do_size(a: Dict(k, v)) -> Int
-
-/// Converts the dict to a list of 2-element tuples `#(key, value)`, one for
-/// each key-value pair in the dict.
-///
-/// The tuples in the list have no specific order.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > new() |> to_list()
-/// []
-/// ```
-///
-/// ```gleam
-/// > new() |> insert("key", 0) |> to_list()
-/// [#("key", 0)]
-/// ```
-///
-pub fn to_list(dict: Dict(key, value)) -> List(#(key, value)) {
- do_to_list(dict)
-}
-
-@external(erlang, "maps", "to_list")
-@external(javascript, "../gleam_stdlib.mjs", "map_to_list")
-fn do_to_list(a: Dict(key, value)) -> List(#(key, value))
-
-/// Converts a list of 2-element tuples `#(key, value)` to a dict.
-///
-/// If two tuples have the same key the last one in the list will be the one
-/// that is present in the dict.
-///
-pub fn from_list(list: List(#(k, v))) -> Dict(k, v) {
- do_from_list(list)
-}
-
-@target(erlang)
-@external(erlang, "maps", "from_list")
-fn do_from_list(a: List(#(key, value))) -> Dict(key, value)
-
-@target(javascript)
-fn fold_list_of_pair(
- over list: List(#(k, v)),
- from initial: Dict(k, v),
-) -> Dict(k, v) {
- case list {
- [] -> initial
- [x, ..rest] -> fold_list_of_pair(rest, insert(initial, x.0, x.1))
- }
-}
-
-@target(javascript)
-fn do_from_list(list: List(#(k, v))) -> Dict(k, v) {
- fold_list_of_pair(list, new())
-}
-
-/// Determines whether or not a value present in the dict for a given key.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > new() |> insert("a", 0) |> has_key("a")
-/// True
-/// ```
-///
-/// ```gleam
-/// > new() |> insert("a", 0) |> has_key("b")
-/// False
-/// ```
-///
-pub fn has_key(dict: Dict(k, v), key: k) -> Bool {
- do_has_key(key, dict)
-}
-
-@target(erlang)
-@external(erlang, "maps", "is_key")
-fn do_has_key(a: key, b: Dict(key, v)) -> Bool
-
-@target(javascript)
-fn do_has_key(key: k, dict: Dict(k, v)) -> Bool {
- get(dict, key) != Error(Nil)
-}
-
-/// Creates a fresh dict that contains no values.
-///
-pub fn new() -> Dict(key, value) {
- do_new()
-}
-
-@external(erlang, "maps", "new")
-@external(javascript, "../gleam_stdlib.mjs", "new_map")
-fn do_new() -> Dict(key, value)
-
-/// Fetches a value from a dict for a given key.
-///
-/// The dict may not have a value for the key, so the value is wrapped in a
-/// `Result`.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > new() |> insert("a", 0) |> get("a")
-/// Ok(0)
-/// ```
-///
-/// ```gleam
-/// > new() |> insert("a", 0) |> get("b")
-/// Error(Nil)
-/// ```
-///
-pub fn get(from: Dict(key, value), get: key) -> Result(value, Nil) {
- do_get(from, get)
-}
-
-@external(erlang, "gleam_stdlib", "map_get")
-@external(javascript, "../gleam_stdlib.mjs", "map_get")
-fn do_get(a: Dict(key, value), b: key) -> Result(value, Nil)
-
-/// Inserts a value into the dict with the given key.
-///
-/// If the dict already has a value for the given key then the value is
-/// replaced with the new value.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > new() |> insert("a", 0) |> to_list
-/// [#("a", 0)]
-/// ```
-///
-/// ```gleam
-/// > new() |> insert("a", 0) |> insert("a", 5) |> to_list
-/// [#("a", 5)]
-/// ```
-///
-pub fn insert(into dict: Dict(k, v), for key: k, insert value: v) -> Dict(k, v) {
- do_insert(key, value, dict)
-}
-
-@external(erlang, "maps", "put")
-@external(javascript, "../gleam_stdlib.mjs", "map_insert")
-fn do_insert(a: key, b: value, c: Dict(key, value)) -> Dict(key, value)
-
-/// Updates all values in a given dict by calling a given function on each key
-/// and value.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > [#(3, 3), #(2, 4)]
-/// > |> from_list
-/// > |> map_values(fn(key, value) { key * value })
-/// [#(3, 9), #(2, 8)]
-/// ```
-///
-pub fn map_values(in dict: Dict(k, v), with fun: fn(k, v) -> w) -> Dict(k, w) {
- do_map_values(fun, dict)
-}
-
-@target(erlang)
-@external(erlang, "maps", "map")
-fn do_map_values(a: fn(key, value) -> b, b: Dict(key, value)) -> Dict(key, b)
-
-@target(javascript)
-fn do_map_values(f: fn(key, value) -> b, dict: Dict(key, value)) -> Dict(key, b) {
- let f = fn(dict, k, v) { insert(dict, k, f(k, v)) }
- dict
- |> fold(from: new(), with: f)
-}
-
-/// Gets a list of all keys in a given dict.
-///
-/// Dicts are not ordered so the keys are not returned in any specific order. Do
-/// not write code that relies on the order keys are returned by this function
-/// as it may change in later versions of Gleam or Erlang.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > keys([#("a", 0), #("b", 1)])
-/// ["a", "b"]
-/// ```
-///
-pub fn keys(dict: Dict(keys, v)) -> List(keys) {
- do_keys(dict)
-}
-
-@target(erlang)
-@external(erlang, "maps", "keys")
-fn do_keys(a: Dict(keys, v)) -> List(keys)
-
-@target(javascript)
-fn reverse_and_concat(remaining, accumulator) {
- case remaining {
- [] -> accumulator
- [item, ..rest] -> reverse_and_concat(rest, [item, ..accumulator])
- }
-}
-
-@target(javascript)
-fn do_keys_acc(list: List(#(k, v)), acc: List(k)) -> List(k) {
- case list {
- [] -> reverse_and_concat(acc, [])
- [x, ..xs] -> do_keys_acc(xs, [x.0, ..acc])
- }
-}
-
-@target(javascript)
-fn do_keys(dict: Dict(k, v)) -> List(k) {
- let list_of_pairs = to_list(dict)
- do_keys_acc(list_of_pairs, [])
-}
-
-/// Gets a list of all values in a given dict.
-///
-/// Dicts are not ordered so the values are not returned in any specific order. Do
-/// not write code that relies on the order values are returned by this function
-/// as it may change in later versions of Gleam or Erlang.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > values(from_list([#("a", 0), #("b", 1)]))
-/// [0, 1]
-/// ```
-///
-pub fn values(dict: Dict(k, values)) -> List(values) {
- do_values(dict)
-}
-
-@target(erlang)
-@external(erlang, "maps", "values")
-fn do_values(a: Dict(k, values)) -> List(values)
-
-@target(javascript)
-fn do_values_acc(list: List(#(k, v)), acc: List(v)) -> List(v) {
- case list {
- [] -> reverse_and_concat(acc, [])
- [x, ..xs] -> do_values_acc(xs, [x.1, ..acc])
- }
-}
-
-@target(javascript)
-fn do_values(dict: Dict(k, v)) -> List(v) {
- let list_of_pairs = to_list(dict)
- do_values_acc(list_of_pairs, [])
-}
-
-/// Creates a new dict from a given dict, minus any entries that a given function
-/// returns `False` for.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > from_list([#("a", 0), #("b", 1)])
-/// > |> filter(fn(key, value) { value != 0 })
-/// from_list([#("b", 1)])
-/// ```
-///
-/// ```gleam
-/// > from_list([#("a", 0), #("b", 1)])
-/// > |> filter(fn(key, value) { True })
-/// from_list([#("a", 0), #("b", 1)])
-/// ```
-///
-pub fn filter(
- in dict: Dict(k, v),
- keeping predicate: fn(k, v) -> Bool,
-) -> Dict(k, v) {
- do_filter(predicate, dict)
-}
-
-@target(erlang)
-@external(erlang, "maps", "filter")
-fn do_filter(a: fn(key, value) -> Bool, b: Dict(key, value)) -> Dict(key, value)
-
-@target(javascript)
-fn do_filter(
- f: fn(key, value) -> Bool,
- dict: Dict(key, value),
-) -> Dict(key, value) {
- let insert = fn(dict, k, v) {
- case f(k, v) {
- True -> insert(dict, k, v)
- _ -> dict
- }
- }
- dict
- |> fold(from: new(), with: insert)
-}
-
-/// Creates a new dict from a given dict, only including any entries for which the
-/// keys are in a given list.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > from_list([#("a", 0), #("b", 1)])
-/// > |> take(["b"])
-/// from_list([#("b", 1)])
-/// ```
-///
-/// ```gleam
-/// > from_list([#("a", 0), #("b", 1)])
-/// > |> take(["a", "b", "c"])
-/// from_list([#("a", 0), #("b", 1)])
-/// ```
-///
-pub fn take(from dict: Dict(k, v), keeping desired_keys: List(k)) -> Dict(k, v) {
- do_take(desired_keys, dict)
-}
-
-@target(erlang)
-@external(erlang, "maps", "with")
-fn do_take(a: List(k), b: Dict(k, v)) -> Dict(k, v)
-
-@target(javascript)
-fn insert_taken(
- dict: Dict(k, v),
- desired_keys: List(k),
- acc: Dict(k, v),
-) -> Dict(k, v) {
- let insert = fn(taken, key) {
- case get(dict, key) {
- Ok(value) -> insert(taken, key, value)
- _ -> taken
- }
- }
- case desired_keys {
- [] -> acc
- [x, ..xs] -> insert_taken(dict, xs, insert(acc, x))
- }
-}
-
-@target(javascript)
-fn do_take(desired_keys: List(k), dict: Dict(k, v)) -> Dict(k, v) {
- insert_taken(dict, desired_keys, new())
-}
-
-/// Creates a new dict from a pair of given dicts by combining their entries.
-///
-/// If there are entries with the same keys in both dicts the entry from the
-/// second dict takes precedence.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > let a = from_list([#("a", 0), #("b", 1)])
-/// > let b = from_list([#("b", 2), #("c", 3)])
-/// > merge(a, b)
-/// from_list([#("a", 0), #("b", 2), #("c", 3)])
-/// ```
-///
-pub fn merge(into dict: Dict(k, v), from new_entries: Dict(k, v)) -> Dict(k, v) {
- do_merge(dict, new_entries)
-}
-
-@target(erlang)
-@external(erlang, "maps", "merge")
-fn do_merge(a: Dict(k, v), b: Dict(k, v)) -> Dict(k, v)
-
-@target(javascript)
-fn insert_pair(dict: Dict(k, v), pair: #(k, v)) -> Dict(k, v) {
- insert(dict, pair.0, pair.1)
-}
-
-@target(javascript)
-fn fold_inserts(new_entries: List(#(k, v)), dict: Dict(k, v)) -> Dict(k, v) {
- case new_entries {
- [] -> dict
- [x, ..xs] -> fold_inserts(xs, insert_pair(dict, x))
- }
-}
-
-@target(javascript)
-fn do_merge(dict: Dict(k, v), new_entries: Dict(k, v)) -> Dict(k, v) {
- new_entries
- |> to_list
- |> fold_inserts(dict)
-}
-
-/// Creates a new dict from a given dict with all the same entries except for the
-/// one with a given key, if it exists.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > delete([#("a", 0), #("b", 1)], "a")
-/// from_list([#("b", 1)])
-/// ```
-///
-/// ```gleam
-/// > delete([#("a", 0), #("b", 1)], "c")
-/// from_list([#("a", 0), #("b", 1)])
-/// ```
-///
-pub fn delete(from dict: Dict(k, v), delete key: k) -> Dict(k, v) {
- do_delete(key, dict)
-}
-
-@external(erlang, "maps", "remove")
-@external(javascript, "../gleam_stdlib.mjs", "map_remove")
-fn do_delete(a: k, b: Dict(k, v)) -> Dict(k, v)
-
-/// Creates a new dict from a given dict with all the same entries except any with
-/// keys found in a given list.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > drop([#("a", 0), #("b", 1)], ["a"])
-/// from_list([#("b", 2)])
-/// ```
-///
-/// ```gleam
-/// > delete([#("a", 0), #("b", 1)], ["c"])
-/// from_list([#("a", 0), #("b", 1)])
-/// ```
-///
-/// ```gleam
-/// > drop([#("a", 0), #("b", 1)], ["a", "b", "c"])
-/// from_list([])
-/// ```
-///
-pub fn drop(from dict: Dict(k, v), drop disallowed_keys: List(k)) -> Dict(k, v) {
- case disallowed_keys {
- [] -> dict
- [x, ..xs] -> drop(delete(dict, x), xs)
- }
-}
-
-/// Creates a new dict with one entry updated using a given function.
-///
-/// If there was not an entry in the dict for the given key then the function
-/// gets `None` as its argument, otherwise it gets `Some(value)`.
-///
-/// ## Example
-///
-/// ```gleam
-/// > let increment = fn(x) {
-/// > case x {
-/// > Some(i) -> i + 1
-/// > None -> 0
-/// > }
-/// > }
-/// > let dict = from_list([#("a", 0)])
-/// >
-/// > update(dict, "a", increment)
-/// from_list([#("a", 1)])
-/// ```
-///
-/// ```gleam
-/// > update(dict, "b", increment)
-/// from_list([#("a", 0), #("b", 0)])
-/// ```
-///
-pub fn update(
- in dict: Dict(k, v),
- update key: k,
- with fun: fn(Option(v)) -> v,
-) -> Dict(k, v) {
- dict
- |> get(key)
- |> option.from_result
- |> fun
- |> insert(dict, key, _)
-}
-
-fn do_fold(list: List(#(k, v)), initial: acc, fun: fn(acc, k, v) -> acc) -> acc {
- case list {
- [] -> initial
- [#(k, v), ..rest] -> do_fold(rest, fun(initial, k, v), fun)
- }
-}
-
-/// Combines all entries into a single value by calling a given function on each
-/// one.
-///
-/// Dicts are not ordered so the values are not returned in any specific order. Do
-/// not write code that relies on the order entries are used by this function
-/// as it may change in later versions of Gleam or Erlang.
-///
-/// # Examples
-///
-/// ```gleam
-/// > let dict = from_list([#("a", 1), #("b", 3), #("c", 9)])
-/// > fold(dict, 0, fn(accumulator, key, value) { accumulator + value })
-/// 13
-/// ```
-///
-/// ```gleam
-/// > import gleam/string.{append}
-/// > fold(dict, "", fn(accumulator, key, value) { append(accumulator, key) })
-/// "abc"
-/// ```
-///
-pub fn fold(
- over dict: Dict(k, v),
- from initial: acc,
- with fun: fn(acc, k, v) -> acc,
-) -> acc {
- dict
- |> to_list
- |> do_fold(initial, fun)
-}
diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam/dynamic.gleam b/aoc2023/build/packages/gleam_stdlib/src/gleam/dynamic.gleam
deleted file mode 100644
index c71c6f3..0000000
--- a/aoc2023/build/packages/gleam_stdlib/src/gleam/dynamic.gleam
+++ /dev/null
@@ -1,1508 +0,0 @@
-import gleam/int
-import gleam/list
-import gleam/dict.{type Dict}
-import gleam/option.{type Option}
-import gleam/result
-import gleam/string_builder
-@target(erlang)
-import gleam/bit_array
-
-/// `Dynamic` data is data that we don't know the type of yet.
-/// We likely get data like this from interop with Erlang, or from
-/// IO with the outside world.
-///
-pub type Dynamic
-
-/// Error returned when unexpected data is encountered
-///
-pub type DecodeError {
- DecodeError(expected: String, found: String, path: List(String))
-}
-
-pub type DecodeErrors =
- List(DecodeError)
-
-pub type Decoder(t) =
- fn(Dynamic) -> Result(t, DecodeErrors)
-
-/// Converts any Gleam data into `Dynamic` data.
-///
-pub fn from(a) -> Dynamic {
- do_from(a)
-}
-
-@external(erlang, "gleam_stdlib", "identity")
-@external(javascript, "../gleam_stdlib.mjs", "identity")
-fn do_from(a: anything) -> Dynamic
-
-/// Unsafely casts a Dynamic value into any other type.
-///
-/// This is an escape hatch for the type system that may be useful when wrapping
-/// native Erlang APIs. It is to be used as a last measure only!
-///
-/// If you can avoid using this function, do!
-///
-pub fn unsafe_coerce(a: Dynamic) -> anything {
- do_unsafe_coerce(a)
-}
-
-@external(erlang, "gleam_stdlib", "identity")
-@external(javascript, "../gleam_stdlib.mjs", "identity")
-fn do_unsafe_coerce(a: Dynamic) -> a
-
-/// Decodes a `Dynamic` value from a `Dynamic` value.
-///
-/// This function doesn't seem very useful at first, but it can be convenient
-/// when you need to give a decoder function but you don't actually care what
-/// the to-decode value is.
-///
-pub fn dynamic(value: Dynamic) -> Result(Dynamic, List(DecodeError)) {
- Ok(value)
-}
-
-/// Checks to see whether a `Dynamic` value is a bit array, and returns that bit
-/// array if it is.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > bit_array(from("Hello")) == bit_array.from_string("Hello")
-/// True
-/// ```
-///
-/// ```gleam
-/// > bit_array(from(123))
-/// Error([DecodeError(expected: "BitArray", found: "Int", path: [])])
-/// ```
-///
-pub fn bit_array(from data: Dynamic) -> Result(BitArray, DecodeErrors) {
- decode_bit_array(data)
-}
-
-@deprecated("Please use `bit_array` instead")
-pub fn bit_string(from data: Dynamic) -> Result(BitArray, DecodeErrors) {
- bit_array(data)
-}
-
-@external(erlang, "gleam_stdlib", "decode_bit_array")
-@external(javascript, "../gleam_stdlib.mjs", "decode_bit_array")
-fn decode_bit_array(a: Dynamic) -> Result(BitArray, DecodeErrors)
-
-/// Checks to see whether a `Dynamic` value is a string, and returns that string if
-/// it is.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > string(from("Hello"))
-/// Ok("Hello")
-/// ```
-///
-/// ```gleam
-/// > string(from(123))
-/// Error([DecodeError(expected: "String", found: "Int", path: [])])
-/// ```
-///
-pub fn string(from data: Dynamic) -> Result(String, DecodeErrors) {
- decode_string(data)
-}
-
-fn map_errors(
- result: Result(t, DecodeErrors),
- f: fn(DecodeError) -> DecodeError,
-) -> Result(t, DecodeErrors) {
- result.map_error(result, list.map(_, f))
-}
-
-@target(erlang)
-fn decode_string(data: Dynamic) -> Result(String, DecodeErrors) {
- bit_array(data)
- |> map_errors(put_expected(_, "String"))
- |> result.try(fn(raw) {
- case bit_array.to_string(raw) {
- Ok(string) -> Ok(string)
- Error(Nil) ->
- Error([DecodeError(expected: "String", found: "BitArray", path: [])])
- }
- })
-}
-
-@target(erlang)
-fn put_expected(error: DecodeError, expected: String) -> DecodeError {
- DecodeError(..error, expected: expected)
-}
-
-@target(javascript)
-@external(javascript, "../gleam_stdlib.mjs", "decode_string")
-fn decode_string(a: Dynamic) -> Result(String, DecodeErrors)
-
-/// Return a string indicating the type of the dynamic value.
-///
-/// ```gleam
-/// > classify(from("Hello"))
-/// "String"
-/// ```
-///
-pub fn classify(data: Dynamic) -> String {
- do_classify(data)
-}
-
-@external(erlang, "gleam_stdlib", "classify_dynamic")
-@external(javascript, "../gleam_stdlib.mjs", "classify_dynamic")
-fn do_classify(a: Dynamic) -> String
-
-/// Checks to see whether a `Dynamic` value is an int, and returns that int if it
-/// is.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > int(from(123))
-/// Ok(123)
-/// ```
-///
-/// ```gleam
-/// > int(from("Hello"))
-/// Error([DecodeError(expected: "Int", found: "String", path: [])])
-/// ```
-///
-pub fn int(from data: Dynamic) -> Result(Int, DecodeErrors) {
- decode_int(data)
-}
-
-@external(erlang, "gleam_stdlib", "decode_int")
-@external(javascript, "../gleam_stdlib.mjs", "decode_int")
-fn decode_int(a: Dynamic) -> Result(Int, DecodeErrors)
-
-/// Checks to see whether a `Dynamic` value is a float, and returns that float if
-/// it is.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > float(from(2.0))
-/// Ok(2.0)
-/// ```
-///
-/// ```gleam
-/// > float(from(123))
-/// Error([DecodeError(expected: "Float", found: "Int", path: [])])
-/// ```
-///
-pub fn float(from data: Dynamic) -> Result(Float, DecodeErrors) {
- decode_float(data)
-}
-
-@external(erlang, "gleam_stdlib", "decode_float")
-@external(javascript, "../gleam_stdlib.mjs", "decode_float")
-fn decode_float(a: Dynamic) -> Result(Float, DecodeErrors)
-
-/// Checks to see whether a `Dynamic` value is a bool, and returns that bool if
-/// it is.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > bool(from(True))
-/// Ok(True)
-/// ```
-///
-/// ```gleam
-/// > bool(from(123))
-/// Error([DecodeError(expected: "Bool", found: "Int", path: [])])
-/// ```
-///
-pub fn bool(from data: Dynamic) -> Result(Bool, DecodeErrors) {
- decode_bool(data)
-}
-
-@external(erlang, "gleam_stdlib", "decode_bool")
-@external(javascript, "../gleam_stdlib.mjs", "decode_bool")
-fn decode_bool(a: Dynamic) -> Result(Bool, DecodeErrors)
-
-/// Checks to see whether a `Dynamic` value is a list, and returns that list if it
-/// is. The types of the elements are not checked.
-///
-/// If you wish to decode all the elements in the list use the `list` function
-/// instead.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > shallow_list(from(["a", "b", "c"]))
-/// Ok([from("a"), from("b"), from("c")])
-/// ```
-///
-/// ```gleam
-/// > shallow_list(1)
-/// Error([DecodeError(expected: "List", found: "Int", path: [])])
-/// ```
-///
-pub fn shallow_list(from value: Dynamic) -> Result(List(Dynamic), DecodeErrors) {
- decode_list(value)
-}
-
-@external(erlang, "gleam_stdlib", "decode_list")
-@external(javascript, "../gleam_stdlib.mjs", "decode_list")
-fn decode_list(a: Dynamic) -> Result(List(Dynamic), DecodeErrors)
-
-@external(erlang, "gleam_stdlib", "decode_result")
-@external(javascript, "../gleam_stdlib.mjs", "decode_result")
-fn decode_result(a: Dynamic) -> Result(Result(a, e), DecodeErrors)
-
-/// Checks to see whether a `Dynamic` value is a result of a particular type, and
-/// returns that result if it is.
-///
-/// The `ok` and `error` arguments are decoders for decoding the `Ok` and
-/// `Error` values of the result.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > from(Ok(1))
-/// > |> result(ok: int, error: string)
-/// Ok(Ok(1))
-/// ```
-///
-/// ```gleam
-/// > from(Error("boom"))
-/// > |> result(ok: int, error: string)
-/// Ok(Error("boom"))
-/// ```
-///
-/// ```gleam
-/// > from(123)
-/// > |> result(ok: int, error: string)
-/// Error([DecodeError(expected: "Result", found: "Int", path: [])])
-/// ```
-///
-pub fn result(
- ok decode_ok: Decoder(a),
- error decode_error: Decoder(e),
-) -> Decoder(Result(a, e)) {
- fn(value) {
- use inner_result <- result.try(decode_result(value))
-
- case inner_result {
- Ok(raw) -> {
- use value <- result.try(
- decode_ok(raw)
- |> map_errors(push_path(_, "ok")),
- )
- Ok(Ok(value))
- }
- Error(raw) -> {
- use value <- result.try(
- decode_error(raw)
- |> map_errors(push_path(_, "error")),
- )
- Ok(Error(value))
- }
- }
- }
-}
-
-/// Checks to see whether a `Dynamic` value is a list of a particular type, and
-/// returns that list if it is.
-///
-/// The second argument is a decoder function used to decode the elements of
-/// the list. The list is only decoded if all elements in the list can be
-/// successfully decoded using this function.
-///
-/// If you do not wish to decode all the elements in the list use the `shallow_list`
-/// function instead.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > from(["a", "b", "c"])
-/// > |> list(of: string)
-/// Ok(["a", "b", "c"])
-/// ```
-///
-/// ```gleam
-/// > from([1, 2, 3])
-/// > |> list(of: string)
-/// Error([DecodeError(expected: "String", found: "Int", path: ["*"])])
-/// ```
-///
-/// ```gleam
-/// > from("ok")
-/// > |> list(of: string)
-/// Error([DecodeError(expected: "List", found: "String", path: [])])
-/// ```
-///
-pub fn list(
- of decoder_type: fn(Dynamic) -> Result(inner, DecodeErrors),
-) -> Decoder(List(inner)) {
- fn(dynamic) {
- use list <- result.try(shallow_list(dynamic))
- list
- |> list.try_map(decoder_type)
- |> map_errors(push_path(_, "*"))
- }
-}
-
-/// Checks to see if a `Dynamic` value is a nullable version of a particular
-/// type, and returns a corresponding `Option` if it is.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > from("Hello")
-/// > |> optional(string)
-/// Ok(Some("Hello"))
-/// ```
-///
-/// ```gleam
-/// > from("Hello")
-/// > |> optional(string)
-/// Ok(Some("Hello"))
-/// ```
-///
-/// ```gleam
-/// > from(atom.from_string("null"))
-/// > |> optional(string)
-/// Ok(None)
-/// ```
-///
-/// ```gleam
-/// > from(atom.from_string("nil"))
-/// > |> optional(string)
-/// Ok(None)
-/// ```
-///
-/// ```gleam
-/// > from(atom.from_string("undefined"))
-/// > |> optional(string)
-/// Ok(None)
-/// ```
-///
-/// ```gleam
-/// > from(123)
-/// > |> optional(string)
-/// Error([DecodeError(expected: "String", found: "Int", path: [])])
-/// ```
-///
-pub fn optional(of decode: Decoder(inner)) -> Decoder(Option(inner)) {
- fn(value) { decode_optional(value, decode) }
-}
-
-@external(erlang, "gleam_stdlib", "decode_option")
-@external(javascript, "../gleam_stdlib.mjs", "decode_option")
-fn decode_optional(a: Dynamic, b: Decoder(a)) -> Result(Option(a), DecodeErrors)
-
-/// Checks to see if a `Dynamic` value is a map with a specific field, and returns
-/// the value of that field if it is.
-///
-/// This will not succeed on a record.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > import gleam/dict
-/// > dict.new()
-/// > |> dict.insert("Hello", "World")
-/// > |> from
-/// > |> field(named: "Hello", of: string)
-/// Ok("World")
-/// ```
-///
-/// ```gleam
-/// > from(123)
-/// > |> field("Hello", string)
-/// Error([DecodeError(expected: "Map", found: "Int", path: [])])
-/// ```
-///
-pub fn field(named name: a, of inner_type: Decoder(t)) -> Decoder(t) {
- fn(value) {
- let missing_field_error =
- DecodeError(expected: "field", found: "nothing", path: [])
-
- use maybe_inner <- result.try(decode_field(value, name))
- maybe_inner
- |> option.to_result([missing_field_error])
- |> result.try(inner_type)
- |> map_errors(push_path(_, name))
- }
-}
-
-/// Checks to see if a `Dynamic` value is a map with a specific field.
-/// If the map does not have the specified field, returns an `Ok(None)` instead of failing; otherwise,
-/// returns the decoded field wrapped in `Some(_)`.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > import gleam/dict
-/// > dict.new()
-/// > |> dict.insert("Hello", "World")
-/// > |> from
-/// > |> field(named: "Hello", of: string)
-/// Ok(Some("World"))
-/// ```
-///
-/// ```gleam
-/// > import gleam/dict
-/// > dict.new()
-/// > |> from
-/// > |> field(named: "Hello", of: string)
-/// Ok(None)
-/// ```
-///
-/// ```gleam
-/// > from(123)
-/// > |> field("Hello", string)
-/// Error([DecodeError(expected: "Map", found: "Int", path: [])])
-/// ```
-///
-pub fn optional_field(
- named name: a,
- of inner_type: Decoder(t),
-) -> Decoder(Option(t)) {
- fn(value) {
- use maybe_inner <- result.try(decode_field(value, name))
- case maybe_inner {
- option.None -> Ok(option.None)
- option.Some(dynamic_inner) ->
- dynamic_inner
- |> decode_optional(inner_type)
- |> map_errors(push_path(_, name))
- }
- }
-}
-
-@external(erlang, "gleam_stdlib", "decode_field")
-@external(javascript, "../gleam_stdlib.mjs", "decode_field")
-fn decode_field(a: Dynamic, b: name) -> Result(Option(Dynamic), DecodeErrors)
-
-/// Checks to see if a `Dynamic` value is a tuple large enough to have a certain
-/// index, and returns the value of that index if it is.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > from(#(1, 2))
-/// > |> element(0, int)
-/// Ok(from(1))
-/// ```
-///
-/// ```gleam
-/// > from(#(1, 2))
-/// > |> element(2, int)
-/// Error([
-/// DecodeError(
-/// expected: "Tuple of at least 3 elements",
-/// found: "Tuple of 2 elements",
-/// path: [],
-/// ),
-/// ])
-/// ```
-///
-pub fn element(at index: Int, of inner_type: Decoder(t)) -> Decoder(t) {
- fn(data: Dynamic) {
- use tuple <- result.try(decode_tuple(data))
- let size = tuple_size(tuple)
- use data <- result.try(case index >= 0 {
- True ->
- case index < size {
- True -> tuple_get(tuple, index)
- False -> at_least_decode_tuple_error(index + 1, data)
- }
- False ->
- case int.absolute_value(index) <= size {
- True -> tuple_get(tuple, size + index)
- False -> at_least_decode_tuple_error(int.absolute_value(index), data)
- }
- })
- inner_type(data)
- |> map_errors(push_path(_, index))
- }
-}
-
-fn at_least_decode_tuple_error(
- size: Int,
- data: Dynamic,
-) -> Result(a, DecodeErrors) {
- let s = case size {
- 1 -> ""
- _ -> "s"
- }
- let error =
- ["Tuple of at least ", int.to_string(size), " element", s]
- |> string_builder.from_strings
- |> string_builder.to_string
- |> DecodeError(found: classify(data), path: [])
- Error([error])
-}
-
-// A tuple of unknown size
-type UnknownTuple
-
-@external(erlang, "gleam_stdlib", "decode_tuple")
-@external(javascript, "../gleam_stdlib.mjs", "decode_tuple")
-fn decode_tuple(a: Dynamic) -> Result(UnknownTuple, DecodeErrors)
-
-@external(erlang, "gleam_stdlib", "decode_tuple2")
-@external(javascript, "../gleam_stdlib.mjs", "decode_tuple2")
-fn decode_tuple2(a: Dynamic) -> Result(#(Dynamic, Dynamic), DecodeErrors)
-
-@external(erlang, "gleam_stdlib", "decode_tuple3")
-@external(javascript, "../gleam_stdlib.mjs", "decode_tuple3")
-fn decode_tuple3(
- a: Dynamic,
-) -> Result(#(Dynamic, Dynamic, Dynamic), DecodeErrors)
-
-@external(erlang, "gleam_stdlib", "decode_tuple4")
-@external(javascript, "../gleam_stdlib.mjs", "decode_tuple4")
-fn decode_tuple4(
- a: Dynamic,
-) -> Result(#(Dynamic, Dynamic, Dynamic, Dynamic), DecodeErrors)
-
-@external(erlang, "gleam_stdlib", "decode_tuple5")
-@external(javascript, "../gleam_stdlib.mjs", "decode_tuple5")
-fn decode_tuple5(
- a: Dynamic,
-) -> Result(#(Dynamic, Dynamic, Dynamic, Dynamic, Dynamic), DecodeErrors)
-
-@external(erlang, "gleam_stdlib", "decode_tuple6")
-@external(javascript, "../gleam_stdlib.mjs", "decode_tuple6")
-fn decode_tuple6(
- a: Dynamic,
-) -> Result(
- #(Dynamic, Dynamic, Dynamic, Dynamic, Dynamic, Dynamic),
- DecodeErrors,
-)
-
-@external(erlang, "gleam_stdlib", "tuple_get")
-@external(javascript, "../gleam_stdlib.mjs", "tuple_get")
-fn tuple_get(a: UnknownTuple, b: Int) -> Result(Dynamic, DecodeErrors)
-
-@external(erlang, "gleam_stdlib", "size_of_tuple")
-@external(javascript, "../gleam_stdlib.mjs", "length")
-fn tuple_size(a: UnknownTuple) -> Int
-
-fn tuple_errors(
- result: Result(a, List(DecodeError)),
- name: String,
-) -> List(DecodeError) {
- case result {
- Ok(_) -> []
- Error(errors) -> list.map(errors, push_path(_, name))
- }
-}
-
-fn push_path(error: DecodeError, name: t) -> DecodeError {
- let name = from(name)
- let decoder = any([string, fn(x) { result.map(int(x), int.to_string) }])
- let name = case decoder(name) {
- Ok(name) -> name
- Error(_) ->
- ["<", classify(name), ">"]
- |> string_builder.from_strings
- |> string_builder.to_string
- }
- DecodeError(..error, path: [name, ..error.path])
-}
-
-/// Checks to see if a `Dynamic` value is a 2-element tuple, list or array containing
-/// specifically typed elements.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > from(#(1, 2))
-/// > |> tuple2(int, int)
-/// Ok(#(1, 2))
-/// ```
-///
-/// ```gleam
-/// > from(#(1, 2.0))
-/// > |> tuple2(int, float)
-/// Ok(#(1, 2.0))
-/// ```
-///
-/// ```gleam
-/// > from([1, 2])
-/// > |> tuple2(int, int)
-/// Ok(#(1, 2))
-/// ```
-///
-/// ```gleam
-/// > from([from(1), from(2.0)])
-/// > |> tuple2(int, float)
-/// Ok(#(1, 2.0))
-/// ```
-///
-/// ```gleam
-/// > from(#(1, 2, 3))
-/// > |> tuple2(int, float)
-/// Error([
-/// DecodeError(expected: "Tuple of 2 elements", found: "Tuple of 3 elements", path: []),
-/// ])
-/// ```
-///
-/// ```gleam
-/// > from("")
-/// > |> tuple2(int, float)
-/// Error([DecodeError(expected: "Tuple of 2 elements", found: "String", path: [])])
-/// ```
-///
-pub fn tuple2(
- first decode1: Decoder(a),
- second decode2: Decoder(b),
-) -> Decoder(#(a, b)) {
- fn(value) {
- use #(a, b) <- result.try(decode_tuple2(value))
- case decode1(a), decode2(b) {
- Ok(a), Ok(b) -> Ok(#(a, b))
- a, b ->
- tuple_errors(a, "0")
- |> list.append(tuple_errors(b, "1"))
- |> Error
- }
- }
-}
-
-/// Checks to see if a `Dynamic` value is a 3-element tuple, list or array containing
-/// specifically typed elements.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > from(#(1, 2, 3))
-/// > |> tuple3(int, int, int)
-/// Ok(#(1, 2, 3))
-/// ```
-///
-/// ```gleam
-/// > from(#(1, 2.0, "3"))
-/// > |> tuple3(int, float, string)
-/// Ok(#(1, 2.0, "3"))
-/// ```
-///
-/// ```gleam
-/// > from([1, 2, 3])
-/// > |> tuple3(int, int, int)
-/// Ok(#(1, 2, 3))
-/// ```
-///
-/// ```gleam
-/// > from([from(1), from(2.0), from("3")])
-/// > |> tuple3(int, float, string)
-/// Ok(#(1, 2.0, "3"))
-/// ```
-///
-/// ```gleam
-/// > from(#(1, 2))
-/// > |> tuple3(int, float, string)
-/// Error([
-/// DecodeError(expected: "Tuple of 3 elements", found: "Tuple of 2 elements", path: [])),
-/// ])
-/// ```
-///
-/// ```gleam
-/// > from("")
-/// > |> tuple3(int, float, string)
-/// Error([
-/// DecodeError(expected: "Tuple of 3 elements", found: "String", path: []),
-/// ])
-/// ```
-///
-pub fn tuple3(
- first decode1: Decoder(a),
- second decode2: Decoder(b),
- third decode3: Decoder(c),
-) -> Decoder(#(a, b, c)) {
- fn(value) {
- use #(a, b, c) <- result.try(decode_tuple3(value))
- case decode1(a), decode2(b), decode3(c) {
- Ok(a), Ok(b), Ok(c) -> Ok(#(a, b, c))
- a, b, c ->
- tuple_errors(a, "0")
- |> list.append(tuple_errors(b, "1"))
- |> list.append(tuple_errors(c, "2"))
- |> Error
- }
- }
-}
-
-/// Checks to see if a `Dynamic` value is a 4-element tuple, list or array containing
-/// specifically typed elements.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > from(#(1, 2, 3, 4))
-/// > |> tuple4(int, int, int, int)
-/// Ok(#(1, 2, 3, 4))
-/// ```
-///
-/// ```gleam
-/// > from(#(1, 2.0, "3", 4))
-/// > |> tuple4(int, float, string, int)
-/// Ok(#(1, 2.0, "3", 4))
-/// ```
-///
-/// ```gleam
-/// > from([1, 2, 3, 4])
-/// > |> tuple4(int, int, int, int)
-/// Ok(#(1, 2, 3, 4))
-/// ```
-///
-/// ```gleam
-/// > from([from(1), from(2.0), from("3"), from(4)])
-/// > |> tuple4(int, float, string, int)
-/// Ok(#(1, 2.0, "3", 4))
-/// ```
-///
-/// ```gleam
-/// > from(#(1, 2))
-/// > |> tuple4(int, float, string, int)
-/// Error([
-/// DecodeError(expected: "Tuple of 4 elements", found: "Tuple of 2 elements", path: []),
-/// ])
-/// ```
-///
-/// ```gleam
-/// > from("")
-/// > |> tuple4(int, float, string, int)
-/// Error([
-/// DecodeError(expected: "Tuple of 4 elements", found: "String", path: []),
-/// ])
-/// ```
-///
-pub fn tuple4(
- first decode1: Decoder(a),
- second decode2: Decoder(b),
- third decode3: Decoder(c),
- fourth decode4: Decoder(d),
-) -> Decoder(#(a, b, c, d)) {
- fn(value) {
- use #(a, b, c, d) <- result.try(decode_tuple4(value))
- case decode1(a), decode2(b), decode3(c), decode4(d) {
- Ok(a), Ok(b), Ok(c), Ok(d) -> Ok(#(a, b, c, d))
- a, b, c, d ->
- tuple_errors(a, "0")
- |> list.append(tuple_errors(b, "1"))
- |> list.append(tuple_errors(c, "2"))
- |> list.append(tuple_errors(d, "3"))
- |> Error
- }
- }
-}
-
-/// Checks to see if a `Dynamic` value is a 5-element tuple, list or array containing
-/// specifically typed elements.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > from(#(1, 2, 3, 4, 5))
-/// > |> tuple5(int, int, int, int, int)
-/// Ok(#(1, 2, 3, 4, 5))
-/// ```
-///
-/// ```gleam
-/// > from(#(1, 2.0, "3", 4, 5))
-/// > |> tuple5(int, float, string, int, int)
-/// Ok(#(1, 2.0, "3", 4, 5))
-/// ```
-///
-/// ```gleam
-/// > from([1, 2, 3, 4, 5])
-/// > |> tuple5(int, int, int, int, int)
-/// Ok(#(1, 2, 3, 4, 5))
-/// ```
-///
-/// ```gleam
-/// > from([from(1), from(2.0), from("3"), from(4), from(True)])
-/// > |> tuple5(int, float, string, int, bool)
-/// Ok(#(1, 2.0, "3", 4, True))
-/// ```
-///
-/// ```gleam
-/// > from(#(1, 2))
-/// > |> tuple5(int, float, string, int, int)
-/// Error([
-/// DecodeError(expected: "Tuple of 5 elements", found: "Tuple of 2 elements", path: [])),
-/// ])
-/// ```
-///
-/// ```gleam
-/// > from("")
-/// > |> tuple5(int, float, string, int, int)
-/// Error([DecodeError(expected: "Tuple of 5 elements", found: "String", path: [])])
-/// ```
-///
-pub fn tuple5(
- first decode1: Decoder(a),
- second decode2: Decoder(b),
- third decode3: Decoder(c),
- fourth decode4: Decoder(d),
- fifth decode5: Decoder(e),
-) -> Decoder(#(a, b, c, d, e)) {
- fn(value) {
- use #(a, b, c, d, e) <- result.try(decode_tuple5(value))
- case decode1(a), decode2(b), decode3(c), decode4(d), decode5(e) {
- Ok(a), Ok(b), Ok(c), Ok(d), Ok(e) -> Ok(#(a, b, c, d, e))
- a, b, c, d, e ->
- tuple_errors(a, "0")
- |> list.append(tuple_errors(b, "1"))
- |> list.append(tuple_errors(c, "2"))
- |> list.append(tuple_errors(d, "3"))
- |> list.append(tuple_errors(e, "4"))
- |> Error
- }
- }
-}
-
-/// Checks to see if a `Dynamic` value is a 6-element tuple, list or array containing
-/// specifically typed elements.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > from(#(1, 2, 3, 4, 5, 6))
-/// > |> tuple6(int, int, int, int, int, int)
-/// Ok(#(1, 2, 3, 4, 5, 6))
-/// ```
-///
-/// ```gleam
-/// > from(#(1, 2.0, "3", 4, 5, 6))
-/// > |> tuple6(int, float, string, int, int, int)
-/// Ok(#(1, 2.0, "3", 4, 5, 6))
-/// ```
-///
-/// ```gleam
-/// > from([1, 2, 3, 4, 5, 6])
-/// > |> tuple6(int, int, int, int, int, int)
-/// Ok(#(1, 2, 3, 4, 5, 6))
-/// ```
-///
-/// ```gleam
-/// > from([from(1), from(2.0), from("3"), from(4), from(True), from(False)])
-/// > |> tuple6(int, float, string, int, bool, bool)
-/// Ok(#(1, 2.0, "3", 4, True, False))
-/// ```
-///
-/// ```gleam
-/// > from(#(1, 2))
-/// > |> tuple6(int, float, string, int, int, int)
-/// Error([
-/// DecodeError(expected: "Tuple of 6 elements", found: "Tuple of 2 elements", path: []),
-/// ])
-/// ```
-///
-/// ```gleam
-/// > from("")
-/// > |> tuple6(int, float, string, int, int, int)
-/// Error([DecodeError(expected: "Tuple of 6 elements", found: "String", path: [])])
-/// ```
-///
-pub fn tuple6(
- first decode1: Decoder(a),
- second decode2: Decoder(b),
- third decode3: Decoder(c),
- fourth decode4: Decoder(d),
- fifth decode5: Decoder(e),
- sixth decode6: Decoder(f),
-) -> Decoder(#(a, b, c, d, e, f)) {
- fn(value) {
- use #(a, b, c, d, e, f) <- result.try(decode_tuple6(value))
- case
- decode1(a),
- decode2(b),
- decode3(c),
- decode4(d),
- decode5(e),
- decode6(f)
- {
- Ok(a), Ok(b), Ok(c), Ok(d), Ok(e), Ok(f) -> Ok(#(a, b, c, d, e, f))
- a, b, c, d, e, f ->
- tuple_errors(a, "0")
- |> list.append(tuple_errors(b, "1"))
- |> list.append(tuple_errors(c, "2"))
- |> list.append(tuple_errors(d, "3"))
- |> list.append(tuple_errors(e, "4"))
- |> list.append(tuple_errors(f, "5"))
- |> Error
- }
- }
-}
-
-/// Checks to see if a `Dynamic` value is a dict.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > import gleam/dict
-/// > dict.new() |> from |> map(string, int)
-/// Ok(dict.new())
-/// ```
-///
-/// ```gleam
-/// > from(1) |> map(string, int)
-/// Error(DecodeError(expected: "Map", found: "Int", path: []))
-/// ```
-///
-/// ```gleam
-/// > from("") |> map(string, int)
-/// Error(DecodeError(expected: "Map", found: "String", path: []))
-/// ```
-///
-pub fn dict(
- of key_type: Decoder(k),
- to value_type: Decoder(v),
-) -> Decoder(Dict(k, v)) {
- fn(value) {
- use map <- result.try(decode_map(value))
- use pairs <- result.try(
- map
- |> dict.to_list
- |> list.try_map(fn(pair) {
- let #(k, v) = pair
- use k <- result.try(
- key_type(k)
- |> map_errors(push_path(_, "keys")),
- )
- use v <- result.try(
- value_type(v)
- |> map_errors(push_path(_, "values")),
- )
- Ok(#(k, v))
- }),
- )
- Ok(dict.from_list(pairs))
- }
-}
-
-@deprecated("Use `dict` instead")
-pub fn map(
- of key_type: Decoder(k),
- to value_type: Decoder(v),
-) -> Decoder(Dict(k, v)) {
- dict(key_type, value_type)
-}
-
-@external(erlang, "gleam_stdlib", "decode_map")
-@external(javascript, "../gleam_stdlib.mjs", "decode_map")
-fn decode_map(a: Dynamic) -> Result(Dict(Dynamic, Dynamic), DecodeErrors)
-
-/// Joins multiple decoders into one. When run they will each be tried in turn
-/// until one succeeds, or they all fail.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > import gleam/result
-/// > let bool_or_string = any(of: [
-/// > string,
-/// > fn(x) { result.map(bool(x), fn(_) { "a bool" }) }
-/// > ])
-/// > bool_or_string(from("ok"))
-/// Ok("ok")
-/// ```
-///
-/// ```gleam
-/// > bool_or_string(from(True))
-/// Ok("a bool")
-/// ```
-///
-/// ```gleam
-/// > bool_or_string(from(1))
-/// Error(DecodeError(expected: "another type", found: "Int", path: []))
-/// ```
-///
-pub fn any(of decoders: List(Decoder(t))) -> Decoder(t) {
- fn(data) {
- case decoders {
- [] ->
- Error([
- DecodeError(found: classify(data), expected: "another type", path: []),
- ])
-
- [decoder, ..decoders] ->
- case decoder(data) {
- Ok(decoded) -> Ok(decoded)
- Error(_) -> any(decoders)(data)
- }
- }
- }
-}
-
-/// Decode 1 values from a `Dynamic` value.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > from(#(1, 2.0, "3"))
-/// > |> decode1(MyRecord, element(0, int))
-/// Ok(MyRecord(1))
-/// ```
-///
-/// ```gleam
-/// > from(#("", "", ""))
-/// > |> decode1(MyRecord, element(0, int))
-/// Error([
-/// DecodeError(expected: "Int", found: "String", path: ["0"]),
-/// ])
-/// ```
-///
-pub fn decode1(constructor: fn(t1) -> t, t1: Decoder(t1)) -> Decoder(t) {
- fn(value) {
- case t1(value) {
- Ok(a) -> Ok(constructor(a))
- a -> Error(all_errors(a))
- }
- }
-}
-
-/// Decode 2 values from a `Dynamic` value.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > from(#(1, 2.0, "3"))
-/// > |> decode2(MyRecord, element(0, int), element(1, float))
-/// Ok(MyRecord(1, 2.0))
-/// ```
-///
-/// ```gleam
-/// > from(#("", "", ""))
-/// > |> decode2(MyRecord, element(0, int), element(1, float))
-/// Error([
-/// DecodeError(expected: "Int", found: "String", path: ["0"]),
-/// DecodeError(expected: "Float", found: "String", path: ["1"]),
-/// ])
-/// ```
-///
-pub fn decode2(
- constructor: fn(t1, t2) -> t,
- t1: Decoder(t1),
- t2: Decoder(t2),
-) -> Decoder(t) {
- fn(value) {
- case t1(value), t2(value) {
- Ok(a), Ok(b) -> Ok(constructor(a, b))
- a, b -> Error(list.concat([all_errors(a), all_errors(b)]))
- }
- }
-}
-
-/// Decode 3 values from a `Dynamic` value.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > from(#(1, 2.0, "3"))
-/// > |> decode3(MyRecord, element(0, int), element(1, float), element(2, string))
-/// Ok(MyRecord(1, 2.0, "3"))
-/// ```
-///
-/// ```gleam
-/// > from(#("", "", ""))
-/// > |> decode3(MyRecord, element(0, int), element(1, float), element(2, string))
-/// Error([
-/// DecodeError(expected: "Int", found: "String", path: ["0"]),
-/// DecodeError(expected: "Float", found: "String", path: ["1"]),
-/// ])
-/// ```
-///
-pub fn decode3(
- constructor: fn(t1, t2, t3) -> t,
- t1: Decoder(t1),
- t2: Decoder(t2),
- t3: Decoder(t3),
-) -> Decoder(t) {
- fn(value) {
- case t1(value), t2(value), t3(value) {
- Ok(a), Ok(b), Ok(c) -> Ok(constructor(a, b, c))
- a, b, c ->
- Error(list.concat([all_errors(a), all_errors(b), all_errors(c)]))
- }
- }
-}
-
-/// Decode 4 values from a `Dynamic` value.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > from(#(1, 2.1, "3", "4"))
-/// > |> decode4(
-/// > MyRecord,
-/// > element(0, int),
-/// > element(1, float),
-/// > element(2, string),
-/// > element(3, string),
-/// > )
-/// Ok(MyRecord(1, 2.1, "3", "4"))
-/// ```
-///
-/// ```gleam
-/// > from(#("", "", "", ""))
-/// > |> decode4(
-/// > MyRecord,
-/// > element(0, int),
-/// > element(1, float),
-/// > element(2, string),
-/// > element(3, string),
-/// > )
-/// Error([
-/// DecodeError(expected: "Int", found: "String", path: ["0"]),
-/// DecodeError(expected: "Float", found: "String", path: ["1"]),
-/// ])
-/// ```
-///
-pub fn decode4(
- constructor: fn(t1, t2, t3, t4) -> t,
- t1: Decoder(t1),
- t2: Decoder(t2),
- t3: Decoder(t3),
- t4: Decoder(t4),
-) -> Decoder(t) {
- fn(x: Dynamic) {
- case t1(x), t2(x), t3(x), t4(x) {
- Ok(a), Ok(b), Ok(c), Ok(d) -> Ok(constructor(a, b, c, d))
- a, b, c, d ->
- Error(list.concat([
- all_errors(a),
- all_errors(b),
- all_errors(c),
- all_errors(d),
- ]))
- }
- }
-}
-
-/// Decode 5 values from a `Dynamic` value.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > from(#(1, 2.1, "3", "4", "5"))
-/// > |> decode5(
-/// > MyRecord,
-/// > element(0, int),
-/// > element(1, float),
-/// > element(2, string),
-/// > element(3, string),
-/// > element(4, string),
-/// > )
-/// Ok(MyRecord(1, 2.1, "3", "4", "5"))
-/// ```
-///
-/// ```gleam
-/// > from(#("", "", "", "", ""))
-/// > |> decode5(
-/// > MyRecord,
-/// > element(0, int),
-/// > element(1, float),
-/// > element(2, string),
-/// > element(3, string),
-/// > element(4, string),
-/// > )
-/// Error([
-/// DecodeError(expected: "Int", found: "String", path: ["0"]),
-/// DecodeError(expected: "Float", found: "String", path: ["1"]),
-/// ])
-/// ```
-///
-pub fn decode5(
- constructor: fn(t1, t2, t3, t4, t5) -> t,
- t1: Decoder(t1),
- t2: Decoder(t2),
- t3: Decoder(t3),
- t4: Decoder(t4),
- t5: Decoder(t5),
-) -> Decoder(t) {
- fn(x: Dynamic) {
- case t1(x), t2(x), t3(x), t4(x), t5(x) {
- Ok(a), Ok(b), Ok(c), Ok(d), Ok(e) -> Ok(constructor(a, b, c, d, e))
- a, b, c, d, e ->
- Error(list.concat([
- all_errors(a),
- all_errors(b),
- all_errors(c),
- all_errors(d),
- all_errors(e),
- ]))
- }
- }
-}
-
-/// Decode 6 values from a `Dynamic` value.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > from(#(1, 2.1, "3", "4", "5", "6"))
-/// > |> decode6(
-/// > MyRecord,
-/// > element(0, int),
-/// > element(1, float),
-/// > element(2, string),
-/// > element(3, string),
-/// > element(4, string),
-/// > element(5, string),
-/// > )
-/// Ok(MyRecord(1, 2.1, "3", "4", "5", "6"))
-/// ```
-///
-/// ```gleam
-/// > from(#("", "", "", "", "", ""))
-/// > |> decode6(
-/// > MyRecord,
-/// > element(0, int),
-/// > element(1, float),
-/// > element(2, string),
-/// > element(3, string),
-/// > element(4, string),
-/// > element(5, string),
-/// > )
-/// Error([
-/// DecodeError(expected: "Int", found: "String", path: ["0"]),
-/// DecodeError(expected: "Float", found: "String", path: ["1"]),
-/// ])
-/// ```
-///
-pub fn decode6(
- constructor: fn(t1, t2, t3, t4, t5, t6) -> t,
- t1: Decoder(t1),
- t2: Decoder(t2),
- t3: Decoder(t3),
- t4: Decoder(t4),
- t5: Decoder(t5),
- t6: Decoder(t6),
-) -> Decoder(t) {
- fn(x: Dynamic) {
- case t1(x), t2(x), t3(x), t4(x), t5(x), t6(x) {
- Ok(a), Ok(b), Ok(c), Ok(d), Ok(e), Ok(f) ->
- Ok(constructor(a, b, c, d, e, f))
- a, b, c, d, e, f ->
- Error(list.concat([
- all_errors(a),
- all_errors(b),
- all_errors(c),
- all_errors(d),
- all_errors(e),
- all_errors(f),
- ]))
- }
- }
-}
-
-/// Decode 7 values from a `Dynamic` value.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > from(#(1, 2.1, "3", "4", "5", "6"))
-/// > |> decode7(
-/// > MyRecord,
-/// > element(0, int),
-/// > element(1, float),
-/// > element(2, string),
-/// > element(3, string),
-/// > element(4, string),
-/// > element(5, string),
-/// > element(6, string),
-/// > )
-/// Ok(MyRecord(1, 2.1, "3", "4", "5", "6", "7"))
-/// ```
-///
-/// ```gleam
-/// > from(#("", "", "", "", "", "", ""))
-/// > |> decode7(
-/// > MyRecord,
-/// > element(0, int),
-/// > element(1, float),
-/// > element(2, string),
-/// > element(3, string),
-/// > element(4, string),
-/// > element(5, string),
-/// > element(6, string),
-/// > )
-/// Error([
-/// DecodeError(expected: "Int", found: "String", path: ["0"]),
-/// DecodeError(expected: "Float", found: "String", path: ["1"]),
-/// ])
-/// ```
-///
-pub fn decode7(
- constructor: fn(t1, t2, t3, t4, t5, t6, t7) -> t,
- t1: Decoder(t1),
- t2: Decoder(t2),
- t3: Decoder(t3),
- t4: Decoder(t4),
- t5: Decoder(t5),
- t6: Decoder(t6),
- t7: Decoder(t7),
-) -> Decoder(t) {
- fn(x: Dynamic) {
- case t1(x), t2(x), t3(x), t4(x), t5(x), t6(x), t7(x) {
- Ok(a), Ok(b), Ok(c), Ok(d), Ok(e), Ok(f), Ok(g) ->
- Ok(constructor(a, b, c, d, e, f, g))
- a, b, c, d, e, f, g ->
- Error(list.concat([
- all_errors(a),
- all_errors(b),
- all_errors(c),
- all_errors(d),
- all_errors(e),
- all_errors(f),
- all_errors(g),
- ]))
- }
- }
-}
-
-/// Decode 8 values from a `Dynamic` value.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > from(#(1, 2.1, "3", "4", "5", "6", "7", "8"))
-/// > |> decode8(
-/// > MyRecord,
-/// > element(0, int),
-/// > element(1, float),
-/// > element(2, string),
-/// > element(3, string),
-/// > element(4, string),
-/// > element(5, string),
-/// > element(6, string),
-/// > element(7, string),
-/// > )
-/// Ok(MyRecord(1, 2.1, "3", "4", "5", "6", "7", "8"))
-/// ```
-///
-/// ```gleam
-/// > from(#("", "", "", "", "", "", "", ""))
-/// > |> decode8(
-/// > MyRecord,
-/// > element(0, int),
-/// > element(1, float),
-/// > element(2, string),
-/// > element(3, string),
-/// > element(4, string),
-/// > element(5, string),
-/// > element(6, string),
-/// > element(7, string),
-/// > )
-/// Error([
-/// DecodeError(expected: "Int", found: "String", path: ["0"]),
-/// DecodeError(expected: "Float", found: "String", path: ["1"]),
-/// ])
-/// ```
-///
-pub fn decode8(
- constructor: fn(t1, t2, t3, t4, t5, t6, t7, t8) -> t,
- t1: Decoder(t1),
- t2: Decoder(t2),
- t3: Decoder(t3),
- t4: Decoder(t4),
- t5: Decoder(t5),
- t6: Decoder(t6),
- t7: Decoder(t7),
- t8: Decoder(t8),
-) -> Decoder(t) {
- fn(x: Dynamic) {
- case t1(x), t2(x), t3(x), t4(x), t5(x), t6(x), t7(x), t8(x) {
- Ok(a), Ok(b), Ok(c), Ok(d), Ok(e), Ok(f), Ok(g), Ok(h) ->
- Ok(constructor(a, b, c, d, e, f, g, h))
- a, b, c, d, e, f, g, h ->
- Error(list.concat([
- all_errors(a),
- all_errors(b),
- all_errors(c),
- all_errors(d),
- all_errors(e),
- all_errors(f),
- all_errors(g),
- all_errors(h),
- ]))
- }
- }
-}
-
-/// Decode 9 values from a `Dynamic` value.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > from(#(1, 2.1, "3", "4", "5", "6", "7", "8", "9"))
-/// > |> decode9(
-/// > MyRecord,
-/// > element(0, int),
-/// > element(1, float),
-/// > element(2, string),
-/// > element(3, string),
-/// > element(4, string),
-/// > element(5, string),
-/// > element(6, string),
-/// > element(7, string),
-/// > element(8, string),
-/// > )
-/// Ok(MyRecord(1, 2.1, "3", "4", "5", "6", "7", "8", "9"))
-/// ```
-///
-/// ```gleam
-/// > from(#("", "", "", "", "", "", "", "", ""))
-/// > |> decode9(
-/// > MyRecord,
-/// > element(0, int),
-/// > element(1, float),
-/// > element(2, string),
-/// > element(3, string),
-/// > element(4, string),
-/// > element(5, string),
-/// > element(6, string),
-/// > element(7, string),
-/// > element(8, string),
-/// > )
-/// Error([
-/// DecodeError(expected: "Int", found: "String", path: ["0"]),
-/// DecodeError(expected: "Float", found: "String", path: ["1"]),
-/// ])
-/// ```
-///
-pub fn decode9(
- constructor: fn(t1, t2, t3, t4, t5, t6, t7, t8, t9) -> t,
- t1: Decoder(t1),
- t2: Decoder(t2),
- t3: Decoder(t3),
- t4: Decoder(t4),
- t5: Decoder(t5),
- t6: Decoder(t6),
- t7: Decoder(t7),
- t8: Decoder(t8),
- t9: Decoder(t9),
-) -> Decoder(t) {
- fn(x: Dynamic) {
- case t1(x), t2(x), t3(x), t4(x), t5(x), t6(x), t7(x), t8(x), t9(x) {
- Ok(a), Ok(b), Ok(c), Ok(d), Ok(e), Ok(f), Ok(g), Ok(h), Ok(i) ->
- Ok(constructor(a, b, c, d, e, f, g, h, i))
- a, b, c, d, e, f, g, h, i ->
- Error(list.concat([
- all_errors(a),
- all_errors(b),
- all_errors(c),
- all_errors(d),
- all_errors(e),
- all_errors(f),
- all_errors(g),
- all_errors(h),
- all_errors(i),
- ]))
- }
- }
-}
-
-fn all_errors(result: Result(a, List(DecodeError))) -> List(DecodeError) {
- case result {
- Ok(_) -> []
- Error(errors) -> errors
- }
-}
diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam/float.gleam b/aoc2023/build/packages/gleam_stdlib/src/gleam/float.gleam
deleted file mode 100644
index 5d62419..0000000
--- a/aoc2023/build/packages/gleam_stdlib/src/gleam/float.gleam
+++ /dev/null
@@ -1,546 +0,0 @@
-//// Functions for working with floats.
-////
-//// ## Division by zero
-////
-//// Gleam runs on the Erlang virtual machine, which does not follow the IEEE
-//// 754 standard for floating point arithmetic and does not have an `Infinity`
-//// value. In Erlang division by zero results in a crash, however Gleam does
-//// not have partial functions and operators in core so instead division by zero
-//// returns zero, a behaviour taken from Pony, Coq, and Lean.
-////
-//// This may seem unexpected at first, but it is no less mathematically valid
-//// than crashing or returning a special value. Division by zero is undefined
-//// in mathematics.
-
-import gleam/order.{type Order}
-
-/// Attempts to parse a string as a `Float`, returning `Error(Nil)` if it was
-/// not possible.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > parse("2.3")
-/// Ok(2.3)
-/// ```
-///
-/// ```gleam
-/// > parse("ABC")
-/// Error(Nil)
-/// ```
-///
-pub fn parse(string: String) -> Result(Float, Nil) {
- do_parse(string)
-}
-
-@external(erlang, "gleam_stdlib", "parse_float")
-@external(javascript, "../gleam_stdlib.mjs", "parse_float")
-fn do_parse(a: String) -> Result(Float, Nil)
-
-/// Returns the string representation of the provided `Float`.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > to_string(2.3)
-/// "2.3"
-/// ```
-///
-pub fn to_string(x: Float) -> String {
- do_to_string(x)
-}
-
-@external(erlang, "gleam_stdlib", "float_to_string")
-@external(javascript, "../gleam_stdlib.mjs", "float_to_string")
-fn do_to_string(a: Float) -> String
-
-/// Restricts a `Float` between a lower and upper bound.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > clamp(1.2, min: 1.4, max: 1.6)
-/// 1.4
-/// ```
-///
-pub fn clamp(x: Float, min min_bound: Float, max max_bound: Float) -> Float {
- x
- |> min(max_bound)
- |> max(min_bound)
-}
-
-/// Compares two `Float`s, returning an `Order`:
-/// `Lt` for lower than, `Eq` for equals, or `Gt` for greater than.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > compare(2.0, 2.3)
-/// Lt
-/// ```
-///
-/// To handle
-/// [Floating Point Imprecision](https://en.wikipedia.org/wiki/Floating-point_arithmetic#Accuracy_problems)
-/// you may use [`loosely_compare`](#loosely_compare) instead.
-///
-pub fn compare(a: Float, with b: Float) -> Order {
- case a == b {
- True -> order.Eq
- False ->
- case a <. b {
- True -> order.Lt
- False -> order.Gt
- }
- }
-}
-
-/// Compares two `Float`s within a tolerance, returning an `Order`:
-/// `Lt` for lower than, `Eq` for equals, or `Gt` for greater than.
-///
-/// This function allows Float comparison while handling
-/// [Floating Point Imprecision](https://en.wikipedia.org/wiki/Floating-point_arithmetic#Accuracy_problems).
-///
-/// Notice: For `Float`s the tolerance won't be exact:
-/// `5.3 - 5.0` is not exactly `0.3`.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > loosely_compare(5.0, with: 5.3, tolerating: 0.5)
-/// Eq
-/// ```
-///
-/// If you want to check only for equality you may use
-/// [`loosely_equals`](#loosely_equals) instead.
-///
-pub fn loosely_compare(
- a: Float,
- with b: Float,
- tolerating tolerance: Float,
-) -> Order {
- let difference = absolute_value(a -. b)
- case difference <=. tolerance {
- True -> order.Eq
- False -> compare(a, b)
- }
-}
-
-/// Checks for equality of two `Float`s within a tolerance,
-/// returning an `Bool`.
-///
-/// This function allows Float comparison while handling
-/// [Floating Point Imprecision](https://en.wikipedia.org/wiki/Floating-point_arithmetic#Accuracy_problems).
-///
-/// Notice: For `Float`s the tolerance won't be exact:
-/// `5.3 - 5.0` is not exactly `0.3`.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > loosely_equals(5.0, with: 5.3, tolerating: 0.5)
-/// True
-/// ```
-///
-/// ```gleam
-/// > loosely_equals(5.0, with: 5.1, tolerating: 0.1)
-/// False
-/// ```
-///
-pub fn loosely_equals(
- a: Float,
- with b: Float,
- tolerating tolerance: Float,
-) -> Bool {
- let difference = absolute_value(a -. b)
- difference <=. tolerance
-}
-
-/// Compares two `Float`s, returning the smaller of the two.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > min(2.0, 2.3)
-/// 2.0
-/// ```
-///
-pub fn min(a: Float, b: Float) -> Float {
- case a <. b {
- True -> a
- False -> b
- }
-}
-
-/// Compares two `Float`s, returning the larger of the two.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > max(2.0, 2.3)
-/// 2.3
-/// ```
-///
-pub fn max(a: Float, b: Float) -> Float {
- case a >. b {
- True -> a
- False -> b
- }
-}
-
-/// Rounds the value to the next highest whole number as a `Float`.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > ceiling(2.3)
-/// 3.0
-/// ```
-///
-pub fn ceiling(x: Float) -> Float {
- do_ceiling(x)
-}
-
-@external(erlang, "math", "ceil")
-@external(javascript, "../gleam_stdlib.mjs", "ceiling")
-fn do_ceiling(a: Float) -> Float
-
-/// Rounds the value to the next lowest whole number as a `Float`.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > floor(2.3)
-/// 2.0
-/// ```
-///
-pub fn floor(x: Float) -> Float {
- do_floor(x)
-}
-
-@external(erlang, "math", "floor")
-@external(javascript, "../gleam_stdlib.mjs", "floor")
-fn do_floor(a: Float) -> Float
-
-/// Rounds the value to the nearest whole number as an `Int`.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > round(2.3)
-/// 2
-/// ```
-///
-/// ```gleam
-/// > round(2.5)
-/// 3
-/// ```
-///
-pub fn round(x: Float) -> Int {
- do_round(x)
-}
-
-@target(erlang)
-@external(erlang, "erlang", "round")
-fn do_round(a: Float) -> Int
-
-@target(javascript)
-fn do_round(x: Float) -> Int {
- case x >=. 0.0 {
- True -> js_round(x)
- _ -> 0 - js_round(negate(x))
- }
-}
-
-@target(javascript)
-@external(javascript, "../gleam_stdlib.mjs", "round")
-fn js_round(a: Float) -> Int
-
-/// Returns the value as an `Int`, truncating all decimal digits.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > truncate(2.4343434847383438)
-/// 2
-/// ```
-///
-pub fn truncate(x: Float) -> Int {
- do_truncate(x)
-}
-
-@external(erlang, "erlang", "trunc")
-@external(javascript, "../gleam_stdlib.mjs", "truncate")
-fn do_truncate(a: Float) -> Int
-
-/// Returns the absolute value of the input as a `Float`.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > absolute_value(-12.5)
-/// 12.5
-/// ```
-///
-/// ```gleam
-/// > absolute_value(10.2)
-/// 10.2
-/// ```
-///
-pub fn absolute_value(x: Float) -> Float {
- case x >=. 0.0 {
- True -> x
- _ -> 0.0 -. x
- }
-}
-
-/// Returns the results of the base being raised to the power of the
-/// exponent, as a `Float`.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > power(2.0, -1.0)
-/// Ok(0.5)
-/// ```
-///
-/// ```gleam
-/// > power(2.0, 2.0)
-/// Ok(4.0)
-/// ```
-///
-/// ```gleam
-/// > power(8.0, 1.5)
-/// Ok(22.627416997969522)
-/// ```
-///
-/// ```gleam
-/// > 4.0 |> power(of: 2.0)
-/// Ok(16.0)
-/// ```
-///
-/// ```gleam
-/// > power(-1.0, 0.5)
-/// Error(Nil)
-/// ```
-///
-pub fn power(base: Float, of exponent: Float) -> Result(Float, Nil) {
- let fractional: Bool = ceiling(exponent) -. exponent >. 0.0
- // In the following check:
- // 1. If the base is negative and the exponent is fractional then
- // return an error as it will otherwise be an imaginary number
- // 2. If the base is 0 and the exponent is negative then the expression
- // is equivalent to the exponent divided by 0 and an error should be
- // returned
- case base <. 0.0 && fractional || base == 0.0 && exponent <. 0.0 {
- True -> Error(Nil)
- False -> Ok(do_power(base, exponent))
- }
-}
-
-@external(erlang, "math", "pow")
-@external(javascript, "../gleam_stdlib.mjs", "power")
-fn do_power(a: Float, b: Float) -> Float
-
-/// Returns the square root of the input as a `Float`.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > square_root(4.0)
-/// Ok(2.0)
-/// ```
-///
-/// ```gleam
-/// > square_root(-16.0)
-/// Error(Nil)
-/// ```
-///
-pub fn square_root(x: Float) -> Result(Float, Nil) {
- power(x, 0.5)
-}
-
-/// Returns the negative of the value provided.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > negate(1.0)
-/// -1.0
-/// ```
-///
-pub fn negate(x: Float) -> Float {
- -1.0 *. x
-}
-
-/// Sums a list of `Float`s.
-///
-/// ## Example
-///
-/// ```gleam
-/// > sum([1.0, 2.2, 3.3])
-/// 6.5
-/// ```
-///
-pub fn sum(numbers: List(Float)) -> Float {
- numbers
- |> do_sum(0.0)
-}
-
-fn do_sum(numbers: List(Float), initial: Float) -> Float {
- case numbers {
- [] -> initial
- [x, ..rest] -> do_sum(rest, x +. initial)
- }
-}
-
-/// Multiplies a list of `Float`s and returns the product.
-///
-/// ## Example
-///
-/// ```gleam
-/// > product([2.5, 3.2, 4.2])
-/// 33.6
-/// ```
-///
-pub fn product(numbers: List(Float)) -> Float {
- case numbers {
- [] -> 1.0
- _ -> do_product(numbers, 1.0)
- }
-}
-
-fn do_product(numbers: List(Float), initial: Float) -> Float {
- case numbers {
- [] -> initial
- [x, ..rest] -> do_product(rest, x *. initial)
- }
-}
-
-/// Generates a random float between the given minimum and maximum values.
-///
-///
-/// ## Examples
-///
-/// ```gleam
-/// > random(1.0, 5.0)
-/// 2.646355926896028
-/// ```
-///
-pub fn random(min: Float, max: Float) -> Float {
- do_random_uniform() *. { max -. min } +. min
-}
-
-/// Returns a random float uniformly distributed in the value range
-/// 0.0 =< X < 1.0 and updates the state in the process dictionary.
-/// See: <https://www.erlang.org/doc/man/rand.html#uniform-0>
-///
-@external(erlang, "rand", "uniform")
-@external(javascript, "../gleam_stdlib.mjs", "random_uniform")
-fn do_random_uniform() -> Float
-
-/// Returns division of the inputs as a `Result`.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > divide(0.0, 1.0)
-/// Ok(1.0)
-/// ```
-///
-/// ```gleam
-/// > divide(1.0, 0.0)
-/// Error(Nil)
-/// ```
-///
-pub fn divide(a: Float, by b: Float) -> Result(Float, Nil) {
- case b {
- 0.0 -> Error(Nil)
- b -> Ok(a /. b)
- }
-}
-
-/// Adds two floats together.
-///
-/// It's the function equivalent of the `+.` operator.
-/// This function is useful in higher order functions or pipes.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > add(1.0, 2.0)
-/// 3.0
-/// ```
-///
-/// ```gleam
-/// > import gleam/list
-/// > list.fold([1.0, 2.0, 3.0], 0.0, add)
-/// 6.0
-/// ```
-///
-/// ```gleam
-/// > 3.0 |> add(2.0)
-/// 5.0
-/// ```
-///
-pub fn add(a: Float, b: Float) -> Float {
- a +. b
-}
-
-/// Multiplies two floats together.
-///
-/// It's the function equivalent of the `*.` operator.
-/// This function is useful in higher order functions or pipes.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > multiply(2.0, 4.0)
-/// 8.0
-/// ```
-///
-/// ```gleam
-/// import gleam/list
-/// > list.fold([2.0, 3.0, 4.0], 1.0, multiply)
-/// 24.0
-/// ```
-///
-/// ```gleam
-/// > 3.0 |> multiply(2.0)
-/// 6.0
-/// ```
-///
-pub fn multiply(a: Float, b: Float) -> Float {
- a *. b
-}
-
-/// Subtracts one float from another.
-///
-/// It's the function equivalent of the `-.` operator.
-/// This function is useful in higher order functions or pipes.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > subtract(3.0, 1.0)
-/// 2.0
-/// ```
-///
-/// ```gleam
-/// > import gleam/list
-/// > list.fold([1.0, 2.0, 3.0], 10.0, subtract)
-/// 4.0
-/// ```
-///
-/// ```gleam
-/// > 3.0 |> subtract(_, 2.0)
-/// 1.0
-/// ```
-///
-/// ```gleam
-/// > 3.0 |> subtract(2.0, _)
-/// -1.0
-/// ```
-///
-pub fn subtract(a: Float, b: Float) -> Float {
- a -. b
-}
diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam/function.gleam b/aoc2023/build/packages/gleam_stdlib/src/gleam/function.gleam
deleted file mode 100644
index daa997d..0000000
--- a/aoc2023/build/packages/gleam_stdlib/src/gleam/function.gleam
+++ /dev/null
@@ -1,162 +0,0 @@
-/// Takes two functions and chains them together to form one function that
-/// takes the input from the first and returns the output of the second.
-///
-pub fn compose(fun1: fn(a) -> b, fun2: fn(b) -> c) -> fn(a) -> c {
- fn(a) { fun2(fun1(a)) }
-}
-
-/// Takes a function with `2` arguments (an arity of `2`), and returns the
-/// curried equivalent.
-///
-/// `fn(a, b) -> c` becomes `fn(a) -> fn(b) -> c`.
-///
-/// ## Examples
-///
-/// *Currying* creates a new function that is identical to the given function
-/// except that arguments must now be supplied one by one over several function
-/// calls. It thus is the process of taking a function with `n` arguments
-/// and producing a sequence of `n` single-argument functions. Given:
-///
-/// ```gleam
-/// > fn my_fun(i: Int, s: String) -> String { ... }
-/// ```
-///
-/// …calling `curry2(my_fun)` would return the curried equivalent, like so:
-///
-/// ```gleam
-/// > curry2(my_fun)
-/// fn(Int) -> fn(String) -> String
-/// ```
-///
-/// Currying is useful when you want to partially apply a function with
-/// some arguments and then pass it somewhere else, for example:
-///
-/// ```gleam
-/// > import gleam/list
-/// > let multiply = curry2(fn(x, y) { x * y })
-/// > let doubles = list.map([1, 2, 3], multiply(2))
-/// [2, 4, 6]
-/// ```
-///
-pub fn curry2(fun: fn(a, b) -> value) {
- fn(a) { fn(b) { fun(a, b) } }
-}
-
-/// Takes a function with `3` arguments (an arity of `3`), and returns the
-/// curried equivalent.
-///
-/// `fn(a, b, c) -> d` becomes `fn(a) -> fn(b) -> fn(c) -> d`.
-///
-/// See [`curry2`](#curry2) for a detailed explanation.
-///
-pub fn curry3(fun: fn(a, b, c) -> value) {
- fn(a) { fn(b) { fn(c) { fun(a, b, c) } } }
-}
-
-/// Takes a function with `4` arguments (an arity of `4`), and returns the
-/// curried equivalent.
-///
-/// `fn(a, b, c, d) -> e` becomes `fn(a) -> fn(b) -> fn(c) -> fn(d) -> e`.
-///
-/// See [`curry2`](#curry2) for a detailed explanation.
-///
-pub fn curry4(fun: fn(a, b, c, d) -> value) {
- fn(a) { fn(b) { fn(c) { fn(d) { fun(a, b, c, d) } } } }
-}
-
-/// Takes a function with `5` arguments (an arity of `5`), and returns the
-/// curried equivalent.
-///
-/// `fn(a, b, c, d, e) -> f` becomes
-/// `fn(a) -> fn(b) -> fn(c) -> fn(d) -> fn(e) -> f`.
-///
-/// See [`curry2`](#curry2) for a detailed explanation.
-///
-pub fn curry5(fun: fn(a, b, c, d, e) -> value) {
- fn(a) { fn(b) { fn(c) { fn(d) { fn(e) { fun(a, b, c, d, e) } } } } }
-}
-
-/// Takes a function with `6` arguments (an arity of `6`), and returns the
-/// curried equivalent.
-///
-/// `fn(a, b, c, d, e, f) -> g` becomes
-/// `fn(a) -> fn(b) -> fn(c) -> fn(d) -> fn(e) -> fn(f) -> g`.
-///
-/// See [`curry2`](#curry2) for a detailed explanation.
-///
-pub fn curry6(fun: fn(a, b, c, d, e, f) -> value) {
- fn(a) {
- fn(b) { fn(c) { fn(d) { fn(e) { fn(f) { fun(a, b, c, d, e, f) } } } } }
- }
-}
-
-/// Takes a function that takes two arguments and returns a new function that
-/// takes the same two arguments, but in reverse order.
-///
-pub fn flip(fun: fn(a, b) -> c) -> fn(b, a) -> c {
- fn(b, a) { fun(a, b) }
-}
-
-/// Takes a single argument and always returns its input value.
-///
-pub fn identity(x: a) -> a {
- x
-}
-
-/// Takes a single argument and returns a new function that
-/// ignores its argument and always returns the input value.
-///
-pub fn constant(value: a) -> fn(b) -> a {
- fn(_) { value }
-}
-
-/// Takes an argument and a single function,
-/// calls that function with that argument
-/// and returns that argument instead of the function return value.
-/// Useful for running synchronous side effects in a pipeline.
-///
-pub fn tap(arg: a, effect: fn(a) -> b) -> a {
- effect(arg)
- arg
-}
-
-/// Takes a function with arity one and an argument,
-/// calls that function with the argument and returns the function return value.
-///
-/// Useful for concisely calling functions returned as a part of a pipeline.
-///
-/// ## Example
-///
-/// ```gleam
-/// > let doubler = fn() {
-/// > fn(x: Int) { x * 2 }
-/// > }
-/// >
-/// > doubler()
-/// > |> apply1(2)
-/// 4
-/// ```
-///
-pub fn apply1(fun: fn(a) -> value, arg1: a) -> value {
- fun(arg1)
-}
-
-/// Takes a function with arity two and two arguments,
-/// calls that function with the arguments
-/// and returns the function return value.
-///
-/// See [`apply1`](#apply1) for more details.
-///
-pub fn apply2(fun: fn(a, b) -> value, arg1: a, arg2: b) -> value {
- fun(arg1, arg2)
-}
-
-/// Takes a function with arity three and three arguments,
-/// calls that function with the arguments
-/// and returns the function return value.
-///
-/// See [`apply1`](#apply1) for more details.
-///
-pub fn apply3(fun: fn(a, b, c) -> value, arg1: a, arg2: b, arg3: c) -> value {
- fun(arg1, arg2, arg3)
-}
diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam/int.gleam b/aoc2023/build/packages/gleam_stdlib/src/gleam/int.gleam
deleted file mode 100644
index d93c16a..0000000
--- a/aoc2023/build/packages/gleam_stdlib/src/gleam/int.gleam
+++ /dev/null
@@ -1,874 +0,0 @@
-//// Functions for working with integers.
-////
-//// ## Division by zero
-////
-//// In Erlang division by zero results in a crash, however Gleam does not have
-//// partial functions and operators in core so instead division by zero returns
-//// zero, a behaviour taken from Pony, Coq, and Lean.
-////
-//// This may seem unexpected at first, but it is no less mathematically valid
-//// than crashing or returning a special value. Division by zero is undefined
-//// in mathematics.
-
-import gleam/float
-import gleam/order.{type Order}
-
-/// Returns the absolute value of the input.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > absolute_value(-12)
-/// 12
-/// ```
-///
-/// ```gleam
-/// > absolute_value(10)
-/// 10
-/// ```
-///
-pub fn absolute_value(x: Int) -> Int {
- case x >= 0 {
- True -> x
- False -> x * -1
- }
-}
-
-/// Returns the results of the base being raised to the power of the
-/// exponent, as a `Float`.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > power(2, -1.0)
-/// Ok(0.5)
-/// ```
-///
-/// ```gleam
-/// > power(2, 2.0)
-/// Ok(4.0)
-/// ```
-///
-/// ```gleam
-/// > power(8, 1.5)
-/// Ok(22.627416997969522)
-/// ```
-///
-/// ```gleam
-/// > 4 |> power(of: 2.0)
-/// Ok(16.0)
-/// ```
-///
-/// ```gleam
-/// > power(-1, 0.5)
-/// Error(Nil)
-/// ```
-///
-pub fn power(base: Int, of exponent: Float) -> Result(Float, Nil) {
- base
- |> to_float()
- |> float.power(exponent)
-}
-
-/// Returns the square root of the input as a `Float`.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > square_root(4)
-/// Ok(2.0)
-/// ```
-///
-/// ```gleam
-/// > square_root(-16)
-/// Error(Nil)
-/// ```
-///
-pub fn square_root(x: Int) -> Result(Float, Nil) {
- x
- |> to_float()
- |> float.square_root()
-}
-
-/// Parses a given string as an int if possible.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > parse("2")
-/// Ok(2)
-/// ```
-///
-/// ```gleam
-/// > parse("ABC")
-/// Error(Nil)
-/// ```
-///
-pub fn parse(string: String) -> Result(Int, Nil) {
- do_parse(string)
-}
-
-@external(erlang, "gleam_stdlib", "parse_int")
-@external(javascript, "../gleam_stdlib.mjs", "parse_int")
-fn do_parse(a: String) -> Result(Int, Nil)
-
-/// Parses a given string as an int in a given base if possible.
-/// Supports only bases 2 to 36, for values outside of which this function returns an `Error(Nil)`.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > base_parse("10", 2)
-/// Ok(2)
-///
-/// > base_parse("30", 16)
-/// Ok(48)
-///
-/// > base_parse("1C", 36)
-/// Ok(48)
-///
-/// > base_parse("48", 1)
-/// Error(Nil)
-///
-/// > base_parse("48", 37)
-/// Error(Nil)
-/// ```
-///
-pub fn base_parse(string: String, base: Int) -> Result(Int, Nil) {
- case base >= 2 && base <= 36 {
- True -> do_base_parse(string, base)
- False -> Error(Nil)
- }
-}
-
-@external(erlang, "gleam_stdlib", "int_from_base_string")
-@external(javascript, "../gleam_stdlib.mjs", "int_from_base_string")
-fn do_base_parse(a: String, b: Int) -> Result(Int, Nil)
-
-/// Prints a given int to a string.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > to_string(2)
-/// "2"
-/// ```
-///
-pub fn to_string(x: Int) {
- do_to_string(x)
-}
-
-@external(erlang, "erlang", "integer_to_binary")
-@external(javascript, "../gleam_stdlib.mjs", "to_string")
-fn do_to_string(a: Int) -> String
-
-/// Error value when trying to operate with a base out of the allowed range.
-///
-pub type InvalidBase {
- InvalidBase
-}
-
-/// Prints a given int to a string using the base number provided.
-/// Supports only bases 2 to 36, for values outside of which this function returns an `Error(InvalidBase)`.
-/// For common bases (2, 8, 16, 36), use the `to_baseN` functions.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > to_base_string(2, 2)
-/// Ok("10")
-/// ```
-///
-/// ```gleam
-/// > to_base_string(48, 16)
-/// Ok("30")
-/// ```
-///
-/// ```gleam
-/// > to_base_string(48, 36)
-/// Ok("1C")
-/// ```
-///
-/// ```gleam
-/// > to_base_string(48, 1)
-/// Error(InvalidBase)
-/// ```
-///
-/// ```gleam
-/// > to_base_string(48, 37)
-/// Error(InvalidBase)
-/// ```
-///
-pub fn to_base_string(x: Int, base: Int) -> Result(String, InvalidBase) {
- case base >= 2 && base <= 36 {
- True -> Ok(do_to_base_string(x, base))
- False -> Error(InvalidBase)
- }
-}
-
-@external(erlang, "erlang", "integer_to_binary")
-@external(javascript, "../gleam_stdlib.mjs", "int_to_base_string")
-fn do_to_base_string(a: Int, b: Int) -> String
-
-/// Prints a given int to a string using base-2.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > to_base2(2)
-/// "10"
-/// ```
-///
-pub fn to_base2(x: Int) -> String {
- do_to_base_string(x, 2)
-}
-
-/// Prints a given int to a string using base-8.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > to_base8(15)
-/// "17"
-/// ```
-///
-pub fn to_base8(x: Int) -> String {
- do_to_base_string(x, 8)
-}
-
-/// Prints a given int to a string using base-16.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > to_base16(48)
-/// "30"
-/// ```
-///
-pub fn to_base16(x: Int) -> String {
- do_to_base_string(x, 16)
-}
-
-/// Prints a given int to a string using base-36.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > to_base36(48)
-/// "1C"
-/// ```
-///
-pub fn to_base36(x: Int) -> String {
- do_to_base_string(x, 36)
-}
-
-/// Takes an int and returns its value as a float.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > to_float(5)
-/// 5.0
-/// ```
-///
-/// ```gleam
-/// > to_float(0)
-/// 0.0
-/// ```
-///
-/// ```gleam
-/// > to_float(-3)
-/// -3.0
-/// ```
-///
-pub fn to_float(x: Int) -> Float {
- do_to_float(x)
-}
-
-@external(erlang, "erlang", "float")
-@external(javascript, "../gleam_stdlib.mjs", "identity")
-fn do_to_float(a: Int) -> Float
-
-/// Restricts an int between a lower and upper bound.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > clamp(40, min: 50, max: 60)
-/// 50
-/// ```
-///
-pub fn clamp(x: Int, min min_bound: Int, max max_bound: Int) -> Int {
- x
- |> min(max_bound)
- |> max(min_bound)
-}
-
-/// Compares two ints, returning an order.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > compare(2, 3)
-/// Lt
-/// ```
-///
-/// ```gleam
-/// > compare(4, 3)
-/// Gt
-/// ```
-///
-/// ```gleam
-/// > compare(3, 3)
-/// Eq
-/// ```
-///
-pub fn compare(a: Int, with b: Int) -> Order {
- case a == b {
- True -> order.Eq
- False ->
- case a < b {
- True -> order.Lt
- False -> order.Gt
- }
- }
-}
-
-/// Compares two ints, returning the smaller of the two.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > min(2, 3)
-/// 2
-/// ```
-///
-pub fn min(a: Int, b: Int) -> Int {
- case a < b {
- True -> a
- False -> b
- }
-}
-
-/// Compares two ints, returning the larger of the two.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > max(2, 3)
-/// 3
-/// ```
-///
-pub fn max(a: Int, b: Int) -> Int {
- case a > b {
- True -> a
- False -> b
- }
-}
-
-/// Returns whether the value provided is even.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > is_even(2)
-/// True
-/// ```
-///
-/// ```gleam
-/// > is_even(3)
-/// False
-/// ```
-///
-pub fn is_even(x: Int) -> Bool {
- x % 2 == 0
-}
-
-/// Returns whether the value provided is odd.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > is_odd(3)
-/// True
-/// ```
-///
-/// ```gleam
-/// > is_odd(2)
-/// False
-/// ```
-///
-pub fn is_odd(x: Int) -> Bool {
- x % 2 != 0
-}
-
-/// Returns the negative of the value provided.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > negate(1)
-/// -1
-/// ```
-///
-pub fn negate(x: Int) -> Int {
- -1 * x
-}
-
-/// Sums a list of ints.
-///
-/// ## Example
-///
-/// ```gleam
-/// > sum([1, 2, 3])
-/// 6
-/// ```
-///
-pub fn sum(numbers: List(Int)) -> Int {
- numbers
- |> do_sum(0)
-}
-
-fn do_sum(numbers: List(Int), initial: Int) -> Int {
- case numbers {
- [] -> initial
- [x, ..rest] -> do_sum(rest, x + initial)
- }
-}
-
-/// Multiplies a list of ints and returns the product.
-///
-/// ## Example
-///
-/// ```gleam
-/// > product([2, 3, 4])
-/// 24
-/// ```
-///
-pub fn product(numbers: List(Int)) -> Int {
- case numbers {
- [] -> 1
- _ -> do_product(numbers, 1)
- }
-}
-
-fn do_product(numbers: List(Int), initial: Int) -> Int {
- case numbers {
- [] -> initial
- [x, ..rest] -> do_product(rest, x * initial)
- }
-}
-
-/// Splits an integer into its digit representation in the specified base
-///
-/// ## Examples
-///
-/// ```gleam
-/// > digits(234, 10)
-/// Ok([2,3,4])
-/// ```
-///
-/// ```gleam
-/// > digits(234, 1)
-/// Error(InvalidBase)
-/// ```
-///
-pub fn digits(x: Int, base: Int) -> Result(List(Int), InvalidBase) {
- case base < 2 {
- True -> Error(InvalidBase)
- False -> Ok(do_digits(x, base, []))
- }
-}
-
-fn do_digits(x: Int, base: Int, acc: List(Int)) -> List(Int) {
- case absolute_value(x) < base {
- True -> [x, ..acc]
- False -> do_digits(x / base, base, [x % base, ..acc])
- }
-}
-
-/// Joins a list of digits into a single value.
-/// Returns an error if the base is less than 2 or if the list contains a digit greater than or equal to the specified base.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > undigits([2,3,4], 10)
-/// Ok(234)
-/// ```
-///
-/// ```gleam
-/// > undigits([2,3,4], 1)
-/// Error(InvalidBase)
-/// ```
-///
-/// ```gleam
-/// > undigits([2,3,4], 2)
-/// Error(InvalidBase)
-/// ```
-///
-pub fn undigits(numbers: List(Int), base: Int) -> Result(Int, InvalidBase) {
- case base < 2 {
- True -> Error(InvalidBase)
- False -> do_undigits(numbers, base, 0)
- }
-}
-
-fn do_undigits(
- numbers: List(Int),
- base: Int,
- acc: Int,
-) -> Result(Int, InvalidBase) {
- case numbers {
- [] -> Ok(acc)
- [digit, ..] if digit >= base -> Error(InvalidBase)
- [digit, ..rest] -> do_undigits(rest, base, acc * base + digit)
- }
-}
-
-/// Generates a random int between the given minimum and maximum values.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > random(1, 5)
-/// 2
-/// ```
-///
-pub fn random(min: Int, max: Int) -> Int {
- float.random(to_float(min), to_float(max))
- |> float.floor()
- |> float.round()
-}
-
-/// Performs a truncated integer division.
-///
-/// Returns division of the inputs as a `Result`: If the given divisor equals
-/// `0`, this function returns an `Error`.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > divide(0, 1)
-/// Ok(1)
-/// ```
-///
-/// ```gleam
-/// > divide(1, 0)
-/// Error(Nil)
-/// ```
-///
-/// ```gleam
-/// > divide(5, 2)
-/// Ok(2)
-/// ```
-///
-/// ```gleam
-/// > divide(-99, 2)
-/// Ok(-49)
-/// ```
-///
-pub fn divide(dividend: Int, by divisor: Int) -> Result(Int, Nil) {
- case divisor {
- 0 -> Error(Nil)
- divisor -> Ok(dividend / divisor)
- }
-}
-
-/// Computes the remainder of an integer division of inputs as a `Result`.
-///
-/// Returns division of the inputs as a `Result`: If the given divisor equals
-/// `0`, this function returns an `Error`.
-///
-/// Most the time you will want to use the `%` operator instead of this
-/// function.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > remainder(3, 2)
-/// Ok(1)
-/// ```
-///
-/// ```gleam
-/// > remainder(1, 0)
-/// Error(Nil)
-/// ```
-///
-/// ```gleam
-/// > remainder(10, -1)
-/// Ok(0)
-/// ```
-///
-/// ```gleam
-/// > remainder(13, by: 3)
-/// Ok(1)
-/// ```
-///
-/// ```gleam
-/// > remainder(-13, by: 3)
-/// Ok(-1)
-/// ```
-///
-/// ```gleam
-/// > remainder(13, by: -3)
-/// Ok(1)
-/// ```
-///
-/// ```gleam
-/// > remainder(-13, by: -3)
-/// Ok(-1)
-/// ```
-///
-pub fn remainder(dividend: Int, by divisor: Int) -> Result(Int, Nil) {
- case divisor {
- 0 -> Error(Nil)
- divisor -> Ok(dividend % divisor)
- }
-}
-
-/// Computes the modulo of an integer division of inputs as a `Result`.
-///
-/// Returns division of the inputs as a `Result`: If the given divisor equals
-/// `0`, this function returns an `Error`.
-///
-/// Most the time you will want to use the `%` operator instead of this
-/// function.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > modulo(3, 2)
-/// Ok(1)
-/// ```
-///
-/// ```gleam
-/// > modulo(1, 0)
-/// Error(Nil)
-/// ```
-///
-/// ```gleam
-/// > modulo(10, -1)
-/// Ok(0)
-/// ```
-///
-/// ```gleam
-/// > modulo(13, by: 3)
-/// Ok(1)
-/// ```
-///
-/// ```gleam
-/// > modulo(-13, by: 3)
-/// Ok(2)
-/// ```
-///
-/// ```gleam
-/// > modulo(13, by: -3)
-/// Ok(-2)
-/// ```
-///
-/// ```gleam
-/// > modulo(-13, by: -3)
-/// Ok(-1)
-/// ```
-///
-pub fn modulo(dividend: Int, by divisor: Int) -> Result(Int, Nil) {
- case divisor {
- 0 -> Error(Nil)
- _ -> {
- let remainder = dividend % divisor
- case remainder * divisor < 0 {
- True -> Ok(remainder + divisor)
- False -> Ok(remainder)
- }
- }
- }
-}
-
-/// Performs a *floored* integer division, which means that the result will
-/// always be rounded towards negative infinity.
-///
-/// If you want to perform truncated integer division (rounding towards zero),
-/// use `int.divide()` or the `/` operator instead.
-///
-/// Returns division of the inputs as a `Result`: If the given divisor equals
-/// `0`, this function returns an `Error`.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > floor_divide(1, 0)
-/// Error(Nil)
-/// ```
-///
-/// ```gleam
-/// > floor_divide(5, 2)
-/// Ok(2)
-/// ```
-///
-/// ```gleam
-/// > floor_divide(6, -4)
-/// Ok(-2)
-/// ```
-///
-/// ```gleam
-/// > floor_divide(-99, 2)
-/// Ok(-50)
-/// ```
-///
-pub fn floor_divide(dividend: Int, by divisor: Int) -> Result(Int, Nil) {
- case divisor {
- 0 -> Error(Nil)
- divisor ->
- case dividend * divisor < 0 && dividend % divisor != 0 {
- True -> Ok(dividend / divisor - 1)
- False -> Ok(dividend / divisor)
- }
- }
-}
-
-/// Adds two integers together.
-///
-/// It's the function equivalent of the `+` operator.
-/// This function is useful in higher order functions or pipes.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > add(1, 2)
-/// 3
-/// ```
-///
-/// ```gleam
-/// import gleam/list
-/// > list.fold([1, 2, 3], 0, add)
-/// 6
-/// ```
-///
-/// ```gleam
-/// > 3 |> add(2)
-/// 5
-/// ```
-///
-pub fn add(a: Int, b: Int) -> Int {
- a + b
-}
-
-/// Multiplies two integers together.
-///
-/// It's the function equivalent of the `*` operator.
-/// This function is useful in higher order functions or pipes.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > multiply(2, 4)
-/// 8
-/// ```
-///
-/// ```gleam
-/// import gleam/list
-/// > list.fold([2, 3, 4], 1, multiply)
-/// 24
-/// ```
-///
-/// ```gleam
-/// > 3 |> multiply(2)
-/// 6
-/// ```
-///
-pub fn multiply(a: Int, b: Int) -> Int {
- a * b
-}
-
-/// Subtracts one int from another.
-///
-/// It's the function equivalent of the `-` operator.
-/// This function is useful in higher order functions or pipes.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > subtract(3, 1)
-/// 2.0
-/// ```
-///
-/// ```gleam
-/// import gleam/list
-/// > list.fold([1, 2, 3], 10, subtract)
-/// 4
-/// ```
-///
-/// ```gleam
-/// > 3 |> subtract(2)
-/// 1
-/// ```
-///
-/// ```gleam
-/// > 3 |> subtract(2, _)
-/// -1
-/// ```
-///
-pub fn subtract(a: Int, b: Int) -> Int {
- a - b
-}
-
-/// Calculates the bitwise AND of its arguments.
-///
-/// The exact behaviour of this function depends on the target platform.
-/// On Erlang it is equivalent to bitwise operations on ints, on JavaScript it
-/// is equivalent to bitwise operations on big-ints.
-///
-@external(erlang, "erlang", "band")
-@external(javascript, "../gleam_stdlib.mjs", "bitwise_and")
-pub fn bitwise_and(x: Int, y: Int) -> Int
-
-/// Calculates the bitwise NOT of its argument.
-///
-/// The exact behaviour of this function depends on the target platform.
-/// On Erlang it is equivalent to bitwise operations on ints, on JavaScript it
-/// is equivalent to bitwise operations on big-ints.
-///
-@external(erlang, "erlang", "bnot")
-@external(javascript, "../gleam_stdlib.mjs", "bitwise_not")
-pub fn bitwise_not(x: Int) -> Int
-
-/// Calculates the bitwise OR of its arguments.
-///
-/// The exact behaviour of this function depends on the target platform.
-/// On Erlang it is equivalent to bitwise operations on ints, on JavaScript it
-/// is equivalent to bitwise operations on big-ints.
-///
-@external(erlang, "erlang", "bor")
-@external(javascript, "../gleam_stdlib.mjs", "bitwise_or")
-pub fn bitwise_or(x: Int, y: Int) -> Int
-
-/// Calculates the bitwise XOR of its arguments.
-///
-/// The exact behaviour of this function depends on the target platform.
-/// On Erlang it is equivalent to bitwise operations on ints, on JavaScript it
-/// is equivalent to bitwise operations on big-ints.
-///
-@external(erlang, "erlang", "bxor")
-@external(javascript, "../gleam_stdlib.mjs", "bitwise_exclusive_or")
-pub fn bitwise_exclusive_or(x: Int, y: Int) -> Int
-
-/// Calculates the result of an arithmetic left bitshift.
-///
-/// The exact behaviour of this function depends on the target platform.
-/// On Erlang it is equivalent to bitwise operations on ints, on JavaScript it
-/// is equivalent to bitwise operations on big-ints.
-///
-@external(erlang, "erlang", "bsl")
-@external(javascript, "../gleam_stdlib.mjs", "bitwise_shift_left")
-pub fn bitwise_shift_left(x: Int, y: Int) -> Int
-
-/// Calculates the result of an arithmetic right bitshift.
-///
-/// The exact behaviour of this function depends on the target platform.
-/// On Erlang it is equivalent to bitwise operations on ints, on JavaScript it
-/// is equivalent to bitwise operations on big-ints.
-///
-@external(erlang, "erlang", "bsr")
-@external(javascript, "../gleam_stdlib.mjs", "bitwise_shift_right")
-pub fn bitwise_shift_right(x: Int, y: Int) -> Int
diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam/io.gleam b/aoc2023/build/packages/gleam_stdlib/src/gleam/io.gleam
deleted file mode 100644
index 0c0a3ee..0000000
--- a/aoc2023/build/packages/gleam_stdlib/src/gleam/io.gleam
+++ /dev/null
@@ -1,117 +0,0 @@
-import gleam/string
-
-/// Writes a string to standard output.
-///
-/// If you want your output to be printed on its own line see `println`.
-///
-/// ## Example
-///
-/// ```gleam
-/// > io.print("Hi mum")
-/// // -> Hi mum
-/// Nil
-/// ```
-///
-pub fn print(string: String) -> Nil {
- do_print(string)
-}
-
-@external(erlang, "gleam_stdlib", "print")
-@external(javascript, "../gleam_stdlib.mjs", "print")
-fn do_print(string string: String) -> Nil
-
-/// Writes a string to standard error.
-///
-/// If you want your output to be printed on its own line see `println_error`.
-///
-/// ## Example
-///
-/// ```
-/// > io.print_error("Hi pop")
-/// // -> Hi pop
-/// Nil
-/// ```
-///
-pub fn print_error(string: String) -> Nil {
- do_print_error(string)
-}
-
-@external(erlang, "gleam_stdlib", "print_error")
-@external(javascript, "../gleam_stdlib.mjs", "print_error")
-fn do_print_error(string string: String) -> Nil
-
-/// Writes a string to standard output, appending a newline to the end.
-///
-/// ## Example
-///
-/// ```gleam
-/// > io.println("Hi mum")
-/// // -> Hi mum
-/// Nil
-/// ```
-///
-pub fn println(string: String) -> Nil {
- do_println(string)
-}
-
-@external(erlang, "gleam_stdlib", "println")
-@external(javascript, "../gleam_stdlib.mjs", "console_log")
-fn do_println(string string: String) -> Nil
-
-/// Writes a string to standard error, appending a newline to the end.
-///
-/// ## Example
-///
-/// ```gleam
-/// > io.println_error("Hi pop")
-/// // -> Hi mum
-/// Nil
-/// ```
-///
-pub fn println_error(string: String) -> Nil {
- do_println_error(string)
-}
-
-@external(erlang, "gleam_stdlib", "println_error")
-@external(javascript, "../gleam_stdlib.mjs", "console_error")
-fn do_println_error(string string: String) -> Nil
-
-/// Prints a value to standard error (stderr) yielding Gleam syntax.
-///
-/// The value is returned after being printed so it can be used in pipelines.
-///
-/// ## Example
-///
-/// ```gleam
-/// > debug("Hi mum")
-/// // -> <<"Hi mum">>
-/// "Hi mum"
-/// ```
-///
-/// ```gleam
-/// > debug(Ok(1))
-/// // -> {ok, 1}
-/// Ok(1)
-/// ```
-///
-/// ```gleam
-/// > import list
-/// > [1, 2]
-/// > |> list.map(fn(x) { x + 1 })
-/// > |> debug
-/// > |> list.map(fn(x) { x * 2 })
-/// // -> [2, 3]
-/// [4, 6]
-/// ```
-///
-pub fn debug(term: anything) -> anything {
- term
- |> string.inspect
- |> do_debug_println
-
- term
-}
-
-@external(erlang, "gleam_stdlib", "println_error")
-@external(javascript, "../gleam_stdlib.mjs", "print_debug")
-fn do_debug_println(string string: String) -> Nil
diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam/iterator.gleam b/aoc2023/build/packages/gleam_stdlib/src/gleam/iterator.gleam
deleted file mode 100644
index c57e7fd..0000000
--- a/aoc2023/build/packages/gleam_stdlib/src/gleam/iterator.gleam
+++ /dev/null
@@ -1,1530 +0,0 @@
-import gleam/result
-import gleam/int
-import gleam/list
-import gleam/dict.{type Dict}
-import gleam/option.{type Option, None, Some}
-import gleam/order
-
-// Internal private representation of an Iterator
-type Action(element) {
- // Dedicated to Electric Six
- // https://youtu.be/_30t2dzEgiw?t=162
- Stop
- Continue(element, fn() -> Action(element))
-}
-
-/// An iterator is a lazily evaluated sequence of element.
-///
-/// Iterators are useful when working with collections that are too large to
-/// fit in memory (or those that are infinite in size) as they only require the
-/// elements currently being processed to be in memory.
-///
-/// As a lazy data structure no work is done when an iterator is filters,
-/// mapped, etc, instead a new iterator is returned with these transformations
-/// applied to the stream. Once the stream has all the required transformations
-/// applied it can be evaluated using functions such as `fold` and `to_list`.
-///
-pub opaque type Iterator(element) {
- Iterator(continuation: fn() -> Action(element))
-}
-
-// Public API for iteration
-pub type Step(element, accumulator) {
- Next(element: element, accumulator: accumulator)
- Done
-}
-
-// Shortcut for an empty iterator.
-fn stop() -> Action(element) {
- Stop
-}
-
-// Creating Iterators
-fn do_unfold(
- initial: acc,
- f: fn(acc) -> Step(element, acc),
-) -> fn() -> Action(element) {
- fn() {
- case f(initial) {
- Next(x, acc) -> Continue(x, do_unfold(acc, f))
- Done -> Stop
- }
- }
-}
-
-/// Creates an iterator from a given function and accumulator.
-///
-/// The function is called on the accumulator and returns either `Done`,
-/// indicating the iterator has no more elements, or `Next` which contains a
-/// new element and accumulator. The element is yielded by the iterator and the
-/// new accumulator is used with the function to compute the next element in
-/// the sequence.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > unfold(from: 5, with: fn(n) {
-/// > case n {
-/// > 0 -> Done
-/// > n -> Next(element: n, accumulator: n - 1)
-/// > }
-/// > })
-/// > |> to_list
-/// [5, 4, 3, 2, 1]
-/// ```
-///
-pub fn unfold(
- from initial: acc,
- with f: fn(acc) -> Step(element, acc),
-) -> Iterator(element) {
- initial
- |> do_unfold(f)
- |> Iterator
-}
-
-// TODO: test
-/// Creates an iterator that yields values created by calling a given function
-/// repeatedly.
-///
-pub fn repeatedly(f: fn() -> element) -> Iterator(element) {
- unfold(Nil, fn(_) { Next(f(), Nil) })
-}
-
-/// Creates an iterator that returns the same value infinitely.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > repeat(10)
-/// > |> take(4)
-/// > |> to_list
-/// [10, 10, 10, 10]
-/// ```
-///
-pub fn repeat(x: element) -> Iterator(element) {
- repeatedly(fn() { x })
-}
-
-/// Creates an iterator that yields each element from the given list.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > from_list([1, 2, 3, 4])
-/// > |> to_list
-/// [1, 2, 3, 4]
-/// ```
-///
-pub fn from_list(list: List(element)) -> Iterator(element) {
- let yield = fn(acc) {
- case acc {
- [] -> Done
- [head, ..tail] -> Next(head, tail)
- }
- }
- unfold(list, yield)
-}
-
-// Consuming Iterators
-fn do_transform(
- continuation: fn() -> Action(a),
- state: acc,
- f: fn(acc, a) -> Step(b, acc),
-) -> fn() -> Action(b) {
- fn() {
- case continuation() {
- Stop -> Stop
- Continue(el, next) ->
- case f(state, el) {
- Done -> Stop
- Next(yield, next_state) ->
- Continue(yield, do_transform(next, next_state, f))
- }
- }
- }
-}
-
-/// Creates an iterator from an existing iterator
-/// and a stateful function that may short-circuit.
-///
-/// `f` takes arguments `acc` for current state and `el` for current element from underlying iterator,
-/// and returns either `Next` with yielded element and new state value, or `Done` to halt the iterator.
-///
-/// ## Examples
-///
-/// Approximate implementation of `index` in terms of `transform`:
-///
-/// ```gleam
-/// > from_list(["a", "b", "c"])
-/// > |> transform(0, fn(i, el) { Next(#(i, el), i + 1) })
-/// > |> to_list
-/// [#(0, "a"), #(1, "b"), #(2, "c")]
-/// ```
-pub fn transform(
- over iterator: Iterator(a),
- from initial: acc,
- with f: fn(acc, a) -> Step(b, acc),
-) -> Iterator(b) {
- do_transform(iterator.continuation, initial, f)
- |> Iterator
-}
-
-fn do_fold(
- continuation: fn() -> Action(e),
- f: fn(acc, e) -> acc,
- accumulator: acc,
-) -> acc {
- case continuation() {
- Continue(elem, next) -> do_fold(next, f, f(accumulator, elem))
- Stop -> accumulator
- }
-}
-
-/// Reduces an iterator of elements into a single value by calling a given
-/// function on each element in turn.
-///
-/// If called on an iterator of infinite length then this function will never
-/// return.
-///
-/// If you do not care about the end value and only wish to evaluate the
-/// iterator for side effects consider using the `run` function instead.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > [1, 2, 3, 4]
-/// > |> from_list
-/// > |> fold(from: 0, with: fn(acc, element) { element + acc })
-/// 10
-/// ```
-///
-pub fn fold(
- over iterator: Iterator(e),
- from initial: acc,
- with f: fn(acc, e) -> acc,
-) -> acc {
- iterator.continuation
- |> do_fold(f, initial)
-}
-
-// TODO: test
-/// Evaluates all elements emitted by the given iterator. This function is useful for when
-/// you wish to trigger any side effects that would occur when evaluating
-/// the iterator.
-///
-pub fn run(iterator: Iterator(e)) -> Nil {
- fold(iterator, Nil, fn(_, _) { Nil })
-}
-
-/// Evaluates an iterator and returns all the elements as a list.
-///
-/// If called on an iterator of infinite length then this function will never
-/// return.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > [1, 2, 3]
-/// > |> from_list
-/// > |> map(fn(x) { x * 2 })
-/// > |> to_list
-/// [2, 4, 6]
-/// ```
-///
-pub fn to_list(iterator: Iterator(element)) -> List(element) {
- iterator
- |> fold([], fn(acc, e) { [e, ..acc] })
- |> list.reverse
-}
-
-/// Eagerly accesses the first value of an iterator, returning a `Next`
-/// that contains the first value and the rest of the iterator.
-///
-/// If called on an empty iterator, `Done` is returned.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > let assert Next(first, rest) = [1, 2, 3, 4]
-/// > |> from_list
-/// > |> step
-/// > first
-/// 1
-/// ```
-///
-/// ```gleam
-/// > rest |> to_list
-/// [2, 3, 4]
-/// ```
-///
-/// ```gleam
-/// > empty() |> step
-/// Done
-/// ```
-///
-pub fn step(iterator: Iterator(e)) -> Step(e, Iterator(e)) {
- case iterator.continuation() {
- Stop -> Done
- Continue(e, a) -> Next(e, Iterator(a))
- }
-}
-
-fn do_take(continuation: fn() -> Action(e), desired: Int) -> fn() -> Action(e) {
- fn() {
- case desired > 0 {
- False -> Stop
- True ->
- case continuation() {
- Stop -> Stop
- Continue(e, next) -> Continue(e, do_take(next, desired - 1))
- }
- }
- }
-}
-
-/// Creates an iterator that only yields the first `desired` elements.
-///
-/// If the iterator does not have enough elements all of them are yielded.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > [1, 2, 3, 4, 5]
-/// > |> from_list
-/// > |> take(up_to: 3)
-/// > |> to_list
-/// [1, 2, 3]
-/// ```
-///
-/// ```gleam
-/// > [1, 2]
-/// > |> from_list
-/// > |> take(up_to: 3)
-/// > |> to_list
-/// [1, 2]
-/// ```
-///
-pub fn take(from iterator: Iterator(e), up_to desired: Int) -> Iterator(e) {
- iterator.continuation
- |> do_take(desired)
- |> Iterator
-}
-
-fn do_drop(continuation: fn() -> Action(e), desired: Int) -> Action(e) {
- case continuation() {
- Stop -> Stop
- Continue(e, next) ->
- case desired > 0 {
- True -> do_drop(next, desired - 1)
- False -> Continue(e, next)
- }
- }
-}
-
-/// Evaluates and discards the first N elements in an iterator, returning a new
-/// iterator.
-///
-/// If the iterator does not have enough elements an empty iterator is
-/// returned.
-///
-/// This function does not evaluate the elements of the iterator, the
-/// computation is performed when the iterator is later run.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > [1, 2, 3, 4, 5]
-/// > |> from_list
-/// > |> drop(up_to: 3)
-/// > |> to_list
-/// [4, 5]
-/// ```
-///
-/// ```gleam
-/// > [1, 2]
-/// > |> from_list
-/// > |> drop(up_to: 3)
-/// > |> to_list
-/// []
-/// ```
-///
-pub fn drop(from iterator: Iterator(e), up_to desired: Int) -> Iterator(e) {
- fn() { do_drop(iterator.continuation, desired) }
- |> Iterator
-}
-
-fn do_map(continuation: fn() -> Action(a), f: fn(a) -> b) -> fn() -> Action(b) {
- fn() {
- case continuation() {
- Stop -> Stop
- Continue(e, continuation) -> Continue(f(e), do_map(continuation, f))
- }
- }
-}
-
-/// Creates an iterator from an existing iterator and a transformation function.
-///
-/// Each element in the new iterator will be the result of calling the given
-/// function on the elements in the given iterator.
-///
-/// This function does not evaluate the elements of the iterator, the
-/// computation is performed when the iterator is later run.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > [1, 2, 3]
-/// > |> from_list
-/// > |> map(fn(x) { x * 2 })
-/// > |> to_list
-/// [2, 4, 6]
-/// ```
-///
-pub fn map(over iterator: Iterator(a), with f: fn(a) -> b) -> Iterator(b) {
- iterator.continuation
- |> do_map(f)
- |> Iterator
-}
-
-fn do_map2(
- continuation1: fn() -> Action(a),
- continuation2: fn() -> Action(b),
- with fun: fn(a, b) -> c,
-) -> fn() -> Action(c) {
- fn() {
- case continuation1() {
- Stop -> Stop
- Continue(a, next_a) ->
- case continuation2() {
- Stop -> Stop
- Continue(b, next_b) ->
- Continue(fun(a, b), do_map2(next_a, next_b, fun))
- }
- }
- }
-}
-
-/// Combines two interators into a single one using the given function.
-///
-/// If an iterator is longer than the other the extra elements are dropped.
-///
-/// This function does not evaluate the elements of the two iterators, the
-/// computation is performed when the resulting iterator is later run.
-///
-/// ## Examples
-///
-/// ```gleam
-/// let first = from_list([1, 2, 3])
-/// let second = from_list([4, 5, 6])
-/// map2(first, second, fn(x, y) { x + y }) |> to_list
-/// // -> [5, 7, 9]
-/// ```
-///
-/// ```gleam
-/// let first = from_list([1, 2])
-/// let second = from_list(["a", "b", "c"])
-/// map2(first, second, fn(i, x) { #(i, x) }) |> to_list
-/// // -> [#(1, "a"), #(2, "b")]
-/// ```
-///
-pub fn map2(
- iterator1: Iterator(a),
- iterator2: Iterator(b),
- with fun: fn(a, b) -> c,
-) -> Iterator(c) {
- do_map2(iterator1.continuation, iterator2.continuation, fun)
- |> Iterator
-}
-
-fn do_append(first: fn() -> Action(a), second: fn() -> Action(a)) -> Action(a) {
- case first() {
- Continue(e, first) -> Continue(e, fn() { do_append(first, second) })
- Stop -> second()
- }
-}
-
-/// Appends two iterators, producing a new iterator.
-///
-/// This function does not evaluate the elements of the iterators, the
-/// computation is performed when the resulting iterator is later run.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > [1, 2]
-/// > |> from_list
-/// > |> append([3, 4] |> from_list)
-/// > |> to_list
-/// [1, 2, 3, 4]
-/// ```
-///
-pub fn append(to first: Iterator(a), suffix second: Iterator(a)) -> Iterator(a) {
- fn() { do_append(first.continuation, second.continuation) }
- |> Iterator
-}
-
-fn do_flatten(flattened: fn() -> Action(Iterator(a))) -> Action(a) {
- case flattened() {
- Stop -> Stop
- Continue(it, next_iterator) ->
- do_append(it.continuation, fn() { do_flatten(next_iterator) })
- }
-}
-
-/// Flattens an iterator of iterators, creating a new iterator.
-///
-/// This function does not evaluate the elements of the iterator, the
-/// computation is performed when the iterator is later run.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > from_list([[1, 2], [3, 4]])
-/// > |> map(from_list)
-/// > |> flatten
-/// > |> to_list
-/// [1, 2, 3, 4]
-/// ```
-///
-pub fn flatten(iterator: Iterator(Iterator(a))) -> Iterator(a) {
- fn() { do_flatten(iterator.continuation) }
- |> Iterator
-}
-
-/// Joins a list of iterators into a single iterator.
-///
-/// This function does not evaluate the elements of the iterator, the
-/// computation is performed when the iterator is later run.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > [[1, 2], [3, 4]]
-/// > |> map(from_list)
-/// > |> concat
-/// > |> to_list
-/// [1, 2, 3, 4]
-/// ```
-///
-pub fn concat(iterators: List(Iterator(a))) -> Iterator(a) {
- flatten(from_list(iterators))
-}
-
-/// Creates an iterator from an existing iterator and a transformation function.
-///
-/// Each element in the new iterator will be the result of calling the given
-/// function on the elements in the given iterator and then flattening the
-/// results.
-///
-/// This function does not evaluate the elements of the iterator, the
-/// computation is performed when the iterator is later run.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > [1, 2]
-/// > |> from_list
-/// > |> flat_map(fn(x) { from_list([x, x + 1]) })
-/// > |> to_list
-/// [1, 2, 2, 3]
-/// ```
-///
-pub fn flat_map(
- over iterator: Iterator(a),
- with f: fn(a) -> Iterator(b),
-) -> Iterator(b) {
- iterator
- |> map(f)
- |> flatten
-}
-
-fn do_filter(
- continuation: fn() -> Action(e),
- predicate: fn(e) -> Bool,
-) -> Action(e) {
- case continuation() {
- Stop -> Stop
- Continue(e, iterator) ->
- case predicate(e) {
- True -> Continue(e, fn() { do_filter(iterator, predicate) })
- False -> do_filter(iterator, predicate)
- }
- }
-}
-
-/// Creates an iterator from an existing iterator and a predicate function.
-///
-/// The new iterator will contain elements from the first iterator for which
-/// the given function returns `True`.
-///
-/// This function does not evaluate the elements of the iterator, the
-/// computation is performed when the iterator is later run.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > import gleam/int
-/// > [1, 2, 3, 4]
-/// > |> from_list
-/// > |> filter(int.is_even)
-/// > |> to_list
-/// [2, 4]
-/// ```
-///
-pub fn filter(
- iterator: Iterator(a),
- keeping predicate: fn(a) -> Bool,
-) -> Iterator(a) {
- fn() { do_filter(iterator.continuation, predicate) }
- |> Iterator
-}
-
-/// Creates an iterator that repeats a given iterator infinitely.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > [1, 2]
-/// > |> from_list
-/// > |> cycle
-/// > |> take(6)
-/// > |> to_list
-/// [1, 2, 1, 2, 1, 2]
-/// ```
-///
-pub fn cycle(iterator: Iterator(a)) -> Iterator(a) {
- repeat(iterator)
- |> flatten
-}
-
-/// Creates an iterator of ints, starting at a given start int and stepping by
-/// one to a given end int.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > range(from: 1, to: 5) |> to_list
-/// [1, 2, 3, 4, 5]
-/// ```
-///
-/// ```gleam
-/// > range(from: 1, to: -2) |> to_list
-/// [1, 0, -1, -2]
-/// ```
-///
-/// ```gleam
-/// > range(from: 0, to: 0) |> to_list
-/// [0]
-/// ```
-///
-pub fn range(from start: Int, to stop: Int) -> Iterator(Int) {
- case int.compare(start, stop) {
- order.Eq -> once(fn() { start })
- order.Gt ->
- unfold(
- from: start,
- with: fn(current) {
- case current < stop {
- False -> Next(current, current - 1)
- True -> Done
- }
- },
- )
-
- order.Lt ->
- unfold(
- from: start,
- with: fn(current) {
- case current > stop {
- False -> Next(current, current + 1)
- True -> Done
- }
- },
- )
- }
-}
-
-fn do_find(continuation: fn() -> Action(a), f: fn(a) -> Bool) -> Result(a, Nil) {
- case continuation() {
- Stop -> Error(Nil)
- Continue(e, next) ->
- case f(e) {
- True -> Ok(e)
- False -> do_find(next, f)
- }
- }
-}
-
-/// Finds the first element in a given iterator for which the given function returns
-/// `True`.
-///
-/// Returns `Error(Nil)` if the function does not return `True` for any of the
-/// elements.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > find(from_list([1, 2, 3]), fn(x) { x > 2 })
-/// Ok(3)
-/// ```
-///
-/// ```gleam
-/// > find(from_list([1, 2, 3]), fn(x) { x > 4 })
-/// Error(Nil)
-/// ```
-///
-/// ```gleam
-/// > find(empty(), fn(_) { True })
-/// Error(Nil)
-/// ```
-///
-pub fn find(
- in haystack: Iterator(a),
- one_that is_desired: fn(a) -> Bool,
-) -> Result(a, Nil) {
- haystack.continuation
- |> do_find(is_desired)
-}
-
-fn do_index(
- continuation: fn() -> Action(element),
- next: Int,
-) -> fn() -> Action(#(Int, element)) {
- fn() {
- case continuation() {
- Stop -> Stop
- Continue(e, continuation) ->
- Continue(#(next, e), do_index(continuation, next + 1))
- }
- }
-}
-
-/// Wraps values yielded from an iterator with indices, starting from 0.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > from_list(["a", "b", "c"]) |> index |> to_list
-/// [#(0, "a"), #(1, "b"), #(2, "c")]
-/// ```
-///
-pub fn index(over iterator: Iterator(element)) -> Iterator(#(Int, element)) {
- iterator.continuation
- |> do_index(0)
- |> Iterator
-}
-
-/// Creates an iterator that inifinitely applies a function to a value.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > iterate(1, fn(n) { n * 3 }) |> take(5) |> to_list
-/// [1, 3, 9, 27, 81]
-/// ```
-///
-pub fn iterate(
- from initial: element,
- with f: fn(element) -> element,
-) -> Iterator(element) {
- unfold(initial, fn(element) { Next(element, f(element)) })
-}
-
-fn do_take_while(
- continuation: fn() -> Action(element),
- predicate: fn(element) -> Bool,
-) -> fn() -> Action(element) {
- fn() {
- case continuation() {
- Stop -> Stop
- Continue(e, next) ->
- case predicate(e) {
- False -> Stop
- True -> Continue(e, do_take_while(next, predicate))
- }
- }
- }
-}
-
-/// Creates an iterator that yields elements while the predicate returns `True`.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > from_list([1, 2, 3, 2, 4])
-/// > |> take_while(satisfying: fn(x) { x < 3 })
-/// > |> to_list
-/// [1, 2]
-/// ```
-///
-pub fn take_while(
- in iterator: Iterator(element),
- satisfying predicate: fn(element) -> Bool,
-) -> Iterator(element) {
- iterator.continuation
- |> do_take_while(predicate)
- |> Iterator
-}
-
-fn do_drop_while(
- continuation: fn() -> Action(element),
- predicate: fn(element) -> Bool,
-) -> Action(element) {
- case continuation() {
- Stop -> Stop
- Continue(e, next) ->
- case predicate(e) {
- False -> Continue(e, next)
- True -> do_drop_while(next, predicate)
- }
- }
-}
-
-/// Creates an iterator that drops elements while the predicate returns `True`,
-/// and then yields the remaining elements.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > from_list([1, 2, 3, 4, 2, 5])
-/// > |> drop_while(satisfying: fn(x) { x < 4 })
-/// > |> to_list
-/// [4, 2, 5]
-/// ```
-///
-pub fn drop_while(
- in iterator: Iterator(element),
- satisfying predicate: fn(element) -> Bool,
-) -> Iterator(element) {
- fn() { do_drop_while(iterator.continuation, predicate) }
- |> Iterator
-}
-
-fn do_scan(
- continuation: fn() -> Action(element),
- f: fn(acc, element) -> acc,
- accumulator: acc,
-) -> fn() -> Action(acc) {
- fn() {
- case continuation() {
- Stop -> Stop
- Continue(el, next) -> {
- let accumulated = f(accumulator, el)
- Continue(accumulated, do_scan(next, f, accumulated))
- }
- }
- }
-}
-
-/// Creates an iterator from an existing iterator and a stateful function.
-///
-/// Specifically, this behaves like `fold`, but yields intermediate results.
-///
-/// ## Examples
-///
-/// ```gleam
-/// // Generate a sequence of partial sums
-/// > from_list([1, 2, 3, 4, 5])
-/// > |> scan(from: 0, with: fn(acc, el) { acc + el })
-/// > |> to_list
-/// [1, 3, 6, 10, 15]
-/// ```
-///
-pub fn scan(
- over iterator: Iterator(element),
- from initial: acc,
- with f: fn(acc, element) -> acc,
-) -> Iterator(acc) {
- iterator.continuation
- |> do_scan(f, initial)
- |> Iterator
-}
-
-fn do_zip(
- left: fn() -> Action(a),
- right: fn() -> Action(b),
-) -> fn() -> Action(#(a, b)) {
- fn() {
- case left() {
- Stop -> Stop
- Continue(el_left, next_left) ->
- case right() {
- Stop -> Stop
- Continue(el_right, next_right) ->
- Continue(#(el_left, el_right), do_zip(next_left, next_right))
- }
- }
- }
-}
-
-/// Zips two iterators together, emitting values from both
-/// until the shorter one runs out.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > from_list(["a", "b", "c"])
-/// > |> zip(range(20, 30))
-/// > |> to_list
-/// [#("a", 20), #("b", 21), #("c", 22)]
-/// ```
-///
-pub fn zip(left: Iterator(a), right: Iterator(b)) -> Iterator(#(a, b)) {
- do_zip(left.continuation, right.continuation)
- |> Iterator
-}
-
-// Result of collecting a single chunk by key
-type Chunk(element, key) {
- AnotherBy(List(element), key, element, fn() -> Action(element))
- LastBy(List(element))
-}
-
-fn next_chunk(
- continuation: fn() -> Action(element),
- f: fn(element) -> key,
- previous_key: key,
- current_chunk: List(element),
-) -> Chunk(element, key) {
- case continuation() {
- Stop -> LastBy(list.reverse(current_chunk))
- Continue(e, next) -> {
- let key = f(e)
- case key == previous_key {
- True -> next_chunk(next, f, key, [e, ..current_chunk])
- False -> AnotherBy(list.reverse(current_chunk), key, e, next)
- }
- }
- }
-}
-
-fn do_chunk(
- continuation: fn() -> Action(element),
- f: fn(element) -> key,
- previous_key: key,
- previous_element: element,
-) -> Action(List(element)) {
- case next_chunk(continuation, f, previous_key, [previous_element]) {
- LastBy(chunk) -> Continue(chunk, stop)
- AnotherBy(chunk, key, el, next) ->
- Continue(chunk, fn() { do_chunk(next, f, key, el) })
- }
-}
-
-/// Creates an iterator that emits chunks of elements
-/// for which `f` returns the same value.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > from_list([1, 2, 2, 3, 4, 4, 6, 7, 7])
-/// > |> chunk(by: fn(n) { n % 2 })
-/// > |> to_list
-/// [[1], [2, 2], [3], [4, 4, 6], [7, 7]]
-/// ```
-///
-pub fn chunk(
- over iterator: Iterator(element),
- by f: fn(element) -> key,
-) -> Iterator(List(element)) {
- fn() {
- case iterator.continuation() {
- Stop -> Stop
- Continue(e, next) -> do_chunk(next, f, f(e), e)
- }
- }
- |> Iterator
-}
-
-// Result of collecting a single sized chunk
-type SizedChunk(element) {
- Another(List(element), fn() -> Action(element))
- Last(List(element))
- NoMore
-}
-
-fn next_sized_chunk(
- continuation: fn() -> Action(element),
- left: Int,
- current_chunk: List(element),
-) -> SizedChunk(element) {
- case continuation() {
- Stop ->
- case current_chunk {
- [] -> NoMore
- remaining -> Last(list.reverse(remaining))
- }
- Continue(e, next) -> {
- let chunk = [e, ..current_chunk]
- case left > 1 {
- False -> Another(list.reverse(chunk), next)
- True -> next_sized_chunk(next, left - 1, chunk)
- }
- }
- }
-}
-
-fn do_sized_chunk(
- continuation: fn() -> Action(element),
- count: Int,
-) -> fn() -> Action(List(element)) {
- fn() {
- case next_sized_chunk(continuation, count, []) {
- NoMore -> Stop
- Last(chunk) -> Continue(chunk, stop)
- Another(chunk, next_element) ->
- Continue(chunk, do_sized_chunk(next_element, count))
- }
- }
-}
-
-/// Creates an iterator that emits chunks of given size.
-///
-/// If the last chunk does not have `count` elements, it is yielded
-/// as a partial chunk, with less than `count` elements.
-///
-/// For any `count` less than 1 this function behaves as if it was set to 1.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > from_list([1, 2, 3, 4, 5, 6])
-/// > |> sized_chunk(into: 2)
-/// > |> to_list
-/// [[1, 2], [3, 4], [5, 6]]
-/// ```
-///
-/// ```gleam
-/// > from_list([1, 2, 3, 4, 5, 6, 7, 8])
-/// > |> sized_chunk(into: 3)
-/// > |> to_list
-/// [[1, 2, 3], [4, 5, 6], [7, 8]]
-/// ```
-///
-pub fn sized_chunk(
- over iterator: Iterator(element),
- into count: Int,
-) -> Iterator(List(element)) {
- iterator.continuation
- |> do_sized_chunk(count)
- |> Iterator
-}
-
-fn do_intersperse(
- continuation: fn() -> Action(element),
- separator: element,
-) -> Action(element) {
- case continuation() {
- Stop -> Stop
- Continue(e, next) -> {
- let next_interspersed = fn() { do_intersperse(next, separator) }
- Continue(separator, fn() { Continue(e, next_interspersed) })
- }
- }
-}
-
-/// Creates an iterator that yields the given `elem` element
-/// between elements emitted by the underlying iterator.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > empty()
-/// > |> intersperse(with: 0)
-/// > |> to_list
-/// []
-///
-/// > from_list([1])
-/// > |> intersperse(with: 0)
-/// > |> to_list
-/// [1]
-///
-/// > from_list([1, 2, 3, 4, 5])
-/// > |> intersperse(with: 0)
-/// > |> to_list
-/// [1, 0, 2, 0, 3, 0, 4, 0, 5]
-/// ```
-///
-pub fn intersperse(
- over iterator: Iterator(element),
- with elem: element,
-) -> Iterator(element) {
- fn() {
- case iterator.continuation() {
- Stop -> Stop
- Continue(e, next) -> Continue(e, fn() { do_intersperse(next, elem) })
- }
- }
- |> Iterator
-}
-
-fn do_any(
- continuation: fn() -> Action(element),
- predicate: fn(element) -> Bool,
-) -> Bool {
- case continuation() {
- Stop -> False
- Continue(e, next) ->
- case predicate(e) {
- True -> True
- False -> do_any(next, predicate)
- }
- }
-}
-
-/// Returns `True` if any element emitted by the iterator satisfies the given predicate,
-/// `False` otherwise.
-///
-/// This function short-circuits once it finds a satisfying element.
-///
-/// An empty iterator results in `False`.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > empty() |> any(fn(n) { n % 2 == 0 })
-/// False
-/// ```
-///
-/// ```gleam
-/// > from_list([1, 2, 5, 7, 9]) |> any(fn(n) { n % 2 == 0 })
-/// True
-/// ```
-///
-/// ```gleam
-/// > from_list([1, 3, 5, 7, 9]) |> any(fn(n) { n % 2 == 0 })
-/// False
-/// ```
-///
-pub fn any(
- in iterator: Iterator(element),
- satisfying predicate: fn(element) -> Bool,
-) -> Bool {
- iterator.continuation
- |> do_any(predicate)
-}
-
-fn do_all(
- continuation: fn() -> Action(element),
- predicate: fn(element) -> Bool,
-) -> Bool {
- case continuation() {
- Stop -> True
- Continue(e, next) ->
- case predicate(e) {
- True -> do_all(next, predicate)
- False -> False
- }
- }
-}
-
-/// Returns `True` if all elements emitted by the iterator satisfy the given predicate,
-/// `False` otherwise.
-///
-/// This function short-circuits once it finds a non-satisfying element.
-///
-/// An empty iterator results in `True`.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > empty() |> all(fn(n) { n % 2 == 0 })
-/// True
-/// ```
-///
-/// ```gleam
-/// > from_list([2, 4, 6, 8]) |> all(fn(n) { n % 2 == 0 })
-/// True
-/// ```
-///
-/// ```gleam
-/// > from_list([2, 4, 5, 8]) |> all(fn(n) { n % 2 == 0 })
-/// False
-/// ```
-///
-pub fn all(
- in iterator: Iterator(element),
- satisfying predicate: fn(element) -> Bool,
-) -> Bool {
- iterator.continuation
- |> do_all(predicate)
-}
-
-fn update_group_with(el: element) -> fn(Option(List(element))) -> List(element) {
- fn(maybe_group) {
- case maybe_group {
- Some(group) -> [el, ..group]
- None -> [el]
- }
- }
-}
-
-fn group_updater(
- f: fn(element) -> key,
-) -> fn(Dict(key, List(element)), element) -> Dict(key, List(element)) {
- fn(groups, elem) {
- groups
- |> dict.update(f(elem), update_group_with(elem))
- }
-}
-
-/// Returns a `Dict(k, List(element))` of elements from the given iterator
-/// grouped with the given key function.
-///
-/// The order within each group is preserved from the iterator.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > from_list([1, 2, 3, 4, 5, 6]) |> group(by: fn(n) { n % 3 })
-/// dict.from_list([#(0, [3, 6]), #(1, [1, 4]), #(2, [2, 5])])
-/// ```
-///
-pub fn group(
- in iterator: Iterator(element),
- by key: fn(element) -> key,
-) -> Dict(key, List(element)) {
- iterator
- |> fold(dict.new(), group_updater(key))
- |> dict.map_values(fn(_, group) { list.reverse(group) })
-}
-
-/// This function acts similar to fold, but does not take an initial state.
-/// Instead, it starts from the first yielded element
-/// and combines it with each subsequent element in turn using the given function.
-/// The function is called as `f(accumulator, current_element)`.
-///
-/// Returns `Ok` to indicate a successful run, and `Error` if called on an empty iterator.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > from_list([]) |> reduce(fn(acc, x) { acc + x })
-/// Error(Nil)
-/// ```
-///
-/// ```gleam
-/// > from_list([1, 2, 3, 4, 5]) |> reduce(fn(acc, x) { acc + x })
-/// Ok(15)
-/// ```
-///
-pub fn reduce(
- over iterator: Iterator(e),
- with f: fn(e, e) -> e,
-) -> Result(e, Nil) {
- case iterator.continuation() {
- Stop -> Error(Nil)
- Continue(e, next) ->
- do_fold(next, f, e)
- |> Ok
- }
-}
-
-/// Returns the last element in the given iterator.
-///
-/// Returns `Error(Nil)` if the iterator is empty.
-///
-/// This function runs in linear time.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > empty() |> last
-/// Error(Nil)
-/// ```
-///
-/// ```gleam
-/// > range(1, 10) |> last
-/// Ok(9)
-/// ```
-///
-pub fn last(iterator: Iterator(element)) -> Result(element, Nil) {
- iterator
- |> reduce(fn(_, elem) { elem })
-}
-
-/// Creates an iterator that yields no elements.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > empty() |> to_list
-/// []
-/// ```
-///
-pub fn empty() -> Iterator(element) {
- Iterator(stop)
-}
-
-/// Creates an iterator that yields exactly one element provided by calling the given function.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > once(fn() { 1 }) |> to_list
-/// [1]
-/// ```
-///
-pub fn once(f: fn() -> element) -> Iterator(element) {
- fn() { Continue(f(), stop) }
- |> Iterator
-}
-
-/// Creates an iterator that yields the given element exactly once.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > single(1) |> to_list
-/// [1]
-/// ```
-///
-pub fn single(elem: element) -> Iterator(element) {
- once(fn() { elem })
-}
-
-fn do_interleave(
- current: fn() -> Action(element),
- next: fn() -> Action(element),
-) -> Action(element) {
- case current() {
- Stop -> next()
- Continue(e, next_other) ->
- Continue(e, fn() { do_interleave(next, next_other) })
- }
-}
-
-/// Creates an iterator that alternates between the two given iterators
-/// until both have run out.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > from_list([1, 2, 3, 4]) |> interleave(from_list([11, 12, 13, 14])) |> to_list
-/// [1, 11, 2, 12, 3, 13, 4, 14]
-/// ```
-///
-/// ```gleam
-/// > from_list([1, 2, 3, 4]) |> interleave(from_list([100])) |> to_list
-/// [1, 100, 2, 3, 4]
-/// ```
-///
-pub fn interleave(
- left: Iterator(element),
- with right: Iterator(element),
-) -> Iterator(element) {
- fn() { do_interleave(left.continuation, right.continuation) }
- |> Iterator
-}
-
-fn do_fold_until(
- continuation: fn() -> Action(e),
- f: fn(acc, e) -> list.ContinueOrStop(acc),
- accumulator: acc,
-) -> acc {
- case continuation() {
- Stop -> accumulator
- Continue(elem, next) ->
- case f(accumulator, elem) {
- list.Continue(accumulator) -> do_fold_until(next, f, accumulator)
- list.Stop(accumulator) -> accumulator
- }
- }
-}
-
-/// Like `fold`, `fold_until` reduces an iterator of elements into a single value by calling a given
-/// function on each element in turn, but uses `list.ContinueOrStop` to determine
-/// whether or not to keep iterating.
-///
-/// If called on an iterator of infinite length then this function will only ever
-/// return if the function returns `list.Stop`.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > import gleam/list
-/// > let f = fn(acc, e) {
-/// > case e {
-/// > _ if e < 4 -> list.Continue(e + acc)
-/// > _ -> list.Stop(acc)
-/// > }
-/// > }
-/// >
-/// > [1, 2, 3, 4]
-/// > |> from_list
-/// > |> fold_until(from: acc, with: f)
-/// 6
-/// ```
-///
-pub fn fold_until(
- over iterator: Iterator(e),
- from initial: acc,
- with f: fn(acc, e) -> list.ContinueOrStop(acc),
-) -> acc {
- iterator.continuation
- |> do_fold_until(f, initial)
-}
-
-fn do_try_fold(
- over continuation: fn() -> Action(a),
- with f: fn(acc, a) -> Result(acc, err),
- from accumulator: acc,
-) -> Result(acc, err) {
- case continuation() {
- Stop -> Ok(accumulator)
- Continue(elem, next) -> {
- use accumulator <- result.try(f(accumulator, elem))
- do_try_fold(next, f, accumulator)
- }
- }
-}
-
-/// A variant of fold that might fail.
-///
-/// The folding function should return `Result(accumulator, error)`.
-/// If the returned value is `Ok(accumulator)` try_fold will try the next value in the iterator.
-/// If the returned value is `Error(error)` try_fold will stop and return that error.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > [1, 2, 3, 4]
-/// > |> iterator.from_list()
-/// > |> try_fold(0, fn(acc, i) {
-/// > case i < 3 {
-/// > True -> Ok(acc + i)
-/// > False -> Error(Nil)
-/// > }
-/// > })
-/// Error(Nil)
-/// ```
-///
-pub fn try_fold(
- over iterator: Iterator(e),
- from initial: acc,
- with f: fn(acc, e) -> Result(acc, err),
-) -> Result(acc, err) {
- iterator.continuation
- |> do_try_fold(f, initial)
-}
-
-/// Returns the first element yielded by the given iterator, if it exists,
-/// or `Error(Nil)` otherwise.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > from_list([1, 2, 3]) |> first
-/// Ok(1)
-/// ```
-///
-/// ```gleam
-/// > empty() |> first
-/// Error(Nil)
-/// ```
-pub fn first(from iterator: Iterator(e)) -> Result(e, Nil) {
- case iterator.continuation() {
- Stop -> Error(Nil)
- Continue(e, _) -> Ok(e)
- }
-}
-
-/// Returns nth element yielded by the given iterator, where `0` means the first element.
-///
-/// If there are not enough elements in the iterator, `Error(Nil)` is returned.
-///
-/// For any `index` less than `0` this function behaves as if it was set to `0`.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > from_list([1, 2, 3, 4]) |> at(2)
-/// Ok(3)
-/// ```
-///
-/// ```gleam
-/// > from_list([1, 2, 3, 4]) |> at(4)
-/// Error(Nil)
-/// ```
-///
-/// ```gleam
-/// > empty() |> at(0)
-/// Error(Nil)
-/// ```
-///
-pub fn at(in iterator: Iterator(e), get index: Int) -> Result(e, Nil) {
- iterator
- |> drop(index)
- |> first
-}
-
-fn do_length(over continuation: fn() -> Action(e), with length: Int) -> Int {
- case continuation() {
- Stop -> length
- Continue(_, next) -> do_length(next, length + 1)
- }
-}
-
-/// Counts the number of elements in the given iterator.
-///
-/// This function has to traverse the entire iterator to count its elements,
-/// so it runs in linear time.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > empty() |> length
-/// 0
-/// ```
-///
-/// ```gleam
-/// > from_list([1, 2, 3, 4]) |> length
-/// 4
-/// ```
-///
-pub fn length(over iterator: Iterator(e)) -> Int {
- iterator.continuation
- |> do_length(0)
-}
-
-/// Traverse an iterator, calling a function on each element.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > empty() |> each(io.println)
-/// Nil
-/// ```
-///
-/// ```gleam
-/// > from_list(["Tom", "Malory", "Louis"]) |> each(io.println)
-/// // -> Tom
-/// // -> Malory
-/// // -> Louis
-/// Nil
-/// ```
-///
-pub fn each(over iterator: Iterator(a), with f: fn(a) -> b) -> Nil {
- iterator
- |> map(f)
- |> run
-}
-
-/// Add a new element to the start of an iterator.
-///
-/// This function is for use with `use` expressions, to replicate the behaviour
-/// of the `yield` keyword found in other languages.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > use <- iterator.yield(1)
-/// > use <- iterator.yield(2)
-/// > use <- iterator.yield(3)
-/// > iterator.empty()
-/// iterator.from_list([1, 2, 3])
-/// ```
-///
-pub fn yield(element: a, next: fn() -> Iterator(a)) -> Iterator(a) {
- Iterator(fn() { Continue(element, next().continuation) })
-}
diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam/list.gleam b/aoc2023/build/packages/gleam_stdlib/src/gleam/list.gleam
deleted file mode 100644
index a5cffa9..0000000
--- a/aoc2023/build/packages/gleam_stdlib/src/gleam/list.gleam
+++ /dev/null
@@ -1,2154 +0,0 @@
-//// Lists are an ordered sequence of elements and are one of the most common
-//// data types in Gleam.
-////
-//// New elements can be added and removed from the front of a list in
-//// constant time, while adding and removing from the end requires traversing
-//// the copying the whole list, so keep this in mind when designing your
-//// programs.
-////
-//// There is a dedicated syntax for prefixing to a list:
-////
-//// ```gleam
-//// let new_list = [1, 2, ..existing_list]
-//// ```
-////
-//// And a matching syntax for getting the first elements of a list:
-////
-//// ```gleam
-//// case list {
-//// [first_element, ..rest] -> first_element
-//// _ -> "this pattern matches when the list is empty"
-//// }
-//// ```
-////
-
-import gleam/int
-import gleam/float
-import gleam/order.{type Order}
-import gleam/pair
-import gleam/dict.{type Dict}
-
-/// An error value returned by the `strict_zip` function.
-///
-pub type LengthMismatch {
- LengthMismatch
-}
-
-/// Counts the number of elements in a given list.
-///
-/// This function has to traverse the list to determine the number of elements,
-/// so it runs in linear time.
-///
-/// This function is natively implemented by the virtual machine and is highly
-/// optimised.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > length([])
-/// 0
-/// ```
-///
-/// ```gleam
-/// > length([1])
-/// 1
-/// ```
-///
-/// ```gleam
-/// > length([1, 2])
-/// 2
-/// ```
-///
-pub fn length(of list: List(a)) -> Int {
- do_length(list)
-}
-
-@target(erlang)
-@external(erlang, "erlang", "length")
-fn do_length(a: List(a)) -> Int
-
-@target(javascript)
-fn do_length(list: List(a)) -> Int {
- do_length_acc(list, 0)
-}
-
-@target(javascript)
-fn do_length_acc(list: List(a), count: Int) -> Int {
- case list {
- [_, ..list] -> do_length_acc(list, count + 1)
- _ -> count
- }
-}
-
-/// Creates a new list from a given list containing the same elements but in the
-/// opposite order.
-///
-/// This function has to traverse the list to create the new reversed list, so
-/// it runs in linear time.
-///
-/// This function is natively implemented by the virtual machine and is highly
-/// optimised.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > reverse([])
-/// []
-/// ```
-///
-/// ```gleam
-/// > reverse([1])
-/// [1]
-/// ```
-///
-/// ```gleam
-/// > reverse([1, 2])
-/// [2, 1]
-/// ```
-///
-pub fn reverse(xs: List(a)) -> List(a) {
- do_reverse(xs)
-}
-
-@target(erlang)
-@external(erlang, "lists", "reverse")
-fn do_reverse(a: List(a)) -> List(a)
-
-@target(javascript)
-fn do_reverse(list) {
- do_reverse_acc(list, [])
-}
-
-@target(javascript)
-fn do_reverse_acc(remaining, accumulator) {
- case remaining {
- [] -> accumulator
- [item, ..rest] -> do_reverse_acc(rest, [item, ..accumulator])
- }
-}
-
-/// Determines whether or not the list is empty.
-///
-/// This function runs in constant time.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > is_empty([])
-/// True
-/// ```
-///
-/// ```gleam
-/// > is_empty([1])
-/// False
-/// ```
-///
-/// ```gleam
-/// > is_empty([1, 1])
-/// False
-/// ```
-///
-pub fn is_empty(list: List(a)) -> Bool {
- list == []
-}
-
-/// Determines whether or not a given element exists within a given list.
-///
-/// This function traverses the list to find the element, so it runs in linear
-/// time.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > [] |> contains(any: 0)
-/// False
-/// ```
-///
-/// ```gleam
-/// > [0] |> contains(any: 0)
-/// True
-/// ```
-///
-/// ```gleam
-/// > [1] |> contains(any: 0)
-/// False
-/// ```
-///
-/// ```gleam
-/// > [1, 1] |> contains(any: 0)
-/// False
-/// ```
-///
-/// ```gleam
-/// > [1, 0] |> contains(any: 0)
-/// True
-/// ```
-///
-pub fn contains(list: List(a), any elem: a) -> Bool {
- case list {
- [] -> False
- [first, ..] if first == elem -> True
- [_, ..rest] -> contains(rest, elem)
- }
-}
-
-/// Gets the first element from the start of the list, if there is one.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > first([])
-/// Error(Nil)
-/// ```
-///
-/// ```gleam
-/// > first([0])
-/// Ok(0)
-/// ```
-///
-/// ```gleam
-/// > first([1, 2])
-/// Ok(1)
-/// ```
-///
-pub fn first(list: List(a)) -> Result(a, Nil) {
- case list {
- [] -> Error(Nil)
- [x, ..] -> Ok(x)
- }
-}
-
-/// Returns the list minus the first element. If the list is empty, `Error(Nil)` is
-/// returned.
-///
-/// This function runs in constant time and does not make a copy of the list.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > rest([])
-/// Error(Nil)
-/// ```
-///
-/// ```gleam
-/// > rest([0])
-/// Ok([])
-/// ```
-///
-/// ```gleam
-/// > rest([1, 2])
-/// Ok([2])
-/// ```
-///
-pub fn rest(list: List(a)) -> Result(List(a), Nil) {
- case list {
- [] -> Error(Nil)
- [_, ..xs] -> Ok(xs)
- }
-}
-
-fn update_group(
- f: fn(element) -> key,
-) -> fn(Dict(key, List(element)), element) -> Dict(key, List(element)) {
- fn(groups, elem) {
- case dict.get(groups, f(elem)) {
- Ok(existing) -> dict.insert(groups, f(elem), [elem, ..existing])
- Error(_) -> dict.insert(groups, f(elem), [elem])
- }
- }
-}
-
-/// Takes a list and groups the values by a key
-/// which is built from a key function.
-///
-/// Does not preserve the initial value order.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > [Ok(3), Error("Wrong"), Ok(200), Ok(73)]
-/// |> group(by: fn(i) {
-/// case i {
-/// Ok(_) -> "Successful"
-/// Error(_) -> "Failed"
-/// }
-/// })
-/// |> dict.to_list
-///
-/// [
-/// #("Failed", [Error("Wrong")]),
-/// #("Successful", [Ok(73), Ok(200), Ok(3)])
-/// ]
-///
-/// > group([1,2,3,4,5], by: fn(i) { i - i / 3 * 3 })
-/// |> dict.to_list
-/// [#(0, [3]), #(1, [4, 1]), #(2, [5, 2])]
-/// ```
-///
-pub fn group(list: List(v), by key: fn(v) -> k) -> Dict(k, List(v)) {
- fold(list, dict.new(), update_group(key))
-}
-
-fn do_filter(list: List(a), fun: fn(a) -> Bool, acc: List(a)) -> List(a) {
- case list {
- [] -> reverse(acc)
- [x, ..xs] -> {
- let new_acc = case fun(x) {
- True -> [x, ..acc]
- False -> acc
- }
- do_filter(xs, fun, new_acc)
- }
- }
-}
-
-/// Returns a new list containing only the elements from the first list for
-/// which the given functions returns `True`.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > filter([2, 4, 6, 1], fn(x) { x > 2 })
-/// [4, 6]
-/// ```
-///
-/// ```gleam
-/// > filter([2, 4, 6, 1], fn(x) { x > 6 })
-/// []
-/// ```
-///
-pub fn filter(list: List(a), keeping predicate: fn(a) -> Bool) -> List(a) {
- do_filter(list, predicate, [])
-}
-
-fn do_filter_map(
- list: List(a),
- fun: fn(a) -> Result(b, e),
- acc: List(b),
-) -> List(b) {
- case list {
- [] -> reverse(acc)
- [x, ..xs] -> {
- let new_acc = case fun(x) {
- Ok(x) -> [x, ..acc]
- Error(_) -> acc
- }
- do_filter_map(xs, fun, new_acc)
- }
- }
-}
-
-/// Returns a new list containing only the elements from the first list for
-/// which the given functions returns `Ok(_)`.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > filter_map([2, 4, 6, 1], Error)
-/// []
-/// ```
-///
-/// ```gleam
-/// > filter_map([2, 4, 6, 1], fn(x) { Ok(x + 1) })
-/// [3, 5, 7, 2]
-/// ```
-///
-pub fn filter_map(list: List(a), with fun: fn(a) -> Result(b, e)) -> List(b) {
- do_filter_map(list, fun, [])
-}
-
-fn do_map(list: List(a), fun: fn(a) -> b, acc: List(b)) -> List(b) {
- case list {
- [] -> reverse(acc)
- [x, ..xs] -> do_map(xs, fun, [fun(x), ..acc])
- }
-}
-
-/// Returns a new list containing only the elements of the first list after the
-/// function has been applied to each one.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > map([2, 4, 6], fn(x) { x * 2 })
-/// [4, 8, 12]
-/// ```
-///
-pub fn map(list: List(a), with fun: fn(a) -> b) -> List(b) {
- do_map(list, fun, [])
-}
-
-/// Combines two lists into a single list using the given function.
-///
-/// If a list is longer than the other the extra elements are dropped.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > map2([1, 2, 3], [4, 5, 6], fn(x, y) { x + y })
-/// [5, 7, 9]
-/// ```
-///
-/// ```gleam
-/// > map2([1, 2], ["a", "b", "c"], fn(i, x) { #(i, x) })
-/// [#(1, "a"), #(2, "b")]
-/// ```
-///
-pub fn map2(list1: List(a), list2: List(b), with fun: fn(a, b) -> c) -> List(c) {
- do_map2(list1, list2, fun, [])
-}
-
-fn do_map2(
- list1: List(a),
- list2: List(b),
- fun: fn(a, b) -> c,
- acc: List(c),
-) -> List(c) {
- case list1, list2 {
- [], _ | _, [] -> reverse(acc)
- [a, ..as_], [b, ..bs] -> do_map2(as_, bs, fun, [fun(a, b), ..acc])
- }
-}
-
-/// Similar to `map` but also lets you pass around an accumulated value.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > map_fold(
-/// over: [1, 2, 3],
-/// from: 100,
-/// with: fn(memo, i) { #(memo + i, i * 2) }
-/// )
-/// #(106, [2, 4, 6])
-/// ```
-///
-pub fn map_fold(
- over list: List(a),
- from acc: acc,
- with fun: fn(acc, a) -> #(acc, b),
-) -> #(acc, List(b)) {
- fold(
- over: list,
- from: #(acc, []),
- with: fn(acc, item) {
- let #(current_acc, items) = acc
- let #(next_acc, next_item) = fun(current_acc, item)
- #(next_acc, [next_item, ..items])
- },
- )
- |> pair.map_second(reverse)
-}
-
-fn do_index_map(
- list: List(a),
- fun: fn(Int, a) -> b,
- index: Int,
- acc: List(b),
-) -> List(b) {
- case list {
- [] -> reverse(acc)
- [x, ..xs] -> {
- let acc = [fun(index, x), ..acc]
- do_index_map(xs, fun, index + 1, acc)
- }
- }
-}
-
-/// Returns a new list containing only the elements of the first list after the
-/// function has been applied to each one and their index.
-///
-/// The index starts at 0, so the first element is 0, the second is 1, and so
-/// on.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > index_map(["a", "b"], fn(i, x) { #(i, x) })
-/// [#(0, "a"), #(1, "b")]
-/// ```
-///
-pub fn index_map(list: List(a), with fun: fn(Int, a) -> b) -> List(b) {
- do_index_map(list, fun, 0, [])
-}
-
-fn do_try_map(
- list: List(a),
- fun: fn(a) -> Result(b, e),
- acc: List(b),
-) -> Result(List(b), e) {
- case list {
- [] -> Ok(reverse(acc))
- [x, ..xs] ->
- case fun(x) {
- Ok(y) -> do_try_map(xs, fun, [y, ..acc])
- Error(error) -> Error(error)
- }
- }
-}
-
-/// Takes a function that returns a `Result` and applies it to each element in a
-/// given list in turn.
-///
-/// If the function returns `Ok(new_value)` for all elements in the list then a
-/// list of the new values is returned.
-///
-/// If the function returns `Error(reason)` for any of the elements then it is
-/// returned immediately. None of the elements in the list are processed after
-/// one returns an `Error`.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > try_map([1, 2, 3], fn(x) { Ok(x + 2) })
-/// Ok([3, 4, 5])
-/// ```
-///
-/// ```gleam
-/// > try_map([1, 2, 3], fn(_) { Error(0) })
-/// Error(0)
-/// ```
-///
-/// ```gleam
-/// > try_map([[1], [2, 3]], first)
-/// Ok([1, 2])
-/// ```
-///
-/// ```gleam
-/// > try_map([[1], [], [2]], first)
-/// Error(Nil)
-/// ```
-///
-pub fn try_map(
- over list: List(a),
- with fun: fn(a) -> Result(b, e),
-) -> Result(List(b), e) {
- do_try_map(list, fun, [])
-}
-
-/// Returns a list that is the given list with up to the given number of
-/// elements removed from the front of the list.
-///
-/// If the element has less than the number of elements an empty list is
-/// returned.
-///
-/// This function runs in linear time but does not copy the list.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > drop([1, 2, 3, 4], 2)
-/// [3, 4]
-/// ```
-///
-/// ```gleam
-/// > drop([1, 2, 3, 4], 9)
-/// []
-/// ```
-///
-pub fn drop(from list: List(a), up_to n: Int) -> List(a) {
- case n <= 0 {
- True -> list
- False ->
- case list {
- [] -> []
- [_, ..xs] -> drop(xs, n - 1)
- }
- }
-}
-
-fn do_take(list: List(a), n: Int, acc: List(a)) -> List(a) {
- case n <= 0 {
- True -> reverse(acc)
- False ->
- case list {
- [] -> reverse(acc)
- [x, ..xs] -> do_take(xs, n - 1, [x, ..acc])
- }
- }
-}
-
-/// Returns a list containing the first given number of elements from the given
-/// list.
-///
-/// If the element has less than the number of elements then the full list is
-/// returned.
-///
-/// This function runs in linear time but does not copy the list.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > take([1, 2, 3, 4], 2)
-/// [1, 2]
-/// ```
-///
-/// ```gleam
-/// > take([1, 2, 3, 4], 9)
-/// [1, 2, 3, 4]
-/// ```
-///
-pub fn take(from list: List(a), up_to n: Int) -> List(a) {
- do_take(list, n, [])
-}
-
-/// Returns a new empty list.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > new()
-/// []
-/// ```
-///
-pub fn new() -> List(a) {
- []
-}
-
-/// Joins one list onto the end of another.
-///
-/// This function runs in linear time, and it traverses and copies the first
-/// list.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > append([1, 2], [3])
-/// [1, 2, 3]
-/// ```
-///
-pub fn append(first: List(a), second: List(a)) -> List(a) {
- do_append(first, second)
-}
-
-@target(erlang)
-@external(erlang, "lists", "append")
-fn do_append(a: List(a), b: List(a)) -> List(a)
-
-@target(javascript)
-fn do_append(first: List(a), second: List(a)) -> List(a) {
- do_append_acc(reverse(first), second)
-}
-
-@target(javascript)
-fn do_append_acc(first: List(a), second: List(a)) -> List(a) {
- case first {
- [] -> second
- [item, ..rest] -> do_append_acc(rest, [item, ..second])
- }
-}
-
-/// Prefixes an item to a list. This can also be done using the dedicated
-/// syntax instead
-///
-/// ```gleam
-/// let new_list = [1, ..existing_list]
-/// ```
-///
-pub fn prepend(to list: List(a), this item: a) -> List(a) {
- [item, ..list]
-}
-
-// Reverses a list and prepends it to another list
-fn reverse_and_prepend(list prefix: List(a), to suffix: List(a)) -> List(a) {
- case prefix {
- [] -> suffix
- [first, ..rest] -> reverse_and_prepend(list: rest, to: [first, ..suffix])
- }
-}
-
-fn do_concat(lists: List(List(a)), acc: List(a)) -> List(a) {
- case lists {
- [] -> reverse(acc)
- [list, ..further_lists] ->
- do_concat(further_lists, reverse_and_prepend(list: list, to: acc))
- }
-}
-
-/// Joins a list of lists into a single list.
-///
-/// This function traverses all elements twice.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > concat([[1], [2, 3], []])
-/// [1, 2, 3]
-/// ```
-///
-pub fn concat(lists: List(List(a))) -> List(a) {
- do_concat(lists, [])
-}
-
-/// This is the same as `concat`: it joins a list of lists into a single
-/// list.
-///
-/// This function traverses all elements twice.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > flatten([[1], [2, 3], []])
-/// [1, 2, 3]
-/// ```
-///
-pub fn flatten(lists: List(List(a))) -> List(a) {
- do_concat(lists, [])
-}
-
-/// Maps the list with the given function into a list of lists, and then flattens it.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > flat_map([2, 4, 6], fn(x) { [x, x + 1] })
-/// [2, 3, 4, 5, 6, 7]
-/// ```
-///
-pub fn flat_map(over list: List(a), with fun: fn(a) -> List(b)) -> List(b) {
- map(list, fun)
- |> concat
-}
-
-/// Reduces a list of elements into a single value by calling a given function
-/// on each element, going from left to right.
-///
-/// `fold([1, 2, 3], 0, add)` is the equivalent of
-/// `add(add(add(0, 1), 2), 3)`.
-///
-/// This function runs in linear time.
-///
-pub fn fold(
- over list: List(a),
- from initial: acc,
- with fun: fn(acc, a) -> acc,
-) -> acc {
- case list {
- [] -> initial
- [x, ..rest] -> fold(rest, fun(initial, x), fun)
- }
-}
-
-/// Reduces a list of elements into a single value by calling a given function
-/// on each element, going from right to left.
-///
-/// `fold_right([1, 2, 3], 0, add)` is the equivalent of
-/// `add(add(add(0, 3), 2), 1)`.
-///
-/// This function runs in linear time.
-///
-/// Unlike `fold` this function is not tail recursive. Where possible use
-/// `fold` instead as it will use less memory.
-///
-pub fn fold_right(
- over list: List(a),
- from initial: acc,
- with fun: fn(acc, a) -> acc,
-) -> acc {
- case list {
- [] -> initial
- [x, ..rest] -> fun(fold_right(rest, initial, fun), x)
- }
-}
-
-fn do_index_fold(
- over: List(a),
- acc: acc,
- with: fn(acc, a, Int) -> acc,
- index: Int,
-) -> acc {
- case over {
- [] -> acc
- [first, ..rest] ->
- do_index_fold(rest, with(acc, first, index), with, index + 1)
- }
-}
-
-/// Like fold but the folding function also receives the index of the current element.
-///
-/// ## Examples
-///
-/// ```gleam
-/// ["a", "b", "c"]
-/// |> index_fold([], fn(acc, item, index) { ... })
-/// ```
-///
-pub fn index_fold(
- over over: List(a),
- from initial: acc,
- with fun: fn(acc, a, Int) -> acc,
-) -> acc {
- do_index_fold(over, initial, fun, 0)
-}
-
-/// A variant of fold that might fail.
-///
-/// The folding function should return `Result(accumulator, error)`.
-/// If the returned value is `Ok(accumulator)` try_fold will try the next value in the list.
-/// If the returned value is `Error(error)` try_fold will stop and return that error.
-///
-/// ## Examples
-///
-/// ```gleam
-/// [1, 2, 3, 4]
-/// |> try_fold(0, fn(acc, i) {
-/// case i < 3 {
-/// True -> Ok(acc + i)
-/// False -> Error(Nil)
-/// }
-/// })
-/// ```
-///
-pub fn try_fold(
- over collection: List(a),
- from accumulator: acc,
- with fun: fn(acc, a) -> Result(acc, e),
-) -> Result(acc, e) {
- case collection {
- [] -> Ok(accumulator)
- [first, ..rest] ->
- case fun(accumulator, first) {
- Ok(result) -> try_fold(rest, result, fun)
- Error(_) as error -> error
- }
- }
-}
-
-pub type ContinueOrStop(a) {
- Continue(a)
- Stop(a)
-}
-
-/// A variant of fold that allows to stop folding earlier.
-///
-/// The folding function should return `ContinueOrStop(accumulator)`.
-/// If the returned value is `Continue(accumulator)` fold_until will try the next value in the list.
-/// If the returned value is `Stop(accumulator)` fold_until will stop and return that accumulator.
-///
-/// ## Examples
-///
-/// ```gleam
-/// [1, 2, 3, 4]
-/// |> fold_until(0, fn(acc, i) {
-/// case i < 3 {
-/// True -> Continue(acc + i)
-/// False -> Stop(acc)
-/// }
-/// })
-/// ```
-///
-pub fn fold_until(
- over collection: List(a),
- from accumulator: acc,
- with fun: fn(acc, a) -> ContinueOrStop(acc),
-) -> acc {
- case collection {
- [] -> accumulator
- [first, ..rest] ->
- case fun(accumulator, first) {
- Continue(next_accumulator) -> fold_until(rest, next_accumulator, fun)
- Stop(b) -> b
- }
- }
-}
-
-/// Finds the first element in a given list for which the given function returns
-/// `True`.
-///
-/// Returns `Error(Nil)` if no such element is found.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > find([1, 2, 3], fn(x) { x > 2 })
-/// Ok(3)
-/// ```
-///
-/// ```gleam
-/// > find([1, 2, 3], fn(x) { x > 4 })
-/// Error(Nil)
-/// ```
-///
-/// ```gleam
-/// > find([], fn(_) { True })
-/// Error(Nil)
-/// ```
-///
-pub fn find(
- in haystack: List(a),
- one_that is_desired: fn(a) -> Bool,
-) -> Result(a, Nil) {
- case haystack {
- [] -> Error(Nil)
- [x, ..rest] ->
- case is_desired(x) {
- True -> Ok(x)
- _ -> find(in: rest, one_that: is_desired)
- }
- }
-}
-
-/// Finds the first element in a given list for which the given function returns
-/// `Ok(new_value)`, then returns the wrapped `new_value`.
-///
-/// Returns `Error(Nil)` if no such element is found.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > find_map([[], [2], [3]], first)
-/// Ok(2)
-/// ```
-///
-/// ```gleam
-/// > find_map([[], []], first)
-/// Error(Nil)
-/// ```
-///
-/// ```gleam
-/// > find_map([], first)
-/// Error(Nil)
-/// ```
-///
-pub fn find_map(
- in haystack: List(a),
- with fun: fn(a) -> Result(b, c),
-) -> Result(b, Nil) {
- case haystack {
- [] -> Error(Nil)
- [x, ..rest] ->
- case fun(x) {
- Ok(x) -> Ok(x)
- _ -> find_map(in: rest, with: fun)
- }
- }
-}
-
-/// Returns `True` if the given function returns `True` for all the elements in
-/// the given list. If the function returns `False` for any of the elements it
-/// immediately returns `False` without checking the rest of the list.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > all([], fn(x) { x > 3 })
-/// True
-/// ```
-///
-/// ```gleam
-/// > all([4, 5], fn(x) { x > 3 })
-/// True
-/// ```
-///
-/// ```gleam
-/// > all([4, 3], fn(x) { x > 3 })
-/// False
-/// ```
-///
-pub fn all(in list: List(a), satisfying predicate: fn(a) -> Bool) -> Bool {
- case list {
- [] -> True
- [first, ..rest] ->
- case predicate(first) {
- True -> all(rest, predicate)
- False -> False
- }
- }
-}
-
-/// Returns `True` if the given function returns `True` for any the elements in
-/// the given list. If the function returns `True` for any of the elements it
-/// immediately returns `True` without checking the rest of the list.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > any([], fn(x) { x > 3 })
-/// False
-/// ```
-///
-/// ```gleam
-/// > any([4, 5], fn(x) { x > 3 })
-/// True
-/// ```
-///
-/// ```gleam
-/// > any([4, 3], fn(x) { x > 4 })
-/// False
-/// ```
-///
-/// ```gleam
-/// > any([3, 4], fn(x) { x > 3 })
-/// True
-/// ```
-///
-pub fn any(in list: List(a), satisfying predicate: fn(a) -> Bool) -> Bool {
- case list {
- [] -> False
- [first, ..rest] ->
- case predicate(first) {
- True -> True
- False -> any(rest, predicate)
- }
- }
-}
-
-fn do_zip(xs: List(a), ys: List(b), acc: List(#(a, b))) -> List(#(a, b)) {
- case xs, ys {
- [x, ..xs], [y, ..ys] -> do_zip(xs, ys, [#(x, y), ..acc])
- _, _ -> reverse(acc)
- }
-}
-
-/// Takes two lists and returns a single list of 2-element tuples.
-///
-/// If one of the lists is longer than the other, the remaining elements from
-/// the longer list are not used.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > zip([], [])
-/// []
-/// ```
-///
-/// ```gleam
-/// > zip([1, 2], [3])
-/// [#(1, 3)]
-/// ```
-///
-/// ```gleam
-/// > zip([1], [3, 4])
-/// [#(1, 3)]
-/// ```
-///
-/// ```gleam
-/// > zip([1, 2], [3, 4])
-/// [#(1, 3), #(2, 4)]
-/// ```
-///
-pub fn zip(list: List(a), with other: List(b)) -> List(#(a, b)) {
- do_zip(list, other, [])
-}
-
-/// Takes two lists and returns a single list of 2-element tuples.
-///
-/// If one of the lists is longer than the other, an `Error` is returned.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > strict_zip([], [])
-/// Ok([])
-/// ```
-///
-/// ```gleam
-/// > strict_zip([1, 2], [3])
-/// Error(LengthMismatch)
-/// ```
-///
-/// ```gleam
-/// > strict_zip([1], [3, 4])
-/// Error(LengthMismatch)
-/// ```
-///
-/// ```gleam
-/// > strict_zip([1, 2], [3, 4])
-/// Ok([#(1, 3), #(2, 4)])
-/// ```
-///
-pub fn strict_zip(
- list: List(a),
- with other: List(b),
-) -> Result(List(#(a, b)), LengthMismatch) {
- case length(of: list) == length(of: other) {
- True -> Ok(zip(list, other))
- False -> Error(LengthMismatch)
- }
-}
-
-fn do_unzip(input, xs, ys) {
- case input {
- [] -> #(reverse(xs), reverse(ys))
- [#(x, y), ..rest] -> do_unzip(rest, [x, ..xs], [y, ..ys])
- }
-}
-
-/// Takes a single list of 2-element tuples and returns two lists.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > unzip([#(1, 2), #(3, 4)])
-/// #([1, 3], [2, 4])
-/// ```
-///
-/// ```gleam
-/// > unzip([])
-/// #([], [])
-/// ```
-///
-pub fn unzip(input: List(#(a, b))) -> #(List(a), List(b)) {
- do_unzip(input, [], [])
-}
-
-fn do_intersperse(list: List(a), separator: a, acc: List(a)) -> List(a) {
- case list {
- [] -> reverse(acc)
- [x, ..rest] -> do_intersperse(rest, separator, [x, separator, ..acc])
- }
-}
-
-/// Inserts a given value between each existing element in a given list.
-///
-/// This function runs in linear time and copies the list.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > intersperse([1, 1, 1], 2)
-/// [1, 2, 1, 2, 1]
-/// ```
-///
-/// ```gleam
-/// > intersperse([], 2)
-/// []
-/// ```
-///
-pub fn intersperse(list: List(a), with elem: a) -> List(a) {
- case list {
- [] | [_] -> list
- [x, ..rest] -> do_intersperse(rest, elem, [x])
- }
-}
-
-/// Returns the element in the Nth position in the list, with 0 being the first
-/// position.
-///
-/// `Error(Nil)` is returned if the list is not long enough for the given index
-/// or if the index is less than 0.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > at([1, 2, 3], 1)
-/// Ok(2)
-/// ```
-///
-/// ```gleam
-/// > at([1, 2, 3], 5)
-/// Error(Nil)
-/// ```
-///
-pub fn at(in list: List(a), get index: Int) -> Result(a, Nil) {
- case index >= 0 {
- True ->
- list
- |> drop(index)
- |> first
- False -> Error(Nil)
- }
-}
-
-/// Removes any duplicate elements from a given list.
-///
-/// This function returns in loglinear time.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > unique([1, 1, 1, 4, 7, 3, 3, 4])
-/// [1, 4, 7, 3]
-/// ```
-///
-pub fn unique(list: List(a)) -> List(a) {
- case list {
- [] -> []
- [x, ..rest] -> [x, ..unique(filter(rest, fn(y) { y != x }))]
- }
-}
-
-/// Merge lists `a` and `b` in ascending order
-/// but only up to `na` and `nb` number of items respectively.
-///
-fn merge_up(
- na: Int,
- nb: Int,
- a: List(a),
- b: List(a),
- acc: List(a),
- compare: fn(a, a) -> Order,
-) {
- case na, nb, a, b {
- 0, 0, _, _ -> acc
- _, 0, [ax, ..ar], _ -> merge_up(na - 1, nb, ar, b, [ax, ..acc], compare)
- 0, _, _, [bx, ..br] -> merge_up(na, nb - 1, a, br, [bx, ..acc], compare)
- _, _, [ax, ..ar], [bx, ..br] ->
- case compare(ax, bx) {
- order.Gt -> merge_up(na, nb - 1, a, br, [bx, ..acc], compare)
- _ -> merge_up(na - 1, nb, ar, b, [ax, ..acc], compare)
- }
- _, _, _, _ -> acc
- }
-}
-
-/// Merge lists `a` and `b` in descending order
-/// but only up to `na` and `nb` number of items respectively.
-///
-fn merge_down(
- na: Int,
- nb: Int,
- a: List(a),
- b: List(a),
- acc: List(a),
- compare: fn(a, a) -> Order,
-) {
- case na, nb, a, b {
- 0, 0, _, _ -> acc
- _, 0, [ax, ..ar], _ -> merge_down(na - 1, nb, ar, b, [ax, ..acc], compare)
- 0, _, _, [bx, ..br] -> merge_down(na, nb - 1, a, br, [bx, ..acc], compare)
- _, _, [ax, ..ar], [bx, ..br] ->
- case compare(bx, ax) {
- order.Lt -> merge_down(na - 1, nb, ar, b, [ax, ..acc], compare)
- _ -> merge_down(na, nb - 1, a, br, [bx, ..acc], compare)
- }
- _, _, _, _ -> acc
- }
-}
-
-/// Merge sort that alternates merging in ascending and descending order
-/// because the merge process also reverses the list.
-///
-/// Some copying is avoided by merging only a subset of the lists
-/// instead of creating and merging new smaller lists.
-///
-fn merge_sort(
- l: List(a),
- ln: Int,
- compare: fn(a, a) -> Order,
- down: Bool,
-) -> List(a) {
- let n = ln / 2
- let a = l
- let b = drop(l, n)
- case ln < 3 {
- True ->
- case down {
- True -> merge_down(n, ln - n, a, b, [], compare)
- False -> merge_up(n, ln - n, a, b, [], compare)
- }
- False ->
- case down {
- True ->
- merge_down(
- n,
- ln - n,
- merge_sort(a, n, compare, False),
- merge_sort(b, ln - n, compare, False),
- [],
- compare,
- )
- False ->
- merge_up(
- n,
- ln - n,
- merge_sort(a, n, compare, True),
- merge_sort(b, ln - n, compare, True),
- [],
- compare,
- )
- }
- }
-}
-
-/// Sorts from smallest to largest based upon the ordering specified by a given
-/// function.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > import gleam/int
-/// > list.sort([4, 3, 6, 5, 4, 1, 2], by: int.compare)
-/// [1, 2, 3, 4, 4, 5, 6]
-/// ```
-///
-pub fn sort(list: List(a), by compare: fn(a, a) -> Order) -> List(a) {
- merge_sort(list, length(list), compare, True)
-}
-
-/// Creates a list of ints ranging from a given start and finish.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > range(0, 0)
-/// [0]
-/// ```
-///
-/// ```gleam
-/// > range(0, 5)
-/// [0, 1, 2, 3, 4, 5]
-/// ```
-///
-/// ```gleam
-/// > range(1, -5)
-/// [1, 0, -1, -2, -3, -4, -5]
-/// ```
-///
-pub fn range(from start: Int, to stop: Int) -> List(Int) {
- tail_recursive_range(start, stop, [])
-}
-
-fn tail_recursive_range(start: Int, stop: Int, acc: List(Int)) -> List(Int) {
- case int.compare(start, stop) {
- order.Eq -> [stop, ..acc]
- order.Gt -> tail_recursive_range(start, stop + 1, [stop, ..acc])
- order.Lt -> tail_recursive_range(start, stop - 1, [stop, ..acc])
- }
-}
-
-fn do_repeat(a: a, times: Int, acc: List(a)) -> List(a) {
- case times <= 0 {
- True -> acc
- False -> do_repeat(a, times - 1, [a, ..acc])
- }
-}
-
-/// Builds a list of a given value a given number of times.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > repeat("a", times: 0)
-/// []
-/// ```
-///
-/// ```gleam
-/// > repeat("a", times: 5)
-/// ["a", "a", "a", "a", "a"]
-/// ```
-///
-pub fn repeat(item a: a, times times: Int) -> List(a) {
- do_repeat(a, times, [])
-}
-
-fn do_split(list: List(a), n: Int, taken: List(a)) -> #(List(a), List(a)) {
- case n <= 0 {
- True -> #(reverse(taken), list)
- False ->
- case list {
- [] -> #(reverse(taken), [])
- [x, ..xs] -> do_split(xs, n - 1, [x, ..taken])
- }
- }
-}
-
-/// Splits a list in two before the given index.
-///
-/// If the list is not long enough to have the given index the before list will
-/// be the input list, and the after list will be empty.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > split([6, 7, 8, 9], 0)
-/// #([], [6, 7, 8, 9])
-/// ```
-///
-/// ```gleam
-/// > split([6, 7, 8, 9], 2)
-/// #([6, 7], [8, 9])
-/// ```
-///
-/// ```gleam
-/// > split([6, 7, 8, 9], 4)
-/// #([6, 7, 8, 9], [])
-/// ```
-///
-pub fn split(list list: List(a), at index: Int) -> #(List(a), List(a)) {
- do_split(list, index, [])
-}
-
-fn do_split_while(
- list: List(a),
- f: fn(a) -> Bool,
- acc: List(a),
-) -> #(List(a), List(a)) {
- case list {
- [] -> #(reverse(acc), [])
- [x, ..xs] ->
- case f(x) {
- False -> #(reverse(acc), list)
- _ -> do_split_while(xs, f, [x, ..acc])
- }
- }
-}
-
-/// Splits a list in two before the first element that a given function returns
-/// `False` for.
-///
-/// If the function returns `True` for all elements the first list will be the
-/// input list, and the second list will be empty.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > split_while([1, 2, 3, 4, 5], fn(x) { x <= 3 })
-/// #([1, 2, 3], [4, 5])
-/// ```
-///
-/// ```gleam
-/// > split_while([1, 2, 3, 4, 5], fn(x) { x <= 5 })
-/// #([1, 2, 3, 4, 5], [])
-/// ```
-///
-pub fn split_while(
- list list: List(a),
- satisfying predicate: fn(a) -> Bool,
-) -> #(List(a), List(a)) {
- do_split_while(list, predicate, [])
-}
-
-/// Given a list of 2-element tuples, finds the first tuple that has a given
-/// key as the first element and returns the second element.
-///
-/// If no tuple is found with the given key then `Error(Nil)` is returned.
-///
-/// This function may be useful for interacting with Erlang code where lists of
-/// tuples are common.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > key_find([#("a", 0), #("b", 1)], "a")
-/// Ok(0)
-/// ```
-///
-/// ```gleam
-/// > key_find([#("a", 0), #("b", 1)], "b")
-/// Ok(1)
-/// ```
-///
-/// ```gleam
-/// > key_find([#("a", 0), #("b", 1)], "c")
-/// Error(Nil)
-/// ```
-///
-pub fn key_find(
- in keyword_list: List(#(k, v)),
- find desired_key: k,
-) -> Result(v, Nil) {
- find_map(
- keyword_list,
- fn(keyword) {
- let #(key, value) = keyword
- case key == desired_key {
- True -> Ok(value)
- False -> Error(Nil)
- }
- },
- )
-}
-
-/// Given a list of 2-element tuples, finds all tuples that have a given
-/// key as the first element and returns the second element.
-///
-/// This function may be useful for interacting with Erlang code where lists of
-/// tuples are common.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > key_filter([#("a", 0), #("b", 1), #("a", 2)], "a")
-/// [0, 2]
-/// ```
-///
-/// ```gleam
-/// > key_filter([#("a", 0), #("b", 1)], "c")
-/// []
-/// ```
-///
-pub fn key_filter(
- in keyword_list: List(#(k, v)),
- find desired_key: k,
-) -> List(v) {
- filter_map(
- keyword_list,
- fn(keyword) {
- let #(key, value) = keyword
- case key == desired_key {
- True -> Ok(value)
- False -> Error(Nil)
- }
- },
- )
-}
-
-fn do_pop(haystack, predicate, checked) {
- case haystack {
- [] -> Error(Nil)
- [x, ..rest] ->
- case predicate(x) {
- True -> Ok(#(x, append(reverse(checked), rest)))
- False -> do_pop(rest, predicate, [x, ..checked])
- }
- }
-}
-
-/// Removes the first element in a given list for which the predicate function returns `True`.
-///
-/// Returns `Error(Nil)` if no such element is found.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > pop([1, 2, 3], fn(x) { x > 2 })
-/// Ok(#(3, [1, 2]))
-/// ```
-///
-/// ```gleam
-/// > pop([1, 2, 3], fn(x) { x > 4 })
-/// Error(Nil)
-/// ```
-///
-/// ```gleam
-/// > pop([], fn(_) { True })
-/// Error(Nil)
-/// ```
-///
-pub fn pop(
- in haystack: List(a),
- one_that is_desired: fn(a) -> Bool,
-) -> Result(#(a, List(a)), Nil) {
- do_pop(haystack, is_desired, [])
-}
-
-fn do_pop_map(haystack, mapper, checked) {
- case haystack {
- [] -> Error(Nil)
- [x, ..rest] ->
- case mapper(x) {
- Ok(y) -> Ok(#(y, append(reverse(checked), rest)))
- Error(_) -> do_pop_map(rest, mapper, [x, ..checked])
- }
- }
-}
-
-/// Removes the first element in a given list for which the given function returns
-/// `Ok(new_value)`, then returns the wrapped `new_value` as well as list with the value removed.
-///
-/// Returns `Error(Nil)` if no such element is found.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > pop_map([[], [2], [3]], first)
-/// Ok(#(2, [[], [3]]))
-/// ```
-///
-/// ```gleam
-/// > pop_map([[], []], first)
-/// Error(Nil)
-/// ```
-///
-/// ```gleam
-/// > pop_map([], first)
-/// Error(Nil)
-/// ```
-///
-pub fn pop_map(
- in haystack: List(a),
- one_that is_desired: fn(a) -> Result(b, c),
-) -> Result(#(b, List(a)), Nil) {
- do_pop_map(haystack, is_desired, [])
-}
-
-/// Given a list of 2-element tuples, finds the first tuple that has a given
-/// key as the first element. This function will return the second element
-/// of the found tuple and list with tuple removed.
-///
-/// If no tuple is found with the given key then `Error(Nil)` is returned.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > key_pop([#("a", 0), #("b", 1)], "a")
-/// Ok(#(0, [#("b", 1)]))
-/// ```
-///
-/// ```gleam
-/// > key_pop([#("a", 0), #("b", 1)], "b")
-/// Ok(#(1, [#("a", 0)]))
-/// ```
-///
-/// ```gleam
-/// > key_pop([#("a", 0), #("b", 1)], "c")
-/// Error(Nil)
-/// ```
-///
-pub fn key_pop(
- haystack: List(#(k, v)),
- key: k,
-) -> Result(#(v, List(#(k, v))), Nil) {
- pop_map(
- haystack,
- fn(entry) {
- let #(k, v) = entry
- case k {
- k if k == key -> Ok(v)
- _ -> Error(Nil)
- }
- },
- )
-}
-
-/// Given a list of 2-element tuples, inserts a key and value into the list.
-///
-/// If there was already a tuple with the key then it is replaced, otherwise it
-/// is added to the end of the list.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > key_set([#(5, 0), #(4, 1)], 4, 100)
-/// [#(5, 0), #(4, 100)]
-/// ```
-///
-/// ```gleam
-/// > key_set([#(5, 0), #(4, 1)], 1, 100)
-/// [#(5, 0), #(4, 1), #(1, 100)]
-/// ```
-///
-pub fn key_set(list: List(#(a, b)), key: a, value: b) -> List(#(a, b)) {
- case list {
- [] -> [#(key, value)]
- [#(k, _), ..rest] if k == key -> [#(key, value), ..rest]
- [first, ..rest] -> [first, ..key_set(rest, key, value)]
- }
-}
-
-/// Calls a function for each element in a list, discarding the return value.
-///
-/// Useful for calling a side effect for every item of a list.
-///
-/// ```gleam
-/// > list.each([1, 2, 3], io.println)
-/// Nil
-/// ```
-///
-pub fn each(list: List(a), f: fn(a) -> b) -> Nil {
- case list {
- [] -> Nil
- [x, ..xs] -> {
- f(x)
- each(xs, f)
- }
- }
-}
-
-/// Calls a `Result` returning function for each element in a list, discarding
-/// the return value. If the function returns `Error` then the iteration is
-/// stopped and the error is returned.
-///
-/// Useful for calling a side effect for every item of a list.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > try_each(
-/// > over: [1, 2, 3],
-/// > with: function_that_might_fail,
-/// > )
-/// Ok(Nil)
-/// ```
-///
-pub fn try_each(
- over list: List(a),
- with fun: fn(a) -> Result(b, e),
-) -> Result(Nil, e) {
- case list {
- [] -> Ok(Nil)
- [x, ..xs] ->
- case fun(x) {
- Ok(_) -> try_each(over: xs, with: fun)
- Error(e) -> Error(e)
- }
- }
-}
-
-fn do_partition(list, categorise, trues, falses) {
- case list {
- [] -> #(reverse(trues), reverse(falses))
- [x, ..xs] ->
- case categorise(x) {
- True -> do_partition(xs, categorise, [x, ..trues], falses)
- False -> do_partition(xs, categorise, trues, [x, ..falses])
- }
- }
-}
-
-/// Partitions a list into a tuple/pair of lists
-/// by a given categorisation function.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > [1, 2, 3, 4, 5] |> list.partition(int.is_odd)
-/// #([1, 3, 5], [2, 4])
-/// ```
-///
-pub fn partition(
- list: List(a),
- with categorise: fn(a) -> Bool,
-) -> #(List(a), List(a)) {
- do_partition(list, categorise, [], [])
-}
-
-/// Returns all the permutations of a list.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > permutations([1, 2])
-/// [[1, 2], [2, 1]]
-/// ```
-///
-pub fn permutations(l: List(a)) -> List(List(a)) {
- case l {
- [] -> [[]]
- _ ->
- l
- |> index_map(fn(i_idx, i) {
- l
- |> index_fold(
- [],
- fn(acc, j, j_idx) {
- case i_idx == j_idx {
- True -> acc
- False -> [j, ..acc]
- }
- },
- )
- |> reverse
- |> permutations
- |> map(fn(permutation) { [i, ..permutation] })
- })
- |> concat
- }
-}
-
-fn do_window(acc: List(List(a)), l: List(a), n: Int) -> List(List(a)) {
- let window = take(l, n)
-
- case length(window) == n {
- True -> do_window([window, ..acc], drop(l, 1), n)
- False -> acc
- }
-}
-
-/// Returns a list of sliding windows.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > window([1,2,3,4,5], 3)
-/// [[1, 2, 3], [2, 3, 4], [3, 4, 5]]
-/// ```
-///
-/// ```gleam
-/// > window([1, 2], 4)
-/// []
-/// ```
-///
-pub fn window(l: List(a), by n: Int) -> List(List(a)) {
- do_window([], l, n)
- |> reverse
-}
-
-/// Returns a list of tuples containing two contiguous elements.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > window_by_2([1,2,3,4])
-/// [#(1, 2), #(2, 3), #(3, 4)]
-/// ```
-///
-/// ```gleam
-/// > window_by_2([1])
-/// []
-/// ```
-///
-pub fn window_by_2(l: List(a)) -> List(#(a, a)) {
- zip(l, drop(l, 1))
-}
-
-/// Drops the first elements in a given list for which the predicate function returns `True`.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > drop_while([1, 2, 3, 4], fn (x) { x < 3 })
-/// [3, 4]
-/// ```
-///
-pub fn drop_while(
- in list: List(a),
- satisfying predicate: fn(a) -> Bool,
-) -> List(a) {
- case list {
- [] -> []
- [x, ..xs] ->
- case predicate(x) {
- True -> drop_while(xs, predicate)
- False -> [x, ..xs]
- }
- }
-}
-
-fn do_take_while(
- list: List(a),
- predicate: fn(a) -> Bool,
- acc: List(a),
-) -> List(a) {
- case list {
- [] -> reverse(acc)
- [first, ..rest] ->
- case predicate(first) {
- True -> do_take_while(rest, predicate, [first, ..acc])
- False -> reverse(acc)
- }
- }
-}
-
-/// Takes the first elements in a given list for which the predicate function returns `True`.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > take_while([1, 2, 3, 2, 4], fn (x) { x < 3 })
-/// [1, 2]
-/// ```
-///
-pub fn take_while(
- in list: List(a),
- satisfying predicate: fn(a) -> Bool,
-) -> List(a) {
- do_take_while(list, predicate, [])
-}
-
-fn do_chunk(
- list: List(a),
- f: fn(a) -> key,
- previous_key: key,
- current_chunk: List(a),
- acc: List(List(a)),
-) -> List(List(a)) {
- case list {
- [first, ..rest] -> {
- let key = f(first)
- case key == previous_key {
- False -> {
- let new_acc = [reverse(current_chunk), ..acc]
- do_chunk(rest, f, key, [first], new_acc)
- }
- _true -> do_chunk(rest, f, key, [first, ..current_chunk], acc)
- }
- }
- _empty -> reverse([reverse(current_chunk), ..acc])
- }
-}
-
-/// Returns a list of chunks in which
-/// the return value of calling `f` on each element is the same.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > [1, 2, 2, 3, 4, 4, 6, 7, 7] |> chunk(by: fn(n) { n % 2 })
-/// [[1], [2, 2], [3], [4, 4, 6], [7, 7]]
-/// ```
-///
-pub fn chunk(in list: List(a), by f: fn(a) -> key) -> List(List(a)) {
- case list {
- [] -> []
- [first, ..rest] -> do_chunk(rest, f, f(first), [first], [])
- }
-}
-
-fn do_sized_chunk(
- list: List(a),
- count: Int,
- left: Int,
- current_chunk: List(a),
- acc: List(List(a)),
-) -> List(List(a)) {
- case list {
- [] ->
- case current_chunk {
- [] -> reverse(acc)
- remaining -> reverse([reverse(remaining), ..acc])
- }
- [first, ..rest] -> {
- let chunk = [first, ..current_chunk]
- case left > 1 {
- False -> do_sized_chunk(rest, count, count, [], [reverse(chunk), ..acc])
- True -> do_sized_chunk(rest, count, left - 1, chunk, acc)
- }
- }
- }
-}
-
-/// Returns a list of chunks containing `count` elements each.
-///
-/// If the last chunk does not have `count` elements, it is instead
-/// a partial chunk, with less than `count` elements.
-///
-/// For any `count` less than 1 this function behaves as if it was set to 1.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > [1, 2, 3, 4, 5, 6] |> sized_chunk(into: 2)
-/// [[1, 2], [3, 4], [5, 6]]
-/// ```
-///
-/// ```gleam
-/// > [1, 2, 3, 4, 5, 6, 7, 8] |> sized_chunk(into: 3)
-/// [[1, 2, 3], [4, 5, 6], [7, 8]]
-/// ```
-///
-pub fn sized_chunk(in list: List(a), into count: Int) -> List(List(a)) {
- do_sized_chunk(list, count, count, [], [])
-}
-
-/// This function acts similar to fold, but does not take an initial state.
-/// Instead, it starts from the first element in the list
-/// and combines it with each subsequent element in turn using the given
-/// function. The function is called as `fun(accumulator, current_element)`.
-///
-/// Returns `Ok` to indicate a successful run, and `Error` if called on an
-/// empty list.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > [] |> reduce(fn(acc, x) { acc + x })
-/// Error(Nil)
-/// ```
-///
-/// ```gleam
-/// > [1, 2, 3, 4, 5] |> reduce(fn(acc, x) { acc + x })
-/// Ok(15)
-/// ```
-///
-pub fn reduce(over list: List(a), with fun: fn(a, a) -> a) -> Result(a, Nil) {
- case list {
- [] -> Error(Nil)
- [first, ..rest] -> Ok(fold(rest, first, fun))
- }
-}
-
-fn do_scan(
- list: List(a),
- accumulator: acc,
- accumulated: List(acc),
- fun: fn(acc, a) -> acc,
-) -> List(acc) {
- case list {
- [] -> reverse(accumulated)
- [x, ..xs] -> {
- let next = fun(accumulator, x)
- do_scan(xs, next, [next, ..accumulated], fun)
- }
- }
-}
-
-/// Similar to `fold`, but yields the state of the accumulator at each stage.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > scan(over: [1, 2, 3], from: 100, with: fn(acc, i) { acc + i })
-/// [101, 103, 106]
-/// ```
-///
-pub fn scan(
- over list: List(a),
- from initial: acc,
- with fun: fn(acc, a) -> acc,
-) -> List(acc) {
- do_scan(list, initial, [], fun)
-}
-
-/// Returns the last element in the given list.
-///
-/// Returns `Error(Nil)` if the list is empty.
-///
-/// This function runs in linear time.
-/// For a collection oriented around performant access at either end,
-/// see `gleam/queue.Queue`.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > last([])
-/// Error(Nil)
-/// ```
-///
-/// ```gleam
-/// > last([1, 2, 3, 4, 5])
-/// Ok(5)
-/// ```
-///
-pub fn last(list: List(a)) -> Result(a, Nil) {
- list
- |> reduce(fn(_, elem) { elem })
-}
-
-/// Return unique combinations of elements in the list.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > combinations([1, 2, 3], 2)
-/// [[1, 2], [1, 3], [2, 3]]
-/// ```
-///
-/// ```gleam
-/// > combinations([1, 2, 3, 4], 3)
-/// [[1, 2, 3], [1, 2, 4], [1, 3, 4], [2, 3, 4]]
-/// ```
-///
-pub fn combinations(items: List(a), by n: Int) -> List(List(a)) {
- case n {
- 0 -> [[]]
- _ ->
- case items {
- [] -> []
- [x, ..xs] -> {
- let first_combinations =
- map(combinations(xs, n - 1), with: fn(com) { [x, ..com] })
- |> reverse
- fold(
- first_combinations,
- combinations(xs, n),
- fn(acc, c) { [c, ..acc] },
- )
- }
- }
- }
-}
-
-fn do_combination_pairs(items: List(a)) -> List(List(#(a, a))) {
- case items {
- [] -> []
- [x, ..xs] -> {
- let first_combinations = map(xs, with: fn(other) { #(x, other) })
- [first_combinations, ..do_combination_pairs(xs)]
- }
- }
-}
-
-/// Return unique pair combinations of elements in the list
-///
-/// ## Examples
-///
-/// ```gleam
-/// > combination_pairs([1, 2, 3])
-/// [#(1, 2), #(1, 3), #(2, 3)]
-/// ```
-///
-pub fn combination_pairs(items: List(a)) -> List(#(a, a)) {
- do_combination_pairs(items)
- |> concat
-}
-
-/// Make a list alternating the elements from the given lists
-///
-/// ## Examples
-///
-/// ```gleam
-/// > list.interleave([[1, 2], [101, 102], [201, 202]])
-/// [1, 101, 201, 2, 102, 202]
-/// ```
-///
-pub fn interleave(list: List(List(a))) -> List(a) {
- transpose(list)
- |> concat
-}
-
-/// Transpose rows and columns of the list of lists.
-///
-/// Notice: This function is not tail recursive,
-/// and thus may exceed stack size if called,
-/// with large lists (on target JavaScript).
-///
-/// ## Examples
-///
-/// ```gleam
-/// > transpose([[1, 2, 3], [101, 102, 103]])
-/// [[1, 101], [2, 102], [3, 103]]
-/// ```
-///
-pub fn transpose(list_of_list: List(List(a))) -> List(List(a)) {
- let take_first = fn(list) {
- case list {
- [] -> []
- [f] -> [f]
- [f, ..] -> [f]
- }
- }
-
- case list_of_list {
- [] -> []
- [[], ..xss] -> transpose(xss)
- rows -> {
- let firsts =
- rows
- |> map(take_first)
- |> concat
- let rest = transpose(map(rows, drop(_, 1)))
- [firsts, ..rest]
- }
- }
-}
-
-fn do_shuffle_pair_unwrap(list: List(#(Float, a)), acc: List(a)) -> List(a) {
- case list {
- [] -> acc
- [elem_pair, ..enumerable] ->
- do_shuffle_pair_unwrap(enumerable, [elem_pair.1, ..acc])
- }
-}
-
-fn do_shuffle_by_pair_indexes(
- list_of_pairs: List(#(Float, a)),
-) -> List(#(Float, a)) {
- sort(
- list_of_pairs,
- fn(a_pair: #(Float, a), b_pair: #(Float, a)) -> Order {
- float.compare(a_pair.0, b_pair.0)
- },
- )
-}
-
-/// Takes a list, randomly sorts all items and returns the shuffled list.
-///
-/// This function uses Erlang's `:rand` module or Javascript's
-/// `Math.random()` to calculate the index shuffling.
-///
-/// ## Example
-///
-/// ```gleam
-/// > range(1, 10)
-/// > |> shuffle()
-/// [1, 6, 9, 10, 3, 8, 4, 2, 7, 5]
-/// ```
-///
-pub fn shuffle(list: List(a)) -> List(a) {
- list
- |> fold(from: [], with: fn(acc, a) { [#(float.random(0.0, 1.0), a), ..acc] })
- |> do_shuffle_by_pair_indexes()
- |> do_shuffle_pair_unwrap([])
-}
diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam/map.gleam b/aoc2023/build/packages/gleam_stdlib/src/gleam/map.gleam
deleted file mode 100644
index 1f8b228..0000000
--- a/aoc2023/build/packages/gleam_stdlib/src/gleam/map.gleam
+++ /dev/null
@@ -1,127 +0,0 @@
-import gleam/option.{type Option}
-import gleam/dict
-
-@deprecated("Please use the `gleam/dict` module instead")
-pub type Map(key, value) =
- dict.Dict(key, value)
-
-@deprecated("Please use the `gleam/dict` module instead")
-pub fn size(map) -> Int {
- dict.size(map)
-}
-
-@deprecated("Please use the `gleam/dict` module instead")
-pub fn to_list(map) -> List(#(key, value)) {
- dict.to_list(map)
-}
-
-@deprecated("Please use the `gleam/dict` module instead")
-pub fn from_list(list: List(#(k, v))) {
- dict.from_list(list)
-}
-
-@deprecated("Please use the `gleam/dict` module instead")
-pub fn has_key(map, key: k) -> Bool {
- dict.has_key(map, key)
-}
-
-@deprecated("Please use the `gleam/dict` module instead")
-pub fn new() {
- dict.new()
-}
-
-@deprecated("Please use the `gleam/dict` module instead")
-pub fn get(from, get: key) -> Result(value, Nil) {
- dict.get(from, get)
-}
-
-@deprecated("Please use the `gleam/dict` module instead")
-pub fn insert(into map, for key: k, insert value: v) {
- dict.insert(map, key, value)
-}
-
-@deprecated("Please use the `gleam/dict` module instead")
-pub fn map_values(in map, with fun: fn(k, v) -> w) {
- dict.map_values(map, fun)
-}
-
-@deprecated("Please use the `gleam/dict` module instead")
-pub fn keys(map) -> List(keys) {
- dict.keys(map)
-}
-
-@target(javascript)
-fn reverse_and_concat(remaining, accumulator) {
- case remaining {
- [] -> accumulator
- [item, ..rest] -> reverse_and_concat(rest, [item, ..accumulator])
- }
-}
-
-@target(javascript)
-fn do_keys_acc(list: List(#(k, v)), acc: List(k)) -> List(k) {
- case list {
- [] -> reverse_and_concat(acc, [])
- [x, ..xs] -> do_keys_acc(xs, [x.0, ..acc])
- }
-}
-
-@target(javascript)
-fn do_keys(map) -> List(k) {
- let list_of_pairs =
- map
- |> to_list
- do_keys_acc(list_of_pairs, [])
-}
-
-@deprecated("Please use the `gleam/dict` module instead")
-pub fn values(map) -> List(values) {
- dict.values(map)
-}
-
-@deprecated("Please use the `gleam/dict` module instead")
-pub fn filter(in map, keeping predicate: fn(k, v) -> Bool) {
- dict.filter(map, predicate)
-}
-
-@target(javascript)
-fn do_filter(f: fn(key, value) -> Bool, map) {
- let insert = fn(map, k, v) {
- case f(k, v) {
- True -> insert(map, k, v)
- _ -> map
- }
- }
- map
- |> fold(from: new(), with: insert)
-}
-
-@deprecated("Please use the `gleam/dict` module instead")
-pub fn take(from map, keeping desired_keys: List(k)) {
- dict.take(map, desired_keys)
-}
-
-@deprecated("Please use the `gleam/dict` module instead")
-pub fn merge(into map, from new_entries) {
- dict.merge(map, new_entries)
-}
-
-@deprecated("Please use the `gleam/dict` module instead")
-pub fn delete(from map, delete key: k) {
- dict.delete(map, key)
-}
-
-@deprecated("Please use the `gleam/dict` module instead")
-pub fn drop(from map, drop disallowed_keys: List(k)) {
- dict.drop(map, disallowed_keys)
-}
-
-@deprecated("Please use the `gleam/dict` module instead")
-pub fn update(in map, update key: k, with fun: fn(Option(v)) -> v) {
- dict.update(map, key, fun)
-}
-
-@deprecated("Please use the `gleam/dict` module instead")
-pub fn fold(over map, from initial: acc, with fun: fn(acc, k, v) -> acc) -> acc {
- dict.fold(map, initial, fun)
-}
diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam/option.gleam b/aoc2023/build/packages/gleam_stdlib/src/gleam/option.gleam
deleted file mode 100644
index 6015c0f..0000000
--- a/aoc2023/build/packages/gleam_stdlib/src/gleam/option.gleam
+++ /dev/null
@@ -1,346 +0,0 @@
-/// `Option` represents a value that may be present or not. `Some` means the value is
-/// present, `None` means the value is not.
-///
-/// This is Gleam's alternative to having a value that could be Null, as is
-/// possible in some other languages.
-///
-pub type Option(a) {
- Some(a)
- None
-}
-
-fn do_all(list: List(Option(a)), acc: List(a)) -> Option(List(a)) {
- case list {
- [] -> Some(acc)
- [x, ..rest] -> {
- let accumulate = fn(acc, item) {
- case acc, item {
- Some(values), Some(value) -> Some([value, ..values])
- _, _ -> None
- }
- }
- accumulate(do_all(rest, acc), x)
- }
- }
-}
-
-/// Combines a list of `Option`s into a single `Option`.
-/// If all elements in the list are `Some` then returns a `Some` holding the list of values.
-/// If any element is `None` then returns`None`.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > all([Some(1), Some(2)])
-/// Some([1, 2])
-/// ```
-///
-/// ```gleam
-/// > all([Some(1), None])
-/// None
-/// ```
-///
-pub fn all(list: List(Option(a))) -> Option(List(a)) {
- do_all(list, [])
-}
-
-/// Checks whether the `Option` is a `Some` value.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > is_some(Some(1))
-/// True
-/// ```
-///
-/// ```gleam
-/// > is_some(None)
-/// False
-/// ```
-///
-pub fn is_some(option: Option(a)) -> Bool {
- option != None
-}
-
-/// Checks whether the `Option` is a `None` value.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > is_none(Some(1))
-/// False
-/// ```
-///
-/// ```gleam
-/// > is_none(None)
-/// True
-/// ```
-///
-pub fn is_none(option: Option(a)) -> Bool {
- option == None
-}
-
-/// Converts an `Option` type to a `Result` type.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > to_result(Some(1), "some_error")
-/// Ok(1)
-/// ```
-///
-/// ```gleam
-/// > to_result(None, "some_error")
-/// Error("some_error")
-/// ```
-///
-pub fn to_result(option: Option(a), e) -> Result(a, e) {
- case option {
- Some(a) -> Ok(a)
- _ -> Error(e)
- }
-}
-
-/// Converts a `Result` type to an `Option` type.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > from_result(Ok(1))
-/// Some(1)
-/// ```
-///
-/// ```gleam
-/// > from_result(Error("some_error"))
-/// None
-/// ```
-///
-pub fn from_result(result: Result(a, e)) -> Option(a) {
- case result {
- Ok(a) -> Some(a)
- _ -> None
- }
-}
-
-/// Extracts the value from an `Option`, returning a default value if there is none.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > unwrap(Some(1), 0)
-/// 1
-/// ```
-///
-/// ```gleam
-/// > unwrap(None, 0)
-/// 0
-/// ```
-///
-pub fn unwrap(option: Option(a), or default: a) -> a {
- case option {
- Some(x) -> x
- None -> default
- }
-}
-
-/// Extracts the value from an `Option`, evaluating the default function if the option is `None`.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > lazy_unwrap(Some(1), fn() { 0 })
-/// 1
-/// ```
-///
-/// ```gleam
-/// > lazy_unwrap(None, fn() { 0 })
-/// 0
-/// ```
-///
-pub fn lazy_unwrap(option: Option(a), or default: fn() -> a) -> a {
- case option {
- Some(x) -> x
- None -> default()
- }
-}
-
-/// Updates a value held within the `Some` of an `Option` by calling a given function
-/// on it.
-///
-/// If the `Option` is a `None` rather than `Some`, the function is not called and the
-/// `Option` stays the same.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > map(over: Some(1), with: fn(x) { x + 1 })
-/// Some(2)
-/// ```
-///
-/// ```gleam
-/// > map(over: None, with: fn(x) { x + 1 })
-/// None
-/// ```
-///
-pub fn map(over option: Option(a), with fun: fn(a) -> b) -> Option(b) {
- case option {
- Some(x) -> Some(fun(x))
- None -> None
- }
-}
-
-/// Merges a nested `Option` into a single layer.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > flatten(Some(Some(1)))
-/// Some(1)
-/// ```
-///
-/// ```gleam
-/// > flatten(Some(None))
-/// None
-/// ```
-///
-/// ```gleam
-/// > flatten(None)
-/// None
-/// ```
-///
-pub fn flatten(option: Option(Option(a))) -> Option(a) {
- case option {
- Some(x) -> x
- None -> None
- }
-}
-
-/// Updates a value held within the `Some` of an `Option` by calling a given function
-/// on it, where the given function also returns an `Option`. The two options are
-/// then merged together into one `Option`.
-///
-/// If the `Option` is a `None` rather than `Some` the function is not called and the
-/// option stays the same.
-///
-/// This function is the equivalent of calling `map` followed by `flatten`, and
-/// it is useful for chaining together multiple functions that return `Option`.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > then(Some(1), fn(x) { Some(x + 1) })
-/// Some(2)
-/// ```
-///
-/// ```gleam
-/// > then(Some(1), fn(x) { Some(#("a", x)) })
-/// Some(#("a", 1))
-/// ```
-///
-/// ```gleam
-/// > then(Some(1), fn(_) { None })
-/// None
-/// ```
-///
-/// ```gleam
-/// > then(None, fn(x) { Some(x + 1) })
-/// None
-/// ```
-///
-pub fn then(option: Option(a), apply fun: fn(a) -> Option(b)) -> Option(b) {
- case option {
- Some(x) -> fun(x)
- None -> None
- }
-}
-
-/// Returns the first value if it is `Some`, otherwise returns the second value.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > or(Some(1), Some(2))
-/// Some(1)
-/// ```
-///
-/// ```gleam
-/// > or(Some(1), None)
-/// Some(1)
-/// ```
-///
-/// ```gleam
-/// > or(None, Some(2))
-/// Some(2)
-/// ```
-///
-/// ```gleam
-/// > or(None, None)
-/// None
-/// ```
-///
-pub fn or(first: Option(a), second: Option(a)) -> Option(a) {
- case first {
- Some(_) -> first
- None -> second
- }
-}
-
-/// Returns the first value if it is `Some`, otherwise evaluates the given function for a fallback value.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > lazy_or(Some(1), fn() { Some(2) })
-/// Some(1)
-/// ```
-///
-/// ```gleam
-/// > lazy_or(Some(1), fn() { None })
-/// Some(1)
-/// ```
-///
-/// ```gleam
-/// > lazy_or(None, fn() { Some(2) })
-/// Some(2)
-/// ```
-///
-/// ```gleam
-/// > lazy_or(None, fn() { None })
-/// None
-/// ```
-///
-pub fn lazy_or(first: Option(a), second: fn() -> Option(a)) -> Option(a) {
- case first {
- Some(_) -> first
- None -> second()
- }
-}
-
-fn do_values(list: List(Option(a)), acc: List(a)) -> List(a) {
- case list {
- [] -> acc
- [x, ..xs] -> {
- let accumulate = fn(acc, item) {
- case item {
- Some(value) -> [value, ..acc]
- None -> acc
- }
- }
- accumulate(do_values(xs, acc), x)
- }
- }
-}
-
-/// Given a list of `Option`s,
-/// returns only the values inside `Some`.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > values([Some(1), None, Some(3)])
-/// [1, 3]
-/// ```
-///
-pub fn values(options: List(Option(a))) -> List(a) {
- do_values(options, [])
-}
diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam/order.gleam b/aoc2023/build/packages/gleam_stdlib/src/gleam/order.gleam
deleted file mode 100644
index 12ce011..0000000
--- a/aoc2023/build/packages/gleam_stdlib/src/gleam/order.gleam
+++ /dev/null
@@ -1,133 +0,0 @@
-/// Represents the result of a single comparison to determine the precise
-/// ordering of two values.
-///
-pub type Order {
- /// Less-than
- Lt
-
- /// Equal
- Eq
-
- /// Greater than
- Gt
-}
-
-/// Inverts an order, so less-than becomes greater-than and greater-than
-/// becomes less-than.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > negate(Lt)
-/// Gt
-/// ```
-///
-/// ```gleam
-/// > negate(Eq)
-/// Eq
-/// ```
-///
-/// ```gleam
-/// > negate(Lt)
-/// Gt
-/// ```
-///
-pub fn negate(order: Order) -> Order {
- case order {
- Lt -> Gt
- Eq -> Eq
- Gt -> Lt
- }
-}
-
-/// Produces a numeric representation of the order.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > to_int(Lt)
-/// -1
-/// ```
-///
-/// ```gleam
-/// > to_int(Eq)
-/// 0
-/// ```
-///
-/// ```gleam
-/// > to_int(Gt)
-/// 1
-/// ```
-///
-pub fn to_int(order: Order) -> Int {
- case order {
- Lt -> -1
- Eq -> 0
- Gt -> 1
- }
-}
-
-/// Compares two `Order` values to one another, producing a new `Order`.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > compare(Eq, with: Lt)
-/// Gt
-/// ```
-///
-pub fn compare(a: Order, with b: Order) -> Order {
- case a, b {
- x, y if x == y -> Eq
- Lt, _ | Eq, Gt -> Lt
- _, _ -> Gt
- }
-}
-
-/// Returns the largest of two orders given that `Gt > Eq > Lt`.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > max(Eq, Lt)
-/// Eq
-/// ```
-///
-pub fn max(a: Order, b: Order) -> Order {
- case a, b {
- Gt, _ -> Gt
- Eq, Lt -> Eq
- _, _ -> b
- }
-}
-
-/// Returns the smallest of two orders given that `Gt > Eq > Lt`.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > min(Eq, Lt)
-/// Lt
-/// ```
-///
-pub fn min(a: Order, b: Order) -> Order {
- case a, b {
- Lt, _ -> Lt
- Eq, Gt -> Eq
- _, _ -> b
- }
-}
-
-/// Inverts an ordering function, so less-than becomes greater-than and greater-than
-/// becomes less-than.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > list.sort([1, 5, 4], by: reverse(int.compare))
-/// [5, 4, 1]
-/// ```
-///
-pub fn reverse(orderer: fn(a, a) -> Order) -> fn(a, a) -> Order {
- fn(a, b) { orderer(b, a) }
-}
diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam/pair.gleam b/aoc2023/build/packages/gleam_stdlib/src/gleam/pair.gleam
deleted file mode 100644
index 894e6a8..0000000
--- a/aoc2023/build/packages/gleam_stdlib/src/gleam/pair.gleam
+++ /dev/null
@@ -1,85 +0,0 @@
-/// Returns the first element in a pair.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > first(#(1, 2))
-/// 1
-/// ```
-///
-pub fn first(pair: #(a, b)) -> a {
- let #(a, _) = pair
- a
-}
-
-/// Returns the second element in a pair.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > second(#(1, 2))
-/// 2
-/// ```
-///
-pub fn second(pair: #(a, b)) -> b {
- let #(_, a) = pair
- a
-}
-
-/// Returns a new pair with the elements swapped.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > swap(#(1, 2))
-/// #(2, 1)
-/// ```
-///
-pub fn swap(pair: #(a, b)) -> #(b, a) {
- let #(a, b) = pair
- #(b, a)
-}
-
-/// Returns a new pair with the first element having had `with` applied to
-/// it.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > #(1, 2) |> map_first(fn(n) { n * 2 })
-/// #(2, 2)
-/// ```
-///
-pub fn map_first(of pair: #(a, b), with fun: fn(a) -> c) -> #(c, b) {
- let #(a, b) = pair
- #(fun(a), b)
-}
-
-/// Returns a new pair with the second element having had `with` applied to
-/// it.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > #(1, 2) |> map_second(fn(n) { n * 2 })
-/// #(1, 4)
-/// ```
-///
-pub fn map_second(of pair: #(a, b), with fun: fn(b) -> c) -> #(a, c) {
- let #(a, b) = pair
- #(a, fun(b))
-}
-
-/// Returns a new pair with the given elements. This can also be done using the dedicated
-/// syntax instead: `new(1, 2) == #(1, 2)`.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > new(1, 2)
-/// #(1, 2)
-/// ```
-///
-pub fn new(first: a, second: b) -> #(a, b) {
- #(first, second)
-}
diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam/queue.gleam b/aoc2023/build/packages/gleam_stdlib/src/gleam/queue.gleam
deleted file mode 100644
index 5bf60c8..0000000
--- a/aoc2023/build/packages/gleam_stdlib/src/gleam/queue.gleam
+++ /dev/null
@@ -1,292 +0,0 @@
-import gleam/list
-
-/// A queue is an ordered collection of elements. It is similar to a list, but
-/// unlike a list elements can be added to or removed from either the front or
-/// the back in a performant fashion.
-///
-/// The internal representation may be different for two queues with the same
-/// elements in the same order if the queues were constructed in different
-/// ways. This is the price paid for a queue's fast access at both the front
-/// and the back.
-///
-/// Because of unpredictable internal representation the equality operator `==`
-/// may return surprising results, and the `is_equal` and `is_logically_equal`
-/// functions are the recommended way to test queues for equality.
-///
-pub opaque type Queue(element) {
- Queue(in: List(element), out: List(element))
-}
-
-/// Creates a fresh queue that contains no values.
-///
-pub fn new() -> Queue(a) {
- Queue(in: [], out: [])
-}
-
-/// Converts a list of elements into a queue of the same elements in the same
-/// order. The first element in the list becomes the front element in the queue.
-///
-/// This function runs in constant time.
-///
-/// # Examples
-///
-/// ```gleam
-/// > [1, 2, 3] |> from_list |> length
-/// 3
-/// ```
-///
-pub fn from_list(list: List(a)) -> Queue(a) {
- Queue(in: [], out: list)
-}
-
-/// Converts a queue of elements into a list of the same elements in the same
-/// order. The front element in the queue becomes the first element in the list.
-///
-/// This function runs in linear time.
-///
-/// # Examples
-///
-/// ```gleam
-/// > new() |> push_back(1) |> push_back(2) |> to_list
-/// [1, 2]
-/// ```
-///
-pub fn to_list(queue: Queue(a)) -> List(a) {
- queue.out
- |> list.append(list.reverse(queue.in))
-}
-
-/// Determines whether or not the queue is empty.
-///
-/// This function runs in constant time.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > [] |> from_list |> is_empty
-/// True
-/// ```
-///
-/// ```gleam
-/// > [1] |> from_list |> is_empty
-/// False
-/// ```
-///
-/// ```gleam
-/// > [1, 2] |> from_list |> is_empty
-/// False
-/// ```
-///
-pub fn is_empty(queue: Queue(a)) -> Bool {
- queue.in == [] && queue.out == []
-}
-
-/// Counts the number of elements in a given queue.
-///
-/// This function has to traverse the queue to determine the number of elements,
-/// so it runs in linear time.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > length(from_list([]))
-/// 0
-/// ```
-///
-/// ```gleam
-/// > length(from_list([1]))
-/// 1
-/// ```
-///
-/// ```gleam
-/// > length(from_list([1, 2]))
-/// 2
-/// ```
-///
-pub fn length(queue: Queue(a)) -> Int {
- list.length(queue.in) + list.length(queue.out)
-}
-
-/// Pushes an element onto the back of the queue.
-///
-/// # Examples
-///
-/// ```gleam
-/// > [1, 2] |> from_list |> push_back(3) |> to_list
-/// [1, 2, 3]
-/// ```
-///
-pub fn push_back(onto queue: Queue(a), this item: a) -> Queue(a) {
- Queue(in: [item, ..queue.in], out: queue.out)
-}
-
-/// Pushes an element onto the front of the queue.
-///
-/// # Examples
-///
-/// ```gleam
-/// > [0, 0] |> from_list |> push_front(1) |> to_list
-/// [1, 0, 0]
-/// ```
-///
-pub fn push_front(onto queue: Queue(a), this item: a) -> Queue(a) {
- Queue(in: queue.in, out: [item, ..queue.out])
-}
-
-/// Gets the last element from the queue, returning the
-/// element and a new queue without that element.
-///
-/// This function typically runs in constant time, but will occasionally run in
-/// linear time.
-///
-/// # Examples
-///
-/// ```gleam
-/// > new()
-/// > |> push_back(0)
-/// > |> push_back(1)
-/// > |> pop_back()
-/// Ok(#(1, push_front(new(), 0)))
-/// ```
-///
-/// ```gleam
-/// > new()
-/// > |> push_front(0)
-/// > |> pop_back()
-/// Ok(#(0, new()))
-/// ```
-///
-/// ```gleam
-/// > new()
-/// > |> pop_back()
-/// Error(Nil)
-/// ```
-///
-pub fn pop_back(from queue: Queue(a)) -> Result(#(a, Queue(a)), Nil) {
- case queue {
- Queue(in: [], out: []) -> Error(Nil)
- Queue(in: [], out: out) -> pop_back(Queue(in: list.reverse(out), out: []))
- Queue(in: [first, ..rest], out: out) -> {
- let queue = Queue(in: rest, out: out)
- Ok(#(first, queue))
- }
- }
-}
-
-/// Gets the first element from the queue, returning the
-/// element and a new queue without that element.
-///
-/// This function typically runs in constant time, but will occasionally run in
-/// linear time.
-///
-/// # Examples
-///
-/// ```gleam
-/// > queue.new()
-/// > |> queue.push_front(1)
-/// > |> queue.push_front(0)
-/// > |> queue.pop_front()
-/// Ok(#(0, queue.push_back(queue.new(), 1)))
-/// ```
-///
-/// ```gleam
-/// > queue.new()
-/// > |> queue.push_back(0)
-/// > |> queue.pop_front()
-/// Ok(#(0, queue.new()))
-/// ```
-///
-/// ```gleam
-/// > queue.new()
-/// > |> queue.pop_back()
-/// Error(Nil)
-/// ```
-///
-pub fn pop_front(from queue: Queue(a)) -> Result(#(a, Queue(a)), Nil) {
- case queue {
- Queue(in: [], out: []) -> Error(Nil)
- Queue(in: in, out: []) -> pop_front(Queue(in: [], out: list.reverse(in)))
- Queue(in: in, out: [first, ..rest]) -> {
- let queue = Queue(in: in, out: rest)
- Ok(#(first, queue))
- }
- }
-}
-
-/// Creates a new queue from a given queue containing the same elements, but in
-/// the opposite order.
-///
-/// This function runs in constant time.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > [] |> from_list |> reverse |> to_list
-/// []
-/// ```
-///
-/// ```gleam
-/// > [1] |> from_list |> reverse |> to_list
-/// [1]
-/// ```
-///
-/// ```gleam
-/// > [1, 2] |> from_list |> reverse |> to_list
-/// [2, 1]
-/// ```
-///
-pub fn reverse(queue: Queue(a)) -> Queue(a) {
- Queue(in: queue.out, out: queue.in)
-}
-
-fn check_equal(
- xs: List(t),
- x_tail: List(t),
- ys: List(t),
- y_tail: List(t),
- eq: fn(t, t) -> Bool,
-) -> Bool {
- case xs, x_tail, ys, y_tail {
- [], [], [], [] -> True
- [x, ..xs], _, [y, ..ys], _ ->
- case eq(x, y) {
- False -> False
- True -> check_equal(xs, x_tail, ys, y_tail, eq)
- }
- [], [_, ..], _, _ -> check_equal(list.reverse(x_tail), [], ys, y_tail, eq)
- _, _, [], [_, ..] -> check_equal(xs, x_tail, list.reverse(y_tail), [], eq)
- _, _, _, _ -> False
- }
-}
-
-/// Checks whether two queues have equal elements in the same order, where the
-/// equality of elements is determined by a given equality checking function.
-///
-/// This function is useful as the internal representation may be different for
-/// two queues with the same elements in the same order depending on how they
-/// were constructed, so the equality operator `==` may return surprising
-/// results.
-///
-/// This function runs in linear time multiplied by the time taken by the
-/// element equality checking function.
-///
-pub fn is_logically_equal(
- a: Queue(t),
- to b: Queue(t),
- checking element_is_equal: fn(t, t) -> Bool,
-) -> Bool {
- check_equal(a.out, a.in, b.out, b.in, element_is_equal)
-}
-
-/// Checks whether two queues have the same elements in the same order.
-///
-/// This function is useful as the internal representation may be different for
-/// two queues with the same elements in the same order depending on how they
-/// were constructed, so the equality operator `==` may return surprising
-/// results.
-///
-/// This function runs in linear time.
-///
-pub fn is_equal(a: Queue(t), to b: Queue(t)) -> Bool {
- check_equal(a.out, a.in, b.out, b.in, fn(a, b) { a == b })
-}
diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam/regex.gleam b/aoc2023/build/packages/gleam_stdlib/src/gleam/regex.gleam
deleted file mode 100644
index 9ffda78..0000000
--- a/aoc2023/build/packages/gleam_stdlib/src/gleam/regex.gleam
+++ /dev/null
@@ -1,214 +0,0 @@
-//// This module contains regular expression matching functions for strings.
-//// The matching algorithms of the library are based on the PCRE library, but not
-//// all of the PCRE library is interfaced and some parts of the library go beyond
-//// what PCRE offers. Currently PCRE version 8.40 (release date 2017-01-11) is used.
-
-import gleam/option.{type Option}
-
-pub type Regex
-
-/// The details about a particular match:
-///
-pub type Match {
- Match(
- /// The full string of the match.
- content: String,
- /// A `Regex` can have subpatterns, sup-parts that are in parentheses.
- submatches: List(Option(String)),
- )
-}
-
-/// When a regular expression fails to compile:
-///
-pub type CompileError {
- CompileError(
- /// The problem encountered that caused the compilation to fail
- error: String,
- /// The byte index into the string to where the problem was found
- /// This value may not be correct in JavaScript environments.
- byte_index: Int,
- )
-}
-
-pub type Options {
- Options(case_insensitive: Bool, multi_line: Bool)
-}
-
-/// Creates a `Regex` with some additional options.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > let options = Options(case_insensitive: False, multi_line: True)
-/// > let assert Ok(re) = compile("^[0-9]", with: options)
-/// > check(re, "abc\n123")
-/// True
-/// ```
-///
-/// ```gleam
-/// > let options = Options(case_insensitive: True, multi_line: False)
-/// > let assert Ok(re) = compile("[A-Z]", with: options)
-/// > check(re, "abc123")
-/// True
-/// ```
-///
-pub fn compile(
- pattern: String,
- with options: Options,
-) -> Result(Regex, CompileError) {
- do_compile(pattern, options)
-}
-
-@external(erlang, "gleam_stdlib", "compile_regex")
-@external(javascript, "../gleam_stdlib.mjs", "compile_regex")
-fn do_compile(a: String, with with: Options) -> Result(Regex, CompileError)
-
-/// Creates a new `Regex`.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > let assert Ok(re) = from_string("[0-9]")
-/// > check(re, "abc123")
-/// True
-/// ```
-///
-/// ```gleam
-/// > check(re, "abcxyz")
-/// False
-/// ```
-///
-/// ```gleam
-/// > from_string("[0-9")
-/// Error(
-/// CompileError(
-/// error: "missing terminating ] for character class",
-/// byte_index: 4
-/// )
-/// )
-/// ```
-///
-pub fn from_string(pattern: String) -> Result(Regex, CompileError) {
- compile(pattern, Options(case_insensitive: False, multi_line: False))
-}
-
-/// Returns a boolean indicating whether there was a match or not.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > let assert Ok(re) = from_string("^f.o.?")
-/// > check(with: re, content: "foo")
-/// True
-/// ```
-///
-/// ```gleam
-/// > check(with: re, content: "boo")
-/// False
-/// ```
-///
-pub fn check(with regex: Regex, content content: String) -> Bool {
- do_check(regex, content)
-}
-
-@external(erlang, "gleam_stdlib", "regex_check")
-@external(javascript, "../gleam_stdlib.mjs", "regex_check")
-fn do_check(a: Regex, b: String) -> Bool
-
-/// Splits a string.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > let assert Ok(re) = from_string(" *, *")
-/// > split(with: re, content: "foo,32, 4, 9 ,0")
-/// ["foo", "32", "4", "9", "0"]
-/// ```
-///
-pub fn split(with regex: Regex, content string: String) -> List(String) {
- do_split(regex, string)
-}
-
-@target(erlang)
-@external(erlang, "gleam_stdlib", "regex_split")
-fn do_split(a: Regex, b: String) -> List(String)
-
-@target(javascript)
-fn do_split(regex, string) -> List(String) {
- js_split(string, regex)
-}
-
-@target(javascript)
-@external(javascript, "../gleam_stdlib.mjs", "split")
-fn js_split(a: String, b: Regex) -> List(String)
-
-/// Collects all matches of the regular expression.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > let assert Ok(re) = from_string("[oi]n a (\\w+)")
-/// > scan(with: re, content: "I am on a boat in a lake.")
-/// [
-/// Match(
-/// content: "on a boat",
-/// submatches: [Some("boat")]
-/// ),
-/// Match(
-/// content: "in a lake",
-/// submatches: [Some("lake")]
-/// )
-/// ]
-/// ```
-///
-/// ```gleam
-/// > let assert Ok(re) = regex.from_string("([+|\\-])?(\\d+)(\\w+)?")
-/// > scan(with: re, content: "-36")
-/// [
-/// Match(
-/// content: "-36",
-/// submatches: [Some("-"), Some("36")]
-/// )
-/// ]
-///
-/// > scan(with: re, content: "36")
-/// [
-/// Match(
-/// content: "36",
-/// submatches: [None, Some("36")]
-/// )
-/// ]
-/// ```
-///
-/// ```gleam
-/// > let assert Ok(re) = regex.from_string("var\\s*(\\w+)\\s*(int|string)?\\s*=\\s*(.*)")
-/// > scan(with: re, content: "var age = 32")
-/// [
-/// Match(
-/// content: "var age = 32",
-/// submatches: [Some("age"), None, Some("32")]
-/// )
-/// ]
-/// ```
-///
-/// ```gleam
-/// > let assert Ok(re) = regex.from_string("let (\\w+) = (\\w+)")
-/// > scan(with: re, content: "let age = 32")
-/// [
-/// Match(
-/// content: "let age = 32",
-/// submatches: [Some("age"), Some("32")]
-/// )
-/// ]
-///
-/// > scan(with: re, content: "const age = 32")
-/// []
-/// ```
-///
-pub fn scan(with regex: Regex, content string: String) -> List(Match) {
- do_scan(regex, string)
-}
-
-@external(erlang, "gleam_stdlib", "regex_scan")
-@external(javascript, "../gleam_stdlib.mjs", "regex_scan")
-fn do_scan(a: Regex, b: String) -> List(Match)
diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam/result.gleam b/aoc2023/build/packages/gleam_stdlib/src/gleam/result.gleam
deleted file mode 100644
index fb6dddb..0000000
--- a/aoc2023/build/packages/gleam_stdlib/src/gleam/result.gleam
+++ /dev/null
@@ -1,482 +0,0 @@
-//// Result represents the result of something that may succeed or not.
-//// `Ok` means it was successful, `Error` means it was not successful.
-
-import gleam/list
-
-/// Checks whether the result is an `Ok` value.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > is_ok(Ok(1))
-/// True
-/// ```
-///
-/// ```gleam
-/// > is_ok(Error(Nil))
-/// False
-/// ```
-///
-pub fn is_ok(result: Result(a, e)) -> Bool {
- case result {
- Error(_) -> False
- Ok(_) -> True
- }
-}
-
-/// Checks whether the result is an `Error` value.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > is_error(Ok(1))
-/// False
-/// ```
-///
-/// ```gleam
-/// > is_error(Error(Nil))
-/// True
-/// ```
-///
-pub fn is_error(result: Result(a, e)) -> Bool {
- case result {
- Ok(_) -> False
- Error(_) -> True
- }
-}
-
-/// Updates a value held within the `Ok` of a result by calling a given function
-/// on it.
-///
-/// If the result is an `Error` rather than `Ok` the function is not called and the
-/// result stays the same.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > map(over: Ok(1), with: fn(x) { x + 1 })
-/// Ok(2)
-/// ```
-///
-/// ```gleam
-/// > map(over: Error(1), with: fn(x) { x + 1 })
-/// Error(1)
-/// ```
-///
-pub fn map(over result: Result(a, e), with fun: fn(a) -> b) -> Result(b, e) {
- case result {
- Ok(x) -> Ok(fun(x))
- Error(e) -> Error(e)
- }
-}
-
-/// Updates a value held within the `Error` of a result by calling a given function
-/// on it.
-///
-/// If the result is `Ok` rather than `Error` the function is not called and the
-/// result stays the same.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > map_error(over: Error(1), with: fn(x) { x + 1 })
-/// Error(2)
-/// ```
-///
-/// ```gleam
-/// > map_error(over: Ok(1), with: fn(x) { x + 1 })
-/// Ok(1)
-/// ```
-///
-pub fn map_error(
- over result: Result(a, e),
- with fun: fn(e) -> f,
-) -> Result(a, f) {
- case result {
- Ok(x) -> Ok(x)
- Error(error) -> Error(fun(error))
- }
-}
-
-/// Merges a nested `Result` into a single layer.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > flatten(Ok(Ok(1)))
-/// Ok(1)
-/// ```
-///
-/// ```gleam
-/// > flatten(Ok(Error("")))
-/// Error("")
-/// ```
-///
-/// ```gleam
-/// > flatten(Error(Nil))
-/// Error(Nil)
-/// ```
-///
-pub fn flatten(result: Result(Result(a, e), e)) -> Result(a, e) {
- case result {
- Ok(x) -> x
- Error(error) -> Error(error)
- }
-}
-
-/// "Updates" an `Ok` result by passing its value to a function that yields a result,
-/// and returning the yielded result. (This may "replace" the `Ok` with an `Error`.)
-///
-/// If the input is an `Error` rather than an `Ok`, the function is not called and
-/// the original `Error` is returned.
-///
-/// This function is the equivalent of calling `map` followed by `flatten`, and
-/// it is useful for chaining together multiple functions that may fail.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > try(Ok(1), fn(x) { Ok(x + 1) })
-/// Ok(2)
-/// ```
-///
-/// ```gleam
-/// > try(Ok(1), fn(x) { Ok(#("a", x)) })
-/// Ok(#("a", 1))
-/// ```
-///
-/// ```gleam
-/// > try(Ok(1), fn(_) { Error("Oh no") })
-/// Error("Oh no")
-/// ```
-///
-/// ```gleam
-/// > try(Error(Nil), fn(x) { Ok(x + 1) })
-/// Error(Nil)
-/// ```
-///
-pub fn try(
- result: Result(a, e),
- apply fun: fn(a) -> Result(b, e),
-) -> Result(b, e) {
- case result {
- Ok(x) -> fun(x)
- Error(e) -> Error(e)
- }
-}
-
-/// An alias for `try`. See the documentation for that function for more information.
-///
-pub fn then(
- result: Result(a, e),
- apply fun: fn(a) -> Result(b, e),
-) -> Result(b, e) {
- try(result, fun)
-}
-
-/// Extracts the `Ok` value from a result, returning a default value if the result
-/// is an `Error`.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > unwrap(Ok(1), 0)
-/// 1
-/// ```
-///
-/// ```gleam
-/// > unwrap(Error(""), 0)
-/// 0
-/// ```
-///
-pub fn unwrap(result: Result(a, e), or default: a) -> a {
- case result {
- Ok(v) -> v
- Error(_) -> default
- }
-}
-
-/// Extracts the `Ok` value from a result, evaluating the default function if the result
-/// is an `Error`.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > lazy_unwrap(Ok(1), fn() { 0 })
-/// 1
-/// ```
-///
-/// ```gleam
-/// > lazy_unwrap(Error(""), fn() { 0 })
-/// 0
-/// ```
-///
-pub fn lazy_unwrap(result: Result(a, e), or default: fn() -> a) -> a {
- case result {
- Ok(v) -> v
- Error(_) -> default()
- }
-}
-
-/// Extracts the `Error` value from a result, returning a default value if the result
-/// is an `Ok`.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > unwrap_error(Error(1), 0)
-/// 1
-/// ```
-///
-/// ```gleam
-/// > unwrap_error(Ok(""), 0)
-/// 0
-/// ```
-///
-pub fn unwrap_error(result: Result(a, e), or default: e) -> e {
- case result {
- Ok(_) -> default
- Error(e) -> e
- }
-}
-
-/// Extracts the inner value from a result. Both the value and error must be of
-/// the same type.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > unwrap_both(Error(1))
-/// 1
-/// ```
-///
-/// ```gleam
-/// > unwrap_both(Ok(2))
-/// 2
-/// ```
-///
-pub fn unwrap_both(result: Result(a, a)) -> a {
- case result {
- Ok(a) -> a
- Error(a) -> a
- }
-}
-
-/// Transforms any error into `Error(Nil)`.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > nil_error(Error(1))
-/// Error(Nil)
-/// ```
-///
-/// ```gleam
-/// > nil_error(Ok(1))
-/// Ok(1)
-/// ```
-///
-pub fn nil_error(result: Result(a, e)) -> Result(a, Nil) {
- map_error(result, fn(_) { Nil })
-}
-
-/// Returns the first value if it is `Ok`, otherwise returns the second value.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > or(Ok(1), Ok(2))
-/// Ok(1)
-/// ```
-///
-/// ```gleam
-/// > or(Ok(1), Error("Error 2"))
-/// Ok(1)
-/// ```
-///
-/// ```gleam
-/// > or(Error("Error 1"), Ok(2))
-/// Ok(2)
-/// ```
-///
-/// ```gleam
-/// > or(Error("Error 1"), Error("Error 2"))
-/// Error("Error 2")
-/// ```
-///
-pub fn or(first: Result(a, e), second: Result(a, e)) -> Result(a, e) {
- case first {
- Ok(_) -> first
- Error(_) -> second
- }
-}
-
-/// Returns the first value if it is `Ok`, otherwise evaluates the given function for a fallback value.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > lazy_or(Ok(1), fn() { Ok(2) })
-/// Ok(1)
-/// ```
-///
-/// ```gleam
-/// > lazy_or(Ok(1), fn() { Error("Error 2") })
-/// Ok(1)
-/// ```
-///
-/// ```gleam
-/// > lazy_or(Error("Error 1"), fn() { Ok(2) })
-/// Ok(2)
-/// ```
-///
-/// ```gleam
-/// > lazy_or(Error("Error 1"), fn() { Error("Error 2") })
-/// Error("Error 2")
-/// ```
-///
-pub fn lazy_or(
- first: Result(a, e),
- second: fn() -> Result(a, e),
-) -> Result(a, e) {
- case first {
- Ok(_) -> first
- Error(_) -> second()
- }
-}
-
-/// Combines a list of results into a single result.
-/// If all elements in the list are `Ok` then returns an `Ok` holding the list of values.
-/// If any element is `Error` then returns the first error.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > all([Ok(1), Ok(2)])
-/// Ok([1, 2])
-/// ```
-///
-/// ```gleam
-/// > all([Ok(1), Error("e")])
-/// Error("e")
-/// ```
-///
-pub fn all(results: List(Result(a, e))) -> Result(List(a), e) {
- list.try_map(results, fn(x) { x })
-}
-
-/// Given a list of results, returns a pair where the first element is a list
-/// of all the values inside `Ok` and the second element is a list with all the
-/// values inside `Error`. The values in both lists appear in reverse order with
-/// respect to their position in the original list of results.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > partition([Ok(1), Error("a"), Error("b"), Ok(2)])
-/// #([2, 1], ["b", "a"])
-/// ```
-///
-pub fn partition(results: List(Result(a, e))) -> #(List(a), List(e)) {
- do_partition(results, [], [])
-}
-
-fn do_partition(results: List(Result(a, e)), oks: List(a), errors: List(e)) {
- case results {
- [] -> #(oks, errors)
- [Ok(a), ..rest] -> do_partition(rest, [a, ..oks], errors)
- [Error(e), ..rest] -> do_partition(rest, oks, [e, ..errors])
- }
-}
-
-/// Replace the value within a result
-///
-/// ## Examples
-///
-/// ```gleam
-/// > replace(Ok(1), Nil)
-/// Ok(Nil)
-/// ```
-///
-/// ```gleam
-/// > replace(Error(1), Nil)
-/// Error(1)
-/// ```
-///
-pub fn replace(result: Result(a, e), value: b) -> Result(b, e) {
- case result {
- Ok(_) -> Ok(value)
- Error(error) -> Error(error)
- }
-}
-
-/// Replace the error within a result
-///
-/// ## Examples
-///
-/// ```gleam
-/// > replace_error(Error(1), Nil)
-/// Error(Nil)
-/// ```
-///
-/// ```gleam
-/// > replace_error(Ok(1), Nil)
-/// Ok(1)
-/// ```
-///
-pub fn replace_error(result: Result(a, e1), error: e2) -> Result(a, e2) {
- case result {
- Ok(x) -> Ok(x)
- Error(_) -> Error(error)
- }
-}
-
-/// Given a list of results, returns only the values inside `Ok`.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > values([Ok(1), Error("a"), Ok(3)])
-/// [1, 3]
-/// ```
-///
-pub fn values(results: List(Result(a, e))) -> List(a) {
- list.filter_map(results, fn(r) { r })
-}
-
-/// Updates a value held within the `Error` of a result by calling a given function
-/// on it, where the given function also returns a result. The two results are
-/// then merged together into one result.
-///
-/// If the result is an `Ok` rather than `Error` the function is not called and the
-/// result stays the same.
-///
-/// This function is useful for chaining together computations that may fail
-/// and trying to recover from possible errors.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > Ok(1) |> try_recover(with: fn(_) { Error("failed to recover") })
-/// Ok(1)
-/// ```
-///
-/// ```gleam
-/// > Error(1) |> try_recover(with: fn(error) { Ok(error + 1) })
-/// Ok(2)
-/// ```
-///
-/// ```gleam
-/// > Error(1) |> try_recover(with: fn(error) { Error("failed to recover") })
-/// Error("failed to recover")
-/// ```
-///
-pub fn try_recover(
- result: Result(a, e),
- with fun: fn(e) -> Result(a, f),
-) -> Result(a, f) {
- case result {
- Ok(value) -> Ok(value)
- Error(error) -> fun(error)
- }
-}
diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam/set.gleam b/aoc2023/build/packages/gleam_stdlib/src/gleam/set.gleam
deleted file mode 100644
index df8d500..0000000
--- a/aoc2023/build/packages/gleam_stdlib/src/gleam/set.gleam
+++ /dev/null
@@ -1,264 +0,0 @@
-import gleam/list
-import gleam/dict.{type Dict}
-import gleam/result
-
-// A list is used as the map value as an empty list has the smallest
-// representation in Erlang's binary format
-@target(erlang)
-type Token =
- List(Nil)
-
-@target(erlang)
-const token = []
-
-@target(javascript)
-type Token =
- Nil
-
-@target(javascript)
-const token = Nil
-
-/// A set is a collection of unique members of the same type.
-///
-/// It is implemented using the `gleam/map` module, so inserts and lookups have
-/// logarithmic time complexity.
-///
-pub opaque type Set(member) {
- Set(map: Dict(member, Token))
-}
-
-/// Creates a new empty set.
-///
-pub fn new() -> Set(member) {
- Set(dict.new())
-}
-
-/// Gets the number of members in a set.
-///
-/// This function runs in constant time.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > new()
-/// > |> insert(1)
-/// > |> insert(2)
-/// > |> size
-/// 2
-/// ```
-///
-pub fn size(set: Set(member)) -> Int {
- dict.size(set.map)
-}
-
-/// Inserts an member into the set.
-///
-/// This function runs in logarithmic time.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > new()
-/// > |> insert(1)
-/// > |> insert(2)
-/// > |> size
-/// 2
-/// ```
-///
-pub fn insert(into set: Set(member), this member: member) -> Set(member) {
- Set(map: dict.insert(set.map, member, token))
-}
-
-/// Checks whether a set contains a given member.
-///
-/// This function runs in logarithmic time.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > new()
-/// > |> insert(2)
-/// > |> contains(2)
-/// True
-/// ```
-///
-/// ```gleam
-/// > new()
-/// > |> insert(2)
-/// > |> contains(1)
-/// False
-/// ```
-///
-pub fn contains(in set: Set(member), this member: member) -> Bool {
- set.map
- |> dict.get(member)
- |> result.is_ok
-}
-
-/// Removes a member from a set. If the set does not contain the member then
-/// the set is returned unchanged.
-///
-/// This function runs in logarithmic time.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > new()
-/// > |> insert(2)
-/// > |> delete(2)
-/// > |> contains(1)
-/// False
-/// ```
-///
-pub fn delete(from set: Set(member), this member: member) -> Set(member) {
- Set(map: dict.delete(set.map, member))
-}
-
-/// Converts the set into a list of the contained members.
-///
-/// The list has no specific ordering, any unintentional ordering may change in
-/// future versions of Gleam or Erlang.
-///
-/// This function runs in linear time.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > new() |> insert(2) |> to_list
-/// [2]
-/// ```
-///
-pub fn to_list(set: Set(member)) -> List(member) {
- dict.keys(set.map)
-}
-
-/// Creates a new set of the members in a given list.
-///
-/// This function runs in loglinear time.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > import gleam/list
-/// > [1, 1, 2, 4, 3, 2] |> from_list |> to_list |> list.sort
-/// [1, 3, 3, 4]
-/// ```
-///
-pub fn from_list(members: List(member)) -> Set(member) {
- let map =
- list.fold(
- over: members,
- from: dict.new(),
- with: fn(m, k) { dict.insert(m, k, token) },
- )
- Set(map)
-}
-
-/// Combines all entries into a single value by calling a given function on each
-/// one.
-///
-/// Sets are not ordered so the values are not returned in any specific order.
-/// Do not write code that relies on the order entries are used by this
-/// function as it may change in later versions of Gleam or Erlang.
-///
-/// # Examples
-///
-/// ```gleam
-/// > from_list([1, 3, 9])
-/// > |> fold(0, fn(member, accumulator) { accumulator + member })
-/// 13
-/// ```
-///
-pub fn fold(
- over set: Set(member),
- from initial: acc,
- with reducer: fn(acc, member) -> acc,
-) -> acc {
- dict.fold(over: set.map, from: initial, with: fn(a, k, _) { reducer(a, k) })
-}
-
-/// Creates a new set from an existing set, minus any members that a given
-/// function returns `False` for.
-///
-/// This function runs in loglinear time.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > import gleam/int
-/// > from_list([1, 4, 6, 3, 675, 44, 67])
-/// > |> filter(for: int.is_even)
-/// > |> to_list
-/// [4, 6, 44]
-/// ```
-///
-pub fn filter(
- in set: Set(member),
- keeping predicate: fn(member) -> Bool,
-) -> Set(member) {
- Set(dict.filter(in: set.map, keeping: fn(m, _) { predicate(m) }))
-}
-
-pub fn drop(from set: Set(member), drop disallowed: List(member)) -> Set(member) {
- list.fold(over: disallowed, from: set, with: delete)
-}
-
-/// Creates a new map from a given map, only including any members which are in
-/// a given list.
-///
-/// This function runs in loglinear time.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > from_list([1, 2, 3])
-/// > |> take([1, 3, 5])
-/// > |> to_list
-/// [1, 3]
-/// ```
-///
-pub fn take(from set: Set(member), keeping desired: List(member)) -> Set(member) {
- Set(dict.take(from: set.map, keeping: desired))
-}
-
-fn order(first: Set(member), second: Set(member)) -> #(Set(member), Set(member)) {
- case dict.size(first.map) > dict.size(second.map) {
- True -> #(first, second)
- False -> #(second, first)
- }
-}
-
-/// Creates a new set that contains all members of both given sets.
-///
-/// This function runs in loglinear time.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > union(from_list([1, 2]), from_list([2, 3])) |> to_list
-/// [1, 2, 3]
-/// ```
-///
-pub fn union(of first: Set(member), and second: Set(member)) -> Set(member) {
- let #(larger, smaller) = order(first, second)
- fold(over: smaller, from: larger, with: insert)
-}
-
-/// Creates a new set that contains members that are present in both given sets.
-///
-/// This function runs in loglinear time.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > intersection(from_list([1, 2]), from_list([2, 3])) |> to_list
-/// [2]
-/// ```
-///
-pub fn intersection(
- of first: Set(member),
- and second: Set(member),
-) -> Set(member) {
- let #(larger, smaller) = order(first, second)
- take(from: larger, keeping: to_list(smaller))
-}
diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam/string.gleam b/aoc2023/build/packages/gleam_stdlib/src/gleam/string.gleam
deleted file mode 100644
index d4496f3..0000000
--- a/aoc2023/build/packages/gleam_stdlib/src/gleam/string.gleam
+++ /dev/null
@@ -1,906 +0,0 @@
-//// Strings in Gleam are UTF-8 binaries. They can be written in your code as
-//// text surrounded by `"double quotes"`.
-
-import gleam/iterator.{type Iterator}
-import gleam/list
-import gleam/option.{type Option, None, Some}
-import gleam/order
-import gleam/string_builder.{type StringBuilder}
-
-/// Determines if a `String` is empty.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > is_empty("")
-/// True
-/// ```
-///
-/// ```gleam
-/// > is_empty("the world")
-/// False
-/// ```
-///
-pub fn is_empty(str: String) -> Bool {
- str == ""
-}
-
-/// Gets the number of grapheme clusters in a given `String`.
-///
-/// This function has to iterate across the whole string to count the number of
-/// graphemes, so it runs in linear time.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > length("Gleam")
-/// 5
-/// ```
-///
-/// ```gleam
-/// > length("ß↑e̊")
-/// 3
-/// ```
-///
-/// ```gleam
-/// > length("")
-/// 0
-/// ```
-///
-pub fn length(string: String) -> Int {
- do_length(string)
-}
-
-@external(erlang, "string", "length")
-@external(javascript, "../gleam_stdlib.mjs", "string_length")
-fn do_length(a: String) -> Int
-
-/// Reverses a `String`.
-///
-/// This function has to iterate across the whole `String` so it runs in linear
-/// time.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > reverse("stressed")
-/// "desserts"
-/// ```
-///
-pub fn reverse(string: String) -> String {
- do_reverse(string)
-}
-
-@target(erlang)
-fn do_reverse(string: String) -> String {
- string
- |> string_builder.from_string
- |> string_builder.reverse
- |> string_builder.to_string
-}
-
-@target(javascript)
-fn do_reverse(string: String) -> String {
- string
- |> to_graphemes
- |> list.reverse
- |> concat
-}
-
-/// Creates a new `String` by replacing all occurrences of a given substring.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > replace("www.example.com", each: ".", with: "-")
-/// "www-example-com"
-/// ```
-///
-/// ```gleam
-/// > replace("a,b,c,d,e", each: ",", with: "/")
-/// "a/b/c/d/e"
-/// ```
-///
-pub fn replace(
- in string: String,
- each pattern: String,
- with substitute: String,
-) -> String {
- string
- |> string_builder.from_string
- |> string_builder.replace(each: pattern, with: substitute)
- |> string_builder.to_string
-}
-
-/// Creates a new `String` with all the graphemes in the input `String` converted to
-/// lowercase.
-///
-/// Useful for case-insensitive comparisons.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > lowercase("X-FILES")
-/// "x-files"
-/// ```
-///
-pub fn lowercase(string: String) -> String {
- do_lowercase(string)
-}
-
-@external(erlang, "string", "lowercase")
-@external(javascript, "../gleam_stdlib.mjs", "lowercase")
-fn do_lowercase(a: String) -> String
-
-/// Creates a new `String` with all the graphemes in the input `String` converted to
-/// uppercase.
-///
-/// Useful for case-insensitive comparisons and VIRTUAL YELLING.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > uppercase("skinner")
-/// "SKINNER"
-/// ```
-///
-pub fn uppercase(string: String) -> String {
- do_uppercase(string)
-}
-
-@external(erlang, "string", "uppercase")
-@external(javascript, "../gleam_stdlib.mjs", "uppercase")
-fn do_uppercase(a: String) -> String
-
-/// Compares two `String`s to see which is "larger" by comparing their graphemes.
-///
-/// This does not compare the size or length of the given `String`s.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > compare("Anthony", "Anthony")
-/// order.Eq
-/// ```
-///
-/// ```gleam
-/// > compare("A", "B")
-/// order.Lt
-/// ```
-///
-pub fn compare(a: String, b: String) -> order.Order {
- case a == b {
- True -> order.Eq
- _ ->
- case less_than(a, b) {
- True -> order.Lt
- _ -> order.Gt
- }
- }
-}
-
-@external(erlang, "gleam_stdlib", "less_than")
-@external(javascript, "../gleam_stdlib.mjs", "less_than")
-fn less_than(a: String, b: String) -> Bool
-
-/// Takes a substring given a start grapheme index and a length. Negative indexes
-/// are taken starting from the *end* of the list.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > slice(from: "gleam", at_index: 1, length: 2)
-/// "le"
-/// ```
-///
-/// ```gleam
-/// > slice(from: "gleam", at_index: 1, length: 10)
-/// "leam"
-/// ```
-///
-/// ```gleam
-/// > slice(from: "gleam", at_index: 10, length: 3)
-/// ""
-/// ```
-///
-/// ```gleam
-/// > slice(from: "gleam", at_index: -2, length: 2)
-/// "am"
-/// ```
-///
-/// ```gleam
-/// > slice(from: "gleam", at_index: -12, length: 2)
-/// ""
-/// ```
-///
-pub fn slice(from string: String, at_index idx: Int, length len: Int) -> String {
- case len < 0 {
- True -> ""
- False ->
- case idx < 0 {
- True -> {
- let translated_idx = length(string) + idx
- case translated_idx < 0 {
- True -> ""
- False -> do_slice(string, translated_idx, len)
- }
- }
- False -> do_slice(string, idx, len)
- }
- }
-}
-
-@target(erlang)
-@external(erlang, "string", "slice")
-fn do_slice(a: String, b: Int, c: Int) -> String
-
-@target(javascript)
-fn do_slice(string: String, idx: Int, len: Int) -> String {
- string
- |> to_graphemes
- |> list.drop(idx)
- |> list.take(len)
- |> concat
-}
-
-/// Drops contents of the first `String` that occur before the second `String`.
-/// If the `from` string does not contain the `before` string, `from` is returned unchanged.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > crop(from: "The Lone Gunmen", before: "Lone")
-/// "Lone Gunmen"
-/// ```
-///
-@external(erlang, "gleam_stdlib", "crop_string")
-@external(javascript, "../gleam_stdlib.mjs", "crop_string")
-pub fn crop(from string: String, before substring: String) -> String
-
-/// Drops *n* graphemes from the left side of a `String`.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > drop_left(from: "The Lone Gunmen", up_to: 2)
-/// "e Lone Gunmen"
-/// ```
-///
-pub fn drop_left(from string: String, up_to num_graphemes: Int) -> String {
- case num_graphemes < 0 {
- True -> string
- False -> slice(string, num_graphemes, length(string) - num_graphemes)
- }
-}
-
-/// Drops *n* graphemes from the right side of a `String`.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > drop_right(from: "Cigarette Smoking Man", up_to: 2)
-/// "Cigarette Smoking M"
-/// ```
-///
-pub fn drop_right(from string: String, up_to num_graphemes: Int) -> String {
- case num_graphemes < 0 {
- True -> string
- False -> slice(string, 0, length(string) - num_graphemes)
- }
-}
-
-/// Checks if the first `String` contains the second.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > contains(does: "theory", contain: "ory")
-/// True
-/// ```
-///
-/// ```gleam
-/// > contains(does: "theory", contain: "the")
-/// True
-/// ```
-///
-/// ```gleam
-/// > contains(does: "theory", contain: "THE")
-/// False
-/// ```
-///
-@external(erlang, "gleam_stdlib", "contains_string")
-@external(javascript, "../gleam_stdlib.mjs", "contains_string")
-pub fn contains(does haystack: String, contain needle: String) -> Bool
-
-/// Checks whether the first `String` starts with the second one.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > starts_with("theory", "ory")
-/// False
-/// ```
-///
-pub fn starts_with(string: String, prefix: String) -> Bool {
- do_starts_with(string, prefix)
-}
-
-@external(erlang, "gleam_stdlib", "string_starts_with")
-@external(javascript, "../gleam_stdlib.mjs", "starts_with")
-fn do_starts_with(a: String, b: String) -> Bool
-
-/// Checks whether the first `String` ends with the second one.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > ends_with("theory", "ory")
-/// True
-/// ```
-///
-pub fn ends_with(string: String, suffix: String) -> Bool {
- do_ends_with(string, suffix)
-}
-
-@external(erlang, "gleam_stdlib", "string_ends_with")
-@external(javascript, "../gleam_stdlib.mjs", "ends_with")
-fn do_ends_with(a: String, b: String) -> Bool
-
-/// Creates a list of `String`s by splitting a given string on a given substring.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > split("home/gleam/desktop/", on: "/")
-/// ["home", "gleam", "desktop", ""]
-/// ```
-///
-pub fn split(x: String, on substring: String) -> List(String) {
- case substring {
- "" -> to_graphemes(x)
- _ ->
- x
- |> string_builder.from_string
- |> string_builder.split(on: substring)
- |> list.map(with: string_builder.to_string)
- }
-}
-
-/// Splits a `String` a single time on the given substring.
-///
-/// Returns an `Error` if substring not present.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > split_once("home/gleam/desktop/", on: "/")
-/// Ok(#("home", "gleam/desktop/"))
-/// ```
-///
-/// ```gleam
-/// > split_once("home/gleam/desktop/", on: "?")
-/// Error(Nil)
-/// ```
-///
-pub fn split_once(
- x: String,
- on substring: String,
-) -> Result(#(String, String), Nil) {
- do_split_once(x, substring)
-}
-
-@target(erlang)
-@external(erlang, "string", "split")
-fn erl_split(a: String, b: String) -> List(String)
-
-@target(erlang)
-fn do_split_once(x: String, substring: String) -> Result(#(String, String), Nil) {
- case erl_split(x, substring) {
- [first, rest] -> Ok(#(first, rest))
- _ -> Error(Nil)
- }
-}
-
-@target(javascript)
-@external(javascript, "../gleam_stdlib.mjs", "split_once")
-fn do_split_once(
- x x: String,
- substring substring: String,
-) -> Result(#(String, String), Nil)
-
-/// Creates a new `String` by joining two `String`s together.
-///
-/// This function copies both `String`s and runs in linear time. If you find
-/// yourself joining `String`s frequently consider using the [`string_builder`](../gleam/string_builder.html)
-/// module as it can append `String`s much faster!
-///
-/// ## Examples
-///
-/// ```gleam
-/// > append(to: "butter", suffix: "fly")
-/// "butterfly"
-/// ```
-///
-pub fn append(to first: String, suffix second: String) -> String {
- first
- |> string_builder.from_string
- |> string_builder.append(second)
- |> string_builder.to_string
-}
-
-/// Creates a new `String` by joining many `String`s together.
-///
-/// This function copies both `String`s and runs in linear time. If you find
-/// yourself joining `String`s frequently consider using the [`string_builder`](../gleam/string_builder.html)
-/// module as it can append `String`s much faster!
-///
-/// ## Examples
-///
-/// ```gleam
-/// > concat(["never", "the", "less"])
-/// "nevertheless"
-/// ```
-///
-pub fn concat(strings: List(String)) -> String {
- strings
- |> string_builder.from_strings
- |> string_builder.to_string
-}
-
-/// Creates a new `String` by repeating a `String` a given number of times.
-///
-/// This function runs in linear time.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > repeat("ha", times: 3)
-/// "hahaha"
-/// ```
-///
-pub fn repeat(string: String, times times: Int) -> String {
- iterator.repeat(string)
- |> iterator.take(times)
- |> iterator.to_list
- |> concat
-}
-
-/// Joins many `String`s together with a given separator.
-///
-/// This function runs in linear time.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > join(["home","evan","Desktop"], with: "/")
-/// "home/evan/Desktop"
-/// ```
-///
-pub fn join(strings: List(String), with separator: String) -> String {
- do_join(strings, separator)
-}
-
-@target(erlang)
-fn do_join(strings: List(String), separator: String) -> String {
- strings
- |> list.intersperse(with: separator)
- |> concat
-}
-
-@target(javascript)
-@external(javascript, "../gleam_stdlib.mjs", "join")
-fn do_join(strings strings: List(String), string string: String) -> String
-
-/// Pads a `String` on the left until it has at least given number of graphemes.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > pad_left("121", to: 5, with: ".")
-/// "..121"
-/// ```
-///
-/// ```gleam
-/// > pad_left("121", to: 3, with: ".")
-/// "121"
-/// ```
-///
-/// ```gleam
-/// > pad_left("121", to: 2, with: ".")
-/// "121"
-/// ```
-///
-pub fn pad_left(string: String, to desired_length: Int, with pad_string: String) {
- let current_length = length(string)
- let to_pad_length = desired_length - current_length
- padding(to_pad_length, pad_string)
- |> iterator.append(iterator.single(string))
- |> iterator.to_list
- |> concat
-}
-
-/// Pads a `String` on the right until it has a given length.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > pad_right("123", to: 5, with: ".")
-/// "123.."
-/// ```
-///
-/// ```gleam
-/// > pad_right("123", to: 3, with: ".")
-/// "123"
-/// ```
-///
-/// ```gleam
-/// > pad_right("123", to: 2, with: ".")
-/// "123"
-/// ```
-///
-pub fn pad_right(
- string: String,
- to desired_length: Int,
- with pad_string: String,
-) {
- let current_length = length(string)
- let to_pad_length = desired_length - current_length
- iterator.single(string)
- |> iterator.append(padding(to_pad_length, pad_string))
- |> iterator.to_list
- |> concat
-}
-
-fn padding(size: Int, pad_string: String) -> Iterator(String) {
- let pad_length = length(pad_string)
- let num_pads = size / pad_length
- let extra = size % pad_length
- iterator.repeat(pad_string)
- |> iterator.take(num_pads)
- |> iterator.append(iterator.single(slice(pad_string, 0, extra)))
-}
-
-/// Removes whitespace on both sides of a `String`.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > trim(" hats \n")
-/// "hats"
-/// ```
-///
-pub fn trim(string: String) -> String {
- do_trim(string)
-}
-
-@target(erlang)
-fn do_trim(string: String) -> String {
- erl_trim(string, Both)
-}
-
-@target(erlang)
-type Direction {
- Leading
- Trailing
- Both
-}
-
-@target(erlang)
-@external(erlang, "string", "trim")
-fn erl_trim(a: String, b: Direction) -> String
-
-@target(javascript)
-@external(javascript, "../gleam_stdlib.mjs", "trim")
-fn do_trim(string string: String) -> String
-
-/// Removes whitespace on the left of a `String`.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > trim_left(" hats \n")
-/// "hats \n"
-/// ```
-///
-pub fn trim_left(string: String) -> String {
- do_trim_left(string)
-}
-
-@target(erlang)
-fn do_trim_left(string: String) -> String {
- erl_trim(string, Leading)
-}
-
-@target(javascript)
-@external(javascript, "../gleam_stdlib.mjs", "trim_left")
-fn do_trim_left(string string: String) -> String
-
-/// Removes whitespace on the right of a `String`.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > trim_right(" hats \n")
-/// " hats"
-/// ```
-///
-pub fn trim_right(string: String) -> String {
- do_trim_right(string)
-}
-
-@target(erlang)
-fn do_trim_right(string: String) -> String {
- erl_trim(string, Trailing)
-}
-
-@target(javascript)
-@external(javascript, "../gleam_stdlib.mjs", "trim_right")
-fn do_trim_right(string string: String) -> String
-
-/// Splits a non-empty `String` into its first element (head) and rest (tail).
-/// This lets you pattern match on `String`s exactly as you would with lists.
-///
-/// Note on JavaScript using the function to iterate over a string will likely
-/// be slower than using `to_graphemes` due to string slicing being more
-/// expensive on JavaScript than Erlang.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > pop_grapheme("gleam")
-/// Ok(#("g", "leam"))
-/// ```
-///
-/// ```gleam
-/// > pop_grapheme("")
-/// Error(Nil)
-/// ```
-///
-pub fn pop_grapheme(string: String) -> Result(#(String, String), Nil) {
- do_pop_grapheme(string)
-}
-
-@external(erlang, "gleam_stdlib", "string_pop_grapheme")
-@external(javascript, "../gleam_stdlib.mjs", "pop_grapheme")
-fn do_pop_grapheme(string string: String) -> Result(#(String, String), Nil)
-
-/// Converts a `String` to a list of
-/// [graphemes](https://en.wikipedia.org/wiki/Grapheme).
-///
-/// ```gleam
-/// > to_graphemes("abc")
-/// ["a", "b", "c"]
-/// ```
-///
-@external(javascript, "../gleam_stdlib.mjs", "graphemes")
-pub fn to_graphemes(string: String) -> List(String) {
- do_to_graphemes(string, [])
- |> list.reverse
-}
-
-fn do_to_graphemes(string: String, acc: List(String)) -> List(String) {
- case pop_grapheme(string) {
- Ok(#(grapheme, rest)) -> do_to_graphemes(rest, [grapheme, ..acc])
- _ -> acc
- }
-}
-
-@external(erlang, "gleam_stdlib", "identity")
-@external(javascript, "../gleam_stdlib.mjs", "codepoint")
-fn unsafe_int_to_utf_codepoint(a: Int) -> UtfCodepoint
-
-/// Converts a `String` to a `List` of `UtfCodepoint`.
-///
-/// See <https://en.wikipedia.org/wiki/Code_point> and
-/// <https://en.wikipedia.org/wiki/Unicode#Codespace_and_Code_Points> for an
-/// explanation on code points.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > "a" |> to_utf_codepoints
-/// [UtfCodepoint(97)]
-/// ```
-///
-/// ```gleam
-/// // Semantically the same as:
-/// // ["🏳", "️", "‍", "🌈"] or:
-/// // [waving_white_flag, variant_selector_16, zero_width_joiner, rainbow]
-/// > "🏳️‍🌈" |> to_utf_codepoints
-/// [UtfCodepoint(127987), UtfCodepoint(65039), UtfCodepoint(8205), UtfCodepoint(127752)]
-/// ```
-///
-pub fn to_utf_codepoints(string: String) -> List(UtfCodepoint) {
- do_to_utf_codepoints(string)
-}
-
-@target(erlang)
-fn do_to_utf_codepoints(string: String) -> List(UtfCodepoint) {
- do_to_utf_codepoints_impl(<<string:utf8>>, [])
- |> list.reverse
-}
-
-@target(erlang)
-fn do_to_utf_codepoints_impl(
- bit_array: BitArray,
- acc: List(UtfCodepoint),
-) -> List(UtfCodepoint) {
- case bit_array {
- <<first:utf8_codepoint, rest:bytes>> ->
- do_to_utf_codepoints_impl(rest, [first, ..acc])
- _ -> acc
- }
-}
-
-@target(javascript)
-fn do_to_utf_codepoints(string: String) -> List(UtfCodepoint) {
- string
- |> string_to_codepoint_integer_list
- |> list.map(unsafe_int_to_utf_codepoint)
-}
-
-@target(javascript)
-@external(javascript, "../gleam_stdlib.mjs", "string_to_codepoint_integer_list")
-fn string_to_codepoint_integer_list(a: String) -> List(Int)
-
-/// Converts a `List` of `UtfCodepoint`s to a `String`.
-///
-/// See <https://en.wikipedia.org/wiki/Code_point> and
-/// <https://en.wikipedia.org/wiki/Unicode#Codespace_and_Code_Points> for an
-/// explanation on code points.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > {
-/// > let assert #(Ok(a), Ok(b), Ok(c)) = #(
-/// > utf_codepoint(97),
-/// > utf_codepoint(98),
-/// > utf_codepoint(99),
-/// > )
-/// > [a, b, c]
-/// > }
-/// > |> from_utf_codepoints
-/// "abc"
-/// ```
-///
-@external(erlang, "gleam_stdlib", "utf_codepoint_list_to_string")
-@external(javascript, "../gleam_stdlib.mjs", "utf_codepoint_list_to_string")
-pub fn from_utf_codepoints(utf_codepoints: List(UtfCodepoint)) -> String
-
-/// Converts an integer to a `UtfCodepoint`.
-///
-/// Returns an `Error` if the integer does not represent a valid UTF codepoint.
-///
-pub fn utf_codepoint(value: Int) -> Result(UtfCodepoint, Nil) {
- case value {
- i if i > 1_114_111 -> Error(Nil)
- 65_534 | 65_535 -> Error(Nil)
- i if i >= 55_296 && i <= 57_343 -> Error(Nil)
- i -> Ok(unsafe_int_to_utf_codepoint(i))
- }
-}
-
-/// Converts an UtfCodepoint to its ordinal code point value.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > let assert [utf_codepoint, ..] = to_utf_codepoints("💜")
-/// > utf_codepoint_to_int(utf_codepoint)
-/// 128156
-/// ```
-///
-pub fn utf_codepoint_to_int(cp: UtfCodepoint) -> Int {
- do_utf_codepoint_to_int(cp)
-}
-
-@external(erlang, "gleam_stdlib", "identity")
-@external(javascript, "../gleam_stdlib.mjs", "utf_codepoint_to_int")
-fn do_utf_codepoint_to_int(cp cp: UtfCodepoint) -> Int
-
-/// Converts a `String` into `Option(String)` where an empty `String` becomes
-/// `None`.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > to_option("")
-/// None
-/// ```
-///
-/// ```gleam
-/// > to_option("hats")
-/// Some("hats")
-/// ```
-///
-pub fn to_option(s: String) -> Option(String) {
- case s {
- "" -> None
- _ -> Some(s)
- }
-}
-
-/// Returns the first grapheme cluster in a given `String` and wraps it in a
-/// `Result(String, Nil)`. If the `String` is empty, it returns `Error(Nil)`.
-/// Otherwise, it returns `Ok(String)`.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > first("")
-/// Error(Nil)
-/// ```
-///
-/// ```gleam
-/// > first("icecream")
-/// Ok("i")
-/// ```
-///
-pub fn first(s: String) -> Result(String, Nil) {
- case pop_grapheme(s) {
- Ok(#(first, _)) -> Ok(first)
- Error(e) -> Error(e)
- }
-}
-
-/// Returns the last grapheme cluster in a given `String` and wraps it in a
-/// `Result(String, Nil)`. If the `String` is empty, it returns `Error(Nil)`.
-/// Otherwise, it returns `Ok(String)`.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > last("")
-/// Error(Nil)
-/// ```
-///
-/// ```gleam
-/// > last("icecream")
-/// Ok("m")
-/// ```
-///
-pub fn last(s: String) -> Result(String, Nil) {
- case pop_grapheme(s) {
- Ok(#(first, "")) -> Ok(first)
- Ok(#(_, rest)) -> Ok(slice(rest, -1, 1))
- Error(e) -> Error(e)
- }
-}
-
-/// Creates a new `String` with the first grapheme in the input `String`
-/// converted to uppercase and the remaining graphemes to lowercase.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > capitalise("mamouna")
-/// "Mamouna"
-/// ```
-///
-pub fn capitalise(s: String) -> String {
- case pop_grapheme(s) {
- Ok(#(first, rest)) -> append(to: uppercase(first), suffix: lowercase(rest))
- _ -> ""
- }
-}
-
-/// Returns a `String` representation of a term in Gleam syntax.
-///
-pub fn inspect(term: anything) -> String {
- do_inspect(term)
- |> string_builder.to_string
-}
-
-@external(erlang, "gleam_stdlib", "inspect")
-@external(javascript, "../gleam_stdlib.mjs", "inspect")
-fn do_inspect(term term: anything) -> StringBuilder
-
-/// Returns the number of bytes in a `String`.
-///
-/// This function runs in constant time on Erlang and in linear time on
-/// JavaScript.
-///
-@external(erlang, "erlang", "byte_size")
-@external(javascript, "../gleam_stdlib.mjs", "byte_size")
-pub fn byte_size(string: String) -> Int
diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam/string_builder.gleam b/aoc2023/build/packages/gleam_stdlib/src/gleam/string_builder.gleam
deleted file mode 100644
index 5792ca8..0000000
--- a/aoc2023/build/packages/gleam_stdlib/src/gleam/string_builder.gleam
+++ /dev/null
@@ -1,298 +0,0 @@
-import gleam/list
-
-/// `StringBuilder` is a type used for efficiently building strings.
-///
-/// When we append one string to another the strings must be copied to a
-/// new location in memory so that they can sit together. This behaviour
-/// enables efficient reading of the string but copying can be expensive,
-/// especially if we want to join many strings together.
-///
-/// `StringBuilder` is different in that it can be joined together in constant time
-/// using minimal memory, and then can be efficiently converted to a string
-/// using the `to_string` function.
-///
-/// On Erlang this type is compatible with Erlang's iodata. On JavaScript this
-/// type is compatible with normal strings.
-///
-pub type StringBuilder
-
-/// Create an empty `StringBuilder`. Useful as the start of a pipe chaining many
-/// builders together.
-///
-pub fn new() -> StringBuilder {
- do_from_strings([])
-}
-
-/// Prepends a `String` onto the start of some `StringBuilder`.
-///
-/// Runs in constant time.
-///
-pub fn prepend(
- to builder: StringBuilder,
- prefix prefix: String,
-) -> StringBuilder {
- append_builder(from_string(prefix), builder)
-}
-
-/// Appends a `String` onto the end of some `StringBuilder`.
-///
-/// Runs in constant time.
-///
-pub fn append(to builder: StringBuilder, suffix second: String) -> StringBuilder {
- append_builder(builder, from_string(second))
-}
-
-/// Prepends some `StringBuilder` onto the start of another.
-///
-/// Runs in constant time.
-///
-pub fn prepend_builder(
- to builder: StringBuilder,
- prefix prefix: StringBuilder,
-) -> StringBuilder {
- do_append(prefix, builder)
-}
-
-/// Appends some `StringBuilder` onto the end of another.
-///
-/// Runs in constant time.
-///
-pub fn append_builder(
- to builder: StringBuilder,
- suffix suffix: StringBuilder,
-) -> StringBuilder {
- do_append(builder, suffix)
-}
-
-@external(erlang, "gleam_stdlib", "iodata_append")
-@external(javascript, "../gleam_stdlib.mjs", "add")
-fn do_append(a: StringBuilder, b: StringBuilder) -> StringBuilder
-
-/// Converts a list of strings into a builder.
-///
-/// Runs in constant time.
-///
-pub fn from_strings(strings: List(String)) -> StringBuilder {
- do_from_strings(strings)
-}
-
-@external(erlang, "gleam_stdlib", "identity")
-@external(javascript, "../gleam_stdlib.mjs", "concat")
-fn do_from_strings(a: List(String)) -> StringBuilder
-
-/// Joins a list of builders into a single builder.
-///
-/// Runs in constant time.
-///
-pub fn concat(builders: List(StringBuilder)) -> StringBuilder {
- do_concat(builders)
-}
-
-@external(erlang, "gleam_stdlib", "identity")
-@external(javascript, "../gleam_stdlib.mjs", "concat")
-fn do_concat(a: List(StringBuilder)) -> StringBuilder
-
-/// Converts a string into a builder.
-///
-/// Runs in constant time.
-///
-pub fn from_string(string: String) -> StringBuilder {
- do_from_string(string)
-}
-
-@external(erlang, "gleam_stdlib", "identity")
-@external(javascript, "../gleam_stdlib.mjs", "identity")
-fn do_from_string(a: String) -> StringBuilder
-
-/// Turns an `StringBuilder` into a `String`
-///
-/// This function is implemented natively by the virtual machine and is highly
-/// optimised.
-///
-pub fn to_string(builder: StringBuilder) -> String {
- do_to_string(builder)
-}
-
-@external(erlang, "unicode", "characters_to_binary")
-@external(javascript, "../gleam_stdlib.mjs", "identity")
-fn do_to_string(a: StringBuilder) -> String
-
-/// Returns the size of the `StringBuilder` in bytes.
-///
-pub fn byte_size(builder: StringBuilder) -> Int {
- do_byte_size(builder)
-}
-
-@external(erlang, "erlang", "iolist_size")
-@external(javascript, "../gleam_stdlib.mjs", "length")
-fn do_byte_size(a: StringBuilder) -> Int
-
-/// Joins the given builders into a new builder separated with the given string
-///
-pub fn join(builders: List(StringBuilder), with sep: String) -> StringBuilder {
- builders
- |> list.intersperse(from_string(sep))
- |> concat
-}
-
-/// Converts a builder to a new builder where the contents have been
-/// lowercased.
-///
-pub fn lowercase(builder: StringBuilder) -> StringBuilder {
- do_lowercase(builder)
-}
-
-@external(erlang, "string", "lowercase")
-@external(javascript, "../gleam_stdlib.mjs", "lowercase")
-fn do_lowercase(a: StringBuilder) -> StringBuilder
-
-/// Converts a builder to a new builder where the contents have been
-/// uppercased.
-///
-pub fn uppercase(builder: StringBuilder) -> StringBuilder {
- do_uppercase(builder)
-}
-
-@external(erlang, "string", "uppercase")
-@external(javascript, "../gleam_stdlib.mjs", "uppercase")
-fn do_uppercase(a: StringBuilder) -> StringBuilder
-
-/// Converts a builder to a new builder with the contents reversed.
-///
-pub fn reverse(builder: StringBuilder) -> StringBuilder {
- do_reverse(builder)
-}
-
-@target(erlang)
-@external(erlang, "string", "reverse")
-fn do_reverse(a: StringBuilder) -> StringBuilder
-
-@target(javascript)
-fn do_reverse(builder: StringBuilder) -> StringBuilder {
- builder
- |> to_string
- |> do_to_graphemes
- |> list.reverse
- |> from_strings
-}
-
-@target(javascript)
-@external(javascript, "../gleam_stdlib.mjs", "graphemes")
-fn do_to_graphemes(string string: String) -> List(String)
-
-/// Splits a builder on a given pattern into a list of builders.
-///
-pub fn split(iodata: StringBuilder, on pattern: String) -> List(StringBuilder) {
- do_split(iodata, pattern)
-}
-
-@target(erlang)
-type Direction {
- All
-}
-
-@target(erlang)
-@external(erlang, "string", "split")
-fn erl_split(a: StringBuilder, b: String, c: Direction) -> List(StringBuilder)
-
-@target(erlang)
-fn do_split(iodata: StringBuilder, pattern: String) -> List(StringBuilder) {
- erl_split(iodata, pattern, All)
-}
-
-@target(javascript)
-@external(javascript, "../gleam_stdlib.mjs", "split")
-fn do_split(
- builder builder: StringBuilder,
- pattern pattern: String,
-) -> List(StringBuilder)
-
-/// Replaces all instances of a pattern with a given string substitute.
-///
-pub fn replace(
- in builder: StringBuilder,
- each pattern: String,
- with substitute: String,
-) -> StringBuilder {
- do_replace(builder, pattern, substitute)
-}
-
-@target(erlang)
-fn do_replace(
- iodata: StringBuilder,
- pattern: String,
- substitute: String,
-) -> StringBuilder {
- erl_replace(iodata, pattern, substitute, All)
-}
-
-@target(erlang)
-@external(erlang, "string", "replace")
-fn erl_replace(
- a: StringBuilder,
- b: String,
- c: String,
- d: Direction,
-) -> StringBuilder
-
-@target(javascript)
-@external(javascript, "../gleam_stdlib.mjs", "string_replace")
-fn do_replace(a: StringBuilder, b: String, c: String) -> StringBuilder
-
-/// Compares two builders to determine if they have the same textual content.
-///
-/// Comparing two iodata using the `==` operator may return `False` even if they
-/// have the same content as they may have been build in different ways, so
-/// using this function is often preferred.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > from_strings(["a", "b"]) == from_string("ab")
-/// False
-/// ```
-///
-/// ```gleam
-/// > is_equal(from_strings(["a", "b"]), from_string("ab"))
-/// True
-/// ```
-///
-pub fn is_equal(a: StringBuilder, b: StringBuilder) -> Bool {
- do_is_equal(a, b)
-}
-
-@external(erlang, "string", "equal")
-@external(javascript, "../gleam_stdlib.mjs", "equal")
-fn do_is_equal(a: StringBuilder, b: StringBuilder) -> Bool
-
-/// Inspects a builder to determine if it is equivalent to an empty string.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > from_string("ok") |> is_empty
-/// False
-/// ```
-///
-/// ```gleam
-/// > from_string("") |> is_empty
-/// True
-/// ```
-///
-/// ```gleam
-/// > from_strings([]) |> is_empty
-/// True
-/// ```
-///
-pub fn is_empty(builder: StringBuilder) -> Bool {
- do_is_empty(builder)
-}
-
-@target(erlang)
-@external(erlang, "string", "is_empty")
-fn do_is_empty(a: StringBuilder) -> Bool
-
-@target(javascript)
-fn do_is_empty(builder: StringBuilder) -> Bool {
- from_string("") == builder
-}
diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam/uri.gleam b/aoc2023/build/packages/gleam_stdlib/src/gleam/uri.gleam
deleted file mode 100644
index 11f6ea6..0000000
--- a/aoc2023/build/packages/gleam_stdlib/src/gleam/uri.gleam
+++ /dev/null
@@ -1,462 +0,0 @@
-//// Utilities for working with URIs
-////
-//// This module provides functions for working with URIs (for example, parsing
-//// URIs or encoding query strings). The functions in this module are implemented
-//// according to [RFC 3986](https://tools.ietf.org/html/rfc3986).
-////
-//// Query encoding (Form encoding) is defined in the
-//// [W3C specification](https://www.w3.org/TR/html52/sec-forms.html#urlencoded-form-data).
-
-import gleam/int
-import gleam/list
-import gleam/option.{type Option, None, Some}
-import gleam/string
-import gleam/string_builder.{type StringBuilder}
-@target(javascript)
-import gleam/pair
-@target(javascript)
-import gleam/regex
-@target(javascript)
-import gleam/result
-
-/// Type representing holding the parsed components of an URI.
-/// All components of a URI are optional, except the path.
-///
-pub type Uri {
- Uri(
- scheme: Option(String),
- userinfo: Option(String),
- host: Option(String),
- port: Option(Int),
- path: String,
- query: Option(String),
- fragment: Option(String),
- )
-}
-
-/// Parses a compliant URI string into the `Uri` Type.
-/// If the string is not a valid URI string then an error is returned.
-///
-/// The opposite operation is `uri.to_string`.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > parse("https://example.com:1234/a/b?query=true#fragment")
-/// Ok(
-/// Uri(
-/// scheme: Some("https"),
-/// userinfo: None,
-/// host: Some("example.com"),
-/// port: Some(1234),
-/// path: "/a/b",
-/// query: Some("query=true"),
-/// fragment: Some("fragment")
-/// )
-/// )
-/// ```
-///
-pub fn parse(uri_string: String) -> Result(Uri, Nil) {
- do_parse(uri_string)
-}
-
-@target(erlang)
-@external(erlang, "gleam_stdlib", "uri_parse")
-fn do_parse(a: String) -> Result(Uri, Nil)
-
-@target(javascript)
-fn do_parse(uri_string: String) -> Result(Uri, Nil) {
- // From https://tools.ietf.org/html/rfc3986#appendix-B
- let pattern =
- // 12 3 4 5 6 7 8
- "^(([a-z][a-z0-9\\+\\-\\.]*):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#.*)?"
- let matches =
- pattern
- |> regex_submatches(uri_string)
- |> pad_list(8)
-
- let #(scheme, authority, path, query, fragment) = case matches {
- [
- _scheme_with_colon,
- scheme,
- authority_with_slashes,
- _authority,
- path,
- query_with_question_mark,
- _query,
- fragment,
- ] -> #(
- scheme,
- authority_with_slashes,
- path,
- query_with_question_mark,
- fragment,
- )
- _ -> #(None, None, None, None, None)
- }
-
- let scheme = noneify_empty_string(scheme)
- let path = option.unwrap(path, "")
- let query = noneify_query(query)
- let #(userinfo, host, port) = split_authority(authority)
- let fragment =
- fragment
- |> option.to_result(Nil)
- |> result.try(string.pop_grapheme)
- |> result.map(pair.second)
- |> option.from_result
- let scheme =
- scheme
- |> noneify_empty_string
- |> option.map(string.lowercase)
- Ok(Uri(
- scheme: scheme,
- userinfo: userinfo,
- host: host,
- port: port,
- path: path,
- query: query,
- fragment: fragment,
- ))
-}
-
-@target(javascript)
-fn regex_submatches(pattern: String, string: String) -> List(Option(String)) {
- pattern
- |> regex.compile(regex.Options(case_insensitive: True, multi_line: False))
- |> result.nil_error
- |> result.map(regex.scan(_, string))
- |> result.try(list.first)
- |> result.map(fn(m: regex.Match) { m.submatches })
- |> result.unwrap([])
-}
-
-@target(javascript)
-fn noneify_query(x: Option(String)) -> Option(String) {
- case x {
- None -> None
- Some(x) ->
- case string.pop_grapheme(x) {
- Ok(#("?", query)) -> Some(query)
- _ -> None
- }
- }
-}
-
-@target(javascript)
-fn noneify_empty_string(x: Option(String)) -> Option(String) {
- case x {
- Some("") | None -> None
- Some(_) -> x
- }
-}
-
-// Split an authority into its userinfo, host and port parts.
-@target(javascript)
-fn split_authority(
- authority: Option(String),
-) -> #(Option(String), Option(String), Option(Int)) {
- case option.unwrap(authority, "") {
- "" -> #(None, None, None)
- "//" -> #(None, Some(""), None)
- authority -> {
- let matches =
- "^(//)?((.*)@)?(\\[[a-zA-Z0-9:.]*\\]|[^:]*)(:(\\d*))?"
- |> regex_submatches(authority)
- |> pad_list(6)
- case matches {
- [_, _, userinfo, host, _, port] -> {
- let userinfo = noneify_empty_string(userinfo)
- let host = noneify_empty_string(host)
- let port =
- port
- |> option.unwrap("")
- |> int.parse
- |> option.from_result
- #(userinfo, host, port)
- }
- _ -> #(None, None, None)
- }
- }
- }
-}
-
-@target(javascript)
-fn pad_list(list: List(Option(a)), size: Int) -> List(Option(a)) {
- list
- |> list.append(list.repeat(None, extra_required(list, size)))
-}
-
-@target(javascript)
-fn extra_required(list: List(a), remaining: Int) -> Int {
- case list {
- _ if remaining == 0 -> 0
- [] -> remaining
- [_, ..xs] -> extra_required(xs, remaining - 1)
- }
-}
-
-/// Parses an urlencoded query string into a list of key value pairs.
-/// Returns an error for invalid encoding.
-///
-/// The opposite operation is `uri.query_to_string`.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > parse_query("a=1&b=2")
-/// Ok([#("a", "1"), #("b", "2")])
-/// ```
-///
-pub fn parse_query(query: String) -> Result(List(#(String, String)), Nil) {
- do_parse_query(query)
-}
-
-@external(erlang, "gleam_stdlib", "parse_query")
-@external(javascript, "../gleam_stdlib.mjs", "parse_query")
-fn do_parse_query(a: String) -> Result(List(#(String, String)), Nil)
-
-/// Encodes a list of key value pairs as a URI query string.
-///
-/// The opposite operation is `uri.parse_query`.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > query_to_string([#("a", "1"), #("b", "2")])
-/// "a=1&b=2"
-/// ```
-///
-pub fn query_to_string(query: List(#(String, String))) -> String {
- query
- |> list.map(query_pair)
- |> list.intersperse(string_builder.from_string("&"))
- |> string_builder.concat
- |> string_builder.to_string
-}
-
-fn query_pair(pair: #(String, String)) -> StringBuilder {
- string_builder.from_strings([
- percent_encode(pair.0),
- "=",
- percent_encode(pair.1),
- ])
-}
-
-/// Encodes a string into a percent encoded representation.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > percent_encode("100% great")
-/// "100%25%20great"
-/// ```
-///
-pub fn percent_encode(value: String) -> String {
- do_percent_encode(value)
-}
-
-@external(erlang, "gleam_stdlib", "percent_encode")
-@external(javascript, "../gleam_stdlib.mjs", "percent_encode")
-fn do_percent_encode(a: String) -> String
-
-/// Decodes a percent encoded string.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > percent_decode("100%25+great")
-/// Ok("100% great")
-/// ```
-///
-pub fn percent_decode(value: String) -> Result(String, Nil) {
- do_percent_decode(value)
-}
-
-@external(erlang, "gleam_stdlib", "percent_decode")
-@external(javascript, "../gleam_stdlib.mjs", "percent_decode")
-fn do_percent_decode(a: String) -> Result(String, Nil)
-
-fn do_remove_dot_segments(
- input: List(String),
- accumulator: List(String),
-) -> List(String) {
- case input {
- [] -> list.reverse(accumulator)
- [segment, ..rest] -> {
- let accumulator = case segment, accumulator {
- "", accumulator -> accumulator
- ".", accumulator -> accumulator
- "..", [] -> []
- "..", [_, ..accumulator] -> accumulator
- segment, accumulator -> [segment, ..accumulator]
- }
- do_remove_dot_segments(rest, accumulator)
- }
- }
-}
-
-fn remove_dot_segments(input: List(String)) -> List(String) {
- do_remove_dot_segments(input, [])
-}
-
-/// Splits the path section of a URI into it's constituent segments.
-///
-/// Removes empty segments and resolves dot-segments as specified in
-/// [section 5.2](https://www.ietf.org/rfc/rfc3986.html#section-5.2) of the RFC.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > path_segments("/users/1")
-/// ["users" ,"1"]
-/// ```
-///
-pub fn path_segments(path: String) -> List(String) {
- remove_dot_segments(string.split(path, "/"))
-}
-
-/// Encodes a `Uri` value as a URI string.
-///
-/// The opposite operation is `uri.parse`.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > let uri = Uri(Some("http"), None, Some("example.com"), ...)
-/// > to_string(uri)
-/// "http://example.com"
-/// ```
-///
-pub fn to_string(uri: Uri) -> String {
- let parts = case uri.fragment {
- Some(fragment) -> ["#", fragment]
- _ -> []
- }
- let parts = case uri.query {
- Some(query) -> ["?", query, ..parts]
- _ -> parts
- }
- let parts = [uri.path, ..parts]
- let parts = case uri.host, string.starts_with(uri.path, "/") {
- Some(host), False if host != "" -> ["/", ..parts]
- _, _ -> parts
- }
- let parts = case uri.host, uri.port {
- Some(_), Some(port) -> [":", int.to_string(port), ..parts]
- _, _ -> parts
- }
- let parts = case uri.scheme, uri.userinfo, uri.host {
- Some(s), Some(u), Some(h) -> [s, "://", u, "@", h, ..parts]
- Some(s), None, Some(h) -> [s, "://", h, ..parts]
- Some(s), Some(_), None | Some(s), None, None -> [s, ":", ..parts]
- None, None, Some(h) -> ["//", h, ..parts]
- _, _, _ -> parts
- }
- string.concat(parts)
-}
-
-/// Fetches the origin of a URI.
-///
-/// Returns the origin of a uri as defined in
-/// [RFC 6454](https://tools.ietf.org/html/rfc6454)
-///
-/// The supported URI schemes are `http` and `https`.
-/// URLs without a scheme will return `Error`.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > let assert Ok(uri) = parse("http://example.com/path?foo#bar")
-/// > origin(uri)
-/// Ok("http://example.com")
-/// ```
-///
-pub fn origin(uri: Uri) -> Result(String, Nil) {
- let Uri(scheme: scheme, host: host, port: port, ..) = uri
- case scheme {
- Some("https") if port == Some(443) -> {
- let origin = Uri(scheme, None, host, None, "", None, None)
- Ok(to_string(origin))
- }
- Some("http") if port == Some(80) -> {
- let origin = Uri(scheme, None, host, None, "", None, None)
- Ok(to_string(origin))
- }
- Some(s) if s == "http" || s == "https" -> {
- let origin = Uri(scheme, None, host, port, "", None, None)
- Ok(to_string(origin))
- }
- _ -> Error(Nil)
- }
-}
-
-fn drop_last(elements: List(a)) -> List(a) {
- list.take(from: elements, up_to: list.length(elements) - 1)
-}
-
-fn join_segments(segments: List(String)) -> String {
- string.join(["", ..segments], "/")
-}
-
-/// Resolves a URI with respect to the given base URI.
-///
-/// The base URI must be an absolute URI or this function will return an error.
-/// The algorithm for merging uris is described in
-/// [RFC 3986](https://tools.ietf.org/html/rfc3986#section-5.2).
-///
-pub fn merge(base: Uri, relative: Uri) -> Result(Uri, Nil) {
- case base {
- Uri(scheme: Some(_), host: Some(_), ..) ->
- case relative {
- Uri(host: Some(_), ..) -> {
- let path =
- string.split(relative.path, "/")
- |> remove_dot_segments()
- |> join_segments()
- let resolved =
- Uri(
- option.or(relative.scheme, base.scheme),
- None,
- relative.host,
- option.or(relative.port, base.port),
- path,
- relative.query,
- relative.fragment,
- )
- Ok(resolved)
- }
- _ -> {
- let #(new_path, new_query) = case relative.path {
- "" -> #(base.path, option.or(relative.query, base.query))
- _ -> {
- let path_segments = case string.starts_with(relative.path, "/") {
- True -> string.split(relative.path, "/")
- False ->
- string.split(base.path, "/")
- |> drop_last()
- |> list.append(string.split(relative.path, "/"))
- }
- let path =
- path_segments
- |> remove_dot_segments()
- |> join_segments()
- #(path, relative.query)
- }
- }
- let resolved =
- Uri(
- base.scheme,
- None,
- base.host,
- base.port,
- new_path,
- new_query,
- relative.fragment,
- )
- Ok(resolved)
- }
- }
- _ -> Error(Nil)
- }
-}
diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam@base.erl b/aoc2023/build/packages/gleam_stdlib/src/gleam@base.erl
deleted file mode 100644
index 65bc3f6..0000000
--- a/aoc2023/build/packages/gleam_stdlib/src/gleam@base.erl
+++ /dev/null
@@ -1,20 +0,0 @@
--module(gleam@base).
--compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]).
-
--export([encode64/2, decode64/1, url_encode64/2, url_decode64/1]).
-
--spec encode64(bitstring(), boolean()) -> binary().
-encode64(Input, Padding) ->
- gleam@bit_array:base64_encode(Input, Padding).
-
--spec decode64(binary()) -> {ok, bitstring()} | {error, nil}.
-decode64(Encoded) ->
- gleam@bit_array:base64_decode(Encoded).
-
--spec url_encode64(bitstring(), boolean()) -> binary().
-url_encode64(Input, Padding) ->
- gleam@bit_array:base64_url_encode(Input, Padding).
-
--spec url_decode64(binary()) -> {ok, bitstring()} | {error, nil}.
-url_decode64(Encoded) ->
- gleam@bit_array:base64_url_decode(Encoded).
diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam@bit_array.erl b/aoc2023/build/packages/gleam_stdlib/src/gleam@bit_array.erl
deleted file mode 100644
index ba18dfa..0000000
--- a/aoc2023/build/packages/gleam_stdlib/src/gleam@bit_array.erl
+++ /dev/null
@@ -1,102 +0,0 @@
--module(gleam@bit_array).
--compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]).
-
--export([from_string/1, byte_size/1, slice/3, is_utf8/1, to_string/1, concat/1, append/2, base64_encode/2, base64_decode/1, base64_url_encode/2, base64_url_decode/1, base16_encode/1, base16_decode/1]).
-
--spec from_string(binary()) -> bitstring().
-from_string(X) ->
- gleam_stdlib:identity(X).
-
--spec byte_size(bitstring()) -> integer().
-byte_size(X) ->
- erlang:byte_size(X).
-
--spec slice(bitstring(), integer(), integer()) -> {ok, bitstring()} |
- {error, nil}.
-slice(String, Position, Length) ->
- gleam_stdlib:bit_array_slice(String, Position, Length).
-
--spec do_is_utf8(bitstring()) -> boolean().
-do_is_utf8(Bits) ->
- case Bits of
- <<>> ->
- true;
-
- <<_/utf8, Rest/binary>> ->
- do_is_utf8(Rest);
-
- _ ->
- false
- end.
-
--spec is_utf8(bitstring()) -> boolean().
-is_utf8(Bits) ->
- do_is_utf8(Bits).
-
--spec do_to_string(bitstring()) -> {ok, binary()} | {error, nil}.
-do_to_string(Bits) ->
- case is_utf8(Bits) of
- true ->
- {ok, gleam_stdlib:identity(Bits)};
-
- false ->
- {error, nil}
- end.
-
--spec to_string(bitstring()) -> {ok, binary()} | {error, nil}.
-to_string(Bits) ->
- do_to_string(Bits).
-
--spec concat(list(bitstring())) -> bitstring().
-concat(Bit_arrays) ->
- gleam_stdlib:bit_array_concat(Bit_arrays).
-
--spec append(bitstring(), bitstring()) -> bitstring().
-append(First, Second) ->
- gleam_stdlib:bit_array_concat([First, Second]).
-
--spec base64_encode(bitstring(), boolean()) -> binary().
-base64_encode(Input, Padding) ->
- Encoded = base64:encode(Input),
- case Padding of
- true ->
- Encoded;
-
- false ->
- gleam@string:replace(Encoded, <<"="/utf8>>, <<""/utf8>>)
- end.
-
--spec base64_decode(binary()) -> {ok, bitstring()} | {error, nil}.
-base64_decode(Encoded) ->
- Padded = case erlang:byte_size(gleam_stdlib:identity(Encoded)) rem 4 of
- 0 ->
- Encoded;
-
- N ->
- gleam@string:append(
- Encoded,
- gleam@string:repeat(<<"="/utf8>>, 4 - N)
- )
- end,
- gleam_stdlib:base_decode64(Padded).
-
--spec base64_url_encode(bitstring(), boolean()) -> binary().
-base64_url_encode(Input, Padding) ->
- _pipe = base64_encode(Input, Padding),
- _pipe@1 = gleam@string:replace(_pipe, <<"+"/utf8>>, <<"-"/utf8>>),
- gleam@string:replace(_pipe@1, <<"/"/utf8>>, <<"_"/utf8>>).
-
--spec base64_url_decode(binary()) -> {ok, bitstring()} | {error, nil}.
-base64_url_decode(Encoded) ->
- _pipe = Encoded,
- _pipe@1 = gleam@string:replace(_pipe, <<"-"/utf8>>, <<"+"/utf8>>),
- _pipe@2 = gleam@string:replace(_pipe@1, <<"_"/utf8>>, <<"/"/utf8>>),
- base64_decode(_pipe@2).
-
--spec base16_encode(bitstring()) -> binary().
-base16_encode(Input) ->
- binary:encode_hex(Input).
-
--spec base16_decode(binary()) -> {ok, bitstring()} | {error, nil}.
-base16_decode(Input) ->
- gleam_stdlib:base16_decode(Input).
diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam@bit_builder.erl b/aoc2023/build/packages/gleam_stdlib/src/gleam@bit_builder.erl
deleted file mode 100644
index 284c6d4..0000000
--- a/aoc2023/build/packages/gleam_stdlib/src/gleam@bit_builder.erl
+++ /dev/null
@@ -1,66 +0,0 @@
--module(gleam@bit_builder).
--compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]).
-
--export([new/0, prepend/2, append/2, prepend_builder/2, append_builder/2, prepend_string/2, append_string/2, concat/1, concat_bit_strings/1, from_string/1, from_string_builder/1, from_bit_string/1, to_bit_string/1, byte_size/1]).
-
--spec new() -> gleam@bytes_builder:bytes_builder().
-new() ->
- gleam@bytes_builder:new().
-
--spec prepend(gleam@bytes_builder:bytes_builder(), bitstring()) -> gleam@bytes_builder:bytes_builder().
-prepend(To, Prefix) ->
- gleam@bytes_builder:prepend(To, Prefix).
-
--spec append(gleam@bytes_builder:bytes_builder(), bitstring()) -> gleam@bytes_builder:bytes_builder().
-append(To, Suffix) ->
- gleam@bytes_builder:append(To, Suffix).
-
--spec prepend_builder(
- gleam@bytes_builder:bytes_builder(),
- gleam@bytes_builder:bytes_builder()
-) -> gleam@bytes_builder:bytes_builder().
-prepend_builder(To, Prefix) ->
- gleam@bytes_builder:prepend_builder(To, Prefix).
-
--spec append_builder(
- gleam@bytes_builder:bytes_builder(),
- gleam@bytes_builder:bytes_builder()
-) -> gleam@bytes_builder:bytes_builder().
-append_builder(First, Second) ->
- gleam_stdlib:iodata_append(First, Second).
-
--spec prepend_string(gleam@bytes_builder:bytes_builder(), binary()) -> gleam@bytes_builder:bytes_builder().
-prepend_string(To, Prefix) ->
- gleam@bytes_builder:prepend_string(To, Prefix).
-
--spec append_string(gleam@bytes_builder:bytes_builder(), binary()) -> gleam@bytes_builder:bytes_builder().
-append_string(To, Suffix) ->
- gleam@bytes_builder:append_string(To, Suffix).
-
--spec concat(list(gleam@bytes_builder:bytes_builder())) -> gleam@bytes_builder:bytes_builder().
-concat(Builders) ->
- gleam_stdlib:identity(Builders).
-
--spec concat_bit_strings(list(bitstring())) -> gleam@bytes_builder:bytes_builder().
-concat_bit_strings(Bits) ->
- gleam_stdlib:identity(Bits).
-
--spec from_string(binary()) -> gleam@bytes_builder:bytes_builder().
-from_string(String) ->
- gleam_stdlib:wrap_list(String).
-
--spec from_string_builder(gleam@string_builder:string_builder()) -> gleam@bytes_builder:bytes_builder().
-from_string_builder(Builder) ->
- gleam_stdlib:wrap_list(Builder).
-
--spec from_bit_string(bitstring()) -> gleam@bytes_builder:bytes_builder().
-from_bit_string(Bits) ->
- gleam_stdlib:wrap_list(Bits).
-
--spec to_bit_string(gleam@bytes_builder:bytes_builder()) -> bitstring().
-to_bit_string(Builder) ->
- erlang:list_to_bitstring(Builder).
-
--spec byte_size(gleam@bytes_builder:bytes_builder()) -> integer().
-byte_size(Builder) ->
- erlang:iolist_size(Builder).
diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam@bit_string.erl b/aoc2023/build/packages/gleam_stdlib/src/gleam@bit_string.erl
deleted file mode 100644
index 7dabaa3..0000000
--- a/aoc2023/build/packages/gleam_stdlib/src/gleam@bit_string.erl
+++ /dev/null
@@ -1,33 +0,0 @@
--module(gleam@bit_string).
--compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]).
-
--export([from_string/1, byte_size/1, append/2, slice/3, is_utf8/1, to_string/1, concat/1]).
-
--spec from_string(binary()) -> bitstring().
-from_string(X) ->
- gleam_stdlib:identity(X).
-
--spec byte_size(bitstring()) -> integer().
-byte_size(X) ->
- erlang:byte_size(X).
-
--spec append(bitstring(), bitstring()) -> bitstring().
-append(First, Second) ->
- gleam@bit_array:append(First, Second).
-
--spec slice(bitstring(), integer(), integer()) -> {ok, bitstring()} |
- {error, nil}.
-slice(String, Position, Length) ->
- gleam_stdlib:bit_array_slice(String, Position, Length).
-
--spec is_utf8(bitstring()) -> boolean().
-is_utf8(Bits) ->
- gleam@bit_array:is_utf8(Bits).
-
--spec to_string(bitstring()) -> {ok, binary()} | {error, nil}.
-to_string(Bits) ->
- gleam@bit_array:to_string(Bits).
-
--spec concat(list(bitstring())) -> bitstring().
-concat(Bit_strings) ->
- gleam_stdlib:bit_array_concat(Bit_strings).
diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam@bool.erl b/aoc2023/build/packages/gleam_stdlib/src/gleam@bool.erl
deleted file mode 100644
index cd55358..0000000
--- a/aoc2023/build/packages/gleam_stdlib/src/gleam@bool.erl
+++ /dev/null
@@ -1,162 +0,0 @@
--module(gleam@bool).
--compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]).
-
--export(['and'/2, 'or'/2, negate/1, nor/2, nand/2, exclusive_or/2, exclusive_nor/2, compare/2, max/2, min/2, to_int/1, to_string/1, guard/3, lazy_guard/3]).
-
--spec 'and'(boolean(), boolean()) -> boolean().
-'and'(A, B) ->
- A andalso B.
-
--spec 'or'(boolean(), boolean()) -> boolean().
-'or'(A, B) ->
- A orelse B.
-
--spec negate(boolean()) -> boolean().
-negate(Bool) ->
- case Bool of
- true ->
- false;
-
- false ->
- true
- end.
-
--spec nor(boolean(), boolean()) -> boolean().
-nor(A, B) ->
- case {A, B} of
- {false, false} ->
- true;
-
- {false, true} ->
- false;
-
- {true, false} ->
- false;
-
- {true, true} ->
- false
- end.
-
--spec nand(boolean(), boolean()) -> boolean().
-nand(A, B) ->
- case {A, B} of
- {false, false} ->
- true;
-
- {false, true} ->
- true;
-
- {true, false} ->
- true;
-
- {true, true} ->
- false
- end.
-
--spec exclusive_or(boolean(), boolean()) -> boolean().
-exclusive_or(A, B) ->
- case {A, B} of
- {false, false} ->
- false;
-
- {false, true} ->
- true;
-
- {true, false} ->
- true;
-
- {true, true} ->
- false
- end.
-
--spec exclusive_nor(boolean(), boolean()) -> boolean().
-exclusive_nor(A, B) ->
- case {A, B} of
- {false, false} ->
- true;
-
- {false, true} ->
- false;
-
- {true, false} ->
- false;
-
- {true, true} ->
- true
- end.
-
--spec compare(boolean(), boolean()) -> gleam@order:order().
-compare(A, B) ->
- case {A, B} of
- {true, true} ->
- eq;
-
- {true, false} ->
- gt;
-
- {false, false} ->
- eq;
-
- {false, true} ->
- lt
- end.
-
--spec max(boolean(), boolean()) -> boolean().
-max(A, B) ->
- case A of
- true ->
- true;
-
- false ->
- B
- end.
-
--spec min(boolean(), boolean()) -> boolean().
-min(A, B) ->
- case A of
- false ->
- false;
-
- true ->
- B
- end.
-
--spec to_int(boolean()) -> integer().
-to_int(Bool) ->
- case Bool of
- false ->
- 0;
-
- true ->
- 1
- end.
-
--spec to_string(boolean()) -> binary().
-to_string(Bool) ->
- case Bool of
- false ->
- <<"False"/utf8>>;
-
- true ->
- <<"True"/utf8>>
- end.
-
--spec guard(boolean(), DDZ, fun(() -> DDZ)) -> DDZ.
-guard(Requirement, Consequence, Alternative) ->
- case Requirement of
- true ->
- Consequence;
-
- false ->
- Alternative()
- end.
-
--spec lazy_guard(boolean(), fun(() -> DEA), fun(() -> DEA)) -> DEA.
-lazy_guard(Requirement, Consequence, Alternative) ->
- case Requirement of
- true ->
- Consequence();
-
- false ->
- Alternative()
- end.
diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam@bytes_builder.erl b/aoc2023/build/packages/gleam_stdlib/src/gleam@bytes_builder.erl
deleted file mode 100644
index 2f6dd93..0000000
--- a/aoc2023/build/packages/gleam_stdlib/src/gleam@bytes_builder.erl
+++ /dev/null
@@ -1,87 +0,0 @@
--module(gleam@bytes_builder).
--compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]).
-
--export([append_builder/2, prepend_builder/2, concat/1, new/0, from_string/1, prepend_string/2, append_string/2, from_string_builder/1, from_bit_array/1, prepend/2, append/2, concat_bit_arrays/1, to_bit_array/1, byte_size/1]).
--export_type([bytes_builder/0]).
-
--opaque bytes_builder() :: {bytes, bitstring()} |
- {text, gleam@string_builder:string_builder()} |
- {many, list(bytes_builder())}.
-
--spec append_builder(bytes_builder(), bytes_builder()) -> bytes_builder().
-append_builder(First, Second) ->
- gleam_stdlib:iodata_append(First, Second).
-
--spec prepend_builder(bytes_builder(), bytes_builder()) -> bytes_builder().
-prepend_builder(Second, First) ->
- gleam_stdlib:iodata_append(First, Second).
-
--spec concat(list(bytes_builder())) -> bytes_builder().
-concat(Builders) ->
- gleam_stdlib:identity(Builders).
-
--spec new() -> bytes_builder().
-new() ->
- gleam_stdlib:identity([]).
-
--spec from_string(binary()) -> bytes_builder().
-from_string(String) ->
- gleam_stdlib:wrap_list(String).
-
--spec prepend_string(bytes_builder(), binary()) -> bytes_builder().
-prepend_string(Second, First) ->
- gleam_stdlib:iodata_append(gleam_stdlib:wrap_list(First), Second).
-
--spec append_string(bytes_builder(), binary()) -> bytes_builder().
-append_string(First, Second) ->
- gleam_stdlib:iodata_append(First, gleam_stdlib:wrap_list(Second)).
-
--spec from_string_builder(gleam@string_builder:string_builder()) -> bytes_builder().
-from_string_builder(Builder) ->
- gleam_stdlib:wrap_list(Builder).
-
--spec from_bit_array(bitstring()) -> bytes_builder().
-from_bit_array(Bits) ->
- gleam_stdlib:wrap_list(Bits).
-
--spec prepend(bytes_builder(), bitstring()) -> bytes_builder().
-prepend(Second, First) ->
- gleam_stdlib:iodata_append(gleam_stdlib:wrap_list(First), Second).
-
--spec append(bytes_builder(), bitstring()) -> bytes_builder().
-append(First, Second) ->
- gleam_stdlib:iodata_append(First, gleam_stdlib:wrap_list(Second)).
-
--spec concat_bit_arrays(list(bitstring())) -> bytes_builder().
-concat_bit_arrays(Bits) ->
- gleam_stdlib:identity(Bits).
-
--spec to_list(list(list(bytes_builder())), list(bitstring())) -> list(bitstring()).
-to_list(Stack, Acc) ->
- case Stack of
- [] ->
- Acc;
-
- [[] | Remaining_stack] ->
- to_list(Remaining_stack, Acc);
-
- [[{bytes, Bits} | Rest] | Remaining_stack@1] ->
- to_list([Rest | Remaining_stack@1], [Bits | Acc]);
-
- [[{text, Builder} | Rest@1] | Remaining_stack@2] ->
- Bits@1 = gleam_stdlib:identity(
- gleam@string_builder:to_string(Builder)
- ),
- to_list([Rest@1 | Remaining_stack@2], [Bits@1 | Acc]);
-
- [[{many, Builders} | Rest@2] | Remaining_stack@3] ->
- to_list([Builders, Rest@2 | Remaining_stack@3], Acc)
- end.
-
--spec to_bit_array(bytes_builder()) -> bitstring().
-to_bit_array(Builder) ->
- erlang:list_to_bitstring(Builder).
-
--spec byte_size(bytes_builder()) -> integer().
-byte_size(Builder) ->
- erlang:iolist_size(Builder).
diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam@dict.erl b/aoc2023/build/packages/gleam_stdlib/src/gleam@dict.erl
deleted file mode 100644
index 44b89ea..0000000
--- a/aoc2023/build/packages/gleam_stdlib/src/gleam@dict.erl
+++ /dev/null
@@ -1,97 +0,0 @@
--module(gleam@dict).
--compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]).
-
--export([size/1, to_list/1, from_list/1, has_key/2, new/0, get/2, insert/3, map_values/2, keys/1, values/1, filter/2, take/2, merge/2, delete/2, drop/2, update/3, fold/3]).
--export_type([dict/2]).
-
--type dict(KS, KT) :: any() | {gleam_phantom, KS, KT}.
-
--spec size(dict(any(), any())) -> integer().
-size(Dict) ->
- maps:size(Dict).
-
--spec to_list(dict(LC, LD)) -> list({LC, LD}).
-to_list(Dict) ->
- maps:to_list(Dict).
-
--spec from_list(list({LM, LN})) -> dict(LM, LN).
-from_list(List) ->
- maps:from_list(List).
-
--spec has_key(dict(LW, any()), LW) -> boolean().
-has_key(Dict, Key) ->
- maps:is_key(Key, Dict).
-
--spec new() -> dict(any(), any()).
-new() ->
- maps:new().
-
--spec get(dict(MM, MN), MM) -> {ok, MN} | {error, nil}.
-get(From, Get) ->
- gleam_stdlib:map_get(From, Get).
-
--spec insert(dict(MY, MZ), MY, MZ) -> dict(MY, MZ).
-insert(Dict, Key, Value) ->
- maps:put(Key, Value, Dict).
-
--spec map_values(dict(NK, NL), fun((NK, NL) -> NO)) -> dict(NK, NO).
-map_values(Dict, Fun) ->
- maps:map(Fun, Dict).
-
--spec keys(dict(NY, any())) -> list(NY).
-keys(Dict) ->
- maps:keys(Dict).
-
--spec values(dict(any(), OJ)) -> list(OJ).
-values(Dict) ->
- maps:values(Dict).
-
--spec filter(dict(OS, OT), fun((OS, OT) -> boolean())) -> dict(OS, OT).
-filter(Dict, Predicate) ->
- maps:filter(Predicate, Dict).
-
--spec take(dict(PE, PF), list(PE)) -> dict(PE, PF).
-take(Dict, Desired_keys) ->
- maps:with(Desired_keys, Dict).
-
--spec merge(dict(PS, PT), dict(PS, PT)) -> dict(PS, PT).
-merge(Dict, New_entries) ->
- maps:merge(Dict, New_entries).
-
--spec delete(dict(QI, QJ), QI) -> dict(QI, QJ).
-delete(Dict, Key) ->
- maps:remove(Key, Dict).
-
--spec drop(dict(QU, QV), list(QU)) -> dict(QU, QV).
-drop(Dict, Disallowed_keys) ->
- case Disallowed_keys of
- [] ->
- Dict;
-
- [X | Xs] ->
- drop(delete(Dict, X), Xs)
- end.
-
--spec update(dict(RB, RC), RB, fun((gleam@option:option(RC)) -> RC)) -> dict(RB, RC).
-update(Dict, Key, Fun) ->
- _pipe = Dict,
- _pipe@1 = get(_pipe, Key),
- _pipe@2 = gleam@option:from_result(_pipe@1),
- _pipe@3 = Fun(_pipe@2),
- insert(Dict, Key, _pipe@3).
-
--spec do_fold(list({RI, RJ}), RL, fun((RL, RI, RJ) -> RL)) -> RL.
-do_fold(List, Initial, Fun) ->
- case List of
- [] ->
- Initial;
-
- [{K, V} | Rest] ->
- do_fold(Rest, Fun(Initial, K, V), Fun)
- end.
-
--spec fold(dict(RM, RN), RQ, fun((RQ, RM, RN) -> RQ)) -> RQ.
-fold(Dict, Initial, Fun) ->
- _pipe = Dict,
- _pipe@1 = to_list(_pipe),
- do_fold(_pipe@1, Initial, Fun).
diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam@dynamic.erl b/aoc2023/build/packages/gleam_stdlib/src/gleam@dynamic.erl
deleted file mode 100644
index 38f4b4e..0000000
--- a/aoc2023/build/packages/gleam_stdlib/src/gleam@dynamic.erl
+++ /dev/null
@@ -1,808 +0,0 @@
--module(gleam@dynamic).
--compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]).
-
--export([from/1, unsafe_coerce/1, dynamic/1, bit_array/1, bit_string/1, classify/1, int/1, float/1, bool/1, shallow_list/1, optional/1, any/1, decode1/2, result/2, list/1, string/1, field/2, optional_field/2, element/2, tuple2/2, tuple3/3, tuple4/4, tuple5/5, tuple6/6, dict/2, map/2, decode2/3, decode3/4, decode4/5, decode5/6, decode6/7, decode7/8, decode8/9, decode9/10]).
--export_type([dynamic_/0, decode_error/0, unknown_tuple/0]).
-
--type dynamic_() :: any().
-
--type decode_error() :: {decode_error, binary(), binary(), list(binary())}.
-
--type unknown_tuple() :: any().
-
--spec from(any()) -> dynamic_().
-from(A) ->
- gleam_stdlib:identity(A).
-
--spec unsafe_coerce(dynamic_()) -> any().
-unsafe_coerce(A) ->
- gleam_stdlib:identity(A).
-
--spec dynamic(dynamic_()) -> {ok, dynamic_()} | {error, list(decode_error())}.
-dynamic(Value) ->
- {ok, Value}.
-
--spec bit_array(dynamic_()) -> {ok, bitstring()} | {error, list(decode_error())}.
-bit_array(Data) ->
- gleam_stdlib:decode_bit_array(Data).
-
--spec bit_string(dynamic_()) -> {ok, bitstring()} |
- {error, list(decode_error())}.
-bit_string(Data) ->
- bit_array(Data).
-
--spec put_expected(decode_error(), binary()) -> decode_error().
-put_expected(Error, Expected) ->
- erlang:setelement(2, Error, Expected).
-
--spec classify(dynamic_()) -> binary().
-classify(Data) ->
- gleam_stdlib:classify_dynamic(Data).
-
--spec int(dynamic_()) -> {ok, integer()} | {error, list(decode_error())}.
-int(Data) ->
- gleam_stdlib:decode_int(Data).
-
--spec float(dynamic_()) -> {ok, float()} | {error, list(decode_error())}.
-float(Data) ->
- gleam_stdlib:decode_float(Data).
-
--spec bool(dynamic_()) -> {ok, boolean()} | {error, list(decode_error())}.
-bool(Data) ->
- gleam_stdlib:decode_bool(Data).
-
--spec shallow_list(dynamic_()) -> {ok, list(dynamic_())} |
- {error, list(decode_error())}.
-shallow_list(Value) ->
- gleam_stdlib:decode_list(Value).
-
--spec optional(fun((dynamic_()) -> {ok, DZX} | {error, list(decode_error())})) -> fun((dynamic_()) -> {ok,
- gleam@option:option(DZX)} |
- {error, list(decode_error())}).
-optional(Decode) ->
- fun(Value) -> gleam_stdlib:decode_option(Value, Decode) end.
-
--spec at_least_decode_tuple_error(integer(), dynamic_()) -> {ok, any()} |
- {error, list(decode_error())}.
-at_least_decode_tuple_error(Size, Data) ->
- S = case Size of
- 1 ->
- <<""/utf8>>;
-
- _ ->
- <<"s"/utf8>>
- end,
- Error = begin
- _pipe = [<<"Tuple of at least "/utf8>>,
- gleam@int:to_string(Size),
- <<" element"/utf8>>,
- S],
- _pipe@1 = gleam@string_builder:from_strings(_pipe),
- _pipe@2 = gleam@string_builder:to_string(_pipe@1),
- {decode_error, _pipe@2, classify(Data), []}
- end,
- {error, [Error]}.
-
--spec any(list(fun((dynamic_()) -> {ok, EEE} | {error, list(decode_error())}))) -> fun((dynamic_()) -> {ok,
- EEE} |
- {error, list(decode_error())}).
-any(Decoders) ->
- fun(Data) -> case Decoders of
- [] ->
- {error,
- [{decode_error, <<"another type"/utf8>>, classify(Data), []}]};
-
- [Decoder | Decoders@1] ->
- case Decoder(Data) of
- {ok, Decoded} ->
- {ok, Decoded};
-
- {error, _} ->
- (any(Decoders@1))(Data)
- end
- end end.
-
--spec all_errors({ok, any()} | {error, list(decode_error())}) -> list(decode_error()).
-all_errors(Result) ->
- case Result of
- {ok, _} ->
- [];
-
- {error, Errors} ->
- Errors
- end.
-
--spec decode1(
- fun((EEI) -> EEJ),
- fun((dynamic_()) -> {ok, EEI} | {error, list(decode_error())})
-) -> fun((dynamic_()) -> {ok, EEJ} | {error, list(decode_error())}).
-decode1(Constructor, T1) ->
- fun(Value) -> case T1(Value) of
- {ok, A} ->
- {ok, Constructor(A)};
-
- A@1 ->
- {error, all_errors(A@1)}
- end end.
-
--spec push_path(decode_error(), any()) -> decode_error().
-push_path(Error, Name) ->
- Name@1 = from(Name),
- Decoder = any(
- [fun string/1,
- fun(X) -> gleam@result:map(int(X), fun gleam@int:to_string/1) end]
- ),
- Name@3 = case Decoder(Name@1) of
- {ok, Name@2} ->
- Name@2;
-
- {error, _} ->
- _pipe = [<<"<"/utf8>>, classify(Name@1), <<">"/utf8>>],
- _pipe@1 = gleam@string_builder:from_strings(_pipe),
- gleam@string_builder:to_string(_pipe@1)
- end,
- erlang:setelement(4, Error, [Name@3 | erlang:element(4, Error)]).
-
--spec result(
- fun((dynamic_()) -> {ok, DZL} | {error, list(decode_error())}),
- fun((dynamic_()) -> {ok, DZN} | {error, list(decode_error())})
-) -> fun((dynamic_()) -> {ok, {ok, DZL} | {error, DZN}} |
- {error, list(decode_error())}).
-result(Decode_ok, Decode_error) ->
- fun(Value) ->
- gleam@result:'try'(
- gleam_stdlib:decode_result(Value),
- fun(Inner_result) -> case Inner_result of
- {ok, Raw} ->
- gleam@result:'try'(
- begin
- _pipe = Decode_ok(Raw),
- map_errors(
- _pipe,
- fun(_capture) ->
- push_path(_capture, <<"ok"/utf8>>)
- end
- )
- end,
- fun(Value@1) -> {ok, {ok, Value@1}} end
- );
-
- {error, Raw@1} ->
- gleam@result:'try'(
- begin
- _pipe@1 = Decode_error(Raw@1),
- map_errors(
- _pipe@1,
- fun(_capture@1) ->
- push_path(_capture@1, <<"error"/utf8>>)
- end
- )
- end,
- fun(Value@2) -> {ok, {error, Value@2}} end
- )
- end end
- )
- end.
-
--spec list(fun((dynamic_()) -> {ok, DZS} | {error, list(decode_error())})) -> fun((dynamic_()) -> {ok,
- list(DZS)} |
- {error, list(decode_error())}).
-list(Decoder_type) ->
- fun(Dynamic) ->
- gleam@result:'try'(shallow_list(Dynamic), fun(List) -> _pipe = List,
- _pipe@1 = gleam@list:try_map(_pipe, Decoder_type),
- map_errors(
- _pipe@1,
- fun(_capture) -> push_path(_capture, <<"*"/utf8>>) end
- ) end)
- end.
-
--spec map_errors(
- {ok, DYG} | {error, list(decode_error())},
- fun((decode_error()) -> decode_error())
-) -> {ok, DYG} | {error, list(decode_error())}.
-map_errors(Result, F) ->
- gleam@result:map_error(
- Result,
- fun(_capture) -> gleam@list:map(_capture, F) end
- ).
-
--spec decode_string(dynamic_()) -> {ok, binary()} |
- {error, list(decode_error())}.
-decode_string(Data) ->
- _pipe = bit_array(Data),
- _pipe@1 = map_errors(
- _pipe,
- fun(_capture) -> put_expected(_capture, <<"String"/utf8>>) end
- ),
- gleam@result:'try'(
- _pipe@1,
- fun(Raw) -> case gleam@bit_array:to_string(Raw) of
- {ok, String} ->
- {ok, String};
-
- {error, nil} ->
- {error,
- [{decode_error,
- <<"String"/utf8>>,
- <<"BitArray"/utf8>>,
- []}]}
- end end
- ).
-
--spec string(dynamic_()) -> {ok, binary()} | {error, list(decode_error())}.
-string(Data) ->
- decode_string(Data).
-
--spec field(
- any(),
- fun((dynamic_()) -> {ok, EAH} | {error, list(decode_error())})
-) -> fun((dynamic_()) -> {ok, EAH} | {error, list(decode_error())}).
-field(Name, Inner_type) ->
- fun(Value) ->
- Missing_field_error = {decode_error,
- <<"field"/utf8>>,
- <<"nothing"/utf8>>,
- []},
- gleam@result:'try'(
- gleam_stdlib:decode_field(Value, Name),
- fun(Maybe_inner) -> _pipe = Maybe_inner,
- _pipe@1 = gleam@option:to_result(_pipe, [Missing_field_error]),
- _pipe@2 = gleam@result:'try'(_pipe@1, Inner_type),
- map_errors(
- _pipe@2,
- fun(_capture) -> push_path(_capture, Name) end
- ) end
- )
- end.
-
--spec optional_field(
- any(),
- fun((dynamic_()) -> {ok, EAL} | {error, list(decode_error())})
-) -> fun((dynamic_()) -> {ok, gleam@option:option(EAL)} |
- {error, list(decode_error())}).
-optional_field(Name, Inner_type) ->
- fun(Value) ->
- gleam@result:'try'(
- gleam_stdlib:decode_field(Value, Name),
- fun(Maybe_inner) -> case Maybe_inner of
- none ->
- {ok, none};
-
- {some, Dynamic_inner} ->
- _pipe = Dynamic_inner,
- _pipe@1 = gleam_stdlib:decode_option(_pipe, Inner_type),
- map_errors(
- _pipe@1,
- fun(_capture) -> push_path(_capture, Name) end
- )
- end end
- )
- end.
-
--spec element(
- integer(),
- fun((dynamic_()) -> {ok, EAT} | {error, list(decode_error())})
-) -> fun((dynamic_()) -> {ok, EAT} | {error, list(decode_error())}).
-element(Index, Inner_type) ->
- fun(Data) ->
- gleam@result:'try'(
- gleam_stdlib:decode_tuple(Data),
- fun(Tuple) ->
- Size = gleam_stdlib:size_of_tuple(Tuple),
- gleam@result:'try'(case Index >= 0 of
- true ->
- case Index < Size of
- true ->
- gleam_stdlib:tuple_get(Tuple, Index);
-
- false ->
- at_least_decode_tuple_error(Index + 1, Data)
- end;
-
- false ->
- case gleam@int:absolute_value(Index) =< Size of
- true ->
- gleam_stdlib:tuple_get(Tuple, Size + Index);
-
- false ->
- at_least_decode_tuple_error(
- gleam@int:absolute_value(Index),
- Data
- )
- end
- end, fun(Data@1) -> _pipe = Inner_type(Data@1),
- map_errors(
- _pipe,
- fun(_capture) -> push_path(_capture, Index) end
- ) end)
- end
- )
- end.
-
--spec tuple_errors({ok, any()} | {error, list(decode_error())}, binary()) -> list(decode_error()).
-tuple_errors(Result, Name) ->
- case Result of
- {ok, _} ->
- [];
-
- {error, Errors} ->
- gleam@list:map(
- Errors,
- fun(_capture) -> push_path(_capture, Name) end
- )
- end.
-
--spec tuple2(
- fun((dynamic_()) -> {ok, EBT} | {error, list(decode_error())}),
- fun((dynamic_()) -> {ok, EBV} | {error, list(decode_error())})
-) -> fun((dynamic_()) -> {ok, {EBT, EBV}} | {error, list(decode_error())}).
-tuple2(Decode1, Decode2) ->
- fun(Value) ->
- gleam@result:'try'(
- gleam_stdlib:decode_tuple2(Value),
- fun(_use0) ->
- {A, B} = _use0,
- case {Decode1(A), Decode2(B)} of
- {{ok, A@1}, {ok, B@1}} ->
- {ok, {A@1, B@1}};
-
- {A@2, B@2} ->
- _pipe = tuple_errors(A@2, <<"0"/utf8>>),
- _pipe@1 = gleam@list:append(
- _pipe,
- tuple_errors(B@2, <<"1"/utf8>>)
- ),
- {error, _pipe@1}
- end
- end
- )
- end.
-
--spec tuple3(
- fun((dynamic_()) -> {ok, EBY} | {error, list(decode_error())}),
- fun((dynamic_()) -> {ok, ECA} | {error, list(decode_error())}),
- fun((dynamic_()) -> {ok, ECC} | {error, list(decode_error())})
-) -> fun((dynamic_()) -> {ok, {EBY, ECA, ECC}} | {error, list(decode_error())}).
-tuple3(Decode1, Decode2, Decode3) ->
- fun(Value) ->
- gleam@result:'try'(
- gleam_stdlib:decode_tuple3(Value),
- fun(_use0) ->
- {A, B, C} = _use0,
- case {Decode1(A), Decode2(B), Decode3(C)} of
- {{ok, A@1}, {ok, B@1}, {ok, C@1}} ->
- {ok, {A@1, B@1, C@1}};
-
- {A@2, B@2, C@2} ->
- _pipe = tuple_errors(A@2, <<"0"/utf8>>),
- _pipe@1 = gleam@list:append(
- _pipe,
- tuple_errors(B@2, <<"1"/utf8>>)
- ),
- _pipe@2 = gleam@list:append(
- _pipe@1,
- tuple_errors(C@2, <<"2"/utf8>>)
- ),
- {error, _pipe@2}
- end
- end
- )
- end.
-
--spec tuple4(
- fun((dynamic_()) -> {ok, ECF} | {error, list(decode_error())}),
- fun((dynamic_()) -> {ok, ECH} | {error, list(decode_error())}),
- fun((dynamic_()) -> {ok, ECJ} | {error, list(decode_error())}),
- fun((dynamic_()) -> {ok, ECL} | {error, list(decode_error())})
-) -> fun((dynamic_()) -> {ok, {ECF, ECH, ECJ, ECL}} |
- {error, list(decode_error())}).
-tuple4(Decode1, Decode2, Decode3, Decode4) ->
- fun(Value) ->
- gleam@result:'try'(
- gleam_stdlib:decode_tuple4(Value),
- fun(_use0) ->
- {A, B, C, D} = _use0,
- case {Decode1(A), Decode2(B), Decode3(C), Decode4(D)} of
- {{ok, A@1}, {ok, B@1}, {ok, C@1}, {ok, D@1}} ->
- {ok, {A@1, B@1, C@1, D@1}};
-
- {A@2, B@2, C@2, D@2} ->
- _pipe = tuple_errors(A@2, <<"0"/utf8>>),
- _pipe@1 = gleam@list:append(
- _pipe,
- tuple_errors(B@2, <<"1"/utf8>>)
- ),
- _pipe@2 = gleam@list:append(
- _pipe@1,
- tuple_errors(C@2, <<"2"/utf8>>)
- ),
- _pipe@3 = gleam@list:append(
- _pipe@2,
- tuple_errors(D@2, <<"3"/utf8>>)
- ),
- {error, _pipe@3}
- end
- end
- )
- end.
-
--spec tuple5(
- fun((dynamic_()) -> {ok, ECO} | {error, list(decode_error())}),
- fun((dynamic_()) -> {ok, ECQ} | {error, list(decode_error())}),
- fun((dynamic_()) -> {ok, ECS} | {error, list(decode_error())}),
- fun((dynamic_()) -> {ok, ECU} | {error, list(decode_error())}),
- fun((dynamic_()) -> {ok, ECW} | {error, list(decode_error())})
-) -> fun((dynamic_()) -> {ok, {ECO, ECQ, ECS, ECU, ECW}} |
- {error, list(decode_error())}).
-tuple5(Decode1, Decode2, Decode3, Decode4, Decode5) ->
- fun(Value) ->
- gleam@result:'try'(
- gleam_stdlib:decode_tuple5(Value),
- fun(_use0) ->
- {A, B, C, D, E} = _use0,
- case {Decode1(A),
- Decode2(B),
- Decode3(C),
- Decode4(D),
- Decode5(E)} of
- {{ok, A@1}, {ok, B@1}, {ok, C@1}, {ok, D@1}, {ok, E@1}} ->
- {ok, {A@1, B@1, C@1, D@1, E@1}};
-
- {A@2, B@2, C@2, D@2, E@2} ->
- _pipe = tuple_errors(A@2, <<"0"/utf8>>),
- _pipe@1 = gleam@list:append(
- _pipe,
- tuple_errors(B@2, <<"1"/utf8>>)
- ),
- _pipe@2 = gleam@list:append(
- _pipe@1,
- tuple_errors(C@2, <<"2"/utf8>>)
- ),
- _pipe@3 = gleam@list:append(
- _pipe@2,
- tuple_errors(D@2, <<"3"/utf8>>)
- ),
- _pipe@4 = gleam@list:append(
- _pipe@3,
- tuple_errors(E@2, <<"4"/utf8>>)
- ),
- {error, _pipe@4}
- end
- end
- )
- end.
-
--spec tuple6(
- fun((dynamic_()) -> {ok, ECZ} | {error, list(decode_error())}),
- fun((dynamic_()) -> {ok, EDB} | {error, list(decode_error())}),
- fun((dynamic_()) -> {ok, EDD} | {error, list(decode_error())}),
- fun((dynamic_()) -> {ok, EDF} | {error, list(decode_error())}),
- fun((dynamic_()) -> {ok, EDH} | {error, list(decode_error())}),
- fun((dynamic_()) -> {ok, EDJ} | {error, list(decode_error())})
-) -> fun((dynamic_()) -> {ok, {ECZ, EDB, EDD, EDF, EDH, EDJ}} |
- {error, list(decode_error())}).
-tuple6(Decode1, Decode2, Decode3, Decode4, Decode5, Decode6) ->
- fun(Value) ->
- gleam@result:'try'(
- gleam_stdlib:decode_tuple6(Value),
- fun(_use0) ->
- {A, B, C, D, E, F} = _use0,
- case {Decode1(A),
- Decode2(B),
- Decode3(C),
- Decode4(D),
- Decode5(E),
- Decode6(F)} of
- {{ok, A@1},
- {ok, B@1},
- {ok, C@1},
- {ok, D@1},
- {ok, E@1},
- {ok, F@1}} ->
- {ok, {A@1, B@1, C@1, D@1, E@1, F@1}};
-
- {A@2, B@2, C@2, D@2, E@2, F@2} ->
- _pipe = tuple_errors(A@2, <<"0"/utf8>>),
- _pipe@1 = gleam@list:append(
- _pipe,
- tuple_errors(B@2, <<"1"/utf8>>)
- ),
- _pipe@2 = gleam@list:append(
- _pipe@1,
- tuple_errors(C@2, <<"2"/utf8>>)
- ),
- _pipe@3 = gleam@list:append(
- _pipe@2,
- tuple_errors(D@2, <<"3"/utf8>>)
- ),
- _pipe@4 = gleam@list:append(
- _pipe@3,
- tuple_errors(E@2, <<"4"/utf8>>)
- ),
- _pipe@5 = gleam@list:append(
- _pipe@4,
- tuple_errors(F@2, <<"5"/utf8>>)
- ),
- {error, _pipe@5}
- end
- end
- )
- end.
-
--spec dict(
- fun((dynamic_()) -> {ok, EDM} | {error, list(decode_error())}),
- fun((dynamic_()) -> {ok, EDO} | {error, list(decode_error())})
-) -> fun((dynamic_()) -> {ok, gleam@dict:dict(EDM, EDO)} |
- {error, list(decode_error())}).
-dict(Key_type, Value_type) ->
- fun(Value) ->
- gleam@result:'try'(
- gleam_stdlib:decode_map(Value),
- fun(Map) ->
- gleam@result:'try'(
- begin
- _pipe = Map,
- _pipe@1 = gleam@dict:to_list(_pipe),
- gleam@list:try_map(
- _pipe@1,
- fun(Pair) ->
- {K, V} = Pair,
- gleam@result:'try'(
- begin
- _pipe@2 = Key_type(K),
- map_errors(
- _pipe@2,
- fun(_capture) ->
- push_path(
- _capture,
- <<"keys"/utf8>>
- )
- end
- )
- end,
- fun(K@1) ->
- gleam@result:'try'(
- begin
- _pipe@3 = Value_type(V),
- map_errors(
- _pipe@3,
- fun(_capture@1) ->
- push_path(
- _capture@1,
- <<"values"/utf8>>
- )
- end
- )
- end,
- fun(V@1) -> {ok, {K@1, V@1}} end
- )
- end
- )
- end
- )
- end,
- fun(Pairs) -> {ok, gleam@dict:from_list(Pairs)} end
- )
- end
- )
- end.
-
--spec map(
- fun((dynamic_()) -> {ok, EDT} | {error, list(decode_error())}),
- fun((dynamic_()) -> {ok, EDV} | {error, list(decode_error())})
-) -> fun((dynamic_()) -> {ok, gleam@dict:dict(EDT, EDV)} |
- {error, list(decode_error())}).
-map(Key_type, Value_type) ->
- dict(Key_type, Value_type).
-
--spec decode2(
- fun((EEM, EEN) -> EEO),
- fun((dynamic_()) -> {ok, EEM} | {error, list(decode_error())}),
- fun((dynamic_()) -> {ok, EEN} | {error, list(decode_error())})
-) -> fun((dynamic_()) -> {ok, EEO} | {error, list(decode_error())}).
-decode2(Constructor, T1, T2) ->
- fun(Value) -> case {T1(Value), T2(Value)} of
- {{ok, A}, {ok, B}} ->
- {ok, Constructor(A, B)};
-
- {A@1, B@1} ->
- {error, gleam@list:concat([all_errors(A@1), all_errors(B@1)])}
- end end.
-
--spec decode3(
- fun((EES, EET, EEU) -> EEV),
- fun((dynamic_()) -> {ok, EES} | {error, list(decode_error())}),
- fun((dynamic_()) -> {ok, EET} | {error, list(decode_error())}),
- fun((dynamic_()) -> {ok, EEU} | {error, list(decode_error())})
-) -> fun((dynamic_()) -> {ok, EEV} | {error, list(decode_error())}).
-decode3(Constructor, T1, T2, T3) ->
- fun(Value) -> case {T1(Value), T2(Value), T3(Value)} of
- {{ok, A}, {ok, B}, {ok, C}} ->
- {ok, Constructor(A, B, C)};
-
- {A@1, B@1, C@1} ->
- {error,
- gleam@list:concat(
- [all_errors(A@1), all_errors(B@1), all_errors(C@1)]
- )}
- end end.
-
--spec decode4(
- fun((EFA, EFB, EFC, EFD) -> EFE),
- fun((dynamic_()) -> {ok, EFA} | {error, list(decode_error())}),
- fun((dynamic_()) -> {ok, EFB} | {error, list(decode_error())}),
- fun((dynamic_()) -> {ok, EFC} | {error, list(decode_error())}),
- fun((dynamic_()) -> {ok, EFD} | {error, list(decode_error())})
-) -> fun((dynamic_()) -> {ok, EFE} | {error, list(decode_error())}).
-decode4(Constructor, T1, T2, T3, T4) ->
- fun(X) -> case {T1(X), T2(X), T3(X), T4(X)} of
- {{ok, A}, {ok, B}, {ok, C}, {ok, D}} ->
- {ok, Constructor(A, B, C, D)};
-
- {A@1, B@1, C@1, D@1} ->
- {error,
- gleam@list:concat(
- [all_errors(A@1),
- all_errors(B@1),
- all_errors(C@1),
- all_errors(D@1)]
- )}
- end end.
-
--spec decode5(
- fun((EFK, EFL, EFM, EFN, EFO) -> EFP),
- fun((dynamic_()) -> {ok, EFK} | {error, list(decode_error())}),
- fun((dynamic_()) -> {ok, EFL} | {error, list(decode_error())}),
- fun((dynamic_()) -> {ok, EFM} | {error, list(decode_error())}),
- fun((dynamic_()) -> {ok, EFN} | {error, list(decode_error())}),
- fun((dynamic_()) -> {ok, EFO} | {error, list(decode_error())})
-) -> fun((dynamic_()) -> {ok, EFP} | {error, list(decode_error())}).
-decode5(Constructor, T1, T2, T3, T4, T5) ->
- fun(X) -> case {T1(X), T2(X), T3(X), T4(X), T5(X)} of
- {{ok, A}, {ok, B}, {ok, C}, {ok, D}, {ok, E}} ->
- {ok, Constructor(A, B, C, D, E)};
-
- {A@1, B@1, C@1, D@1, E@1} ->
- {error,
- gleam@list:concat(
- [all_errors(A@1),
- all_errors(B@1),
- all_errors(C@1),
- all_errors(D@1),
- all_errors(E@1)]
- )}
- end end.
-
--spec decode6(
- fun((EFW, EFX, EFY, EFZ, EGA, EGB) -> EGC),
- fun((dynamic_()) -> {ok, EFW} | {error, list(decode_error())}),
- fun((dynamic_()) -> {ok, EFX} | {error, list(decode_error())}),
- fun((dynamic_()) -> {ok, EFY} | {error, list(decode_error())}),
- fun((dynamic_()) -> {ok, EFZ} | {error, list(decode_error())}),
- fun((dynamic_()) -> {ok, EGA} | {error, list(decode_error())}),
- fun((dynamic_()) -> {ok, EGB} | {error, list(decode_error())})
-) -> fun((dynamic_()) -> {ok, EGC} | {error, list(decode_error())}).
-decode6(Constructor, T1, T2, T3, T4, T5, T6) ->
- fun(X) -> case {T1(X), T2(X), T3(X), T4(X), T5(X), T6(X)} of
- {{ok, A}, {ok, B}, {ok, C}, {ok, D}, {ok, E}, {ok, F}} ->
- {ok, Constructor(A, B, C, D, E, F)};
-
- {A@1, B@1, C@1, D@1, E@1, F@1} ->
- {error,
- gleam@list:concat(
- [all_errors(A@1),
- all_errors(B@1),
- all_errors(C@1),
- all_errors(D@1),
- all_errors(E@1),
- all_errors(F@1)]
- )}
- end end.
-
--spec decode7(
- fun((EGK, EGL, EGM, EGN, EGO, EGP, EGQ) -> EGR),
- fun((dynamic_()) -> {ok, EGK} | {error, list(decode_error())}),
- fun((dynamic_()) -> {ok, EGL} | {error, list(decode_error())}),
- fun((dynamic_()) -> {ok, EGM} | {error, list(decode_error())}),
- fun((dynamic_()) -> {ok, EGN} | {error, list(decode_error())}),
- fun((dynamic_()) -> {ok, EGO} | {error, list(decode_error())}),
- fun((dynamic_()) -> {ok, EGP} | {error, list(decode_error())}),
- fun((dynamic_()) -> {ok, EGQ} | {error, list(decode_error())})
-) -> fun((dynamic_()) -> {ok, EGR} | {error, list(decode_error())}).
-decode7(Constructor, T1, T2, T3, T4, T5, T6, T7) ->
- fun(X) -> case {T1(X), T2(X), T3(X), T4(X), T5(X), T6(X), T7(X)} of
- {{ok, A}, {ok, B}, {ok, C}, {ok, D}, {ok, E}, {ok, F}, {ok, G}} ->
- {ok, Constructor(A, B, C, D, E, F, G)};
-
- {A@1, B@1, C@1, D@1, E@1, F@1, G@1} ->
- {error,
- gleam@list:concat(
- [all_errors(A@1),
- all_errors(B@1),
- all_errors(C@1),
- all_errors(D@1),
- all_errors(E@1),
- all_errors(F@1),
- all_errors(G@1)]
- )}
- end end.
-
--spec decode8(
- fun((EHA, EHB, EHC, EHD, EHE, EHF, EHG, EHH) -> EHI),
- fun((dynamic_()) -> {ok, EHA} | {error, list(decode_error())}),
- fun((dynamic_()) -> {ok, EHB} | {error, list(decode_error())}),
- fun((dynamic_()) -> {ok, EHC} | {error, list(decode_error())}),
- fun((dynamic_()) -> {ok, EHD} | {error, list(decode_error())}),
- fun((dynamic_()) -> {ok, EHE} | {error, list(decode_error())}),
- fun((dynamic_()) -> {ok, EHF} | {error, list(decode_error())}),
- fun((dynamic_()) -> {ok, EHG} | {error, list(decode_error())}),
- fun((dynamic_()) -> {ok, EHH} | {error, list(decode_error())})
-) -> fun((dynamic_()) -> {ok, EHI} | {error, list(decode_error())}).
-decode8(Constructor, T1, T2, T3, T4, T5, T6, T7, T8) ->
- fun(X) -> case {T1(X), T2(X), T3(X), T4(X), T5(X), T6(X), T7(X), T8(X)} of
- {{ok, A},
- {ok, B},
- {ok, C},
- {ok, D},
- {ok, E},
- {ok, F},
- {ok, G},
- {ok, H}} ->
- {ok, Constructor(A, B, C, D, E, F, G, H)};
-
- {A@1, B@1, C@1, D@1, E@1, F@1, G@1, H@1} ->
- {error,
- gleam@list:concat(
- [all_errors(A@1),
- all_errors(B@1),
- all_errors(C@1),
- all_errors(D@1),
- all_errors(E@1),
- all_errors(F@1),
- all_errors(G@1),
- all_errors(H@1)]
- )}
- end end.
-
--spec decode9(
- fun((EHS, EHT, EHU, EHV, EHW, EHX, EHY, EHZ, EIA) -> EIB),
- fun((dynamic_()) -> {ok, EHS} | {error, list(decode_error())}),
- fun((dynamic_()) -> {ok, EHT} | {error, list(decode_error())}),
- fun((dynamic_()) -> {ok, EHU} | {error, list(decode_error())}),
- fun((dynamic_()) -> {ok, EHV} | {error, list(decode_error())}),
- fun((dynamic_()) -> {ok, EHW} | {error, list(decode_error())}),
- fun((dynamic_()) -> {ok, EHX} | {error, list(decode_error())}),
- fun((dynamic_()) -> {ok, EHY} | {error, list(decode_error())}),
- fun((dynamic_()) -> {ok, EHZ} | {error, list(decode_error())}),
- fun((dynamic_()) -> {ok, EIA} | {error, list(decode_error())})
-) -> fun((dynamic_()) -> {ok, EIB} | {error, list(decode_error())}).
-decode9(Constructor, T1, T2, T3, T4, T5, T6, T7, T8, T9) ->
- fun(X) ->
- case {T1(X), T2(X), T3(X), T4(X), T5(X), T6(X), T7(X), T8(X), T9(X)} of
- {{ok, A},
- {ok, B},
- {ok, C},
- {ok, D},
- {ok, E},
- {ok, F},
- {ok, G},
- {ok, H},
- {ok, I}} ->
- {ok, Constructor(A, B, C, D, E, F, G, H, I)};
-
- {A@1, B@1, C@1, D@1, E@1, F@1, G@1, H@1, I@1} ->
- {error,
- gleam@list:concat(
- [all_errors(A@1),
- all_errors(B@1),
- all_errors(C@1),
- all_errors(D@1),
- all_errors(E@1),
- all_errors(F@1),
- all_errors(G@1),
- all_errors(H@1),
- all_errors(I@1)]
- )}
- end
- end.
diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam@float.erl b/aoc2023/build/packages/gleam_stdlib/src/gleam@float.erl
deleted file mode 100644
index 33b3d4a..0000000
--- a/aoc2023/build/packages/gleam_stdlib/src/gleam@float.erl
+++ /dev/null
@@ -1,181 +0,0 @@
--module(gleam@float).
--compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]).
-
--export([parse/1, to_string/1, compare/2, min/2, max/2, clamp/3, ceiling/1, floor/1, round/1, truncate/1, absolute_value/1, loosely_compare/3, loosely_equals/3, power/2, square_root/1, negate/1, sum/1, product/1, random/2, divide/2, add/2, multiply/2, subtract/2]).
-
--spec parse(binary()) -> {ok, float()} | {error, nil}.
-parse(String) ->
- gleam_stdlib:parse_float(String).
-
--spec to_string(float()) -> binary().
-to_string(X) ->
- gleam_stdlib:float_to_string(X).
-
--spec compare(float(), float()) -> gleam@order:order().
-compare(A, B) ->
- case A =:= B of
- true ->
- eq;
-
- false ->
- case A < B of
- true ->
- lt;
-
- false ->
- gt
- end
- end.
-
--spec min(float(), float()) -> float().
-min(A, B) ->
- case A < B of
- true ->
- A;
-
- false ->
- B
- end.
-
--spec max(float(), float()) -> float().
-max(A, B) ->
- case A > B of
- true ->
- A;
-
- false ->
- B
- end.
-
--spec clamp(float(), float(), float()) -> float().
-clamp(X, Min_bound, Max_bound) ->
- _pipe = X,
- _pipe@1 = min(_pipe, Max_bound),
- max(_pipe@1, Min_bound).
-
--spec ceiling(float()) -> float().
-ceiling(X) ->
- math:ceil(X).
-
--spec floor(float()) -> float().
-floor(X) ->
- math:floor(X).
-
--spec round(float()) -> integer().
-round(X) ->
- erlang:round(X).
-
--spec truncate(float()) -> integer().
-truncate(X) ->
- erlang:trunc(X).
-
--spec absolute_value(float()) -> float().
-absolute_value(X) ->
- case X >= +0.0 of
- true ->
- X;
-
- _ ->
- +0.0 - X
- end.
-
--spec loosely_compare(float(), float(), float()) -> gleam@order:order().
-loosely_compare(A, B, Tolerance) ->
- Difference = absolute_value(A - B),
- case Difference =< Tolerance of
- true ->
- eq;
-
- false ->
- compare(A, B)
- end.
-
--spec loosely_equals(float(), float(), float()) -> boolean().
-loosely_equals(A, B, Tolerance) ->
- Difference = absolute_value(A - B),
- Difference =< Tolerance.
-
--spec power(float(), float()) -> {ok, float()} | {error, nil}.
-power(Base, Exponent) ->
- Fractional = (ceiling(Exponent) - Exponent) > +0.0,
- case ((Base < +0.0) andalso Fractional) orelse ((Base =:= +0.0) andalso (Exponent
- < +0.0)) of
- true ->
- {error, nil};
-
- false ->
- {ok, math:pow(Base, Exponent)}
- end.
-
--spec square_root(float()) -> {ok, float()} | {error, nil}.
-square_root(X) ->
- power(X, 0.5).
-
--spec negate(float()) -> float().
-negate(X) ->
- -1.0 * X.
-
--spec do_sum(list(float()), float()) -> float().
-do_sum(Numbers, Initial) ->
- case Numbers of
- [] ->
- Initial;
-
- [X | Rest] ->
- do_sum(Rest, X + Initial)
- end.
-
--spec sum(list(float())) -> float().
-sum(Numbers) ->
- _pipe = Numbers,
- do_sum(_pipe, +0.0).
-
--spec do_product(list(float()), float()) -> float().
-do_product(Numbers, Initial) ->
- case Numbers of
- [] ->
- Initial;
-
- [X | Rest] ->
- do_product(Rest, X * Initial)
- end.
-
--spec product(list(float())) -> float().
-product(Numbers) ->
- case Numbers of
- [] ->
- 1.0;
-
- _ ->
- do_product(Numbers, 1.0)
- end.
-
--spec random(float(), float()) -> float().
-random(Min, Max) ->
- (rand:uniform() * (Max - Min)) + Min.
-
--spec divide(float(), float()) -> {ok, float()} | {error, nil}.
-divide(A, B) ->
- case B of
- +0.0 ->
- {error, nil};
-
- B@1 ->
- {ok, case B@1 of
- +0.0 -> +0.0;
- -0.0 -> -0.0;
- Gleam@denominator -> A / Gleam@denominator
- end}
- end.
-
--spec add(float(), float()) -> float().
-add(A, B) ->
- A + B.
-
--spec multiply(float(), float()) -> float().
-multiply(A, B) ->
- A * B.
-
--spec subtract(float(), float()) -> float().
-subtract(A, B) ->
- A - B.
diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam@function.erl b/aoc2023/build/packages/gleam_stdlib/src/gleam@function.erl
deleted file mode 100644
index 3496318..0000000
--- a/aoc2023/build/packages/gleam_stdlib/src/gleam@function.erl
+++ /dev/null
@@ -1,67 +0,0 @@
--module(gleam@function).
--compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]).
-
--export([compose/2, curry2/1, curry3/1, curry4/1, curry5/1, curry6/1, flip/1, identity/1, constant/1, tap/2, apply1/2, apply2/3, apply3/4]).
-
--spec compose(fun((DOO) -> DOP), fun((DOP) -> DOQ)) -> fun((DOO) -> DOQ).
-compose(Fun1, Fun2) ->
- fun(A) -> Fun2(Fun1(A)) end.
-
--spec curry2(fun((DOR, DOS) -> DOT)) -> fun((DOR) -> fun((DOS) -> DOT)).
-curry2(Fun) ->
- fun(A) -> fun(B) -> Fun(A, B) end end.
-
--spec curry3(fun((DOV, DOW, DOX) -> DOY)) -> fun((DOV) -> fun((DOW) -> fun((DOX) -> DOY))).
-curry3(Fun) ->
- fun(A) -> fun(B) -> fun(C) -> Fun(A, B, C) end end end.
-
--spec curry4(fun((DPA, DPB, DPC, DPD) -> DPE)) -> fun((DPA) -> fun((DPB) -> fun((DPC) -> fun((DPD) -> DPE)))).
-curry4(Fun) ->
- fun(A) -> fun(B) -> fun(C) -> fun(D) -> Fun(A, B, C, D) end end end end.
-
--spec curry5(fun((DPG, DPH, DPI, DPJ, DPK) -> DPL)) -> fun((DPG) -> fun((DPH) -> fun((DPI) -> fun((DPJ) -> fun((DPK) -> DPL))))).
-curry5(Fun) ->
- fun(A) ->
- fun(B) ->
- fun(C) -> fun(D) -> fun(E) -> Fun(A, B, C, D, E) end end end
- end
- end.
-
--spec curry6(fun((DPN, DPO, DPP, DPQ, DPR, DPS) -> DPT)) -> fun((DPN) -> fun((DPO) -> fun((DPP) -> fun((DPQ) -> fun((DPR) -> fun((DPS) -> DPT)))))).
-curry6(Fun) ->
- fun(A) ->
- fun(B) ->
- fun(C) ->
- fun(D) -> fun(E) -> fun(F) -> Fun(A, B, C, D, E, F) end end end
- end
- end
- end.
-
--spec flip(fun((DPV, DPW) -> DPX)) -> fun((DPW, DPV) -> DPX).
-flip(Fun) ->
- fun(B, A) -> Fun(A, B) end.
-
--spec identity(DPY) -> DPY.
-identity(X) ->
- X.
-
--spec constant(DPZ) -> fun((any()) -> DPZ).
-constant(Value) ->
- fun(_) -> Value end.
-
--spec tap(DQB, fun((DQB) -> any())) -> DQB.
-tap(Arg, Effect) ->
- Effect(Arg),
- Arg.
-
--spec apply1(fun((DQD) -> DQE), DQD) -> DQE.
-apply1(Fun, Arg1) ->
- Fun(Arg1).
-
--spec apply2(fun((DQF, DQG) -> DQH), DQF, DQG) -> DQH.
-apply2(Fun, Arg1, Arg2) ->
- Fun(Arg1, Arg2).
-
--spec apply3(fun((DQI, DQJ, DQK) -> DQL), DQI, DQJ, DQK) -> DQL.
-apply3(Fun, Arg1, Arg2, Arg3) ->
- Fun(Arg1, Arg2, Arg3).
diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam@int.erl b/aoc2023/build/packages/gleam_stdlib/src/gleam@int.erl
deleted file mode 100644
index 2a5dd2c..0000000
--- a/aoc2023/build/packages/gleam_stdlib/src/gleam@int.erl
+++ /dev/null
@@ -1,332 +0,0 @@
--module(gleam@int).
--compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]).
-
--export([absolute_value/1, parse/1, base_parse/2, to_string/1, to_base_string/2, to_base2/1, to_base8/1, to_base16/1, to_base36/1, to_float/1, power/2, square_root/1, compare/2, min/2, max/2, clamp/3, is_even/1, is_odd/1, negate/1, sum/1, product/1, digits/2, undigits/2, random/2, divide/2, remainder/2, modulo/2, floor_divide/2, add/2, multiply/2, subtract/2, bitwise_and/2, bitwise_not/1, bitwise_or/2, bitwise_exclusive_or/2, bitwise_shift_left/2, bitwise_shift_right/2]).
--export_type([invalid_base/0]).
-
--type invalid_base() :: invalid_base.
-
--spec absolute_value(integer()) -> integer().
-absolute_value(X) ->
- case X >= 0 of
- true ->
- X;
-
- false ->
- X * -1
- end.
-
--spec parse(binary()) -> {ok, integer()} | {error, nil}.
-parse(String) ->
- gleam_stdlib:parse_int(String).
-
--spec base_parse(binary(), integer()) -> {ok, integer()} | {error, nil}.
-base_parse(String, Base) ->
- case (Base >= 2) andalso (Base =< 36) of
- true ->
- gleam_stdlib:int_from_base_string(String, Base);
-
- false ->
- {error, nil}
- end.
-
--spec to_string(integer()) -> binary().
-to_string(X) ->
- erlang:integer_to_binary(X).
-
--spec to_base_string(integer(), integer()) -> {ok, binary()} |
- {error, invalid_base()}.
-to_base_string(X, Base) ->
- case (Base >= 2) andalso (Base =< 36) of
- true ->
- {ok, erlang:integer_to_binary(X, Base)};
-
- false ->
- {error, invalid_base}
- end.
-
--spec to_base2(integer()) -> binary().
-to_base2(X) ->
- erlang:integer_to_binary(X, 2).
-
--spec to_base8(integer()) -> binary().
-to_base8(X) ->
- erlang:integer_to_binary(X, 8).
-
--spec to_base16(integer()) -> binary().
-to_base16(X) ->
- erlang:integer_to_binary(X, 16).
-
--spec to_base36(integer()) -> binary().
-to_base36(X) ->
- erlang:integer_to_binary(X, 36).
-
--spec to_float(integer()) -> float().
-to_float(X) ->
- erlang:float(X).
-
--spec power(integer(), float()) -> {ok, float()} | {error, nil}.
-power(Base, Exponent) ->
- _pipe = Base,
- _pipe@1 = to_float(_pipe),
- gleam@float:power(_pipe@1, Exponent).
-
--spec square_root(integer()) -> {ok, float()} | {error, nil}.
-square_root(X) ->
- _pipe = X,
- _pipe@1 = to_float(_pipe),
- gleam@float:square_root(_pipe@1).
-
--spec compare(integer(), integer()) -> gleam@order:order().
-compare(A, B) ->
- case A =:= B of
- true ->
- eq;
-
- false ->
- case A < B of
- true ->
- lt;
-
- false ->
- gt
- end
- end.
-
--spec min(integer(), integer()) -> integer().
-min(A, B) ->
- case A < B of
- true ->
- A;
-
- false ->
- B
- end.
-
--spec max(integer(), integer()) -> integer().
-max(A, B) ->
- case A > B of
- true ->
- A;
-
- false ->
- B
- end.
-
--spec clamp(integer(), integer(), integer()) -> integer().
-clamp(X, Min_bound, Max_bound) ->
- _pipe = X,
- _pipe@1 = min(_pipe, Max_bound),
- max(_pipe@1, Min_bound).
-
--spec is_even(integer()) -> boolean().
-is_even(X) ->
- (X rem 2) =:= 0.
-
--spec is_odd(integer()) -> boolean().
-is_odd(X) ->
- (X rem 2) /= 0.
-
--spec negate(integer()) -> integer().
-negate(X) ->
- -1 * X.
-
--spec do_sum(list(integer()), integer()) -> integer().
-do_sum(Numbers, Initial) ->
- case Numbers of
- [] ->
- Initial;
-
- [X | Rest] ->
- do_sum(Rest, X + Initial)
- end.
-
--spec sum(list(integer())) -> integer().
-sum(Numbers) ->
- _pipe = Numbers,
- do_sum(_pipe, 0).
-
--spec do_product(list(integer()), integer()) -> integer().
-do_product(Numbers, Initial) ->
- case Numbers of
- [] ->
- Initial;
-
- [X | Rest] ->
- do_product(Rest, X * Initial)
- end.
-
--spec product(list(integer())) -> integer().
-product(Numbers) ->
- case Numbers of
- [] ->
- 1;
-
- _ ->
- do_product(Numbers, 1)
- end.
-
--spec do_digits(integer(), integer(), list(integer())) -> list(integer()).
-do_digits(X, Base, Acc) ->
- case absolute_value(X) < Base of
- true ->
- [X | Acc];
-
- false ->
- do_digits(case Base of
- 0 -> 0;
- Gleam@denominator -> X div Gleam@denominator
- end, Base, [case Base of
- 0 -> 0;
- Gleam@denominator@1 -> X rem Gleam@denominator@1
- end | Acc])
- end.
-
--spec digits(integer(), integer()) -> {ok, list(integer())} |
- {error, invalid_base()}.
-digits(X, Base) ->
- case Base < 2 of
- true ->
- {error, invalid_base};
-
- false ->
- {ok, do_digits(X, Base, [])}
- end.
-
--spec do_undigits(list(integer()), integer(), integer()) -> {ok, integer()} |
- {error, invalid_base()}.
-do_undigits(Numbers, Base, Acc) ->
- case Numbers of
- [] ->
- {ok, Acc};
-
- [Digit | _] when Digit >= Base ->
- {error, invalid_base};
-
- [Digit@1 | Rest] ->
- do_undigits(Rest, Base, (Acc * Base) + Digit@1)
- end.
-
--spec undigits(list(integer()), integer()) -> {ok, integer()} |
- {error, invalid_base()}.
-undigits(Numbers, Base) ->
- case Base < 2 of
- true ->
- {error, invalid_base};
-
- false ->
- do_undigits(Numbers, Base, 0)
- end.
-
--spec random(integer(), integer()) -> integer().
-random(Min, Max) ->
- _pipe = gleam@float:random(to_float(Min), to_float(Max)),
- _pipe@1 = gleam@float:floor(_pipe),
- gleam@float:round(_pipe@1).
-
--spec divide(integer(), integer()) -> {ok, integer()} | {error, nil}.
-divide(Dividend, Divisor) ->
- case Divisor of
- 0 ->
- {error, nil};
-
- Divisor@1 ->
- {ok, case Divisor@1 of
- 0 -> 0;
- Gleam@denominator -> Dividend div Gleam@denominator
- end}
- end.
-
--spec remainder(integer(), integer()) -> {ok, integer()} | {error, nil}.
-remainder(Dividend, Divisor) ->
- case Divisor of
- 0 ->
- {error, nil};
-
- Divisor@1 ->
- {ok, case Divisor@1 of
- 0 -> 0;
- Gleam@denominator -> Dividend rem Gleam@denominator
- end}
- end.
-
--spec modulo(integer(), integer()) -> {ok, integer()} | {error, nil}.
-modulo(Dividend, Divisor) ->
- case Divisor of
- 0 ->
- {error, nil};
-
- _ ->
- Remainder = case Divisor of
- 0 -> 0;
- Gleam@denominator -> Dividend rem Gleam@denominator
- end,
- case (Remainder * Divisor) < 0 of
- true ->
- {ok, Remainder + Divisor};
-
- false ->
- {ok, Remainder}
- end
- end.
-
--spec floor_divide(integer(), integer()) -> {ok, integer()} | {error, nil}.
-floor_divide(Dividend, Divisor) ->
- case Divisor of
- 0 ->
- {error, nil};
-
- Divisor@1 ->
- case ((Dividend * Divisor@1) < 0) andalso ((case Divisor@1 of
- 0 -> 0;
- Gleam@denominator -> Dividend rem Gleam@denominator
- end) /= 0) of
- true ->
- {ok, (case Divisor@1 of
- 0 -> 0;
- Gleam@denominator@1 -> Dividend div Gleam@denominator@1
- end) - 1};
-
- false ->
- {ok, case Divisor@1 of
- 0 -> 0;
- Gleam@denominator@2 -> Dividend div Gleam@denominator@2
- end}
- end
- end.
-
--spec add(integer(), integer()) -> integer().
-add(A, B) ->
- A + B.
-
--spec multiply(integer(), integer()) -> integer().
-multiply(A, B) ->
- A * B.
-
--spec subtract(integer(), integer()) -> integer().
-subtract(A, B) ->
- A - B.
-
--spec bitwise_and(integer(), integer()) -> integer().
-bitwise_and(X, Y) ->
- erlang:'band'(X, Y).
-
--spec bitwise_not(integer()) -> integer().
-bitwise_not(X) ->
- erlang:'bnot'(X).
-
--spec bitwise_or(integer(), integer()) -> integer().
-bitwise_or(X, Y) ->
- erlang:'bor'(X, Y).
-
--spec bitwise_exclusive_or(integer(), integer()) -> integer().
-bitwise_exclusive_or(X, Y) ->
- erlang:'bxor'(X, Y).
-
--spec bitwise_shift_left(integer(), integer()) -> integer().
-bitwise_shift_left(X, Y) ->
- erlang:'bsl'(X, Y).
-
--spec bitwise_shift_right(integer(), integer()) -> integer().
-bitwise_shift_right(X, Y) ->
- erlang:'bsr'(X, Y).
diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam@io.erl b/aoc2023/build/packages/gleam_stdlib/src/gleam@io.erl
deleted file mode 100644
index a46eae3..0000000
--- a/aoc2023/build/packages/gleam_stdlib/src/gleam@io.erl
+++ /dev/null
@@ -1,27 +0,0 @@
--module(gleam@io).
--compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]).
-
--export([print/1, print_error/1, println/1, println_error/1, debug/1]).
-
--spec print(binary()) -> nil.
-print(String) ->
- gleam_stdlib:print(String).
-
--spec print_error(binary()) -> nil.
-print_error(String) ->
- gleam_stdlib:print_error(String).
-
--spec println(binary()) -> nil.
-println(String) ->
- gleam_stdlib:println(String).
-
--spec println_error(binary()) -> nil.
-println_error(String) ->
- gleam_stdlib:println_error(String).
-
--spec debug(CZT) -> CZT.
-debug(Term) ->
- _pipe = Term,
- _pipe@1 = gleam@string:inspect(_pipe),
- gleam_stdlib:println_error(_pipe@1),
- Term.
diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam@iterator.erl b/aoc2023/build/packages/gleam_stdlib/src/gleam@iterator.erl
deleted file mode 100644
index aa84139..0000000
--- a/aoc2023/build/packages/gleam_stdlib/src/gleam@iterator.erl
+++ /dev/null
@@ -1,744 +0,0 @@
--module(gleam@iterator).
--compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]).
-
--export([unfold/2, repeatedly/1, repeat/1, from_list/1, transform/3, fold/3, run/1, to_list/1, step/1, take/2, drop/2, map/2, map2/3, append/2, flatten/1, concat/1, flat_map/2, filter/2, cycle/1, find/2, index/1, iterate/2, take_while/2, drop_while/2, scan/3, zip/2, chunk/2, sized_chunk/2, intersperse/2, any/2, all/2, group/2, reduce/2, last/1, empty/0, once/1, range/2, single/1, interleave/2, fold_until/3, try_fold/3, first/1, at/2, length/1, each/2, yield/2]).
--export_type([action/1, iterator/1, step/2, chunk/2, sized_chunk/1]).
-
--type action(BPF) :: stop | {continue, BPF, fun(() -> action(BPF))}.
-
--opaque iterator(BPG) :: {iterator, fun(() -> action(BPG))}.
-
--type step(BPH, BPI) :: {next, BPH, BPI} | done.
-
--type chunk(BPJ, BPK) :: {another_by,
- list(BPJ),
- BPK,
- BPJ,
- fun(() -> action(BPJ))} |
- {last_by, list(BPJ)}.
-
--type sized_chunk(BPL) :: {another, list(BPL), fun(() -> action(BPL))} |
- {last, list(BPL)} |
- no_more.
-
--spec stop() -> action(any()).
-stop() ->
- stop.
-
--spec do_unfold(BPO, fun((BPO) -> step(BPP, BPO))) -> fun(() -> action(BPP)).
-do_unfold(Initial, F) ->
- fun() -> case F(Initial) of
- {next, X, Acc} ->
- {continue, X, do_unfold(Acc, F)};
-
- done ->
- stop
- end end.
-
--spec unfold(BPT, fun((BPT) -> step(BPU, BPT))) -> iterator(BPU).
-unfold(Initial, F) ->
- _pipe = Initial,
- _pipe@1 = do_unfold(_pipe, F),
- {iterator, _pipe@1}.
-
--spec repeatedly(fun(() -> BPY)) -> iterator(BPY).
-repeatedly(F) ->
- unfold(nil, fun(_) -> {next, F(), nil} end).
-
--spec repeat(BQA) -> iterator(BQA).
-repeat(X) ->
- repeatedly(fun() -> X end).
-
--spec from_list(list(BQC)) -> iterator(BQC).
-from_list(List) ->
- Yield = fun(Acc) -> case Acc of
- [] ->
- done;
-
- [Head | Tail] ->
- {next, Head, Tail}
- end end,
- unfold(List, Yield).
-
--spec do_transform(
- fun(() -> action(BQF)),
- BQH,
- fun((BQH, BQF) -> step(BQI, BQH))
-) -> fun(() -> action(BQI)).
-do_transform(Continuation, State, F) ->
- fun() -> case Continuation() of
- stop ->
- stop;
-
- {continue, El, Next} ->
- case F(State, El) of
- done ->
- stop;
-
- {next, Yield, Next_state} ->
- {continue, Yield, do_transform(Next, Next_state, F)}
- end
- end end.
-
--spec transform(iterator(BQM), BQO, fun((BQO, BQM) -> step(BQP, BQO))) -> iterator(BQP).
-transform(Iterator, Initial, F) ->
- _pipe = do_transform(erlang:element(2, Iterator), Initial, F),
- {iterator, _pipe}.
-
--spec do_fold(fun(() -> action(BQT)), fun((BQV, BQT) -> BQV), BQV) -> BQV.
-do_fold(Continuation, F, Accumulator) ->
- case Continuation() of
- {continue, Elem, Next} ->
- do_fold(Next, F, F(Accumulator, Elem));
-
- stop ->
- Accumulator
- end.
-
--spec fold(iterator(BQW), BQY, fun((BQY, BQW) -> BQY)) -> BQY.
-fold(Iterator, Initial, F) ->
- _pipe = erlang:element(2, Iterator),
- do_fold(_pipe, F, Initial).
-
--spec run(iterator(any())) -> nil.
-run(Iterator) ->
- fold(Iterator, nil, fun(_, _) -> nil end).
-
--spec to_list(iterator(BRB)) -> list(BRB).
-to_list(Iterator) ->
- _pipe = Iterator,
- _pipe@1 = fold(_pipe, [], fun(Acc, E) -> [E | Acc] end),
- gleam@list:reverse(_pipe@1).
-
--spec step(iterator(BRE)) -> step(BRE, iterator(BRE)).
-step(Iterator) ->
- case (erlang:element(2, Iterator))() of
- stop ->
- done;
-
- {continue, E, A} ->
- {next, E, {iterator, A}}
- end.
-
--spec do_take(fun(() -> action(BRJ)), integer()) -> fun(() -> action(BRJ)).
-do_take(Continuation, Desired) ->
- fun() -> case Desired > 0 of
- false ->
- stop;
-
- true ->
- case Continuation() of
- stop ->
- stop;
-
- {continue, E, Next} ->
- {continue, E, do_take(Next, Desired - 1)}
- end
- end end.
-
--spec take(iterator(BRM), integer()) -> iterator(BRM).
-take(Iterator, Desired) ->
- _pipe = erlang:element(2, Iterator),
- _pipe@1 = do_take(_pipe, Desired),
- {iterator, _pipe@1}.
-
--spec do_drop(fun(() -> action(BRP)), integer()) -> action(BRP).
-do_drop(Continuation, Desired) ->
- case Continuation() of
- stop ->
- stop;
-
- {continue, E, Next} ->
- case Desired > 0 of
- true ->
- do_drop(Next, Desired - 1);
-
- false ->
- {continue, E, Next}
- end
- end.
-
--spec drop(iterator(BRS), integer()) -> iterator(BRS).
-drop(Iterator, Desired) ->
- _pipe = fun() -> do_drop(erlang:element(2, Iterator), Desired) end,
- {iterator, _pipe}.
-
--spec do_map(fun(() -> action(BRV)), fun((BRV) -> BRX)) -> fun(() -> action(BRX)).
-do_map(Continuation, F) ->
- fun() -> case Continuation() of
- stop ->
- stop;
-
- {continue, E, Continuation@1} ->
- {continue, F(E), do_map(Continuation@1, F)}
- end end.
-
--spec map(iterator(BRZ), fun((BRZ) -> BSB)) -> iterator(BSB).
-map(Iterator, F) ->
- _pipe = erlang:element(2, Iterator),
- _pipe@1 = do_map(_pipe, F),
- {iterator, _pipe@1}.
-
--spec do_map2(
- fun(() -> action(BSD)),
- fun(() -> action(BSF)),
- fun((BSD, BSF) -> BSH)
-) -> fun(() -> action(BSH)).
-do_map2(Continuation1, Continuation2, Fun) ->
- fun() -> case Continuation1() of
- stop ->
- stop;
-
- {continue, A, Next_a} ->
- case Continuation2() of
- stop ->
- stop;
-
- {continue, B, Next_b} ->
- {continue, Fun(A, B), do_map2(Next_a, Next_b, Fun)}
- end
- end end.
-
--spec map2(iterator(BSJ), iterator(BSL), fun((BSJ, BSL) -> BSN)) -> iterator(BSN).
-map2(Iterator1, Iterator2, Fun) ->
- _pipe = do_map2(
- erlang:element(2, Iterator1),
- erlang:element(2, Iterator2),
- Fun
- ),
- {iterator, _pipe}.
-
--spec do_append(fun(() -> action(BSP)), fun(() -> action(BSP))) -> action(BSP).
-do_append(First, Second) ->
- case First() of
- {continue, E, First@1} ->
- {continue, E, fun() -> do_append(First@1, Second) end};
-
- stop ->
- Second()
- end.
-
--spec append(iterator(BST), iterator(BST)) -> iterator(BST).
-append(First, Second) ->
- _pipe = fun() ->
- do_append(erlang:element(2, First), erlang:element(2, Second))
- end,
- {iterator, _pipe}.
-
--spec do_flatten(fun(() -> action(iterator(BSX)))) -> action(BSX).
-do_flatten(Flattened) ->
- case Flattened() of
- stop ->
- stop;
-
- {continue, It, Next_iterator} ->
- do_append(
- erlang:element(2, It),
- fun() -> do_flatten(Next_iterator) end
- )
- end.
-
--spec flatten(iterator(iterator(BTB))) -> iterator(BTB).
-flatten(Iterator) ->
- _pipe = fun() -> do_flatten(erlang:element(2, Iterator)) end,
- {iterator, _pipe}.
-
--spec concat(list(iterator(BTF))) -> iterator(BTF).
-concat(Iterators) ->
- flatten(from_list(Iterators)).
-
--spec flat_map(iterator(BTJ), fun((BTJ) -> iterator(BTL))) -> iterator(BTL).
-flat_map(Iterator, F) ->
- _pipe = Iterator,
- _pipe@1 = map(_pipe, F),
- flatten(_pipe@1).
-
--spec do_filter(fun(() -> action(BTO)), fun((BTO) -> boolean())) -> action(BTO).
-do_filter(Continuation, Predicate) ->
- case Continuation() of
- stop ->
- stop;
-
- {continue, E, Iterator} ->
- case Predicate(E) of
- true ->
- {continue, E, fun() -> do_filter(Iterator, Predicate) end};
-
- false ->
- do_filter(Iterator, Predicate)
- end
- end.
-
--spec filter(iterator(BTR), fun((BTR) -> boolean())) -> iterator(BTR).
-filter(Iterator, Predicate) ->
- _pipe = fun() -> do_filter(erlang:element(2, Iterator), Predicate) end,
- {iterator, _pipe}.
-
--spec cycle(iterator(BTU)) -> iterator(BTU).
-cycle(Iterator) ->
- _pipe = repeat(Iterator),
- flatten(_pipe).
-
--spec do_find(fun(() -> action(BTY)), fun((BTY) -> boolean())) -> {ok, BTY} |
- {error, nil}.
-do_find(Continuation, F) ->
- case Continuation() of
- stop ->
- {error, nil};
-
- {continue, E, Next} ->
- case F(E) of
- true ->
- {ok, E};
-
- false ->
- do_find(Next, F)
- end
- end.
-
--spec find(iterator(BUC), fun((BUC) -> boolean())) -> {ok, BUC} | {error, nil}.
-find(Haystack, Is_desired) ->
- _pipe = erlang:element(2, Haystack),
- do_find(_pipe, Is_desired).
-
--spec do_index(fun(() -> action(BUG)), integer()) -> fun(() -> action({integer(),
- BUG})).
-do_index(Continuation, Next) ->
- fun() -> case Continuation() of
- stop ->
- stop;
-
- {continue, E, Continuation@1} ->
- {continue, {Next, E}, do_index(Continuation@1, Next + 1)}
- end end.
-
--spec index(iterator(BUJ)) -> iterator({integer(), BUJ}).
-index(Iterator) ->
- _pipe = erlang:element(2, Iterator),
- _pipe@1 = do_index(_pipe, 0),
- {iterator, _pipe@1}.
-
--spec iterate(BUM, fun((BUM) -> BUM)) -> iterator(BUM).
-iterate(Initial, F) ->
- unfold(Initial, fun(Element) -> {next, Element, F(Element)} end).
-
--spec do_take_while(fun(() -> action(BUO)), fun((BUO) -> boolean())) -> fun(() -> action(BUO)).
-do_take_while(Continuation, Predicate) ->
- fun() -> case Continuation() of
- stop ->
- stop;
-
- {continue, E, Next} ->
- case Predicate(E) of
- false ->
- stop;
-
- true ->
- {continue, E, do_take_while(Next, Predicate)}
- end
- end end.
-
--spec take_while(iterator(BUR), fun((BUR) -> boolean())) -> iterator(BUR).
-take_while(Iterator, Predicate) ->
- _pipe = erlang:element(2, Iterator),
- _pipe@1 = do_take_while(_pipe, Predicate),
- {iterator, _pipe@1}.
-
--spec do_drop_while(fun(() -> action(BUU)), fun((BUU) -> boolean())) -> action(BUU).
-do_drop_while(Continuation, Predicate) ->
- case Continuation() of
- stop ->
- stop;
-
- {continue, E, Next} ->
- case Predicate(E) of
- false ->
- {continue, E, Next};
-
- true ->
- do_drop_while(Next, Predicate)
- end
- end.
-
--spec drop_while(iterator(BUX), fun((BUX) -> boolean())) -> iterator(BUX).
-drop_while(Iterator, Predicate) ->
- _pipe = fun() -> do_drop_while(erlang:element(2, Iterator), Predicate) end,
- {iterator, _pipe}.
-
--spec do_scan(fun(() -> action(BVA)), fun((BVC, BVA) -> BVC), BVC) -> fun(() -> action(BVC)).
-do_scan(Continuation, F, Accumulator) ->
- fun() -> case Continuation() of
- stop ->
- stop;
-
- {continue, El, Next} ->
- Accumulated = F(Accumulator, El),
- {continue, Accumulated, do_scan(Next, F, Accumulated)}
- end end.
-
--spec scan(iterator(BVE), BVG, fun((BVG, BVE) -> BVG)) -> iterator(BVG).
-scan(Iterator, Initial, F) ->
- _pipe = erlang:element(2, Iterator),
- _pipe@1 = do_scan(_pipe, F, Initial),
- {iterator, _pipe@1}.
-
--spec do_zip(fun(() -> action(BVI)), fun(() -> action(BVK))) -> fun(() -> action({BVI,
- BVK})).
-do_zip(Left, Right) ->
- fun() -> case Left() of
- stop ->
- stop;
-
- {continue, El_left, Next_left} ->
- case Right() of
- stop ->
- stop;
-
- {continue, El_right, Next_right} ->
- {continue,
- {El_left, El_right},
- do_zip(Next_left, Next_right)}
- end
- end end.
-
--spec zip(iterator(BVN), iterator(BVP)) -> iterator({BVN, BVP}).
-zip(Left, Right) ->
- _pipe = do_zip(erlang:element(2, Left), erlang:element(2, Right)),
- {iterator, _pipe}.
-
--spec next_chunk(fun(() -> action(BVS)), fun((BVS) -> BVU), BVU, list(BVS)) -> chunk(BVS, BVU).
-next_chunk(Continuation, F, Previous_key, Current_chunk) ->
- case Continuation() of
- stop ->
- {last_by, gleam@list:reverse(Current_chunk)};
-
- {continue, E, Next} ->
- Key = F(E),
- case Key =:= Previous_key of
- true ->
- next_chunk(Next, F, Key, [E | Current_chunk]);
-
- false ->
- {another_by,
- gleam@list:reverse(Current_chunk),
- Key,
- E,
- Next}
- end
- end.
-
--spec do_chunk(fun(() -> action(BVY)), fun((BVY) -> BWA), BWA, BVY) -> action(list(BVY)).
-do_chunk(Continuation, F, Previous_key, Previous_element) ->
- case next_chunk(Continuation, F, Previous_key, [Previous_element]) of
- {last_by, Chunk} ->
- {continue, Chunk, fun stop/0};
-
- {another_by, Chunk@1, Key, El, Next} ->
- {continue, Chunk@1, fun() -> do_chunk(Next, F, Key, El) end}
- end.
-
--spec chunk(iterator(BWD), fun((BWD) -> any())) -> iterator(list(BWD)).
-chunk(Iterator, F) ->
- _pipe = fun() -> case (erlang:element(2, Iterator))() of
- stop ->
- stop;
-
- {continue, E, Next} ->
- do_chunk(Next, F, F(E), E)
- end end,
- {iterator, _pipe}.
-
--spec next_sized_chunk(fun(() -> action(BWI)), integer(), list(BWI)) -> sized_chunk(BWI).
-next_sized_chunk(Continuation, Left, Current_chunk) ->
- case Continuation() of
- stop ->
- case Current_chunk of
- [] ->
- no_more;
-
- Remaining ->
- {last, gleam@list:reverse(Remaining)}
- end;
-
- {continue, E, Next} ->
- Chunk = [E | Current_chunk],
- case Left > 1 of
- false ->
- {another, gleam@list:reverse(Chunk), Next};
-
- true ->
- next_sized_chunk(Next, Left - 1, Chunk)
- end
- end.
-
--spec do_sized_chunk(fun(() -> action(BWM)), integer()) -> fun(() -> action(list(BWM))).
-do_sized_chunk(Continuation, Count) ->
- fun() -> case next_sized_chunk(Continuation, Count, []) of
- no_more ->
- stop;
-
- {last, Chunk} ->
- {continue, Chunk, fun stop/0};
-
- {another, Chunk@1, Next_element} ->
- {continue, Chunk@1, do_sized_chunk(Next_element, Count)}
- end end.
-
--spec sized_chunk(iterator(BWQ), integer()) -> iterator(list(BWQ)).
-sized_chunk(Iterator, Count) ->
- _pipe = erlang:element(2, Iterator),
- _pipe@1 = do_sized_chunk(_pipe, Count),
- {iterator, _pipe@1}.
-
--spec do_intersperse(fun(() -> action(BWU)), BWU) -> action(BWU).
-do_intersperse(Continuation, Separator) ->
- case Continuation() of
- stop ->
- stop;
-
- {continue, E, Next} ->
- Next_interspersed = fun() -> do_intersperse(Next, Separator) end,
- {continue, Separator, fun() -> {continue, E, Next_interspersed} end}
- end.
-
--spec intersperse(iterator(BWX), BWX) -> iterator(BWX).
-intersperse(Iterator, Elem) ->
- _pipe = fun() -> case (erlang:element(2, Iterator))() of
- stop ->
- stop;
-
- {continue, E, Next} ->
- {continue, E, fun() -> do_intersperse(Next, Elem) end}
- end end,
- {iterator, _pipe}.
-
--spec do_any(fun(() -> action(BXA)), fun((BXA) -> boolean())) -> boolean().
-do_any(Continuation, Predicate) ->
- case Continuation() of
- stop ->
- false;
-
- {continue, E, Next} ->
- case Predicate(E) of
- true ->
- true;
-
- false ->
- do_any(Next, Predicate)
- end
- end.
-
--spec any(iterator(BXC), fun((BXC) -> boolean())) -> boolean().
-any(Iterator, Predicate) ->
- _pipe = erlang:element(2, Iterator),
- do_any(_pipe, Predicate).
-
--spec do_all(fun(() -> action(BXE)), fun((BXE) -> boolean())) -> boolean().
-do_all(Continuation, Predicate) ->
- case Continuation() of
- stop ->
- true;
-
- {continue, E, Next} ->
- case Predicate(E) of
- true ->
- do_all(Next, Predicate);
-
- false ->
- false
- end
- end.
-
--spec all(iterator(BXG), fun((BXG) -> boolean())) -> boolean().
-all(Iterator, Predicate) ->
- _pipe = erlang:element(2, Iterator),
- do_all(_pipe, Predicate).
-
--spec update_group_with(BXI) -> fun((gleam@option:option(list(BXI))) -> list(BXI)).
-update_group_with(El) ->
- fun(Maybe_group) -> case Maybe_group of
- {some, Group} ->
- [El | Group];
-
- none ->
- [El]
- end end.
-
--spec group_updater(fun((BXM) -> BXN)) -> fun((gleam@dict:dict(BXN, list(BXM)), BXM) -> gleam@dict:dict(BXN, list(BXM))).
-group_updater(F) ->
- fun(Groups, Elem) -> _pipe = Groups,
- gleam@dict:update(_pipe, F(Elem), update_group_with(Elem)) end.
-
--spec group(iterator(BXU), fun((BXU) -> BXW)) -> gleam@dict:dict(BXW, list(BXU)).
-group(Iterator, Key) ->
- _pipe = Iterator,
- _pipe@1 = fold(_pipe, gleam@dict:new(), group_updater(Key)),
- gleam@dict:map_values(
- _pipe@1,
- fun(_, Group) -> gleam@list:reverse(Group) end
- ).
-
--spec reduce(iterator(BYA), fun((BYA, BYA) -> BYA)) -> {ok, BYA} | {error, nil}.
-reduce(Iterator, F) ->
- case (erlang:element(2, Iterator))() of
- stop ->
- {error, nil};
-
- {continue, E, Next} ->
- _pipe = do_fold(Next, F, E),
- {ok, _pipe}
- end.
-
--spec last(iterator(BYE)) -> {ok, BYE} | {error, nil}.
-last(Iterator) ->
- _pipe = Iterator,
- reduce(_pipe, fun(_, Elem) -> Elem end).
-
--spec empty() -> iterator(any()).
-empty() ->
- {iterator, fun stop/0}.
-
--spec once(fun(() -> BYK)) -> iterator(BYK).
-once(F) ->
- _pipe = fun() -> {continue, F(), fun stop/0} end,
- {iterator, _pipe}.
-
--spec range(integer(), integer()) -> iterator(integer()).
-range(Start, Stop) ->
- case gleam@int:compare(Start, Stop) of
- eq ->
- once(fun() -> Start end);
-
- gt ->
- unfold(Start, fun(Current) -> case Current < Stop of
- false ->
- {next, Current, Current - 1};
-
- true ->
- done
- end end);
-
- lt ->
- unfold(Start, fun(Current@1) -> case Current@1 > Stop of
- false ->
- {next, Current@1, Current@1 + 1};
-
- true ->
- done
- end end)
- end.
-
--spec single(BYM) -> iterator(BYM).
-single(Elem) ->
- once(fun() -> Elem end).
-
--spec do_interleave(fun(() -> action(BYO)), fun(() -> action(BYO))) -> action(BYO).
-do_interleave(Current, Next) ->
- case Current() of
- stop ->
- Next();
-
- {continue, E, Next_other} ->
- {continue, E, fun() -> do_interleave(Next, Next_other) end}
- end.
-
--spec interleave(iterator(BYS), iterator(BYS)) -> iterator(BYS).
-interleave(Left, Right) ->
- _pipe = fun() ->
- do_interleave(erlang:element(2, Left), erlang:element(2, Right))
- end,
- {iterator, _pipe}.
-
--spec do_fold_until(
- fun(() -> action(BYW)),
- fun((BYY, BYW) -> gleam@list:continue_or_stop(BYY)),
- BYY
-) -> BYY.
-do_fold_until(Continuation, F, Accumulator) ->
- case Continuation() of
- stop ->
- Accumulator;
-
- {continue, Elem, Next} ->
- case F(Accumulator, Elem) of
- {continue, Accumulator@1} ->
- do_fold_until(Next, F, Accumulator@1);
-
- {stop, Accumulator@2} ->
- Accumulator@2
- end
- end.
-
--spec fold_until(
- iterator(BZA),
- BZC,
- fun((BZC, BZA) -> gleam@list:continue_or_stop(BZC))
-) -> BZC.
-fold_until(Iterator, Initial, F) ->
- _pipe = erlang:element(2, Iterator),
- do_fold_until(_pipe, F, Initial).
-
--spec do_try_fold(
- fun(() -> action(BZE)),
- fun((BZG, BZE) -> {ok, BZG} | {error, BZH}),
- BZG
-) -> {ok, BZG} | {error, BZH}.
-do_try_fold(Continuation, F, Accumulator) ->
- case Continuation() of
- stop ->
- {ok, Accumulator};
-
- {continue, Elem, Next} ->
- gleam@result:'try'(
- F(Accumulator, Elem),
- fun(Accumulator@1) -> do_try_fold(Next, F, Accumulator@1) end
- )
- end.
-
--spec try_fold(iterator(BZM), BZO, fun((BZO, BZM) -> {ok, BZO} | {error, BZP})) -> {ok,
- BZO} |
- {error, BZP}.
-try_fold(Iterator, Initial, F) ->
- _pipe = erlang:element(2, Iterator),
- do_try_fold(_pipe, F, Initial).
-
--spec first(iterator(BZU)) -> {ok, BZU} | {error, nil}.
-first(Iterator) ->
- case (erlang:element(2, Iterator))() of
- stop ->
- {error, nil};
-
- {continue, E, _} ->
- {ok, E}
- end.
-
--spec at(iterator(BZY), integer()) -> {ok, BZY} | {error, nil}.
-at(Iterator, Index) ->
- _pipe = Iterator,
- _pipe@1 = drop(_pipe, Index),
- first(_pipe@1).
-
--spec do_length(fun(() -> action(any())), integer()) -> integer().
-do_length(Continuation, Length) ->
- case Continuation() of
- stop ->
- Length;
-
- {continue, _, Next} ->
- do_length(Next, Length + 1)
- end.
-
--spec length(iterator(any())) -> integer().
-length(Iterator) ->
- _pipe = erlang:element(2, Iterator),
- do_length(_pipe, 0).
-
--spec each(iterator(CAG), fun((CAG) -> any())) -> nil.
-each(Iterator, F) ->
- _pipe = Iterator,
- _pipe@1 = map(_pipe, F),
- run(_pipe@1).
-
--spec yield(CAJ, fun(() -> iterator(CAJ))) -> iterator(CAJ).
-yield(Element, Next) ->
- {iterator, fun() -> {continue, Element, erlang:element(2, Next())} end}.
diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam@list.erl b/aoc2023/build/packages/gleam_stdlib/src/gleam@list.erl
deleted file mode 100644
index 6c2e684..0000000
--- a/aoc2023/build/packages/gleam_stdlib/src/gleam@list.erl
+++ /dev/null
@@ -1,1129 +0,0 @@
--module(gleam@list).
--compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]).
-
--export([length/1, reverse/1, is_empty/1, contains/2, first/1, rest/1, filter/2, filter_map/2, map/2, map2/3, index_map/2, try_map/2, drop/2, take/2, new/0, append/2, prepend/2, concat/1, flatten/1, flat_map/2, fold/3, group/2, map_fold/3, fold_right/3, index_fold/3, try_fold/3, fold_until/3, find/2, find_map/2, all/2, any/2, zip/2, strict_zip/2, unzip/1, intersperse/2, at/2, unique/1, sort/2, range/2, repeat/2, split/2, split_while/2, key_find/2, key_filter/2, pop/2, pop_map/2, key_pop/2, key_set/3, each/2, try_each/2, partition/2, permutations/1, window/2, window_by_2/1, drop_while/2, take_while/2, chunk/2, sized_chunk/2, reduce/2, scan/3, last/1, combinations/2, combination_pairs/1, transpose/1, interleave/1, shuffle/1]).
--export_type([length_mismatch/0, continue_or_stop/1]).
-
--type length_mismatch() :: length_mismatch.
-
--type continue_or_stop(UD) :: {continue, UD} | {stop, UD}.
-
--spec length(list(any())) -> integer().
-length(List) ->
- erlang:length(List).
-
--spec reverse(list(UI)) -> list(UI).
-reverse(Xs) ->
- lists:reverse(Xs).
-
--spec is_empty(list(any())) -> boolean().
-is_empty(List) ->
- List =:= [].
-
--spec contains(list(UQ), UQ) -> boolean().
-contains(List, Elem) ->
- case List of
- [] ->
- false;
-
- [First | _] when First =:= Elem ->
- true;
-
- [_ | Rest] ->
- contains(Rest, Elem)
- end.
-
--spec first(list(US)) -> {ok, US} | {error, nil}.
-first(List) ->
- case List of
- [] ->
- {error, nil};
-
- [X | _] ->
- {ok, X}
- end.
-
--spec rest(list(UW)) -> {ok, list(UW)} | {error, nil}.
-rest(List) ->
- case List of
- [] ->
- {error, nil};
-
- [_ | Xs] ->
- {ok, Xs}
- end.
-
--spec update_group(fun((VB) -> VC)) -> fun((gleam@dict:dict(VC, list(VB)), VB) -> gleam@dict:dict(VC, list(VB))).
-update_group(F) ->
- fun(Groups, Elem) -> case gleam@dict:get(Groups, F(Elem)) of
- {ok, Existing} ->
- gleam@dict:insert(Groups, F(Elem), [Elem | Existing]);
-
- {error, _} ->
- gleam@dict:insert(Groups, F(Elem), [Elem])
- end end.
-
--spec do_filter(list(VP), fun((VP) -> boolean()), list(VP)) -> list(VP).
-do_filter(List, Fun, Acc) ->
- case List of
- [] ->
- reverse(Acc);
-
- [X | Xs] ->
- New_acc = case Fun(X) of
- true ->
- [X | Acc];
-
- false ->
- Acc
- end,
- do_filter(Xs, Fun, New_acc)
- end.
-
--spec filter(list(VT), fun((VT) -> boolean())) -> list(VT).
-filter(List, Predicate) ->
- do_filter(List, Predicate, []).
-
--spec do_filter_map(list(VW), fun((VW) -> {ok, VY} | {error, any()}), list(VY)) -> list(VY).
-do_filter_map(List, Fun, Acc) ->
- case List of
- [] ->
- reverse(Acc);
-
- [X | Xs] ->
- New_acc = case Fun(X) of
- {ok, X@1} ->
- [X@1 | Acc];
-
- {error, _} ->
- Acc
- end,
- do_filter_map(Xs, Fun, New_acc)
- end.
-
--spec filter_map(list(WE), fun((WE) -> {ok, WG} | {error, any()})) -> list(WG).
-filter_map(List, Fun) ->
- do_filter_map(List, Fun, []).
-
--spec do_map(list(WL), fun((WL) -> WN), list(WN)) -> list(WN).
-do_map(List, Fun, Acc) ->
- case List of
- [] ->
- reverse(Acc);
-
- [X | Xs] ->
- do_map(Xs, Fun, [Fun(X) | Acc])
- end.
-
--spec map(list(WQ), fun((WQ) -> WS)) -> list(WS).
-map(List, Fun) ->
- do_map(List, Fun, []).
-
--spec do_map2(list(XA), list(XC), fun((XA, XC) -> XE), list(XE)) -> list(XE).
-do_map2(List1, List2, Fun, Acc) ->
- case {List1, List2} of
- {[], _} ->
- reverse(Acc);
-
- {_, []} ->
- reverse(Acc);
-
- {[A | As_], [B | Bs]} ->
- do_map2(As_, Bs, Fun, [Fun(A, B) | Acc])
- end.
-
--spec map2(list(WU), list(WW), fun((WU, WW) -> WY)) -> list(WY).
-map2(List1, List2, Fun) ->
- do_map2(List1, List2, Fun, []).
-
--spec do_index_map(list(XM), fun((integer(), XM) -> XO), integer(), list(XO)) -> list(XO).
-do_index_map(List, Fun, Index, Acc) ->
- case List of
- [] ->
- reverse(Acc);
-
- [X | Xs] ->
- Acc@1 = [Fun(Index, X) | Acc],
- do_index_map(Xs, Fun, Index + 1, Acc@1)
- end.
-
--spec index_map(list(XR), fun((integer(), XR) -> XT)) -> list(XT).
-index_map(List, Fun) ->
- do_index_map(List, Fun, 0, []).
-
--spec do_try_map(list(XV), fun((XV) -> {ok, XX} | {error, XY}), list(XX)) -> {ok,
- list(XX)} |
- {error, XY}.
-do_try_map(List, Fun, Acc) ->
- case List of
- [] ->
- {ok, reverse(Acc)};
-
- [X | Xs] ->
- case Fun(X) of
- {ok, Y} ->
- do_try_map(Xs, Fun, [Y | Acc]);
-
- {error, Error} ->
- {error, Error}
- end
- end.
-
--spec try_map(list(YF), fun((YF) -> {ok, YH} | {error, YI})) -> {ok, list(YH)} |
- {error, YI}.
-try_map(List, Fun) ->
- do_try_map(List, Fun, []).
-
--spec drop(list(YO), integer()) -> list(YO).
-drop(List, N) ->
- case N =< 0 of
- true ->
- List;
-
- false ->
- case List of
- [] ->
- [];
-
- [_ | Xs] ->
- drop(Xs, N - 1)
- end
- end.
-
--spec do_take(list(YR), integer(), list(YR)) -> list(YR).
-do_take(List, N, Acc) ->
- case N =< 0 of
- true ->
- reverse(Acc);
-
- false ->
- case List of
- [] ->
- reverse(Acc);
-
- [X | Xs] ->
- do_take(Xs, N - 1, [X | Acc])
- end
- end.
-
--spec take(list(YV), integer()) -> list(YV).
-take(List, N) ->
- do_take(List, N, []).
-
--spec new() -> list(any()).
-new() ->
- [].
-
--spec append(list(AAA), list(AAA)) -> list(AAA).
-append(First, Second) ->
- lists:append(First, Second).
-
--spec prepend(list(AAI), AAI) -> list(AAI).
-prepend(List, Item) ->
- [Item | List].
-
--spec reverse_and_prepend(list(AAL), list(AAL)) -> list(AAL).
-reverse_and_prepend(Prefix, Suffix) ->
- case Prefix of
- [] ->
- Suffix;
-
- [First | Rest] ->
- reverse_and_prepend(Rest, [First | Suffix])
- end.
-
--spec do_concat(list(list(AAP)), list(AAP)) -> list(AAP).
-do_concat(Lists, Acc) ->
- case Lists of
- [] ->
- reverse(Acc);
-
- [List | Further_lists] ->
- do_concat(Further_lists, reverse_and_prepend(List, Acc))
- end.
-
--spec concat(list(list(AAU))) -> list(AAU).
-concat(Lists) ->
- do_concat(Lists, []).
-
--spec flatten(list(list(AAY))) -> list(AAY).
-flatten(Lists) ->
- do_concat(Lists, []).
-
--spec flat_map(list(ABC), fun((ABC) -> list(ABE))) -> list(ABE).
-flat_map(List, Fun) ->
- _pipe = map(List, Fun),
- concat(_pipe).
-
--spec fold(list(ABH), ABJ, fun((ABJ, ABH) -> ABJ)) -> ABJ.
-fold(List, Initial, Fun) ->
- case List of
- [] ->
- Initial;
-
- [X | Rest] ->
- fold(Rest, Fun(Initial, X), Fun)
- end.
-
--spec group(list(VJ), fun((VJ) -> VL)) -> gleam@dict:dict(VL, list(VJ)).
-group(List, Key) ->
- fold(List, gleam@dict:new(), update_group(Key)).
-
--spec map_fold(list(XH), XJ, fun((XJ, XH) -> {XJ, XK})) -> {XJ, list(XK)}.
-map_fold(List, Acc, Fun) ->
- _pipe = fold(
- List,
- {Acc, []},
- fun(Acc@1, Item) ->
- {Current_acc, Items} = Acc@1,
- {Next_acc, Next_item} = Fun(Current_acc, Item),
- {Next_acc, [Next_item | Items]}
- end
- ),
- gleam@pair:map_second(_pipe, fun reverse/1).
-
--spec fold_right(list(ABK), ABM, fun((ABM, ABK) -> ABM)) -> ABM.
-fold_right(List, Initial, Fun) ->
- case List of
- [] ->
- Initial;
-
- [X | Rest] ->
- Fun(fold_right(Rest, Initial, Fun), X)
- end.
-
--spec do_index_fold(
- list(ABN),
- ABP,
- fun((ABP, ABN, integer()) -> ABP),
- integer()
-) -> ABP.
-do_index_fold(Over, Acc, With, Index) ->
- case Over of
- [] ->
- Acc;
-
- [First | Rest] ->
- do_index_fold(Rest, With(Acc, First, Index), With, Index + 1)
- end.
-
--spec index_fold(list(ABQ), ABS, fun((ABS, ABQ, integer()) -> ABS)) -> ABS.
-index_fold(Over, Initial, Fun) ->
- do_index_fold(Over, Initial, Fun, 0).
-
--spec try_fold(list(ABT), ABV, fun((ABV, ABT) -> {ok, ABV} | {error, ABW})) -> {ok,
- ABV} |
- {error, ABW}.
-try_fold(Collection, Accumulator, Fun) ->
- case Collection of
- [] ->
- {ok, Accumulator};
-
- [First | Rest] ->
- case Fun(Accumulator, First) of
- {ok, Result} ->
- try_fold(Rest, Result, Fun);
-
- {error, _} = Error ->
- Error
- end
- end.
-
--spec fold_until(list(ACB), ACD, fun((ACD, ACB) -> continue_or_stop(ACD))) -> ACD.
-fold_until(Collection, Accumulator, Fun) ->
- case Collection of
- [] ->
- Accumulator;
-
- [First | Rest] ->
- case Fun(Accumulator, First) of
- {continue, Next_accumulator} ->
- fold_until(Rest, Next_accumulator, Fun);
-
- {stop, B} ->
- B
- end
- end.
-
--spec find(list(ACF), fun((ACF) -> boolean())) -> {ok, ACF} | {error, nil}.
-find(Haystack, Is_desired) ->
- case Haystack of
- [] ->
- {error, nil};
-
- [X | Rest] ->
- case Is_desired(X) of
- true ->
- {ok, X};
-
- _ ->
- find(Rest, Is_desired)
- end
- end.
-
--spec find_map(list(ACJ), fun((ACJ) -> {ok, ACL} | {error, any()})) -> {ok, ACL} |
- {error, nil}.
-find_map(Haystack, Fun) ->
- case Haystack of
- [] ->
- {error, nil};
-
- [X | Rest] ->
- case Fun(X) of
- {ok, X@1} ->
- {ok, X@1};
-
- _ ->
- find_map(Rest, Fun)
- end
- end.
-
--spec all(list(ACR), fun((ACR) -> boolean())) -> boolean().
-all(List, Predicate) ->
- case List of
- [] ->
- true;
-
- [First | Rest] ->
- case Predicate(First) of
- true ->
- all(Rest, Predicate);
-
- false ->
- false
- end
- end.
-
--spec any(list(ACT), fun((ACT) -> boolean())) -> boolean().
-any(List, Predicate) ->
- case List of
- [] ->
- false;
-
- [First | Rest] ->
- case Predicate(First) of
- true ->
- true;
-
- false ->
- any(Rest, Predicate)
- end
- end.
-
--spec do_zip(list(ACV), list(ACX), list({ACV, ACX})) -> list({ACV, ACX}).
-do_zip(Xs, Ys, Acc) ->
- case {Xs, Ys} of
- {[X | Xs@1], [Y | Ys@1]} ->
- do_zip(Xs@1, Ys@1, [{X, Y} | Acc]);
-
- {_, _} ->
- reverse(Acc)
- end.
-
--spec zip(list(ADB), list(ADD)) -> list({ADB, ADD}).
-zip(List, Other) ->
- do_zip(List, Other, []).
-
--spec strict_zip(list(ADG), list(ADI)) -> {ok, list({ADG, ADI})} |
- {error, length_mismatch()}.
-strict_zip(List, Other) ->
- case length(List) =:= length(Other) of
- true ->
- {ok, zip(List, Other)};
-
- false ->
- {error, length_mismatch}
- end.
-
--spec do_unzip(list({ATA, ATB}), list(ATA), list(ATB)) -> {list(ATA), list(ATB)}.
-do_unzip(Input, Xs, Ys) ->
- case Input of
- [] ->
- {reverse(Xs), reverse(Ys)};
-
- [{X, Y} | Rest] ->
- do_unzip(Rest, [X | Xs], [Y | Ys])
- end.
-
--spec unzip(list({ADR, ADS})) -> {list(ADR), list(ADS)}.
-unzip(Input) ->
- do_unzip(Input, [], []).
-
--spec do_intersperse(list(ADW), ADW, list(ADW)) -> list(ADW).
-do_intersperse(List, Separator, Acc) ->
- case List of
- [] ->
- reverse(Acc);
-
- [X | Rest] ->
- do_intersperse(Rest, Separator, [X, Separator | Acc])
- end.
-
--spec intersperse(list(AEA), AEA) -> list(AEA).
-intersperse(List, Elem) ->
- case List of
- [] ->
- List;
-
- [_] ->
- List;
-
- [X | Rest] ->
- do_intersperse(Rest, Elem, [X])
- end.
-
--spec at(list(AED), integer()) -> {ok, AED} | {error, nil}.
-at(List, Index) ->
- case Index >= 0 of
- true ->
- _pipe = List,
- _pipe@1 = drop(_pipe, Index),
- first(_pipe@1);
-
- false ->
- {error, nil}
- end.
-
--spec unique(list(AEH)) -> list(AEH).
-unique(List) ->
- case List of
- [] ->
- [];
-
- [X | Rest] ->
- [X | unique(filter(Rest, fun(Y) -> Y /= X end))]
- end.
-
--spec merge_up(
- integer(),
- integer(),
- list(AEK),
- list(AEK),
- list(AEK),
- fun((AEK, AEK) -> gleam@order:order())
-) -> list(AEK).
-merge_up(Na, Nb, A, B, Acc, Compare) ->
- case {Na, Nb, A, B} of
- {0, 0, _, _} ->
- Acc;
-
- {_, 0, [Ax | Ar], _} ->
- merge_up(Na - 1, Nb, Ar, B, [Ax | Acc], Compare);
-
- {0, _, _, [Bx | Br]} ->
- merge_up(Na, Nb - 1, A, Br, [Bx | Acc], Compare);
-
- {_, _, [Ax@1 | Ar@1], [Bx@1 | Br@1]} ->
- case Compare(Ax@1, Bx@1) of
- gt ->
- merge_up(Na, Nb - 1, A, Br@1, [Bx@1 | Acc], Compare);
-
- _ ->
- merge_up(Na - 1, Nb, Ar@1, B, [Ax@1 | Acc], Compare)
- end;
-
- {_, _, _, _} ->
- Acc
- end.
-
--spec merge_down(
- integer(),
- integer(),
- list(AEP),
- list(AEP),
- list(AEP),
- fun((AEP, AEP) -> gleam@order:order())
-) -> list(AEP).
-merge_down(Na, Nb, A, B, Acc, Compare) ->
- case {Na, Nb, A, B} of
- {0, 0, _, _} ->
- Acc;
-
- {_, 0, [Ax | Ar], _} ->
- merge_down(Na - 1, Nb, Ar, B, [Ax | Acc], Compare);
-
- {0, _, _, [Bx | Br]} ->
- merge_down(Na, Nb - 1, A, Br, [Bx | Acc], Compare);
-
- {_, _, [Ax@1 | Ar@1], [Bx@1 | Br@1]} ->
- case Compare(Bx@1, Ax@1) of
- lt ->
- merge_down(Na - 1, Nb, Ar@1, B, [Ax@1 | Acc], Compare);
-
- _ ->
- merge_down(Na, Nb - 1, A, Br@1, [Bx@1 | Acc], Compare)
- end;
-
- {_, _, _, _} ->
- Acc
- end.
-
--spec merge_sort(
- list(AEU),
- integer(),
- fun((AEU, AEU) -> gleam@order:order()),
- boolean()
-) -> list(AEU).
-merge_sort(L, Ln, Compare, Down) ->
- N = Ln div 2,
- A = L,
- B = drop(L, N),
- case Ln < 3 of
- true ->
- case Down of
- true ->
- merge_down(N, Ln - N, A, B, [], Compare);
-
- false ->
- merge_up(N, Ln - N, A, B, [], Compare)
- end;
-
- false ->
- case Down of
- true ->
- merge_down(
- N,
- Ln - N,
- merge_sort(A, N, Compare, false),
- merge_sort(B, Ln - N, Compare, false),
- [],
- Compare
- );
-
- false ->
- merge_up(
- N,
- Ln - N,
- merge_sort(A, N, Compare, true),
- merge_sort(B, Ln - N, Compare, true),
- [],
- Compare
- )
- end
- end.
-
--spec sort(list(AEX), fun((AEX, AEX) -> gleam@order:order())) -> list(AEX).
-sort(List, Compare) ->
- merge_sort(List, length(List), Compare, true).
-
--spec tail_recursive_range(integer(), integer(), list(integer())) -> list(integer()).
-tail_recursive_range(Start, Stop, Acc) ->
- case gleam@int:compare(Start, Stop) of
- eq ->
- [Stop | Acc];
-
- gt ->
- tail_recursive_range(Start, Stop + 1, [Stop | Acc]);
-
- lt ->
- tail_recursive_range(Start, Stop - 1, [Stop | Acc])
- end.
-
--spec range(integer(), integer()) -> list(integer()).
-range(Start, Stop) ->
- tail_recursive_range(Start, Stop, []).
-
--spec do_repeat(AFD, integer(), list(AFD)) -> list(AFD).
-do_repeat(A, Times, Acc) ->
- case Times =< 0 of
- true ->
- Acc;
-
- false ->
- do_repeat(A, Times - 1, [A | Acc])
- end.
-
--spec repeat(AFG, integer()) -> list(AFG).
-repeat(A, Times) ->
- do_repeat(A, Times, []).
-
--spec do_split(list(AFI), integer(), list(AFI)) -> {list(AFI), list(AFI)}.
-do_split(List, N, Taken) ->
- case N =< 0 of
- true ->
- {reverse(Taken), List};
-
- false ->
- case List of
- [] ->
- {reverse(Taken), []};
-
- [X | Xs] ->
- do_split(Xs, N - 1, [X | Taken])
- end
- end.
-
--spec split(list(AFN), integer()) -> {list(AFN), list(AFN)}.
-split(List, Index) ->
- do_split(List, Index, []).
-
--spec do_split_while(list(AFR), fun((AFR) -> boolean()), list(AFR)) -> {list(AFR),
- list(AFR)}.
-do_split_while(List, F, Acc) ->
- case List of
- [] ->
- {reverse(Acc), []};
-
- [X | Xs] ->
- case F(X) of
- false ->
- {reverse(Acc), List};
-
- _ ->
- do_split_while(Xs, F, [X | Acc])
- end
- end.
-
--spec split_while(list(AFW), fun((AFW) -> boolean())) -> {list(AFW), list(AFW)}.
-split_while(List, Predicate) ->
- do_split_while(List, Predicate, []).
-
--spec key_find(list({AGA, AGB}), AGA) -> {ok, AGB} | {error, nil}.
-key_find(Keyword_list, Desired_key) ->
- find_map(
- Keyword_list,
- fun(Keyword) ->
- {Key, Value} = Keyword,
- case Key =:= Desired_key of
- true ->
- {ok, Value};
-
- false ->
- {error, nil}
- end
- end
- ).
-
--spec key_filter(list({AGF, AGG}), AGF) -> list(AGG).
-key_filter(Keyword_list, Desired_key) ->
- filter_map(
- Keyword_list,
- fun(Keyword) ->
- {Key, Value} = Keyword,
- case Key =:= Desired_key of
- true ->
- {ok, Value};
-
- false ->
- {error, nil}
- end
- end
- ).
-
--spec do_pop(list(AWT), fun((AWT) -> boolean()), list(AWT)) -> {ok,
- {AWT, list(AWT)}} |
- {error, nil}.
-do_pop(Haystack, Predicate, Checked) ->
- case Haystack of
- [] ->
- {error, nil};
-
- [X | Rest] ->
- case Predicate(X) of
- true ->
- {ok, {X, append(reverse(Checked), Rest)}};
-
- false ->
- do_pop(Rest, Predicate, [X | Checked])
- end
- end.
-
--spec pop(list(AGN), fun((AGN) -> boolean())) -> {ok, {AGN, list(AGN)}} |
- {error, nil}.
-pop(Haystack, Is_desired) ->
- do_pop(Haystack, Is_desired, []).
-
--spec do_pop_map(list(AXH), fun((AXH) -> {ok, AXU} | {error, any()}), list(AXH)) -> {ok,
- {AXU, list(AXH)}} |
- {error, nil}.
-do_pop_map(Haystack, Mapper, Checked) ->
- case Haystack of
- [] ->
- {error, nil};
-
- [X | Rest] ->
- case Mapper(X) of
- {ok, Y} ->
- {ok, {Y, append(reverse(Checked), Rest)}};
-
- {error, _} ->
- do_pop_map(Rest, Mapper, [X | Checked])
- end
- end.
-
--spec pop_map(list(AGW), fun((AGW) -> {ok, AGY} | {error, any()})) -> {ok,
- {AGY, list(AGW)}} |
- {error, nil}.
-pop_map(Haystack, Is_desired) ->
- do_pop_map(Haystack, Is_desired, []).
-
--spec key_pop(list({AHF, AHG}), AHF) -> {ok, {AHG, list({AHF, AHG})}} |
- {error, nil}.
-key_pop(Haystack, Key) ->
- pop_map(
- Haystack,
- fun(Entry) ->
- {K, V} = Entry,
- case K of
- K@1 when K@1 =:= Key ->
- {ok, V};
-
- _ ->
- {error, nil}
- end
- end
- ).
-
--spec key_set(list({AHL, AHM}), AHL, AHM) -> list({AHL, AHM}).
-key_set(List, Key, Value) ->
- case List of
- [] ->
- [{Key, Value}];
-
- [{K, _} | Rest] when K =:= Key ->
- [{Key, Value} | Rest];
-
- [First | Rest@1] ->
- [First | key_set(Rest@1, Key, Value)]
- end.
-
--spec each(list(AHP), fun((AHP) -> any())) -> nil.
-each(List, F) ->
- case List of
- [] ->
- nil;
-
- [X | Xs] ->
- F(X),
- each(Xs, F)
- end.
-
--spec try_each(list(AHS), fun((AHS) -> {ok, any()} | {error, AHV})) -> {ok, nil} |
- {error, AHV}.
-try_each(List, Fun) ->
- case List of
- [] ->
- {ok, nil};
-
- [X | Xs] ->
- case Fun(X) of
- {ok, _} ->
- try_each(Xs, Fun);
-
- {error, E} ->
- {error, E}
- end
- end.
-
--spec do_partition(list(AZB), fun((AZB) -> boolean()), list(AZB), list(AZB)) -> {list(AZB),
- list(AZB)}.
-do_partition(List, Categorise, Trues, Falses) ->
- case List of
- [] ->
- {reverse(Trues), reverse(Falses)};
-
- [X | Xs] ->
- case Categorise(X) of
- true ->
- do_partition(Xs, Categorise, [X | Trues], Falses);
-
- false ->
- do_partition(Xs, Categorise, Trues, [X | Falses])
- end
- end.
-
--spec partition(list(AIF), fun((AIF) -> boolean())) -> {list(AIF), list(AIF)}.
-partition(List, Categorise) ->
- do_partition(List, Categorise, [], []).
-
--spec permutations(list(AIJ)) -> list(list(AIJ)).
-permutations(L) ->
- case L of
- [] ->
- [[]];
-
- _ ->
- _pipe = L,
- _pipe@5 = index_map(_pipe, fun(I_idx, I) -> _pipe@1 = L,
- _pipe@2 = index_fold(
- _pipe@1,
- [],
- fun(Acc, J, J_idx) -> case I_idx =:= J_idx of
- true ->
- Acc;
-
- false ->
- [J | Acc]
- end end
- ),
- _pipe@3 = reverse(_pipe@2),
- _pipe@4 = permutations(_pipe@3),
- map(_pipe@4, fun(Permutation) -> [I | Permutation] end) end),
- concat(_pipe@5)
- end.
-
--spec do_window(list(list(AIN)), list(AIN), integer()) -> list(list(AIN)).
-do_window(Acc, L, N) ->
- Window = take(L, N),
- case length(Window) =:= N of
- true ->
- do_window([Window | Acc], drop(L, 1), N);
-
- false ->
- Acc
- end.
-
--spec window(list(AIT), integer()) -> list(list(AIT)).
-window(L, N) ->
- _pipe = do_window([], L, N),
- reverse(_pipe).
-
--spec window_by_2(list(AIX)) -> list({AIX, AIX}).
-window_by_2(L) ->
- zip(L, drop(L, 1)).
-
--spec drop_while(list(AJA), fun((AJA) -> boolean())) -> list(AJA).
-drop_while(List, Predicate) ->
- case List of
- [] ->
- [];
-
- [X | Xs] ->
- case Predicate(X) of
- true ->
- drop_while(Xs, Predicate);
-
- false ->
- [X | Xs]
- end
- end.
-
--spec do_take_while(list(AJD), fun((AJD) -> boolean()), list(AJD)) -> list(AJD).
-do_take_while(List, Predicate, Acc) ->
- case List of
- [] ->
- reverse(Acc);
-
- [First | Rest] ->
- case Predicate(First) of
- true ->
- do_take_while(Rest, Predicate, [First | Acc]);
-
- false ->
- reverse(Acc)
- end
- end.
-
--spec take_while(list(AJH), fun((AJH) -> boolean())) -> list(AJH).
-take_while(List, Predicate) ->
- do_take_while(List, Predicate, []).
-
--spec do_chunk(list(AJK), fun((AJK) -> AJM), AJM, list(AJK), list(list(AJK))) -> list(list(AJK)).
-do_chunk(List, F, Previous_key, Current_chunk, Acc) ->
- case List of
- [First | Rest] ->
- Key = F(First),
- case Key =:= Previous_key of
- false ->
- New_acc = [reverse(Current_chunk) | Acc],
- do_chunk(Rest, F, Key, [First], New_acc);
-
- _ ->
- do_chunk(Rest, F, Key, [First | Current_chunk], Acc)
- end;
-
- _ ->
- reverse([reverse(Current_chunk) | Acc])
- end.
-
--spec chunk(list(AJS), fun((AJS) -> any())) -> list(list(AJS)).
-chunk(List, F) ->
- case List of
- [] ->
- [];
-
- [First | Rest] ->
- do_chunk(Rest, F, F(First), [First], [])
- end.
-
--spec do_sized_chunk(
- list(AJX),
- integer(),
- integer(),
- list(AJX),
- list(list(AJX))
-) -> list(list(AJX)).
-do_sized_chunk(List, Count, Left, Current_chunk, Acc) ->
- case List of
- [] ->
- case Current_chunk of
- [] ->
- reverse(Acc);
-
- Remaining ->
- reverse([reverse(Remaining) | Acc])
- end;
-
- [First | Rest] ->
- Chunk = [First | Current_chunk],
- case Left > 1 of
- false ->
- do_sized_chunk(
- Rest,
- Count,
- Count,
- [],
- [reverse(Chunk) | Acc]
- );
-
- true ->
- do_sized_chunk(Rest, Count, Left - 1, Chunk, Acc)
- end
- end.
-
--spec sized_chunk(list(AKE), integer()) -> list(list(AKE)).
-sized_chunk(List, Count) ->
- do_sized_chunk(List, Count, Count, [], []).
-
--spec reduce(list(AKI), fun((AKI, AKI) -> AKI)) -> {ok, AKI} | {error, nil}.
-reduce(List, Fun) ->
- case List of
- [] ->
- {error, nil};
-
- [First | Rest] ->
- {ok, fold(Rest, First, Fun)}
- end.
-
--spec do_scan(list(AKM), AKO, list(AKO), fun((AKO, AKM) -> AKO)) -> list(AKO).
-do_scan(List, Accumulator, Accumulated, Fun) ->
- case List of
- [] ->
- reverse(Accumulated);
-
- [X | Xs] ->
- Next = Fun(Accumulator, X),
- do_scan(Xs, Next, [Next | Accumulated], Fun)
- end.
-
--spec scan(list(AKR), AKT, fun((AKT, AKR) -> AKT)) -> list(AKT).
-scan(List, Initial, Fun) ->
- do_scan(List, Initial, [], Fun).
-
--spec last(list(AKV)) -> {ok, AKV} | {error, nil}.
-last(List) ->
- _pipe = List,
- reduce(_pipe, fun(_, Elem) -> Elem end).
-
--spec combinations(list(AKZ), integer()) -> list(list(AKZ)).
-combinations(Items, N) ->
- case N of
- 0 ->
- [[]];
-
- _ ->
- case Items of
- [] ->
- [];
-
- [X | Xs] ->
- First_combinations = begin
- _pipe = map(
- combinations(Xs, N - 1),
- fun(Com) -> [X | Com] end
- ),
- reverse(_pipe)
- end,
- fold(
- First_combinations,
- combinations(Xs, N),
- fun(Acc, C) -> [C | Acc] end
- )
- end
- end.
-
--spec do_combination_pairs(list(ALD)) -> list(list({ALD, ALD})).
-do_combination_pairs(Items) ->
- case Items of
- [] ->
- [];
-
- [X | Xs] ->
- First_combinations = map(Xs, fun(Other) -> {X, Other} end),
- [First_combinations | do_combination_pairs(Xs)]
- end.
-
--spec combination_pairs(list(ALH)) -> list({ALH, ALH}).
-combination_pairs(Items) ->
- _pipe = do_combination_pairs(Items),
- concat(_pipe).
-
--spec transpose(list(list(ALO))) -> list(list(ALO)).
-transpose(List_of_list) ->
- Take_first = fun(List) -> case List of
- [] ->
- [];
-
- [F] ->
- [F];
-
- [F@1 | _] ->
- [F@1]
- end end,
- case List_of_list of
- [] ->
- [];
-
- [[] | Xss] ->
- transpose(Xss);
-
- Rows ->
- Firsts = begin
- _pipe = Rows,
- _pipe@1 = map(_pipe, Take_first),
- concat(_pipe@1)
- end,
- Rest = transpose(map(Rows, fun(_capture) -> drop(_capture, 1) end)),
- [Firsts | Rest]
- end.
-
--spec interleave(list(list(ALK))) -> list(ALK).
-interleave(List) ->
- _pipe = transpose(List),
- concat(_pipe).
-
--spec do_shuffle_pair_unwrap(list({float(), ALT}), list(ALT)) -> list(ALT).
-do_shuffle_pair_unwrap(List, Acc) ->
- case List of
- [] ->
- Acc;
-
- [Elem_pair | Enumerable] ->
- do_shuffle_pair_unwrap(
- Enumerable,
- [erlang:element(2, Elem_pair) | Acc]
- )
- end.
-
--spec do_shuffle_by_pair_indexes(list({float(), ALX})) -> list({float(), ALX}).
-do_shuffle_by_pair_indexes(List_of_pairs) ->
- sort(
- List_of_pairs,
- fun(A_pair, B_pair) ->
- gleam@float:compare(
- erlang:element(1, A_pair),
- erlang:element(1, B_pair)
- )
- end
- ).
-
--spec shuffle(list(AMA)) -> list(AMA).
-shuffle(List) ->
- _pipe = List,
- _pipe@1 = fold(
- _pipe,
- [],
- fun(Acc, A) -> [{gleam@float:random(+0.0, 1.0), A} | Acc] end
- ),
- _pipe@2 = do_shuffle_by_pair_indexes(_pipe@1),
- do_shuffle_pair_unwrap(_pipe@2, []).
diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam@map.erl b/aoc2023/build/packages/gleam_stdlib/src/gleam@map.erl
deleted file mode 100644
index 33e89a9..0000000
--- a/aoc2023/build/packages/gleam_stdlib/src/gleam@map.erl
+++ /dev/null
@@ -1,76 +0,0 @@
--module(gleam@map).
--compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]).
-
--export([size/1, to_list/1, from_list/1, has_key/2, new/0, get/2, insert/3, map_values/2, keys/1, values/1, filter/2, take/2, merge/2, delete/2, drop/2, update/3, fold/3]).
-
--spec size(gleam@dict:dict(any(), any())) -> integer().
-size(Map) ->
- gleam@dict:size(Map).
-
--spec to_list(gleam@dict:dict(DAJ, DAK)) -> list({DAJ, DAK}).
-to_list(Map) ->
- gleam@dict:to_list(Map).
-
--spec from_list(list({DAM, DAN})) -> gleam@dict:dict(DAM, DAN).
-from_list(List) ->
- gleam@dict:from_list(List).
-
--spec has_key(gleam@dict:dict(DAR, any()), DAR) -> boolean().
-has_key(Map, Key) ->
- gleam@dict:has_key(Map, Key).
-
--spec new() -> gleam@dict:dict(any(), any()).
-new() ->
- gleam@dict:new().
-
--spec get(gleam@dict:dict(DAU, DAV), DAU) -> {ok, DAV} | {error, nil}.
-get(From, Get) ->
- gleam@dict:get(From, Get).
-
--spec insert(gleam@dict:dict(DAZ, DBA), DAZ, DBA) -> gleam@dict:dict(DAZ, DBA).
-insert(Map, Key, Value) ->
- gleam@dict:insert(Map, Key, Value).
-
--spec map_values(gleam@dict:dict(DBD, DBE), fun((DBD, DBE) -> DBF)) -> gleam@dict:dict(DBD, DBF).
-map_values(Map, Fun) ->
- gleam@dict:map_values(Map, Fun).
-
--spec keys(gleam@dict:dict(DBI, any())) -> list(DBI).
-keys(Map) ->
- gleam@dict:keys(Map).
-
--spec values(gleam@dict:dict(any(), DBL)) -> list(DBL).
-values(Map) ->
- gleam@dict:values(Map).
-
--spec filter(gleam@dict:dict(DBO, DBP), fun((DBO, DBP) -> boolean())) -> gleam@dict:dict(DBO, DBP).
-filter(Map, Predicate) ->
- gleam@dict:filter(Map, Predicate).
-
--spec take(gleam@dict:dict(DBS, DDM), list(DBS)) -> gleam@dict:dict(DBS, DDM).
-take(Map, Desired_keys) ->
- gleam@dict:take(Map, Desired_keys).
-
--spec merge(gleam@dict:dict(DDN, DDO), gleam@dict:dict(DDN, DDO)) -> gleam@dict:dict(DDN, DDO).
-merge(Map, New_entries) ->
- gleam@dict:merge(Map, New_entries).
-
--spec delete(gleam@dict:dict(DBZ, DDQ), DBZ) -> gleam@dict:dict(DBZ, DDQ).
-delete(Map, Key) ->
- gleam@dict:delete(Map, Key).
-
--spec drop(gleam@dict:dict(DCC, DDS), list(DCC)) -> gleam@dict:dict(DCC, DDS).
-drop(Map, Disallowed_keys) ->
- gleam@dict:drop(Map, Disallowed_keys).
-
--spec update(
- gleam@dict:dict(DCG, DCH),
- DCG,
- fun((gleam@option:option(DCH)) -> DCH)
-) -> gleam@dict:dict(DCG, DCH).
-update(Map, Key, Fun) ->
- gleam@dict:update(Map, Key, Fun).
-
--spec fold(gleam@dict:dict(DCM, DCN), DCL, fun((DCL, DCM, DCN) -> DCL)) -> DCL.
-fold(Map, Initial, Fun) ->
- gleam@dict:fold(Map, Initial, Fun).
diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam@option.erl b/aoc2023/build/packages/gleam_stdlib/src/gleam@option.erl
deleted file mode 100644
index 5c20713..0000000
--- a/aoc2023/build/packages/gleam_stdlib/src/gleam@option.erl
+++ /dev/null
@@ -1,147 +0,0 @@
--module(gleam@option).
--compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]).
-
--export([all/1, is_some/1, is_none/1, to_result/2, from_result/1, unwrap/2, lazy_unwrap/2, map/2, flatten/1, then/2, 'or'/2, lazy_or/2, values/1]).
--export_type([option/1]).
-
--type option(GB) :: {some, GB} | none.
-
--spec do_all(list(option(GC)), list(GC)) -> option(list(GC)).
-do_all(List, Acc) ->
- case List of
- [] ->
- {some, Acc};
-
- [X | Rest] ->
- Accumulate = fun(Acc@1, Item) -> case {Acc@1, Item} of
- {{some, Values}, {some, Value}} ->
- {some, [Value | Values]};
-
- {_, _} ->
- none
- end end,
- Accumulate(do_all(Rest, Acc), X)
- end.
-
--spec all(list(option(GI))) -> option(list(GI)).
-all(List) ->
- do_all(List, []).
-
--spec is_some(option(any())) -> boolean().
-is_some(Option) ->
- Option /= none.
-
--spec is_none(option(any())) -> boolean().
-is_none(Option) ->
- Option =:= none.
-
--spec to_result(option(GR), GU) -> {ok, GR} | {error, GU}.
-to_result(Option, E) ->
- case Option of
- {some, A} ->
- {ok, A};
-
- _ ->
- {error, E}
- end.
-
--spec from_result({ok, GX} | {error, any()}) -> option(GX).
-from_result(Result) ->
- case Result of
- {ok, A} ->
- {some, A};
-
- _ ->
- none
- end.
-
--spec unwrap(option(HC), HC) -> HC.
-unwrap(Option, Default) ->
- case Option of
- {some, X} ->
- X;
-
- none ->
- Default
- end.
-
--spec lazy_unwrap(option(HE), fun(() -> HE)) -> HE.
-lazy_unwrap(Option, Default) ->
- case Option of
- {some, X} ->
- X;
-
- none ->
- Default()
- end.
-
--spec map(option(HG), fun((HG) -> HI)) -> option(HI).
-map(Option, Fun) ->
- case Option of
- {some, X} ->
- {some, Fun(X)};
-
- none ->
- none
- end.
-
--spec flatten(option(option(HK))) -> option(HK).
-flatten(Option) ->
- case Option of
- {some, X} ->
- X;
-
- none ->
- none
- end.
-
--spec then(option(HO), fun((HO) -> option(HQ))) -> option(HQ).
-then(Option, Fun) ->
- case Option of
- {some, X} ->
- Fun(X);
-
- none ->
- none
- end.
-
--spec 'or'(option(HT), option(HT)) -> option(HT).
-'or'(First, Second) ->
- case First of
- {some, _} ->
- First;
-
- none ->
- Second
- end.
-
--spec lazy_or(option(HX), fun(() -> option(HX))) -> option(HX).
-lazy_or(First, Second) ->
- case First of
- {some, _} ->
- First;
-
- none ->
- Second()
- end.
-
--spec do_values(list(option(IB)), list(IB)) -> list(IB).
-do_values(List, Acc) ->
- case List of
- [] ->
- Acc;
-
- [X | Xs] ->
- Accumulate = fun(Acc@1, Item) -> case Item of
- {some, Value} ->
- [Value | Acc@1];
-
- none ->
- Acc@1
- end end,
- Accumulate(do_values(Xs, Acc), X)
- end.
-
--spec values(list(option(IG))) -> list(IG).
-values(Options) ->
- do_values(Options, []).
diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam@order.erl b/aoc2023/build/packages/gleam_stdlib/src/gleam@order.erl
deleted file mode 100644
index 61649b9..0000000
--- a/aoc2023/build/packages/gleam_stdlib/src/gleam@order.erl
+++ /dev/null
@@ -1,79 +0,0 @@
--module(gleam@order).
--compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]).
-
--export([negate/1, to_int/1, compare/2, max/2, min/2, reverse/1]).
--export_type([order/0]).
-
--type order() :: lt | eq | gt.
-
--spec negate(order()) -> order().
-negate(Order) ->
- case Order of
- lt ->
- gt;
-
- eq ->
- eq;
-
- gt ->
- lt
- end.
-
--spec to_int(order()) -> integer().
-to_int(Order) ->
- case Order of
- lt ->
- -1;
-
- eq ->
- 0;
-
- gt ->
- 1
- end.
-
--spec compare(order(), order()) -> order().
-compare(A, B) ->
- case {A, B} of
- {X, Y} when X =:= Y ->
- eq;
-
- {lt, _} ->
- lt;
-
- {eq, gt} ->
- lt;
-
- {_, _} ->
- gt
- end.
-
--spec max(order(), order()) -> order().
-max(A, B) ->
- case {A, B} of
- {gt, _} ->
- gt;
-
- {eq, lt} ->
- eq;
-
- {_, _} ->
- B
- end.
-
--spec min(order(), order()) -> order().
-min(A, B) ->
- case {A, B} of
- {lt, _} ->
- lt;
-
- {eq, gt} ->
- eq;
-
- {_, _} ->
- B
- end.
-
--spec reverse(fun((I, I) -> order())) -> fun((I, I) -> order()).
-reverse(Orderer) ->
- fun(A, B) -> Orderer(B, A) end.
diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam@pair.erl b/aoc2023/build/packages/gleam_stdlib/src/gleam@pair.erl
deleted file mode 100644
index f4eff52..0000000
--- a/aoc2023/build/packages/gleam_stdlib/src/gleam@pair.erl
+++ /dev/null
@@ -1,33 +0,0 @@
--module(gleam@pair).
--compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]).
-
--export([first/1, second/1, swap/1, map_first/2, map_second/2, new/2]).
-
--spec first({FM, any()}) -> FM.
-first(Pair) ->
- {A, _} = Pair,
- A.
-
--spec second({any(), FP}) -> FP.
-second(Pair) ->
- {_, A} = Pair,
- A.
-
--spec swap({FQ, FR}) -> {FR, FQ}.
-swap(Pair) ->
- {A, B} = Pair,
- {B, A}.
-
--spec map_first({FS, FT}, fun((FS) -> FU)) -> {FU, FT}.
-map_first(Pair, Fun) ->
- {A, B} = Pair,
- {Fun(A), B}.
-
--spec map_second({FV, FW}, fun((FW) -> FX)) -> {FV, FX}.
-map_second(Pair, Fun) ->
- {A, B} = Pair,
- {A, Fun(B)}.
-
--spec new(FY, FZ) -> {FY, FZ}.
-new(First, Second) ->
- {First, Second}.
diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam@queue.erl b/aoc2023/build/packages/gleam_stdlib/src/gleam@queue.erl
deleted file mode 100644
index 6b587e7..0000000
--- a/aoc2023/build/packages/gleam_stdlib/src/gleam@queue.erl
+++ /dev/null
@@ -1,121 +0,0 @@
--module(gleam@queue).
--compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]).
-
--export([new/0, from_list/1, to_list/1, is_empty/1, length/1, push_back/2, push_front/2, pop_back/1, pop_front/1, reverse/1, is_logically_equal/3, is_equal/2]).
--export_type([queue/1]).
-
--opaque queue(DRL) :: {queue, list(DRL), list(DRL)}.
-
--spec new() -> queue(any()).
-new() ->
- {queue, [], []}.
-
--spec from_list(list(DRO)) -> queue(DRO).
-from_list(List) ->
- {queue, [], List}.
-
--spec to_list(queue(DRR)) -> list(DRR).
-to_list(Queue) ->
- _pipe = erlang:element(3, Queue),
- gleam@list:append(_pipe, gleam@list:reverse(erlang:element(2, Queue))).
-
--spec is_empty(queue(any())) -> boolean().
-is_empty(Queue) ->
- (erlang:element(2, Queue) =:= []) andalso (erlang:element(3, Queue) =:= []).
-
--spec length(queue(any())) -> integer().
-length(Queue) ->
- gleam@list:length(erlang:element(2, Queue)) + gleam@list:length(
- erlang:element(3, Queue)
- ).
-
--spec push_back(queue(DRY), DRY) -> queue(DRY).
-push_back(Queue, Item) ->
- {queue, [Item | erlang:element(2, Queue)], erlang:element(3, Queue)}.
-
--spec push_front(queue(DSB), DSB) -> queue(DSB).
-push_front(Queue, Item) ->
- {queue, erlang:element(2, Queue), [Item | erlang:element(3, Queue)]}.
-
--spec pop_back(queue(DSE)) -> {ok, {DSE, queue(DSE)}} | {error, nil}.
-pop_back(Queue) ->
- case Queue of
- {queue, [], []} ->
- {error, nil};
-
- {queue, [], Out} ->
- pop_back({queue, gleam@list:reverse(Out), []});
-
- {queue, [First | Rest], Out@1} ->
- Queue@1 = {queue, Rest, Out@1},
- {ok, {First, Queue@1}}
- end.
-
--spec pop_front(queue(DSJ)) -> {ok, {DSJ, queue(DSJ)}} | {error, nil}.
-pop_front(Queue) ->
- case Queue of
- {queue, [], []} ->
- {error, nil};
-
- {queue, In, []} ->
- pop_front({queue, [], gleam@list:reverse(In)});
-
- {queue, In@1, [First | Rest]} ->
- Queue@1 = {queue, In@1, Rest},
- {ok, {First, Queue@1}}
- end.
-
--spec reverse(queue(DSO)) -> queue(DSO).
-reverse(Queue) ->
- {queue, erlang:element(3, Queue), erlang:element(2, Queue)}.
-
--spec check_equal(
- list(DSR),
- list(DSR),
- list(DSR),
- list(DSR),
- fun((DSR, DSR) -> boolean())
-) -> boolean().
-check_equal(Xs, X_tail, Ys, Y_tail, Eq) ->
- case {Xs, X_tail, Ys, Y_tail} of
- {[], [], [], []} ->
- true;
-
- {[X | Xs@1], _, [Y | Ys@1], _} ->
- case Eq(X, Y) of
- false ->
- false;
-
- true ->
- check_equal(Xs@1, X_tail, Ys@1, Y_tail, Eq)
- end;
-
- {[], [_ | _], _, _} ->
- check_equal(gleam@list:reverse(X_tail), [], Ys, Y_tail, Eq);
-
- {_, _, [], [_ | _]} ->
- check_equal(Xs, X_tail, gleam@list:reverse(Y_tail), [], Eq);
-
- {_, _, _, _} ->
- false
- end.
-
--spec is_logically_equal(queue(DSW), queue(DSW), fun((DSW, DSW) -> boolean())) -> boolean().
-is_logically_equal(A, B, Element_is_equal) ->
- check_equal(
- erlang:element(3, A),
- erlang:element(2, A),
- erlang:element(3, B),
- erlang:element(2, B),
- Element_is_equal
- ).
-
--spec is_equal(queue(DSZ), queue(DSZ)) -> boolean().
-is_equal(A, B) ->
- check_equal(
- erlang:element(3, A),
- erlang:element(2, A),
- erlang:element(3, B),
- erlang:element(2, B),
- fun(A@1, B@1) -> A@1 =:= B@1 end
- ).
diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam@regex.erl b/aoc2023/build/packages/gleam_stdlib/src/gleam@regex.erl
deleted file mode 100644
index 2d1c5fc..0000000
--- a/aoc2023/build/packages/gleam_stdlib/src/gleam@regex.erl
+++ /dev/null
@@ -1,33 +0,0 @@
--module(gleam@regex).
--compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]).
-
--export([compile/2, from_string/1, check/2, split/2, scan/2]).
--export_type([regex/0, match/0, compile_error/0, options/0]).
-
--type regex() :: any().
-
--type match() :: {match, binary(), list(gleam@option:option(binary()))}.
-
--type compile_error() :: {compile_error, binary(), integer()}.
-
--type options() :: {options, boolean(), boolean()}.
-
--spec compile(binary(), options()) -> {ok, regex()} | {error, compile_error()}.
-compile(Pattern, Options) ->
- gleam_stdlib:compile_regex(Pattern, Options).
-
--spec from_string(binary()) -> {ok, regex()} | {error, compile_error()}.
-from_string(Pattern) ->
- compile(Pattern, {options, false, false}).
-
--spec check(regex(), binary()) -> boolean().
-check(Regex, Content) ->
- gleam_stdlib:regex_check(Regex, Content).
-
--spec split(regex(), binary()) -> list(binary()).
-split(Regex, String) ->
- gleam_stdlib:regex_split(Regex, String).
-
--spec scan(regex(), binary()) -> list(match()).
-scan(Regex, String) ->
- gleam_stdlib:regex_scan(Regex, String).
diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam@result.erl b/aoc2023/build/packages/gleam_stdlib/src/gleam@result.erl
deleted file mode 100644
index 7324e45..0000000
--- a/aoc2023/build/packages/gleam_stdlib/src/gleam@result.erl
+++ /dev/null
@@ -1,201 +0,0 @@
--module(gleam@result).
--compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]).
-
--export([is_ok/1, is_error/1, map/2, map_error/2, flatten/1, 'try'/2, then/2, unwrap/2, lazy_unwrap/2, unwrap_error/2, unwrap_both/1, nil_error/1, 'or'/2, lazy_or/2, all/1, partition/1, replace/2, replace_error/2, values/1, try_recover/2]).
-
--spec is_ok({ok, any()} | {error, any()}) -> boolean().
-is_ok(Result) ->
- case Result of
- {error, _} ->
- false;
-
- {ok, _} ->
- true
- end.
-
--spec is_error({ok, any()} | {error, any()}) -> boolean().
-is_error(Result) ->
- case Result of
- {ok, _} ->
- false;
-
- {error, _} ->
- true
- end.
-
--spec map({ok, BFM} | {error, BFN}, fun((BFM) -> BFQ)) -> {ok, BFQ} |
- {error, BFN}.
-map(Result, Fun) ->
- case Result of
- {ok, X} ->
- {ok, Fun(X)};
-
- {error, E} ->
- {error, E}
- end.
-
--spec map_error({ok, BFT} | {error, BFU}, fun((BFU) -> BFX)) -> {ok, BFT} |
- {error, BFX}.
-map_error(Result, Fun) ->
- case Result of
- {ok, X} ->
- {ok, X};
-
- {error, Error} ->
- {error, Fun(Error)}
- end.
-
--spec flatten({ok, {ok, BGA} | {error, BGB}} | {error, BGB}) -> {ok, BGA} |
- {error, BGB}.
-flatten(Result) ->
- case Result of
- {ok, X} ->
- X;
-
- {error, Error} ->
- {error, Error}
- end.
-
--spec 'try'({ok, BGI} | {error, BGJ}, fun((BGI) -> {ok, BGM} | {error, BGJ})) -> {ok,
- BGM} |
- {error, BGJ}.
-'try'(Result, Fun) ->
- case Result of
- {ok, X} ->
- Fun(X);
-
- {error, E} ->
- {error, E}
- end.
-
--spec then({ok, BGR} | {error, BGS}, fun((BGR) -> {ok, BGV} | {error, BGS})) -> {ok,
- BGV} |
- {error, BGS}.
-then(Result, Fun) ->
- 'try'(Result, Fun).
-
--spec unwrap({ok, BHA} | {error, any()}, BHA) -> BHA.
-unwrap(Result, Default) ->
- case Result of
- {ok, V} ->
- V;
-
- {error, _} ->
- Default
- end.
-
--spec lazy_unwrap({ok, BHE} | {error, any()}, fun(() -> BHE)) -> BHE.
-lazy_unwrap(Result, Default) ->
- case Result of
- {ok, V} ->
- V;
-
- {error, _} ->
- Default()
- end.
-
--spec unwrap_error({ok, any()} | {error, BHJ}, BHJ) -> BHJ.
-unwrap_error(Result, Default) ->
- case Result of
- {ok, _} ->
- Default;
-
- {error, E} ->
- E
- end.
-
--spec unwrap_both({ok, BHM} | {error, BHM}) -> BHM.
-unwrap_both(Result) ->
- case Result of
- {ok, A} ->
- A;
-
- {error, A@1} ->
- A@1
- end.
-
--spec nil_error({ok, BHP} | {error, any()}) -> {ok, BHP} | {error, nil}.
-nil_error(Result) ->
- map_error(Result, fun(_) -> nil end).
-
--spec 'or'({ok, BHV} | {error, BHW}, {ok, BHV} | {error, BHW}) -> {ok, BHV} |
- {error, BHW}.
-'or'(First, Second) ->
- case First of
- {ok, _} ->
- First;
-
- {error, _} ->
- Second
- end.
-
--spec lazy_or({ok, BID} | {error, BIE}, fun(() -> {ok, BID} | {error, BIE})) -> {ok,
- BID} |
- {error, BIE}.
-lazy_or(First, Second) ->
- case First of
- {ok, _} ->
- First;
-
- {error, _} ->
- Second()
- end.
-
--spec all(list({ok, BIL} | {error, BIM})) -> {ok, list(BIL)} | {error, BIM}.
-all(Results) ->
- gleam@list:try_map(Results, fun(X) -> X end).
-
--spec do_partition(list({ok, BJA} | {error, BJB}), list(BJA), list(BJB)) -> {list(BJA),
- list(BJB)}.
-do_partition(Results, Oks, Errors) ->
- case Results of
- [] ->
- {Oks, Errors};
-
- [{ok, A} | Rest] ->
- do_partition(Rest, [A | Oks], Errors);
-
- [{error, E} | Rest@1] ->
- do_partition(Rest@1, Oks, [E | Errors])
- end.
-
--spec partition(list({ok, BIT} | {error, BIU})) -> {list(BIT), list(BIU)}.
-partition(Results) ->
- do_partition(Results, [], []).
-
--spec replace({ok, any()} | {error, BJJ}, BJM) -> {ok, BJM} | {error, BJJ}.
-replace(Result, Value) ->
- case Result of
- {ok, _} ->
- {ok, Value};
-
- {error, Error} ->
- {error, Error}
- end.
-
--spec replace_error({ok, BJP} | {error, any()}, BJT) -> {ok, BJP} | {error, BJT}.
-replace_error(Result, Error) ->
- case Result of
- {ok, X} ->
- {ok, X};
-
- {error, _} ->
- {error, Error}
- end.
-
--spec values(list({ok, BJW} | {error, any()})) -> list(BJW).
-values(Results) ->
- gleam@list:filter_map(Results, fun(R) -> R end).
-
--spec try_recover(
- {ok, BKC} | {error, BKD},
- fun((BKD) -> {ok, BKC} | {error, BKG})
-) -> {ok, BKC} | {error, BKG}.
-try_recover(Result, Fun) ->
- case Result of
- {ok, Value} ->
- {ok, Value};
-
- {error, Error} ->
- Fun(Error)
- end.
diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam@set.erl b/aoc2023/build/packages/gleam_stdlib/src/gleam@set.erl
deleted file mode 100644
index df87b13..0000000
--- a/aoc2023/build/packages/gleam_stdlib/src/gleam@set.erl
+++ /dev/null
@@ -1,85 +0,0 @@
--module(gleam@set).
--compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]).
-
--export([new/0, size/1, insert/2, contains/2, delete/2, to_list/1, from_list/1, fold/3, filter/2, drop/2, take/2, union/2, intersection/2]).
--export_type([set/1]).
-
--opaque set(DJZ) :: {set, gleam@dict:dict(DJZ, list(nil))}.
-
--spec new() -> set(any()).
-new() ->
- {set, gleam@dict:new()}.
-
--spec size(set(any())) -> integer().
-size(Set) ->
- gleam@dict:size(erlang:element(2, Set)).
-
--spec insert(set(DKF), DKF) -> set(DKF).
-insert(Set, Member) ->
- {set, gleam@dict:insert(erlang:element(2, Set), Member, [])}.
-
--spec contains(set(DKI), DKI) -> boolean().
-contains(Set, Member) ->
- _pipe = erlang:element(2, Set),
- _pipe@1 = gleam@dict:get(_pipe, Member),
- gleam@result:is_ok(_pipe@1).
-
--spec delete(set(DKK), DKK) -> set(DKK).
-delete(Set, Member) ->
- {set, gleam@dict:delete(erlang:element(2, Set), Member)}.
-
--spec to_list(set(DKN)) -> list(DKN).
-to_list(Set) ->
- gleam@dict:keys(erlang:element(2, Set)).
-
--spec from_list(list(DKQ)) -> set(DKQ).
-from_list(Members) ->
- Map = gleam@list:fold(
- Members,
- gleam@dict:new(),
- fun(M, K) -> gleam@dict:insert(M, K, []) end
- ),
- {set, Map}.
-
--spec fold(set(DKT), DKV, fun((DKV, DKT) -> DKV)) -> DKV.
-fold(Set, Initial, Reducer) ->
- gleam@dict:fold(
- erlang:element(2, Set),
- Initial,
- fun(A, K, _) -> Reducer(A, K) end
- ).
-
--spec filter(set(DKW), fun((DKW) -> boolean())) -> set(DKW).
-filter(Set, Predicate) ->
- {set,
- gleam@dict:filter(erlang:element(2, Set), fun(M, _) -> Predicate(M) end)}.
-
--spec drop(set(DKZ), list(DKZ)) -> set(DKZ).
-drop(Set, Disallowed) ->
- gleam@list:fold(Disallowed, Set, fun delete/2).
-
--spec take(set(DLD), list(DLD)) -> set(DLD).
-take(Set, Desired) ->
- {set, gleam@dict:take(erlang:element(2, Set), Desired)}.
-
--spec order(set(DLH), set(DLH)) -> {set(DLH), set(DLH)}.
-order(First, Second) ->
- case gleam@dict:size(erlang:element(2, First)) > gleam@dict:size(
- erlang:element(2, Second)
- ) of
- true ->
- {First, Second};
-
- false ->
- {Second, First}
- end.
-
--spec union(set(DLM), set(DLM)) -> set(DLM).
-union(First, Second) ->
- {Larger, Smaller} = order(First, Second),
- fold(Smaller, Larger, fun insert/2).
-
--spec intersection(set(DLQ), set(DLQ)) -> set(DLQ).
-intersection(First, Second) ->
- {Larger, Smaller} = order(First, Second),
- take(Larger, to_list(Smaller)).
diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam@string.erl b/aoc2023/build/packages/gleam_stdlib/src/gleam@string.erl
deleted file mode 100644
index 6cba31d..0000000
--- a/aoc2023/build/packages/gleam_stdlib/src/gleam@string.erl
+++ /dev/null
@@ -1,352 +0,0 @@
--module(gleam@string).
--compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]).
-
--export([is_empty/1, length/1, reverse/1, replace/3, lowercase/1, uppercase/1, compare/2, slice/3, crop/2, drop_left/2, drop_right/2, contains/2, starts_with/2, ends_with/2, split_once/2, append/2, concat/1, repeat/2, join/2, pad_left/3, pad_right/3, trim/1, trim_left/1, trim_right/1, pop_grapheme/1, to_graphemes/1, split/2, to_utf_codepoints/1, from_utf_codepoints/1, utf_codepoint/1, utf_codepoint_to_int/1, to_option/1, first/1, last/1, capitalise/1, inspect/1, byte_size/1]).
--export_type([direction/0]).
-
--type direction() :: leading | trailing | both.
-
--spec is_empty(binary()) -> boolean().
-is_empty(Str) ->
- Str =:= <<""/utf8>>.
-
--spec length(binary()) -> integer().
-length(String) ->
- string:length(String).
-
--spec do_reverse(binary()) -> binary().
-do_reverse(String) ->
- _pipe = String,
- _pipe@1 = gleam@string_builder:from_string(_pipe),
- _pipe@2 = gleam@string_builder:reverse(_pipe@1),
- gleam@string_builder:to_string(_pipe@2).
-
--spec reverse(binary()) -> binary().
-reverse(String) ->
- do_reverse(String).
-
--spec replace(binary(), binary(), binary()) -> binary().
-replace(String, Pattern, Substitute) ->
- _pipe = String,
- _pipe@1 = gleam@string_builder:from_string(_pipe),
- _pipe@2 = gleam@string_builder:replace(_pipe@1, Pattern, Substitute),
- gleam@string_builder:to_string(_pipe@2).
-
--spec lowercase(binary()) -> binary().
-lowercase(String) ->
- string:lowercase(String).
-
--spec uppercase(binary()) -> binary().
-uppercase(String) ->
- string:uppercase(String).
-
--spec compare(binary(), binary()) -> gleam@order:order().
-compare(A, B) ->
- case A =:= B of
- true ->
- eq;
-
- _ ->
- case gleam_stdlib:less_than(A, B) of
- true ->
- lt;
-
- _ ->
- gt
- end
- end.
-
--spec slice(binary(), integer(), integer()) -> binary().
-slice(String, Idx, Len) ->
- case Len < 0 of
- true ->
- <<""/utf8>>;
-
- false ->
- case Idx < 0 of
- true ->
- Translated_idx = length(String) + Idx,
- case Translated_idx < 0 of
- true ->
- <<""/utf8>>;
-
- false ->
- string:slice(String, Translated_idx, Len)
- end;
-
- false ->
- string:slice(String, Idx, Len)
- end
- end.
-
--spec crop(binary(), binary()) -> binary().
-crop(String, Substring) ->
- gleam_stdlib:crop_string(String, Substring).
-
--spec drop_left(binary(), integer()) -> binary().
-drop_left(String, Num_graphemes) ->
- case Num_graphemes < 0 of
- true ->
- String;
-
- false ->
- slice(String, Num_graphemes, length(String) - Num_graphemes)
- end.
-
--spec drop_right(binary(), integer()) -> binary().
-drop_right(String, Num_graphemes) ->
- case Num_graphemes < 0 of
- true ->
- String;
-
- false ->
- slice(String, 0, length(String) - Num_graphemes)
- end.
-
--spec contains(binary(), binary()) -> boolean().
-contains(Haystack, Needle) ->
- gleam_stdlib:contains_string(Haystack, Needle).
-
--spec starts_with(binary(), binary()) -> boolean().
-starts_with(String, Prefix) ->
- gleam_stdlib:string_starts_with(String, Prefix).
-
--spec ends_with(binary(), binary()) -> boolean().
-ends_with(String, Suffix) ->
- gleam_stdlib:string_ends_with(String, Suffix).
-
--spec do_split_once(binary(), binary()) -> {ok, {binary(), binary()}} |
- {error, nil}.
-do_split_once(X, Substring) ->
- case string:split(X, Substring) of
- [First, Rest] ->
- {ok, {First, Rest}};
-
- _ ->
- {error, nil}
- end.
-
--spec split_once(binary(), binary()) -> {ok, {binary(), binary()}} |
- {error, nil}.
-split_once(X, Substring) ->
- do_split_once(X, Substring).
-
--spec append(binary(), binary()) -> binary().
-append(First, Second) ->
- _pipe = First,
- _pipe@1 = gleam@string_builder:from_string(_pipe),
- _pipe@2 = gleam@string_builder:append(_pipe@1, Second),
- gleam@string_builder:to_string(_pipe@2).
-
--spec concat(list(binary())) -> binary().
-concat(Strings) ->
- _pipe = Strings,
- _pipe@1 = gleam@string_builder:from_strings(_pipe),
- gleam@string_builder:to_string(_pipe@1).
-
--spec repeat(binary(), integer()) -> binary().
-repeat(String, Times) ->
- _pipe = gleam@iterator:repeat(String),
- _pipe@1 = gleam@iterator:take(_pipe, Times),
- _pipe@2 = gleam@iterator:to_list(_pipe@1),
- concat(_pipe@2).
-
--spec do_join(list(binary()), binary()) -> binary().
-do_join(Strings, Separator) ->
- _pipe = Strings,
- _pipe@1 = gleam@list:intersperse(_pipe, Separator),
- concat(_pipe@1).
-
--spec join(list(binary()), binary()) -> binary().
-join(Strings, Separator) ->
- do_join(Strings, Separator).
-
--spec padding(integer(), binary()) -> gleam@iterator:iterator(binary()).
-padding(Size, Pad_string) ->
- Pad_length = length(Pad_string),
- Num_pads = case Pad_length of
- 0 -> 0;
- Gleam@denominator -> Size div Gleam@denominator
- end,
- Extra = case Pad_length of
- 0 -> 0;
- Gleam@denominator@1 -> Size rem Gleam@denominator@1
- end,
- _pipe = gleam@iterator:repeat(Pad_string),
- _pipe@1 = gleam@iterator:take(_pipe, Num_pads),
- gleam@iterator:append(
- _pipe@1,
- gleam@iterator:single(slice(Pad_string, 0, Extra))
- ).
-
--spec pad_left(binary(), integer(), binary()) -> binary().
-pad_left(String, Desired_length, Pad_string) ->
- Current_length = length(String),
- To_pad_length = Desired_length - Current_length,
- _pipe = padding(To_pad_length, Pad_string),
- _pipe@1 = gleam@iterator:append(_pipe, gleam@iterator:single(String)),
- _pipe@2 = gleam@iterator:to_list(_pipe@1),
- concat(_pipe@2).
-
--spec pad_right(binary(), integer(), binary()) -> binary().
-pad_right(String, Desired_length, Pad_string) ->
- Current_length = length(String),
- To_pad_length = Desired_length - Current_length,
- _pipe = gleam@iterator:single(String),
- _pipe@1 = gleam@iterator:append(_pipe, padding(To_pad_length, Pad_string)),
- _pipe@2 = gleam@iterator:to_list(_pipe@1),
- concat(_pipe@2).
-
--spec do_trim(binary()) -> binary().
-do_trim(String) ->
- string:trim(String, both).
-
--spec trim(binary()) -> binary().
-trim(String) ->
- do_trim(String).
-
--spec do_trim_left(binary()) -> binary().
-do_trim_left(String) ->
- string:trim(String, leading).
-
--spec trim_left(binary()) -> binary().
-trim_left(String) ->
- do_trim_left(String).
-
--spec do_trim_right(binary()) -> binary().
-do_trim_right(String) ->
- string:trim(String, trailing).
-
--spec trim_right(binary()) -> binary().
-trim_right(String) ->
- do_trim_right(String).
-
--spec pop_grapheme(binary()) -> {ok, {binary(), binary()}} | {error, nil}.
-pop_grapheme(String) ->
- gleam_stdlib:string_pop_grapheme(String).
-
--spec do_to_graphemes(binary(), list(binary())) -> list(binary()).
-do_to_graphemes(String, Acc) ->
- case pop_grapheme(String) of
- {ok, {Grapheme, Rest}} ->
- do_to_graphemes(Rest, [Grapheme | Acc]);
-
- _ ->
- Acc
- end.
-
--spec to_graphemes(binary()) -> list(binary()).
-to_graphemes(String) ->
- _pipe = do_to_graphemes(String, []),
- gleam@list:reverse(_pipe).
-
--spec split(binary(), binary()) -> list(binary()).
-split(X, Substring) ->
- case Substring of
- <<""/utf8>> ->
- to_graphemes(X);
-
- _ ->
- _pipe = X,
- _pipe@1 = gleam@string_builder:from_string(_pipe),
- _pipe@2 = gleam@string_builder:split(_pipe@1, Substring),
- gleam@list:map(_pipe@2, fun gleam@string_builder:to_string/1)
- end.
-
--spec do_to_utf_codepoints_impl(bitstring(), list(integer())) -> list(integer()).
-do_to_utf_codepoints_impl(Bit_array, Acc) ->
- case Bit_array of
- <<First/utf8, Rest/binary>> ->
- do_to_utf_codepoints_impl(Rest, [First | Acc]);
-
- _ ->
- Acc
- end.
-
--spec do_to_utf_codepoints(binary()) -> list(integer()).
-do_to_utf_codepoints(String) ->
- _pipe = do_to_utf_codepoints_impl(<<String/binary>>, []),
- gleam@list:reverse(_pipe).
-
--spec to_utf_codepoints(binary()) -> list(integer()).
-to_utf_codepoints(String) ->
- do_to_utf_codepoints(String).
-
--spec from_utf_codepoints(list(integer())) -> binary().
-from_utf_codepoints(Utf_codepoints) ->
- gleam_stdlib:utf_codepoint_list_to_string(Utf_codepoints).
-
--spec utf_codepoint(integer()) -> {ok, integer()} | {error, nil}.
-utf_codepoint(Value) ->
- case Value of
- I when I > 1114111 ->
- {error, nil};
-
- 65534 ->
- {error, nil};
-
- 65535 ->
- {error, nil};
-
- I@1 when (I@1 >= 55296) andalso (I@1 =< 57343) ->
- {error, nil};
-
- I@2 ->
- {ok, gleam_stdlib:identity(I@2)}
- end.
-
--spec utf_codepoint_to_int(integer()) -> integer().
-utf_codepoint_to_int(Cp) ->
- gleam_stdlib:identity(Cp).
-
--spec to_option(binary()) -> gleam@option:option(binary()).
-to_option(S) ->
- case S of
- <<""/utf8>> ->
- none;
-
- _ ->
- {some, S}
- end.
-
--spec first(binary()) -> {ok, binary()} | {error, nil}.
-first(S) ->
- case pop_grapheme(S) of
- {ok, {First, _}} ->
- {ok, First};
-
- {error, E} ->
- {error, E}
- end.
-
--spec last(binary()) -> {ok, binary()} | {error, nil}.
-last(S) ->
- case pop_grapheme(S) of
- {ok, {First, <<""/utf8>>}} ->
- {ok, First};
-
- {ok, {_, Rest}} ->
- {ok, slice(Rest, -1, 1)};
-
- {error, E} ->
- {error, E}
- end.
-
--spec capitalise(binary()) -> binary().
-capitalise(S) ->
- case pop_grapheme(S) of
- {ok, {First, Rest}} ->
- append(uppercase(First), lowercase(Rest));
-
- _ ->
- <<""/utf8>>
- end.
-
--spec inspect(any()) -> binary().
-inspect(Term) ->
- _pipe = gleam_stdlib:inspect(Term),
- gleam@string_builder:to_string(_pipe).
-
--spec byte_size(binary()) -> integer().
-byte_size(String) ->
- erlang:byte_size(String).
diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam@string_builder.erl b/aoc2023/build/packages/gleam_stdlib/src/gleam@string_builder.erl
deleted file mode 100644
index 693e840..0000000
--- a/aoc2023/build/packages/gleam_stdlib/src/gleam@string_builder.erl
+++ /dev/null
@@ -1,91 +0,0 @@
--module(gleam@string_builder).
--compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]).
-
--export([prepend_builder/2, append_builder/2, new/0, from_strings/1, concat/1, from_string/1, prepend/2, append/2, to_string/1, byte_size/1, join/2, lowercase/1, uppercase/1, reverse/1, split/2, replace/3, is_equal/2, is_empty/1]).
--export_type([string_builder/0, direction/0]).
-
--type string_builder() :: any().
-
--type direction() :: all.
-
--spec prepend_builder(string_builder(), string_builder()) -> string_builder().
-prepend_builder(Builder, Prefix) ->
- gleam_stdlib:iodata_append(Prefix, Builder).
-
--spec append_builder(string_builder(), string_builder()) -> string_builder().
-append_builder(Builder, Suffix) ->
- gleam_stdlib:iodata_append(Builder, Suffix).
-
--spec new() -> string_builder().
-new() ->
- gleam_stdlib:identity([]).
-
--spec from_strings(list(binary())) -> string_builder().
-from_strings(Strings) ->
- gleam_stdlib:identity(Strings).
-
--spec concat(list(string_builder())) -> string_builder().
-concat(Builders) ->
- gleam_stdlib:identity(Builders).
-
--spec from_string(binary()) -> string_builder().
-from_string(String) ->
- gleam_stdlib:identity(String).
-
--spec prepend(string_builder(), binary()) -> string_builder().
-prepend(Builder, Prefix) ->
- append_builder(from_string(Prefix), Builder).
-
--spec append(string_builder(), binary()) -> string_builder().
-append(Builder, Second) ->
- append_builder(Builder, from_string(Second)).
-
--spec to_string(string_builder()) -> binary().
-to_string(Builder) ->
- unicode:characters_to_binary(Builder).
-
--spec byte_size(string_builder()) -> integer().
-byte_size(Builder) ->
- erlang:iolist_size(Builder).
-
--spec join(list(string_builder()), binary()) -> string_builder().
-join(Builders, Sep) ->
- _pipe = Builders,
- _pipe@1 = gleam@list:intersperse(_pipe, from_string(Sep)),
- concat(_pipe@1).
-
--spec lowercase(string_builder()) -> string_builder().
-lowercase(Builder) ->
- string:lowercase(Builder).
-
--spec uppercase(string_builder()) -> string_builder().
-uppercase(Builder) ->
- string:uppercase(Builder).
-
--spec reverse(string_builder()) -> string_builder().
-reverse(Builder) ->
- string:reverse(Builder).
-
--spec do_split(string_builder(), binary()) -> list(string_builder()).
-do_split(Iodata, Pattern) ->
- string:split(Iodata, Pattern, all).
-
--spec split(string_builder(), binary()) -> list(string_builder()).
-split(Iodata, Pattern) ->
- do_split(Iodata, Pattern).
-
--spec do_replace(string_builder(), binary(), binary()) -> string_builder().
-do_replace(Iodata, Pattern, Substitute) ->
- string:replace(Iodata, Pattern, Substitute, all).
-
--spec replace(string_builder(), binary(), binary()) -> string_builder().
-replace(Builder, Pattern, Substitute) ->
- do_replace(Builder, Pattern, Substitute).
-
--spec is_equal(string_builder(), string_builder()) -> boolean().
-is_equal(A, B) ->
- string:equal(A, B).
-
--spec is_empty(string_builder()) -> boolean().
-is_empty(Builder) ->
- string:is_empty(Builder).
diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam@uri.erl b/aoc2023/build/packages/gleam_stdlib/src/gleam@uri.erl
deleted file mode 100644
index 7ec4fe7..0000000
--- a/aoc2023/build/packages/gleam_stdlib/src/gleam@uri.erl
+++ /dev/null
@@ -1,252 +0,0 @@
--module(gleam@uri).
--compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]).
-
--export([parse/1, parse_query/1, percent_encode/1, query_to_string/1, percent_decode/1, path_segments/1, to_string/1, origin/1, merge/2]).
--export_type([uri/0]).
-
--type uri() :: {uri,
- gleam@option:option(binary()),
- gleam@option:option(binary()),
- gleam@option:option(binary()),
- gleam@option:option(integer()),
- binary(),
- gleam@option:option(binary()),
- gleam@option:option(binary())}.
-
--spec parse(binary()) -> {ok, uri()} | {error, nil}.
-parse(Uri_string) ->
- gleam_stdlib:uri_parse(Uri_string).
-
--spec parse_query(binary()) -> {ok, list({binary(), binary()})} | {error, nil}.
-parse_query(Query) ->
- gleam_stdlib:parse_query(Query).
-
--spec percent_encode(binary()) -> binary().
-percent_encode(Value) ->
- gleam_stdlib:percent_encode(Value).
-
--spec query_pair({binary(), binary()}) -> gleam@string_builder:string_builder().
-query_pair(Pair) ->
- gleam@string_builder:from_strings(
- [percent_encode(erlang:element(1, Pair)),
- <<"="/utf8>>,
- percent_encode(erlang:element(2, Pair))]
- ).
-
--spec query_to_string(list({binary(), binary()})) -> binary().
-query_to_string(Query) ->
- _pipe = Query,
- _pipe@1 = gleam@list:map(_pipe, fun query_pair/1),
- _pipe@2 = gleam@list:intersperse(
- _pipe@1,
- gleam@string_builder:from_string(<<"&"/utf8>>)
- ),
- _pipe@3 = gleam@string_builder:concat(_pipe@2),
- gleam@string_builder:to_string(_pipe@3).
-
--spec percent_decode(binary()) -> {ok, binary()} | {error, nil}.
-percent_decode(Value) ->
- gleam_stdlib:percent_decode(Value).
-
--spec do_remove_dot_segments(list(binary()), list(binary())) -> list(binary()).
-do_remove_dot_segments(Input, Accumulator) ->
- case Input of
- [] ->
- gleam@list:reverse(Accumulator);
-
- [Segment | Rest] ->
- Accumulator@5 = case {Segment, Accumulator} of
- {<<""/utf8>>, Accumulator@1} ->
- Accumulator@1;
-
- {<<"."/utf8>>, Accumulator@2} ->
- Accumulator@2;
-
- {<<".."/utf8>>, []} ->
- [];
-
- {<<".."/utf8>>, [_ | Accumulator@3]} ->
- Accumulator@3;
-
- {Segment@1, Accumulator@4} ->
- [Segment@1 | Accumulator@4]
- end,
- do_remove_dot_segments(Rest, Accumulator@5)
- end.
-
--spec remove_dot_segments(list(binary())) -> list(binary()).
-remove_dot_segments(Input) ->
- do_remove_dot_segments(Input, []).
-
--spec path_segments(binary()) -> list(binary()).
-path_segments(Path) ->
- remove_dot_segments(gleam@string:split(Path, <<"/"/utf8>>)).
-
--spec to_string(uri()) -> binary().
-to_string(Uri) ->
- Parts = case erlang:element(8, Uri) of
- {some, Fragment} ->
- [<<"#"/utf8>>, Fragment];
-
- _ ->
- []
- end,
- Parts@1 = case erlang:element(7, Uri) of
- {some, Query} ->
- [<<"?"/utf8>>, Query | Parts];
-
- _ ->
- Parts
- end,
- Parts@2 = [erlang:element(6, Uri) | Parts@1],
- Parts@3 = case {erlang:element(4, Uri),
- gleam@string:starts_with(erlang:element(6, Uri), <<"/"/utf8>>)} of
- {{some, Host}, false} when Host =/= <<""/utf8>> ->
- [<<"/"/utf8>> | Parts@2];
-
- {_, _} ->
- Parts@2
- end,
- Parts@4 = case {erlang:element(4, Uri), erlang:element(5, Uri)} of
- {{some, _}, {some, Port}} ->
- [<<":"/utf8>>, gleam@int:to_string(Port) | Parts@3];
-
- {_, _} ->
- Parts@3
- end,
- Parts@5 = case {erlang:element(2, Uri),
- erlang:element(3, Uri),
- erlang:element(4, Uri)} of
- {{some, S}, {some, U}, {some, H}} ->
- [S, <<"://"/utf8>>, U, <<"@"/utf8>>, H | Parts@4];
-
- {{some, S@1}, none, {some, H@1}} ->
- [S@1, <<"://"/utf8>>, H@1 | Parts@4];
-
- {{some, S@2}, {some, _}, none} ->
- [S@2, <<":"/utf8>> | Parts@4];
-
- {{some, S@2}, none, none} ->
- [S@2, <<":"/utf8>> | Parts@4];
-
- {none, none, {some, H@2}} ->
- [<<"//"/utf8>>, H@2 | Parts@4];
-
- {_, _, _} ->
- Parts@4
- end,
- gleam@string:concat(Parts@5).
-
--spec origin(uri()) -> {ok, binary()} | {error, nil}.
-origin(Uri) ->
- {uri, Scheme, _, Host, Port, _, _, _} = Uri,
- case Scheme of
- {some, <<"https"/utf8>>} when Port =:= {some, 443} ->
- Origin = {uri, Scheme, none, Host, none, <<""/utf8>>, none, none},
- {ok, to_string(Origin)};
-
- {some, <<"http"/utf8>>} when Port =:= {some, 80} ->
- Origin@1 = {uri, Scheme, none, Host, none, <<""/utf8>>, none, none},
- {ok, to_string(Origin@1)};
-
- {some, S} when (S =:= <<"http"/utf8>>) orelse (S =:= <<"https"/utf8>>) ->
- Origin@2 = {uri, Scheme, none, Host, Port, <<""/utf8>>, none, none},
- {ok, to_string(Origin@2)};
-
- _ ->
- {error, nil}
- end.
-
--spec drop_last(list(DFL)) -> list(DFL).
-drop_last(Elements) ->
- gleam@list:take(Elements, gleam@list:length(Elements) - 1).
-
--spec join_segments(list(binary())) -> binary().
-join_segments(Segments) ->
- gleam@string:join([<<""/utf8>> | Segments], <<"/"/utf8>>).
-
--spec merge(uri(), uri()) -> {ok, uri()} | {error, nil}.
-merge(Base, Relative) ->
- case Base of
- {uri, {some, _}, _, {some, _}, _, _, _, _} ->
- case Relative of
- {uri, _, _, {some, _}, _, _, _, _} ->
- Path = begin
- _pipe = gleam@string:split(
- erlang:element(6, Relative),
- <<"/"/utf8>>
- ),
- _pipe@1 = remove_dot_segments(_pipe),
- join_segments(_pipe@1)
- end,
- Resolved = {uri,
- gleam@option:'or'(
- erlang:element(2, Relative),
- erlang:element(2, Base)
- ),
- none,
- erlang:element(4, Relative),
- gleam@option:'or'(
- erlang:element(5, Relative),
- erlang:element(5, Base)
- ),
- Path,
- erlang:element(7, Relative),
- erlang:element(8, Relative)},
- {ok, Resolved};
-
- _ ->
- {New_path, New_query} = case erlang:element(6, Relative) of
- <<""/utf8>> ->
- {erlang:element(6, Base),
- gleam@option:'or'(
- erlang:element(7, Relative),
- erlang:element(7, Base)
- )};
-
- _ ->
- Path_segments = case gleam@string:starts_with(
- erlang:element(6, Relative),
- <<"/"/utf8>>
- ) of
- true ->
- gleam@string:split(
- erlang:element(6, Relative),
- <<"/"/utf8>>
- );
-
- false ->
- _pipe@2 = gleam@string:split(
- erlang:element(6, Base),
- <<"/"/utf8>>
- ),
- _pipe@3 = drop_last(_pipe@2),
- gleam@list:append(
- _pipe@3,
- gleam@string:split(
- erlang:element(6, Relative),
- <<"/"/utf8>>
- )
- )
- end,
- Path@1 = begin
- _pipe@4 = Path_segments,
- _pipe@5 = remove_dot_segments(_pipe@4),
- join_segments(_pipe@5)
- end,
- {Path@1, erlang:element(7, Relative)}
- end,
- Resolved@1 = {uri,
- erlang:element(2, Base),
- none,
- erlang:element(4, Base),
- erlang:element(5, Base),
- New_path,
- New_query,
- erlang:element(8, Relative)},
- {ok, Resolved@1}
- end;
-
- _ ->
- {error, nil}
- end.
diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam_stdlib.app.src b/aoc2023/build/packages/gleam_stdlib/src/gleam_stdlib.app.src
deleted file mode 100644
index bcf08e2..0000000
--- a/aoc2023/build/packages/gleam_stdlib/src/gleam_stdlib.app.src
+++ /dev/null
@@ -1,31 +0,0 @@
-{application, gleam_stdlib, [
- {vsn, "0.33.0"},
- {applications, []},
- {description, "A standard library for the Gleam programming language"},
- {modules, [gleam@base,
- gleam@bit_array,
- gleam@bit_builder,
- gleam@bit_string,
- gleam@bool,
- gleam@bytes_builder,
- gleam@dict,
- gleam@dynamic,
- gleam@float,
- gleam@function,
- gleam@int,
- gleam@io,
- gleam@iterator,
- gleam@list,
- gleam@map,
- gleam@option,
- gleam@order,
- gleam@pair,
- gleam@queue,
- gleam@regex,
- gleam@result,
- gleam@set,
- gleam@string,
- gleam@string_builder,
- gleam@uri]},
- {registered, []}
-]}.
diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam_stdlib.erl b/aoc2023/build/packages/gleam_stdlib/src/gleam_stdlib.erl
deleted file mode 100644
index c6ea125..0000000
--- a/aoc2023/build/packages/gleam_stdlib/src/gleam_stdlib.erl
+++ /dev/null
@@ -1,529 +0,0 @@
--module(gleam_stdlib).
-
--export([
- map_get/2, iodata_append/2, identity/1, decode_int/1, decode_bool/1,
- decode_float/1, decode_list/1, decode_option/2, decode_field/2, parse_int/1,
- parse_float/1, less_than/2, string_pop_grapheme/1, string_starts_with/2,
- wrap_list/1, string_ends_with/2, string_pad/4, decode_map/1, uri_parse/1,
- bit_array_int_to_u32/1, bit_array_int_from_u32/1, decode_result/1,
- bit_array_slice/3, decode_bit_array/1, compile_regex/2, regex_scan/2,
- percent_encode/1, percent_decode/1, regex_check/2, regex_split/2,
- base_decode64/1, parse_query/1, bit_array_concat/1, size_of_tuple/1,
- decode_tuple/1, decode_tuple2/1, decode_tuple3/1, decode_tuple4/1,
- decode_tuple5/1, decode_tuple6/1, tuple_get/2, classify_dynamic/1, print/1,
- println/1, print_error/1, println_error/1, inspect/1, float_to_string/1,
- int_from_base_string/2, utf_codepoint_list_to_string/1, contains_string/2,
- crop_string/2, base16_decode/1
-]).
-
-%% Taken from OTP's uri_string module
--define(DEC2HEX(X),
- if ((X) >= 0) andalso ((X) =< 9) -> (X) + $0;
- ((X) >= 10) andalso ((X) =< 15) -> (X) + $A - 10
- end).
-
-%% Taken from OTP's uri_string module
--define(HEX2DEC(X),
- if ((X) >= $0) andalso ((X) =< $9) -> (X) - $0;
- ((X) >= $A) andalso ((X) =< $F) -> (X) - $A + 10;
- ((X) >= $a) andalso ((X) =< $f) -> (X) - $a + 10
- end).
-
--define(is_lowercase_char(X), (X > 96 andalso X < 123)).
--define(is_underscore_char(X), (X == 95)).
--define(is_digit_char(X), (X > 47 andalso X < 58)).
-
-uppercase(X) -> X - 32.
-
-map_get(Map, Key) ->
- case maps:find(Key, Map) of
- error -> {error, nil};
- OkFound -> OkFound
- end.
-
-iodata_append(Iodata, String) -> [Iodata, String].
-
-identity(X) -> X.
-
-decode_error_msg(Expected, Data) when is_binary(Expected) ->
- decode_error(Expected, classify_dynamic(Data)).
-decode_error(Expected, Got) when is_binary(Expected) andalso is_binary(Got) ->
- {error, [{decode_error, Expected, Got, []}]}.
-
-classify_dynamic(nil) -> <<"Nil">>;
-classify_dynamic(X) when is_atom(X) -> <<"Atom">>;
-classify_dynamic(X) when is_binary(X) -> <<"String">>;
-classify_dynamic(X) when is_bitstring(X) -> <<"BitArray">>;
-classify_dynamic(X) when is_integer(X) -> <<"Int">>;
-classify_dynamic(X) when is_float(X) -> <<"Float">>;
-classify_dynamic(X) when is_list(X) -> <<"List">>;
-classify_dynamic(X) when is_boolean(X) -> <<"Bool">>;
-classify_dynamic(X) when is_map(X) -> <<"Map">>;
-classify_dynamic(X) when is_tuple(X) ->
- iolist_to_binary(["Tuple of ", integer_to_list(tuple_size(X)), " elements"]);
-classify_dynamic(X) when
- is_function(X, 0) orelse is_function(X, 1) orelse is_function(X, 2) orelse
- is_function(X, 3) orelse is_function(X, 4) orelse is_function(X, 5) orelse
- is_function(X, 6) orelse is_function(X, 7) orelse is_function(X, 8) orelse
- is_function(X, 9) orelse is_function(X, 10) orelse is_function(X, 11) orelse
- is_function(X, 12) -> <<"Function">>;
-classify_dynamic(_) -> <<"Some other type">>.
-
-decode_map(Data) when is_map(Data) -> {ok, Data};
-decode_map(Data) -> decode_error_msg(<<"Map">>, Data).
-
-decode_bit_array(Data) when is_bitstring(Data) -> {ok, Data};
-decode_bit_array(Data) -> decode_error_msg(<<"BitArray">>, Data).
-
-decode_int(Data) when is_integer(Data) -> {ok, Data};
-decode_int(Data) -> decode_error_msg(<<"Int">>, Data).
-
-decode_float(Data) when is_float(Data) -> {ok, Data};
-decode_float(Data) -> decode_error_msg(<<"Float">>, Data).
-
-decode_bool(Data) when is_boolean(Data) -> {ok, Data};
-decode_bool(Data) -> decode_error_msg(<<"Bool">>, Data).
-
-decode_list(Data) when is_list(Data) -> {ok, Data};
-decode_list(Data) -> decode_error_msg(<<"List">>, Data).
-
-decode_field(Data, Key) when is_map(Data) ->
- case Data of
- #{Key := Value} -> {ok, {some, Value}};
- _ ->
- {ok, none}
- end;
-decode_field(Data, _) ->
- decode_error_msg(<<"Map">>, Data).
-
-size_of_tuple(Data) -> tuple_size(Data).
-
-tuple_get(_tup, Index) when Index < 0 -> {error, nil};
-tuple_get(Data, Index) when Index >= tuple_size(Data) -> {error, nil};
-tuple_get(Data, Index) -> {ok, element(Index + 1, Data)}.
-
-decode_tuple(Data) when is_tuple(Data) -> {ok, Data};
-decode_tuple(Data) -> decode_error_msg(<<"Tuple">>, Data).
-
-decode_tuple2({_,_} = A) -> {ok, A};
-decode_tuple2([A,B]) -> {ok, {A,B}};
-decode_tuple2(Data) -> decode_error_msg(<<"Tuple of 2 elements">>, Data).
-
-decode_tuple3({_,_,_} = A) -> {ok, A};
-decode_tuple3([A,B,C]) -> {ok, {A,B,C}};
-decode_tuple3(Data) -> decode_error_msg(<<"Tuple of 3 elements">>, Data).
-
-decode_tuple4({_,_,_,_} = A) -> {ok, A};
-decode_tuple4([A,B,C,D]) -> {ok, {A,B,C,D}};
-decode_tuple4(Data) -> decode_error_msg(<<"Tuple of 4 elements">>, Data).
-
-decode_tuple5({_,_,_,_,_} = A) -> {ok, A};
-decode_tuple5([A,B,C,D,E]) -> {ok, {A,B,C,D,E}};
-decode_tuple5(Data) -> decode_error_msg(<<"Tuple of 5 elements">>, Data).
-
-decode_tuple6({_,_,_,_,_,_} = A) -> {ok, A};
-decode_tuple6([A,B,C,D,E,F]) -> {ok, {A,B,C,D,E,F}};
-decode_tuple6(Data) -> decode_error_msg(<<"Tuple of 6 elements">>, Data).
-
-decode_option(Term, F) ->
- Decode = fun(Inner) ->
- case F(Inner) of
- {ok, Decoded} -> {ok, {some, Decoded}};
- Error -> Error
- end
- end,
- case Term of
- undefined -> {ok, none};
- error -> {ok, none};
- null -> {ok, none};
- none -> {ok, none};
- nil -> {ok, none};
- {some, Inner} -> Decode(Inner);
- _ -> Decode(Term)
- end.
-
-decode_result(Term) ->
- case Term of
- {ok, Inner} -> {ok, {ok, Inner}};
- ok -> {ok, {ok, nil}};
- {error, Inner} -> {ok, {error, Inner}};
- error -> {ok, {error, nil}};
- _ -> decode_error_msg(<<"Result">>, Term)
- end.
-
-int_from_base_string(String, Base) ->
- case catch binary_to_integer(String, Base) of
- Int when is_integer(Int) -> {ok, Int};
- _ -> {error, nil}
- end.
-
-parse_int(String) ->
- case catch binary_to_integer(String) of
- Int when is_integer(Int) -> {ok, Int};
- _ -> {error, nil}
- end.
-
-parse_float(String) ->
- case catch binary_to_float(String) of
- Float when is_float(Float) -> {ok, Float};
- _ -> {error, nil}
- end.
-
-less_than(Lhs, Rhs) ->
- Lhs < Rhs.
-
-string_starts_with(_, <<>>) -> true;
-string_starts_with(String, Prefix) when byte_size(Prefix) > byte_size(String) -> false;
-string_starts_with(String, Prefix) ->
- PrefixSize = byte_size(Prefix),
- Prefix == binary_part(String, 0, PrefixSize).
-
-string_ends_with(_, <<>>) -> true;
-string_ends_with(String, Suffix) when byte_size(Suffix) > byte_size(String) -> false;
-string_ends_with(String, Suffix) ->
- SuffixSize = byte_size(Suffix),
- Suffix == binary_part(String, byte_size(String) - SuffixSize, SuffixSize).
-
-string_pad(String, Length, Dir, PadString) ->
- Chars = string:pad(String, Length, Dir, binary_to_list(PadString)),
- case unicode:characters_to_binary(Chars) of
- Bin when is_binary(Bin) -> Bin;
- Error -> erlang:error({gleam_error, {string_invalid_utf8, Error}})
- end.
-
-string_pop_grapheme(String) ->
- case string:next_grapheme(String) of
- [ Next | Rest ] ->
- {ok, {unicode:characters_to_binary([Next]), unicode:characters_to_binary(Rest)}};
- _ -> {error, nil}
- end.
-
-bit_array_concat(BitArrays) ->
- list_to_bitstring(BitArrays).
-
-bit_array_slice(Bin, Pos, Len) ->
- try {ok, binary:part(Bin, Pos, Len)}
- catch error:badarg -> {error, nil}
- end.
-
-bit_array_int_to_u32(I) when 0 =< I, I < 4294967296 ->
- {ok, <<I:32>>};
-bit_array_int_to_u32(_) ->
- {error, nil}.
-
-bit_array_int_from_u32(<<I:32>>) ->
- {ok, I};
-bit_array_int_from_u32(_) ->
- {error, nil}.
-
-compile_regex(String, Options) ->
- {options, Caseless, Multiline} = Options,
- OptionsList = [
- unicode,
- ucp,
- Caseless andalso caseless,
- Multiline andalso multiline
- ],
- FilteredOptions = [Option || Option <- OptionsList, Option /= false],
- case re:compile(String, FilteredOptions) of
- {ok, MP} -> {ok, MP};
- {error, {Str, Pos}} ->
- {error, {compile_error, unicode:characters_to_binary(Str), Pos}}
- end.
-
-regex_check(Regex, String) ->
- re:run(String, Regex) /= nomatch.
-
-regex_split(Regex, String) ->
- re:split(String, Regex).
-
-regex_submatches(_, {-1, 0}) -> none;
-regex_submatches(String, {Start, Length}) ->
- BinarySlice = binary:part(String, {Start, Length}),
- case string:is_empty(binary_to_list(BinarySlice)) of
- true -> none;
- false -> {some, BinarySlice}
- end.
-
-regex_matches(String, [{Start, Length} | Submatches]) ->
- Submatches1 = lists:map(fun(X) -> regex_submatches(String, X) end, Submatches),
- {match, binary:part(String, Start, Length), Submatches1}.
-
-regex_scan(Regex, String) ->
- case re:run(String, Regex, [global]) of
- {match, Captured} -> lists:map(fun(X) -> regex_matches(String, X) end, Captured);
- nomatch -> []
- end.
-
-base_decode64(S) ->
- try {ok, base64:decode(S)}
- catch error:_ -> {error, nil}
- end.
-
-wrap_list(X) when is_list(X) -> X;
-wrap_list(X) -> [X].
-
-parse_query(Query) ->
- case uri_string:dissect_query(Query) of
- {error, _, _} -> {error, nil};
- Pairs ->
- Pairs1 = lists:map(fun
- ({K, true}) -> {K, <<"">>};
- (Pair) -> Pair
- end, Pairs),
- {ok, Pairs1}
- end.
-
-percent_encode(B) -> percent_encode(B, <<>>).
-percent_encode(<<>>, Acc) ->
- Acc;
-percent_encode(<<H,T/binary>>, Acc) ->
- case percent_ok(H) of
- true ->
- percent_encode(T, <<Acc/binary,H>>);
- false ->
- <<A:4,B:4>> = <<H>>,
- percent_encode(T, <<Acc/binary,$%,(?DEC2HEX(A)),(?DEC2HEX(B))>>)
- end.
-
-percent_decode(Cs) -> percent_decode(Cs, <<>>).
-percent_decode(<<$%, C0, C1, Cs/binary>>, Acc) ->
- case is_hex_digit(C0) andalso is_hex_digit(C1) of
- true ->
- B = ?HEX2DEC(C0)*16+?HEX2DEC(C1),
- percent_decode(Cs, <<Acc/binary, B>>);
- false ->
- {error, nil}
- end;
-percent_decode(<<C,Cs/binary>>, Acc) ->
- percent_decode(Cs, <<Acc/binary, C>>);
-percent_decode(<<>>, Acc) ->
- check_utf8(Acc).
-
-percent_ok($!) -> true;
-percent_ok($$) -> true;
-percent_ok($') -> true;
-percent_ok($() -> true;
-percent_ok($)) -> true;
-percent_ok($*) -> true;
-percent_ok($+) -> true;
-percent_ok($-) -> true;
-percent_ok($.) -> true;
-percent_ok($_) -> true;
-percent_ok($~) -> true;
-percent_ok(C) when $0 =< C, C =< $9 -> true;
-percent_ok(C) when $A =< C, C =< $Z -> true;
-percent_ok(C) when $a =< C, C =< $z -> true;
-percent_ok(_) -> false.
-
-is_hex_digit(C) ->
- ($0 =< C andalso C =< $9) orelse ($a =< C andalso C =< $f) orelse ($A =< C andalso C =< $F).
-
-check_utf8(Cs) ->
- case unicode:characters_to_list(Cs) of
- {incomplete, _, _} -> {error, nil};
- {error, _, _} -> {error, nil};
- _ -> {ok, Cs}
- end.
-
-uri_parse(String) ->
- case uri_string:parse(String) of
- {error, _, _} -> {error, nil};
- Uri ->
- {ok, {uri,
- maps_get_optional(Uri, scheme),
- maps_get_optional(Uri, userinfo),
- maps_get_optional(Uri, host),
- maps_get_optional(Uri, port),
- maps_get_or(Uri, path, <<>>),
- maps_get_optional(Uri, query),
- maps_get_optional(Uri, fragment)
- }}
- end.
-
-maps_get_optional(Map, Key) ->
- try {some, maps:get(Key, Map)}
- catch _:_ -> none
- end.
-
-maps_get_or(Map, Key, Default) ->
- try maps:get(Key, Map)
- catch _:_ -> Default
- end.
-
-print(String) ->
- io:put_chars(String),
- nil.
-
-println(String) ->
- io:put_chars([String, $\n]),
- nil.
-
-print_error(String) ->
- io:put_chars(standard_error, String),
- nil.
-
-println_error(String) ->
- io:put_chars(standard_error, [String, $\n]),
- nil.
-
-inspect(true) ->
- "True";
-inspect(false) ->
- "False";
-inspect(nil) ->
- "Nil";
-inspect(Data) when is_map(Data) ->
- Fields = [
- [<<"#(">>, inspect(Key), <<", ">>, inspect(Value), <<")">>]
- || {Key, Value} <- maps:to_list(Data)
- ],
- ["dict.from_list([", lists:join(", ", Fields), "])"];
-inspect(Atom) when is_atom(Atom) ->
- Binary = erlang:atom_to_binary(Atom),
- case inspect_maybe_gleam_atom(Binary, none, <<>>) of
- {ok, Inspected} -> Inspected;
- {error, _} -> ["atom.create_from_string(\"", Binary, "\")"]
- end;
-inspect(Any) when is_integer(Any) ->
- erlang:integer_to_list(Any);
-inspect(Any) when is_float(Any) ->
- io_lib_format:fwrite_g(Any);
-inspect(Binary) when is_binary(Binary) ->
- case inspect_maybe_utf8_string(Binary, <<>>) of
- {ok, InspectedUtf8String} -> InspectedUtf8String;
- {error, not_a_utf8_string} ->
- Segments = [erlang:integer_to_list(X) || <<X>> <= Binary],
- ["<<", lists:join(", ", Segments), ">>"]
- end;
-inspect(Bits) when is_bitstring(Bits) ->
- inspect_bit_array(Bits);
-inspect(List) when is_list(List) ->
- case inspect_list(List) of
- {proper, Elements} -> ["[", Elements, "]"];
- {improper, Elements} -> ["//erl([", Elements, "])"]
- end;
-inspect(Any) when is_tuple(Any) % Record constructors
- andalso is_atom(element(1, Any))
- andalso element(1, Any) =/= false
- andalso element(1, Any) =/= true
- andalso element(1, Any) =/= nil
-->
- [Atom | ArgsList] = erlang:tuple_to_list(Any),
- Args = lists:join(<<", ">>,
- lists:map(fun inspect/1, ArgsList)
- ),
- [inspect(Atom), "(", Args, ")"];
-inspect(Tuple) when is_tuple(Tuple) ->
- Elements = lists:map(fun inspect/1, erlang:tuple_to_list(Tuple)),
- ["#(", lists:join(", ", Elements), ")"];
-inspect(Any) when is_function(Any) ->
- {arity, Arity} = erlang:fun_info(Any, arity),
- ArgsAsciiCodes = lists:seq($a, $a + Arity - 1),
- Args = lists:join(<<", ">>,
- lists:map(fun(Arg) -> <<Arg>> end, ArgsAsciiCodes)
- ),
- ["//fn(", Args, ") { ... }"];
-inspect(Any) ->
- ["//erl(", io_lib:format("~p", [Any]), ")"].
-
-
-inspect_maybe_gleam_atom(<<>>, none, _) ->
- {error, nil};
-inspect_maybe_gleam_atom(<<First, _Rest/binary>>, none, _) when ?is_digit_char(First) ->
- {error, nil};
-inspect_maybe_gleam_atom(<<"_", _Rest/binary>>, none, _) ->
- {error, nil};
-inspect_maybe_gleam_atom(<<"_">>, _PrevChar, _Acc) ->
- {error, nil};
-inspect_maybe_gleam_atom(<<"_", _Rest/binary>>, $_, _Acc) ->
- {error, nil};
-inspect_maybe_gleam_atom(<<First, _Rest/binary>>, _PrevChar, _Acc)
- when not (?is_lowercase_char(First) orelse ?is_underscore_char(First) orelse ?is_digit_char(First)) ->
- {error, nil};
-inspect_maybe_gleam_atom(<<First, Rest/binary>>, none, Acc) ->
- inspect_maybe_gleam_atom(Rest, First, <<Acc/binary, (uppercase(First))>>);
-inspect_maybe_gleam_atom(<<"_", Rest/binary>>, _PrevChar, Acc) ->
- inspect_maybe_gleam_atom(Rest, $_, Acc);
-inspect_maybe_gleam_atom(<<First, Rest/binary>>, $_, Acc) ->
- inspect_maybe_gleam_atom(Rest, First, <<Acc/binary, (uppercase(First))>>);
-inspect_maybe_gleam_atom(<<First, Rest/binary>>, _PrevChar, Acc) ->
- inspect_maybe_gleam_atom(Rest, First, <<Acc/binary, First>>);
-inspect_maybe_gleam_atom(<<>>, _PrevChar, Acc) ->
- {ok, Acc};
-inspect_maybe_gleam_atom(A, B, C) ->
- erlang:display({A, B, C}),
- throw({gleam_error, A, B, C}).
-
-inspect_list([]) ->
- {proper, []};
-inspect_list([First]) ->
- {proper, [inspect(First)]};
-inspect_list([First | Rest]) when is_list(Rest) ->
- {Kind, Inspected} = inspect_list(Rest),
- {Kind, [inspect(First), <<", ">> | Inspected]};
-inspect_list([First | ImproperTail]) ->
- {improper, [inspect(First), <<" | ">>, inspect(ImproperTail)]}.
-
-inspect_bit_array(Bits) ->
- Text = inspect_bit_array(Bits, <<"<<">>),
- <<Text/binary, ">>">>.
-
-inspect_bit_array(<<>>, Acc) ->
- Acc;
-inspect_bit_array(<<X, Rest/bitstring>>, Acc) ->
- inspect_bit_array(Rest, append_segment(Acc, erlang:integer_to_binary(X)));
-inspect_bit_array(Rest, Acc) ->
- Size = bit_size(Rest),
- <<X:Size>> = Rest,
- X1 = erlang:integer_to_binary(X),
- Size1 = erlang:integer_to_binary(Size),
- Segment = <<X1/binary, ":size(", Size1/binary, ")">>,
- inspect_bit_array(<<>>, append_segment(Acc, Segment)).
-
-append_segment(<<"<<">>, Segment) ->
- <<"<<", Segment/binary>>;
-append_segment(Acc, Segment) ->
- <<Acc/binary, ", ", Segment/binary>>.
-
-
-inspect_maybe_utf8_string(Binary, Acc) ->
- case Binary of
- <<>> -> {ok, <<$", Acc/binary, $">>};
- <<First/utf8, Rest/binary>> ->
- Escaped = case First of
- $" -> <<$\\, $">>;
- $\\ -> <<$\\, $\\>>;
- $\r -> <<$\\, $r>>;
- $\n -> <<$\\, $n>>;
- $\t -> <<$\\, $t>>;
- Other -> <<Other/utf8>>
- end,
- inspect_maybe_utf8_string(Rest, <<Acc/binary, Escaped/binary>>);
- _ -> {error, not_a_utf8_string}
- end.
-
-float_to_string(Float) when is_float(Float) ->
- erlang:iolist_to_binary(io_lib_format:fwrite_g(Float)).
-
-utf_codepoint_list_to_string(List) ->
- case unicode:characters_to_binary(List) of
- {error, _} -> erlang:error({gleam_error, {string_invalid_utf8, List}});
- Binary -> Binary
- end.
-
-crop_string(String, Prefix) ->
- case string:find(String, Prefix) of
- nomatch -> String;
- New -> New
- end.
-
-contains_string(String, Substring) ->
- is_bitstring(string:find(String, Substring)).
-
-base16_decode(String) ->
- try
- {ok, binary:decode_hex(String)}
- catch
- _:_ -> {error, nil}
- end.
diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam_stdlib.mjs b/aoc2023/build/packages/gleam_stdlib/src/gleam_stdlib.mjs
deleted file mode 100644
index a908b23..0000000
--- a/aoc2023/build/packages/gleam_stdlib/src/gleam_stdlib.mjs
+++ /dev/null
@@ -1,875 +0,0 @@
-import {
- BitArray,
- Error,
- List,
- Ok,
- Result,
- UtfCodepoint,
- stringBits,
- toBitArray,
- NonEmpty,
- CustomType,
-} from "./gleam.mjs";
-import {
- CompileError as RegexCompileError,
- Match as RegexMatch,
-} from "./gleam/regex.mjs";
-import { DecodeError } from "./gleam/dynamic.mjs";
-import { Some, None } from "./gleam/option.mjs";
-import Dict from "./dict.mjs";
-
-const Nil = undefined;
-const NOT_FOUND = {};
-
-export function identity(x) {
- return x;
-}
-
-export function parse_int(value) {
- if (/^[-+]?(\d+)$/.test(value)) {
- return new Ok(parseInt(value));
- } else {
- return new Error(Nil);
- }
-}
-
-export function parse_float(value) {
- if (/^[-+]?(\d+)\.(\d+)$/.test(value)) {
- return new Ok(parseFloat(value));
- } else {
- return new Error(Nil);
- }
-}
-
-export function to_string(term) {
- return term.toString();
-}
-
-export function float_to_string(float) {
- const string = float.toString();
- if (string.indexOf(".") >= 0) {
- return string;
- } else {
- return string + ".0";
- }
-}
-
-export function int_to_base_string(int, base) {
- return int.toString(base).toUpperCase();
-}
-
-const int_base_patterns = {
- 2: /[^0-1]/,
- 3: /[^0-2]/,
- 4: /[^0-3]/,
- 5: /[^0-4]/,
- 6: /[^0-5]/,
- 7: /[^0-6]/,
- 8: /[^0-7]/,
- 9: /[^0-8]/,
- 10: /[^0-9]/,
- 11: /[^0-9a]/,
- 12: /[^0-9a-b]/,
- 13: /[^0-9a-c]/,
- 14: /[^0-9a-d]/,
- 15: /[^0-9a-e]/,
- 16: /[^0-9a-f]/,
- 17: /[^0-9a-g]/,
- 18: /[^0-9a-h]/,
- 19: /[^0-9a-i]/,
- 20: /[^0-9a-j]/,
- 21: /[^0-9a-k]/,
- 22: /[^0-9a-l]/,
- 23: /[^0-9a-m]/,
- 24: /[^0-9a-n]/,
- 25: /[^0-9a-o]/,
- 26: /[^0-9a-p]/,
- 27: /[^0-9a-q]/,
- 28: /[^0-9a-r]/,
- 29: /[^0-9a-s]/,
- 30: /[^0-9a-t]/,
- 31: /[^0-9a-u]/,
- 32: /[^0-9a-v]/,
- 33: /[^0-9a-w]/,
- 34: /[^0-9a-x]/,
- 35: /[^0-9a-y]/,
- 36: /[^0-9a-z]/,
-};
-
-export function int_from_base_string(string, base) {
- if (int_base_patterns[base].test(string.replace(/^-/, "").toLowerCase())) {
- return new Error(Nil);
- }
-
- const result = parseInt(string, base);
-
- if (isNaN(result)) {
- return new Error(Nil);
- }
-
- return new Ok(result);
-}
-
-export function string_replace(string, target, substitute) {
- if (typeof string.replaceAll !== "undefined") {
- return string.replaceAll(target, substitute);
- }
- // Fallback for older Node.js versions:
- // 1. <https://stackoverflow.com/a/1144788>
- // 2. <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#escaping>
- // TODO: This fallback could be remove once Node.js 14 is EOL
- // aka <https://nodejs.org/en/about/releases/> on or after 2024-04-30
- return string.replace(
- // $& means the whole matched string
- new RegExp(target.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), "g"),
- substitute
- );
-}
-
-export function string_reverse(string) {
- return [...string].reverse().join("");
-}
-
-export function string_length(string) {
- if (string === "") {
- return 0;
- }
- const iterator = graphemes_iterator(string);
- if (iterator) {
- let i = 0;
- for (const _ of iterator) {
- i++;
- }
- return i;
- } else {
- return string.match(/./gsu).length;
- }
-}
-
-export function graphemes(string) {
- return List.fromArray(
- Array.from(graphemes_iterator(string)).map((item) => item.segment)
- );
-}
-
-function graphemes_iterator(string) {
- if (Intl && Intl.Segmenter) {
- return new Intl.Segmenter().segment(string)[Symbol.iterator]();
- }
-}
-
-export function pop_grapheme(string) {
- let first;
- const iterator = graphemes_iterator(string);
- if (iterator) {
- first = iterator.next().value?.segment;
- } else {
- first = string.match(/./su)?.[0];
- }
- if (first) {
- return new Ok([first, string.slice(first.length)]);
- } else {
- return new Error(Nil);
- }
-}
-
-export function lowercase(string) {
- return string.toLowerCase();
-}
-
-export function uppercase(string) {
- return string.toUpperCase();
-}
-
-export function less_than(a, b) {
- return a < b;
-}
-
-export function add(a, b) {
- return a + b;
-}
-
-export function equal(a, b) {
- return a === b;
-}
-
-export function split(xs, pattern) {
- return List.fromArray(xs.split(pattern));
-}
-
-export function join(xs, separator) {
- const iterator = xs[Symbol.iterator]();
- let result = iterator.next().value || "";
- let current = iterator.next();
- while (!current.done) {
- result = result + separator + current.value;
- current = iterator.next();
- }
- return result;
-}
-
-export function concat(xs) {
- let result = "";
- for (const x of xs) {
- result = result + x;
- }
- return result;
-}
-
-export function length(data) {
- return data.length;
-}
-
-export function crop_string(string, substring) {
- return string.substring(string.indexOf(substring));
-}
-
-export function contains_string(haystack, needle) {
- return haystack.indexOf(needle) >= 0;
-}
-
-export function starts_with(haystack, needle) {
- return haystack.startsWith(needle);
-}
-
-export function ends_with(haystack, needle) {
- return haystack.endsWith(needle);
-}
-
-export function split_once(haystack, needle) {
- const index = haystack.indexOf(needle);
- if (index >= 0) {
- const before = haystack.slice(0, index);
- const after = haystack.slice(index + needle.length);
- return new Ok([before, after]);
- } else {
- return new Error(Nil);
- }
-}
-
-export function trim(string) {
- return string.trim();
-}
-
-export function trim_left(string) {
- return string.trimLeft();
-}
-
-export function trim_right(string) {
- return string.trimRight();
-}
-
-export function bit_array_from_string(string) {
- return toBitArray([stringBits(string)]);
-}
-
-export function bit_array_concat(bit_arrays) {
- return toBitArray(bit_arrays.toArray().map((b) => b.buffer));
-}
-
-export function console_log(term) {
- console.log(term);
-}
-
-export function console_error(term) {
- console.error(term);
-}
-
-export function crash(message) {
- throw new globalThis.Error(message);
-}
-
-export function bit_array_to_string(bit_array) {
- try {
- const decoder = new TextDecoder("utf-8", { fatal: true });
- return new Ok(decoder.decode(bit_array.buffer));
- } catch (_error) {
- return new Error(Nil);
- }
-}
-
-export function print(string) {
- if (typeof process === "object") {
- process.stdout.write(string); // We can write without a trailing newline
- } else if (typeof Deno === "object") {
- Deno.stdout.writeSync(new TextEncoder().encode(string)); // We can write without a trailing newline
- } else {
- console.log(string); // We're in a browser. Newlines are mandated
- }
-}
-
-export function print_error(string) {
- if (typeof process === "object" && process.stderr?.write) {
- process.stderr.write(string); // We can write without a trailing newline
- } else if (typeof Deno === "object") {
- Deno.stderr.writeSync(new TextEncoder().encode(string)); // We can write without a trailing newline
- } else {
- console.error(string); // We're in a browser. Newlines are mandated
- }
-}
-
-export function print_debug(string) {
- if (typeof process === "object" && process.stderr?.write) {
- process.stderr.write(string + "\n"); // If we're in Node.js, use `stderr`
- } else if (typeof Deno === "object") {
- Deno.stderr.writeSync(new TextEncoder().encode(string + "\n")); // If we're in Deno, use `stderr`
- } else {
- console.log(string); // Otherwise, use `console.log` (so that it doesn't look like an error)
- }
-}
-
-export function ceiling(float) {
- return Math.ceil(float);
-}
-
-export function floor(float) {
- return Math.floor(float);
-}
-
-export function round(float) {
- return Math.round(float);
-}
-
-export function truncate(float) {
- return Math.trunc(float);
-}
-
-export function power(base, exponent) {
- // It is checked in Gleam that:
- // - The base is non-negative and that the exponent is not fractional.
- // - The base is non-zero and the exponent is non-negative (otherwise
- // the result will essentially be division by zero).
- // It can thus be assumed that valid input is passed to the Math.pow
- // function and a NaN or Infinity value will not be produced.
- return Math.pow(base, exponent);
-}
-
-export function random_uniform() {
- const random_uniform_result = Math.random();
- // With round-to-nearest-even behavior, the ranges claimed for the functions below
- // (excluding the one for Math.random() itself) aren't exact.
- // If extremely large bounds are chosen (2^53 or higher),
- // it's possible in extremely rare cases to calculate the usually-excluded upper bound.
- // Note that as numbers in JavaScript are IEEE 754 floating point numbers
- // See: <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random>
- // Because of this, we just loop 'until' we get a valid result where 0.0 <= x < 1.0:
- if (random_uniform_result === 1.0) {
- return random_uniform();
- }
- return random_uniform_result;
-}
-
-export function bit_array_slice(bits, position, length) {
- const start = Math.min(position, position + length);
- const end = Math.max(position, position + length);
- if (start < 0 || end > bits.length) return new Error(Nil);
- const buffer = new Uint8Array(bits.buffer.buffer, start, Math.abs(length));
- return new Ok(new BitArray(buffer));
-}
-
-export function codepoint(int) {
- return new UtfCodepoint(int);
-}
-
-export function string_to_codepoint_integer_list(string) {
- return List.fromArray(Array.from(string).map((item) => item.codePointAt(0)));
-}
-
-export function utf_codepoint_list_to_string(utf_codepoint_integer_list) {
- return utf_codepoint_integer_list
- .toArray()
- .map((x) => String.fromCodePoint(x.value))
- .join("");
-}
-
-export function utf_codepoint_to_int(utf_codepoint) {
- return utf_codepoint.value;
-}
-
-export function regex_check(regex, string) {
- regex.lastIndex = 0;
- return regex.test(string);
-}
-
-export function compile_regex(pattern, options) {
- try {
- let flags = "gu";
- if (options.case_insensitive) flags += "i";
- if (options.multi_line) flags += "m";
- return new Ok(new RegExp(pattern, flags));
- } catch (error) {
- const number = (error.columnNumber || 0) | 0;
- return new Error(new RegexCompileError(error.message, number));
- }
-}
-
-export function regex_scan(regex, string) {
- const matches = Array.from(string.matchAll(regex)).map((match) => {
- const content = match[0];
- const submatches = [];
- for (let n = match.length - 1; n > 0; n--) {
- if (match[n]) {
- submatches[n - 1] = new Some(match[n]);
- continue;
- }
- if (submatches.length > 0) {
- submatches[n - 1] = new None();
- }
- }
- return new RegexMatch(content, List.fromArray(submatches));
- });
- return List.fromArray(matches);
-}
-
-export function new_map() {
- return Dict.new();
-}
-
-export function map_size(map) {
- return map.size;
-}
-
-export function map_to_list(map) {
- return List.fromArray(map.entries());
-}
-
-export function map_remove(key, map) {
- return map.delete(key);
-}
-
-export function map_get(map, key) {
- const value = map.get(key, NOT_FOUND);
- if (value === NOT_FOUND) {
- return new Error(Nil);
- }
- return new Ok(value);
-}
-
-export function map_insert(key, value, map) {
- return map.set(key, value);
-}
-
-function unsafe_percent_decode(string) {
- return decodeURIComponent((string || "").replace("+", " "));
-}
-
-export function percent_decode(string) {
- try {
- return new Ok(unsafe_percent_decode(string));
- } catch (_error) {
- return new Error(Nil);
- }
-}
-
-export function percent_encode(string) {
- return encodeURIComponent(string);
-}
-
-export function parse_query(query) {
- try {
- const pairs = [];
- for (const section of query.split("&")) {
- const [key, value] = section.split("=");
- if (!key) continue;
- pairs.push([unsafe_percent_decode(key), unsafe_percent_decode(value)]);
- }
- return new Ok(List.fromArray(pairs));
- } catch (_error) {
- return new Error(Nil);
- }
-}
-
-// From https://developer.mozilla.org/en-US/docs/Glossary/Base64#Solution_2_%E2%80%93_rewrite_the_DOMs_atob()_and_btoa()_using_JavaScript's_TypedArrays_and_UTF-8
-export function encode64(bit_array) {
- const aBytes = bit_array.buffer;
- let nMod3 = 2;
- let sB64Enc = "";
-
- for (let nLen = aBytes.length, nUint24 = 0, nIdx = 0; nIdx < nLen; nIdx++) {
- nMod3 = nIdx % 3;
- if (nIdx > 0 && ((nIdx * 4) / 3) % 76 === 0) {
- sB64Enc += "\r\n";
- }
- nUint24 |= aBytes[nIdx] << ((16 >>> nMod3) & 24);
- if (nMod3 === 2 || aBytes.length - nIdx === 1) {
- sB64Enc += String.fromCharCode(
- uint6ToB64((nUint24 >>> 18) & 63),
- uint6ToB64((nUint24 >>> 12) & 63),
- uint6ToB64((nUint24 >>> 6) & 63),
- uint6ToB64(nUint24 & 63)
- );
- nUint24 = 0;
- }
- }
-
- return (
- sB64Enc.substr(0, sB64Enc.length - 2 + nMod3) +
- (nMod3 === 2 ? "" : nMod3 === 1 ? "=" : "==")
- );
-}
-
-// From https://developer.mozilla.org/en-US/docs/Glossary/Base64#Solution_2_%E2%80%93_rewrite_the_DOMs_atob()_and_btoa()_using_JavaScript's_TypedArrays_and_UTF-8
-function uint6ToB64(nUint6) {
- return nUint6 < 26
- ? nUint6 + 65
- : nUint6 < 52
- ? nUint6 + 71
- : nUint6 < 62
- ? nUint6 - 4
- : nUint6 === 62
- ? 43
- : nUint6 === 63
- ? 47
- : 65;
-}
-
-// From https://developer.mozilla.org/en-US/docs/Glossary/Base64#Solution_2_%E2%80%93_rewrite_the_DOMs_atob()_and_btoa()_using_JavaScript's_TypedArrays_and_UTF-8
-function b64ToUint6(nChr) {
- return nChr > 64 && nChr < 91
- ? nChr - 65
- : nChr > 96 && nChr < 123
- ? nChr - 71
- : nChr > 47 && nChr < 58
- ? nChr + 4
- : nChr === 43
- ? 62
- : nChr === 47
- ? 63
- : 0;
-}
-
-// From https://developer.mozilla.org/en-US/docs/Glossary/Base64#Solution_2_%E2%80%93_rewrite_the_DOMs_atob()_and_btoa()_using_JavaScript's_TypedArrays_and_UTF-8
-export function decode64(sBase64) {
- if (sBase64.match(/[^A-Za-z0-9\+\/=]/g)) return new Error(Nil);
- const sB64Enc = sBase64.replace(/=/g, "");
- const nInLen = sB64Enc.length;
- const nOutLen = (nInLen * 3 + 1) >> 2;
- const taBytes = new Uint8Array(nOutLen);
-
- for (
- let nMod3, nMod4, nUint24 = 0, nOutIdx = 0, nInIdx = 0;
- nInIdx < nInLen;
- nInIdx++
- ) {
- nMod4 = nInIdx & 3;
- nUint24 |= b64ToUint6(sB64Enc.charCodeAt(nInIdx)) << (6 * (3 - nMod4));
- if (nMod4 === 3 || nInLen - nInIdx === 1) {
- for (nMod3 = 0; nMod3 < 3 && nOutIdx < nOutLen; nMod3++, nOutIdx++) {
- taBytes[nOutIdx] = (nUint24 >>> ((16 >>> nMod3) & 24)) & 255;
- }
- nUint24 = 0;
- }
- }
-
- return new Ok(new BitArray(taBytes));
-}
-
-export function classify_dynamic(data) {
- if (typeof data === "string") {
- return "String";
- } else if (data instanceof Result) {
- return "Result";
- } else if (data instanceof List) {
- return "List";
- } else if (data instanceof BitArray) {
- return "BitArray";
- } else if (data instanceof Dict) {
- return "Map";
- } else if (Number.isInteger(data)) {
- return "Int";
- } else if (Array.isArray(data)) {
- return `Tuple of ${data.length} elements`;
- } else if (typeof data === "number") {
- return "Float";
- } else if (data === null) {
- return "Null";
- } else if (data === undefined) {
- return "Nil";
- } else {
- const type = typeof data;
- return type.charAt(0).toUpperCase() + type.slice(1);
- }
-}
-
-function decoder_error(expected, got) {
- return decoder_error_no_classify(expected, classify_dynamic(got));
-}
-
-function decoder_error_no_classify(expected, got) {
- return new Error(
- List.fromArray([new DecodeError(expected, got, List.fromArray([]))])
- );
-}
-
-export function decode_string(data) {
- return typeof data === "string"
- ? new Ok(data)
- : decoder_error("String", data);
-}
-
-export function decode_int(data) {
- return Number.isInteger(data) ? new Ok(data) : decoder_error("Int", data);
-}
-
-export function decode_float(data) {
- return typeof data === "number" ? new Ok(data) : decoder_error("Float", data);
-}
-
-export function decode_bool(data) {
- return typeof data === "boolean" ? new Ok(data) : decoder_error("Bool", data);
-}
-
-export function decode_bit_array(data) {
- if (data instanceof BitArray) {
- return new Ok(data);
- }
- if (data instanceof Uint8Array) {
- return new Ok(new BitArray(data));
- }
- return decoder_error("BitArray", data);
-}
-
-export function decode_tuple(data) {
- return Array.isArray(data) ? new Ok(data) : decoder_error("Tuple", data);
-}
-
-export function decode_tuple2(data) {
- return decode_tupleN(data, 2);
-}
-
-export function decode_tuple3(data) {
- return decode_tupleN(data, 3);
-}
-
-export function decode_tuple4(data) {
- return decode_tupleN(data, 4);
-}
-
-export function decode_tuple5(data) {
- return decode_tupleN(data, 5);
-}
-
-export function decode_tuple6(data) {
- return decode_tupleN(data, 6);
-}
-
-function decode_tupleN(data, n) {
- if (Array.isArray(data) && data.length == n) {
- return new Ok(data);
- }
-
- const list = decode_exact_length_list(data, n);
- if (list) return new Ok(list);
-
- return decoder_error(`Tuple of ${n} elements`, data);
-}
-
-function decode_exact_length_list(data, n) {
- if (!(data instanceof List)) return;
-
- const elements = [];
- let current = data;
-
- for (let i = 0; i < n; i++) {
- if (!(current instanceof NonEmpty)) break;
- elements.push(current.head);
- current = current.tail;
- }
-
- if (elements.length === n && !(current instanceof NonEmpty)) return elements;
-}
-
-export function tuple_get(data, index) {
- return index >= 0 && data.length > index
- ? new Ok(data[index])
- : new Error(Nil);
-}
-
-export function decode_list(data) {
- if (Array.isArray(data)) {
- return new Ok(List.fromArray(data));
- }
- return data instanceof List ? new Ok(data) : decoder_error("List", data);
-}
-
-export function decode_result(data) {
- return data instanceof Result ? new Ok(data) : decoder_error("Result", data);
-}
-
-export function decode_map(data) {
- if (data instanceof Dict) {
- return new Ok(Dict.fromMap(data));
- }
- if (data == null) {
- return decoder_error("Map", data);
- }
- if (typeof data !== "object") {
- return decoder_error("Map", data);
- }
- const proto = Object.getPrototypeOf(data);
- if (proto === Object.prototype || proto === null) {
- return new Ok(Dict.fromObject(data));
- }
- return decoder_error("Map", data);
-}
-
-export function decode_option(data, decoder) {
- if (data === null || data === undefined || data instanceof None)
- return new Ok(new None());
- if (data instanceof Some) data = data[0];
- const result = decoder(data);
- if (result.isOk()) {
- return new Ok(new Some(result[0]));
- } else {
- return result;
- }
-}
-
-export function decode_field(value, name) {
- const not_a_map_error = () => decoder_error("Map", value);
-
- if (
- value instanceof Dict ||
- value instanceof WeakMap ||
- value instanceof Map
- ) {
- const entry = map_get(value, name);
- return new Ok(entry.isOk() ? new Some(entry[0]) : new None());
- } else if (Object.getPrototypeOf(value) == Object.prototype) {
- return try_get_field(value, name, () => new Ok(new None()));
- } else {
- return try_get_field(value, name, not_a_map_error);
- }
-}
-
-function try_get_field(value, field, or_else) {
- try {
- return field in value ? new Ok(new Some(value[field])) : or_else();
- } catch {
- return or_else();
- }
-}
-
-export function byte_size(string) {
- return new TextEncoder().encode(string).length;
-}
-
-// In Javascript bitwise operations convert numbers to a sequence of 32 bits
-// while Erlang uses arbitrary precision.
-// To get around this problem and get consistent results use BigInt and then
-// downcast the value back to a Number value.
-
-export function bitwise_and(x, y) {
- return Number(BigInt(x) & BigInt(y));
-}
-
-export function bitwise_not(x) {
- return Number(~BigInt(x));
-}
-
-export function bitwise_or(x, y) {
- return Number(BigInt(x) | BigInt(y));
-}
-
-export function bitwise_exclusive_or(x, y) {
- return Number(BigInt(x) ^ BigInt(y));
-}
-
-export function bitwise_shift_left(x, y) {
- return Number(BigInt(x) << BigInt(y));
-}
-
-export function bitwise_shift_right(x, y) {
- return Number(BigInt(x) >> BigInt(y));
-}
-
-export function inspect(v) {
- const t = typeof v;
- if (v === true) return "True";
- if (v === false) return "False";
- if (v === null) return "//js(null)";
- if (v === undefined) return "Nil";
- if (t === "string") return JSON.stringify(v);
- if (t === "bigint" || t === "number") return v.toString();
- if (Array.isArray(v)) return `#(${v.map(inspect).join(", ")})`;
- if (v instanceof List) return inspectList(v);
- if (v instanceof UtfCodepoint) return inspectUtfCodepoint(v);
- if (v instanceof BitArray) return inspectBitArray(v);
- if (v instanceof CustomType) return inspectCustomType(v);
- if (v instanceof Dict) return inspectDict(v);
- if (v instanceof Set) return `//js(Set(${[...v].map(inspect).join(", ")}))`;
- if (v instanceof RegExp) return `//js(${v})`;
- if (v instanceof Date) return `//js(Date("${v.toISOString()}"))`;
- if (v instanceof Function) {
- const args = [];
- for (const i of Array(v.length).keys())
- args.push(String.fromCharCode(i + 97));
- return `//fn(${args.join(", ")}) { ... }`;
- }
- return inspectObject(v);
-}
-
-function inspectDict(map) {
- let body = "dict.from_list([";
- let first = true;
- map.forEach((value, key) => {
- if (!first) body = body + ", ";
- body = body + "#(" + inspect(key) + ", " + inspect(value) + ")";
- first = false;
- });
- return body + "])";
-}
-
-function inspectObject(v) {
- const name = Object.getPrototypeOf(v)?.constructor?.name || "Object";
- const props = [];
- for (const k of Object.keys(v)) {
- props.push(`${inspect(k)}: ${inspect(v[k])}`);
- }
- const body = props.length ? " " + props.join(", ") + " " : "";
- const head = name === "Object" ? "" : name + " ";
- return `//js(${head}{${body}})`;
-}
-
-function inspectCustomType(record) {
- const props = Object.keys(record)
- .map((label) => {
- const value = inspect(record[label]);
- return isNaN(parseInt(label)) ? `${label}: ${value}` : value;
- })
- .join(", ");
- return props
- ? `${record.constructor.name}(${props})`
- : record.constructor.name;
-}
-
-export function inspectList(list) {
- return `[${list.toArray().map(inspect).join(", ")}]`;
-}
-
-export function inspectBitArray(bits) {
- return `<<${Array.from(bits.buffer).join(", ")}>>`;
-}
-
-export function inspectUtfCodepoint(codepoint) {
- return `//utfcodepoint(${String.fromCodePoint(codepoint.value)})`;
-}
-
-export function base16_encode(bit_array) {
- let result = "";
- for (const byte of bit_array.buffer) {
- result += byte.toString(16).padStart(2, "0").toUpperCase();
- }
- return result;
-}
-
-export function base16_decode(string) {
- const bytes = new Uint8Array(string.length / 2);
- for (let i = 0; i < string.length; i += 2) {
- const a = parseInt(string[i], 16);
- const b = parseInt(string[i + 1], 16);
- if (isNaN(a) || isNaN(b)) return new Error(Nil);
- bytes[i / 2] = a * 16 + b;
- }
- return new Ok(new BitArray(bytes));
-}