Browse Source

2016 days 12-13

part 2 present but not working
master
Terrana Ninetailed 6 months ago
parent
commit
1da7f4991a
7 changed files with 195 additions and 4 deletions
  1. +10
    -0
      .idea/inspectionProfiles/Project_Default.xml
  2. +23
    -0
      2016/resources/day12.input
  3. +1
    -0
      2016/resources/day13.input
  4. +66
    -0
      2016/src/day12.rs
  5. +65
    -0
      2016/src/day13.rs
  6. +12
    -0
      2016/src/main.rs
  7. +18
    -4
      2016/src/pathfinding.rs

+ 10
- 0
.idea/inspectionProfiles/Project_Default.xml View File

@@ -0,0 +1,10 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="SpellCheckingInspection" enabled="false" level="TYPO" enabled_by_default="false">
<option name="processCode" value="true" />
<option name="processLiterals" value="true" />
<option name="processComments" value="true" />
</inspection_tool>
</profile>
</component>

+ 23
- 0
2016/resources/day12.input View File

@@ -0,0 +1,23 @@
cpy 1 a
cpy 1 b
cpy 26 d
jnz c 2
jnz 1 5
cpy 7 c
inc d
dec c
jnz c -2
cpy a c
inc a
dec b
jnz b -2
cpy c b
dec d
jnz d -6
cpy 18 c
cpy 11 d
inc a
dec d
jnz d -2
dec c
jnz c -5

+ 1
- 0
2016/resources/day13.input View File

@@ -0,0 +1 @@
1352

+ 66
- 0
2016/src/day12.rs View File

@@ -0,0 +1,66 @@
use crate::file_input::read_input_file;
use std::str::FromStr;
use std::usize::MAX;

pub fn part1() {
println!("Day 12 part 1");
run_program([0;4]);
}

pub fn part2() {
println!("Day 12 part 2");
run_program([0, 0, 1, 0]);
}

fn run_program(mut registers: [i32; 4]) {
let input_file = read_input_file("day12.input");
let program: Vec<&str> = input_file.split_terminator('\n').collect();
let mut ptr = 0;
while ptr < program.len() {
// println!("{} {:?} {}", ptr, registers, program[ptr]);
let mut chunks = program[ptr].split(' ');
match chunks.next() {
Some("cpy") => {
let from_val = value(chunks.next().unwrap(), &registers);
let to_reg = register(chunks.next().unwrap());
registers[to_reg] = from_val;
}
Some("inc") => {
let reg = register(chunks.next().unwrap());
registers[reg] += 1;
}
Some("dec") => {
let reg = register(chunks.next().unwrap());
registers[reg] -= 1;
}
Some("jnz") => {
let from_val = value(chunks.next().unwrap(), &registers);
if from_val != 0 {
let ptr_to = value(chunks.next().unwrap(), &registers);
ptr = (ptr as i32 + ptr_to) as usize;
continue;
}
}
_ => break
}
ptr += 1;
}
println!("{:?}", registers);
}

fn value(reference: &str, registers: &[i32;4]) -> i32 {
match i32::from_str(reference) {
Ok(val) => val,
Err(_) => registers[register(reference)]
}
}

fn register(name: &str) -> usize {
match name {
"a" => 0,
"b" => 1,
"c" => 2,
"d" => 3,
_ => MAX
}
}

+ 65
- 0
2016/src/day13.rs View File

@@ -0,0 +1,65 @@
use crate::file_input::read_input_file;
use std::str::FromStr;
use crate::pathfinding::{dijkstra_single_goal, Edge, dijkstra_multi_goal};
use std::collections::HashSet;

pub fn part1() {
let odfn = office_designers_favourite_number();
let path = dijkstra_single_goal((1,1), (31,39),
|(x,y)| neighbours(odfn, x, y));
match path {
Some((cost,_)) => println!("{}", cost),
None => println!("No path found")
}
}

pub fn part2() {
let odfn = office_designers_favourite_number();
let mut goals: HashSet<(u16,u16)> = HashSet::new();
for y in 0..52 {
for x in 0..52 {
if (x as i32 - 1).abs() + (y as i32 - 1).abs() <= 50 {
if is_open(1, 1, odfn) {
goals.insert((x as u16, y as u16));
} else if x > 1 {
break;
}
}
}
}
let result = dijkstra_multi_goal((1,1), goals,
|(x,y)| neighbours(odfn, x, y));
let mut count = 0;
for (cost,_) in result.values() {
if *cost <= 50 {
count += 1;
}
}
println!("{}", count);
}

