solve day 4
This commit is contained in:
parent
b863e1b2aa
commit
1d9a506f76
@ -3,7 +3,7 @@ const Allocator = std.mem.Allocator;
|
||||
|
||||
pub const Input = struct {
|
||||
allocator: Allocator,
|
||||
lines: [][]const u8
|
||||
lines: []const []const u8
|
||||
};
|
||||
|
||||
pub const Result = union(enum) {
|
||||
|
28
src/day2.zig
28
src/day2.zig
@ -42,7 +42,7 @@ fn parse_game(game: *Game, line: []const u8) void {
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_games(allocator: Allocator, lines: [][]const u8) ![]Game {
|
||||
fn parse_games(allocator: Allocator, lines: []const []const u8) ![]Game {
|
||||
var games = try allocator.alloc(Game, lines.len);
|
||||
for (0.., lines) |i, line| {
|
||||
parse_game(&games[i], line);
|
||||
@ -102,29 +102,23 @@ pub fn part2(input: *aoc.Input) !aoc.Result {
|
||||
return .{ .uint = sum };
|
||||
}
|
||||
|
||||
const example_input = [_][]const u8{
|
||||
"Game 1: 3 blue, 4 red; 1 red, 2 green, 6 blue; 2 green",
|
||||
"Game 2: 1 blue, 2 green; 3 green, 4 blue, 1 red; 1 green, 1 blue",
|
||||
"Game 3: 8 green, 6 blue, 20 red; 5 blue, 4 red, 13 green; 5 green, 1 red",
|
||||
"Game 4: 1 green, 3 red, 6 blue; 3 green, 6 red; 3 green, 15 blue, 14 red",
|
||||
"Game 5: 6 red, 1 blue, 3 green; 2 blue, 1 red, 2 green"
|
||||
};
|
||||
|
||||
test "part 1 example" {
|
||||
var lines = [_][]const u8{
|
||||
"Game 1: 3 blue, 4 red; 1 red, 2 green, 6 blue; 2 green",
|
||||
"Game 2: 1 blue, 2 green; 3 green, 4 blue, 1 red; 1 green, 1 blue",
|
||||
"Game 3: 8 green, 6 blue, 20 red; 5 blue, 4 red, 13 green; 5 green, 1 red",
|
||||
"Game 4: 1 green, 3 red, 6 blue; 3 green, 6 red; 3 green, 15 blue, 14 red",
|
||||
"Game 5: 6 red, 1 blue, 3 green; 2 blue, 1 red, 2 green"
|
||||
};
|
||||
var input = aoc.Input{ .lines = &lines, .allocator = std.testing.allocator };
|
||||
var input = aoc.Input{ .lines = &example_input, .allocator = std.testing.allocator };
|
||||
var actual = try part1(&input);
|
||||
var expected: u32 = 8;
|
||||
try std.testing.expectEqual(expected, actual.uint);
|
||||
}
|
||||
|
||||
test "part 2 example" {
|
||||
var lines = [_][]const u8{
|
||||
"Game 1: 3 blue, 4 red; 1 red, 2 green, 6 blue; 2 green",
|
||||
"Game 2: 1 blue, 2 green; 3 green, 4 blue, 1 red; 1 green, 1 blue",
|
||||
"Game 3: 8 green, 6 blue, 20 red; 5 blue, 4 red, 13 green; 5 green, 1 red",
|
||||
"Game 4: 1 green, 3 red, 6 blue; 3 green, 6 red; 3 green, 15 blue, 14 red",
|
||||
"Game 5: 6 red, 1 blue, 3 green; 2 blue, 1 red, 2 green"
|
||||
};
|
||||
var input = aoc.Input{ .lines = &lines, .allocator = std.testing.allocator };
|
||||
var input = aoc.Input{ .lines = &example_input, .allocator = std.testing.allocator };
|
||||
var actual = try part2(&input);
|
||||
var expected: u32 = 2286;
|
||||
try std.testing.expectEqual(expected, actual.uint);
|
||||
|
43
src/day3.zig
43
src/day3.zig
@ -28,7 +28,7 @@ fn append_unique(list: *PointList, point: PointU32) !void {
|
||||
try list.append(point);
|
||||
}
|
||||
|
||||
fn find_neighbouring_numbers(found_list: *PointList, lines: [][]const u8, x: usize, y: usize) !void {
|
||||
fn find_neighbouring_numbers(found_list: *PointList, lines: []const []const u8, x: usize, y: usize) !void {
|
||||
const neighbours = .{
|
||||
.{ -1, -1 }, .{ 0, -1 }, .{ 1, -1 },
|
||||
.{ -1, 0 }, .{ 1, 0 },
|
||||
@ -107,39 +107,28 @@ pub fn part2(input: *aoc.Input) !aoc.Result {
|
||||
return .{ .uint = sum };
|
||||
}
|
||||
|
||||
const example_input = [_][]const u8{
|
||||
"467..114..",
|
||||
"...*......",
|
||||
"..35..633.",
|
||||
"......#...",
|
||||
"617*......",
|
||||
".....+.58.",
|
||||
"..592.....",
|
||||
"......755.",
|
||||
"...$.*....",
|
||||
".664.598.."
|
||||
};
|
||||
|
||||
test "part 1 example" {
|
||||
var lines = [_][]const u8{
|
||||
"467..114..",
|
||||
"...*......",
|
||||
"..35..633.",
|
||||
"......#...",
|
||||
"617*......",
|
||||
".....+.58.",
|
||||
"..592.....",
|
||||
"......755.",
|
||||
"...$.*....",
|
||||
".664.598.."
|
||||
};
|
||||
var input = aoc.Input{ .lines = &lines, .allocator = std.testing.allocator };
|
||||
var input = aoc.Input{ .lines = &example_input, .allocator = std.testing.allocator };
|
||||
var actual = try part1(&input);
|
||||
var expected: u32 = 4361;
|
||||
try std.testing.expectEqual(expected, actual.uint);
|
||||
}
|
||||
|
||||
test "part 2 example" {
|
||||
var lines = [_][]const u8{
|
||||
"467..114..",
|
||||
"...*......",
|
||||
"..35..633.",
|
||||
"......#...",
|
||||
"617*......",
|
||||
".....+.58.",
|
||||
"..592.....",
|
||||
"......755.",
|
||||
"...$.*....",
|
||||
".664.598.."
|
||||
};
|
||||
var input = aoc.Input{ .lines = &lines, .allocator = std.testing.allocator };
|
||||
var input = aoc.Input{ .lines = &example_input, .allocator = std.testing.allocator };
|
||||
var actual = try part2(&input);
|
||||
var expected: u32 = 467835;
|
||||
try std.testing.expectEqual(expected, actual.uint);
|
||||
|
119
src/day4.zig
Normal file
119
src/day4.zig
Normal file
@ -0,0 +1,119 @@
|
||||
const aoc = @import("./aoc.zig");
|
||||
const std = @import("std");
|
||||
const Allocator = std.mem.Allocator;
|
||||
const assert = std.debug.assert;
|
||||
|
||||
const BoundedUintArray = std.BoundedArray(u32, 32);
|
||||
|
||||
const Card = struct {
|
||||
winning: BoundedUintArray,
|
||||
mine: BoundedUintArray
|
||||
};
|
||||
|
||||
const CardArray = std.ArrayList(Card);
|
||||
|
||||
fn parse_numbers(result: *BoundedUintArray, text: []const u8) !void {
|
||||
var i: usize = 0;
|
||||
var tokens = std.mem.tokenizeScalar(u8, text, ' ');
|
||||
while (tokens.next()) |token| : (i += 1) {
|
||||
const number = try std.fmt.parseInt(u32, token, 10);
|
||||
try result.append(number);
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_input(allocator: Allocator, lines: []const []const u8) !CardArray {
|
||||
var cards = CardArray.init(allocator);
|
||||
for (lines) |line| {
|
||||
var card = Card{
|
||||
.winning = try BoundedUintArray.init(0),
|
||||
.mine = try BoundedUintArray.init(0)
|
||||
};
|
||||
const colon = std.mem.indexOfScalar(u8, line, ':') orelse @panic("Invalid format");
|
||||
const bar = std.mem.indexOfScalar(u8, line, '|') orelse @panic("Invalid format");
|
||||
|
||||
const winning_str = line[(colon+2)..(bar-1)];
|
||||
try parse_numbers(&card.winning, winning_str);
|
||||
|
||||
const mine_str = line[(bar+2)..];
|
||||
try parse_numbers(&card.mine, mine_str);
|
||||
|
||||
try cards.append(card);
|
||||
}
|
||||
|
||||
return cards;
|
||||
}
|
||||
|
||||
pub fn part1(input: *aoc.Input) !aoc.Result {
|
||||
const allocator = input.allocator;
|
||||
const cards = try parse_input(allocator, input.lines);
|
||||
defer cards.deinit();
|
||||
|
||||
var result: u32 = 0;
|
||||
for (cards.items) |card| {
|
||||
var matches: u32 = 0;
|
||||
for (card.mine.slice()) |num| {
|
||||
if (std.mem.indexOfScalar(u32, card.winning.slice(), num) != null) {
|
||||
matches += 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (matches >= 1) {
|
||||
result += try std.math.powi(u32, 2, matches-1);
|
||||
}
|
||||
}
|
||||
|
||||
return .{ .uint = result };
|
||||
}
|
||||
|
||||
pub fn part2(input: *aoc.Input) !aoc.Result {
|
||||
const allocator = input.allocator;
|
||||
const cards = try parse_input(allocator, input.lines);
|
||||
defer cards.deinit();
|
||||
|
||||
var multipliers = try allocator.alloc(u32, cards.items.len);
|
||||
defer allocator.free(multipliers);
|
||||
@memset(multipliers, 1);
|
||||
|
||||
for (cards.items, 0..) |card, i| {
|
||||
var matches: u32 = 0;
|
||||
for (card.mine.slice()) |num| {
|
||||
if (std.mem.indexOfScalar(u32, card.winning.slice(), num) != null) {
|
||||
matches += 1;
|
||||
}
|
||||
}
|
||||
|
||||
for (0..matches) |j| {
|
||||
multipliers[i+j+1] += multipliers[i];
|
||||
}
|
||||
}
|
||||
|
||||
var result: u32 = 0;
|
||||
for (multipliers) |count| {
|
||||
result += count;
|
||||
}
|
||||
|
||||
return .{ .uint = result };
|
||||
}
|
||||
|
||||
const example_input = [_][]const u8{
|
||||
"Card 1: 41 48 83 86 17 | 83 86 6 31 17 9 48 53",
|
||||
"Card 2: 13 32 20 16 61 | 61 30 68 82 17 32 24 19",
|
||||
"Card 3: 1 21 53 59 44 | 69 82 63 72 16 21 14 1",
|
||||
"Card 4: 41 92 73 84 69 | 59 84 76 51 58 5 54 83",
|
||||
"Card 5: 87 83 26 28 32 | 88 30 70 12 93 22 82 36",
|
||||
"Card 6: 31 18 13 56 72 | 74 77 10 23 35 67 36 11"
|
||||
};
|
||||
|
||||
test "part 1 example" {
|
||||
var input = aoc.Input{ .lines = &example_input, .allocator = std.testing.allocator };
|
||||
var actual = try part1(&input);
|
||||
var expected: u32 = 13;
|
||||
try std.testing.expectEqual(expected, actual.uint);
|
||||
}
|
||||
|
||||
test "part 2 example" {
|
||||
var input = aoc.Input{ .lines = &example_input, .allocator = std.testing.allocator };
|
||||
var actual = try part2(&input);
|
||||
var expected: u32 = 30;
|
||||
try std.testing.expectEqual(expected, actual.uint);
|
||||
}
|
@ -22,7 +22,8 @@ fn create_day(comptime module: anytype) aoc.Day {
|
||||
const Days = [_]aoc.Day{
|
||||
create_day(@import("day1.zig")),
|
||||
create_day(@import("day2.zig")),
|
||||
create_day(@import("day3.zig"))
|
||||
create_day(@import("day3.zig")),
|
||||
create_day(@import("day4.zig")),
|
||||
};
|
||||
|
||||
pub fn main() !u8 {
|
||||
@ -100,4 +101,5 @@ test {
|
||||
_ = @import("day1.zig");
|
||||
_ = @import("day2.zig");
|
||||
_ = @import("day3.zig");
|
||||
_ = @import("day4.zig");
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user