From ae86ff3fd9c47e43650a3471805b37a54735b4fc Mon Sep 17 00:00:00 2001 From: Brendan Hansen Date: Fri, 9 Dec 2022 22:37:31 -0600 Subject: [PATCH] added Pair structure --- core/container/pair.onyx | 41 +++++++++++++++++++++++++++++++++++++++ core/std.onyx | 1 + tests/aoc-2021/day14.onyx | 18 +++++++---------- tests/aoc-2021/day21.onyx | 20 ------------------- 4 files changed, 49 insertions(+), 31 deletions(-) create mode 100644 core/container/pair.onyx diff --git a/core/container/pair.onyx b/core/container/pair.onyx new file mode 100644 index 00000000..292b2cc9 --- /dev/null +++ b/core/container/pair.onyx @@ -0,0 +1,41 @@ +package core + +// +// A `Pair` represents a pair of values of heterogenous types. +// This structure does not do much on its own; however, it +// is useful because provides overloads for formatting, hashing +// and equality. This means you can use a `Pair(T, R)` as a key +// for a Map or Set out of the box, provided T and R are hashable +// and equatable. +// + +@conv.Custom_Format.{#solidify _format {First_Type=First_Type, Second_Type=Second_Type}} +Pair :: struct (First_Type: type_expr, Second_Type: type_expr) { + first: First_Type; + second: Second_Type; +} + +#inject Pair { + make :: (x: $X, y: $Y) => Pair(X, Y).{x, y}; + + _format :: (output: ^conv.Format_Output, format: ^conv.Format, p: ^Pair($First_Type, $Second_Type)) { + conv.format(output, "({}, {})", p.first, p.second); + } +} + +#overload +core.hash.to_u32 :: (p: Pair($First_Type/hash.Hashable, $Second_Type/hash.Hashable)) => { + h := 7; + h += h << 5 + hash.to_u32(p.first); + h += h << 5 + hash.to_u32(p.second); + return h; +} + + +#operator == (p1, p2: Pair($First_Type/Equatable, $Second_Type/Equatable)) => { + return p1.first == p2.first && p1.second == p2.second; +} + +#local Equatable :: interface (t: $T) { + { t == t } -> bool; +} \ No newline at end of file diff --git a/core/std.onyx b/core/std.onyx index 1b03d811..7d226994 100644 --- a/core/std.onyx +++ b/core/std.onyx @@ -12,6 +12,7 @@ package core #load "./container/set" #load "./container/bucket_array" #load "./container/heap" +#load "./container/pair" #load "./conv/conv" #load "./conv/format" diff --git a/tests/aoc-2021/day14.onyx b/tests/aoc-2021/day14.onyx index 1da615f4..8716771e 100644 --- a/tests/aoc-2021/day14.onyx +++ b/tests/aoc-2021/day14.onyx @@ -3,14 +3,10 @@ use package core Rule :: struct { - pair: Pair; + pair: Pair(u8, u8); insert: u8; } -Pair :: struct {a, b:u8;} -#match hash.to_u32 (p: Pair) => cast(u32) (p.a * 3 + p.b * 7); -#operator == (p1, p2: Pair) => p1.a == p2.a && p1.b == p2.b; - State :: struct { now, next: u64; } @@ -42,8 +38,8 @@ main :: (args) => { io.skip_whitespace(^reader); } - polymer_state: Map(Pair, State); - add_to_state :: macro (pair: Pair, count: u64) { + polymer_state: Map(Pair(u8, u8), State); + add_to_state :: macro (pair: Pair(u8, u8), count: u64) { if polymer_state->has(pair) { (^polymer_state[pair]).next += ~~count; } else { @@ -59,7 +55,7 @@ main :: (args) => { } for start_polymer.count - 1 { - p := Pair.{ start_polymer[it], start_polymer[it + 1] }; + p := Pair(u8, u8).{ start_polymer[it], start_polymer[it + 1] }; add_to_state(p, 1); } @@ -70,8 +66,8 @@ main :: (args) => { pair_count := ^polymer_state[rule.pair]; if pair_count != null { if pair_count.now > 0 { - pair1 := Pair.{ rule.pair.a, rule.insert }; - pair2 := Pair.{ rule.insert, rule.pair.b }; + pair1 := Pair(u8, u8).{ rule.pair.first, rule.insert }; + pair2 := Pair(u8, u8).{ rule.insert, rule.pair.second }; add_to_state(pair1, pair_count.now); add_to_state(pair2, pair_count.now); } @@ -82,7 +78,7 @@ main :: (args) => { mode: Map(u8, u64); for^ polymer_state.entries { - mode[it.key.b] = mode[it.key.b] + it.value.now; + mode[it.key.second] = mode[it.key.second] + it.value.now; } maximum := array.fold(mode.entries, cast(u64) 0, (x, y) => math.max(x.value, y)); diff --git a/tests/aoc-2021/day21.onyx b/tests/aoc-2021/day21.onyx index cce34f15..639fb6c5 100644 --- a/tests/aoc-2021/day21.onyx +++ b/tests/aoc-2021/day21.onyx @@ -214,23 +214,3 @@ main :: () { } } - - - -Pair :: struct (T1: type_expr, T2: type_expr) { - first: T1; - second: T2; -} - -#inject Pair { - hash :: (p: Pair($T/hash.Hashable, $R/hash.Hashable)) -> u32 { - h := 7; - h += h << 5 + hash.to_u32(p.first); - h += h << 5 + hash.to_u32(p.second); - return h; - } -} - -#operator == (p1: Pair, p2: typeof p1) => - p1.first == p2.first && p1.second == p2.second; - -- 2.25.1