Part 1 and first pass at Part 2

This commit is contained in:
2021-12-15 20:20:15 +00:00
parent 6b21ea4aff
commit b0e761fb7a
7 changed files with 407 additions and 0 deletions

View File

@@ -153,3 +153,13 @@ The solution for "fourteen" is:
The result of subtracting the least from most common element quantities is 2988 The result of subtracting the least from most common element quantities is 2988
The result of subtracting the least from most common element quantities is 3572761917024 The result of subtracting the least from most common element quantities is 3572761917024
``` ```
### Day fifteen
```sh
$ ./aoc2021 --fifteen
The solution for "fifteen" is:
fifteen part 1 answer for path
fifteen part 2 answer for path
```

100
fifteen/input.txt Normal file
View File

@@ -0,0 +1,100 @@
1153122486338196417261639921288211131723142991381714663988573539371125147579911789799911191116969182
1831332932365721112271938859551961274184513439211372318789319176946137219492492161941188122228928142
9821911543414142186827941122266167714126412612261328558992198212729611567923298114131222451713511114
7246861617121926197913771333862216431691242331821373133472917112415411291112194329821255594119385913
7283532811518311511133564162553362112249591513461311252729218443397781539589433111319711824661393631
2515929137212718342949516922111713621859318118719617839125124564721161658335944181553941811143591517
4916512552144322517215234299958319381621661767349167411222321248229439251953192958644239143882919241
6262117322113477913692595649873914143546632433711128717141141195552948491953485631229194119276499991
7392251899873812797958691238437453551415231331821364182879918291981738573962231152511911211128951113
8413992251188993837397124261942199712837511841216512261395311785116811331719185479137512367447923291
5231148122926582218424829117852548196215169569393712471373474748341292612868417935562413892295951885
6969394124432223195175331296521928139597331582718251211495645114941612246194231312174117214121281842
1492115983511981562257418211112925117322921195483112122256639228399618419541416852185938991328915818
3337387528424632949433449211831892186689931141431821341112121116121183221372428184716111222586158651
2919993831163121652312168296893876448879562949946693212289822132922233191147264817817431124414532533
9831131365513121681981321111241225246211721245114513343139123311189247841338544122968113145391142716
1727694314953352984564533684197836278119128336766459163262254212898918649112624992813951781316416374
2271812917172151781117223114852112121981121667671421934421226898295554752996914271128911169789451951
9641181231223141385164135392637559471954819529821233561311577143643837514229221871189471954194331152
4842773719613551934224188641425166389122136165128121415358911721153164127212813948168736781136952951
1192227966237198835311112231914836119223535631325132172552427754922112812179423656275381194611522453
4587521661134142224185212119671223232647264672526518611961218313988518799959611424294177988911237867
7841978128159981542211119531397179123564484381479727821915161363181216177352158299813648446813627222
7284166795958241131999192919211621771144435542434154129323533329121215444282759763242637299473619699
1521878281243112584389365171394192883659218227373853328197872435319181781919941925172732491338886311
1327321441516991964782129484116368713248197522187147122388963111996334499727625711211235126217275463
5432221784759463981982328941214217778116531411971739126861352255217191611697312757994113151311379972
1185912419912167768598675227235243957241898718929234342122112138667448683289595212416151634918119782
2142391197693165425931997914283877473934922668732952746725116377382215211222574165995121111118383226
2517671922159312542191175127158214971341213911213276212516415975771618811321511144775331189114464662
7422195152192114261215487181219928252132916876218849814118182116115931338892173123147871155216241119
3619695411396123442155212519261891139921251199959962859246511384671182317569141243719313574613299114
2895333123772993112294182624661491247795159971883633469119158351982981542649324118914796267121748913
1421145424229377289371813129244589145113287748254253711637741529919416291278816369198475199772891934
4226139942429431915575192843585749419348133173935216599874822673919238822771191128122524833751214529
1682417751943991485271671248268311378571948341453293291196141934239152143595141717431161329855424112
9916921853141162653286394526948121272378729683198391723494146711544133983626379417921189376352821798
3251721727717131197339261311211519541459852173796114841169131848229719476992898439988142411881982514
4224411911215323811873118144131911362211323994194273231611315238461136131411252251162414111299942115
2245998155138161121631272285319936718281123752141998833128632147447117622119239893148242825136988411
5128199191117746931424197696535944336182191931232292669562695112789951271493241291449919211342319956
6185982121672329189115713515854662969113811769468312383127983222331916531821851915411131158716583266
5447295461711381231589918947462282687649213121842921247116618391182167591292292272427141281715111177
8257924948412473451961749898696413137392994416792374818227237143259116197488773961321624141163921432
5189182291437314198489212141482184531697461226931512711191277526274712938812991613191947812232211244
4555193184311911877999628197321551669874119131381183472179843972338461241911119924731168169352182272
1121437621439149119353295941221222611786169917291122315558611419191633395499286111392381131171511238
3181921181713184161942383164918982475421419929329239389548923261242417419233827235774153744131399151
2144212113563135873312739193234226974131375159978272831447529333649424911425997613845276711174127394
3139444361591195812958262711719931339591119823111113659752771219379921513182322111739482111579992212
5621114341514728539451953111111724132613731214322289351224233177342291112529731353511549332152218981
6158168164191463855184279714113662914367391459179668815811157124186552341548726599639264298312521815
1995166266961996427961626535695212999191152112511338187611994115221111513691288611241921111251372396
1339761931754125912894291611219167392229911558394529712234844524138351824911642926117836229449412319
9127349377251112496211472777128795852299174781996397114134149188119193322618691616951273511925125149
8979991927511499882118151229977284915581711491442571271831929283464123921696618123459172952156541118
1911692955379514126841178174387511771789182282127314533841585231141954116191778276825221831612429254
5812355192199983562136559621645794551755421236216311141149191254313741187262232164511315391297811915
3424115732536482892978161186279711991592926127111589527519294376927741975118126955891355141746112114
6989941658111289514721269122153856231312841221973781139894173114171591227833319376143957344117411911
6125319278191932229114977252161577595177236842461172428859131892491678152164849198117325377432911476
1152159324115134285596152231419112191947931122416535331212222762281719735281322382683941829919252797
1119721171315374228473139951219963744542691955341851975111136422261596313992998971487819823291188481
7916691142991816614421279131181771221333191348939869225827422531914334297979111781117184291912141817
4459327512328523319571281171326141578961259819944448411558661132918284758431913397353129322141161339
2636366417937791462122113461636413998893541599942374691221751914312218911394582119131724772161614249
2312134166373181653911821772162314821142231391492122319111729983112421444715911629144339121416957937
3112516582317416535542536957174341267787173494338391217911299591219692263281699341161832522294199592
9514591666441193718119658181314241938166223118279113851527114813726452723842267929929348492111811581
2482729124382111776179548733255881848149314161382118317221111921159882699921428496911916531781511634
9673188569811459713271234169339644147411196161312836419131114224582591681121732551983658361231121738
5977261429276572591351918817394787862812237116862142154391916283123565283389128193466927821786719949
1769231445614929166298921531456368161915897211818781845929893127147256121829334316761162311125197837
1312932111292124723831423127589975348261278421245946222431414328266141181139541218291313371199864618
1591541125718121791926128149145611995157614226342145453466331146123719411716214432222151824877286273
5619772119639321277117794132142411693117313872211776175416651697194197314115755297937932111148312514
3178155419234246512532322711217369829144825612481941883499963679121511192214851616393725262185717671
8114544152321812691913671222116334143125135245317392176495119442215315158941951195112914646111416558
2741424121962339159791233465491165831161141431641127346424975111522251556164932982924154345265421893
9921292358581466829119129911354441116986795112151124693382512674629191214183823931133116279292839481
4569992111222111767136498792647332989342421348986559111618194724271412113395213251221446621936113217
4991122344121493911982135121517399926352621891628211138999762133631115524112414391988299737366143123
1114219232723168147329499525731115791152145213242183484163395711685154619941295185822161212821127794
3839939524162212272145271115941119628111292192143171182921748857216541211912191929681297597929989911
6189222318123913691725491531195561764199223114289691819733939824312544261311413928241912419255471755
6426739442179681969621433347831187114554482194517792954314812523872919511933951481153159254111697312
3891136638118997612371161161869992758221428676819193193631251844929339437511925493964819195151911142
3115528121186224125618416185811129492665191334214154857416725217848287113213313571291989451911312351
1921697432735261814811926199115788283324123249786652194311225419818513851175191913114233615261679173
9444991493136334111115319771955169591434195411111175815119829517874288512561129573999727849941111891
1431112211573298299618391113146347462491189192712317692165138111135921811621112921281114883152314218
5349597921218431142281944271195411131831918391119511453181163891916131323533571231586827199329874375
2393311319453249344541783217229449844183323339879189832259959321537131883822116122414429411226898557
5457346279314981225362682181133799953141791522219253884328373198344561547931335524431911513277866156
9699896735252183122231391818121491312934119311392547291169316419871163336631292698139515916993934313
8556743922581192811645225163415825162574946272881497914233171916774511883981111996335911294624327449
7521896193918149224732111989318369361944639558148182889252323156955979551215231329134223563528193297
1911494977559119125389742991144919361368163938188656739221192361834613121494215789387959266616116631
9511636215215555892846453398163358213162129919192181114219891142443311555291982463217261131119391179
1549621141231921135259218425986586892253161313771915914851811321611989191411321126995515519721279591

