day20 part 1 super slow

This commit is contained in:
Johannes committed 2018-12-21 10:03:06 +01:00
1 parent 0438a052d2
commit a35881fb01
2 files changed
+93 -6

No files matched your search

+1
View File
@@ -0,0 +1 @@
^SESESWWWWSSWNWWNENWNEENWWWWNENNNNESSESENEEEESESS(WNWWW(WWWN|NEE|SSE(N|S(WWSNEE|)E))|SENNNNNW(NNNENNESENNWNEEEEEESSSWNWN(E|WWSSSWSESWW(WNENSWSE|)SEESSSWW(NENWESWS|)SEEESWSWSEEEN(W|NEENWWNNW(NEESSENNNENNENNNNW(NNWWNNNEESS(WNSE|)EEEEESWSSESSSENENNENEEENNWNNNWNNWSWNNNNWWSWNWSSSSSENNNESSE(NNN|SWSEENESESWSWW(N(E|WWNWSWNNW(SS|WNNWSWWNNWWSSSE(SWSWSWS(EENEE(SWEN|)N(NNEEWWSS|)W|WWWSES(ENSW|)SWWWWSESEE(N(W|E)|SWWWSES(ENESNWSW|)WWWNENWNNNE(SSEWNN|)NEEE(E|NNNWNWSWWSEES(ENSW|)WWWS(E|SWWSWWWSSESESSS(WNWN(E|NWNNWWNEENWWNNNEEEESWS(WWNEWSEE|)ES(W|ENENE(NWW(S|NENWWSWWWWWNWSSWWSWWNENWNNESESENNENENWWSW(WNENWNNNEENENWNWSSWWWWWWSSENEESE(SSSWNWWWSSESEE(N(WNWESE|)E|SSSWWNN(ESNW|)WWWSWNNNWSWSESSESWSSWSEENNESEENESSSENNNE(NWWWW(WNENES|S)|ESSW(SSENEESWSEENEE(SENESSWWSWWN(ENSW|)WSWNWNWSSESWWNWSWSESENESESSSWNWWSWNN(WSWNNWNNENWWSWSSE(SWSWWSSWNWSSSENESSESEESENESSWSWWWWWNEN(ESE(E|N)|NWSWSSWWNENWWNEEN(WWNWWNENWWWWSWWSESWSEEEESWSWSWWWSESSWSEESSWNWWSSE(EEESWSWSSWNWNWN(EE(E|S)|WNNE(S|NWNENNNWNWNENWWNNENNEENWWNWWWWWNENESENNENNWWS(E|SWW(NNE(S|NNESENNEENEENWNNNWNNNNWSWSESSWSSEE(NWES|)SWWWWNW(NENNW(NEE(S(E|SSS)|NNENENNESSESSSSENNNNENWNEESSENNNESSSENNNESSSESSWNWWSESWWWW(SSENEEESWWSSSSWSW(NNENNWSWNN(SSENESNWSWNN|)|SEENENNNEN(W|ESSSSSW(WSESSSSESENEESS(ESEE(SSWNWESENN|)NNENNES(EENWNENNNE(ENESENNN(WSWNWSSWNNNWSSSSSSWSWNWSWNWWSES(WWNWSWNNNESENEENWNEEEESE(SWWWNE|NNNNNNNWNNWSWWWSEEESWWWSWSSS(W(SSENSWNN|)NNNNENWN(WSSNNE|)ENENNENWW(SS|WNNEES(ENNWNWWWWWWNENWNNWSWNWWSSWSWSSS(WSSWWNNW(SSSSSENNE(WSSWNNSSENNE|)|NENNW(NENENWNNW(SSS|NEENESEEENWWNENESEESESWSW(WS(WWN(E|WWSESES(ENSW|)SW(SSW(NN|S(SS|E))|N))|EEENEENNW(S|NNENEENWWWSWNWNNWNENWWWWWWWNW(NEENNNENNNNWSSWW(SSSE(SW|NNE)|NENNNW(SS|NNESESES(W|ESESWSESSW(SWSSENESENENW(NENWNENESESSW(N|SESSW(WS(WWWWW|EEEENENWW(S|NEENWNNW(SS|NWNENNENN(WWS(E|WNWWWSW(SESENE(NWES|)EESWWS(WSNE|)E|WN(W|E)))|EESENEESSEENEN(WWSNEE|)EEEESEEEEN(EESWSWSESEESWWSSWWWNNWWSSWWWNWWNNWWWN(WSWSESSW(NW(S|NWNNE(EN(EEN|WN)|S))|SSENEESEEEEEN(ESENE(NN|SSENEN(W|EESENNEEN(ENWNNWN(WSNE|)ENESENN(WWWSNEEE|)ESEEEN(ESSSWWWSWSSSEENWNEEN(W|EESENNEENNEN(WWWSW(S(EENSWW|)S|N)|EEEESEEEN(ESEEN(ESSWSESWWNWWSESSWWWWWWSESWSWNNWWWSWWWSESSSENENN(WSNE|)EE(NWES|)SWSSESEENWN(NESESSSSENENWNNNESSESESWSEESENNENESENEEESSESEEEENWNENWWSW(SEWN|)WNNNWNENWWSSS(E|WWWWNNEES(W|ENNWNWWWN(WSWNWSS(SEEN(W|E(SSWS(WNWESE|)S(ENSW|)S|EE))|WW(NNES|WS))|EEEEENWWN(NNENNESSSWSEEESSS(W(WW|NN)|EESWSESS(ENNNEEESWSS(WNNSSE|)SESEENNNNEESWSSENENNNNNWSWWW(NENE(NWWNENNENWWN(EEEESEEN(W|ESENEEESWSEESWSWWSWNWSSESWWW(SSSENEN(EEENWNENESEEESESSEEEENWWNNNWW(SESSNNWN|)WWWNENEENEENN(EEESESWWNWSSS(ENESSSS(ENNNNEENENWN(EEESSW(SSW(WWSESEEN(EESWSESWSWNWSSESWWSEESSWWSSSWWSWNWSSWNWSSWWNWNWNWNNWSSWNNWWWNNESEEENESESENNESEEENENESSWSS(WSWNWW(NEEEWWWS|)W(W|SESE(N|S))|ENENNE(SSSWENNN|)(NWNWN(NESE(NE(S|NN(EE|W(SWWEEN|)N))|S)|WSWNWWWWSWWWS(EE(S|EEESEN(NWWEES|)E)|WNNEN(NNESSSENENWN(SESWSWENENWN|)|WWSW(WSWWSSE(NEENESSE(WNNWSWENESSE|)|SSSSENEESSW(WSWSSWWSWNNNWNWWSWWWNN(EE(SWEN|)NWN(N|EEESES(WWNSEE|)EEE(S(E|W(SESWENWN|)W)|NWWNEENW(WWSNEE|)N))|WWSESWWSESENESSSSSENESSENESS(WWSWNWSWWNEN(EE|WNENNWSWSSSSS(EES(WSNE|)EEE(NWW|SSWN)|WNNWSWNNEENWWWSWWSWWSWNNWSWWSEESSWWN(WWWWWNNWNENENNEEEENWNWSWNNNWSWWWNWNNWNEESSESENNESENEEN(E(N|EESSESENN(W|EENEN(WWSNEE|)ENESSSW(SSSSWWNW(NEE(N(WW|N)|S)|WWSSWSW(SS(EEN(W|NENE(NWES|)SSENNESS(SWWW(SEWN|)N|EENN(WSNE|)ENE(ES(SW(WSEWNE|)N|EE)|NWNN(WSSSNNNE|)E(ENWWNSEESW|)S)))|WNWWSW(N|SWSSENESENN(N|W|EE)))|NNWNEE(S|NWWWSWNNEEENW(ESWWWSNEEENW|))))|N)))|WWNWWW(S(EE|S)|N(NW(N|WWWNWWNEN(ESNW|)WNN(E(S|NEEN(E(ENEEE(SWWEEN|)NESEEENNN(WWWS(EESWENWW|)WN(NEE|WSSWW)|E(SSSEWNNN|)EEE)|S)|W(N|W)))|WWSESSSWWNENWWNENW(WWSSSWWSESENESE(NNWNNSSESS|)ESSESESESWWWN(WSWNWWNNESENE(SEWN|)NWWWWSSWWSWSESENNESESE(N|EESENEESWSWSWNWNWWW(SWWWN(WSWNNNWWSESSWNWNWNENNWWNWNEEENENNWSWNN(WWSESWS(WNNNW(WSESWSSSS(WNWNENW(NENNSSWS|)WWWSSENESS(WW|E)|EE(SE(N|E(SWWWNWSSSESENN(ESE(N|SSSEESWWSSSEESEESENESSENNNNWWS(WWNWN(WSNE|)EE(NNN(ESSENEEN(WW|EEENESESSEEE(ENN(WSWWEENE|)EN(W|NEEE(NWW(W|NNNNN(NWSW(WNE|SES)|ES(SSSEWNNN|)ENEESW))|ESESSENE(SSWWWWSSSW(SWSSW(WNEWSE|)SEEEEENE(NNWSWW(S(WNSE|)E|NENNNE(E|SS))|EEEESWWSWW(NEWS|)WWSSS(WN(NN|W)|EENN(WSNE|)EES(W|ENEN(W|ESSWSE(S(S|W)|ENE(S|NNW(S|N(WNSE|)EESENNEEN(WW|NESESWSESEE(SWWWNWNWSSWWSEESESEENEN(E|WW(WNSE|)S)|NWNEN(WNNWSNESSE|)E)))))))))|NNNW(WNENNESE(ESWWEENW|)N|S))|N(ESNW|)W)))|SSWWN(WWS(E|WWWNENW(NEEESWS(NENWWWEEESWS|)|WS(SSSSESWSS(WNWSWS(E|SSSWNW(SSESSE(SWEN|)NE(N(W|N)|S)|NENNWSWSSWNW(SSWNSENN|)NNNNEES(EN(ESENSWNW|)NWWWWN(EE|NNWSSWNNNEENNWN(ENSW|)WWNWW(SSE(N|SWW(SEEE(NNESEWNWSS|)SWW(SSENES|W)|W))|N(ENWESW|)W))|WS(E|S))))|ENE(SSS(WNSE|)E|N(NNNWSNESSS|)EEE(N|E)))|W(N|WW))))|E)))|W(WWN(E|N)|SS))|S)|E))|W)|E))|NWN(E|N)))|N)|EE)|EEEESESSSWNW(SWS(EESS(WNWSNESE|)E(SSEWNN|)NEN(W|EENWNE(E|NWN(WSSSNNNE|)NE(EE|N|S)))|WW)|N(N|E)))|EE)|N))|E)|NENNNWNEENEEE(WWWSWWEENEEE|))))|EEE)))|E)))|ENNNN(EESSW(SSEEN(NEENNN(NESENESENNEE(ESSSSSENESSENNNNEN(WWSW(SEWN|)N|NEEEN(ESESENNESSESSEENEEESESWSESSSWSWNNWWSSWWWNENNE(NWWN(EEEENESSS(ES|WNWS)|WNN(ESNW|)WSWNWN(E|WWSSSSW(NN|SSWWSESEEESENNNNEEN(ESS(ENSW|)WWSEESWSSSWWSEEEESWSEENEESENESSEENNE(NWNELine truncated
+92 -6
View File
@@ -1,25 +1,46 @@
use self::Tile::*; use self::Tile::*;
#[allow(unused_imports)] #[allow(unused_imports)]
use crate::utils; use crate::utils;
use std::collections::HashMap; use std::collections::{HashMap, HashSet};
use std::ops::Add;
use std::collections::VecDeque;
pub fn task1() { pub fn task1() {
// let input = utils::read_file("input/day20.txt"); let input = utils::read_file("input/day20.txt");
let input = "^ENWWW(NEEE|SSE(EE|N))$".to_string(); // let input = "^ENNWSWW(NEWS|)SSSEEN(WNSE|)EE(SWEN|)NNN$".to_string();
let input = &input[1..]; let input = &input[1..];
let mut map: HashMap<Point, Tile> = HashMap::new(); let mut map: HashMap<Point, Tile> = HashMap::new();
add_default_neighbors_for_room(&mut map, Point(0, 0)); add_default_neighbors_for_room(&mut map, Point(0, 0));
parse_input(&mut map, &input, Point(0, 0)); parse_input(&mut map, &input, Point(0, 0));
print_map(&map); print_map(&map);
println!("Most distant point: {:?}", longest_shortest_path(&map, Point(0,0)));
} }
fn parse_input(map: &mut HashMap<Point, Tile>, input: &str, position: Point) { fn parse_input(map: &mut HashMap<Point, Tile>, input: &str, position: Point) {
// println!("{}, {:?}", input, position);
if input == "$" {
println!("End of the road.");
return;
}
let mut position = position; let mut position = position;
let mut input = input; let mut input = input;
while let Some(c) = input.chars().next() { let mut iterator = input.chars();
while let Some(c) = iterator.next() {
match c { match c {
'(' => return, '(' => {
let (parts, rest) = split_parts(&input);
// println!("{:?}", parts);
// println!("{:?}", rest);
for part in parts {
let mut flattened = String::with_capacity(part.len() + rest.len());
flattened = flattened.add(part);
flattened = flattened.add(rest);
parse_input(map, &flattened, position);
}
break;
}
'N' => { 'N' => {
position = Point(position.0, position.1 - 2); position = Point(position.0, position.1 - 2);
add_default_neighbors_for_room(map, position); add_default_neighbors_for_room(map, position);
@@ -53,6 +74,42 @@ fn parse_input(map: &mut HashMap<Point, Tile>, input: &str, position: Point) {
} }
} }
/// Splits the input by '|', but only by those that are not enclosed by further parenthesises.
/// The second return value is the rest after the closing parenthesis
fn split_parts(input: &str) -> (Vec<&str>, &str) {
// println!("Splitting '{}'", input);
let mut count = 0;
let mut closing_index = None::<usize>;
let mut last_separator = 0;
let mut parts = Vec::new();
for (i, c) in input.chars().enumerate() {
match c {
'(' => count += 1,
')' => {
count -= 1;
if count == 0 {
closing_index = Some(i);
parts.push(&input[last_separator + 1..i]);
break;
}
}
'|' => {
// println!("| at {} (depth {})", i, count);
if count == 1 {
parts.push(&input[last_separator + 1..i]);
last_separator = i;
}
}
_ => {}
}
}
let closing_index =
closing_index.expect(&format!("No matching closing parenthesis in {}", input));
(parts, &input[closing_index + 1..])
}
fn add_default_neighbors_for_room(map: &mut HashMap<Point, Tile>, position: Point) { fn add_default_neighbors_for_room(map: &mut HashMap<Point, Tile>, position: Point) {
map.insert(position, Room); map.insert(position, Room);
for p in position.diagonals() { for p in position.diagonals() {
@@ -82,7 +139,7 @@ fn print_map(map: &HashMap<Point, Tile>) {
None => " ", None => " ",
Some(Wall) => "#", Some(Wall) => "#",
Some(Room) => ".", Some(Room) => ".",
Some(Unknown) => "?", Some(Unknown) => "#",
Some(Door) => { Some(Door) => {
if y % 2 == 0 { if y % 2 == 0 {
"|" "|"
@@ -98,6 +155,31 @@ fn print_map(map: &HashMap<Point, Tile>) {
} }
} }
fn longest_shortest_path(map: &HashMap<Point, Tile>, start: Point) -> Option<(Point, usize)> {
let mut distances: HashMap<Point, usize> = HashMap::with_capacity(map.len());
let mut open: VecDeque<(usize,Point)> = VecDeque::new();
let mut visited: HashSet<Point> = HashSet::new();
open.push_back((0,start));
visited.insert(start);
while let Some((distance, predecessor)) = open.pop_front() {
distances.insert(predecessor, distance);
for p in predecessor.neighbors() {
if let Some(Door) = map.get(&p) {
let room = predecessor.next_room(&p);
if !visited.contains(&room) {
visited.insert(room);
open.push_back((distance + 1, room));
}
}
}
}
if let Some((point, distance)) = distances.iter().max_by_key(|it| it.1) {
Some((*point, *distance))
} else {
None
}
}
#[derive(Eq, PartialEq, Hash, Clone, Copy, Debug)] #[derive(Eq, PartialEq, Hash, Clone, Copy, Debug)]
struct Point(i32, i32); struct Point(i32, i32);
@@ -119,6 +201,10 @@ impl Point {
Point(self.0, self.1 + 1), Point(self.0, self.1 + 1),
] ]
} }
fn next_room(&self, other: &Self) -> Self {
Point(self.0 + 2*(other.0 - self.0), self.1 +2*(other.1-self.1))
}
} }
enum Tile { enum Tile {