Brute forcing it like this was my first thought - like they say: if it's stupid and it works, it's not stupid.
Rust
use std::{cmp::Ordering, fs, str::FromStr};
use color_eyre::eyre::{Result, bail};
const DIAL_NUMBERS: isize = 100;
#[derive(Clone, Copy)]
struct Dial(usize);
impl Dial {
fn new() -> Self {
Self(50)
}
fn rotate(&mut self, rot: isize) -> usize {
let pass_0s;
let total = rot.wrapping_add_unsigned(self.0);
match total.cmp(&0) {
Ordering::Equal => {
pass_0s = 1;
self.0 = 0;
}
Ordering::Less => {
// Starting on 0 means we don't cross it
let started_0 = if self.0 == 0 { 1 } else { 0 };
pass_0s = 1 + (-total / DIAL_NUMBERS) as usize - started_0;
self.0 = (self.0 as isize + rot).rem_euclid(DIAL_NUMBERS) as usize;
}
Ordering::Greater => {
let full_turns = total / DIAL_NUMBERS;
pass_0s = full_turns as usize;
self.0 = (total - DIAL_NUMBERS * full_turns) as usize;
}
};
pass_0s
}
fn sequence(&mut self, s: &str) -> Result<(usize, usize)> {
let mut end_0s = 0;
let mut pass_0s = 0;
for l in s.lines() {
let num = isize::from_str(&l[1..]).unwrap();
let dir = l.bytes().next().unwrap();
pass_0s += match dir {
b'L' => self.rotate(-num),
b'R' => self.rotate(num),
_ => bail!("b{dir} is an invalid rotation direction"),
};
if self.0 == 0 {
end_0s += 1;
}
}
Ok((end_0s, pass_0s))
}
}
fn parts(filepath: &str) -> Result<(usize, usize)> {
let input = fs::read_to_string(filepath)?;
let mut dial = Dial::new();
let res = dial.sequence(&input)?;
Ok(res)
}
fn main() -> Result<()> {
color_eyre::install()?;
let (p1, p2) = parts("d01/input.txt")?;
println!("Part 1: {p1}");
println!("Part 2: {p2}");
Ok(())
}
I lost a lot of time struggling with edge cases in part two since I thought it was wasteful to run rem_euclid() (i.e. modulus) when I'd already got the information to do it more efficiently. While I got there in the end my final code was a bit ugly. This prettier, "unoptimised" version runs in 1.6ms, so I was being an idiot.
I'm far from sure I understand what you're doing in part 2, but I think maybe you hit the same logic bug I did (I solved it with a shameful if statement that I will have to fix later).
REUNION October 17, 2025
I solved it in 1๏ธโฃ5๏ธโฃ moves!
โญ โญ โญ ๐ฆ ๐ฆ ๐
You'd recommend Heroic launcher over Lutris? Epic didn't install via Lutris for me, but I haven't got around to looking into it.
Can you also fly them at 90ยฐ? I'm thinking about flags like Japan ๐ฏ๐ต where is the same or the UK ๐ฌ๐ง where most couldn't tell.
To be clear, the command is made with modern C++, not the icons (which come from nerd fonts or the dev's equivalent).
Haha, nice. I'm your 75th upvote there.
Scrobbling's set up per-user using OAuth in the browser, which is better since different users can scrobble to different accounts.
I'm guessing it's left in because why remove it since it's working, and it would be useful if the default API key stopped working.
I always use https://whatthefont.com/ although mostly cos the name's funny which makes it easy to remember. Any idea which is better?
I hope this is banished, and quickly. This absolutely ruins Lemmy as everything feels quieter than it really is because you see fewer posts, and worst everyone feels ignored themselves as you don't even get any upvotes let alone replies.
This bug is like half of users are suddenly shadow-banned, something designed to stop users from interacting.
Deebster
0 post score0 comment score
Every so often I look for a library that will compile the regex at compile time - iirc, there's some stuff needing to made const fn before that can happen.
Last time I used regex, lazy_static was the way to go; I assume that regex can go in OnceCell nowadays.