Complete day 15

This commit is contained in:
Tyler Hallada 2021-12-26 18:37:29 -05:00
parent 9599641ddc
commit 4e2fb8a341
5 changed files with 357 additions and 0 deletions

8
Cargo.lock generated
View File

@ -123,3 +123,11 @@ dependencies = [
"anyhow",
"common",
]
[[package]]
name = "day15"
version = "0.1.0"
dependencies = [
"anyhow",
"common",
]

10
crates/day15/Cargo.toml Normal file
View File

@ -0,0 +1,10 @@
[package]
name = "day15"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
anyhow = "1.0"
common = { path = "../common" }

View File

@ -0,0 +1,100 @@
1797218461142179319573884891481221191657631838831754357117998319396235714788116521813149318951532839
8696981297918411971289919865719836144693333162529142812974198292932295491956499215586135482941739392
2991519621128967692174919369871962711711888349621119249111241263371998761114982461871811915749818981
9519298621148891919219116926535193934326629926112136839413932239182391497985687943399987482691961448
3322441212551229339949332249462272248555173795333563937398919128799491931719178641531998141722584429
9118353711988171611983883569964392454546273683762581127881992188984158689612224523966629229869841368
6619293351892345695919931961961959917575811995111642219592114857133566312236841811951318937396921471
4119719294958136935585131572211882179799139693669968792713194888628799229972719918777119331922298192
2897361395359964817739628715924942441921486256913485426413911886166322118384197271142719438976157178
3389638941186823278892211919997494993715555987282539661565969785971121324112299762618146712244947159
9282911861243373596527491925976176995918989739998978638179963274848391398779728689754153765948619469
8659237241858888999515587517811573419717292977626899259293151572296128169661741752918682542171942321
7764241289968175261192129897224933828487961991159914599166517495921873868188964356615533731833973441
5211819126749298191741999756776373271358917928175911622381895311231992844719941999396791192927375871
7147248429776976347262913517219841812956611529169838774299925229977967856924839394369116944811677481
9999327358212995943299686946957298991514945979821411233241473988197932142383177144729479991836191427
3118856861346926341911713996912169631119911431551249817492292818844125715189849969193192961131621911
9725216819926791171517898194558972919139137513355733988171946498928816869874911791891669217257113496
7233995695449113678612444521112129251251273195695889939964857843349673413266536268949113769342251889
6127221278819178621741141313355129711426692693677392749193553853936972975965634954629141151231879898
9316815118477222367841192213391742191959264299125536916699819514396152297399182268877162451983336217
9462996178167836998492412349917112812632399196941153512738339788549881946851158124161362774914992894
7967964922318976294433211213741866891119759725314487732559823798274829681391981566174639155611351418
8929424417132556157634716487111521991271289231745124921192394921986921935952364171299975161231824774
3218194149784328917294438859919299949729271441816111296879933691981973292149147435115597882711494998
9963686292555144316424191747459116221815592814842158141691641997871258112472186921312965944237595294
6895964781364928469137998279116249898846673137174356126748598484323966111982813263974112357699899763
7269811648363829147741792898355598248569675813169571842631115991782571118598396148154361996719188448
8844191981976773829997291691395479942961199359734575829759316784548382466496616827221178185913513238
3257332961391991114574911188523198843295839929161419384837634973422188848727297597838217868798186511
6923161896988782579586511869949273142676719174251591792643298288772526859781298141569266186617218381
7784717941413921956659125922992333927913184321298989112521798475113465863391148588936386584969341199
7729281363926216291184126185146911946599969922215989319947928254933624961823119312713825739752727942
9791595898229915783452994189791381989371243326849571162258539814113211999121938944928495688393186918
8891733154174974952723922594949579111188836887289616671917191976149512141593991859811284259441183431
8882142834538653968328977548117488826724429161466849928479176885239389889939199981835126994327391896
9517995278111242818459916811998944915697417117912182611857541473935942618223818819762995154781472981
5688665816361987489729842796931921414512473917441794427741369262172816993213983458958198919913823991
1191916752824613923926969193925957295939327864123259676198986799118369891115359391957249452752929126
7953359279426186179959629664623979247293134816151993933394146989756964927672838611674519931995335481
2588619583212263911463327947238911867191914187199422968181249242598932119917178149668551829479381692
9139997197211729428879315949158215521759731858227871598393911996977179197936292442539968196974143392
4232261554187854128157992418243551168633731913177429834412129191717919582896366737612182389415784188
4821243736858296431871216889694294547359824994296126745919812123118983919554436811916197471485951899
1789444139925892222466367952996429927297845751229192689449127919198952992139293319744714159936449428
9826695391968915127581997372149393515911949277794233746169181958714194329918573751286548977459133984
2192337259911892484227791261124721948491913173653784167993128393999959499743131219363182119952283978
3217492185391446491561359499251152813678989728154211194698554711579573178949291439543428975396999969
3867861429971172192458819948178991957886669668729948991163661783211114251141521367232129119114793985
8987756326299362119986998879589364162214661191762462991978789152965978499991924196194961211923983946
3941989955272175768425292121934436939925252349513897482811328179579133112112915747923399298497919231
8218972259833197878184194815191533999833125399873974758921718196132623614183515273946514288499727111
1437751958193491251887139961112992551391137225591413591259855297573633593916711792611198698994214931
9222784952843174957289129282688819183797667123851928962298111123475891321173291351957242491579929288
4732619159819497865337378815817638211711793289431191451159913994292222658957311641117562199447187762
1922578172811266932889929671898587112921216994269163349194897862669631216699811517641929113879429965
5161989656251729327191879868564154192726119219819183244889135163523927489855954468739959421881994238
4819921164369791999159813491399265881691121929971789718215883948391891598814936575118939822189471793
8882513759175398582299829751631629348693254997893362776799788389998788399339972916897658269997913718
1292943248881936384125164876519422482179293397552386181794636147294912887491588373821779931911191187
2629847941812784111897761715195255788824381859149113249724664791999515675414915516679929144685692278
2772682798815662376827394271849212113213692687627694877365198595132768349941735916599485286144676945
2393932687723188393839519563914218446613793719169118499134828955151218298152994598289712724891857191
3617398318482265926582994889268631869955227758698817939992471699819589382891915143633491667191983217
6911471527859211299313851863879935129278786895167159956316181913899978246167119482583766973277121191
1981719349418167792118929872278117552711988231248819194187731813131144284461159795271818599994593714
2811199196149453976164391892639388999124279731159528893891121792118688173627549881311642338117962758
4691716484637299892159474721929413914233367741429229241226899989254686631611518944863887979681529782
4482138978699511118519118488472749721682121879121719142129127792216962898129618931812891762991227189
9165122888898199618119141611974614971971318493267915612313211217617392424197681312999919621771185729
1588131199884516629986871332411227313281192112941476434724378996881979822418196899342121282934856816
7126317411441358114193567599682892334987381251188952754399928769359297971214875844983937899953212988
8587246861996999349587179148718697599488796398983115487494693657146299118222219134299111489194231965
1756191969194346888194346711493762171765976629194948439394646717346291964222987169438133774148812918
8789198221258954468986293399419779223378943346282786847513649264261539662294929759499768986798169241
1138369993982331549196792976559799283413654949889158671638369975888731165551659877511934953998822274
2114826371811112198999564997711125991529298612214145587752669675324982818263881118627791312962819135
3289283332363218131299181648827294977213217215138555913699183855926348817213881719932396959992968121
8587853367939591685793783997226894713789913999892859923556161114899661253264292692714823239899982193
9941317127358865229192397619611212997255961574849569689922816181189151859769399141999257779295762263
2171999627694757517559219922489957852841854844663175892649861832198936898853491281118127119111126853
9847187251892486999189989912188191379499126327252917351356711496334291364415686662182219562193321111
9189929424982871168612797812515916182171273998199863665452736918916924969999612492935667517295168295
3624681856881799987199539193723942395334489531142412618491447421164524793877168198845117125491337311
9297711591387465324465917921116922742218791943839142882882181986523416323962918891995927533949493181
3913897745491184244299396997431791991291596184419148627215918152618971355656911422988362342829957918
2161357198129894981258979893981129271657818883175987718298879242297781166689323717991763995914111299
1429691393132159496998994989721998771653222413191152795122991422999714758548118211476912919569859657
1155146287171621743862845462211983191917592287951249299195262481191199691967277142619868428281772552
2435517981879328114574698787193894982992581195327819651511899224491686961899174168226249522658661146
1919894989221529553399133386169999552895185552222755159922552431149786511973745343931818539315311175
2683381835121351182998489919911372894291894973399493194281379971969183416974346479151274291799853129
1751991384249781899947665921219827616999239519455929713722239711149225383616519712941889322712828418
3295919911592497192118828258118529133121427523281991929691965274368825689299671219749189813124887278
7828319259851721362716353874221716695129721491254728715913967965694595858939949833991856557249153792
4643162283932891824519919817417814174343124346663682549387955944171239182344299415172323771718859129
9382811937823973227813927835213688211415836968191527337792159834142739892661818877429739395149421471
3279512226121999191142499711269119643819431895822859387584439741423768775114929691745825321781118144
9391973246579999241217437296325675163824334513949186691912595622177779849572792973716569959311526846
4671438158382646393847419899596676468374198874175298772399482512793928838556984113933878117348995239

