From 7f93599f346d38a53ea6c31e911ed87658861c61 Mon Sep 17 00:00:00 2001 From: Toni Date: Sun, 21 Dec 2025 14:26:12 +0100 Subject: [PATCH] port some aoc solutions to zern --- examples/puzzles/aoc2024_01.zr | 35 ++++++++++++++++ examples/puzzles/aoc2024_02.zr | 54 +++++++++++++++++++++++++ examples/puzzles/aoc2024_04.zr | 62 +++++++++++++++++++++++++++++ examples/puzzles/aoc2024_05.zr | 73 ++++++++++++++++++++++++++++++++++ examples/puzzles/aoc2025_03.zr | 51 ++++++++++++++++++++++++ src/codegen_x86_64.rs | 6 +-- src/std.zr | 26 ++++++++++++ 7 files changed, 302 insertions(+), 5 deletions(-) create mode 100644 examples/puzzles/aoc2024_01.zr create mode 100644 examples/puzzles/aoc2024_02.zr create mode 100644 examples/puzzles/aoc2024_04.zr create mode 100644 examples/puzzles/aoc2024_05.zr create mode 100644 examples/puzzles/aoc2025_03.zr diff --git a/examples/puzzles/aoc2024_01.zr b/examples/puzzles/aoc2024_01.zr new file mode 100644 index 0000000..6ca88c2 --- /dev/null +++ b/examples/puzzles/aoc2024_01.zr @@ -0,0 +1,35 @@ +func part1[l1: Array, l2: Array] : Void + let out: I64 = 0 + + for i in 0..array.size(l1) + out = out + math.abs(array.nth(l1, i) - array.nth(l2, i)) + + io.println_i64(out) + +func part2[l1: Array, l2: Array] : Void + let out: I64 = 0 + + for i in 0..array.size(l1) + out = out + array.nth(l1, i) * alg.count(l2, array.nth(l1, i)) + + io.println_i64(out) + +func main[] : I64 + let lines: Array = io.read_file("input.txt") |> str.split("\n") + + let l1: Array = [] + let l2: Array = [] + + for i in 0..array.size(lines) + let line: String = array.nth(lines, i) + + let parts: Array = str.split(line, " ") + + array.push(l1, str.parse_i64(array.nth(parts, 0))) + array.push(l2, str.parse_i64(array.nth(parts, 1))) + + alg.quicksort(l1) + alg.quicksort(l2) + + part1(l1, l2) + part2(l1, l2) \ No newline at end of file diff --git a/examples/puzzles/aoc2024_02.zr b/examples/puzzles/aoc2024_02.zr new file mode 100644 index 0000000..3ffbfc9 --- /dev/null +++ b/examples/puzzles/aoc2024_02.zr @@ -0,0 +1,54 @@ +func check[report: Array] : Bool + let increasing: Bool = array.nth(report, 0) < array.nth(report, 1) + + for i in 0..array.size(report)-1 + if array.nth(report, i) > array.nth(report, i + 1) & increasing + return false + if array.nth(report, i) < array.nth(report, i + 1) & !increasing + return false + + let diff: I64 = math.abs(array.nth(report, i) - array.nth(report, i + 1)) + if diff < 1 | diff > 3 + return false + + return true + +func part1[data: Array] : Void + let out: I64 = 0 + + for i in 0..array.size(data) + if check(array.nth(data, i)) + out = out + 1 + + io.println_i64(out) + +func part2[data: Array] : Void + let out: I64 = 0 + + for i in 0..array.size(data) + if check(array.nth(data, i)) + out = out + 1 + else + for j in 0..array.size(array.nth(data, i)) + let sliced: Array = array.concat(array.slice(array.nth(data, i), 0, j), array.slice(array.nth(data, i), j + 1, array.size(array.nth(data, i)) - (j + 1))) + + if check(sliced) + out = out + 1 + break + + io.println_i64(out) + +func main[] : I64 + let lines: Array = io.read_file("input.txt") |> str.split("\n") + + let data: Array = [] + for i in 0..array.size(lines) + let line: String = array.nth(lines, i) + + let report: Array = str.split(line, " ") + for i in 0..array.size(report) + array.set(report, i, str.parse_i64(array.nth(report, i))) + array.push(data, report) + + part1(data) + part2(data) \ No newline at end of file diff --git a/examples/puzzles/aoc2024_04.zr b/examples/puzzles/aoc2024_04.zr new file mode 100644 index 0000000..d890d80 --- /dev/null +++ b/examples/puzzles/aoc2024_04.zr @@ -0,0 +1,62 @@ +func check[lines: Array, x: I64, y: I64, dx: I64, dy: I64] : Bool + if x + dx * 3 < 0 | x + dx * 3 >= array.size(lines) | y + dy * 3 < 0 | y + dy * 3 >= str.len(array.nth(lines, 0)) + return false + + if array.nth(lines, x)[y] != 'X' + return false + if array.nth(lines, x + dx)[y + dy] != 'M' + return false + if array.nth(lines, x + dx * 2)[y + dy * 2] != 'A' + return false + if array.nth(lines, x + dx * 3)[y + dy * 3] != 'S' + return false + + return true + +func part1[lines: Array] : Void + let out: I64 = 0 + + for x in 0..array.size(lines) + for y in 0..str.len(array.nth(lines, x)) + if check(lines, x, y, 0, 1) + out = out + 1 + if check(lines, x, y, 0, -1) + out = out + 1 + if check(lines, x, y, 1, 0) + out = out + 1 + if check(lines, x, y, -1, 0) + out = out + 1 + if check(lines, x, y, 1, 1) + out = out + 1 + if check(lines, x, y, -1, -1) + out = out + 1 + if check(lines, x, y, 1, -1) + out = out + 1 + if check(lines, x, y, -1, 1) + out = out + 1 + + io.println_i64(out) + +func part2[lines: Array] : Void + let out: I64 = 0 + + for x in 1..array.size(lines)-1 + for y in 1..str.len(array.nth(lines, x))-1 + if array.nth(lines, x)[y] == 'A' + let s: String = mem.alloc(5) + str.set(s, 0, array.nth(lines, x - 1)[y - 1]) + str.set(s, 1, array.nth(lines, x + 1)[y - 1]) + str.set(s, 2, array.nth(lines, x + 1)[y + 1]) + str.set(s, 3, array.nth(lines, x - 1)[y + 1]) + str.set(s, 4, 0) + + if str.equal(s, "MSSM") | str.equal(s, "SMMS") | str.equal(s, "MMSS") | str.equal(s, "SSMM") + out = out + 1 + + io.println_i64(out) + +func main[] : I64 + let lines: Array = io.read_file("input.txt") |> str.split("\n") + + part1(lines) + part2(lines) \ No newline at end of file diff --git a/examples/puzzles/aoc2024_05.zr b/examples/puzzles/aoc2024_05.zr new file mode 100644 index 0000000..1f7e24c --- /dev/null +++ b/examples/puzzles/aoc2024_05.zr @@ -0,0 +1,73 @@ +func rule_exists[rules_left: Array, rules_right: Array, a: I64, b: I64] : Bool + for k in 0..array.size(rules_left) + if array.nth(rules_left, k) == a & array.nth(rules_right, k) == b + return true + return false + +func check[update: Array, rules_left: Array, rules_right: Array] : Bool + for i in 0..array.size(update) + for j in 0..i + if rule_exists(rules_left, rules_right, array.nth(update, i), array.nth(update, j)) + return false + return true + +func sort_by_rules[update: Array, rules_left: Array, rules_right: Array] : Void + let swapped: Bool = true + + while swapped + swapped = false + for i in 0..array.size(update)-1 + let a: I64 = array.nth(update, i) + let b: I64 = array.nth(update, i+1) + if rule_exists(rules_left, rules_right, b, a) + let tmp: I64 = a + array.set(update, i, b) + array.set(update, i+1, tmp) + swapped = true + +func part1[updates: Array, rules_left: Array, rules_right: Array] : Void + let out: I64 = 0 + + for i in 0..array.size(updates) + let update: Array = array.nth(updates, i) + if check(update, rules_left, rules_right) + out = out + array.nth(update, array.size(update) / 2) + + io.println_i64(out) + +func part2[updates: Array, rules_left: Array, rules_right: Array] : Void + let out: I64 = 0 + + for i in 0..array.size(updates) + let update: Array = array.nth(updates, i) + if !check(update, rules_left, rules_right) + sort_by_rules(update, rules_left, rules_right) + out = out + array.nth(update, array.size(update) / 2) + + io.println_i64(out) + +func main[] : I64 + let data: Array = io.read_file("input.txt") |> str.split("\n\n") + + let rules_left: Array = [] + let rules_right: Array = [] + let rules_lines: Array = str.split(array.nth(data, 0), "\n") + for i in 0..array.size(rules_lines) + let line: String = array.nth(rules_lines, i) + let parts: Array = str.split(line, "|") + + array.push(rules_left, str.parse_i64(array.nth(parts, 0))) + array.push(rules_right, str.parse_i64(array.nth(parts, 1))) + + let updates: Array = [] + let updates_lines: Array = str.split(array.nth(data, 1), "\n") + for i in 0..array.size(updates_lines) + let line: String = array.nth(updates_lines, i) + let xs: Array = str.split(line, ",") + + for i in 0..array.size(xs) + array.set(xs, i, str.parse_i64(array.nth(xs, i))) + array.push(updates, xs) + + part1(updates, rules_left, rules_right) + part2(updates, rules_left, rules_right) \ No newline at end of file diff --git a/examples/puzzles/aoc2025_03.zr b/examples/puzzles/aoc2025_03.zr new file mode 100644 index 0000000..7503f7b --- /dev/null +++ b/examples/puzzles/aoc2025_03.zr @@ -0,0 +1,51 @@ +func part1[lines: Array] : Void + let sum: I64 = 0 + + for i in 0..array.size(lines) + let line: String = array.nth(lines, i) + + let largest: I64 = 0 + for j in 0..str.len(line) + for k in (j+1)..str.len(line) + let s: String = mem.alloc(3) + str.set(s, 0, line[j]) + str.set(s, 1, line[k]) + str.set(s, 2, 0) + let n: I64 = str.parse_i64(s) + if n > largest + largest = n + + sum = sum + largest + io.println_i64(sum) + +// had to cheat this one +func part2_rec[bank: String, start: I64, remaining: I64] : I64 + let largest: I64 = 0 + let largest_idx: I64 = start + let len: I64 = str.len(bank) + + for i in (start)..(len-remaining+1) + let v: I64 = bank[i] - '0' + if v > largest + largest = v + largest_idx = i + + if remaining > 1 + return largest * math.pow(10, remaining - 1) + part2_rec(bank, largest_idx + 1, remaining - 1) + else + return largest + +func part2[lines: Array] : Void + let sum: I64 = 0 + + for i in 0..array.size(lines) + let line: String = array.nth(lines, i) + + sum = sum + part2_rec(line, 0, 12) + io.println_i64(sum) + +func main[] : I64 + let lines: Array = io.read_file("input.txt") |> str.split("\n") + + part1(lines) + part2(lines) \ No newline at end of file diff --git a/src/codegen_x86_64.rs b/src/codegen_x86_64.rs index 109d9c3..b8cc0a7 100644 --- a/src/codegen_x86_64.rs +++ b/src/codegen_x86_64.rs @@ -87,11 +87,7 @@ impl CodegenX86_64 { } pub fn get_output(&self) -> String { - format!( - "section .data -{}{}", - self.data_section, self.output - ) + format!("section .data\n{}{}", self.data_section, self.output) } pub fn emit_prologue(&mut self) -> Result<(), ZernError> { diff --git a/src/std.zr b/src/std.zr index 76f68d5..71f74f4 100644 --- a/src/std.zr +++ b/src/std.zr @@ -6,6 +6,7 @@ extern gethostbyname func dbg.panic[msg: String] : Void io.print("PANIC: ") io.println(msg) + 0/0 // crashes program which is kinda better since you get a gdb backtrace os.exit(1) func mem.alloc[x: I64] : Ptr @@ -400,6 +401,23 @@ func array.free[xs: Array] : Void mem.free(data) mem.free(xs) +func array.slice[xs: Array, start: I64, length: I64] : Array + if start < 0 | length < 0 | start + length > array.size(xs) + dbg.panic("array.slice out of bounds") + + let new_array: Array = [] + for i in 0..length + array.push(new_array, array.nth(xs, start + i)) + return new_array + +func array.concat[a: Array, b: Array] : Array + let new_array: Array = [] + for i in 0..array.size(a) + array.push(new_array, array.nth(a, i)) + for i in 0..array.size(b) + array.push(new_array, array.nth(b, i)) + return new_array + func alg.quicksort[arr: Array] : Void alg._do_quicksort(arr, 0, array.size(arr) - 1) @@ -423,6 +441,14 @@ func alg._partition[arr: Array, low: I64, high: I64] : I64 array.set(arr, high, temp) return i + 1 +func alg.count[arr: Array, item: I64] : I64 + let count: I64 = 0 + let size: I64 = array.size(arr) + for i in 0..size + if array.nth(arr, i) == item + count = count + 1 + return count + func os.exit[code: I64] : Void _builtin_syscall(60, code)