172 lines
4.2 KiB
Zig
172 lines
4.2 KiB
Zig
const std = @import("std");
|
|
|
|
const Outcomes = enum(u16) {
|
|
Lost = 0,
|
|
Draw = 3,
|
|
Win = 6,
|
|
INVALID = 99,
|
|
|
|
pub fn from_guide(value: u8) Outcomes{
|
|
return switch(value) {
|
|
'X' => Outcomes.Lost,
|
|
'Y' => Outcomes.Draw,
|
|
'Z' => Outcomes.Win,
|
|
else => Outcomes.INVALID,
|
|
};
|
|
}
|
|
};
|
|
|
|
const RPSStates = enum(i8) {
|
|
Rock = 0,
|
|
Paper =1,
|
|
Scissors = 2,
|
|
INVALID = 99,
|
|
_,
|
|
|
|
pub fn from_opponent(value: u8) RPSStates {
|
|
return switch(value) {
|
|
'A' => RPSStates.Rock,
|
|
'B' => RPSStates.Paper,
|
|
'C' => RPSStates.Scissors,
|
|
else => RPSStates.INVALID
|
|
};
|
|
}
|
|
|
|
pub fn from_me(value: u8) RPSStates {
|
|
return switch(value) {
|
|
'X' => RPSStates.Rock,
|
|
'Y' => RPSStates.Paper,
|
|
'Z' => RPSStates.Scissors,
|
|
else => RPSStates.INVALID
|
|
};
|
|
}
|
|
|
|
|
|
pub fn get_move_needed(outcome_needed: Outcomes, opp_choice: RPSStates) RPSStates {
|
|
return switch(outcome_needed) {
|
|
.Lost => opp_choice.get_strong_to_move(),
|
|
.Draw => opp_choice,
|
|
.Win => opp_choice.get_weak_to_move(),
|
|
else => unreachable
|
|
};
|
|
}
|
|
|
|
pub fn outcome(self: RPSStates, opp_choice: RPSStates) Outcomes {
|
|
if (self == opp_choice) {
|
|
return Outcomes.Draw;
|
|
}
|
|
else {
|
|
if (self.get_strong_to_move() == opp_choice) {
|
|
return Outcomes.Win;
|
|
}
|
|
else {
|
|
return Outcomes.Lost;
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn score_round(self: RPSStates, opp_choice: RPSStates) u16 {
|
|
var score: u16 = switch(self) {
|
|
.Rock => 1,
|
|
.Paper => 2,
|
|
.Scissors => 3,
|
|
else => unreachable
|
|
};
|
|
|
|
score += @enumToInt(self.outcome(opp_choice));
|
|
|
|
return score;
|
|
}
|
|
|
|
pub fn get_weak_to_move(self: RPSStates) RPSStates {
|
|
return @intToEnum(RPSStates, @mod((@enumToInt(self) + 1), 3));
|
|
}
|
|
|
|
pub fn get_strong_to_move(self: RPSStates) RPSStates {
|
|
return @intToEnum(RPSStates, @mod((@enumToInt(self) - 1), 3));
|
|
}
|
|
};
|
|
|
|
pub fn part1(opp_letter: u8, my_letter: u8) u16 {
|
|
const opp_choice = RPSStates.from_opponent(opp_letter);
|
|
const my_choice = RPSStates.from_me(my_letter);
|
|
|
|
return my_choice.score_round(opp_choice);
|
|
}
|
|
|
|
pub fn part2(opp_letter: u8, my_letter: u8) u16 {
|
|
const opp_choice = RPSStates.from_opponent(opp_letter);
|
|
|
|
const win_cond = Outcomes.from_guide(my_letter);
|
|
const my_choice = RPSStates.get_move_needed(win_cond, opp_choice);
|
|
|
|
return my_choice.score_round(opp_choice);
|
|
}
|
|
|
|
pub fn main() !void {
|
|
var file = try std.fs.cwd().openFile("inputs/day2.txt", .{});
|
|
defer file.close();
|
|
|
|
var buf_reader = std.io.bufferedReader(file.reader());
|
|
var in_stream = buf_reader.reader();
|
|
|
|
var buf: [1024]u8 = undefined;
|
|
var score_part1: u16 = 0;
|
|
var score_part2: u16 = 0;
|
|
while (try in_stream.readUntilDelimiterOrEof(&buf, '\n')) |line| {
|
|
const opp_letter: u8 = line[0];
|
|
const my_letter: u8 = line[2];
|
|
|
|
|
|
score_part1 += part1(opp_letter, my_letter);
|
|
score_part2 += part2(opp_letter, my_letter);
|
|
}
|
|
|
|
std.debug.print("PART1: My total score: {}\n", .{score_part1});
|
|
std.debug.print("PART2: My total score: {}\n", .{score_part2});
|
|
}
|
|
|
|
test "Win Conditions" {
|
|
var opp = RPSStates.Paper;
|
|
var me = RPSStates.Rock;
|
|
|
|
var score = me.score_round(opp);
|
|
|
|
try std.testing.expect(score == 1);
|
|
|
|
opp = RPSStates.Scissors;
|
|
me = RPSStates.Paper;
|
|
|
|
score = me.score_round(opp);
|
|
|
|
try std.testing.expect(score == 2);
|
|
|
|
opp = RPSStates.Rock;
|
|
me = RPSStates.Scissors;
|
|
|
|
score = me.score_round(opp);
|
|
|
|
try std.testing.expect(score == 3);
|
|
|
|
opp = RPSStates.Rock;
|
|
me = RPSStates.Paper;
|
|
|
|
score = me.score_round(opp);
|
|
|
|
try std.testing.expect(me.outcome(opp) == Outcomes.Win);
|
|
try std.testing.expect(score == 8);
|
|
|
|
opp = RPSStates.Paper;
|
|
me = RPSStates.Scissors;
|
|
|
|
score = me.score_round(opp);
|
|
|
|
try std.testing.expect(score == 9);
|
|
|
|
opp = RPSStates.Scissors;
|
|
me = RPSStates.Rock;
|
|
|
|
score = me.score_round(opp);
|
|
|
|
try std.testing.expect(score == 7);
|
|
} |