From 074256679d26581d2b87a3c3ba76418e1d4b7f9f Mon Sep 17 00:00:00 2001 From: Antoine Date: Sat, 2 Dec 2023 09:35:36 +0100 Subject: [PATCH] [2023] Day 1 in Zig --- .gitignore | 5 ++-- 2023/01/first.zig | 49 ++++++++++++++++++++++++++++++++ 2023/01/second.zig | 70 ++++++++++++++++++++++++++++++++++++++++++++++ 2023/01/utils.py | 6 ++++ 4 files changed, 128 insertions(+), 2 deletions(-) create mode 100644 2023/01/first.zig create mode 100644 2023/01/second.zig create mode 100644 2023/01/utils.py diff --git a/.gitignore b/.gitignore index 74965a8..91988fd 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ -*~ #*# +*~ +*.o __pycache__ -*.txt \ No newline at end of file +*.txt diff --git a/2023/01/first.zig b/2023/01/first.zig new file mode 100644 index 0000000..825c59e --- /dev/null +++ b/2023/01/first.zig @@ -0,0 +1,49 @@ +const std = @import("std"); + +const LineIterator = struct { + buffer: [1024]u8 = undefined, + file: std.fs.File = std.io.getStdIn(), + pub fn next(self: *LineIterator) ?[]u8 { + return self.file.reader().readUntilDelimiterOrEof(&self.buffer, '\n') catch { + return null; + }; + } +}; + +fn extractValue(line: []const u8) ?u8 { + var numbers = std.ArrayList(u8).init(std.heap.page_allocator); + defer numbers.deinit(); + + for (line) |c| { + if (std.ascii.isDigit(c)) { + numbers.append(std.fmt.charToDigit(c, 10) catch 0) catch return null; + } + } + return 10 * numbers.items[0] + numbers.getLast(); +} + +pub fn main() void { + var result: u32 = 0; + var lines = LineIterator{}; + while (lines.next()) |line| { + result += extractValue(line) orelse 0; + } + std.fmt.format(std.io.getStdOut().writer(), "Sum: {}\n", .{result}) catch {}; +} + +test "Use the first and last digits" { + try std.testing.expect(extractValue("12345") == 15); + try std.testing.expect(extractValue("987654") == 94); +} + +test "Ignore non digits" { + try std.testing.expect(extractValue("toto8hello5lmao2ok") == 82); + try std.testing.expect(extractValue("no7non4nine6nein") == 76); +} + +test "Sample" { + try std.testing.expect(extractValue("1abc2") == 12); + try std.testing.expect(extractValue("pqr3stu8vwx") == 38); + try std.testing.expect(extractValue("a1b2c3d4e5f") == 15); + try std.testing.expect(extractValue("treb7uchet") == 77); +} diff --git a/2023/01/second.zig b/2023/01/second.zig new file mode 100644 index 0000000..0b63ebd --- /dev/null +++ b/2023/01/second.zig @@ -0,0 +1,70 @@ +const std = @import("std"); + +const LineIterator = struct { + buffer: [1024]u8 = undefined, + file: std.fs.File = std.io.getStdIn(), + pub fn next(self: *LineIterator) ?[]u8 { + return self.file.reader().readUntilDelimiterOrEof(&self.buffer, '\n') catch { + return null; + }; + } +}; + +pub fn extractValue(line: []const u8) u8 { + const spelled = std.ComptimeStringMap(u8, .{ .{ "one", 1 }, .{ "two", 2 }, .{ "three", 3 }, .{ "four", 4 }, .{ "five", 5 }, .{ "six", 6 }, .{ "seven", 7 }, .{ "eight", 8 }, .{ "nine", 9 } }); + var numbers = std.ArrayList(u8).init(std.heap.page_allocator); + defer numbers.deinit(); + + for (line, 0..) |c, i| { + if (std.fmt.charToDigit(c, 10)) |digit| { + numbers.append(digit) catch break; + } else |_| for (3..6) |length| { + if (length + i > line.len) + break; + if (spelled.get(line[i..][0..length])) |digit| + numbers.append(digit) catch break; + } + } + return 10 * numbers.items[0] + numbers.getLast(); +} + +pub fn main() void { + var result: u32 = 0; + var lines = LineIterator{}; + + while (lines.next()) |line| { + result += extractValue(line); + } + std.fmt.format(std.io.getStdOut().writer(), "Sum: {}\n", .{result}) catch {}; +} + +test "Still extract first and last simple digits" { + try std.testing.expect(extractValue("12345") == 15); + try std.testing.expect(extractValue("987654") == 94); + try std.testing.expect(extractValue("toto8hello5lmao2ok") == 82); + try std.testing.expect(extractValue("no7non4nine6nein") == 76); +} + +test "Read numbers spelled out in letters" { + try std.testing.expect(extractValue("nononosix7654seven3fourmis") == 64); + try std.testing.expect(extractValue("wwtwo1one2eightxx") == 28); +} + +test "Watch out for overlap" { + try std.testing.expect(extractValue("oneight") == 18); + try std.testing.expect(extractValue("twone") == 21); + try std.testing.expect(extractValue("eightwo") == 82); + try std.testing.expect(extractValue("threeight") == 38); + try std.testing.expect(extractValue("fiveight") == 58); + try std.testing.expect(extractValue("sevenine") == 79); +} + +test "Sample" { + try std.testing.expect(extractValue("two1nine") == 29); + try std.testing.expect(extractValue("eightwothree") == 83); + try std.testing.expect(extractValue("abcone2threexyz") == 13); + try std.testing.expect(extractValue("xtwone3four") == 24); + try std.testing.expect(extractValue("4nineeightseven2") == 42); + try std.testing.expect(extractValue("zoneight234") == 14); + try std.testing.expect(extractValue("7pqrstsixteen") == 76); +} diff --git a/2023/01/utils.py b/2023/01/utils.py new file mode 100644 index 0000000..e951ba1 --- /dev/null +++ b/2023/01/utils.py @@ -0,0 +1,6 @@ +def lines(): + while True: + try: + yield input() + except: + break