Last active
May 12, 2024 14:07
-
-
Save 8/eb60ec14ccebffcd58530d94fddd2921 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const std = @import("std"); | |
pub fn main() !void { | |
_ = try part1_example(); | |
_ = try part1_file(); | |
} | |
fn print(comptime format: []const u8, args: anytype) !void { | |
_ = try std.io.getStdOut().writer().print(format, args); | |
} | |
const example = | |
\\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 | |
; | |
fn part1_example() !void { | |
var fbs = std.io.fixedBufferStream(example); | |
const reader = fbs.reader().any(); | |
const result = try part1(reader, 12, 13, 14); | |
_ = try print("part1_example: {}\n", .{result}); | |
} | |
fn part1_file() !void { | |
var file = try std.fs.cwd().openFile("day2.txt", .{}); | |
const reader = file.reader().any(); | |
const result = try part1(reader, 12, 13, 14); | |
_ = try print("part1_file: {}\n", .{result}); | |
} | |
fn part1(reader: std.io.AnyReader, r: u32, g: u32, b: u32) !u32 { | |
var buf: [1024]u8 = undefined; | |
var sum : u32 = 0; | |
while (reader.readUntilDelimiterOrEof(&buf, '\n')) |line_or_null| { | |
if (line_or_null) |line| { | |
// _ = try print("{s}\n", .{line}); | |
// parse a game | |
const game = try Game(20).from_line(line); | |
if (game.is_valid(r, g, b)) { | |
sum += game.number; | |
} | |
// _ = try print("Game {}\n", .{game.number}); | |
} else { | |
break; | |
} | |
} else |err| { | |
return err; | |
} | |
return sum; | |
} | |
const ColorType = enum { | |
Red, Green, Blue | |
}; | |
const Color = struct { | |
count: u32, | |
color_type: ColorType, | |
pub fn from(text: []u8) !Color { | |
var fbs = std.io.fixedBufferStream(text); | |
var reader = fbs.reader(); | |
var buf: [256]u8 = undefined; | |
const text_count = reader.readUntilDelimiter(&buf, ' ') catch |e| { return e; }; | |
// _ = try print("text_count: {s}\n", .{text_count}); | |
const i = std.fmt.parseInt(u32, text_count, 10) catch |e| {return e;}; | |
const text_color_type = text[text_count.len+1..text.len]; | |
// _ = try print("text_color_type: {s}", .{text_color_type}); | |
const color_type = | |
if (std.mem.eql(u8, text_color_type, "red")) | |
ColorType.Red | |
else if(std.mem.eql(u8, text_color_type, "green")) | |
ColorType.Green | |
else | |
ColorType.Blue; | |
return Color { | |
.count = i, | |
.color_type = color_type, | |
}; | |
} | |
}; | |
const Set = struct { | |
red: u32, | |
green: u32, | |
blue: u32, | |
pub fn from(text: []u8) !Set { | |
var fbs = std.io.fixedBufferStream(text); | |
var reader = fbs.reader(); | |
var buf: [1024]u8 = undefined; | |
var red: u32 = 0; | |
var green: u32 = 0; | |
var blue: u32 = 0; | |
while (reader.readUntilDelimiterOrEof(&buf, ',')) |r| { | |
if (r) |text_color| { | |
// _ = try print("text_color: {s}\n", .{text_color}); | |
const color = try Color.from(text_color[1..]); | |
// _ = try print("color: count={}, type={}\n", .{color.count, color.color_type}); | |
if (color.color_type == ColorType.Red) { | |
red = color.count; | |
} else if (color.color_type == ColorType.Green) { | |
green = color.count; | |
} else if (color.color_type == ColorType.Blue) { | |
blue = color.count; | |
} | |
} else { // eof | |
break; | |
} | |
} else |e| { return e;} | |
return Set { | |
.red = red, | |
.green = green, | |
.blue = blue, | |
}; | |
} | |
}; | |
fn Game(comptime max_sets: usize) type { | |
return struct { | |
number: u32, | |
sets: [max_sets]Set, | |
sets_used: usize, | |
// example line: "Game 1: 3 blue, 4 red; 1 red, 2 green, 6 blue; 2 green" | |
pub fn from_line(line: []u8) !Game(max_sets) { | |
var fbs = std.io.fixedBufferStream(line); | |
var reader = fbs.reader(); | |
// parse the game number | |
var game_num : u32 = undefined; | |
var buf_game: [1024]u8 = undefined; | |
if (reader.readUntilDelimiter(&buf_game, ':')) |game| { | |
if (std.fmt.parseInt(u32, game[("Game ".len)..game.len], 10)) |i| { | |
game_num = i; | |
} else |e| { | |
return e; | |
} | |
// _ = try print("game: {}\n", .{game_num}); | |
// parse the sets | |
var buf_set: [1024]u8 = undefined; | |
var sets: [max_sets]Set = undefined; | |
var set_index : usize = 0; | |
while (reader.readUntilDelimiterOrEof(&buf_set, ';')) |set_or_null| { | |
if (set_or_null) |set_slice| { | |
// _ = try print("slice: {s}\n", .{set_slice}); | |
const set = try Set.from(set_slice); | |
sets[set_index] = set; | |
set_index=set_index+1; | |
} else { | |
break; | |
} | |
} else |err| { return err; } | |
return Game(max_sets) { | |
.number = game_num, | |
.sets = sets, | |
.sets_used = set_index, | |
}; | |
} else |e| { | |
return e; | |
} | |
} | |
pub fn is_valid(self: Game(max_sets), r: u32, g: u32, b: u32) bool { | |
var all_valid = true; | |
for (0..self.sets_used) |i| { | |
const s = self.sets[i]; | |
// print("r:{},g:{},b:{}\n", .{s.red, s.green, s.blue}) catch {}; | |
all_valid = s.red <= r and s.green <= g and s.blue <= b; | |
if (!all_valid) { | |
break; | |
} | |
} | |
return all_valid; | |
} | |
}; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment