summaryrefslogtreecommitdiff
path: root/2019/src/bin/day_25.rs
blob: 522789e01baa983949db2ff45a1f950f94d306a1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
use aoc2019::*;
use std::io;
use std::io::prelude::*;
use std::process;
use structopt::StructOpt;

#[derive(Debug, StructOpt)]
#[structopt(name = "Day 25: Cryostasis")]
/// Pilots a robot to save Santa!
///
/// See https://adventofcode.com/2019/day/25 for details.
struct Opt {}

fn main() {
    let stdin = io::stdin();
    let _opt = Opt::from_args();

    let program: IntcodeProgram = stdin
        .lock()
        .split(b',')
        .map(|x| exit_on_failed_assertion(x, "Error reading input"))
        .map(|x| exit_on_failed_assertion(String::from_utf8(x), "Input was not valid UTF-8"))
        .map(|x| exit_on_failed_assertion(x.trim().parse::<Intcode>(), "Invalid number"))
        .collect::<IntcodeProgram>();

    let input = vec![
        "east",
        "take antenna",
        "west",
        "north",
        "take weather machine",
        "north",
        "take klein bottle",
        "east",
        "take spool of cat6",
        "east",
        "south",
        "take mug",
        "north",
        "north",
        "west",
        "north",
        "take cake",
        "south",
        "east",
        "east",
        "north",
        "north",
        "take tambourine",
        "south",
        "south",
        "south",
        "take shell",
        "north",
        "west",
        "south",
        "west",
        "south",
        "south",
        "inv",
        //"drop mug",
        //"drop weather machine",
        "drop cake",
        "drop shell",
        "drop klein bottle",
        "drop tambourine",
        //"drop antenna",
        //"drop spool of cat6",
        "east",
    ];

    let result = exit_on_failed_assertion(
        program
            .with_input(
                input
                    .iter()
                    .flat_map(|line| {
                        line.chars()
                            .map(|c| Intcode::from(c as u8))
                            .chain(vec![Intcode::from(10)].into_iter())
                    })
                    .collect(),
            )
            .run_to_termination_or_input()
            .output_into_result(),
        "Program failed",
    );

    println!(
        "{}",
        result
            .drop_last()
            .unwrap()
            .iter()
            .flat_map(|c| c.to_signed_bytes_be())
            .map(|c| c as char)
            .collect::<String>()
    );
    println!("{}", result.last().unwrap());
}

fn exit_on_failed_assertion<A, E: std::error::Error>(data: Result<A, E>, message: &str) -> A {
    match data {
        Ok(data) => data,
        Err(e) => {
            eprintln!("{}: {}", message, e);
            process::exit(1);
        }
    }
}