slovo/benchmarks/enum-struct-payload-loop/rust/enum_struct_payload_loop.rs
2026-05-22 08:38:43 +02:00

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 });
}