View File

@ -0,0 +1,10 @@
1163751742
1381373672
2136511328
3694931569
7463417111
1319128137
1359912421
3125421639
1293138521
2311944581

229
crates/day15/src/main.rs Normal file
View File

@ -0,0 +1,229 @@
use anyhow::{anyhow, Result};
use common::instrument;
use std::cmp::{Ord, Ordering, PartialOrd};
use std::collections::{BinaryHeap, HashMap};
use std::convert::From;
const INPUT: &str = include_str!("input/input.txt");
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
struct Point {
x: i32,
y: i32,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
struct OpenPoint {
x: i32,
y: i32,
f_score: i32,
}
impl Ord for OpenPoint {
fn cmp(&self, other: &Self) -> Ordering {
other.f_score.cmp(&self.f_score)
}
}
impl PartialOrd for OpenPoint {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl From<Point> for OpenPoint {
fn from(point: Point) -> Self {
OpenPoint {
x: point.x,
y: point.y,
f_score: 0,
}
}
}
impl From<OpenPoint> for Point {
fn from(open_point: OpenPoint) -> Self {
Point {
x: open_point.x,
y: open_point.y,
}
}
}
impl Point {
fn manhattan_distance(&self, other: &Point) -> usize {
((self.x - other.x).abs() + (self.y - other.y).abs()) as usize
}
}
fn reconstruct_path(came_from: &HashMap<Point, Point>, current: Point, start: Point) -> Vec<Point> {
let mut path = vec![current];
let mut current = current;
loop {
current = came_from[&current];
if current == start {
break;
}
path.push(current);
}
path
}
fn find_shortest_path(grid: &Vec<Vec<usize>>) -> Result<Vec<Point>> {
let destination = Point {
x: grid[0].len() as i32 - 1,
y: grid.len() as i32 - 1,
};
let mut open_list = BinaryHeap::new();
open_list.push(OpenPoint {
x: 0,
y: 0,
f_score: 0,
});
let mut came_from = HashMap::new();
let mut g_score = HashMap::new();
g_score.insert(Point { x: 0, y: 0 }, 0);
let mut f_score = HashMap::new();
f_score.insert(Point { x: 0, y: 0 }, 0);
// A* algorithm
while !open_list.is_empty() {
let current = open_list.pop().unwrap();
if current.x == destination.x && current.y == destination.y {
let path = reconstruct_path(&came_from, current.into(), Point { x: 0, y: 0 });
return Ok(path);
}
let mut neighbors = vec![];
if current.x > 0 {
neighbors.push(Point {
x: current.x - 1,
y: current.y,
});
}
if current.x < grid.len() as i32 - 1 {
neighbors.push(Point {
x: current.x + 1,
y: current.y,
});
}
if current.y > 0 {
neighbors.push(Point {
x: current.x,
y: current.y - 1,
});
}
if current.y < grid[0].len() as i32 - 1 {
neighbors.push(Point {
x: current.x,
y: current.y + 1,
});
}
for neighbor in neighbors {
let tentative_g_score =
g_score[&current.into()] + grid[neighbor.y as usize][neighbor.x as usize];
let neighbor_g_score = *g_score.get(&neighbor).unwrap_or(&std::usize::MAX);
if tentative_g_score < neighbor_g_score {
came_from.insert(neighbor, current.into());
g_score.insert(neighbor, tentative_g_score);
let neighbor_f_score =
tentative_g_score + neighbor.manhattan_distance(&destination);
f_score.insert(neighbor, neighbor_f_score);
if open_list
.iter()
.find(|&p| p.x == neighbor.x && p.y == neighbor.y)
== None
{
open_list.push(OpenPoint {
x: neighbor.x,
y: neighbor.y,
f_score: neighbor_f_score as i32,
});
}
}
}
}
Err(anyhow!("no path found"))
}
fn solve_part1(input: &str) -> Result<i32> {
let lines = input.trim().lines();
let mut grid = vec![];
for line in lines {
let mut row = vec![];
for c in line.chars() {
row.push(c.to_digit(10).ok_or(anyhow!("invalid risk level"))? as usize);
}
grid.push(row);
}
let path = find_shortest_path(&grid)?;
Ok(path
.iter()
.map(|p| grid[p.y as usize][p.x as usize] as i32)
.sum())
}
fn expand_grid(grid: &Vec<Vec<usize>>, n: usize) -> Vec<Vec<usize>> {
let mut new_grid = vec![];
for y in 0..(grid.len() * n) {
let mut new_row = vec![];
for x in 0..(grid[0].len() * n) {
let mut orig = grid[y % grid.len()][x % grid[0].len()];
orig += x / grid[0].len() + y / grid.len();
if orig > 9 {
orig = (orig % 10) + 1;
}
new_row.push(orig);
}
new_grid.push(new_row);
}
new_grid
}
fn solve_part2(input: &str) -> Result<i32> {
let lines = input.trim().lines();
let mut grid = vec![];
for line in lines {
let mut row = vec![];
for c in line.chars() {
row.push(c.to_digit(10).ok_or(anyhow!("invalid risk level"))? as usize);
}
grid.push(row);
}
let grid = expand_grid(&grid, 5);
let path = find_shortest_path(&grid)?;
Ok(path
.iter()
.map(|p| grid[p.y as usize][p.x as usize] as i32)
.sum())
}
fn main() {
instrument!(solve_part1(INPUT).unwrap(), solve_part2(INPUT).unwrap());
}
#[cfg(test)]
mod tests {
use super::*;
const TEST_INPUT: &str = include_str!("input/test.txt");
#[test]
fn solves_part1() {
assert_eq!(solve_part1(TEST_INPUT).unwrap(), 40);
}
#[test]
fn solves_part2() {
assert_eq!(solve_part2(TEST_INPUT).unwrap(), 315);
}
}