Even more clean up.

Removed duplicated code in the descend stage and moved it to different
functions. Also, range finders are no longer technically infinite, but
are assumed to be.
This commit is contained in:
2018-12-17 11:45:23 +01:00
parent a632bdff10
commit 851868bed4
2 changed files with 63 additions and 75 deletions

View File

@@ -32,10 +32,10 @@ z
<defs> <defs>
<path d="M 0 0 <path d="M 0 0
L 0 3.5 L 0 3.5
" id="md180c468f1" style="stroke:#000000;stroke-width:0.8;"/> " id="m7d08bf4d8b" style="stroke:#000000;stroke-width:0.8;"/>
</defs> </defs>
<g> <g>
<use style="stroke:#000000;stroke-width:0.8;" x="60.305455" xlink:href="#md180c468f1" y="307.584"/> <use style="stroke:#000000;stroke-width:0.8;" x="60.305455" xlink:href="#m7d08bf4d8b" y="307.584"/>
</g> </g>
</g> </g>
<g id="text_1"> <g id="text_1">
@@ -71,7 +71,7 @@ z
<g id="xtick_2"> <g id="xtick_2">
<g id="line2d_2"> <g id="line2d_2">
<g> <g>
<use style="stroke:#000000;stroke-width:0.8;" x="127.941818" xlink:href="#md180c468f1" y="307.584"/> <use style="stroke:#000000;stroke-width:0.8;" x="127.941818" xlink:href="#m7d08bf4d8b" y="307.584"/>
</g> </g>
</g> </g>
<g id="text_2"> <g id="text_2">
@@ -110,7 +110,7 @@ z
<g id="xtick_3"> <g id="xtick_3">
<g id="line2d_3"> <g id="line2d_3">
<g> <g>
<use style="stroke:#000000;stroke-width:0.8;" x="195.578182" xlink:href="#md180c468f1" y="307.584"/> <use style="stroke:#000000;stroke-width:0.8;" x="195.578182" xlink:href="#m7d08bf4d8b" y="307.584"/>
</g> </g>
</g> </g>
<g id="text_3"> <g id="text_3">
@@ -139,7 +139,7 @@ z
<g id="xtick_4"> <g id="xtick_4">
<g id="line2d_4"> <g id="line2d_4">
<g> <g>
<use style="stroke:#000000;stroke-width:0.8;" x="263.214545" xlink:href="#md180c468f1" y="307.584"/> <use style="stroke:#000000;stroke-width:0.8;" x="263.214545" xlink:href="#m7d08bf4d8b" y="307.584"/>
</g> </g>
</g> </g>
<g id="text_4"> <g id="text_4">
@@ -153,7 +153,7 @@ z
<g id="xtick_5"> <g id="xtick_5">
<g id="line2d_5"> <g id="line2d_5">
<g> <g>
<use style="stroke:#000000;stroke-width:0.8;" x="330.850909" xlink:href="#md180c468f1" y="307.584"/> <use style="stroke:#000000;stroke-width:0.8;" x="330.850909" xlink:href="#m7d08bf4d8b" y="307.584"/>
</g> </g>
</g> </g>
<g id="text_5"> <g id="text_5">
@@ -193,7 +193,7 @@ z
<g id="xtick_6"> <g id="xtick_6">
<g id="line2d_6"> <g id="line2d_6">
<g> <g>
<use style="stroke:#000000;stroke-width:0.8;" x="398.487273" xlink:href="#md180c468f1" y="307.584"/> <use style="stroke:#000000;stroke-width:0.8;" x="398.487273" xlink:href="#m7d08bf4d8b" y="307.584"/>
</g> </g>
</g> </g>
<g id="text_6"> <g id="text_6">
@@ -286,10 +286,10 @@ z
<defs> <defs>
<path d="M 0 0 <path d="M 0 0
L -3.5 0 L -3.5 0
" id="mf0f7226eb2" style="stroke:#000000;stroke-width:0.8;"/> " id="mbcaa2d2acc" style="stroke:#000000;stroke-width:0.8;"/>
</defs> </defs>
<g> <g>
<use style="stroke:#000000;stroke-width:0.8;" x="57.6" xlink:href="#mf0f7226eb2" y="295.488"/> <use style="stroke:#000000;stroke-width:0.8;" x="57.6" xlink:href="#mbcaa2d2acc" y="295.488"/>
</g> </g>
</g> </g>
<g id="text_8"> <g id="text_8">
@@ -302,7 +302,7 @@ L -3.5 0
<g id="ytick_2"> <g id="ytick_2">
<g id="line2d_8"> <g id="line2d_8">
<g> <g>
<use style="stroke:#000000;stroke-width:0.8;" x="57.6" xlink:href="#mf0f7226eb2" y="247.488"/> <use style="stroke:#000000;stroke-width:0.8;" x="57.6" xlink:href="#mbcaa2d2acc" y="247.488"/>
</g> </g>
</g> </g>
<g id="text_9"> <g id="text_9">
@@ -316,7 +316,7 @@ L -3.5 0
<g id="ytick_3"> <g id="ytick_3">
<g id="line2d_9"> <g id="line2d_9">
<g> <g>
<use style="stroke:#000000;stroke-width:0.8;" x="57.6" xlink:href="#mf0f7226eb2" y="199.488"/> <use style="stroke:#000000;stroke-width:0.8;" x="57.6" xlink:href="#mbcaa2d2acc" y="199.488"/>
</g> </g>
</g> </g>
<g id="text_10"> <g id="text_10">
@@ -331,7 +331,7 @@ L -3.5 0
<g id="ytick_4"> <g id="ytick_4">
<g id="line2d_10"> <g id="line2d_10">
<g> <g>
<use style="stroke:#000000;stroke-width:0.8;" x="57.6" xlink:href="#mf0f7226eb2" y="151.488"/> <use style="stroke:#000000;stroke-width:0.8;" x="57.6" xlink:href="#mbcaa2d2acc" y="151.488"/>
</g> </g>
</g> </g>
<g id="text_11"> <g id="text_11">
@@ -346,7 +346,7 @@ L -3.5 0
<g id="ytick_5"> <g id="ytick_5">
<g id="line2d_11"> <g id="line2d_11">
<g> <g>
<use style="stroke:#000000;stroke-width:0.8;" x="57.6" xlink:href="#mf0f7226eb2" y="103.488"/> <use style="stroke:#000000;stroke-width:0.8;" x="57.6" xlink:href="#mbcaa2d2acc" y="103.488"/>
</g> </g>
</g> </g>
<g id="text_12"> <g id="text_12">
@@ -361,7 +361,7 @@ L -3.5 0
<g id="ytick_6"> <g id="ytick_6">
<g id="line2d_12"> <g id="line2d_12">
<g> <g>
<use style="stroke:#000000;stroke-width:0.8;" x="57.6" xlink:href="#mf0f7226eb2" y="55.488"/> <use style="stroke:#000000;stroke-width:0.8;" x="57.6" xlink:href="#mbcaa2d2acc" y="55.488"/>
</g> </g>
</g> </g>
<g id="text_13"> <g id="text_13">
@@ -577,7 +577,7 @@ z
</g> </g>
</g> </g>
<g id="line2d_13"> <g id="line2d_13">
<path clip-path="url(#p26e262efc8)" d="M 73.832727 282.048 <path clip-path="url(#pa0af5c901d)" d="M 73.832727 282.048
L 87.36 277.248 L 87.36 277.248
L 100.887273 270.528 L 100.887273 270.528
L 114.414545 269.568 L 114.414545 269.568
@@ -593,7 +593,7 @@ L 236.16 265.728
L 249.687273 277.248 L 249.687273 277.248
L 263.214545 251.328 L 263.214545 251.328
L 276.741818 259.008 L 276.741818 259.008
L 290.269091 265.728 L 290.269091 266.688
L 303.796364 289.728 L 303.796364 289.728
L 317.323636 289.728 L 317.323636 289.728
L 330.850909 289.728 L 330.850909 289.728
@@ -605,7 +605,7 @@ L 398.487273 289.728
" style="fill:none;stroke:#1f77b4;stroke-linecap:square;stroke-width:1.5;"/> " style="fill:none;stroke:#1f77b4;stroke-linecap:square;stroke-width:1.5;"/>
</g> </g>
<g id="line2d_14"> <g id="line2d_14">
<path clip-path="url(#p26e262efc8)" d="M 73.832727 295.488 <path clip-path="url(#pa0af5c901d)" d="M 73.832727 295.488
L 87.36 293.568 L 87.36 293.568
L 100.887273 295.488 L 100.887273 295.488
L 114.414545 295.488 L 114.414545 295.488
@@ -633,7 +633,7 @@ L 398.487273 295.488
" style="fill:none;stroke:#ff7f0e;stroke-linecap:square;stroke-width:1.5;"/> " style="fill:none;stroke:#ff7f0e;stroke-linecap:square;stroke-width:1.5;"/>
</g> </g>
<g id="line2d_15"> <g id="line2d_15">
<path clip-path="url(#p26e262efc8)" d="M 73.832727 233.088 <path clip-path="url(#pa0af5c901d)" d="M 73.832727 233.088
L 87.36 218.688 L 87.36 218.688
L 100.887273 208.128 L 100.887273 208.128
L 114.414545 191.808 L 114.414545 191.808
@@ -649,7 +649,7 @@ L 236.16 95.808
L 249.687273 205.248 L 249.687273 205.248
L 263.214545 53.568 L 263.214545 53.568
L 276.741818 86.208 L 276.741818 86.208
L 290.269091 165.888 L 290.269091 176.448
L 303.796364 277.248 L 303.796364 277.248
L 317.323636 277.248 L 317.323636 277.248
L 330.850909 277.248 L 330.850909 277.248
@@ -870,7 +870,7 @@ L 348.72625 83.926688
</g> </g>
</g> </g>
<defs> <defs>
<clipPath id="p26e262efc8"> <clipPath id="pa0af5c901d">
<rect height="266.112" width="357.12" x="57.6" y="41.472"/> <rect height="266.112" width="357.12" x="57.6" y="41.472"/>
</clipPath> </clipPath>
</defs> </defs>

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 25 KiB

View File

@@ -1,12 +1,13 @@
use std::collections::HashSet;
use std::io::BufRead;
use std::io::BufReader;
use std::io::Read; use std::io::Read;
use common::Solution;
use std::collections::HashSet;
use regex::Regex;
use std::io::BufReader;
use std::io::BufRead;
use itertools::Itertools; use itertools::Itertools;
use itertools::MinMaxResult; use itertools::MinMaxResult;
use regex::Regex;
use common::Solution;
type Coordinate = (usize, usize); type Coordinate = (usize, usize);
@@ -41,7 +42,7 @@ impl Day17 {
for y in a..=b { for y in a..=b {
self.clays.insert((fixed, y)); self.clays.insert((fixed, y));
} }
}, }
"y" => { "y" => {
for x in a..=b { for x in a..=b {
self.clays.insert((x, fixed)); self.clays.insert((x, fixed));
@@ -55,11 +56,35 @@ impl Day17 {
MinMaxResult::MinMax(a, b) => { MinMaxResult::MinMax(a, b) => {
self.ymin = *a; self.ymin = *a;
self.ymax = *b; self.ymax = *b;
}, }
_ => panic!(), _ => panic!(),
}; };
} }
fn support_end<T>(&mut self, center: usize, range: T, y: usize) -> (usize, bool)
where T: Iterator<Item=usize>
{
let mut prev = center;
for x in range {
let pos = (x, y);
if self.clays.contains(&pos) {
return (prev, true);
}
prev = x;
let below = (x, y + 1);
self.descend(below);
if !self.is_supported(&below) {
return (x, false);
}
}
unreachable!();
}
fn is_supported(&self, pos: &Coordinate) -> bool {
self.clays.contains(pos) || self.contained.contains(pos)
}
fn descend(&mut self, pos: Coordinate) { fn descend(&mut self, pos: Coordinate) {
let (x, y) = pos; let (x, y) = pos;
@@ -71,49 +96,16 @@ impl Day17 {
self.descend(below); self.descend(below);
if self.clays.contains(&below) || self.contained.contains(&below) { if self.is_supported(&below) {
let mut contained = true; let (right, right_contained) = self.support_end(x, (x + 1).., y);
let (left, left_contained) = self.support_end(x, (0..x).rev(), y);
let mut layer = vec![pos]; let range = (left..=right).map(|x| (x, y));
let mut nx = x + 1; if left_contained && right_contained {
loop { self.contained.extend(range);
let npos = (nx, y);
if self.clays.contains(&npos) {
break;
}
layer.push(npos);
let nbelow = (nx, y + 1);
self.descend(nbelow);
if !self.clays.contains(&nbelow) && !self.contained.contains(&nbelow) {
contained = false;
break;
}
nx += 1;
}
let mut nx = x - 1;
loop {
let npos = (nx, y);
if self.clays.contains(&npos) {
break;
}
layer.push(npos);
let nbelow = (nx, y + 1);
self.descend(nbelow);
if !self.clays.contains(&nbelow) && !self.contained.contains(&nbelow) {
contained = false;
break;
}
nx -= 1;
}
if contained {
self.contained.extend(layer);
} else { } else {
self.flowing.extend(layer); self.flowing.extend(range);
} }
} else { } else {
self.flowing.insert(pos); self.flowing.insert(pos);
@@ -127,9 +119,8 @@ impl Solution for Day17 {
self.descend((500, 0)); self.descend((500, 0));
let result = self.contained.iter() let result = self.contained.len()
.chain(self.flowing.iter()) + self.flowing.len() - self.ymin;
.filter(|&&(_, y)| y >= self.ymin && y <= self.ymax).count();
format!("{}", result) format!("{}", result)
} }
@@ -138,16 +129,14 @@ impl Solution for Day17 {
self.descend((500, 0)); self.descend((500, 0));
let result = self.contained.iter() format!("{}", self.contained.len())
.filter(|&&(_, y)| y >= self.ymin && y <= self.ymax).count();
format!("{}", result)
} }
} }
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use day17::Day17;
use common::Solution; use common::Solution;
use day17::Day17;
const SAMPLE_INPUT: &[u8] = include_bytes!("samples/17.txt"); const SAMPLE_INPUT: &[u8] = include_bytes!("samples/17.txt");
@@ -162,5 +151,4 @@ mod tests {
let mut instance = Day17::new(); let mut instance = Day17::new();
assert_eq!("29", instance.part2(&mut SAMPLE_INPUT)); assert_eq!("29", instance.part2(&mut SAMPLE_INPUT));
} }
} }