From 2590aee0dd4967b3ff2f5cedf54341eb582ce9ba Mon Sep 17 00:00:00 2001 From: oabrivard Date: Mon, 4 Dec 2023 00:07:34 +0100 Subject: [PATCH] Completed both parts of Day 3 puzzle --- day3/day3.go | 232 ++++++++++++++++++++++++++++++++++++++++++++++ day3/day3_test.go | 67 +++++++++++++ day3/input.txt | 140 ++++++++++++++++++++++++++++ 3 files changed, 439 insertions(+) create mode 100644 day3/day3.go create mode 100644 day3/day3_test.go create mode 100644 day3/input.txt diff --git a/day3/day3.go b/day3/day3.go new file mode 100644 index 0000000..0833202 --- /dev/null +++ b/day3/day3.go @@ -0,0 +1,232 @@ +package day3 + +import ( + "fmt" + "strconv" +) + +type Number struct { + value int + l int + js int + je int +} + +type Gear struct { + l int + c int +} + +var gears map[Gear]*[]*Number + +func parseNumber(lineNum int, line string, start int) *Number { + js := start + + // move to first digit + for ; js < len(line); js++ { + + c := line[js] + + if c >= '0' && c <= '9' { + break + } + } + + // return nil if no digit + if js == len(line) { + return nil + } + + je := js + 1 + + // move to last digit in sequence + for ; je < len(line); je++ { + + c := line[je] + + if c < '0' || c > '9' { + break + } + } + + //fmt.Println("-->", js, je) + num, err := strconv.Atoi(line[js:je]) + if err != nil { + fmt.Println(err) + } + + return &Number{ + value: num, + l: lineNum, + js: js, + je: je - 1, + } +} + +func hasGearInRange(lineNum int, line string, start int, end int) *Gear { + i := start - 1 + if i < 1 { + i = 0 + } + + for ; i < len(line) && i <= end+1; i++ { + c := line[i] + + if (c < '0' || c > '9') && c != '.' { + return &Gear{ + l: lineNum, + c: i, + } + } + } + + return nil +} + +func hasAdjacentSymbol(n *Number, before string, line string, after string) *Gear { + + if before != "" { + g := hasGearInRange(n.l-1, before, n.js, n.je) + + if g != nil { + return g + } + } + + g := hasGearInRange(n.l, line, n.js, n.je) + if g != nil { + return g + } + + if after != "" { + g := hasGearInRange(n.l+1, after, n.js, n.je) + + if g != nil { + return g + } + } + + return nil +} + +func PartNumberSum(lines []string) int { + result := 0 + + for i, line := range lines { + + for j := 0; j < len(line); { + num := parseNumber(i, line, j) + + if num == nil { + break // no new number on this line + } + + // number found + before := "" + after := "" + + if i > 0 { + before = lines[i-1] + } + + if i < len(lines)-1 { + after = lines[i+1] + } + + g := hasAdjacentSymbol(num, before, line, after) + b := g != nil + fmt.Printf("%t : Found %d at line %d between col %d and col %d\n", b, num.value, i, num.js, num.je) + if b { + result += num.value + } + + // move cursor to the first char following the number + j = num.je + 1 + } + } + + return result +} + +func markGearInRange(n *Number, lineNum int, line string, start int, end int) { + i := start - 1 + if i < 1 { + i = 0 + } + + for ; i < len(line) && i <= end+1; i++ { + c := line[i] + + if (c < '0' || c > '9') && c != '.' { + key := Gear{ + l: lineNum, + c: i, + } + + nums, ok := gears[key] + if !ok { + newNums := make([]*Number, 0) + nums = &newNums + gears[key] = nums + } + newNums := append(*nums, n) + gears[key] = &newNums + } + } +} + +func markAdjacentSymbols(n *Number, before string, line string, after string) { + + if before != "" { + markGearInRange(n, n.l-1, before, n.js, n.je) + } + + markGearInRange(n, n.l, line, n.js, n.je) + + if after != "" { + markGearInRange(n, n.l+1, after, n.js, n.je) + } +} + +func GearRatioSum(lines []string) int64 { + result := int64(0) + gears = make(map[Gear]*[]*Number) + + for i, line := range lines { + + for j := 0; j < len(line); { + num := parseNumber(i, line, j) + + if num == nil { + break // no new number on this line + } + + // number found + before := "" + after := "" + + if i > 0 { + before = lines[i-1] + } + + if i < len(lines)-1 { + after = lines[i+1] + } + + markAdjacentSymbols(num, before, line, after) + + // move cursor to the first char following the number + j = num.je + 1 + } + } + + for k, v := range gears { + t := *v + if len(t) == 2 { + ratio := t[0].value * t[1].value + fmt.Printf("Found gear at line %d and col %d with ratio %v\n", k.l, k.c, ratio) + result += int64(ratio) + } + } + return result +} diff --git a/day3/day3_test.go b/day3/day3_test.go new file mode 100644 index 0000000..81bdd92 --- /dev/null +++ b/day3/day3_test.go @@ -0,0 +1,67 @@ +package day3 + +import ( + "testing" + + "gitea.paas.celticinfo.fr/oabrivard/aoc2023/utils" +) + +func TestPartNumberSum(t *testing.T) { + lines := []string{ + "467..114..", + "...*......", + "..35..633.", + "......#...", + "617*......", + ".....+.58.", + "..592.....", + "......755.", + "...$.*....", + ".664.598..", + } + + result := PartNumberSum(lines) + + if result != 4361 { + t.Fatalf("expected 4361, got %d", result) + } +} + +func TestPartNumberWithInput(t *testing.T) { + lines := utils.ReadLines("input.txt") + result := PartNumberSum(lines) + + if result != 532331 { + t.Fatalf("expected 532331, got %d", result) + } +} + +func TestGearRatioSum(t *testing.T) { + lines := []string{ + "467..114..", + "...*......", + "..35..633.", + "......#...", + "617*......", + ".....+.58.", + "..592.....", + "......755.", + "...$.*....", + ".664.598..", + } + + result := GearRatioSum(lines) + + if result != 467835 { + t.Fatalf("expected 467835, got %d", result) + } +} + +func TestGearRatioSumWithInput(t *testing.T) { + lines := utils.ReadLines("input.txt") + result := GearRatioSum(lines) + + if result != 82301120 { + t.Fatalf("expected 82301120, got %d", result) + } +} diff --git a/day3/input.txt b/day3/input.txt new file mode 100644 index 0000000..30b7cbd --- /dev/null +++ b/day3/input.txt @@ -0,0 +1,140 @@ +........440...............418..643.....438......740.261......................................727...........................870.............. +...............338.............-........*.......*.......34&.$........@.....&742................................353..26.......*...188...238.. +..................*369.....334.......624..749....533........690...894...........466......../....&......294....................1............. +..338....367............................................../...............565..@....456.357....873........#..=...916.#60.................... +........*...............*......402.......473..%400..+415.165....364........*.....$....*......*...............410...=..........#........#.... +..342....886....122..457..866........438....*.....................*........739...716...131....561..748.......................206......155... +.................-.........../..........@.185..78.556........120..856..436............................*.....%730.307....382#................ +...................352...........................*....282.......$...........*......716......904*588....807.........*........................ +.590.......225....*......610...............&434......*...................805.878......*......................#539..412......452......993.... +....*407...................%............=..........489..............#..................390....621.708........................-.............. +..........542#...880...@.......*.....%...877..................264....3........750.............../.*.............-.......570.......&......... +.....290...........@.540....167.873.970................669.....#.....................169...........718....&...240......*........764.400..... +.......*......639.......................103.....@.......*..................................731.........413...........974...............*.... +......174........#..-331....&................465.............428...$118.....................*......714.......209*418........*....@......513. +...........869.............120.....101................379...*..................488.579...344......*.......................94.802.105........ +...834.............254............=........657.........@...198..160....258........*.............449........972@.553%.................234.... +...*.....@...........*....................../.....273............*...................&......................................545.365......... +.773......296.........85...256.......977.............*....203...216.....394......872.240.......406*.......&254...............*..*........... +......-...............................................830.....%....................*..............................................615.608... +...739..15*903....93.........714..442*...769.....838.......829.....741.....@469.......60...........181..376.......63.........172........*... +.................=......306............@...*.......*...900.....309..*...............-.....428..333...*.....*921..*....673............499.... +.........599...........&........221....137..432....930....*.....*..216..........#..381...*.....*....767.................@..........=........ +.993......-..............243....$.......................150...456.............677......400..338.............................766.468......... +........................*....................509....................815.............................................308.....*..........575.. +...................908.112........767....215..........400..220........*............962.825......46......30.....21-........875......453*..... +....845........840............../....*.../........423*....*....929..76......682-...*.....&.........@.....*..........&196.................... +867.*.........+.........=671....429..278......46.......$...194../.................611.............401.....788....&.......201.........*38.... +....21...599........................................863..................946...23............*547.............244...........*.....963....... +.........*...........65.............659......612..........497.......&705..................121.........................29....80.............. +.......670....391...*......&....405.*..........*..........=.....................721............321...........585.464...............598...... +....................892..472.....*...526....615.......51......790..........-633........847.......*...310..60..#..*.......517.415......*..... +.....732......*473.............825.................67*.......*.....488...........@....*....298.240....*....*....548.............+........... +........*..222.....377.........................710......512...839........340......829.836....#.........619.776.........695.358......417..... +.......51................632*........................85*..........*.......*..125...........%....@360............109....../.............*.... +...........880....836........979...........496.247.......885......754..658.....*..622.......840...........118......*.120......779..92..746.. +651....617....*..*...............@.....291*.......*883...*...................529...*.............531.........*...857.-..........%.=......... +.........*.......699.....639.583.181........457+.......699.829......308..........704....299.......*....332.622..........467*.........684.491 +......258...............................25*........441...............-...212..............*......820...............440*.....352.........*... +...34.........186................255.......526.618..........775.702.........*.940......=...822.........................515......947......... +...*.............*195.....693.......*..........#.....826.......*.....%....331...*.......49.....677..............920.........781*......-..... +....657....52.............*..........766................*..289.....589........34................*...................&............=...421.... +............*.......9.$...831..............*952....469.886....*.........283........525.....986..516..............184..949......670.......... +.568........283...../.431......*....420.259...................807..568..*........%..+..634*...........915..&938.........$................... +...*...........................77............874...558..............#....596..902..............368......#..................&....$.958..702.. +455....................389..............&..../.......+......*409......-.............909.......*...........978*341...188...74..26..*....*.... +..........17....360.......*............617...............153.........887.122.......*.......184........258........................755...348.. +......612.#.......*......425.968$..496..............918.......313........+....535..764.............19*.....*......173....=.................. +........-......440..384...................474...940..=..586@.&.....466...........=...............-.........797.......@.406...-......%....... +....816............*..............@.760....*.....*..................$..156...............676...451..462........774.........346.....558...... +....*.......258..888...#165.....166...#...27......766...........83......$.........&302......-........*........*............................. +..655.....$.................548.......................109......-....................................61..252..849.......299.....880....-..... +..........550.=495.62.........*.......-........691*......*648.......837&....736*722....*12.................*......*......$.283*.....35...539 +......475............*358...&.........605..........963..............................514....673..840........787....420....................... +..431....*....62.964.......814.$832.............................................844.......*.......*.293.......................297.....+..... +......%..730......*........................./..145...&............45.#.............*.....365....276...*..............125......*.......178... +....924.........814......143%.............295.#....811.*253.....-..-.910.....605..595................34..957.........*........413........... +..........220.................$.....769......................738......................461.177.........../.......848...63..407........354.... +.........$..........657.985...426........................-....................903.......*..#...703........784.....&......*.............*.... +...............105....&.-...................264..........50.....593.181..252...*......808.........*.......*............509.154.....678..210. +.......263........@...........57....854.............*38.........*....*...-.....89...........$../........%.889....404.........-.............. +.918..%.................*534..*.............838..731.......$501.409...............942....958..516....720.........%..............777......... +....$.........%435....24.......657.561.......*.......841...................961......./............-.......886*......442....627=...*....516.. +.........925...............827......*...149..236..28*.........599...249...$......958...........220............611.....*.&.......314......... +..........*..*.........120....*..$..158.*...........................................=..786...............428.......831...211.........%...... +.........530.456........*..355..74......870........65.........................843........&.../......@......*..........................425... +.....................657..........................*....50.......=............*.......93......817..413..598..83.............................. +.....818*427...+131.................459..474.938...570.........53........217..785...*..................*.......*......................#..... +.193....................233..491.......*................52.........$.......*........483...817...484....114....295.......%298..689..552...... +....*...........................#....25...848....@537..$...........302.....507............&.........................%....................... +...817..........383..431...464............................845....................896.........................715.920....468..........531.... +........................*.................337...85.......*.....................................331.........................*326..../.=...... +.........587.....533...601.................*...+.......726...949.760...374*.............849...............923.....328...........671......... +.705....../........*..............437.....426..................*...........945...............................*................/.....670..... +....*...........657....*593........./.............279.......672................*711..........742*679.........754....351@.......225.......... +..898...600..........57................86....826...#..................97....601........................93................163..........270... +..........*..............&.530-....324*.....*........833.....876........*.........908*........172$....*............548................*..... +..71......403.........584................377.........*......*...........920...........432.............723......650*....570.......593...718.. +...............739...........................199..418......16..668.............852.........555#...........................*516..*........... +....642.............*..................93@.....*..........................602.+............................49......&.............202.267.... +..........861..268...60.....-...............993......%...320................/...............261.........$.........897..................=.... +.........*........*..........249....................389..*.........416.........*...........*.............962...........928*310.............. +................33................727...346*850...........845.......*.......695.388...690..834.....471.........................746.....882.. +....576...............824.....491../...............464...........173..............................*.....514+....27.965........#....939...... +.................................*.............832....*.....515......337........./215..640$.......985.............*..................%...... +.......-..........343..586......................*....569..*....=......#...618.............................368.................%188.....815.. +....721...480..................847...............651.......576...........&........./...356..........287..-.................................. +..........+.......587...........*.....................34.......84.................96..*......790....+..............286..310.@........451.... +............929..*.......613.....480.389..761........*........*..............97......712.......*....................*..*....335....%.....795 +....125.762*......104....&...900.......*...*.......794........83..............*.............860.....$........622.723..771.......706.....*... +119*........................*....&....474..268..............*....65.........781.......817............814.................................940 +..............777.192.....187.302....................363.253....=.............................565........834........-.......519............. +..............*...................*..+197.........*.....................14....230.........................*....552.733..657....-......134... +....47$...448.744.....562..234..849.......894...298........136..........*....$...........650*..31...787....357.............................. +..........=..........*.......@..............*.............$..........839.........................*....*.............201...992............... +......+...........535...@.............989-..........477......................273.......625.....544.367....................+............69... +....456..493..........282..............................@....810..689@.361.....*...123.....*262...............995..429*........../......*.... +.............................564.115...507*720................................473..*.../........................+.....200....230........8... +.................814.....90.*.......+..........508.872..418....496*783.................643......&437..244.....$...................654....... +.......376..........*...*....32..........356......*......*.................691.../.......................*.221............813@.......$...... +.........#.........31....971....352@.....*...566*.......278....-.......%..*......25.........*...222....963.......42.............-........... +.....944...............................189.........#..&.......213....542.468.613.........494.......*..........$...............666........... +.......+...783...........930......*701......772...148.350...................../.../681..........*......@.......799......30........729....... +..................407.....#.....#............*............$.............142..................513.858...431................*.513...=......... +.....621.+720.41...@.............318...$661..197.104..997.252.*346.......*.....241..............................249....296../.........*355.. +.........................*........................*....=.................194..../....285............&......204*...*................614...... +....465......256.......31.154............84....990..............999..+.................*...965.....817..........674......................... +......+.........$...............515.........................554.*.....485.$411.......382..#...........................399....364....*568.... +.........87..52.....896..........&....................583..@.....550..........................@774...........97*106.....*......-.670........ +..........*...........*.&......@...2....*444.............*...388........................................................150................. +.........263.........20.623..264..*..513.................655.......430.....820.....................=....156..840/..883...........283*78..... +..........................................793.....298........../.......212...@..234.715.*133....705.....*............#...................... +.....................................*.......*...*.............992......*.........=..@..................870................324......=..712.. +.452.......818*237...........329...73.....754.....955....645.+...........478............340.970......*................817....@...982........ +....@..705..........115...................................*...157.620...........&.......*....$......565.....8.@.........*.............669... +..........*715.481.*....................*........836......714.....*...........124....968........=...........*..426....693........753...*.... +..26@..........*....892...272.259....461.387..82....*...........208...126.....................850..........299..........................135. +......947...682...*..........*................@...482.....854............*.....613.....................719.................................. +...33.-.........131....586............396.......#.....1...................889..+....*577..........782....*.......969$...............951.653. +....*........$............*.............*....469......*..111./822................105.........131+.*..........816........618............*.... +...95.....355..........+.....+.469.241..736.........831...........227.......639........474$........703..610.....*......*.....199.....$...... +..................597...572.85....*............462.......@536..........@793....*..77.........................798...374..20......&....246.... +......374.........*.................848....552*................545...........307......956.67............336*.........*...................... +.647.......#819..305.........735...*....................-........*...............824....*...*....100........383...@...695........%...245.... +....@.762...............727...*..373.........241*656...581..842.910...................672..229...*...............869............249......... +........*...........563......899.........406................*..........12%.....................78..614......+166........../92...........787. +.........558....282*.......................*.763...313.....999.....807...............+....489.......*............261...........130...*.*.... +.....356.............325.....265..740...923..*......*................*..../....120...456.....*....%.102.....791....*..141........@.666.65... +......*...870$.......*...431..#......*.......631...212............957..124.......*........558..946.............&.763...-..903#.............. +....437..............412....*.........29....................539...............703.......*............844.................................... +.........345................177..................609..398......@.....................138.185..+......*......................193-.....929.... +..............&...%....950...............489........=....*119.....909.522........%.............928.331...18.799.....*914.................... +....422.....304....753.*..................=.....751....................*........144.....53*878............%..$...579...............658...... +.......................618...................$.........344*91........533............439...........556..................=..............*..... +.........275..................................12.................764........&..........*..................710..609....902........80.753..... +............*.738......5#.................................595..........976+.887.......468.-.......114............./........*484............. +495.......804...*.................988....+..411...........=................................86...........$......=........631................. +.................458.........927...*..514.....-.......933.........192.850.85......858..209............379......462............139....70..... +........@.....+..........107*.....229....................*............*....%.896./......../..................=...........*.....#............ +........991..272.....575.................................958...........917.....*............*.......94.....985...+587...184................. +...............................................657..........................423..........742.367...............................634..........