25
fifteen/main.go Normal file
View File

@@ -0,0 +1,25 @@
package fifteen
import "fmt"
type Fifteen struct {
path path
}
func Init(filepath string) *Fifteen {
fifteen := &Fifteen{
path: path{},
}
fifteen.path.load(filepath)
return fifteen
}
func (d *Fifteen) Answer() string {
return fmt.Sprintf("The total risk of the least risky path is %d", d.path.totalRisk())
}
func (d *Fifteen) FollowUp() string {
scaled := d.path.scale(5, 5)
return fmt.Sprintf("The total risk of the least risky path is %d", scaled.totalRisk())
}

215
fifteen/path.go Normal file
View File

@@ -0,0 +1,215 @@
package fifteen
import (
"bufio"
"fmt"
"os"
"strconv"
"strings"
)
type path struct {
riskLevel [][]int
width int
height int
}
type point struct {
x int
y int
}
func (p *path) load(filename string) error {
file, err := os.Open(filename)
if err != nil {
return err
}
defer file.Close()
scanner := bufio.NewScanner(file)
p.riskLevel = [][]int{}
for scanner.Scan() {
row := []int{}
for _, n := range strings.Split(scanner.Text(), "") {
v, err := strconv.Atoi(string(n))
if err != nil {
return err
}
row = append(row, v)
}
p.riskLevel = append(p.riskLevel, row)
}
p.height = len(p.riskLevel)
p.width = len(p.riskLevel[0])
return nil
}
func (p *path) scale(sizeX int, sizeY int) *path {
scaledPath := &path{
width: p.width * sizeX,
height: p.height * sizeY,
}
scaledPath.riskLevel = make([][]int, scaledPath.height)
for i := 0; i < scaledPath.height; i++ {
scaledPath.riskLevel[i] = make([]int, scaledPath.width)
}
for i := 0; i < sizeX; i++ {
for j := 0; j < sizeY; j++ {
for y := 0; y < p.height; y++ {
for x := 0; x < p.width; x++ {
risk := p.riskLevel[y][x] + i + j
for risk > 9 {
risk -= 9
}
scaledPath.riskLevel[(j*p.height)+y][(i*p.width)+x] = risk
}
}
}
}
return scaledPath
}
func (p *path) print() {
for y := 0; y < p.height; y++ {
row := ""
for x := 0; x < p.width; x++ {
row += fmt.Sprintf("%d", p.riskLevel[y][x])
}
fmt.Println(row)
}
}
func (p *path) totalRisk() int {
start := point{
x: 0,
y: 0,
}
end := point{
x: p.width - 1,
y: p.height - 1,
}
path := p.path(start, end)
total := 0
for i, point := range path {
if i == 0 {
continue
}
total += p.riskLevel[point.y][point.x]
}
return total
}
func minValue(distance map[point]int, nodes []point) (point, []point) {
var min *point
remaining := []point{}
for i := range nodes {
if min == nil {
min = &nodes[i]
continue
}
if distance[nodes[i]] < distance[*min] {
remaining = append(remaining, *min)
min = &nodes[i]
} else {
remaining = append(remaining, nodes[i])
}
}
return *min, remaining
}
func contains(nodes []point, x int, y int) bool {
for _, n := range nodes {
if n.x == x && n.y == y {
return true
}
}
return false
}
func (p *path) path(start point, end point) []point {
dist := map[point]int{}
prev := map[point]point{}
nodes := []point{}
for y := 0; y < p.height; y++ {
for x := 0; x < p.width; x++ {
point := point{x: x, y: y}
// Virtually infinite for worst case
dist[point] = 10 * (p.width + p.height)
nodes = append(nodes, point)
}
}
dist[start] = 0
for len(nodes) > 0 {
current, newNodes := minValue(dist, nodes)
// Check neigbours
neighbours := []point{}
// left
if current.x > 0 && contains(newNodes, current.x-1, current.y) {
left := point{
x: current.x - 1,
y: current.y,
}
neighbours = append(neighbours, left)
}
// up
if current.y > 0 && contains(newNodes, current.x, current.y-1) {
up := point{
x: current.x,
y: current.y - 1,
}
neighbours = append(neighbours, up)
}
// right
if current.x < p.width-1 && contains(newNodes, current.x+1, current.y) {
right := point{
x: current.x + 1,
y: current.y,
}
neighbours = append(neighbours, right)
}
// down
if current.y < p.height-1 && contains(newNodes, current.x, current.y+1) {
down := point{
x: current.x,
y: current.y + 1,
}
neighbours = append(neighbours, down)
}
for _, n := range neighbours {
cost := dist[current] + p.riskLevel[n.y][n.x]
if cost < dist[n] {
dist[n] = cost
prev[n] = current
}
}
nodes = newNodes
}
path := []point{end}
index := end
for index != start {
prefix := []point{prev[index]}
path = append(prefix, path...)
index = prev[index]
}
return path
}

