#![no_std]
use common::{print, read};
fn main() {
let buf = [0u8; 65000];
read(buf.as_ptr(), buf.len());
let input = str::from_utf8(&buf).unwrap();
let result_one = one(input);
let result_two = two(input);
print!(32, "one: {}\ntwo: {}\n", result_one, result_two);
}
fn one(input: &str) -> u16 {
let mut zeros: u16 = 0;
let mut pos: i16 = 50;
for ins in input.split("\n") {
// Last entry is all unused bytes.
if ins.len() > 10 {
continue;
}
let (direction, amount_s) = ins.split_at(1);
let amount = amount_s.parse::<i16>().unwrap();
match direction {
"R" => {
pos += amount;
while pos > 99 {
pos -= 100;
}
}
"L" => {
pos -= amount;
while pos < 0 {
pos += 100;
}
}
_ => unreachable!(),
}
if pos == 0 {
zeros += 1;
}
}
zeros
}
fn two(input: &str) -> u16 {
let mut zeros: u16 = 0;
let mut pos: i16 = 50;
for ins in input.split("\n") {
// Last entry is all unused bytes.
if ins.len() > 10 {
continue;
}
let (direction, amount_s) = ins.split_at(1);
let mut amount = amount_s.parse::<i16>().unwrap();
match direction {
"R" => {}
"L" => amount = -amount,
_ => unreachable!(),
}
pos += amount;
if pos <= 0 && amount != pos {
zeros += 1;
}
let overflows = pos.abs() / 100;
zeros += overflows as u16;
pos = pos.rem_euclid(100);
}
zeros
}
#[cfg(test)]
mod test {
use super::*;
const EXAMPLE_INPUT: &str = r#"L68
L30
R48
L5
R60
L55
L1
L99
R14
L82"#;
#[test]
fn example() {
assert_eq!(one(EXAMPLE_INPUT), 3);
assert_eq!(two(EXAMPLE_INPUT), 6);
}
#[test]
fn two_1000() {
assert_eq!(two("R1000"), 10);
}
#[test]
fn two_basics() {
// Move to zero (!), move one left, should be at 99.
assert_eq!(two("L50\nL1"), 1);
// Move to 99, move one right, should be at zero (!).
assert_eq!(two("R49\nR1"), 1);
// Move to 5, move ten left (!), should be at 95, move 5 right, should be at zero (!).
assert_eq!(two("L45\nL10\nR5"), 2);
}
#[test]
fn two_a() {
let input = r#"R50
L1"#;
assert_eq!(two(input), 1);
}
#[test]
fn two_b() {
assert_eq!(two("L100"), 1);
}
#[test]
fn two_c() {
assert_eq!(two("L120"), 1);
}
#[test]
fn two_d() {
let input = r#"R250
L1"#;
assert_eq!(two(input), 3);
}
#[test]
fn two_e() {
let input = r#"R400"#;
assert_eq!(two(input), 4);
}
#[test]
fn two_f() {
let input = r#"L250"#;
assert_eq!(two(input), 3);
}
#[test]
fn two_g() {
let input = r#"L50
R200"#;
assert_eq!(two(input), 3);
}
#[test]
fn two_h() {
let input = r#"R38
R17"#;
assert_eq!(two(input), 1);
}
}