187 lines
6.1 KiB
Rust
187 lines
6.1 KiB
Rust
mod arcade;
|
|
mod args;
|
|
#[cfg(test)]
|
|
mod chemistry;
|
|
mod fuel;
|
|
mod image;
|
|
mod machine;
|
|
#[cfg(test)]
|
|
mod nbody;
|
|
mod orbits;
|
|
#[cfg(test)]
|
|
mod repair;
|
|
#[cfg(test)]
|
|
mod robot;
|
|
#[cfg(test)]
|
|
mod router;
|
|
#[cfg(test)]
|
|
mod scaffold;
|
|
#[cfg(test)]
|
|
mod spring;
|
|
#[cfg(test)]
|
|
mod station;
|
|
#[cfg(test)]
|
|
mod tractor;
|
|
mod wiremap;
|
|
|
|
use crate::args::Command;
|
|
use crate::fuel::calculate_fuel;
|
|
use crate::orbits::Object;
|
|
use crate::wiremap::WireMap;
|
|
use std::cmp::{max,min};
|
|
use terminal_graphics::Display;
|
|
|
|
fn main() {
|
|
match Command::get() {
|
|
Command::ComputeFuel(masses) => {
|
|
let mut total = 0;
|
|
|
|
for mass in masses {
|
|
let fuel = calculate_fuel(mass);
|
|
println!("Mass {}: {} fuel", mass, fuel);
|
|
total += fuel;
|
|
}
|
|
|
|
println!("TOTAL FUEL: {}", total);
|
|
}
|
|
|
|
Command::RunComputer(initial) => {
|
|
println!("Initial Computer:");
|
|
initial.show();
|
|
println!("Running, with input 5.");
|
|
let results = initial.standard_run(&[5]);
|
|
for val in results.iter() {
|
|
println!("Received value: {}", val);
|
|
}
|
|
}
|
|
|
|
Command::WireMap(wires) => {
|
|
let mut wiremap = WireMap::new();
|
|
|
|
for (num, wire) in wires.iter().enumerate() {
|
|
wiremap.add_wire(wire, num);
|
|
}
|
|
|
|
let (target, distance) = wiremap.closest_intersection();
|
|
println!("Closest intersection: ({}, {}) [distance {}]",
|
|
target.0, target.1, distance);
|
|
|
|
let mut best_total_steps = usize::max_value();
|
|
|
|
for (target_num, join_point) in wiremap.joins().iter().enumerate() {
|
|
let mut total_steps = 0;
|
|
|
|
for (num, wire) in wires.iter().enumerate() {
|
|
let wire_steps = wiremap.steps_to(wire, *join_point);
|
|
println!("Wire #{} takes {} steps to target #{}.", num, wire_steps, target_num);
|
|
total_steps += wire_steps;
|
|
}
|
|
|
|
if total_steps < best_total_steps {
|
|
best_total_steps = total_steps;
|
|
}
|
|
}
|
|
|
|
println!("Total steps taken: {}", best_total_steps);
|
|
}
|
|
|
|
Command::PasswordCrack(start, end) => {
|
|
let mut count = 0;
|
|
let first = max(start, 100000);
|
|
let last = min(end, 999999);
|
|
|
|
for cur in first..last {
|
|
let d0 = cur % 10;
|
|
let d1 = (cur / 10) % 10;
|
|
let d2 = (cur / 100) % 10;
|
|
let d3 = (cur / 1000) % 10;
|
|
let d4 = (cur / 10000) % 10;
|
|
let d5 = (cur / 100000) % 10;
|
|
|
|
if d5 > d4 { continue; }
|
|
if d4 > d3 { continue; }
|
|
if d3 > d2 { continue; }
|
|
if d2 > d1 { continue; }
|
|
if d1 > d0 { continue; }
|
|
|
|
let mut got_double = false;
|
|
if d0 == d1 { got_double |= !( d1 == d2 ); }
|
|
if d1 == d2 { got_double |= !((d0 == d1) || (d2 == d3)); }
|
|
if d2 == d3 { got_double |= !((d1 == d2) || (d3 == d4)); }
|
|
if d3 == d4 { got_double |= !((d2 == d3) || (d4 == d5)); }
|
|
if d4 == d5 { got_double |= !( d3 == d4 ); }
|
|
|
|
if got_double {
|
|
count += 1;
|
|
println!("{} is a possibility [total {}]", cur, count);
|
|
}
|
|
}
|
|
|
|
// 353 is wrong (low)
|
|
println!("Successful digits: {}", count);
|
|
}
|
|
|
|
Command::Orbits(uom) => {
|
|
println!("Got orbits:");
|
|
uom.show();
|
|
println!("Base map has {} orbits.", uom.num_orbits());
|
|
match uom.find_path(&Object::new("YOU"), &Object::new("SAN")) {
|
|
None =>
|
|
println!("There is no path from you to Santa. :("),
|
|
Some(path) => {
|
|
print!("The path from you to Santa is: ");
|
|
let mut path_iter = path.iter().peekable();
|
|
|
|
while let Some(x) = path_iter.next() {
|
|
print!("{}", x);
|
|
if path_iter.peek().is_some() {
|
|
print!(" => ");
|
|
}
|
|
}
|
|
println!("");
|
|
println!(" ... so the number of transfers needed is {}", path.len() - 3);
|
|
}
|
|
}
|
|
}
|
|
|
|
Command::Amplify(computer) => {
|
|
let (amount_a, settings_a) = computer.find_best_signal(0..5, |x| computer.serialize(x));
|
|
println!("Best signal without loopback is {} @ {:?}", amount_a, settings_a);
|
|
let (amount_b, settings_b) = computer.find_best_signal(5..10, |x| computer.amplifier(x));
|
|
println!("Best signal with loopback is {} @ {:?}", amount_b, settings_b);
|
|
}
|
|
|
|
Command::Image(image) => {
|
|
let zero_byte_counts = image.digits_per_layer(0);
|
|
let mut lowest_score = usize::max_value();
|
|
let mut lowest_idx = 0;
|
|
|
|
for (idx, layer_count) in zero_byte_counts.iter().enumerate() {
|
|
if layer_count < &lowest_score {
|
|
lowest_score = *layer_count;
|
|
lowest_idx = idx;
|
|
}
|
|
}
|
|
|
|
println!("Fewest number of zeros at layer {} [{} zeros]", lowest_idx, lowest_score);
|
|
let one_digits = image.digits_for_layer(lowest_idx, 1);
|
|
println!("Layer {} has {} one digits.", lowest_idx, one_digits);
|
|
let two_digits = image.digits_for_layer(lowest_idx, 2);
|
|
println!("Layer {} has {} two digits.", lowest_idx, two_digits);
|
|
println!("Multiplied together is {}", one_digits * two_digits);
|
|
image.draw();
|
|
}
|
|
|
|
Command::Arcade(arcade) => {
|
|
let mut screen = Display::new(40, 40);
|
|
|
|
screen.clear();
|
|
let result = arcade.run(move |a| {
|
|
a.draw(&mut screen);
|
|
screen.print();
|
|
});
|
|
println!("Final score: {}", result.score);
|
|
}
|
|
}
|
|
}
|