44
fifteen/path_test.go Normal file
View File

@@ -0,0 +1,44 @@
package fifteen
import "testing"
func Test_read(t *testing.T) {
p := path{}
if err := p.load("test_input.txt"); err != nil {
t.Log(err)
t.FailNow()
}
if len(p.riskLevel) != 10 {
t.Logf("Expected 10 rows, found %d", len(p.riskLevel))
t.Fail()
}
if len(p.riskLevel[0]) != 10 {
t.Logf("Expected 10 rows, found %d", len(p.riskLevel[0]))
t.Fail()
}
}
func Test_totalRisk(t *testing.T) {
p := path{}
p.load("test_input.txt")
if value := p.totalRisk(); value != 40 {
t.Logf("Expected a total risk of 40, found %d", value)
t.Fail()
}
}
func Test_totalRiskScaled(t *testing.T) {
p := path{}
p.load("test_input.txt")
p = *p.scale(5, 5)
p.print()
if value := p.totalRisk(); value != 315 {
t.Logf("Expected a total risk of 315, found %d", value)
t.Fail()
}
}

10
fifteen/test_input.txt Normal file
View File

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

View File

@@ -7,6 +7,7 @@ import (
"unsupervised.ca/aoc2021/eight" "unsupervised.ca/aoc2021/eight"
"unsupervised.ca/aoc2021/eleven" "unsupervised.ca/aoc2021/eleven"
"unsupervised.ca/aoc2021/fifteen"
"unsupervised.ca/aoc2021/five" "unsupervised.ca/aoc2021/five"
"unsupervised.ca/aoc2021/four" "unsupervised.ca/aoc2021/four"
"unsupervised.ca/aoc2021/fourteen" "unsupervised.ca/aoc2021/fourteen"
@@ -64,6 +65,8 @@ func main() {
day = thirteen.Init("thirteen/input.txt") day = thirteen.Init("thirteen/input.txt")
case "fourteen": case "fourteen":
day = fourteen.Init("fourteen/input.txt") day = fourteen.Init("fourteen/input.txt")
case "fifteen":
day = fifteen.Init("fifteen/input.txt")
default: default:
fmt.Printf("%q does not have a solution.\n", flagParts[1]) fmt.Printf("%q does not have a solution.\n", flagParts[1])
help() help()