day 7
This commit is contained in:
206
07/src/main.zig
Normal file
206
07/src/main.zig
Normal file
@@ -0,0 +1,206 @@
|
||||
// tedious and bad code but zig is mostly fine ig
|
||||
|
||||
const std = @import("std");
|
||||
|
||||
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
|
||||
const alloc = arena.allocator();
|
||||
|
||||
const test_data = @embedFile("test");
|
||||
const input_data = @embedFile("input");
|
||||
|
||||
pub fn main() !void {
|
||||
const stdout = std.io.getStdOut().writer();
|
||||
|
||||
const value1 = try run1(input_data);
|
||||
try stdout.print("{d}\n", .{value1});
|
||||
|
||||
const value2 = try run2(input_data);
|
||||
try stdout.print("{d}\n", .{value2});
|
||||
}
|
||||
|
||||
test "test input part 1" {
|
||||
std.debug.print("\n", .{});
|
||||
const value = try run1(test_data);
|
||||
std.debug.print("{d}\n", .{value});
|
||||
try std.testing.expectEqual(3749, value);
|
||||
}
|
||||
|
||||
test "test input part 2" {
|
||||
std.debug.print("\n",.{});
|
||||
const value = try run2(test_data);
|
||||
std.debug.print("{d}\n", .{value});
|
||||
try std.testing.expectEqual(11387, value);
|
||||
}
|
||||
|
||||
fn parseIntFromReader(reader: anytype) anyerror!u64 {
|
||||
const f = try reader.readByte();
|
||||
if (f < '0' or f > '9') return error.BadCharacter;
|
||||
var v: u64 = f - '0';
|
||||
while (true) {
|
||||
const c = try reader.readByte();
|
||||
if (c < '0' or c > '9') {
|
||||
break;
|
||||
} else {
|
||||
v = (v * 10) + (c - '0');
|
||||
}
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
fn run2(s: []const u8) !u64 {
|
||||
var total: u64 = 0;
|
||||
|
||||
const Entry = struct {
|
||||
n: u64,
|
||||
nums: std.ArrayList(u64)
|
||||
};
|
||||
|
||||
var entries = std.ArrayList(Entry).init(alloc);
|
||||
var s_fbs = std.io.fixedBufferStream(s);
|
||||
var s_reader = s_fbs.reader();
|
||||
l: while (true) {
|
||||
const err: anyerror!void = b: {
|
||||
const n = parseIntFromReader(s_reader) catch |e| break :b e;
|
||||
try s_fbs.seekBy(-1);
|
||||
if ((s_reader.readByte() catch |e| break :b e) != ':') break :b error.BadCharacter;
|
||||
var e: Entry = Entry {
|
||||
.n = n,
|
||||
.nums = std.ArrayList(u64).init(alloc)
|
||||
};
|
||||
while ((s_reader.readByte() catch |er| break :b er) != '\n') {
|
||||
const i = parseIntFromReader(s_reader) catch |er| break :b er;
|
||||
try s_fbs.seekBy(-1);
|
||||
try e.nums.append(i);
|
||||
}
|
||||
try entries.append(e);
|
||||
};
|
||||
_ = err catch |e| switch (e) {
|
||||
error.EndOfStream => { break :l; },
|
||||
else => return e
|
||||
};
|
||||
}
|
||||
|
||||
var str_buf: [64]u8 = undefined;
|
||||
var str_buf_fbs = std.io.fixedBufferStream(&str_buf);
|
||||
var str_buf_writer = str_buf_fbs.writer();
|
||||
for (entries.items) |entry| {
|
||||
const nums: []u64 = entry.nums.items;
|
||||
std.debug.print("{}:", .{entry.n});
|
||||
for (nums) |i| {
|
||||
std.debug.print(" {}", .{i});
|
||||
}
|
||||
std.debug.print("\n",.{});
|
||||
|
||||
const OP = enum { ADD, MUL, CAT };
|
||||
var ops: [32]OP = .{OP.ADD}**32;
|
||||
check: while (true) {
|
||||
var op_i: usize = 0;
|
||||
var v = nums[0];
|
||||
for (nums[1..]) |n| {
|
||||
switch (ops[op_i]) {
|
||||
OP.ADD => v += n,
|
||||
OP.MUL => v *= n,
|
||||
OP.CAT => {
|
||||
try str_buf_fbs.seekTo(0);
|
||||
try std.fmt.formatInt(v, 10, std.fmt.Case.lower, .{}, &str_buf_writer);
|
||||
try std.fmt.formatInt(n, 10, std.fmt.Case.lower, .{}, &str_buf_writer);
|
||||
v = try std.fmt.parseInt(u64, str_buf[0..str_buf_fbs.pos], 10);
|
||||
},
|
||||
}
|
||||
op_i += 1;
|
||||
}
|
||||
|
||||
if (v == entry.n) {
|
||||
std.debug.print("good!\n",.{});
|
||||
total += entry.n;
|
||||
break :check;
|
||||
}
|
||||
|
||||
var i: usize = 0;
|
||||
while (true) {
|
||||
switch(ops[i]) {
|
||||
OP.ADD => ops[i] = OP.MUL,
|
||||
OP.MUL => ops[i] = OP.CAT,
|
||||
OP.CAT => { ops[i] = OP.ADD; i += 1; continue; }
|
||||
}
|
||||
if (i >= nums.len - 1) break :check;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
total += 0;
|
||||
return total;
|
||||
}
|
||||
|
||||
fn run1(s: []const u8) !u64 {
|
||||
var total: u64 = 0;
|
||||
|
||||
const Entry = struct {
|
||||
n: u64,
|
||||
nums: std.ArrayList(u64)
|
||||
};
|
||||
|
||||
var entries = std.ArrayList(Entry).init(alloc);
|
||||
var s_fbs = std.io.fixedBufferStream(s);
|
||||
var s_reader = s_fbs.reader();
|
||||
l: while (true) {
|
||||
const err: anyerror!void = b: {
|
||||
const n = parseIntFromReader(s_reader) catch |e| break :b e;
|
||||
try s_fbs.seekBy(-1);
|
||||
if ((s_reader.readByte() catch |e| break :b e) != ':') break :b error.BadCharacter;
|
||||
var e: Entry = Entry {
|
||||
.n = n,
|
||||
.nums = std.ArrayList(u64).init(alloc)
|
||||
};
|
||||
while ((s_reader.readByte() catch |er| break :b er) != '\n') {
|
||||
const i = parseIntFromReader(s_reader) catch |er| break :b er;
|
||||
try s_fbs.seekBy(-1);
|
||||
try e.nums.append(i);
|
||||
}
|
||||
try entries.append(e);
|
||||
};
|
||||
_ = err catch |e| switch (e) {
|
||||
error.EndOfStream => { break :l; },
|
||||
else => return e
|
||||
};
|
||||
}
|
||||
|
||||
for (entries.items) |entry| {
|
||||
const nums: []u64 = entry.nums.items;
|
||||
std.debug.print("{}:", .{entry.n});
|
||||
for (nums) |i| {
|
||||
std.debug.print(" {}", .{i});
|
||||
}
|
||||
std.debug.print("\n",.{});
|
||||
|
||||
var ops: u32 = 0;
|
||||
const op_mask = (@as(u32,1) << @intCast(nums.len - 1)) - 1;
|
||||
check: while (true) {
|
||||
var no = ops;
|
||||
var v = nums[0];
|
||||
for (nums[1..]) |n| {
|
||||
if (no & 1 == 1) {
|
||||
v *= n;
|
||||
} else {
|
||||
v += n;
|
||||
}
|
||||
no >>= 1;
|
||||
}
|
||||
|
||||
if (v == entry.n) {
|
||||
std.debug.print("good!\n",.{});
|
||||
total += entry.n;
|
||||
break :check;
|
||||
}
|
||||
|
||||
ops += 1;
|
||||
if (ops & op_mask == 0) {
|
||||
break :check;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
total += 0;
|
||||
return total;
|
||||
}
|
Reference in New Issue
Block a user