kari's recent activity

  1. Comment on Is it possible to expand my Windows EFI partition? in ~tech

    kari
    Link Parent
    Thanks! I’ll give it a shot with GParted then, probably. I already had to reinstall Windows last week while troubleshooting a different issue so no big deal if I end up breaking something and...

    Thanks! I’ll give it a shot with GParted then, probably. I already had to reinstall Windows last week while troubleshooting a different issue so no big deal if I end up breaking something and having to re-install.

    2 votes
  2. Is it possible to expand my Windows EFI partition?

    I currently dual-boot Arch and Windows and just use the Windows EFI partition in Arch as well, however I only have about 13 MB of space left on it. I’d like to try installing Gentoo on an extra...

    I currently dual-boot Arch and Windows and just use the Windows EFI partition in Arch as well, however I only have about 13 MB of space left on it.

    I’d like to try installing Gentoo on an extra SSD I have with nothing on it, but don’t really want to have a second EFI partition if I can avoid it.

    So my question is, can I shrink the Windows main partition towards the right and expand the the Windows EFI partition into the newly freed space?

    6 votes
  3. Comment on What games have you been playing, and what's your opinion on them? in ~games

    kari
    Link
    I’ve been replaying Borderlands 3 and really enjoy it. I don’t think the humour’s quite up to par with BL2 but it still a fun looter shooter.

    I’ve been replaying Borderlands 3 and really enjoy it. I don’t think the humour’s quite up to par with BL2 but it still a fun looter shooter.

    4 votes
  4. Comment on Having been on Android for over a decade, I just got my first iPhone! What should I know? in ~tech

    kari
    Link Parent
    Ha, I love my Siri widget just because it'll tell me to pull up the Maps route to places I've only been to a few times but at roughly the same time and day of the week. For example, I got Cabo...

    Ha, I love my Siri widget just because it'll tell me to pull up the Maps route to places I've only been to a few times but at roughly the same time and day of the week. For example, I got Cabo Bob's (kind of like an Austin-based Chipotle) for dinner two or three Monday's in a row, and Siri was suggesting it as a location to go to.

    3 votes
  5. Comment on Having been on Android for over a decade, I just got my first iPhone! What should I know? in ~tech

    kari
    Link Parent
    I use Apple Maps for Austin to and from DFW pretty often and it's decent. I generally just use it because I don't like Google, but I think it's generally on par with Google Maps. Reroutes for...

    I use Apple Maps for Austin to and from DFW pretty often and it's decent. I generally just use it because I don't like Google, but I think it's generally on par with Google Maps.

    Reroutes for traffic are okay, but a little delayed IMO. For example, some times it won't notify me that taking Loop 340 in Waco will be faster than 35, but if I pull up the full-route view in the CarPlay app it'll show it as a faster option. I do get less info about stuff on the road, but I think maybe that's because Google can use Waze's data where people tend to be pretty active about reports compared to Apple Maps, where people presumably aren't.

    My favorite thing by far is that Apple Maps will show/tell you, like you said, information about lights, stop signs, etc. which can be really helpful when trying to find where to turn in a place you've never been before.

    1 vote
  6. Comment on Having been on Android for over a decade, I just got my first iPhone! What should I know? in ~tech

    kari
    Link Parent
    Also, at least here in the US, not everywhere accepts Apple Pay (I mean, we're way behind on payment tech so not surprising). I have all my cards in my digital wallet, but I also carry a debit...

    Also, at least here in the US, not everywhere accepts Apple Pay (I mean, we're way behind on payment tech so not surprising). I have all my cards in my digital wallet, but I also carry a debit card, a credit card, and my driver's license in my MagSafe wallet.

    1 vote
  7. Comment on What are you reading these days? in ~books

    kari
    Link
    I started After the Revolution by Robert Evans a couple weeks ago. It’s *okay*. I enjoy it so far but some of it’s pretty cheesy and any time he makes any references to specific streets or...

    I started After the Revolution by Robert Evans a couple weeks ago. It’s *okay*. I enjoy it so far but some of it’s pretty cheesy and any time he makes any references to specific streets or neighborhoods in DFW I laugh a bit and get taken out of it. I still am glad to support him and AK Press, though.

    2 votes
  8. Comment on What games have you been playing, and what's your opinion on them? in ~games

    kari
    Link
    I picked up Lego Harry Potter for Switch on Saturday and I’ve been enjoying playing through it with my girlfriend a lot! I also bought the Felix A320 and PMDG 737-700 for Microsoft Flight...
    • I picked up Lego Harry Potter for Switch on Saturday and I’ve been enjoying playing through it with my girlfriend a lot!

    • I also bought the Felix A320 and PMDG 737-700 for Microsoft Flight Simulator which I’ve been enjoying a lot (on top of the Leonardo Fly the Maddog X which I bought a few weeks ago). MSFS was a bit hard for me to get into from X-Plane 11, but now that it’s got some good airliners it’ll be hard for me to go back to XP11 except for some specific planes.

    2 votes
  9. Comment on What have you been listening to this week? in ~music

    kari
    Link
    I went to a concert for the first time since 2019 last week so I’ve been listing to lots of The Regrettes specifically Monday

    I went to a concert for the first time since 2019 last week so I’ve been listing to lots of The Regrettes specifically Monday

    2 votes
  10. Comment on What games have you been playing, and what's your opinion on them? in ~games

    kari
    Link
    I’ve been playing RuneScape 3 a lot lately. It’s not the same as back in the day but I love Ironman mode. I also redownloaded Microsoft Flight Simulator (2020) and bought the Leonardo MD-82 that...

    I’ve been playing RuneScape 3 a lot lately. It’s not the same as back in the day but I love Ironman mode.

    I also redownloaded Microsoft Flight Simulator (2020) and bought the Leonardo MD-82 that came out. It might make me get back into flight simming after a few months away.

    2 votes
  11. Comment on What are you reading these days? in ~books

    kari
    Link
    I've been (extremely slowly) reading The Illuminatus! Trilogy by Robert Shea and Robert Anton Wilson. It's interesting and pretty enjoyable. I'm hoping to start Discworld once I can get a copy...

    I've been (extremely slowly) reading The Illuminatus! Trilogy by Robert Shea and Robert Anton Wilson. It's interesting and pretty enjoyable. I'm hoping to start Discworld once I can get a copy from my library. Some time next month a novel by a podcaster I like, After The Revolution is supposed to come out in physical format and I pre-ordered one so I'll be reading that at some point, too.

    3 votes
  12. Comment on What games have you been playing, and what's your opinion on them? in ~games

    kari
    Link Parent
    Wasn’t Wolfenstein 3D the first FPS?

    Wasn’t Wolfenstein 3D the first FPS?

    2 votes
  13. Comment on What's up with the NFT hate? in ~tech

    kari
    Link Parent
    This article goes into it, but it's pretty much guaranteed that Bitcoin will eventually be mined exclusively by a few major mining groups and thus they'll have lots of power. Here's an excerpt...

    This article goes into it, but it's pretty much guaranteed that Bitcoin will eventually be mined exclusively by a few major mining groups and thus they'll have lots of power. Here's an excerpt about that:

    The resulting problem is the tragedy of the commons: as the currency gets closer to having no more new coins to mint, miners will no longer find it worth the effort to mine, as it won’t be worth enough in coin rewards. Users will then have to pay higher transaction fees to miners to offset this; since users will be keen to get the lowest transaction fees possible, there will be gargantuan pressure on miners to achieve the lowest mining costs they can.

    That means that most mining operations that aren’t gigantic and using cheap energy only available in some geographic locations would run at a loss — and nobody is going to mine for a loss. Thus, you would end up with a handful of very large miners, who could easily band together to raise prices and form a cartel, or subvert the blockchain for their own gain if they so chose.

    I'm not super knowledgeable about all the big cryptocurrencies, but I'd assume most others have a limit on the number of coins which would effectively do the same thing.

    And, for smaller cryptos, it's a lot easier to do 51% attacks.

    8 votes
  14. Comment on What's up with the NFT hate? in ~tech

    kari
    Link Parent
    I mean, 51% attacks are still possible on Bitcoin even if it'd be incredibly difficult, so BTC can 100% be stolen. This article goes into it in the "Proof of Work: Tragedy of the Comments"...

    I mean, 51% attacks are still possible on Bitcoin even if it'd be incredibly difficult, so BTC can 100% be stolen. This article goes into it in the "Proof of Work: Tragedy of the Comments" section, but essentially over time it's likely that BTC will be exclusively mined by a few incredibly massive groups and, even if they don't actually have 51% of the mining power, they can band together to form a cartel and manipulate BTC in ways they like.

    4 votes
  15. Comment on Day 15: Chiton in ~comp.advent_of_code

    kari
    Link Parent
    Another thing you can do to make a min-heap in Rust is make it of type BinaryHeap<Reverse<your dat>> and then push like heap.push(Reverse(data)) and do the same when popping. With something like...

    Another thing you can do to make a min-heap in Rust is make it of type BinaryHeap<Reverse<your dat>> and then push like heap.push(Reverse(data)) and do the same when popping. With something like this where you have to implement Ord on your own anyways it's definitely easier to just do that backwards like you did

    3 votes
  16. Comment on Day 14: Extended Polymerization in ~comp.advent_of_code

    kari
    Link
    Rust Did part 1 with brute force because I wanted to get the first star in (even though I guess what part 2 would be and assumed brute force wouldn't work for it). Eventually figured out how to...

    Rust

    Did part 1 with brute force because I wanted to get the first star in (even though I guess what part 2 would be and assumed brute force wouldn't work for it). Eventually figured out how to refactor for part 2.

    Part 1 (before refactor)
    use crate::lib::aoc;
    use std::collections::HashMap;
    
    pub fn run() {
        let lines = aoc::get_lines("./inputs/day14.in");
        let template = lines[0].clone();
        let rules: HashMap<String, String> =
            lines[2..].iter().fold(HashMap::new(), |mut rules, line| {
                if let Some((pair, insertion)) = line.split_once(" -> ") {
                    rules.insert(pair.to_owned(), insertion.to_owned());
                }
                rules
            });
    
        // Part 1
        let mut polymer = template;
        for _ in 0..10 {
            let mut polymer_chars = polymer.chars().peekable();
            let mut new_polymer = String::new();
            for i in 0..polymer.len() {
                let ith_char = polymer_chars.next().unwrap();
                new_polymer.push(ith_char);
    
                if i + 1 < polymer.len() {
                    new_polymer.push_str(
                        rules
                            .get(&format!("{}{}", ith_char, polymer_chars.peek().unwrap()))
                            .expect("Missing some rule!"),
                    );
                }
            }
            polymer = new_polymer;
        }
    
        let mut result_p1: Vec<u32> = polymer
            .chars()
            .fold(HashMap::<char, u32>::new(), |mut accum, element| {
                let count = accum.get(&element).unwrap_or(&0) + 1;
                accum.insert(element, count);
    
                accum
            })
            .values()
            .cloned()
            .collect();
        result_p1.sort_unstable();
    
        let result_p1 = result_p1.last().unwrap() - result_p1[0];
    
        aoc::output(14, "result", result_p1, 0);
    }
    
    Both Parts (after refactor)
    use crate::lib::aoc;
    use std::collections::HashMap;
    
    fn do_steps(
        rules: &HashMap<String, char>,
        polymer: HashMap<(char, char), u64>,
        mut ends_with: (char, char),
    ) -> (HashMap<(char, char), u64>, (char, char)) {
        let mut new_polymer = HashMap::new();
        for (pair, count) in &polymer {
            let new_char = *rules
                .get(&format!("{}{}", pair.0, pair.1))
                .expect("Missing some rule!");
    
            // Now we can make two pairs
            let new_pair1 = (pair.0, new_char);
            let new_pair2 = (new_char, pair.1);
            new_polymer.insert(new_pair1, new_polymer.get(&new_pair1).unwrap_or(&0) + count);
            new_polymer.insert(new_pair2, new_polymer.get(&new_pair2).unwrap_or(&0) + count);
    
            if *pair == ends_with {
                ends_with = new_pair2;
            }
        }
        (new_polymer, ends_with)
    }
    
    fn get_result(polymer: &HashMap<(char, char), u64>, ends_with: &(char, char)) -> u64 {
        let mut count_vec: Vec<u64> = polymer
            .iter()
            .fold(
                HashMap::<char, u64>::new(),
                |mut accum, ((ith_char, jth_char), pair_count)| {
                    let ith_char_count = accum.get(ith_char).unwrap_or(&0) + pair_count;
                    let jth_char_count = accum.get(jth_char).unwrap_or(&0) + 1;
    
                    if (*ith_char, *jth_char) == *ends_with {
                        accum.insert(*ith_char, ith_char_count);
                        accum.insert(*jth_char, jth_char_count);
                    } else {
                        accum.insert(*ith_char, ith_char_count);
                    }
    
                    accum
                },
            )
            .values()
            .cloned()
            .collect();
        count_vec.sort_unstable();
    
        count_vec.last().unwrap() - count_vec[0]
    }
    
    pub fn run() {
        // Parse the input
        let lines = aoc::get_lines("./inputs/day14.in");
        let template = lines[0].clone();
        let rules: HashMap<String, char> = lines[2..].iter().fold(HashMap::new(), |mut rules, line| {
            if let Some((pair, insertion)) = line.split_once(" -> ") {
                rules.insert(
                    pair.to_owned(),
                    insertion.chars().next().expect("Some rule is invalid!"),
                );
            }
            rules
        });
    
        // Set up the polymer HashMap
        let mut template_chars = template.chars().peekable();
        let mut polymer: HashMap<(char, char), u64> = HashMap::new();
        let mut ends_with: (char, char) = ('0', '0');
        for i in 0..template.len() - 1 {
            let ith_char = template_chars.next().unwrap();
            let jth_char = *template_chars.peek().unwrap();
            let pair = (ith_char, jth_char);
            polymer.insert(pair, polymer.get(&pair).unwrap_or(&0) + 1);
    
            // We need to keep track of the ending pairs so that we can count chars correctly
            if i == template.len() - 2 {
                ends_with = pair;
            }
        }
    
        // ~~~ Part 1 ~~~
        for _ in 0..10 {
            let (new_polymer, new_ends_with) = do_steps(&rules, polymer.clone(), ends_with);
            polymer = new_polymer;
            ends_with = new_ends_with;
        }
    
        let result_p1 = get_result(&polymer, &ends_with);
    
        // ~~~ Part 2 ~~~
        for _ in 10..40 {
            let (new_polymer, new_ends_with) = do_steps(&rules, polymer.clone(), ends_with);
            polymer = new_polymer;
            ends_with = new_ends_with;
        }
        let result_p2 = get_result(&polymer, &ends_with);
    
        aoc::big_output(14, "result", result_p1, result_p2);
    }
    
    Discussion(?)

    I could probably make it run a bit faster (not that it's particularly slow right) if I passed the number of steps to my do_steps function and iterated there so that I didn't have to pass the map to the function so much.

    I guess I could also just keep track of the very last letter and add a count of 1 for that letter instead of keeping track of the last pair.

    2 votes
  17. Comment on Day 14: Extended Polymerization in ~comp.advent_of_code

    kari
    Link Parent
    Relatable :P

    Since it took me so long, today's code is even less clean than usually.

    Relatable :P

    1 vote
  18. Comment on Day 13: Transparent Origami in ~comp.advent_of_code

    kari
    Link
    Rust Today wasn't too bad but I spent an embarrassingly long amount of time trying to figure out the relation for which spots on the right/bottom map to which spots on the left/top after a fold....

    Rust

    Today wasn't too bad but I spent an embarrassingly long amount of time trying to figure out the relation for which spots on the right/bottom map to which spots on the left/top after a fold.

    Rust (both days)

    I definitely could clean my code up quite a bit but it works so, eh, maybe later :).

    use crate::lib::aoc;
    use std::{
        cmp::Ordering,
        collections::VecDeque,
        fmt::{Display, Formatter, Result},
        ops::{BitOr, BitOrAssign},
    };
    
    type Paper = Vec<Vec<PaperSpot>>;
    
    #[derive(Debug, Copy, Clone)]
    enum Fold {
        Up(usize),
        Left(usize),
        Invalid,
    }
    
    #[derive(Debug, Copy, Clone, PartialEq, Eq)]
    enum PaperSpot {
        Dot,
        Empty,
    }
    
    impl Display for PaperSpot {
        fn fmt(&self, f: &mut Formatter) -> Result {
            write!(
                f,
                "{}",
                match self {
                    PaperSpot::Dot => '#',
                    PaperSpot::Empty => '.',
                }
            )
        }
    }
    
    impl BitOr for PaperSpot {
        type Output = Self;
    
        fn bitor(self, rhs: Self) -> Self::Output {
            match self == PaperSpot::Dot || rhs == PaperSpot::Dot {
                true => PaperSpot::Dot,
                false => PaperSpot::Empty,
            }
        }
    }
    
    impl BitOrAssign for PaperSpot {
        fn bitor_assign(&mut self, rhs: Self) {
            match *self == PaperSpot::Dot || rhs == PaperSpot::Dot {
                true => *self = PaperSpot::Dot,
                false => *self = PaperSpot::Empty,
            }
        }
    }
    
    fn new_paper(num_rows: usize, num_cols: usize) -> Paper {
        vec![vec![PaperSpot::Empty; num_cols]; num_rows]
    }
    
    fn fold_paper(paper: Paper, fold: Fold) -> Paper {
        match fold {
            Fold::Up(fold_row) => {
                let mut folded_paper = new_paper(paper.len() / 2, paper[0].len());
                for row in 0..paper.len() {
                    for col in 0..paper[row].len() {
                        match row.cmp(&fold_row) {
                            Ordering::Greater => {
                                folded_paper[paper.len() - 1 - row][col] |= paper[row][col]
                            }
                            Ordering::Less => folded_paper[row][col] |= paper[row][col],
                            Ordering::Equal => { /* If it's equal, this row is *on* the fold line so we can skip it*/
                            }
                        }
                    }
                }
                folded_paper
            }
            Fold::Left(fold_col) => {
                let mut folded_paper = new_paper(paper.len(), paper[0].len() / 2);
                for row in 0..paper.len() {
                    for col in 0..paper[row].len() {
                        match col.cmp(&fold_col) {
                            Ordering::Greater => {
                                folded_paper[row][paper[0].len() - 1 - col] |= paper[row][col]
                            }
                            Ordering::Less => folded_paper[row][col] |= paper[row][col],
                            Ordering::Equal => { /* If it's equal, this col is *on* the fold line so we can skip it*/
                            }
                        }
                    }
                }
                folded_paper
            }
            Fold::Invalid => {
                eprintln!("Tried to fold an invalid fold! Ignoring...");
                paper.to_vec()
            }
        }
    }
    
    fn display_paper(paper: Paper) {
        for row in paper {
            for paper_spot in row {
                print!("{}", paper_spot)
            }
            println!()
        }
        println!()
    }
    
    fn count_dots(paper: Paper) -> u32 {
        let mut num_dots = 0;
    
        for row in paper {
            for paper_spot in row {
                if let PaperSpot::Dot = paper_spot {
                    num_dots += 1
                };
            }
        }
    
        num_dots
    }
    
    pub fn run() {
        let lines = aoc::get_lines("./inputs/day13.in");
    
        let (num_rows, num_cols) =
            lines
                .iter()
                .take_while(|line| line.contains(','))
                .fold((0, 0), |(max_y, max_x), line| {
                    let (x, y): (usize, usize) = match line.split_once(',') {
                        Some((x, y)) => (
                            x.parse().expect("Some x val is wrong!"),
                            y.parse().expect("Some y val is wrong!"),
                        ),
                        None => panic!("One of your dot lines is entered incorrectly!"),
                    };
    
                    // Add 1 to x and y since x and y are indices but max_x and max_y are number of
                    // cols/rows
                    (usize::max(y + 1, max_y), usize::max(x + 1, max_x))
                });
    
        let (paper, mut folds): (Paper, VecDeque<Fold>) = lines.iter().fold(
            (new_paper(num_rows, num_cols), VecDeque::new()),
            |(mut paper, mut folds), line| {
                if let Some((x, y)) = line.split_once(',') {
                    // We already did the expects up there ^^
                    let col: usize = x.parse().unwrap();
                    let row: usize = y.parse().unwrap();
                    paper[row][col] = PaperSpot::Dot;
                } else if line.starts_with("fold along") {
                    if let Some((axis, index)) = line
                        .split(' ')
                        .nth(2)
                        .expect("One of your fold lines is entered incorrectly!")
                        .split_once('=')
                    {
                        let index: usize = index.parse().unwrap();
                        let fold = match axis {
                            "y" => Fold::Up(index),
                            "x" => Fold::Left(index),
                            _ => {
                                eprintln!("Your input file has an invalid fold! Ignoring...");
                                Fold::Invalid
                            }
                        };
    
                        folds.push_back(fold);
                    }
                }
    
                (paper, folds)
            },
        );
    
        // Do the first fold for part 1
        let paper_p1 = fold_paper(paper, folds.pop_front().expect("No folds in your input!"));
    
        // Finish folding then display the paper for part 2
        let mut paper = paper_p1.clone();
        while let Some(fold) = folds.pop_front() {
            paper = fold_paper(paper, fold);
        }
    
        aoc::output(13, "num dots", count_dots(paper_p1), 0);
        display_paper(paper);
        println!();
    
    }
    
    3 votes
  19. Comment on Day 11: Dumbo Octopus in ~comp.advent_of_code

    kari
    Link
    Rust Not too bad, but I could've written this cleaner. Structs use std::fmt::{Display, Formatter, Result}; #[derive(Debug)] struct Row { row: Vec<u32>, } #[derive(Debug)] pub struct Map { rows:...

    Rust
    Not too bad, but I could've written this cleaner.

    Structs
    use std::fmt::{Display, Formatter, Result};
    
    #[derive(Debug)]
    struct Row {
        row: Vec<u32>,
    }
    
    #[derive(Debug)]
    pub struct Map {
        rows: Vec<Row>,
        num_flashes: u32,
    }
    
    impl From<&String> for Row {
        fn from(row: &String) -> Self {
            let row = row.chars().fold(Vec::new(), |mut accum, cur| {
                accum.push(cur.to_digit(10).expect("Failed to convert a char to u32!"));
                accum
            });
    
            Row { row }
        }
    }
    
    impl From<Vec<String>> for Map {
        fn from(lines: Vec<String>) -> Self {
            let rows = lines.iter().map(Row::from).collect();
    
            Map {
                rows,
                num_flashes: 0,
            }
        }
    }
    
    impl Display for Row {
        fn fmt(&self, f: &mut Formatter) -> Result {
            for octopus in &self.row {
                if let Err(e) = write!(f, "{}", octopus) {
                    return Err(e);
                }
            }
            writeln!(f)
        }
    }
    
    impl Display for Map {
        fn fmt(&self, f: &mut Formatter) -> Result {
            for row in &self.rows {
                if let Err(e) = write!(f, "{}", row) {
                    return Err(e);
                }
            }
            writeln!(f)
        }
    }
    
    impl Row {
        fn len(&self) -> usize {
            self.row.len()
        }
    
        /// Returns a Vec of any indices that hit 9, i.e. indices that will flash
        fn step(&mut self) -> Vec<usize> {
            let mut flashing_cols = Vec::new();
    
            for col in 0..self.len() {
                self.row[col] += 1;
                if self.row[col] == 10 {
                    flashing_cols.push(col);
                }
            }
            flashing_cols
        }
    
        /// Returns a Vec of any indices that hit 9, i.e. indices that will flash
        fn flash(&mut self, col: isize) -> Vec<usize> {
            let mut flashing_cols = Vec::new();
    
            if col >= 0 && col < self.len() as isize {
                let col = col as usize;
                self.row[col] += 1;
                if self.row[col] == 10 {
                    flashing_cols.push(col);
                }
            }
    
            flashing_cols
        }
    
        /// Zero-out a flashed coordinate
        fn reset_coord(&mut self, col: usize) {
            self.row[col] = 0;
        }
    }
    
    impl Map {
        /**
         * Complete one step of the map.
         *
         * Returns an bool which is true if the flashes synchronize, else false
         **/
        pub fn step(&mut self) -> bool {
            let mut flashing_coords: Vec<(usize, usize)> = Vec::new();
            let mut flashed_coords: Vec<(usize, usize)> = Vec::new();
    
            // Get any coords that flash during the initial step
            for row in 0..self.rows.len() {
                let flashing_cols = self.rows[row].step();
                self.num_flashes += flashing_cols.len() as u32;
                let mut flashing_cols = flashing_cols.iter().map(|col| (row, *col)).collect();
                flashing_coords.append(&mut flashing_cols);
            }
    
            // While we still have newly flashed coords, flash its neighbors
            while let Some((row, col)) = flashing_coords.pop() {
                flashed_coords.push((row, col));
    
                for row_offset in [-1, 0, 1] {
                    if row as isize + row_offset >= 0
                        && row as isize + row_offset < self.rows.len() as isize
                    {
                        let row = (row as isize + row_offset) as usize;
                        for col_offset in [-1, 0, 1] {
                            let flashing_cols = self.rows[row].flash(col as isize + col_offset);
                            self.num_flashes += flashing_cols.len() as u32;
                            let mut flashing_cols =
                                flashing_cols.iter().map(|col| (row, *col)).collect();
                            flashing_coords.append(&mut flashing_cols);
                        }
                    }
                }
            }
    
            for (row, col) in &flashed_coords {
                self.rows[*row].reset_coord(*col);
            }
    
            // We can assume that the map is always a rectangle, so the flashes synchronize if
            // flashed_coords.len() == num rows * num cols
            flashed_coords.len() == self.rows.len() * self.rows[0].len()
        }
    
        pub fn get_num_flashes(&self) -> u32 {
            self.num_flashes
        }
    }
    
    Solution
    mod map;
    use crate::lib::aoc;
    use map::Map;
    
    pub fn run() {
        let mut map = Map::from(aoc::get_lines("./inputs/day11.in"));
    
        let mut first_synchronization: u32 = 0;
        let mut first_synchronization_found = false;
        // We need specifically through 100 steps for part 1
        for i in 0..100 {
            first_synchronization_found = map.step();
            if first_synchronization_found {
                first_synchronization = i;
            }
        }
        let num_flashes_p1 = map.get_num_flashes();
    
        if !first_synchronization_found {
            for i in 101.. {
                first_synchronization_found = map.step();
                if first_synchronization_found {
                    first_synchronization = i;
                    break;
                }
            }
        }
    
        aoc::output(11, "num flashes", num_flashes_p1, first_synchronization);
    }
    
    2 votes