2016/11
This commit is contained in:
4
2016/11/Cargo.lock
generated
Normal file
4
2016/11/Cargo.lock
generated
Normal file
@@ -0,0 +1,4 @@
|
||||
[root]
|
||||
name = "11"
|
||||
version = "0.1.0"
|
||||
|
||||
6
2016/11/Cargo.toml
Normal file
6
2016/11/Cargo.toml
Normal file
@@ -0,0 +1,6 @@
|
||||
[package]
|
||||
name = "11"
|
||||
version = "0.1.0"
|
||||
authors = ["logaritmisk <anders.e.olsson@gmail.com>"]
|
||||
|
||||
[dependencies]
|
||||
4
2016/11/example.txt
Normal file
4
2016/11/example.txt
Normal file
@@ -0,0 +1,4 @@
|
||||
The first floor contains a hydrogen-compatible microchip and a lithium-compatible microchip.
|
||||
The second floor contains a hydrogen generator.
|
||||
The third floor contains a lithium generator.
|
||||
The fourth floor contains nothing relevant.
|
||||
4
2016/11/input.txt
Normal file
4
2016/11/input.txt
Normal file
@@ -0,0 +1,4 @@
|
||||
The first floor contains a thulium generator, a thulium-compatible microchip, a plutonium generator, and a strontium generator.
|
||||
The second floor contains a plutonium-compatible microchip and a strontium-compatible microchip.
|
||||
The third floor contains a promethium generator, a promethium-compatible microchip, a ruthenium generator, and a ruthenium-compatible microchip.
|
||||
The fourth floor contains nothing relevant.
|
||||
399
2016/11/src/main.rs
Normal file
399
2016/11/src/main.rs
Normal file
@@ -0,0 +1,399 @@
|
||||
use std::collections::HashSet;
|
||||
|
||||
|
||||
type Floor = usize;
|
||||
|
||||
|
||||
#[derive(Debug, Clone, Hash, Eq, PartialEq)]
|
||||
pub struct Facility {
|
||||
elevator: Floor,
|
||||
components: Vec<(Floor, Floor)>,
|
||||
top_floor: Floor
|
||||
}
|
||||
|
||||
impl Facility {
|
||||
pub fn new(elevator: Floor, top_floor: Floor) -> Self {
|
||||
Facility {
|
||||
elevator: elevator,
|
||||
components: Vec::new(),
|
||||
top_floor: top_floor - 1
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_done(&self) -> bool {
|
||||
if self.elevator != self.top_floor {
|
||||
return false;
|
||||
}
|
||||
|
||||
for &(g, m) in self.components.iter() {
|
||||
if g != self.top_floor {
|
||||
return false;
|
||||
}
|
||||
|
||||
if m != self.top_floor {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
pub fn validate(&self) -> bool {
|
||||
let mut generators = HashSet::new();
|
||||
let mut microchips = HashSet::new();
|
||||
|
||||
for (i, &(g, m)) in self.components.iter().enumerate() {
|
||||
if g == self.elevator {
|
||||
generators.insert(i);
|
||||
}
|
||||
if m == self.elevator {
|
||||
microchips.insert(i);
|
||||
}
|
||||
}
|
||||
|
||||
if !generators.is_empty() {
|
||||
let diff = microchips.difference(&generators).collect::<Vec<_>>();
|
||||
|
||||
if !diff.is_empty() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
pub fn steps(&self) -> Vec<Facility> {
|
||||
let mut variants = Vec::new();
|
||||
|
||||
for (i, &(g, m)) in self.components.iter().enumerate() {
|
||||
if self.elevator < self.top_floor {
|
||||
if g == self.elevator {
|
||||
let mut variant = self.clone();
|
||||
|
||||
variant.elevator += 1;
|
||||
|
||||
variant.components[i].0 += 1;
|
||||
|
||||
if variant.validate() {
|
||||
variants.push(variant);
|
||||
}
|
||||
}
|
||||
|
||||
if m == self.elevator {
|
||||
let mut variant = self.clone();
|
||||
|
||||
variant.elevator += 1;
|
||||
|
||||
variant.components[i].1 += 1;
|
||||
|
||||
if variant.validate() {
|
||||
variants.push(variant);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if self.elevator > 0 {
|
||||
if g == self.elevator {
|
||||
let mut variant = self.clone();
|
||||
|
||||
variant.elevator -= 1;
|
||||
|
||||
variant.components[i].0 -= 1;
|
||||
|
||||
if variant.validate() {
|
||||
variants.push(variant);
|
||||
}
|
||||
}
|
||||
|
||||
if m == self.elevator {
|
||||
let mut variant = self.clone();
|
||||
|
||||
variant.elevator -= 1;
|
||||
|
||||
variant.components[i].1 -= 1;
|
||||
|
||||
if variant.validate() {
|
||||
variants.push(variant);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let mut components = self.components.iter().enumerate()
|
||||
.flat_map(|(i, &(g, m))| vec![(i, 0, g), (i, 1, m)].into_iter())
|
||||
.filter(|&(_, _, f)| f == self.elevator)
|
||||
.map(|(i, c, _)| (i, c))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
while !components.is_empty() {
|
||||
let a = components.remove(0);
|
||||
|
||||
for b in components.iter() {
|
||||
if self.elevator < self.top_floor {
|
||||
let mut variant = self.clone();
|
||||
|
||||
variant.elevator += 1;
|
||||
|
||||
match a.1 {
|
||||
0 => variant.components[a.0].0 += 1,
|
||||
1 => variant.components[a.0].1 += 1,
|
||||
_ => unreachable!()
|
||||
}
|
||||
|
||||
match b.1 {
|
||||
0 => variant.components[b.0].0 += 1,
|
||||
1 => variant.components[b.0].1 += 1,
|
||||
_ => unreachable!()
|
||||
}
|
||||
|
||||
if variant.validate() {
|
||||
variants.push(variant);
|
||||
}
|
||||
}
|
||||
|
||||
if self.elevator > 0 {
|
||||
let mut variant = self.clone();
|
||||
|
||||
variant.elevator -= 1;
|
||||
|
||||
match a.1 {
|
||||
0 => variant.components[a.0].0 -= 1,
|
||||
1 => variant.components[a.0].1 -= 1,
|
||||
_ => unreachable!()
|
||||
}
|
||||
|
||||
match b.1 {
|
||||
0 => variant.components[b.0].0 -= 1,
|
||||
1 => variant.components[b.0].1 -= 1,
|
||||
_ => unreachable!()
|
||||
}
|
||||
|
||||
if variant.validate() {
|
||||
variants.push(variant);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
variants
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fn main() {
|
||||
let mut facilities = Vec::new();
|
||||
|
||||
let mut facility = Facility::new(0, 4);
|
||||
|
||||
// Thulium
|
||||
facility.components.push((0, 0));
|
||||
|
||||
// Plutonium
|
||||
facility.components.push((0, 1));
|
||||
|
||||
// Strontium
|
||||
facility.components.push((0, 1));
|
||||
|
||||
// Promethium
|
||||
facility.components.push((2, 2));
|
||||
|
||||
// Ruthenium
|
||||
facility.components.push((2, 2));
|
||||
|
||||
// Elerium
|
||||
facility.components.push((0, 0));
|
||||
|
||||
// Dilithium
|
||||
facility.components.push((0, 0));
|
||||
|
||||
facility.steps();
|
||||
|
||||
facilities.push(facility);
|
||||
|
||||
let mut checked = HashSet::new();
|
||||
|
||||
for i in 0..100 {
|
||||
let mut step_variants = Vec::new();
|
||||
|
||||
for facility in facilities.clone() {
|
||||
if checked.contains(&facility) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let mut variants = facility.steps();
|
||||
|
||||
checked.insert(facility);
|
||||
|
||||
step_variants.append(&mut variants);
|
||||
}
|
||||
|
||||
println!("step={}, variants={}", i + 1, step_variants.len());
|
||||
|
||||
|
||||
let done = step_variants.iter().filter(|x| x.is_done()).count();
|
||||
|
||||
if done > 0 {
|
||||
println!("DONE!");
|
||||
break;
|
||||
}
|
||||
|
||||
facilities = step_variants;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_step_01() {
|
||||
let mut facility = Facility::new(0, 4);
|
||||
|
||||
// Hydrogen
|
||||
facility.components.push((1, 0));
|
||||
|
||||
// Lithium
|
||||
facility.components.push((2, 0));
|
||||
|
||||
assert_eq!(true, facility.validate());
|
||||
assert_eq!(false, facility.is_done());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_step_02() {
|
||||
let mut facility = Facility::new(1, 4);
|
||||
|
||||
// Hydrogen
|
||||
facility.components.push((1, 1));
|
||||
|
||||
// Lithium
|
||||
facility.components.push((2, 0));
|
||||
|
||||
assert_eq!(true, facility.validate());
|
||||
assert_eq!(false, facility.is_done());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_step_03() {
|
||||
let mut facility = Facility::new(2, 4);
|
||||
|
||||
// Hydrogen
|
||||
facility.components.push((2, 2));
|
||||
|
||||
// Lithium
|
||||
facility.components.push((2, 0));
|
||||
|
||||
assert_eq!(true, facility.validate());
|
||||
assert_eq!(false, facility.is_done());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_step_04() {
|
||||
let mut facility = Facility::new(1, 4);
|
||||
|
||||
facility.components.push((2, 1));
|
||||
facility.components.push((2, 0));
|
||||
|
||||
assert_eq!(true, facility.validate());
|
||||
assert_eq!(false, facility.is_done());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_step_05() {
|
||||
let mut facility = Facility::new(0, 4);
|
||||
|
||||
facility.components.push((2, 0));
|
||||
facility.components.push((2, 0));
|
||||
|
||||
assert_eq!(true, facility.validate());
|
||||
assert_eq!(false, facility.is_done());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_step_06() {
|
||||
let mut facility = Facility::new(0, 4);
|
||||
|
||||
facility.components.push((2, 1));
|
||||
facility.components.push((2, 1));
|
||||
|
||||
assert_eq!(true, facility.validate());
|
||||
assert_eq!(false, facility.is_done());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_step_07() {
|
||||
let mut facility = Facility::new(0, 4);
|
||||
|
||||
facility.components.push((2, 2));
|
||||
facility.components.push((2, 2));
|
||||
|
||||
assert_eq!(true, facility.validate());
|
||||
assert_eq!(false, facility.is_done());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_step_08() {
|
||||
let mut facility = Facility::new(0, 4);
|
||||
|
||||
facility.components.push((2, 3));
|
||||
facility.components.push((2, 3));
|
||||
|
||||
assert_eq!(true, facility.validate());
|
||||
assert_eq!(false, facility.is_done());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_step_09() {
|
||||
let mut facility = Facility::new(0, 4);
|
||||
|
||||
facility.components.push((2, 2));
|
||||
facility.components.push((2, 3));
|
||||
|
||||
assert_eq!(true, facility.validate());
|
||||
assert_eq!(false, facility.is_done());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_step_10() {
|
||||
let mut facility = Facility::new(0, 4);
|
||||
|
||||
facility.components.push((3, 2));
|
||||
facility.components.push((3, 3));
|
||||
|
||||
assert_eq!(true, facility.validate());
|
||||
assert_eq!(false, facility.is_done());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_step_11() {
|
||||
let mut facility = Facility::new(0, 4);
|
||||
|
||||
facility.components.push((3, 2));
|
||||
facility.components.push((3, 2));
|
||||
|
||||
assert_eq!(true, facility.validate());
|
||||
assert_eq!(false, facility.is_done());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_step_12() {
|
||||
let mut facility = Facility::new(3, 4);
|
||||
|
||||
facility.components.push((3, 3));
|
||||
facility.components.push((3, 3));
|
||||
|
||||
assert_eq!(true, facility.validate());
|
||||
assert_eq!(true, facility.is_done());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_validate_01() {
|
||||
let mut facility = Facility::new(0, 4);
|
||||
|
||||
facility.components.push((1, 0));
|
||||
facility.components.push((0, 1));
|
||||
|
||||
assert_eq!(false, facility.validate());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user