fn office_designers_favourite_number() -> u16 {
u16::from_str(read_input_file("day13.input").trim()).unwrap()
}

fn neighbours(odfn: u16, x: &u16, y: &u16) -> Vec<Edge<(u16, u16)>> {
let x = *x;
let y = *y;
let mut edges = Vec::new();
if y > 0 && is_open(x, y - 1, odfn) { edges.push(Edge { node: (x, y - 1), cost: 1 }) }
if x > 0 && is_open(x - 1, y, odfn) { edges.push(Edge { node: (x - 1, y), cost: 1 }) }
if is_open(x, y + 1, odfn) { edges.push(Edge { node: (x, y + 1), cost: 1 }) }
if is_open(x + 1, y, odfn) { edges.push(Edge { node: (x + 1, y), cost: 1 }) }
edges
}

fn is_open(x: u16, y: u16, odfn: u16) -> bool {
let weirdly_specific_formula = x*x + 3*x + 2*x*y + y + y*y + odfn;
let mut one_count = 0;
for i in 0..16 {
if (1 << i) & weirdly_specific_formula != 0 {
one_count += 1;
}
}
(one_count & 1) == 0
}

+ 12
- 0
2016/src/main.rs View File

@@ -14,6 +14,8 @@ mod day10;
mod day11;
mod file_input;
mod pathfinding;
mod day12;
mod day13;

fn main() {
let mut selection= String::new();
@@ -79,6 +81,16 @@ fn main() {
Some("2") => day11::part2(),
_ => ()
},
Some("12") => match choices.next() {
Some("1") => day12::part1(),
Some("2") => day12::part2(),
_ => ()
},
Some("13") => match choices.next() {
Some("1") => day13::part1(),
Some("2") => day13::part2(),
_ => ()
},
_ => ()
}
}

+ 18
- 4
2016/src/pathfinding.rs View File

@@ -21,27 +21,41 @@ impl<Node: Ord> PartialOrd for State<Node> {
}
}

#[derive(Eq, PartialEq, Debug)]
pub struct Edge<Node> {
pub node: Node,
pub cost: u32
}


pub fn dijkstra_single_goal<Node: Hash + Clone + Ord, EdgeFunction: Fn(&Node) -> Vec<Edge<Node>>>(start: Node, goal: Node, edges: EdgeFunction) -> Option<(u32, VecDeque<Node>)> {
pub fn dijkstra_single_goal<Node: Hash + Clone + Ord, EdgeFunction: Fn(&Node) -> Vec<Edge<Node>>>
(start: Node, goal: Node, edges: EdgeFunction) -> Option<(u32, VecDeque<Node>)> {
let mut goals = HashSet::new();
goals.insert(goal.clone());
match dijkstra_multi_goal(start, goals, edges).get(&goal) {
Some(x) => Some(x.to_owned()),
None => None
}
}

pub fn dijkstra_multi_goal<Node: Hash + Clone + Ord, EdgeFunction: Fn(&Node) -> Vec<Edge<Node>>>
(start: Node, goals: HashSet<Node>, edges: EdgeFunction) -> HashMap<Node, (u32, VecDeque<Node>)> {
let mut results: HashMap<Node, (u32, VecDeque<Node>)> = HashMap::new();
let mut distances: HashMap<Node, u32> = HashMap::new();
let mut came_from: HashMap<Node, Node> = HashMap::new();
let mut heap: BinaryHeap<State<Node>> = BinaryHeap::new();
distances.insert(start.clone(), 0);
heap.push(State { cost: 0, node: start });
while let Some(current) = heap.pop() {
if current.node == goal {
if goals.contains(&current.node) {
let mut path_el = Some(&current.node);
let mut path = VecDeque::new();
while let Some(el) = path_el {
path_el = came_from.get(el);
path.push_front(el.to_owned());
}
return Some((current.cost, path));
results.insert(current.node.clone(), (current.cost, path));
if results.len() >= goals.len() { break; }
}
let node = &current.node;
if let Some(other_cost) = distances.get(node) {
@@ -62,7 +76,7 @@ pub fn dijkstra_single_goal<Node: Hash + Clone + Ord, EdgeFunction: Fn(&Node) ->
heap.push(next);
}
}
None
results
}

pub fn a_star<Node: Hash + Clone + Ord, EdgeFunction: Fn(&Node) -> Vec<Edge<Node>>, Heuristic: Fn(&Node) -> u32>

Loading…
Cancel
Save