From 5af35d0ccca42cd0b2cd6ded8d12520f7eaf5e77 Mon Sep 17 00:00:00 2001 From: Dan Anglin Date: Mon, 4 Dec 2023 01:26:50 +0000 Subject: [PATCH] feat: add solution for 2023, Day 3 Add the solution and test suite for AoC 2023, Day 3: Gear Ratios --- 2023/day-3/files/input | 140 ++++++++++++++++++++++++++++++++++++ 2023/day-3/main.go | 155 ++++++++++++++++++++++++++++++++++++++++ 2023/day-3/main_test.go | 48 +++++++++++++ 3 files changed, 343 insertions(+) create mode 100644 2023/day-3/files/input create mode 100644 2023/day-3/main.go create mode 100644 2023/day-3/main_test.go diff --git a/2023/day-3/files/input b/2023/day-3/files/input new file mode 100644 index 0000000..08ecfbe --- /dev/null +++ b/2023/day-3/files/input @@ -0,0 +1,140 @@ +..172..............................454..46.......507..........809......923.778..................793..............137.............238........ +............*.........712........=.......*................515.*...........*.......690.........../..........658.........=.........*.......... +.........823.835........%.........710.....749........134..%............................#812...&.....925.../..........276.......386.......... +519..................13......341.................481....=.....$............-.......211.......92.......*..................................... +............832*105..@........$..................*.........797.....535..932.........*....152...........123.........678.540...........-...6.. +....&..948..........................271....-....228..79.26.........................733...=...715............27.586........*.......883...*... +..172.......=..+.............88&....%....340.55.....+.............465..398......=..................585.......*....*812...347................ +...........374.462.......166..................*...........786........*....*910..675.................*.....149................653*....+80.... +.......*............680.....*......876.........864..................259.................124.169....799............608..*.........98......951 +....615.......*....%.....151.........*....#802........$.......680......................../...............857........-.901...............*... +..............3.................637..493...........926....636..*.....350........881.........699......886.../.458...........#..474*409...246. +...&...336......922............*..........370..............$..581....*.....335.*.......608$..*..11.......$....-..........928................ +...50..*.........*...........978...453.....*.......-..22..........298.......*...711.........794...*...267............44*.......460....*..... +...................................*........534..797....-.............61....272.....@874..........892.....707.............230....*..72.537.. +....................405............309..........................221./..*....................872%.......75..*......237.....*................. +..208.176..239.........*172.............795.............670.......*..9..504......*.717..641........908*....975.....*......130............... +.....*....*.......711$....................*..54.....494..../.333.882...........282....@.......927*....../.......555..983*...........479..... +.915......670.524................866...862..@.........*../....*...................................72.901..................995..........&.... +...*..%.......*.....71.............*..................33.350.796.....612.............#..463..............*399.....=.......*......309........ +....8..951.886......@......41*......606.680...787................605*.....892.......219.*........972..846.........377....644................ +..............................718........*.......*.......355*688............*.145...................*.......576............................. +..........867.*.....................+...974...148..........................87.#........500&...534..986..269...*.....576....302....+......... +........@......504.......-........652.........................104....@502......................*...............691.*.........*.423..706..402 +.286..218.882........-....579......................320.....=...-..........48.393.....202......758.....242..951.............................. +....*.....*.....$..943.............928.....*......*......310......&........*....*...*......=..............*......295*133.................... +..698...331...859.......91.........#....815....822..............39..........833....749...591...........455....*..........&30....*........... +............*............+..............................117............................%........727........256.439...19.......478........... +......67.595...599.........442...997..187.................@.596..276..141.597*792...780.........*......*.............@..............#....... +266@.............-..713.....*....*.......=..783...564*.......*.......@.........................839......255.............636......749..%..... +........+............*.....963.926.39../......&.......274...228..../.....812.........487@.24.............................*..*..........348.. +...618...364.936.....708...........*....63..&.......................212....-..191..............798................*....591..906............. +......./.....@...............591...127.......491...141..*.....+...............*......339.@483........204*......871.465..................%... +....890..................997*............723........$..675..465..............372.875*.........%..........534.............209.......*.....648 +..............+................139*..........273..................../7.....-..............854.920...968%..........384......%.......830...... +......+632...273.......132*........793.........................207..........952..../..66..*........................#...........@............ +.......................................162..................35.*.................22..*....234..........468...................#.750.......... +.....15...161.....................93....@...818..-580........*.449...................125...........129....*................723......365..... +.....-....*.......678.........&21...=....../..............547.......$.........701....................#.....845.........................#.... +743........634...*.................................................679...........*176......979....................928.......$..848.......... +...............107....296....845.....*..........@...........................69..............$..442.........960/...........311.*............. +.........................*............519.....58..............248.......582*........403.......*........929..............-......486.......151 +....-390....396.........279.......718............449.....794..#..............+......*......251...980....../.../...328..476.................. +.............*.....................-......../...*...........*...292.........188...&..112............*315.....529............................ +713..........860......114.743&.......368.776...195.........850.=................943............543...................483*625................ +......889........=.../.................*.............916.............201............-...............426&....627..............284............ +.452...........579...........786.961.15.......488.......*373.....830*......947.645.189........367.................$..../551................. +....*.....99*........388.793...*...*....578..../...........................*...%.......-497.........@221..720...885.........588....692...... +....................*........903..81.......*.......*........=./....615.....202...355........997-..........*................$.........*...... +...........780.@....259.439.................483....596...490..415....*............-........................683........*371...&644..964...... +.......796......161.......*..#884....................................458.247.500........145.895.62.742.267..........16...................... +......+............../.998...........173..511............552*847...%.....&.........+651..*.....*........*.....108........+..............*975 +.444.....560.297...149..............*....*......*...................173...................365............986.$............271...182...26.... +....*84....*......................#..471.696.736.107....974...-614............................../...%930..........................+......364 +............800...-155..235......446...................*....................286.......822../...199............670-....................%..... +....882.................*.................521....*20.282.............641.......*..703*.....887......513*271....................+819..100.... +.99..*........933*...649.......407............922...............-......*....681.............................*....#426...204................. +.....112................../.....*...819.94......................689...652...........182.933.858.............711...............610.....*437.. +.540..........#.........740...500....*...$....184.......................................*....#.......386...........................668...... +....$..........719..695...........824............&...882...........@......811........771.........142*.........867.667.*299.....143.......... +425....120.............*....401........................*....75..2..551.....*...719....................44..141...+..............+............ +...%..*..........963....209..&.....913.................871..=............%.904.........365.244.495....*....*........19...................... +.....971.........=.............883*.........225.967.............#......44.................*.....*..182......830.....@..190............487... +...................................../........*.%........93....577..%......541.....*456.....370.52......................%.............@..... +..82......396....................927..887...268...........&..........517...................%...............753................+............. +.........*..........................*.........................................607..493.479.........521......*.....680*58..&....879.......... +......951.................136.&....585.........69....933.........25......265......*............923...&......5.............624........109.... +...........826..............$..407..............*...............*...+...........772.=...........*.............................628........... +.......293..*...420...................................140.......728..815.196.-.......470.....403.................807..........*...99.....443 +......-.....732...*.........795....35........18.........*................*....789................931................-.52....727....*....*... +.................477..@682..*.......*...118.........539.................844......................*...481.....%..........*..........863...773 +...479&......................585..817...@...........*...16*244...826*..........427...............694.......834.......949.................... +....................336....................-.....205..............................&............................................899.......... +....49...971...............331..289.......661.........400...57...-...................711......./873.........-...668...94......*.....42...... +.../.......#...........68...&...#...557.*.....425.......*...-..267.+.................*......#........@....993..=.......-....49......../.65.. +.............647..569.....*...........@..1...*......+...823.........579.............153...65...263....320..........243...........626........ +.......128...+.......*..215...%..684.........519..247.....................+.....................*...........320...*.................*....... +........*..........827.......954...*.....378..........553..............434..........644....................*.......208............88..387... +.907..402..............-..........16....*....%.........*...507..403.........*.................272...496....750.12.......................*... +.............555.610.454.............322....954..529..25...*.....*../....651.43...534...........*......+.......$.........=...-121.442..709.. +.269*410......*...................................+.......163.608...451.........................999.....................292................. +...........867....595*88.....#990...473.................................406.285.825......464...............378-..835&........%.......570*484 +.....550.............................-......162....812*37..................*.....*......+.................................693....%.......... +........*385...............*934..810.......*...................758..313........413..+.......265.691...559............807@.......824.608..... +....373..................................580.....506..........*............852.......786....*.....*......*.........&...................*.... +.......%...932....194*688...713..................&.....333..410..817.524.....*...438.......410.129......312.....452......202..........146... +.........=....+..............*....................................#..........626.*.....745.........974.....................+................ +580...212........485.........511.....495.768.361.....323-..............*176......595......*........*.......+.......147.........227....491... +...*........%....*........85........*......*..*.............@..329$.623........*.......=..161.%...680...104.........$..452....*.........=... +854..*489....33...992.......*......15...418..890...%......362............603.224.....431......701.............929.=....../.....408.......... +............................980..................428......................*......615..............%343............827..............686-..... +48.213..................353.....%902......616.........583..%674.....361....711.........821&...31%.............................285........... +...&...614.....@52.207#....*228............*..........*.............*..............................624.............734..........%.411*876... +......*............................358...807.....280..174...232..715...$..............804..522........=........717..*..=.................... +434....262.655.822.358.&709...........*..........*..........=.........876.....952.............*................$...81.412.160....751........ +..................*.................976.......739..490*913.....@...........+....#.374..625..236..539........$............................... +..743...................737@.............766....................197........878.....*....*...........*...861..32...............16...975...... +................972..@.....................&...293..85/.....561.......919..........156.............435....*..........835........*3.......... +........823.690.*....747...............799....*..........=....*........&...................241.........558...............459................ +....552*.....*...701.........................579.......187...691...#.*......694*980...........*.#...........244.............*....842........ +.57.......687.....................110*873........................469.217....................573..324.308*......%...........855....*..553.... +......551..................................................................142.......771*................902...................606.......... +.....*....990........869........8.......#477............330-....................37*......408.-751......-......239..........362.............. +...994...*..............=.984..*...194...............................972*967.......150...............433..517...*...........*........947.... +.........189..501*334...........56...#...............531...846...562..........477...............................19........396...570.*....... +......................761..............243.....692......*.....*.....*.#985.......*...991-......=.320/.................%...........*.585..... +....590.....&....$...$....993.554.....*.........%....132...623....429........549..31........643...................134.237........50......... +.............385.538.....*....*.....826...........@....................................644......151*919......733.............73.....848..... +.477...871..............5....68.841......80*.......405.70*898..............+25............*787..........368...*................/.......*.... +...*....*.....6....................*..=.....370......................................186.........146.......*...447.......287............611. +443...893.....$.......%20.......108...43..........637......396...596............64......#.505...*.........141..............*......543....... +.................197......244.................530.=...334.......*....335..745...../.......*......99..182..............645.963............... +...........%....*........*.......593..704&..............-...@...211.....*......./.......571..178...............#.................+476....... +.....*812..17.617.......249..327..-........527..15........238............926.564..............................260...........715*......../793 +....................826.........*............*.......................................@.........685.....@................954.....423......... +.............796*..............260..946.....848...902.............285......136....211............*.....258.874.....332.*.................... +....&829.........348....539.........*............*....623....*.....&.........*..........252.%253..86......../..599.*...592.......672-.232... +............752.........-.........375............859....*.926.182....733......241......=..............276..........762................*..... +.............................482...........346........374...........&............................493.....*322..........................175.. +...*../........793..&532.........530..........*...........509.861.......134........353............*....................*94.................. +480....761........+.....................=..768..790..@......&.*....296.................311........340...344.....989.142..........411........ +.............208.......300.............506......*.....267.....918....*.......204..........%.606.........*....+...=.......*397.......*...257. +............+.........*......-...............636..476................109......*.............*......-....115...91......823........929....@... +...595........313.....849.452......568...............%..802....................915...730....138.30..455.....................589............. +..............*................290....%.......147..........#....492..83....12*........=.........*.............................@.......17.... +970.....+.-...701....#264....%....$.......113.......916........*..............620............809........$788....@.....446........904..*..... +...*..221.112..............610............@.....799............713........657.......325..........................551..*.............=..615.. +.295...............852..........*....986.........*..........................................-............620..........665.....930........... +.....785.......542.*............732...=........583...+....................424....$....702.367..993.......*....386..#.............*.......... +........*...........114....704..........377...........633...........=730...#..241.......%.....*.....-.396...........372......135..806....... +.......122......963........$............*.....................509$........................50.....280.........672.........538..$........619.. +.....................957.....542...731..941.......*....59..........571*554....214....108.@...............104*............=.............*.... +.....=...............*.......*....../.............337./...........................=..%..........................................873..563.... +....771..500........868.......213......902....456........../.........255.....377.781......=348................133..@...367*696.....*........ +........*....$..25........784..................$...........735..413.....*108./............................645...*..8............185......... +..603.389..956.*...........*.......636...866.....338...+25......*...+..........................................667........#..........+..296. +...*............544.....510..418.=....=....*....................379.478.....961.............410&...........413......*912..469..758.733..-... +798....*565.793.............*....98.....447.....@......291...$...............*..244................%..491.../...................*........... +....546......*....454...120..683.............923.....@...*...865.574......276........56......57.659..*................-...-...512........... +............329...*.................................606.599...................*927..*.........-.......674..*........723..974................ +................378..911........987.....606......................899.73....489......848.....................664...............388......589.. diff --git a/2023/day-3/main.go b/2023/day-3/main.go new file mode 100644 index 0000000..ae435a7 --- /dev/null +++ b/2023/day-3/main.go @@ -0,0 +1,155 @@ +package main + +import ( + "bufio" + "fmt" + "log" + "os" + "strconv" + "unicode" +) + +const ( + dot = '.' + potentialGear = '*' +) + +type answer struct { + sumOfValidEnginePartNumbers int + sumOfGearRatios int +} + +func main() { + schematic, err := engineSchematic("2023/day-3/files/input") + if err != nil { + log.Fatalf("ERROR: Unable to retrieve the engine schematic; %v\n", err) + } + + answer, err := fixTheGondola(schematic) + if err != nil { + log.Fatalf("ERROR: Unable to calculate the sum of all valid engine part numbers; %v\n", err) + } + + fmt.Printf("[Part 1] The sum of all valid engine part numbers: %d\n", answer.sumOfValidEnginePartNumbers) + fmt.Printf("[Part 2] The sum of all Gear Ratios: %d\n", answer.sumOfGearRatios) +} + +func fixTheGondola(schematic []string) (answer, error) { + var ( + partNumSum = 0 + partNum = "" + validPartNum = false + maxY = len(schematic) - 1 + maxX = len(schematic[0]) - 1 + mapOfPotentialGears = make(map[string][]int) + potentialGearPos = "" + ) + + for y := range schematic { + for x, v := range schematic[y] { + if unicode.IsDigit(v) { + partNum = partNum + string(v) + if !validPartNum { + switch { + // check above left + case ((y - 1) >= 0) && ((x - 1) >= 0) && !unicode.IsDigit(rune(schematic[y-1][x-1])) && (schematic[y-1][x-1] != dot): + validPartNum = true + if schematic[y-1][x-1] == potentialGear { + potentialGearPos = fmt.Sprintf("%d-%d", y-1, x-1) + } + // check straight above + case ((y - 1) >= 0) && !unicode.IsDigit(rune(schematic[y-1][x])) && (schematic[y-1][x] != dot): + validPartNum = true + if schematic[y-1][x] == potentialGear { + potentialGearPos = fmt.Sprintf("%d-%d", y-1, x) + } + // check above right + case ((y - 1) >= 0) && ((x + 1) <= maxX) && !unicode.IsDigit(rune(schematic[y-1][x+1])) && (schematic[y-1][x+1] != dot): + validPartNum = true + if schematic[y-1][x+1] == potentialGear { + potentialGearPos = fmt.Sprintf("%d-%d", y-1, x+1) + } + // check left + case ((x - 1) >= 0) && !unicode.IsDigit(rune(schematic[y][x-1])) && (schematic[y][x-1] != dot): + validPartNum = true + if schematic[y][x-1] == potentialGear { + potentialGearPos = fmt.Sprintf("%d-%d", y, x-1) + } + // check right + case ((x + 1) <= maxX) && !unicode.IsDigit(rune(schematic[y][x+1])) && (schematic[y][x+1] != dot): + validPartNum = true + if schematic[y][x+1] == potentialGear { + potentialGearPos = fmt.Sprintf("%d-%d", y, x+1) + } + // check below left + case ((y + 1) <= maxY) && ((x - 1) >= 0) && !unicode.IsDigit(rune(schematic[y+1][x-1])) && (schematic[y+1][x-1] != dot): + validPartNum = true + if schematic[y+1][x-1] == potentialGear { + potentialGearPos = fmt.Sprintf("%d-%d", y+1, x-1) + } + // check straight below + case ((y + 1) <= maxY) && !unicode.IsDigit(rune(schematic[y+1][x])) && (schematic[y+1][x] != dot): + validPartNum = true + if schematic[y+1][x] == potentialGear { + potentialGearPos = fmt.Sprintf("%d-%d", y+1, x) + } + // check below right + case ((y + 1) <= maxY) && ((x + 1) <= maxX) && !unicode.IsDigit(rune(schematic[y+1][x+1])) && (schematic[y+1][x+1] != dot): + validPartNum = true + if schematic[y+1][x+1] == potentialGear { + potentialGearPos = fmt.Sprintf("%d-%d", y+1, x+1) + } + } + } + } else { + if validPartNum { + value, err := strconv.Atoi(partNum) + if err != nil { + return answer{}, fmt.Errorf("unable to convert %q to int; %w", partNum, err) + } + partNumSum = partNumSum + value + + if len(potentialGearPos) > 0 { + mapOfPotentialGears[potentialGearPos] = append(mapOfPotentialGears[potentialGearPos], value) + } + } + + partNum = "" + validPartNum = false + potentialGearPos = "" + } + } + } + + // Calculate the sum of all gear ratios + sumGearRatios := 0 + + for _, v := range mapOfPotentialGears { + if len(v) == 2 { + sumGearRatios = sumGearRatios + (v[0] * v[1]) + } + } + + ans := answer{ + sumOfValidEnginePartNumbers: partNumSum, + sumOfGearRatios: sumGearRatios, + } + + return ans, nil +} + +func engineSchematic(filename string) ([]string, error) { + file, err := os.Open(filename) + if err != nil { + return nil, fmt.Errorf("unable to open %q; %w", filename, err) + } + + scanner := bufio.NewScanner(file) + var lines []string + + for scanner.Scan() { + lines = append(lines, scanner.Text()) + } + + return lines, nil +} diff --git a/2023/day-3/main_test.go b/2023/day-3/main_test.go new file mode 100644 index 0000000..11589af --- /dev/null +++ b/2023/day-3/main_test.go @@ -0,0 +1,48 @@ +package main + +import ( + "reflect" + "strings" + "testing" +) + +func TestDay3GearRatios(t *testing.T) { + t.Logf("This is the test suite for Advent of Code - Day 3 - Gear Ratio") + + testEngineSchematic := ` +467..114.. +...*...... +..35..633. +......#... +617*...... +.....+.58. +..592..... +......755. +...$.*.... +.664.598.. +` + schematic := strings.Split(testEngineSchematic, "\n") + + // remove the first and last lines of the test schematic as they are blank. + schematic = schematic[1 : len(schematic)-1] + + t.Run("Test the fix to the Gondola issue", testFixTheGondola(schematic)) +} + +func testFixTheGondola(schematic []string) func(t *testing.T) { + return func(t *testing.T) { + got, err := fixTheGondola(schematic) + if err != nil { + t.Fatalf("Received an error after running sumOfValidEnginePartNumbers(); %v\n", err) + } + + want := answer{ + sumOfValidEnginePartNumbers: 4361, + sumOfGearRatios: 467835, + } + + if !reflect.DeepEqual(want, got) { + t.Errorf("unexpected result received from sumOfValidEnginePartNumbers(); want %d, got %d\n", want, got) + } + } +} -- 2.45.2