This commit is contained in:
Patrick Stevens
2021-12-21 14:35:12 +00:00
committed by GitHub
parent 73d4814ab4
commit bd7cfa8662
9 changed files with 334 additions and 0 deletions

8
Cargo.lock generated
View File

@@ -219,6 +219,14 @@ dependencies = [
"criterion",
]
[[package]]
name = "day_15"
version = "0.1.0"
dependencies = [
"array",
"criterion",
]
[[package]]
name = "day_16"
version = "0.1.0"

View File

@@ -14,6 +14,7 @@ members = [
"day_11",
"day_12",
"day_13",
"day_15",
"day_14",
"day_16",
"day_17",

View File

@@ -58,6 +58,14 @@ pub mod array {
None
}
}
pub fn get_mut(&mut self, row: usize, col: usize) -> Option<&mut T> {
let index = row * self.row_len + col;
if row < self.col_len() && col < self.row_len && index < self.elts.len() {
Some(&mut self.elts[index])
} else {
None
}
}
pub fn get_unsafe(&self, row: usize, col: usize) -> &T {
let index = row * self.row_len + col;
&self.elts[index]

17
day_15/Cargo.toml Normal file
View File

@@ -0,0 +1,17 @@
[package]
name = "day_15"
version = "0.1.0"
authors = ["Smaug123 <patrick+github@patrickstevens.co.uk>"]
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
array = { path = "../array" }
[dev-dependencies]
criterion = "0.3"
[[bench]]
name = "bench"
harness = false

19
day_15/benches/bench.rs Normal file
View File

@@ -0,0 +1,19 @@
use criterion::{black_box, criterion_group, criterion_main, Criterion};
use day_15::day_15::{input, part_1, part_2};
fn criterion_benchmark(c: &mut Criterion) {
let input = input();
c.bench_function("day 15 part 1", |b| {
b.iter(|| {
black_box(part_1(&input));
})
});
c.bench_function("day 15 part 2", |b| {
b.iter(|| {
black_box(part_2(&input));
})
});
}
criterion_group!(benches, criterion_benchmark);
criterion_main!(benches);

16
day_15/day15.m Normal file
View File

@@ -0,0 +1,16 @@
(* ::Package:: *)
actual=StringTrim@ReadString[StringJoin[NotebookDirectory[], "/input.txt"]];
numbers[s_]:=Map[FromDigits,Characters/@StringSplit[s],{2}];
edgeWeighted[numbers_]:=With[{vertices=Table[{x,y},{x,1,Length[numbers]},{y,1,Length[First@numbers]}]},With[{edges=UndirectedEdge@@@Flatten[Join[Table[{{i,j},{i+1,j}},{i,1,Length@numbers-1},{j,1,Length@First@numbers}],Table[{{i,j},{i,j+1}},{i,1,Length@numbers},{j,1,Length@First@numbers-1}]],1]},Graph[Flatten[Table[{x,y},{x,1,Length[numbers]},{y,1,Length[First@numbers]}],1],edges,EdgeWeight->(Extract[numbers,#[[1]]]+Extract[numbers,#[[2]]]&/@edges)
]]]
part1[numbers_]:=Total[Extract[numbers,#]&/@Rest@With[{g=edgeWeighted[numbers]},FindShortestPath[g,{1,1},Dimensions[numbers],Method->"Dijkstra"]]]
part1[numbers[actual]]
With[{original=numbers[actual]},With[{numbers=Mod[Flatten[Map[Flatten,Transpose/@Table[original+i+j,{i,0,4},{j,0,4}],{2}],1],9,1]},part1@numbers]]

100
day_15/input.txt Normal file
View File

@@ -0,0 +1,100 @@
3389468957195191621612774424781291213569193831469897426487912119997336538328929529524567932999764397
9696723499379962193291388224211989319681442926919991941367126322911153337169884311818994691998142818
7814276813122519516197651882922789689697678423766816984171349893557699216293531566171577752862999189
8695248971983831118888345832382379869828991721417166494233961814479616298512617993916199484169768863
9438388913239281978754611917891972779819131371394848464949495975929194988978263297929499659581689931
1969369226881869218169885835118239749691599946731678781981449349938381248989441932791317925352759942
7123779172193954721688869139758196888794211367981479259955577415226913521927979417918717189391166677
7943535198721159911645992488162197692426999278117467587266221897325185828271274831492759999389981518
7887619766952832911156929833966381186297622871182811544331199411149635721326489819882214998153596213
4648859361999318828881375191941748791136972816261717334561674919882252411527611484116833231296411618
2212833947623292922961462362496994195995499987579663947111959949488113399114998685977193848697511116
3969643397751161263327478692813671171847775693111943664189164399861484521889181142821292229863551167
8151199761993969924113338516875823735898546129898975198189479571912373955912635949179871968717523778
1414763299794192255175491986733883171469919251932778658489558798293791213523573113651247139189979782
2914799981456921799818211127852862317673886288925766299289279774929166126931375969181699919238741667
2698477149739411976291599914938267421975388151967614241699299899988245295611437935247966657591969778
5111685483932883334989653569619111635366491297319621661611923917367917419122271997221566146467196419
1788715511737849818313857123597911255911246797868723244979271345629978187199964189721899894769193943
7799127514813556529152157494481412175528363357891151919575984268994117588197854536971298218293132975
5191589471484411568918992274115248889993179919351221221161883968825191864548331595791166197198127399
7134111721142222921564942388988611329462613295296451198969241921221266311131154727752149669939921451
9231215817921161996961419339655958616296399432964859979861791388899829432588951126486912217259167832
7288383496924661955553368918859194248378665392455721328875918986215811121839385268238274922337419599
5398269731871319317925166181127791822121922995312494296518745191129851711261599329258446769978513371
7519911347619499998183144921992923383195118218717115338898919755349399522578587858498623729969364439
7799129986113515119414994929919839999292571679437875189815112227229198341931879969713161977291229411
7935126516249816371388747122241374929559962158944822262859887411378978918828979468577636757199381622
9619932788677832767569586827293945491235991219829538299775962554614497461119146288916992936563148974
9274593916115941959559369931419911191379991777178297819173418914511525194974235391698919979979326488
4197882683459929888814912339873331135564287344534278415271819298251894178819155117432111915162524437
5433115493211699435793985889978218741372736831392184941927199689192129119118358892894452459744481878
1657317855321186979916212557229189126829384985198684586779197782862729537145651985526969534395252897
2116541971938549922767831913227758894366215369534934499842711566152199691337438913318633821118197342
1983831969661227223991853684189749239981961379472232986914971478185157749262379825981151116111391621
4151918985339445215718286389479225192892875919181211445498736766932899588886875199965186938911692151
9589959948482774911319126412426417169841631999115519761879839629477452625111738644112591572966125182
5966781638868275174869483219311675196979665689337619115451698221599569139959921748975692418154161215
9139294185336919134967481513876592918798682562619962843826889317923849891328947261161198818175918218
8953314967869319325225222819348241292514342588988219916851746196188279568772199878152119741943687547
3623975797337114736793127911219891616989941371351811389988939226193113299227559114939998824933596189
4792198337789991513998111115624229327919716399125683154671864613488996913763986297989392214918799549
9582156162119767191968293111982148921117852365798973396484976367431679823788317266841239191591867913
1832427961318389595862199619377811881597987152846538794932933914386173429144926381195992913531469974
9691161819686318892917368671921731596121389837296929711715188131389941519996979627999199591991447237
9215185378797971821395199789981278927982378673997259983291882657292328181898316839993294691643299918
5923989193525399996283385481919987227168623211393319139671359456396994159292245311434669927135312996
1884625283194198884964982369891828185782113217292219114831166257469135571961533825926199954629417349
6111949696979799811373595191234733819562148384923973895979211192836681941894691812541844218336511339
1249191116838794499929495172321833926959698393418491245194131441699723727197797164925165634819657988
2759999328431922998429144768748826516915128299397318379136812516257417734757929719859994463953714737
8412564991848221147123362451415229129914455129828797121813332839683412625979532529977754174985173312
9742465485298332327612945182849383772991183957251966333793827252746988179943996447941239888251319238
3671711995796174979139941113938431582899299195925181152951151397591597629215954959631917337368878879
8572911294992269273413272895293193181435721329699969666966951818961271149911584782639851838411128653
8639931138942796916933259811589581615765937985989129659479818479119983893281668137497597192317551992
6929874911682426233195283262476189294111737918136624982649316917143913141994718522713155795784823193
2145599768916692449167618961187975991119259336856741211277385399699249992884451697138386924211373474
1873372796987436943131312835256225161714919262191652723119832296197636121922849295821535283538916762
2265491922334921624297523951291195949212943689816426171136931252288434457431397165991971931349772995
7948989914979949319739929811162848197242594572224894223185178399413154839347668173522499315412849841
6512298397749956981193929432127349154191232992723791712799399549897128999753472377332829713939844361
8318256681893818447127522891199585141899915919979948991198619491619713884191379396176914496755588291
9719173813321238564133749261368914593111277529319912988479688926274151821671943875362235784319616865
7311898511997891581895653229799294836812924356416919365514454829976974192691985278349914191448329111
8817168994132999198368881732584351379817759819491141482294889256135317795783961892249539482715816792
5896213329918833292293911783651125119972217853144928455791518991884939185238272581218289359229314319
3617297154332885617165178984393881998243916999482731981356353638517787187224712118912138456814919133
3535392788469846427491259255498814338119727966121371696135591892721238769329394666922458135939662918
8978713293695632285874319439519191528111993197233921631728174431879983883769192996395656124959349113
3992992899774912938872961918235813659794322493593751297111889487248153992595796911879156514968951999
1471382318485251196198453195432318184626959713594972656999554854114159575689998859276493989363544466
1914898952712968817183517192313388723953142976199329737616825511227233527517211968929219797929437618
1272193394839879255172979571591474229318787739666234782976964698287147711148116199239659167242671661
3654331179111349792874431999652732599285596829861644244916181997299656916269261632958231258617213317
5271993216416317872662593141986931579961338264743488457429991961919194199494921524355223119718991439
8891127916699131371791479939236581692148538871244496989159269311413633195198718812918128848518994988
9813245138697623492999496366863719931948111957276344647113779158171811823828433971481294592115619244
7516259831363511251771637699119734921996998577511252532589636172425851888377191246923711967978189775
6111913728638886247111116979292975943492991527751161823641178386991291519931894872596111234978997189
6717611188354611555241979133156559369829996819272871115282379926296281342657121174182835474195629231
9878715996669514192488194781194942751813814811131235169867122578931899198195111198493947432296924683
6438791983961828369724259934167221814427296949178238944938113283325719271944992987711875824461298118
5195451989571871525468815787519187119118618952998991277251131269781141749196471955457995478697886443
2959822826382133121882563591589713899811521478342383738916889783729421618338343491998126218314915171
2631923589942121913799763789216419692361914546181659457617782336821942122188811851383138241753649489
9992289429129341984433974315622294639852937888122388158231848984421542369311819216942259519936215481
3349464198938889131791931113242889116216542154192949399985916979215922819649429733791931278834994712
2711163996265866311352189994619383246984822916993759144813151815299488934194181213986395739964258137
2174745854781389832416122151952317564328122421644357343168175979482567885291413293993996938675362939
7579317491998958176743892229898112525411948981982915814899523891116829898692464736273842737917296699
3943981243848348897569424647878277184921348331489927195159961856893716141223583261711275595691219931
3894196153581992667198693188995168422145894399925925177632929527319482971447681924549328174989362194
1938318592297692293779317816386969248919752566557915139919614121911113231921769686888496487914655978
6895761659942389992173411367761419996886179248923636115218383311645919491759834821511123413585319447
1714992394989415348976956296915691959991463176292895154115458928981111111658281985886256787111317281
6111427283128793746188988196974159169972211989199319534919763791982577916819976818935222459811561994
9112369767928176941992947719126492789972131111267191921699379681595192912698118983672353699932949194
3691316978229429439969257627496969959919188996129916822468586994891228183171556583538735756981191184
1889273619911397689813219925751671129554482532979374999962138151188171289238825995754135581779326797
2865692499363943591911977961231313686973849878387599963859497937346925669637729745891898997393123146

158
day_15/src/lib.rs Normal file
View File

@@ -0,0 +1,158 @@
pub mod day_15 {
use ::array::array::*;
use std::cmp::min;
fn surrounding<T>(data: &Array<T>, row: usize, col: usize, output: &mut Vec<(usize, usize)>) {
if row > 0 {
output.push((row - 1, col));
}
if row < data.col_len() - 1 {
output.push((row + 1, col));
}
if col > 0 {
output.push((row, col - 1));
}
if col < data.row_len() - 1 {
output.push((row, col + 1));
}
}
fn solve(data: &Array<u8>) -> u32 {
let mut visited: Array<bool> = Array::make_default(data.row_len(), data.col_len(), false);
let mut distances: Array<u32> =
Array::make_default(data.row_len(), data.col_len(), u32::MAX);
let mut to_visit = vec![(0, 0)];
distances.set(0, 0, 0);
let mut where_to_go = Vec::with_capacity(4);
'outer: while let Some((current_row, current_col)) = to_visit.pop() {
if current_row + 1 == data.col_len() && current_col + 1 == data.row_len() {
return *distances.get_unsafe(current_row, current_col);
}
match visited.get_mut(current_row, current_col) {
None => {
panic!("Bounds error");
}
Some(slot) => {
if *slot {
continue 'outer;
} else {
*slot = true;
}
}
}
let current_distance = *distances.get_unsafe(current_row, current_col);
where_to_go.resize(0, (0, 0));
surrounding(data, current_row, current_col, &mut where_to_go);
for &(row, col) in where_to_go.iter() {
if !visited.get_unsafe(row, col) {
to_visit.push((row, col));
let distance =
data.get_unsafe(row, col) + data.get_unsafe(current_row, current_col);
let distance_via_here = current_distance + distance as u32;
distances.apply_at(row, col, |i| min(distance_via_here, i))
}
}
to_visit.sort_by_key(|v| u32::MAX - distances.get_unsafe(v.0, v.1));
}
panic!("Should have finished");
}
pub(crate) fn parse(s: &str) -> Array<u8> {
Array::from_rows(
s.split('\n')
.map(|line| line.chars().map(|c| char::to_digit(c, 10).unwrap() as u8)),
)
}
pub fn input() -> Array<u8> {
parse(include_str!("../input.txt"))
}
pub fn part_1(data: &Array<u8>) -> u32 {
let edge_weight = solve(data);
let first_node = *data.get_unsafe(0, 0) as u32;
let last_node = *data.get_unsafe(data.row_len() - 1, data.col_len() - 1) as u32;
(edge_weight + first_node + last_node) / 2 - first_node
}
pub(crate) fn quintuple(arr: &Array<u8>) -> Array<u8> {
let row_len = 5 * arr.row_len();
let elts = vec![0u8; row_len * row_len];
let mut result = Array::make(elts, row_len);
for row in 0..arr.col_len() {
for col in 0..arr.row_len() {
for x in 0..5 {
for y in 0..5 {
result.set(
arr.row_len() * x + row,
arr.col_len() * y + col,
(arr.get_unsafe(row, col) + (x as u8) + (y as u8) - 1) % 9 + 1,
);
}
}
}
}
result
}
pub fn part_2(data: &Array<u8>) -> u32 {
let data = quintuple(data);
let edge_weight = solve(&data);
let first_node = *data.get_unsafe(0, 0) as u32;
let last_node = *data.get_unsafe(data.row_len() - 1, data.col_len() - 1) as u32;
(edge_weight + first_node + last_node) / 2 - first_node
}
}
#[cfg(test)]
mod tests {
use super::day_15::*;
static TEST_INPUT: &str = "1163751742
1381373672
2136511328
3694931569
7463417111
1319128137
1359912421
3125421639
1293138521
2311944581";
#[test]
fn part1_known() {
let data = parse(TEST_INPUT);
assert_eq!(part_1(&data), 40);
}
#[test]
fn part2_known() {
let data = parse(TEST_INPUT);
assert_eq!(part_2(&data), 315);
}
#[test]
fn test_day_15() {
let input = input();
assert_eq!(part_1(&input), 523);
assert_eq!(part_2(&input), 2876);
}
}

7
day_15/src/main.rs Normal file
View File

@@ -0,0 +1,7 @@
use day_15::day_15::{input, part_1, part_2};
fn main() {
let input = input();
println!("part 1 => {}", part_1(&input));
println!("part 2 => {}", part_2(&input));
}