79 lines
1.6 KiB
Rust
79 lines
1.6 KiB
Rust
const LOOP_COUNT: i32 = 1_000_000;
|
|
const EXPECTED_CHECKSUM: i32 = 3_500_013;
|
|
|
|
struct Packet {
|
|
digits: [i32; 8],
|
|
}
|
|
|
|
enum PacketState {
|
|
Missing,
|
|
Live(Packet),
|
|
Cached(Packet),
|
|
}
|
|
|
|
fn configured_loop_count() -> i32 {
|
|
let mut input = String::new();
|
|
if std::io::stdin().read_line(&mut input).is_err() {
|
|
return LOOP_COUNT;
|
|
}
|
|
|
|
input
|
|
.trim()
|
|
.parse::<i32>()
|
|
.ok()
|
|
.filter(|value| *value > 0)
|
|
.unwrap_or(LOOP_COUNT)
|
|
}
|
|
|
|
fn live_state() -> PacketState {
|
|
PacketState::Live(Packet {
|
|
digits: [2, 7, 1, 8, 2, 8, 1, 8],
|
|
})
|
|
}
|
|
|
|
fn cached_state() -> PacketState {
|
|
PacketState::Cached(Packet {
|
|
digits: [1, 6, 1, 8, 0, 3, 4, 5],
|
|
})
|
|
}
|
|
|
|
fn select_state<'a>(i: i32, live: &'a PacketState, cached: &'a PacketState) -> &'a PacketState {
|
|
if i % 2 == 0 {
|
|
live
|
|
} else {
|
|
cached
|
|
}
|
|
}
|
|
|
|
fn state_digit(state: &PacketState, index: i32) -> i32 {
|
|
match state {
|
|
PacketState::Missing => 0,
|
|
PacketState::Live(payload) | PacketState::Cached(payload) => payload.digits[index as usize],
|
|
}
|
|
}
|
|
|
|
fn enum_struct_payload_loop(limit: i32) -> i32 {
|
|
let live = live_state();
|
|
let cached = cached_state();
|
|
let mut i = 0;
|
|
let mut acc = 13;
|
|
|
|
while i < limit {
|
|
acc += state_digit(select_state(i, &live, &cached), i % 8);
|
|
acc = if acc > 1_000_000_000 {
|
|
acc - 1_000_000_000
|
|
} else {
|
|
acc
|
|
};
|
|
i += 1;
|
|
}
|
|
|
|
acc
|
|
}
|
|
|
|
fn main() {
|
|
let result = enum_struct_payload_loop(configured_loop_count());
|
|
println!("{}", result);
|
|
std::process::exit(if result == EXPECTED_CHECKSUM { 0 } else { 1 });
|
|
}
|