1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Advent of Code 2025 Day 4: Printing Department をRustで解いた

Last updated at Posted at 2025-12-07

Advent of Code

毎日2題出題されます。競技プログラミングチックに楽しめます。

この問題概要と実装解答を以下にご紹介します。
問題概要は生成AIに書いてもらったものを貼り付けています。
実装は人間が行なっています。

Day 4: Printing Department

part1 問題概要

  • 紙のロール(@)が、2次元グリッド状に並んでいる。
  • 入力は、. と @ からなる複数行の図。@ = 紙のロール. = 何もない
  • 各ロール(@)について、その8近傍の中にある @ の数が 4 未満ならそのロールはフォークリフトがアクセス可能。このロールの個数を数えて

解答

全探索。

use std::{cmp::max, collections::HashSet};

use itertools::Itertools;
use proconio::{input, marker::Chars};


fn main() {
    let h = 139;
    input! {
        s: [Chars; h]
    }
    let w = s[0].len();
    let didj = vec![(-1, -1), (-1, 0), (-1, 1), (0, -1), (0, 1), (1, -1), (1, 0), (1, 1)];
    let mut ans = 0;
    for i in 0..h {
        for j in 0..w {
            if s[i][j] != '@' {
                continue;
            }
            let mut count = 0;
            for &(di, dj) in didj.iter() {
                let ni = i as isize + di;
                let nj = j as isize + dj;
                if ni < 0 || ni >= h as isize || nj < 0 || nj >= w as isize {
                    continue;
                }
                let ni = ni as usize;
                let nj = nj as usize;
                if s[ni][nj] == '@' {
                    count += 1usize;
                }
            }
            if count < 4 {
                ans += 1usize;
            }
        }
    }
    println!("{}", ans);
}

part2 問題概要

  • 現在のグリッドで、周囲8マスの @ が 4 未満のロール(アクセス可能)を全部探す。
  • それらを. に変える
  • 取り除かれたことで、また周りのロールの「隣接 @ の数」が変わるので、再び 1 に戻って「新しくアクセス可能になったロール」を探す。
  • これ以上アクセス可能なロールが無くなるまで繰り返す。

その間に取り除かれた @ の 総数 が答え。

解答

とれるものは取っておいて損はないのでどんどん取っていく。
あるますを取り除いた時の影響範囲は8近傍しかないので、BFSして近傍4つ未満になったロールをどんどん取っていくことで答え。

fn main() {
    let h = 139;
    input! {
        s: [Chars; h]
    }
    let w = s[0].len();
    let didj = vec![(-1, -1), (-1, 0), (-1, 1), (0, -1), (0, 1), (1, -1), (1, 0), (1, 1)];
    let mut ans = vec![vec![false; w]; h];
    let mut c = vec![vec![0; w]; h];
    let mut que = VecDeque::new();
    for i in 0..h {
        for j in 0..w {
            if s[i][j] != '@' {
                continue;
            }
            let mut count = 0;
            for &(di, dj) in didj.iter() {
                let ni = i as isize + di;
                let nj = j as isize + dj;
                if ni < 0 || ni >= h as isize || nj < 0 || nj >= w as isize {
                    continue;
                }
                let ni = ni as usize;
                let nj = nj as usize;
                if s[ni][nj] == '@' {
                    count += 1usize;
                }
            }
            c[i][j] = count;
            if count < 4 {
                que.push_back((i, j));
                ans[i][j] = true;
            }
        }
    }
    while !que.is_empty() {
        let (i, j) = que.pop_front().unwrap();
        for &(di, dj) in didj.iter() {
            let ni = i as isize + di;
            let nj = j as isize + dj;
            if ni < 0 || ni >= h as isize || nj < 0 || nj >= w as isize {
                continue;
            }
            let ni = ni as usize;
            let nj = nj as usize;
            if ans[ni][nj] || c[ni][nj] == 0 || s[ni][nj] == '.' {
                continue;
            }
            c[ni][nj] -= 1;
            if c[ni][nj] < 4 {
                ans[ni][nj] = true;
                que.push_back((ni, nj));
            }
        }
    }
    let ans = ans.iter().flatten().filter(|&&e|e).count();
    println!("{}", ans);
}

終わりに

Day5も頑張ります!

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?