1use super::intcode::*;
5use crate::util::grid::*;
6use crate::util::hash::*;
7use crate::util::parse::*;
8use crate::util::point::*;
9
10pub fn parse(input: &str) -> Vec<i64> {
11 input.iter_signed().collect()
12}
13
14pub fn part1(input: &[i64]) -> usize {
15 paint(input, 0).len()
16}
17
18pub fn part2(input: &[i64]) -> String {
19 let hull = paint(input, 1);
20
21 let panels: Vec<_> = hull.iter().filter(|&(_, &v)| v == 1).map(|(&k, _)| k).collect();
23
24 let (x1, x2, y1, y2) = panels.iter().fold(
26 (i32::MAX, i32::MIN, i32::MAX, i32::MIN),
27 |(min_x, max_x, min_y, max_y), p| {
28 (min_x.min(p.x), max_x.max(p.x), min_y.min(p.y), max_y.max(p.y))
29 },
30 );
31
32 let width = x2 - x1 + 2; let height = y2 - y1 + 1;
35 let mut image = Grid::new(width, height, b'.');
36
37 let offset = Point::new(x1 - 1, y1);
38 panels.iter().for_each(|&point| image[point - offset] = b'#');
39
40 (0..height).for_each(|y| image[Point::new(0, y)] = b'\n');
41
42 String::from_utf8(image.bytes).unwrap()
43}
44
45fn paint(input: &[i64], initial: i64) -> FastMap<Point, i64> {
46 let mut computer = Computer::new(input);
47 let mut position = ORIGIN;
48 let mut direction = UP;
49 let mut hull = FastMap::with_capacity(5_000);
50
51 hull.insert(position, initial);
52
53 loop {
54 let panel = hull.entry(position).or_default();
55 computer.input(*panel);
56
57 match computer.run() {
58 State::Output(color) => {
59 *panel = color;
60 }
61 _ => break,
62 }
63
64 match computer.run() {
65 State::Output(next) => {
66 direction =
67 if next == 0 { direction.counter_clockwise() } else { direction.clockwise() };
68 position += direction;
69 }
70 _ => break,
71 }
72 }
73
74 hull
75}