├── .gitignore ├── LICENSE ├── README.md ├── aoc ├── challenges ├── 2020 │ ├── 01-reportRepair │ │ ├── README.md │ │ ├── go │ │ │ ├── challenge │ │ │ │ ├── common.go │ │ │ │ ├── partOne.go │ │ │ │ └── partTwo.go │ │ │ └── main.go │ │ ├── python │ │ │ ├── __main__.py │ │ │ ├── common.py │ │ │ ├── partOne.py │ │ │ └── partTwo.py │ │ └── testCases.json │ ├── 02-passwordPhilosophy │ │ ├── README.md │ │ ├── go │ │ │ ├── challenge │ │ │ │ ├── common.go │ │ │ │ ├── partOne.go │ │ │ │ └── partTwo.go │ │ │ └── main.go │ │ ├── python │ │ │ ├── __main__.py │ │ │ ├── common.py │ │ │ ├── partOne.py │ │ │ └── partTwo.py │ │ └── testCases.json │ ├── 03-tobogganTrajectory │ │ ├── README.md │ │ ├── go │ │ │ ├── challenge │ │ │ │ ├── common.go │ │ │ │ ├── partOne.go │ │ │ │ └── partTwo.go │ │ │ └── main.go │ │ └── python │ │ │ ├── __main__.py │ │ │ ├── common.py │ │ │ ├── partOne.py │ │ │ └── partTwo.py │ ├── 04-passportProcessing │ │ ├── README.md │ │ ├── go │ │ │ ├── challenge │ │ │ │ ├── common.go │ │ │ │ ├── partOne.go │ │ │ │ └── partTwo.go │ │ │ └── main.go │ │ ├── python │ │ │ ├── __main__.py │ │ │ ├── common.py │ │ │ ├── partOne.py │ │ │ └── partTwo.py │ │ └── testCases.json │ ├── 05-binaryBoarding │ │ ├── README.md │ │ ├── go │ │ │ ├── challenge │ │ │ │ ├── common.go │ │ │ │ ├── partOne.go │ │ │ │ └── partTwo.go │ │ │ └── main.go │ │ ├── info.json │ │ └── python │ │ │ ├── __main__.py │ │ │ ├── common.py │ │ │ ├── partOne.py │ │ │ └── partTwo.py │ ├── 06-customCustoms │ │ ├── README.md │ │ ├── go │ │ │ ├── challenge │ │ │ │ ├── common.go │ │ │ │ ├── partOne.go │ │ │ │ └── partTwo.go │ │ │ └── main.go │ │ ├── info.json │ │ └── python │ │ │ ├── __main__.py │ │ │ ├── common.py │ │ │ ├── partOne.py │ │ │ └── partTwo.py │ ├── 07-handyHaversacks │ │ ├── README.md │ │ ├── go │ │ │ ├── challenge │ │ │ │ ├── common.go │ │ │ │ ├── partOne.go │ │ │ │ └── partTwo.go │ │ │ └── main.go │ │ ├── info.json │ │ └── python │ │ │ ├── __main__.py │ │ │ ├── common.py │ │ │ ├── partOne.py │ │ │ └── partTwo.py │ ├── 08-handheldHalting │ │ ├── README.md │ │ ├── go │ │ │ ├── challenge │ │ │ │ ├── common.go │ │ │ │ ├── partOne.go │ │ │ │ └── partTwo.go │ │ │ └── main.go │ │ ├── info.json │ │ └── python │ │ │ ├── __main__.py │ │ │ ├── common.py │ │ │ ├── partOne.py │ │ │ └── partTwo.py │ ├── 09-encodingError │ │ ├── README.md │ │ ├── go │ │ │ ├── challenge │ │ │ │ ├── common.go │ │ │ │ ├── partOne.go │ │ │ │ └── partTwo.go │ │ │ └── main.go │ │ ├── info.json │ │ └── python │ │ │ ├── __main__.py │ │ │ ├── common.py │ │ │ ├── partOne.py │ │ │ └── partTwo.py │ ├── 10-adapterArray │ │ ├── README.md │ │ ├── go │ │ │ ├── challenge │ │ │ │ ├── partOne.go │ │ │ │ └── partTwo.go │ │ │ └── main.go │ │ ├── info.json │ │ └── python │ │ │ ├── __main__.py │ │ │ ├── partOne.py │ │ │ └── partTwo.py │ ├── 11-seatingSystem │ │ ├── 0.gif │ │ ├── 1.gif │ │ ├── README.md │ │ ├── go │ │ │ ├── challenge │ │ │ │ ├── common.go │ │ │ │ ├── partOne.go │ │ │ │ └── partTwo.go │ │ │ └── main.go │ │ ├── info.json │ │ └── python │ │ │ ├── __main__.py │ │ │ ├── common.py │ │ │ ├── partOne.py │ │ │ ├── partTwo.py │ │ │ └── visualise.py │ ├── 12-rainRisk │ │ ├── 0.gif │ │ ├── 1.gif │ │ ├── README.md │ │ ├── go │ │ │ ├── challenge │ │ │ │ ├── common.go │ │ │ │ ├── partOne.go │ │ │ │ └── partTwo.go │ │ │ └── main.go │ │ ├── info.json │ │ ├── python │ │ │ ├── __main__.py │ │ │ ├── common.py │ │ │ ├── partOne.py │ │ │ ├── partTwo.py │ │ │ └── visualise.py │ │ ├── quadrants.png │ │ └── rotation.png │ ├── 13-shuttleSearch │ │ ├── README.md │ │ ├── info.json │ │ ├── python │ │ │ ├── __main__.py │ │ │ ├── partOne.py │ │ │ └── partTwo.py │ │ └── working.jpg │ ├── 14-dockingData │ │ ├── README.md │ │ ├── go │ │ │ ├── challenge │ │ │ │ ├── common.go │ │ │ │ ├── partOne.go │ │ │ │ └── partTwo.go │ │ │ └── main.go │ │ ├── info.json │ │ └── python │ │ │ ├── __main__.py │ │ │ ├── common.py │ │ │ ├── partOne.py │ │ │ └── partTwo.py │ ├── 15-rambunctiousRecitation │ │ ├── 0.png │ │ ├── 1-hires.png │ │ ├── 1-lores.png │ │ ├── README.md │ │ ├── go │ │ │ ├── challenge │ │ │ │ ├── common.go │ │ │ │ ├── partOne.go │ │ │ │ └── partTwo.go │ │ │ └── main.go │ │ ├── info.json │ │ └── python │ │ │ ├── __main__.py │ │ │ ├── common.py │ │ │ ├── partOne.py │ │ │ ├── partTwo.py │ │ │ └── visualise.py │ ├── 16-ticketTranslation │ │ ├── README.md │ │ ├── go │ │ │ ├── challenge │ │ │ │ ├── common.go │ │ │ │ ├── partOne.go │ │ │ │ └── partTwo.go │ │ │ └── main.go │ │ ├── info.json │ │ └── python │ │ │ ├── __main__.py │ │ │ ├── common.py │ │ │ ├── partOne.py │ │ │ └── partTwo.py │ ├── 17-conwayCubes │ │ ├── README.md │ │ ├── info.json │ │ └── python │ │ │ ├── __main__.py │ │ │ ├── common.py │ │ │ ├── partOne.py │ │ │ └── partTwo.py │ ├── 18-operationOrder │ │ ├── README.md │ │ ├── info.json │ │ └── python │ │ │ ├── __main__.py │ │ │ ├── partOne.py │ │ │ ├── partTwo.py │ │ │ └── test.py │ ├── 19-monsterMessages │ │ ├── README.md │ │ ├── go │ │ │ ├── challenge │ │ │ │ ├── common.go │ │ │ │ ├── partOne.go │ │ │ │ └── partTwo.go │ │ │ └── main.go │ │ ├── info.json │ │ └── python │ │ │ ├── __main__.py │ │ │ ├── common.py │ │ │ ├── partOne.py │ │ │ └── partTwo.py │ ├── 20-jurassicJigsaw │ │ ├── README.md │ │ ├── info.json │ │ └── python │ │ │ ├── __main__.py │ │ │ ├── common.py │ │ │ ├── partOne.py │ │ │ └── partTwo.py │ ├── 21-allergenAmusement │ │ ├── README.md │ │ ├── info.json │ │ └── python │ │ │ ├── __main__.py │ │ │ ├── common.py │ │ │ ├── partOne.py │ │ │ └── partTwo.py │ ├── 22-crabCombat │ │ ├── README.md │ │ ├── info.json │ │ └── python │ │ │ ├── __main__.py │ │ │ ├── common.py │ │ │ ├── partOne.py │ │ │ └── partTwo.py │ ├── 23-crabCups │ │ ├── README.md │ │ ├── crab.jpg │ │ ├── info.json │ │ └── python │ │ │ ├── __main__.py │ │ │ ├── common.py │ │ │ ├── partOne.py │ │ │ └── partTwo.py │ ├── 24-lobbyLayout │ │ ├── README.md │ │ ├── info.json │ │ └── python │ │ │ ├── __main__.py │ │ │ ├── common.py │ │ │ ├── partOne.py │ │ │ └── partTwo.py │ ├── 25-comboBreaker │ │ ├── README.md │ │ ├── go │ │ │ ├── challenge │ │ │ │ ├── common.go │ │ │ │ ├── partOne.go │ │ │ │ └── partTwo.go │ │ │ └── main.go │ │ ├── info.json │ │ └── python │ │ │ ├── __main__.py │ │ │ ├── common.py │ │ │ ├── partOne.py │ │ │ └── partTwo.py │ ├── README.md │ └── clocgraph.png ├── 2021 │ ├── 01-sonarSweep │ │ ├── README.md │ │ ├── benchmark.json │ │ ├── go │ │ │ └── challenge.go │ │ ├── info.json │ │ ├── nim │ │ │ └── challenge.nim │ │ └── py │ │ │ └── __init__.py │ ├── 02-dive │ │ ├── README.md │ │ ├── benchmark.json │ │ ├── go │ │ │ └── challenge.go │ │ ├── info.json │ │ └── py │ │ │ └── __init__.py │ ├── 03-binaryDiagnostic │ │ ├── README.md │ │ ├── benchmark.json │ │ ├── info.json │ │ ├── nim │ │ │ └── challenge.nim │ │ └── py │ │ │ └── __init__.py │ ├── 04-giantSquid │ │ ├── README.md │ │ ├── benchmark.json │ │ ├── info.json │ │ └── py │ │ │ └── __init__.py │ ├── 05-hydrothermalVenture │ │ ├── README.md │ │ ├── benchmark.json │ │ ├── go │ │ │ └── challenge.go │ │ ├── info.json │ │ ├── napkinmath.jpg │ │ ├── nim │ │ │ └── challenge.nim │ │ └── py │ │ │ └── __init__.py │ ├── 06-lanternfish │ │ ├── README.md │ │ ├── benchmark.json │ │ ├── info.json │ │ ├── py │ │ │ └── __init__.py │ │ └── whiteboard.jpg │ ├── 07-theTreacheryOfWhales │ │ ├── README.md │ │ ├── benchmark.json │ │ ├── info.json │ │ └── py │ │ │ └── __init__.py │ ├── 08-sevenSegmentSearch │ │ ├── README.md │ │ ├── benchmark.json │ │ ├── go │ │ │ └── challenge.go │ │ ├── info.json │ │ └── py │ │ │ └── __init__.py │ ├── 09-smokeBasin │ │ ├── README.md │ │ ├── benchmark.json │ │ ├── info.json │ │ ├── partTwo.mp4 │ │ └── py │ │ │ └── __init__.py │ ├── 10-syntaxScoring │ │ ├── README.md │ │ ├── benchmark.json │ │ ├── info.json │ │ └── py │ │ │ └── __init__.py │ ├── 11-dumboOctopus │ │ ├── README.md │ │ ├── benchmark.json │ │ ├── info.json │ │ ├── nim │ │ │ └── challenge.nim │ │ └── py │ │ │ └── __init__.py │ ├── 12-passagePathing │ │ ├── README.md │ │ ├── benchmark.json │ │ ├── go │ │ │ └── challenge.go │ │ ├── graph.py │ │ └── info.json │ ├── 13-transparentOrigami │ │ ├── README.md │ │ ├── benchmark.json │ │ ├── info.json │ │ ├── nim │ │ │ └── challenge.nim │ │ └── py │ │ │ └── __init__.py │ ├── 14-extendedPolymerization │ │ ├── README.md │ │ ├── benchmark.json │ │ ├── info.json │ │ └── py │ │ │ └── __init__.py │ ├── 15-chiton │ │ ├── README.md │ │ ├── benchmark.json │ │ ├── info.json │ │ └── py │ │ │ └── __init__.py │ ├── 16-packetDecoder │ │ ├── README.md │ │ ├── benchmark.json │ │ ├── info.json │ │ └── py │ │ │ └── __init__.py │ ├── 20-trenchMap │ │ ├── README.md │ │ ├── benchmark.json │ │ ├── info.json │ │ ├── nim │ │ │ └── challenge.nim │ │ ├── part2.mp4 │ │ └── py │ │ │ └── __init__.py │ ├── 21-diracDice │ │ ├── README.md │ │ ├── benchmark.json │ │ ├── info.json │ │ └── py │ │ │ └── __init__.py │ ├── 22-reactorReboot │ │ ├── README.md │ │ ├── blender-part-2.png │ │ ├── info.json │ │ ├── openscad-generate.py │ │ ├── openscad-part-2.png │ │ ├── part.1.scad │ │ ├── part.2.scad │ │ └── py │ │ │ └── __init__.py │ ├── 25-seaCucumber │ │ ├── README.md │ │ ├── benchmark.json │ │ ├── info.json │ │ └── py │ │ │ └── __init__.py │ ├── README.md │ └── running-times.png ├── 2022 │ ├── 01-calorieCounting │ │ ├── README.md │ │ ├── benchmark.json │ │ ├── info.json │ │ ├── java │ │ │ └── src │ │ │ │ ├── Challenge.java │ │ │ │ └── Main.java │ │ ├── nim │ │ │ └── challenge.nim │ │ └── py │ │ │ └── __init__.py │ ├── 02-rockPaperScissors │ │ ├── README.md │ │ ├── benchmark.json │ │ ├── info.json │ │ ├── nim │ │ │ └── challenge.nim │ │ └── py │ │ │ └── __init__.py │ ├── 03-rucksackReorganization │ │ ├── README.md │ │ ├── benchmark.json │ │ ├── info.json │ │ ├── nim │ │ │ └── challenge.nim │ │ └── py │ │ │ └── __init__.py │ ├── 04-campCleanup │ │ ├── README.md │ │ ├── benchmark.json │ │ ├── info.json │ │ ├── nim │ │ │ └── challenge.nim │ │ └── py │ │ │ └── __init__.py │ ├── 05-supplyStacks │ │ ├── README.md │ │ ├── benchmark.json │ │ ├── info.json │ │ ├── nim │ │ │ └── challenge.nim │ │ └── py │ │ │ └── __init__.py │ ├── 06-tuningTrouble │ │ ├── README.md │ │ ├── benchmark.json │ │ ├── info.json │ │ ├── nim │ │ │ └── challenge.nim │ │ └── py │ │ │ └── __init__.py │ ├── 07-noSpaceLeftOnDevice │ │ ├── README.md │ │ ├── benchmark.json │ │ ├── info.json │ │ ├── nim │ │ │ └── challenge.nim │ │ └── py │ │ │ └── __init__.py │ ├── 08-treetopTreeHouse │ │ ├── README.md │ │ ├── benchmark.json │ │ ├── info.json │ │ ├── nim │ │ │ └── challenge.nim │ │ └── py │ │ │ └── __init__.py │ ├── 09-ropeBridge │ │ ├── README.md │ │ ├── benchmark.json │ │ ├── info.json │ │ ├── nim │ │ │ └── challenge.nim │ │ └── py │ │ │ └── __init__.py │ ├── 10-cathodeRayTube │ │ ├── README.md │ │ ├── benchmark.json │ │ ├── info.json │ │ └── py │ │ │ └── __init__.py │ ├── 11-monkeyInTheMiddle │ │ ├── README.md │ │ ├── benchmark.json │ │ ├── info.json │ │ └── py │ │ │ └── __init__.py │ ├── 12-hillClimbingAlgorithm │ │ ├── README.md │ │ ├── benchmark.json │ │ ├── info.json │ │ └── py │ │ │ └── __init__.py │ ├── 13-distressSignal │ │ ├── README.md │ │ ├── benchmark.json │ │ ├── info.json │ │ └── py │ │ │ └── __init__.py │ ├── 14-regolithReservoir │ │ ├── README.md │ │ ├── benchmark.json │ │ ├── info.json │ │ └── py │ │ │ └── __init__.py │ ├── 15-beaconExclusionZone │ │ ├── README.md │ │ ├── benchmark.json │ │ ├── doodles.jpg │ │ ├── info.json │ │ └── py │ │ │ └── __init__.py │ ├── 16-proboscideaVolcanium │ │ ├── README.md │ │ ├── benchmark.json │ │ ├── info.json │ │ └── py │ │ │ └── __init__.py │ ├── 17-pyroclasticFlow │ │ ├── README.md │ │ ├── benchmark.json │ │ ├── info.json │ │ └── py │ │ │ └── __init__.py │ ├── 18-boilingBoulders │ │ ├── README.md │ │ ├── benchmark.json │ │ ├── info.json │ │ ├── openscad-generate.py │ │ └── py │ │ │ └── __init__.py │ ├── 19-notEnoughMinerals │ │ ├── README.md │ │ ├── benchmark.json │ │ ├── info.json │ │ └── py │ │ │ └── __init__.py │ ├── 20-grovePositioningSystem │ │ ├── README.md │ │ ├── benchmark.json │ │ ├── info.json │ │ └── py │ │ │ └── __init__.py │ ├── 21-monkeyMath │ │ ├── README.md │ │ ├── benchmark.json │ │ ├── info.json │ │ └── py │ │ │ └── __init__.py │ ├── 22-monkeyMap │ │ ├── README.md │ │ ├── benchmark.json │ │ ├── info.json │ │ └── py │ │ │ └── __init__.py │ ├── 23-unstableDiffusion │ │ ├── README.md │ │ ├── benchmark.json │ │ ├── info.json │ │ └── py │ │ │ └── __init__.py │ ├── 24-blizzardBasin │ │ ├── README.md │ │ ├── benchmark.json │ │ ├── info.json │ │ └── py │ │ │ └── __init__.py │ ├── 25-fullOfHotAir │ │ ├── README.md │ │ ├── benchmark.json │ │ ├── info.json │ │ └── py │ │ │ └── __init__.py │ ├── README.md │ └── running-times.png ├── 2023 │ ├── 01-trebuchet │ │ ├── README.md │ │ ├── main.hs │ │ ├── main.py │ │ └── tests.json │ ├── 02-cubeConundrum │ │ ├── README.md │ │ ├── main.py │ │ └── tests.json │ ├── 03-gearRatios │ │ ├── README.md │ │ ├── main.py │ │ └── tests.json │ ├── 04-scratchcards │ │ ├── README.md │ │ ├── main.py │ │ └── tests.json │ ├── 05-ifYouGiveASeedAFertilizer │ │ ├── README.md │ │ ├── main.py │ │ └── tests.json │ ├── 06-waitForIt │ │ ├── README.md │ │ ├── main.py │ │ └── tests.json │ ├── 07-camelCards │ │ ├── README.md │ │ ├── main.py │ │ └── tests.json │ ├── 08-hauntedWasteland │ │ ├── README.md │ │ ├── main.py │ │ └── tests.json │ ├── 09-mirageMaintenance │ │ ├── README.md │ │ ├── main.py │ │ └── tests.json │ ├── 10-pipeMaze │ │ ├── README.md │ │ ├── main.py │ │ └── tests.json │ ├── 11-cosmicExpansion │ │ ├── README.md │ │ ├── main.py │ │ └── tests.json │ ├── 12-hotSprings │ │ ├── README.md │ │ ├── main.py │ │ ├── p1before.svg │ │ ├── p2after.svg │ │ └── tests.json │ ├── 13-pointOfIncidence │ │ ├── README.md │ │ ├── main.py │ │ └── tests.json │ ├── 14-parabolicReflectorDish │ │ ├── README.md │ │ ├── digits.txt │ │ ├── generate-vis.sh │ │ ├── main.py │ │ ├── out.mp4 │ │ ├── tests.json │ │ └── vis.py │ ├── 15-lensLibrary │ │ ├── README.md │ │ ├── main.go │ │ └── tests.json │ ├── 16-theFloorWillBeLava │ │ ├── README.md │ │ ├── main.py │ │ ├── test.txt │ │ └── tests.json │ ├── 17-clumsyCrucible │ │ ├── README.md │ │ ├── main.py │ │ └── tests.json │ ├── 18-lavaductLagoon │ │ ├── README.md │ │ ├── main.py │ │ └── tests.json │ ├── 19-aplenty │ │ ├── README.md │ │ ├── main.py │ │ └── tests.json │ ├── 20-pulsePropagation │ │ ├── README.md │ │ ├── main.py │ │ └── tests.json │ ├── 21-stepCounter │ │ ├── README.md │ │ ├── main.py │ │ └── tests.json │ ├── 22-sandSlabs │ │ ├── README.md │ │ ├── main.py │ │ └── tests.json │ ├── 23-aLongWalk │ │ ├── README.md │ │ ├── main.py │ │ └── tests.json │ ├── 24-neverTellMeTheOdds │ │ ├── README.md │ │ ├── main.py │ │ └── tests.json │ ├── 25-snowverload │ │ ├── README.md │ │ ├── main.py │ │ └── tests.json │ ├── README.md │ ├── benchmark-graph.png │ └── benchmarks.jsonl └── 2024 │ ├── 01-historianHysteria │ ├── README.md │ ├── main.py │ └── tests.json │ ├── 02-redNosedReports │ ├── README.md │ ├── main.py │ └── tests.json │ ├── 03-mullItOver │ ├── README.md │ ├── main.py │ └── tests.json │ ├── 04-ceresSearch │ ├── README.md │ ├── generate-vis.sh │ ├── heatmap-1.png │ ├── heatmap-2.png │ ├── main.py │ ├── tests.json │ └── vis.py │ ├── 05-printQueue │ ├── README.md │ ├── main.py │ └── tests.json │ ├── 06-guardGallivant │ ├── README.md │ ├── main.py │ └── tests.json │ ├── 07-bridgeRepair │ ├── README.md │ ├── main.py │ └── tests.json │ ├── 08-resonantCollinearity │ ├── README.md │ ├── generate-vis.sh │ ├── main.py │ ├── out.mp4 │ ├── tests.json │ └── vis.py │ ├── 09-diskFragmenter │ ├── README.md │ ├── main.py │ └── tests.json │ ├── README.md │ ├── benchmark-graph.png │ └── benchmarks.jsonl ├── generate-benchmark-graph.py ├── gridutil ├── __init__.py ├── coord.py └── grid.py ├── runners ├── buildGo.sh ├── buildKotlin.sh ├── jar.sh └── py.sh └── templates ├── main.go ├── main.hs ├── main.kt └── main.py /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 - 2022 codemicro 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /challenges/2020/01-reportRepair/README.md: -------------------------------------------------------------------------------- 1 | # [Day 1: Report Repair](https://adventofcode.com/2020/day/1) 2 | 3 |
Script output 4 | 5 | ``` 6 | ❯ python .\python\ 7 | AoC 2020: day 1 - Report Repair 8 | 9 | Test cases 10 | 1.1 pass 11 | 2.1 pass 12 | 13 | Answers 14 | Part 1: 1010884 15 | Part 2: 253928438 16 | 17 | ❯ go run .\go\ 18 | AoC 2020: day 1 - Report Repair 19 | Go go1.15.2 20 | 21 | Test cases 22 | 1.1 pass 23 | 2.1 pass 24 | 25 | Answers 26 | Part 1: 1010884 27 | Part 2: 253928438 28 | ``` 29 | 30 |
31 | 32 | -------------------------------------------------------------------------------- /challenges/2020/01-reportRepair/go/challenge/common.go: -------------------------------------------------------------------------------- 1 | package challenge 2 | 3 | import ( 4 | "strconv" 5 | "strings" 6 | ) 7 | 8 | func parse(instr string) []int { 9 | inputSlice := strings.Split(strings.TrimSpace(instr), "\n") 10 | 11 | var values []int 12 | for _, v := range inputSlice { 13 | str, _ := strconv.Atoi(v) 14 | values = append(values, str) 15 | } 16 | 17 | return values 18 | } 19 | -------------------------------------------------------------------------------- /challenges/2020/01-reportRepair/go/challenge/partOne.go: -------------------------------------------------------------------------------- 1 | package challenge 2 | 3 | func PartOne(instr string) int { 4 | values := parse(instr) 5 | 6 | for _, i := range values { 7 | for _, v := range values { 8 | if v+i == 2020 { 9 | return v * i 10 | } 11 | } 12 | } 13 | 14 | return 0 15 | } 16 | -------------------------------------------------------------------------------- /challenges/2020/01-reportRepair/go/challenge/partTwo.go: -------------------------------------------------------------------------------- 1 | package challenge 2 | 3 | func PartTwo(instr string) int { 4 | values := parse(instr) 5 | 6 | for _, i := range values { 7 | for _, v := range values { 8 | for _, x := range values { 9 | if v+i+x == 2020 { 10 | return v * i * x 11 | } 12 | } 13 | } 14 | } 15 | 16 | return 0 17 | } 18 | -------------------------------------------------------------------------------- /challenges/2020/01-reportRepair/python/common.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | def parse(instr: str) -> List: 5 | return [int(x) for x in instr.strip().split("\n")] 6 | -------------------------------------------------------------------------------- /challenges/2020/01-reportRepair/python/partOne.py: -------------------------------------------------------------------------------- 1 | from common import * 2 | 3 | 4 | def partOne(instr: str) -> int: 5 | values = parse(instr) 6 | 7 | for i in values: 8 | for v in values: 9 | if v + i == 2020: 10 | return v * i 11 | 12 | return 0 13 | -------------------------------------------------------------------------------- /challenges/2020/01-reportRepair/python/partTwo.py: -------------------------------------------------------------------------------- 1 | from common import * 2 | 3 | 4 | def partTwo(instr: str) -> int: 5 | values = parse(instr) 6 | 7 | for i in values: 8 | for v in values: 9 | for x in values: 10 | if v + i + x == 2020: 11 | return v * i * x 12 | 13 | return 0 14 | -------------------------------------------------------------------------------- /challenges/2020/01-reportRepair/testCases.json: -------------------------------------------------------------------------------- 1 | { 2 | "one": [ 3 | { 4 | "input": "1721\n979\n366\n299\n675\n1456", 5 | "expected": 514579 6 | } 7 | ], 8 | "two": [ 9 | { 10 | "input": "1721\n979\n366\n299\n675\n1456", 11 | "expected": 241861950 12 | } 13 | ] 14 | } -------------------------------------------------------------------------------- /challenges/2020/02-passwordPhilosophy/README.md: -------------------------------------------------------------------------------- 1 | # [Day 2: Password Philosophy](https://adventofcode.com/2020/day/2) 2 | 3 |
Script output 4 | 5 | ``` 6 | ❯ python .\python\ 7 | AoC 2020: day 2 - Password Philosophy 8 | Python 3.8.5 9 | 10 | Test cases 11 | 1.1 pass 12 | 2.1 pass 13 | 14 | Answers 15 | Part 1: 500 16 | Part 2: 313 17 | 18 | ❯ go run .\go\ 19 | AoC 2020: day 2 - Password Philosophy 20 | Go go1.15.2 21 | 22 | Test cases 23 | 1.1 pass 24 | 2.1 pass 25 | 26 | Answers 27 | Part 1: 500 28 | Part 2: 313 29 | ``` 30 | 31 |
32 | -------------------------------------------------------------------------------- /challenges/2020/02-passwordPhilosophy/go/challenge/common.go: -------------------------------------------------------------------------------- 1 | package challenge 2 | 3 | import ( 4 | "regexp" 5 | "strings" 6 | ) 7 | 8 | func parse(instr string) []string { 9 | return strings.Split(strings.TrimSpace(string(instr)), "\n") 10 | } 11 | 12 | var parserRegex = regexp.MustCompile(`(?m)(\d+)-(\d+) ([a-z]): (.+)`) 13 | -------------------------------------------------------------------------------- /challenges/2020/02-passwordPhilosophy/go/challenge/partOne.go: -------------------------------------------------------------------------------- 1 | package challenge 2 | 3 | import ( 4 | "strconv" 5 | ) 6 | 7 | func PartOne(instr string) int { 8 | inputSlice := parse(instr) 9 | 10 | type Password struct { 11 | plaintext string 12 | targetLetter rune 13 | minRepeats int 14 | maxRepeats int 15 | } 16 | 17 | var passwords []Password 18 | for _, line := range inputSlice { 19 | matches := parserRegex.FindAllStringSubmatch(line, -1) 20 | miR, _ := strconv.Atoi(matches[0][1]) 21 | maR, _ := strconv.Atoi(matches[0][2]) 22 | passwords = append(passwords, Password{ 23 | plaintext: matches[0][4], 24 | targetLetter: rune(matches[0][3][0]), 25 | minRepeats: miR, 26 | maxRepeats: maR, 27 | }) 28 | } 29 | 30 | var num_valid_passwords int 31 | 32 | for _, password := range passwords { 33 | var target_letter_count int 34 | for _, char := range password.plaintext { 35 | if char == password.targetLetter { 36 | target_letter_count += 1 37 | } 38 | } 39 | 40 | if (target_letter_count >= password.minRepeats) && (target_letter_count <= password.maxRepeats) { 41 | num_valid_passwords += 1 42 | } 43 | } 44 | 45 | return num_valid_passwords 46 | } 47 | -------------------------------------------------------------------------------- /challenges/2020/02-passwordPhilosophy/go/challenge/partTwo.go: -------------------------------------------------------------------------------- 1 | package challenge 2 | 3 | import ( 4 | "strconv" 5 | ) 6 | 7 | func PartTwo(instr string) int { 8 | inputSlice := parse(instr) 9 | 10 | type Password struct { 11 | plaintext string 12 | targetLetter rune 13 | positionOne int 14 | positionTwo int 15 | } 16 | 17 | var passwords []Password 18 | for _, line := range inputSlice { 19 | matches := parserRegex.FindAllStringSubmatch(line, -1) 20 | miR, _ := strconv.Atoi(matches[0][1]) 21 | maR, _ := strconv.Atoi(matches[0][2]) 22 | passwords = append(passwords, Password{ 23 | plaintext: matches[0][4], 24 | targetLetter: rune(matches[0][3][0]), 25 | positionOne: miR - 1, 26 | positionTwo: maR - 1, 27 | }) 28 | } 29 | 30 | var num_valid_passwords int 31 | 32 | for _, password := range passwords { 33 | positionOneMatches := rune(password.plaintext[password.positionOne]) == password.targetLetter 34 | positionTwoMatches := rune(password.plaintext[password.positionTwo]) == password.targetLetter 35 | 36 | if positionOneMatches != positionTwoMatches { 37 | num_valid_passwords += 1 38 | } 39 | } 40 | 41 | return num_valid_passwords 42 | } 43 | -------------------------------------------------------------------------------- /challenges/2020/02-passwordPhilosophy/python/common.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | def parse(instr: str) -> List: 5 | return instr.strip().split("\n") 6 | -------------------------------------------------------------------------------- /challenges/2020/02-passwordPhilosophy/testCases.json: -------------------------------------------------------------------------------- 1 | { 2 | "one": [ 3 | { 4 | "input": "1-3 a: abcde\n1-3 b: cdefg\n2-9 c: ccccccccc", 5 | "expected": 2 6 | } 7 | ], 8 | "two": [ 9 | { 10 | "input": "1-3 a: abcde\n1-3 b: cdefg\n2-9 c: ccccccccc", 11 | "expected": 1 12 | } 13 | ] 14 | } -------------------------------------------------------------------------------- /challenges/2020/03-tobogganTrajectory/README.md: -------------------------------------------------------------------------------- 1 | # [Day 3: Toboggan Trajectory](https://adventofcode.com/2020/day/3) 2 | 3 |
Script output 4 | 5 | ``` 6 | ❯ python .\python\ 7 | AoC 2020: day 3 - Toboggan Trajectory 8 | Python 3.8.5 9 | 10 | Info: could not open testCases.json. Skipping tests 11 | 12 | Answers 13 | Part 1: 292 14 | Part 2: 9354744432 15 | 16 | ❯ go run .\go\ 17 | AoC 2020: day 3 - Toboggan Trajectory 18 | Go go1.15.2 19 | 20 | Info: could not open testCases.json. Skipping tests 21 | 22 | Answers 23 | Part 1: 292 24 | Part 2: 9354744432 25 | ``` 26 | 27 |
28 | -------------------------------------------------------------------------------- /challenges/2020/03-tobogganTrajectory/go/challenge/common.go: -------------------------------------------------------------------------------- 1 | package challenge 2 | 3 | import "strings" 4 | 5 | func parse(instr string) [][]rune { 6 | inputSlice := strings.Split(strings.TrimSpace(instr), "\n") 7 | 8 | var forest [][]rune 9 | for _, line := range inputSlice { 10 | forest = append(forest, []rune(line)) 11 | } 12 | return forest 13 | } 14 | 15 | var tree_char = []rune("#")[0] // No idea why I can't just do rune("#") 16 | 17 | func findCollisions(forest [][]rune, xOffset, yOffset int) int { 18 | var encounteredTrees int 19 | var xPointer int 20 | var yPointer int 21 | 22 | for yPointer < len(forest) { 23 | row := forest[yPointer] 24 | targetIndex := xPointer % len(row) 25 | if row[targetIndex] == tree_char { 26 | encounteredTrees += 1 27 | } 28 | xPointer += xOffset 29 | yPointer += yOffset 30 | } 31 | 32 | return encounteredTrees 33 | } 34 | -------------------------------------------------------------------------------- /challenges/2020/03-tobogganTrajectory/go/challenge/partOne.go: -------------------------------------------------------------------------------- 1 | package challenge 2 | 3 | func PartOne(instr string) int { 4 | return findCollisions(parse(instr), 3, 1) 5 | } 6 | -------------------------------------------------------------------------------- /challenges/2020/03-tobogganTrajectory/go/challenge/partTwo.go: -------------------------------------------------------------------------------- 1 | package challenge 2 | 3 | func PartTwo(instr string) int { 4 | forest := parse(instr) 5 | 6 | offsetPairs := [][]int{ 7 | {3, 1}, 8 | {1, 1}, 9 | {5, 1}, 10 | {7, 1}, 11 | {1, 2}, 12 | } 13 | 14 | treeProduct := 1 15 | 16 | for _, pair := range offsetPairs { 17 | encounteredTrees := findCollisions(forest, pair[0], pair[1]) 18 | treeProduct *= encounteredTrees 19 | } 20 | 21 | return treeProduct 22 | } 23 | -------------------------------------------------------------------------------- /challenges/2020/03-tobogganTrajectory/python/common.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | tree_char = "#" 4 | 5 | 6 | def parse(instr: str) -> List: 7 | return [[char for char in line] for line in instr.strip().split("\n")] 8 | 9 | 10 | def find_collisions(forest: list, x_offset: int, y_offset: int) -> int: 11 | encountered_trees = 0 12 | x_pointer = 0 13 | 14 | for row in forest[::y_offset]: 15 | target_index = x_pointer % len(row) 16 | if row[target_index] == tree_char: 17 | encountered_trees += 1 18 | x_pointer += x_offset 19 | 20 | return encountered_trees 21 | -------------------------------------------------------------------------------- /challenges/2020/03-tobogganTrajectory/python/partOne.py: -------------------------------------------------------------------------------- 1 | from common import * 2 | 3 | 4 | def partOne(instr: str) -> int: 5 | return find_collisions(parse(instr), 3, 1) 6 | -------------------------------------------------------------------------------- /challenges/2020/03-tobogganTrajectory/python/partTwo.py: -------------------------------------------------------------------------------- 1 | from common import * 2 | 3 | 4 | def partTwo(instr: str) -> int: 5 | forest = parse(instr) 6 | 7 | tree_product = 1 8 | 9 | offset_pairs = [(3, 1), (1, 1), (5, 1), (7, 1), (1, 2)] 10 | 11 | for i, pair in enumerate(offset_pairs): 12 | encountered_trees = find_collisions(forest, *pair) 13 | tree_product *= encountered_trees 14 | 15 | return tree_product 16 | -------------------------------------------------------------------------------- /challenges/2020/04-passportProcessing/README.md: -------------------------------------------------------------------------------- 1 | # [Day 4: Passport Processing](https://adventofcode.com/2020/day/4) 2 | 3 |
Script output 4 | 5 | ``` 6 | ❯ python .\python\ 7 | AoC 2020: day 4 - Passport Processing 8 | Python 3.8.5 9 | 10 | Test cases 11 | 1.1 pass 12 | 2.1 pass 13 | 2.2 pass 14 | 15 | Answers 16 | Part 1: 213 17 | Part 2: 147 18 | 19 | ❯ go run .\go\ 20 | AoC 2020: day 4 - Passport Processing 21 | Go go1.15.2 22 | 23 | Test cases 24 | 1.1 pass 25 | 2.1 pass 26 | 2.2 pass 27 | 28 | Answers 29 | Part 1: 213 30 | Part 2: 147 31 | ``` 32 | 33 |
34 | -------------------------------------------------------------------------------- /challenges/2020/04-passportProcessing/go/challenge/common.go: -------------------------------------------------------------------------------- 1 | package challenge 2 | 3 | import "strings" 4 | 5 | func parse(instr string) []string { 6 | inputSlice := strings.Split(strings.TrimSpace(instr), "\n\n") 7 | for i, x := range inputSlice { 8 | inputSlice[i] = strings.ReplaceAll(x, "\n", " ") 9 | } 10 | return inputSlice 11 | } 12 | -------------------------------------------------------------------------------- /challenges/2020/04-passportProcessing/go/challenge/partOne.go: -------------------------------------------------------------------------------- 1 | package challenge 2 | 3 | import "regexp" 4 | 5 | func PartOne(instr string) int { 6 | inputSlice := parse(instr) 7 | 8 | var valid_passports int 9 | 10 | testCases := []*regexp.Regexp{ 11 | regexp.MustCompile(`byr:([^ ]+)`), 12 | regexp.MustCompile(`iyr:([^ ]+)`), 13 | regexp.MustCompile(`eyr:([^ ]+)`), 14 | regexp.MustCompile(`hgt:([^ ]+)`), 15 | regexp.MustCompile(`hcl:([^ ]+)`), 16 | regexp.MustCompile(`ecl:([^ ]+)`), 17 | regexp.MustCompile(`pid:([^ ]+)`), 18 | } 19 | 20 | for _, passport := range inputSlice { 21 | valid := true 22 | for _, tc := range testCases { 23 | if !tc.MatchString(passport) { 24 | valid = false 25 | break 26 | } 27 | } 28 | 29 | if valid { 30 | valid_passports += 1 31 | } 32 | 33 | } 34 | 35 | return valid_passports 36 | } 37 | -------------------------------------------------------------------------------- /challenges/2020/04-passportProcessing/python/common.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | def parse(instr: str) -> List: 5 | return [x.replace("\n", " ") for x in instr.strip().split("\n\n")] 6 | -------------------------------------------------------------------------------- /challenges/2020/04-passportProcessing/python/partOne.py: -------------------------------------------------------------------------------- 1 | import re 2 | 3 | from common import * 4 | 5 | 6 | def partOne(instr: str) -> int: 7 | input_list = parse(instr) 8 | 9 | test_cases = [ 10 | # Regex to match expression, bool if can be skipped 11 | [r"byr:([^ ]+)", False], 12 | [r"iyr:([^ ]+)", False], 13 | [r"eyr:([^ ]+)", False], 14 | [r"hgt:([^ ]+)", False], 15 | [r"hcl:([^ ]+)", False], 16 | [r"ecl:([^ ]+)", False], 17 | [r"pid:([^ ]+)", False], 18 | [r"cid:([^ ]+)", True], 19 | ] 20 | 21 | valid_passports = 0 22 | 23 | for passport in input_list: 24 | 25 | results = [] 26 | for tc in test_cases: 27 | results.append([re.search(tc[0], passport) is not None, tc[1]]) 28 | 29 | valid = True 30 | for r in results: 31 | if not (r[0] or r[1]): 32 | valid = False 33 | break 34 | 35 | valid_passports += 1 if valid else 0 36 | 37 | return valid_passports 38 | -------------------------------------------------------------------------------- /challenges/2020/05-binaryBoarding/README.md: -------------------------------------------------------------------------------- 1 | # [Day 5: Binary Boarding](https://adventofcode.com/2020/day/5) 2 | 3 |
Script output 4 | 5 | ``` 6 | ❯ python .\python\ 7 | AoC 2020: day 5 - Binary Boarding 8 | Python 3.8.5 9 | 10 | Test cases 11 | 1.1 pass 12 | 1.2 pass 13 | 1.3 pass 14 | 15 | Answers 16 | Part 1: 989 17 | Part 2: 548 18 | 19 | ❯ go run .\go\ 20 | AoC 2020: day 5 - Binary Boarding 21 | Go go1.15.2 22 | 23 | Test cases 24 | 1.1 pass 25 | 1.2 pass 26 | 1.3 pass 27 | 28 | Answers 29 | Part 1: 989 30 | Part 2: 548 31 | ``` 32 | 33 |
34 | -------------------------------------------------------------------------------- /challenges/2020/05-binaryBoarding/go/challenge/partOne.go: -------------------------------------------------------------------------------- 1 | package challenge 2 | 3 | func PartOne(instr string) int { 4 | inputSlice := parse(instr) 5 | 6 | var highestSeatId int 7 | for _, seat := range inputSlice { 8 | psr, psc := parseSeat(seat) 9 | seatId := getSeatId(psr, psc) 10 | if seatId > highestSeatId { 11 | highestSeatId = seatId 12 | } 13 | } 14 | 15 | return highestSeatId 16 | } 17 | -------------------------------------------------------------------------------- /challenges/2020/05-binaryBoarding/go/challenge/partTwo.go: -------------------------------------------------------------------------------- 1 | package challenge 2 | 3 | func PartTwo(instr string) int { 4 | inputSlice := parse(instr) 5 | 6 | var seatMatrix [numRows][numCols]bool 7 | for _, seat := range inputSlice { 8 | row, col := parseSeat(seat) 9 | seatMatrix[row][col] = true 10 | } 11 | 12 | var ( 13 | lastOne bool 14 | lastTwo bool 15 | ) 16 | 17 | for row := 0; row < len(seatMatrix); row += 1 { 18 | for col := 0; col < len(seatMatrix[row]); col += 1 { 19 | this := seatMatrix[row][col] 20 | if lastTwo && !lastOne && this { 21 | // We need to get the previous item because at this point, we've already moved on one 22 | prevRow := row 23 | prevCol := col - 1 24 | if prevCol < 0 { 25 | prevRow -= 1 26 | prevCol += numCols 27 | } 28 | return getSeatId(prevRow, prevCol) 29 | } 30 | lastTwo = lastOne 31 | lastOne = this 32 | } 33 | } 34 | 35 | return 0 36 | } 37 | -------------------------------------------------------------------------------- /challenges/2020/05-binaryBoarding/info.json: -------------------------------------------------------------------------------- 1 | { 2 | "year": "2020", 3 | "day": "5", 4 | "title": "Binary Boarding", 5 | "testCases": { 6 | "one": [ 7 | { 8 | "input": "BFFFBBFRRR", 9 | "expected": 567 10 | }, 11 | { 12 | "input": "FFFBBBFRRR", 13 | "expected": 119 14 | }, 15 | { 16 | "input": "BBFFBBFRLL", 17 | "expected": 820 18 | } 19 | ], 20 | "two": [] 21 | } 22 | } -------------------------------------------------------------------------------- /challenges/2020/05-binaryBoarding/python/common.py: -------------------------------------------------------------------------------- 1 | from typing import List, Tuple 2 | 3 | front = "F" 4 | back = "B" 5 | left = "L" 6 | right = "R" 7 | 8 | num_rows = 128 9 | num_cols = 8 10 | 11 | 12 | def parse(instr: str) -> List: 13 | return instr.strip().split("\n") 14 | 15 | 16 | def decode_position(row_string: str, dec_char: str, inc_char: str, max_val: int) -> int: 17 | min_val = 0 18 | max_val -= 1 19 | 20 | current_range = (max_val + 1) - min_val 21 | 22 | for char in row_string.upper(): 23 | 24 | range_modifier = current_range / 2 25 | 26 | if char == dec_char: 27 | max_val -= range_modifier 28 | elif char == inc_char: 29 | min_val += range_modifier 30 | 31 | current_range /= 2 32 | 33 | if row_string[-1] == dec_char: 34 | return min_val 35 | else: 36 | return max_val 37 | 38 | 39 | def parse_seat(seat_string: str) -> Tuple[int, int]: 40 | row = decode_position(seat_string[:7], front, back, num_rows) 41 | col = decode_position(seat_string[7:], left, right, num_cols) 42 | 43 | return int(row), int(col) 44 | 45 | 46 | def get_seat_id(row: int, col: int) -> int: 47 | return (row * 8) + col 48 | -------------------------------------------------------------------------------- /challenges/2020/05-binaryBoarding/python/partOne.py: -------------------------------------------------------------------------------- 1 | from common import * 2 | 3 | 4 | def partOne(instr: str) -> int: 5 | input_list = parse(instr) 6 | 7 | highest_seat_id = 0 8 | for seat in input_list: 9 | parsed_seat = parse_seat(seat) 10 | seat_id = get_seat_id(*parsed_seat) 11 | if seat_id > highest_seat_id: 12 | highest_seat_id = seat_id 13 | 14 | return highest_seat_id 15 | -------------------------------------------------------------------------------- /challenges/2020/06-customCustoms/README.md: -------------------------------------------------------------------------------- 1 | # [Day 6: Custom Customs](https://adventofcode.com/2020/day/6) 2 | 3 |
Script output 4 | 5 | ``` 6 | ❯ python .\python\ 7 | AoC 2020: day 6 - Custom Customs 8 | Python 3.8.5 9 | 10 | Test cases 11 | 1.1 pass 12 | 2.1 pass 13 | 14 | Answers 15 | Part 1: 6310 16 | Part 2: 3193 17 | 18 | ❯ go run .\go\ 19 | AoC 2020: day 6 - Custom Customs 20 | Go go1.15.2 21 | 22 | Test cases 23 | 1.1 pass 24 | 2.1 pass 25 | 26 | Answers 27 | Part 1: 6310 28 | Part 2: 3193 29 | ``` 30 | 31 |
32 | -------------------------------------------------------------------------------- /challenges/2020/06-customCustoms/go/challenge/common.go: -------------------------------------------------------------------------------- 1 | package challenge 2 | 3 | import "strings" 4 | 5 | func parse(instr string) []string { 6 | return strings.Split(strings.TrimSpace(instr), "\n\n") 7 | } 8 | 9 | type Group struct { 10 | Questions []rune 11 | NumPax int 12 | } 13 | 14 | func IsRuneInSlice(r rune, s []rune) bool { 15 | for _, v := range s { 16 | if v == r { 17 | return true 18 | } 19 | } 20 | return false 21 | } 22 | -------------------------------------------------------------------------------- /challenges/2020/06-customCustoms/go/challenge/partOne.go: -------------------------------------------------------------------------------- 1 | package challenge 2 | 3 | import "strings" 4 | 5 | func PartOne(instr string) int { 6 | newGroup := func(instr string) Group { 7 | g := Group{} 8 | 9 | individualPax := strings.Split(instr, "\n") 10 | g.NumPax = len(individualPax) 11 | 12 | for _, pax := range individualPax { 13 | for _, char := range pax { 14 | if !IsRuneInSlice(char, g.Questions) { 15 | g.Questions = append(g.Questions, char) 16 | } 17 | } 18 | } 19 | 20 | return g 21 | } 22 | 23 | var questionTotal int 24 | 25 | for _, x := range parse(instr) { 26 | questionTotal += len(newGroup(x).Questions) 27 | } 28 | 29 | return questionTotal 30 | } 31 | -------------------------------------------------------------------------------- /challenges/2020/06-customCustoms/go/challenge/partTwo.go: -------------------------------------------------------------------------------- 1 | package challenge 2 | 3 | import "strings" 4 | 5 | func PartTwo(instr string) int { 6 | 7 | checkChar := func(aq map[int][]rune, char rune) (isInAll bool) { 8 | 9 | isInAll = true 10 | for _, val := range aq { 11 | if !IsRuneInSlice(char, val) { 12 | isInAll = false 13 | break 14 | } 15 | } 16 | 17 | return 18 | } 19 | 20 | newGroup := func(instr string) Group { 21 | g := Group{} 22 | 23 | individualPax := strings.Split(instr, "\n") 24 | g.NumPax = len(individualPax) 25 | 26 | paxQuestions := make(map[int][]rune) 27 | for i, pax := range individualPax { 28 | paxQuestions[i] = []rune(pax) 29 | } 30 | 31 | for _, val := range paxQuestions { 32 | for _, char := range val { 33 | if checkChar(paxQuestions, char) { 34 | if !IsRuneInSlice(char, g.Questions) { 35 | g.Questions = append(g.Questions, char) 36 | } 37 | } 38 | } 39 | } 40 | 41 | return g 42 | } 43 | 44 | var questionTotal int 45 | 46 | for _, x := range parse(instr) { 47 | questionTotal += len(newGroup(x).Questions) 48 | } 49 | 50 | return questionTotal 51 | } 52 | -------------------------------------------------------------------------------- /challenges/2020/06-customCustoms/info.json: -------------------------------------------------------------------------------- 1 | { 2 | "year": "2020", 3 | "day": "6", 4 | "title": "Custom Customs", 5 | "testCases": { 6 | "one": [ 7 | { 8 | "input": "abc\n\na\nb\nc\n\nab\nac\n\na\na\na\na\n\nb\n", 9 | "expected": 11 10 | } 11 | ], 12 | "two": [ 13 | { 14 | "input": "abc\n\na\nb\nc\n\nab\nac\n\na\na\na\na\n\nb\n", 15 | "expected": 6 16 | } 17 | ] 18 | } 19 | } -------------------------------------------------------------------------------- /challenges/2020/06-customCustoms/python/common.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | def parse(instr: str) -> List[str]: 5 | return instr.strip().split("\n\n") 6 | -------------------------------------------------------------------------------- /challenges/2020/06-customCustoms/python/partOne.py: -------------------------------------------------------------------------------- 1 | from common import * 2 | 3 | 4 | class Group: 5 | questions: List[str] 6 | num_pax: int 7 | 8 | def __init__(self, instr: str) -> None: 9 | individual_pax = instr.split("\n") 10 | self.num_pax = len(individual_pax) 11 | 12 | self.questions = [] 13 | 14 | for pax in individual_pax: 15 | for char in pax: 16 | if char not in self.questions: 17 | self.questions.append(char) 18 | 19 | 20 | def partOne(instr: str) -> int: 21 | groups = [Group(x) for x in parse(instr)] 22 | 23 | question_total = 0 24 | 25 | for group in groups: 26 | question_total += len(group.questions) 27 | 28 | return question_total 29 | -------------------------------------------------------------------------------- /challenges/2020/07-handyHaversacks/README.md: -------------------------------------------------------------------------------- 1 | # [Day 7: Handy Haversacks](https://adventofcode.com/2020/day/7) 2 | 3 |
Script output 4 | 5 | ``` 6 | ❯ python .\python\ 7 | AoC 2020: day 7 - Handy Haversacks 8 | Python 3.8.5 9 | 10 | Test cases 11 | 1.1 pass 12 | 2.1 pass 13 | 2.2 pass 14 | 15 | Answers 16 | Part 1: 300 17 | Part 2: 8030 18 | 19 | ❯ go run .\go\ 20 | AoC 2020: day 7 - Handy Haversacks 21 | Go go1.15.2 22 | 23 | Test cases 24 | 1.1 pass 25 | 2.1 pass 26 | 2.2 pass 27 | 28 | Answers 29 | Part 1: 300 30 | Part 2: 8030 31 | ``` 32 | 33 |
34 | -------------------------------------------------------------------------------- /challenges/2020/07-handyHaversacks/go/challenge/common.go: -------------------------------------------------------------------------------- 1 | package challenge 2 | 3 | import ( 4 | "regexp" 5 | "strconv" 6 | "strings" 7 | ) 8 | 9 | var ( 10 | ruleRegex = regexp.MustCompile(`(.+) bags contain (.+).`) 11 | definitionRegex = regexp.MustCompile(`(\d+) (.+) bags?`) 12 | ) 13 | 14 | const ( 15 | targetColour = "shiny gold" 16 | ) 17 | 18 | func parse(instr string) map[string]map[string]int { 19 | inp := strings.Split(strings.TrimSpace(instr), "\n") 20 | rules := make(map[string]map[string]int) 21 | 22 | for _, rule := range inp { 23 | rr := ruleRegex.FindAllStringSubmatch(rule, -1) 24 | containerBag := rr[0][1] 25 | ruleSet := strings.Split(rr[0][2], ", ") 26 | 27 | bagRules := make(map[string]int) 28 | 29 | for _, definition := range ruleSet { 30 | rsr := definitionRegex.FindAllStringSubmatch(definition, -1) 31 | if len(rsr) != 0 { 32 | i, _ := strconv.Atoi(rsr[0][1]) 33 | bagRules[rsr[0][2]] = i 34 | } 35 | } 36 | 37 | rules[containerBag] = bagRules 38 | 39 | } 40 | 41 | return rules 42 | } 43 | -------------------------------------------------------------------------------- /challenges/2020/07-handyHaversacks/go/challenge/partOne.go: -------------------------------------------------------------------------------- 1 | package challenge 2 | 3 | func checkBag(ruleset map[string]map[string]int, testCl, targetCl string) bool { 4 | { 5 | var isPresent bool 6 | for v := range ruleset[testCl] { 7 | if v == targetCl { 8 | isPresent = true 9 | break 10 | } 11 | } 12 | if isPresent { 13 | return true 14 | } 15 | } 16 | 17 | for childColour := range ruleset[testCl] { 18 | if checkBag(ruleset, childColour, targetCl) { 19 | return true 20 | } 21 | } 22 | 23 | return false 24 | 25 | } 26 | 27 | func PartOne(instr string) int { 28 | rules := parse(instr) 29 | 30 | canContainTarget := 0 31 | 32 | for bagColour, _ := range rules { 33 | if bagColour != targetColour { 34 | if checkBag(rules, bagColour, targetColour) { 35 | canContainTarget += 1 36 | } 37 | } 38 | } 39 | 40 | return canContainTarget 41 | } 42 | -------------------------------------------------------------------------------- /challenges/2020/07-handyHaversacks/go/challenge/partTwo.go: -------------------------------------------------------------------------------- 1 | package challenge 2 | 3 | func countForBag(ruleset map[string]map[string]int, testCl string) int { 4 | if len(ruleset[testCl]) == 0 { 5 | return -1 6 | } 7 | 8 | count := 0 9 | 10 | for childColour := range ruleset[testCl] { 11 | childBags := countForBag(ruleset, childColour) 12 | var v int 13 | if childBags == -1 { 14 | v = ruleset[testCl][childColour] 15 | } else { 16 | v = ruleset[testCl][childColour] * childBags 17 | v += ruleset[testCl][childColour] 18 | } 19 | count += v 20 | } 21 | 22 | return count 23 | 24 | } 25 | 26 | func PartTwo(instr string) int { 27 | return countForBag(parse(instr), targetColour) 28 | } 29 | -------------------------------------------------------------------------------- /challenges/2020/07-handyHaversacks/python/common.py: -------------------------------------------------------------------------------- 1 | import re 2 | from typing import Dict 3 | 4 | 5 | rule_regex = re.compile(r"(.+) bags contain (.+).") 6 | definition_regex = re.compile( 7 | r"(\d+) (.+) bags?" 8 | ) # A definiton is the section of a rule that contains the conditions 9 | 10 | 11 | target_colour = "shiny gold" 12 | 13 | 14 | def parse(instr: str) -> Dict[str, Dict[str, int]]: 15 | inp = instr.strip().split("\n") 16 | 17 | rules = {} 18 | 19 | for rule in inp: 20 | rr = rule_regex.match(rule) 21 | container_bag = rr.group(1) 22 | rule_set = rr.group(2).split(", ") 23 | 24 | bag_rules = {} 25 | 26 | for definition in rule_set: 27 | rsr = definition_regex.match(definition) 28 | # if this is false, it probably means we've encountered something saying "no other bags" 29 | if rsr is not None: 30 | bag_rules[rsr.group(2)] = int(rsr.group(1)) 31 | 32 | rules[container_bag] = bag_rules 33 | 34 | return rules 35 | -------------------------------------------------------------------------------- /challenges/2020/07-handyHaversacks/python/partOne.py: -------------------------------------------------------------------------------- 1 | from common import * 2 | from typing import Dict 3 | 4 | 5 | def check_bag(ruleset: Dict[str, Dict[str, int]], test_cl: str, target_cl: str) -> bool: 6 | if ( 7 | target_cl in ruleset[test_cl] 8 | ): # bag colour can directly contain the target colour 9 | return True 10 | 11 | for child_colours in ruleset[test_cl]: 12 | if check_bag(ruleset, child_colours, target_cl): 13 | return True 14 | 15 | return False 16 | 17 | 18 | def partOne(instr: str) -> int: 19 | rules = parse(instr) 20 | 21 | can_contain_target = 0 22 | 23 | for bag_colour in rules: 24 | if bag_colour != target_colour: 25 | if check_bag(rules, bag_colour, target_colour): 26 | can_contain_target += 1 27 | 28 | return can_contain_target 29 | -------------------------------------------------------------------------------- /challenges/2020/07-handyHaversacks/python/partTwo.py: -------------------------------------------------------------------------------- 1 | from common import * 2 | from typing import Dict 3 | 4 | 5 | def count_for_bag(ruleset: Dict[str, Dict[str, int]], test_cl: str) -> int: 6 | if len(ruleset[test_cl]) == 0: 7 | return -1 8 | 9 | count = 0 10 | 11 | for child_colour in ruleset[test_cl]: 12 | child_bags = count_for_bag(ruleset, child_colour) 13 | if child_bags == -1: 14 | v = ruleset[test_cl][child_colour] 15 | else: 16 | v = ruleset[test_cl][child_colour] * child_bags 17 | # The below line includes the number of bags that contain all the children - for 18 | # example, if you had a bag type that had 6 child bags, and there were 3 of these 19 | # master bags, the line above would add all the child bags (6*3 of them), and the line 20 | # below would add the 3 container bags. 21 | v += ruleset[test_cl][child_colour] 22 | count += v 23 | 24 | return count 25 | 26 | 27 | def partTwo(instr: str) -> int: 28 | rules = parse(instr) 29 | return count_for_bag(rules, target_colour) 30 | -------------------------------------------------------------------------------- /challenges/2020/08-handheldHalting/README.md: -------------------------------------------------------------------------------- 1 | # [Day 8: Handheld Halting](https://adventofcode.com/2020/day/8) 2 | 3 |
Script output 4 | 5 | ``` 6 | ❯ python .\python\ 7 | AoC 2020: day 8 - Handheld Halting 8 | Python 3.8.5 9 | 10 | Test cases 11 | 1.1 pass 12 | 2.1 pass 13 | 14 | Answers 15 | Part 1: 1816 16 | Part 2: 1149 17 | 18 | ❯ go run .\go\ 19 | AoC 2020: day 8 - Handheld Halting 20 | Go go1.15.2 21 | 22 | Test cases 23 | 1.1 pass 24 | 2.1 pass 25 | 26 | Answers 27 | Part 1: 1816 28 | Part 2: 1149 29 | ``` 30 | 31 |
32 | -------------------------------------------------------------------------------- /challenges/2020/08-handheldHalting/go/challenge/common.go: -------------------------------------------------------------------------------- 1 | package challenge 2 | 3 | import ( 4 | "strconv" 5 | "strings" 6 | ) 7 | 8 | type Instruction struct { 9 | Opcode string 10 | Operand int 11 | } 12 | 13 | func NewInstruction(instr string) Instruction { 14 | icp := strings.Split(instr, " ") 15 | opc, err := strconv.Atoi(icp[1]) 16 | if err != nil { 17 | panic(err) 18 | } 19 | return Instruction{ 20 | Opcode: icp[0], 21 | Operand: opc, 22 | } 23 | } 24 | 25 | func parse(instr string) (o []Instruction) { 26 | for _, v := range strings.Split(strings.TrimSpace(instr), "\n") { 27 | o = append(o, NewInstruction(v)) 28 | } 29 | return 30 | } 31 | -------------------------------------------------------------------------------- /challenges/2020/08-handheldHalting/go/challenge/partOne.go: -------------------------------------------------------------------------------- 1 | package challenge 2 | 3 | func PartOne(instr string) int { 4 | instructions := parse(instr) 5 | 6 | var ( 7 | acc int 8 | pc int 9 | visited []int 10 | ) 11 | 12 | for { 13 | { 14 | var found bool 15 | for _, v := range visited { 16 | if v == pc { 17 | found = true 18 | break 19 | } 20 | } 21 | if found { 22 | return acc 23 | } else { 24 | visited = append(visited, pc) 25 | } 26 | } 27 | 28 | cir := instructions[pc] 29 | 30 | if cir.Opcode == "jmp" { 31 | pc += cir.Operand 32 | } else { 33 | switch cir.Opcode { 34 | case "acc": 35 | acc += cir.Operand 36 | case "nop": 37 | } 38 | 39 | pc += 1 40 | 41 | } 42 | 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /challenges/2020/08-handheldHalting/info.json: -------------------------------------------------------------------------------- 1 | { 2 | "year": "2020", 3 | "day": "8", 4 | "title": "Handheld Halting", 5 | "testCases": { 6 | "one": [ 7 | { 8 | "input": "nop +0\nacc +1\njmp +4\nacc +3\njmp -3\nacc -99\nacc +1\njmp -4\nacc +6", 9 | "expected": 5 10 | } 11 | ], 12 | "two": [ 13 | { 14 | "input": "nop +0\nacc +1\njmp +4\nacc +3\njmp -3\nacc -99\nacc +1\njmp -4\nacc +6", 15 | "expected": 8 16 | } 17 | ] 18 | } 19 | } -------------------------------------------------------------------------------- /challenges/2020/08-handheldHalting/python/common.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Instruction: 5 | opcode: str 6 | operand: int 7 | 8 | def __init__(self, instr: str) -> None: 9 | self.opcode, t = instr.split(" ") 10 | self.operand = int(t) 11 | 12 | 13 | def parse(instr: str) -> List[Instruction]: 14 | return [Instruction(x) for x in instr.strip().split("\n")] 15 | -------------------------------------------------------------------------------- /challenges/2020/08-handheldHalting/python/partOne.py: -------------------------------------------------------------------------------- 1 | from common import * 2 | 3 | 4 | def partOne(instr: str) -> int: 5 | instructions = parse(instr) 6 | 7 | acc = 0 8 | pc = 0 9 | 10 | visited = [] # indexes of visited instructions 11 | 12 | while True: 13 | 14 | if pc in visited: 15 | return acc 16 | else: 17 | visited.append(pc) 18 | 19 | cir = instructions[pc] 20 | 21 | if cir.opcode == "jmp": 22 | pc += cir.operand 23 | else: 24 | if cir.opcode == "acc": 25 | acc += cir.operand 26 | elif cir.opcode == "nop": 27 | pass 28 | pc += 1 29 | -------------------------------------------------------------------------------- /challenges/2020/09-encodingError/README.md: -------------------------------------------------------------------------------- 1 | # [Day 9: Encoding Error](https://adventofcode.com/2020/day/9) 2 | 3 |
Script output 4 | 5 | ``` 6 | ❯ python .\python\ 7 | AoC 2020: day 9 - Encoding Error 8 | Python 3.8.5 9 | 10 | Test cases 11 | 1.1 pass 12 | 2.1 pass 13 | 14 | Answers 15 | Part 1: 530627549 16 | Part 2: 77730285 17 | 18 | ❯ go run .\go\ 19 | AoC 2020: day 9 - Encoding Error 20 | Go go1.15.2 21 | 22 | Test cases 23 | 1.1 pass 24 | 2.1 pass 25 | 26 | Answers 27 | Part 1: 530627549 28 | Part 2: 77730285 29 | ``` 30 | 31 |
32 | -------------------------------------------------------------------------------- /challenges/2020/09-encodingError/go/challenge/common.go: -------------------------------------------------------------------------------- 1 | package challenge 2 | 3 | import ( 4 | "strconv" 5 | "strings" 6 | ) 7 | 8 | func parse(instr string) (o []int) { 9 | for _, x := range strings.Split(strings.TrimSpace(instr), "\n") { 10 | i, err := strconv.Atoi(x) 11 | if err != nil { 12 | panic(err) 13 | } 14 | o = append(o, i) 15 | } 16 | return 17 | } 18 | -------------------------------------------------------------------------------- /challenges/2020/09-encodingError/go/challenge/partTwo.go: -------------------------------------------------------------------------------- 1 | package challenge 2 | 3 | func PartTwo(instr string) int { 4 | inputSlice := parse(instr) 5 | 6 | targetValue := PartOne(instr) 7 | if targetValue == 0 { 8 | return 0 9 | } 10 | 11 | var pointer int 12 | for pointer < len(inputSlice) { 13 | startPoint := pointer 14 | iptr := pointer 15 | var count int 16 | for iptr < len(inputSlice) { 17 | count += inputSlice[iptr] 18 | 19 | if count == targetValue { 20 | if iptr-startPoint < 2 { 21 | break 22 | } 23 | 24 | allValues := inputSlice[startPoint : iptr+1] 25 | min := allValues[0] 26 | max := allValues[0] 27 | for _, v := range allValues { 28 | if v < min { 29 | min = v 30 | } 31 | if v > max { 32 | max = v 33 | } 34 | } 35 | return min + max 36 | } 37 | 38 | if count > targetValue { 39 | break 40 | } 41 | 42 | iptr += 1 43 | } 44 | 45 | pointer += 1 46 | } 47 | 48 | return 0 49 | } 50 | -------------------------------------------------------------------------------- /challenges/2020/09-encodingError/info.json: -------------------------------------------------------------------------------- 1 | { 2 | "year": "2020", 3 | "day": "9", 4 | "title": "Encoding Error", 5 | "testCases": { 6 | "one": [ 7 | { 8 | "input": "35\n20\n15\n25\n47\n40\n62\n55\n65\n95\n102\n117\n150\n182\n127\n219\n299\n277\n309\n576", 9 | "expected": 127 10 | } 11 | ], 12 | "two": [ 13 | { 14 | "input": "35\n20\n15\n25\n47\n40\n62\n55\n65\n95\n102\n117\n150\n182\n127\n219\n299\n277\n309\n576", 15 | "expected": 62 16 | } 17 | ] 18 | } 19 | } -------------------------------------------------------------------------------- /challenges/2020/09-encodingError/python/common.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | def parse(instr: str) -> List[int]: 5 | return [int(x) for x in instr.strip().split("\n")] 6 | -------------------------------------------------------------------------------- /challenges/2020/09-encodingError/python/partOne.py: -------------------------------------------------------------------------------- 1 | from typing import Set 2 | 3 | from common import * 4 | 5 | 6 | def has_combinations(options: Set[int], target: int) -> bool: 7 | # Returns true of the options set has two values that sum to be the target, else returns false 8 | 9 | options = sorted(options) 10 | 11 | l_ptr = 0 12 | r_ptr = len(options) - 1 13 | 14 | while l_ptr < r_ptr: 15 | v = options[l_ptr] + options[r_ptr] 16 | if v == target: 17 | return True 18 | elif v < target: 19 | l_ptr += 1 20 | else: 21 | r_ptr -= 1 22 | 23 | return False 24 | 25 | 26 | def partOne(instr: str) -> int: 27 | input_list = parse(instr) 28 | 29 | preamble_len = 25 30 | if len(input_list) < 30: # This is for tests 31 | preamble_len = 5 32 | 33 | pointer = preamble_len 34 | while pointer < len(input_list): 35 | if not has_combinations( 36 | set(input_list[pointer - preamble_len : pointer]), input_list[pointer] 37 | ): 38 | return input_list[pointer] 39 | pointer += 1 40 | 41 | return 0 42 | -------------------------------------------------------------------------------- /challenges/2020/09-encodingError/python/partTwo.py: -------------------------------------------------------------------------------- 1 | from common import * 2 | from partOne import partOne 3 | 4 | 5 | def partTwo(instr: str) -> int: 6 | input_list = parse(instr) 7 | 8 | target_value = partOne(instr) 9 | if target_value == 0: 10 | return 0 11 | 12 | pointer = 0 13 | while pointer < len(input_list): 14 | # iterate consecutive values from here 15 | start_point = pointer 16 | iptr = pointer # Internal PoinTeR 17 | count = 0 18 | while iptr < len(input_list): 19 | count += input_list[iptr] 20 | 21 | if count == target_value: 22 | # must be at least two values 23 | if iptr - start_point < 2: 24 | break 25 | 26 | all_values = input_list[start_point : iptr + 1] 27 | return min(all_values) + max(all_values) 28 | 29 | if count > target_value: 30 | break 31 | 32 | iptr += 1 33 | 34 | pointer += 1 35 | 36 | return 0 37 | -------------------------------------------------------------------------------- /challenges/2020/10-adapterArray/go/challenge/partTwo.go: -------------------------------------------------------------------------------- 1 | package challenge 2 | 3 | import ( 4 | "sort" 5 | "strconv" 6 | "strings" 7 | ) 8 | 9 | func PartTwo(instr string) int { 10 | var joltages []int 11 | for _, x := range strings.Split(strings.TrimSpace(instr), "\n") { 12 | i, err := strconv.Atoi(x) 13 | if err != nil { 14 | panic(err) 15 | } 16 | joltages = append(joltages, i) 17 | } 18 | sort.Ints(joltages) 19 | 20 | routeLengths := map[int]int{0: 1} 21 | 22 | for _, joltage := range joltages { 23 | var totalRoutes int 24 | for _, n := range []int{1, 2, 3} { 25 | v, exists := routeLengths[joltage-n] 26 | if !exists { 27 | v = 0 28 | } 29 | totalRoutes += v 30 | } 31 | routeLengths[joltage] = totalRoutes 32 | } 33 | 34 | return routeLengths[joltages[len(joltages)-1]] 35 | } 36 | -------------------------------------------------------------------------------- /challenges/2020/10-adapterArray/info.json: -------------------------------------------------------------------------------- 1 | { 2 | "year": "2020", 3 | "day": "10", 4 | "title": "Adapter Array", 5 | "testCases": { 6 | "one": [ 7 | { 8 | "input": "16\n10\n15\n5\n1\n11\n7\n19\n6\n12\n4", 9 | "expected": 35 10 | }, 11 | { 12 | "input": "28\n33\n18\n42\n31\n14\n46\n20\n48\n47\n24\n23\n49\n45\n19\n38\n39\n11\n1\n32\n25\n35\n8\n17\n7\n9\n4\n2\n34\n10\n3", 13 | "expected": 220 14 | } 15 | ], 16 | "two": [ 17 | { 18 | "input": "16\n10\n15\n5\n1\n11\n7\n19\n6\n12\n4", 19 | "expected": 8 20 | }, 21 | { 22 | "input": "28\n33\n18\n42\n31\n14\n46\n20\n48\n47\n24\n23\n49\n45\n19\n38\n39\n11\n1\n32\n25\n35\n8\n17\n7\n9\n4\n2\n34\n10\n3", 23 | "expected": 19208 24 | } 25 | ] 26 | } 27 | } -------------------------------------------------------------------------------- /challenges/2020/10-adapterArray/python/partTwo.py: -------------------------------------------------------------------------------- 1 | def partTwo(instr: str) -> int: 2 | joltages = sorted([int(x) for x in instr.strip().split("\n")]) 3 | 4 | route_lengths = {0: 1} 5 | for joltage in joltages: 6 | total_routes = 0 7 | # Get the route lengths for the three previous joltages 8 | for n in [1, 2, 3]: 9 | total_routes += route_lengths.get(joltage - n, 0) 10 | print(joltage, total_routes) 11 | route_lengths[joltage] = total_routes 12 | 13 | return route_lengths[max(joltages)] 14 | -------------------------------------------------------------------------------- /challenges/2020/11-seatingSystem/0.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codemicro/adventOfCode/569c26b209f4f0a8879cac902fc926f0f9515703/challenges/2020/11-seatingSystem/0.gif -------------------------------------------------------------------------------- /challenges/2020/11-seatingSystem/1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codemicro/adventOfCode/569c26b209f4f0a8879cac902fc926f0f9515703/challenges/2020/11-seatingSystem/1.gif -------------------------------------------------------------------------------- /challenges/2020/11-seatingSystem/README.md: -------------------------------------------------------------------------------- 1 | # [Day 11: Seating System](https://adventofcode.com/2020/day/11) 2 | 3 | ### Related 4 | 5 | * [Wikipedia - Cellular automata](https://en.wikipedia.org/wiki/Cellular_automaton) 6 | * [Wikipedia - Moore neighbourhood](https://en.wikipedia.org/wiki/Moore_neighborhood) 7 | 8 | ### Visualisation 9 | 10 | | Part one | Part two | 11 | | ------------------------------ | ------------------------------ | 12 | | ![partOne gif](0.gif?raw=true) | ![partTwo gif](1.gif?raw=true) | 13 | 14 | --- 15 | 16 |
Script output 17 | 18 | ``` 19 | ❯ python .\python\ 20 | AoC 2020: day 11 - Seating System 21 | Python 3.8.5 22 | 23 | Test cases 24 | 1.1 pass 25 | 2.1 pass 26 | 27 | Answers 28 | Part 1: 2283 29 | Part 2: 2054 30 | 31 | ❯ go run .\go\ 32 | AoC 2020: day 11 - Seating System 33 | Go go1.15.2 34 | 35 | Test cases 36 | 1.1 pass 37 | 2.1 pass 38 | 39 | Answers 40 | Part 1: 2283 41 | Part 2: 2054 42 | ``` 43 | 44 |
45 | -------------------------------------------------------------------------------- /challenges/2020/11-seatingSystem/go/challenge/partOne.go: -------------------------------------------------------------------------------- 1 | package challenge 2 | 3 | func getNewStateOne(numNeighbours int, oldState rune) rune { 4 | if numNeighbours == 0 { 5 | return filledSeat 6 | } else if numNeighbours >= 4 && oldState == filledSeat { 7 | return openSeat 8 | } 9 | return oldState 10 | } 11 | 12 | func countNeighboursOne(hall [][]rune, currentPos [2]int, hallSize [2]int) (numNeighbours int) { 13 | row := currentPos[0] 14 | col := currentPos[1] 15 | 16 | for _, position := range lookupPositions { 17 | test_x_pos := position[0] + col 18 | test_y_pos := position[1] + row 19 | 20 | if 0 <= test_x_pos && test_x_pos < hallSize[0] && 0 <= test_y_pos && test_y_pos < hallSize[1] { 21 | if hall[test_y_pos][test_x_pos] == filledSeat { 22 | numNeighbours += 1 23 | } 24 | } 25 | } 26 | 27 | return 28 | } 29 | 30 | func PartOne(instr string) int { 31 | return run(parse(instr), countNeighboursOne, getNewStateOne) 32 | } 33 | -------------------------------------------------------------------------------- /challenges/2020/11-seatingSystem/go/challenge/partTwo.go: -------------------------------------------------------------------------------- 1 | package challenge 2 | 3 | func getNewStateTwo(numNeighbours int, oldState rune) rune { 4 | if numNeighbours == 0 { 5 | return filledSeat 6 | } else if numNeighbours >= 5 && oldState == filledSeat { 7 | return openSeat 8 | } 9 | return oldState 10 | } 11 | 12 | func countNeighboursTwo(hall [][]rune, currentPos [2]int, hallSize [2]int) (numNeighbours int) { 13 | row := currentPos[0] 14 | col := currentPos[1] 15 | 16 | for _, position := range lookupPositions { 17 | test_x_pos := position[0] + col 18 | test_y_pos := position[1] + row 19 | 20 | for 0 <= test_x_pos && test_x_pos < hallSize[0] && 0 <= test_y_pos && test_y_pos < hallSize[1] { 21 | 22 | testLocation := hall[test_y_pos][test_x_pos] 23 | 24 | if testLocation == filledSeat { 25 | numNeighbours += 1 26 | } 27 | 28 | if testLocation == openSeat || testLocation == filledSeat { 29 | break 30 | } 31 | 32 | test_x_pos += position[0] 33 | test_y_pos += position[1] 34 | 35 | } 36 | } 37 | 38 | return 39 | } 40 | 41 | func PartTwo(instr string) int { 42 | return run(parse(instr), countNeighboursTwo, getNewStateTwo) 43 | } 44 | -------------------------------------------------------------------------------- /challenges/2020/11-seatingSystem/info.json: -------------------------------------------------------------------------------- 1 | { 2 | "year": "2020", 3 | "day": "11", 4 | "title": "Seating System", 5 | "testCases": { 6 | "one": [ 7 | { 8 | "input": "L.LL.LL.LL\nLLLLLLL.LL\nL.L.L..L..\nLLLL.LL.LL\nL.LL.LL.LL\nL.LLLLL.LL\n..L.L.....\nLLLLLLLLLL\nL.LLLLLL.L\nL.LLLLL.LL\n", 9 | "expected": 37 10 | } 11 | ], 12 | "two": [ 13 | { 14 | "input": "L.LL.LL.LL\nLLLLLLL.LL\nL.L.L..L..\nLLLL.LL.LL\nL.LL.LL.LL\nL.LLLLL.LL\n..L.L.....\nLLLLLLLLLL\nL.LLLLLL.L\nL.LLLLL.LL\n", 15 | "expected": 26 16 | } 17 | ] 18 | } 19 | } -------------------------------------------------------------------------------- /challenges/2020/11-seatingSystem/python/partOne.py: -------------------------------------------------------------------------------- 1 | from typing import List, Tuple 2 | 3 | from common import * 4 | 5 | 6 | def get_new_state(num_neighbours: int, old_state: str) -> str: 7 | if num_neighbours == 0: 8 | return filled_seat 9 | elif num_neighbours >= 4 and old_state == filled_seat: 10 | return open_seat 11 | 12 | return old_state 13 | 14 | 15 | def count_neighbours( 16 | hall: List[List[str]], current_pos: Tuple[int, int], hall_size: Tuple[int, int] 17 | ) -> int: 18 | num_neighbours = 0 19 | 20 | row, col = current_pos 21 | 22 | for (x, y) in lookup_positions: 23 | test_x_pos = x + col 24 | test_y_pos = y + row 25 | 26 | if 0 <= test_x_pos < hall_size[0] and 0 <= test_y_pos < hall_size[1]: 27 | if hall[test_y_pos][test_x_pos] == filled_seat: 28 | num_neighbours += 1 29 | 30 | return num_neighbours 31 | 32 | 33 | def partOne(instr: str) -> int: 34 | return run(parse(instr), count_neighbours, get_new_state) 35 | -------------------------------------------------------------------------------- /challenges/2020/12-rainRisk/0.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codemicro/adventOfCode/569c26b209f4f0a8879cac902fc926f0f9515703/challenges/2020/12-rainRisk/0.gif -------------------------------------------------------------------------------- /challenges/2020/12-rainRisk/1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codemicro/adventOfCode/569c26b209f4f0a8879cac902fc926f0f9515703/challenges/2020/12-rainRisk/1.gif -------------------------------------------------------------------------------- /challenges/2020/12-rainRisk/info.json: -------------------------------------------------------------------------------- 1 | { 2 | "year": "2020", 3 | "day": "12", 4 | "title": "Rain Risk", 5 | "testCases": { 6 | "one": [ 7 | { 8 | "input": "F10\nN3\nF7\nR90\nF11", 9 | "expected": 25 10 | } 11 | ], 12 | "two": [ 13 | { 14 | "input": "F10\nN3\nF7\nR90\nF11", 15 | "expected": 286 16 | } 17 | ] 18 | } 19 | } -------------------------------------------------------------------------------- /challenges/2020/12-rainRisk/python/common.py: -------------------------------------------------------------------------------- 1 | from typing import List, Tuple 2 | 3 | 4 | class Instruction: 5 | action: str 6 | magnitude: int 7 | raw: str 8 | 9 | def __init__(self, instruction: str) -> None: 10 | self.action = instruction[0].lower() 11 | self.magnitude = int(instruction[1:]) 12 | self.raw = instruction 13 | 14 | 15 | def parse(instr: str) -> List[Instruction]: 16 | return [Instruction(x) for x in instr.strip().split("\n")] 17 | 18 | 19 | def calculate_direction_deltas(direction: str, amount: int) -> Tuple[int, int]: 20 | # returns a pair of deltas representing lat,long 21 | lat_delta = 0 22 | long_delta = 0 23 | 24 | if direction == "n": 25 | lat_delta += amount 26 | elif direction == "s": 27 | lat_delta -= amount 28 | 29 | elif direction == "e": 30 | long_delta += amount 31 | elif direction == "w": 32 | long_delta -= amount 33 | 34 | else: 35 | raise AssertionError(f"invalid direction '{direction}'") 36 | 37 | return lat_delta, long_delta 38 | -------------------------------------------------------------------------------- /challenges/2020/12-rainRisk/quadrants.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codemicro/adventOfCode/569c26b209f4f0a8879cac902fc926f0f9515703/challenges/2020/12-rainRisk/quadrants.png -------------------------------------------------------------------------------- /challenges/2020/12-rainRisk/rotation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codemicro/adventOfCode/569c26b209f4f0a8879cac902fc926f0f9515703/challenges/2020/12-rainRisk/rotation.png -------------------------------------------------------------------------------- /challenges/2020/13-shuttleSearch/README.md: -------------------------------------------------------------------------------- 1 | # [Day 13: Shuttle Search](https://adventofcode.com/2020/day/13) 2 | 3 | No, I don't really know why the maths works, but it works! 4 | 5 | Here are the notes I made for part two to work this out for a test case before implementing it for the first time to make sure that my method worked. 6 | 7 | ![test notes](working.jpg) 8 | 9 | ### Related 10 | 11 | * [Maths with Jay - Chinese remainder theorem](https://www.youtube.com/watch?v=zIFehsBHB8o) 12 | * [StackOverflow - Modular multiplicative inverse function in Python](https://stackoverflow.com/a/9758173) 13 | 14 |
Script output 15 | 16 | ``` 17 | ❯ python .\python\ 18 | AoC 2020: day 13 - Shuttle Search 19 | Python 3.8.5 20 | 21 | Test cases 22 | 1.1 pass 23 | 2.1 pass 24 | 2.2 pass 25 | 2.3 pass 26 | 2.4 pass 27 | 2.5 pass 28 | 2.6 pass 29 | 30 | Answers 31 | Part 1: 4782 32 | Part 2: 1118684865113056 33 | ``` 34 | 35 |
36 | -------------------------------------------------------------------------------- /challenges/2020/13-shuttleSearch/info.json: -------------------------------------------------------------------------------- 1 | { 2 | "year": "2020", 3 | "day": "13", 4 | "title": "Shuttle Search", 5 | "testCases": { 6 | "one": [ 7 | { 8 | "input": "939\n7,13,x,x,59,x,31,19", 9 | "expected": 295 10 | } 11 | ], 12 | "two": [ 13 | { 14 | "input": "939\n7,13,x,x,59,x,31,19", 15 | "expected": 1068781 16 | }, 17 | { 18 | "input": "1\n17,x,13,19", 19 | "expected": 3417 20 | }, 21 | { 22 | "input": "1\n67,7,59,61", 23 | "expected": 754018 24 | }, 25 | { 26 | "input": "1\n67,x,7,59,61", 27 | "expected": 779210 28 | }, 29 | { 30 | "input": "1\n67,7,x,59,61", 31 | "expected": 1261476 32 | }, 33 | { 34 | "input": "1\n1789,37,47,1889", 35 | "expected": 1202161486 36 | } 37 | ] 38 | } 39 | } -------------------------------------------------------------------------------- /challenges/2020/13-shuttleSearch/python/partOne.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Timetable: 5 | earliest_departure: int 6 | services: List[int] 7 | 8 | def __init__(self, earliest_departure: int, services: str): 9 | self.earliest_departure = earliest_departure 10 | self.services = [int(s) for s in services.split(",") if s != "x"] 11 | 12 | 13 | def parse(instr: str) -> Timetable: 14 | instr = instr.strip().split("\n") 15 | return Timetable(int(instr[0]), instr[1]) 16 | 17 | 18 | def partOne(instr: str) -> int: 19 | timetable = parse(instr) 20 | 21 | earliest_times = [] 22 | for service in timetable.services: 23 | earliest_times.append( 24 | (service, (int(timetable.earliest_departure / service) + 1) * service) 25 | ) 26 | 27 | route, earliest_departure = min(earliest_times, key=lambda x: x[1]) 28 | 29 | return route * (earliest_departure - timetable.earliest_departure) 30 | -------------------------------------------------------------------------------- /challenges/2020/13-shuttleSearch/python/partTwo.py: -------------------------------------------------------------------------------- 1 | def partTwo(instr: str) -> int: 2 | # This is the parsing section 3 | service_list = instr.strip().split("\n")[-1].split(",") 4 | 5 | eqns = [] 6 | for i, svc in enumerate(service_list): 7 | if svc == "x": 8 | continue 9 | svc = int(svc) 10 | 11 | v = 0 12 | if i != 0: 13 | v = svc - i # This is the only maths stuff in the parsing 14 | 15 | eqns.append((v, svc)) 16 | 17 | # This is the maths section 18 | 19 | n = 1 20 | for (_, v) in eqns: 21 | n *= v 22 | 23 | sigma_x = 0 24 | for (bi, ni) in eqns: 25 | # this type cast could potentially cause a problem. 26 | # int required for pow function and the division *should* produce a whole number anyway 27 | Ni = int(n / ni) 28 | yi = pow(Ni, -1, ni) # https://stackoverflow.com/a/9758173 29 | sigma_x += bi * Ni * yi 30 | 31 | return sigma_x % n 32 | -------------------------------------------------------------------------------- /challenges/2020/13-shuttleSearch/working.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codemicro/adventOfCode/569c26b209f4f0a8879cac902fc926f0f9515703/challenges/2020/13-shuttleSearch/working.jpg -------------------------------------------------------------------------------- /challenges/2020/14-dockingData/README.md: -------------------------------------------------------------------------------- 1 | # [Day 14: Docking Data](https://adventofcode.com/2020/day/14) 2 | 3 |
Script output 4 | 5 | ``` 6 | ❯ python .\python\ 7 | AoC 2020: day 14 - Docking Data 8 | Python 3.8.5 9 | 10 | Test cases 11 | 1.1 pass 12 | 2.1 pass 13 | 14 | Answers 15 | Part 1: 8570568288597 16 | Part 2: 3289441921203 17 | 18 | ❯ go run .\go\ 19 | AoC 2020: day 14 - Docking Data 20 | Go go1.15.2 21 | 22 | Test cases 23 | 1.1 pass 24 | 2.1 pass 25 | 26 | Answers 27 | Part 1: 8570568288597 28 | Part 2: 3289441921203 29 | ``` 30 | 31 |
32 | -------------------------------------------------------------------------------- /challenges/2020/14-dockingData/go/challenge/partOne.go: -------------------------------------------------------------------------------- 1 | package challenge 2 | 3 | import ( 4 | "strconv" 5 | "strings" 6 | ) 7 | 8 | func applyMask(number int, mask string) int { 9 | mask = strings.ToLower(mask) 10 | value := numberToBase(number, 2) 11 | value = zfill(value, len(mask)-len(value)) 12 | var combi string 13 | for i := 0; i < len(value); i += 1 { 14 | v := string(value[i]) 15 | m := string(mask[i]) 16 | 17 | if m == "x" { 18 | combi += v 19 | } else { 20 | combi += m 21 | } 22 | } 23 | ix, err := strconv.ParseInt(combi, 2, 64) 24 | if err != nil { 25 | panic(err) 26 | } 27 | return int(ix) 28 | } 29 | 30 | func PartOne(instr string) int { 31 | inputInstructions := parse(instr) 32 | memory := make(map[int]int) 33 | 34 | for _, instruction := range inputInstructions { 35 | memory[instruction.Address] = applyMask(instruction.Value, instruction.Mask) 36 | } 37 | 38 | var sigma int 39 | for _, v := range memory { 40 | sigma += v 41 | } 42 | return sigma 43 | } 44 | -------------------------------------------------------------------------------- /challenges/2020/14-dockingData/info.json: -------------------------------------------------------------------------------- 1 | { 2 | "year": "2020", 3 | "day": "14", 4 | "title": "Docking Data", 5 | "testCases": { 6 | "one": [ 7 | { 8 | "input": "mask = XXXXXXXXXXXXXXXXXXXXXXXXXXXXX1XXXX0X\nmem[8] = 11\nmem[7] = 101\nmem[8] = 0\n", 9 | "expected": 165 10 | } 11 | ], 12 | "two": [ 13 | { 14 | "input": "mask = 000000000000000000000000000000X1001X\nmem[42] = 100\nmask = 00000000000000000000000000000000X0XX\nmem[26] = 1\n", 15 | "expected": 208 16 | } 17 | ] 18 | } 19 | } -------------------------------------------------------------------------------- /challenges/2020/14-dockingData/python/partOne.py: -------------------------------------------------------------------------------- 1 | from common import * 2 | 3 | 4 | def apply_mask(number: int, mask: str) -> int: 5 | # There has to be a better way to do this... but oh well 6 | # it works, after all 7 | value = number_to_base(number, 2).zfill(len(mask)) 8 | combi = "" 9 | for (v, m) in zip(value, mask.lower()): 10 | if m == "x": 11 | combi += v 12 | else: 13 | combi += m 14 | return int(combi, 2) 15 | 16 | 17 | def partOne(instr: str) -> int: 18 | input_instructions = parse(instr) 19 | memory = {} 20 | 21 | for instruction in input_instructions: 22 | memory[instruction.address] = apply_mask(instruction.value, instruction.mask) 23 | 24 | sigma = 0 25 | for key in memory: 26 | sigma += memory[key] 27 | 28 | return sigma 29 | -------------------------------------------------------------------------------- /challenges/2020/15-rambunctiousRecitation/0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codemicro/adventOfCode/569c26b209f4f0a8879cac902fc926f0f9515703/challenges/2020/15-rambunctiousRecitation/0.png -------------------------------------------------------------------------------- /challenges/2020/15-rambunctiousRecitation/1-hires.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codemicro/adventOfCode/569c26b209f4f0a8879cac902fc926f0f9515703/challenges/2020/15-rambunctiousRecitation/1-hires.png -------------------------------------------------------------------------------- /challenges/2020/15-rambunctiousRecitation/1-lores.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codemicro/adventOfCode/569c26b209f4f0a8879cac902fc926f0f9515703/challenges/2020/15-rambunctiousRecitation/1-lores.png -------------------------------------------------------------------------------- /challenges/2020/15-rambunctiousRecitation/README.md: -------------------------------------------------------------------------------- 1 | # [Day 15: Rambunctious Recitation](https://adventofcode.com/2020/day/15) 2 | 3 | ### Visualisation 4 | 5 | | Part one | Part two | 6 | | ------------------------------ | ------------------------------------ | 7 | | ![partOne png](0.png?raw=true) | ![partTwo png](1-hires.png?raw=true) | 8 | 9 | ### Related 10 | 11 | - [Numberphile - Don't Know (the Van Eck Sequence)](https://www.youtube.com/watch?v=etMJxB-igrc) 12 | 13 |
Script output 14 | 15 | ``` 16 | ❯ python .\python\ 17 | AoC 2020: day 15 - Rambunctious Recitation 18 | Python 3.8.5 19 | 20 | Test cases 21 | 1.1 pass 22 | 1.2 pass 23 | 1.3 pass 24 | 1.4 pass 25 | 1.5 pass 26 | 1.6 pass 27 | 2.1 pass 28 | 29 | Answers 30 | Part 1: 206 31 | Part 2: 955 32 | 33 | ❯ go run .\go\ 34 | AoC 2020: day 15 - Rambunctious Recitation 35 | Go go1.15.2 36 | 37 | Test cases 38 | 1.1 pass 39 | 1.2 pass 40 | 1.3 pass 41 | 1.4 pass 42 | 1.5 pass 43 | 1.6 pass 44 | 2.1 pass 45 | 46 | Answers 47 | Part 1: 206 48 | Part 2: 955 49 | ``` 50 | 51 |
52 | -------------------------------------------------------------------------------- /challenges/2020/15-rambunctiousRecitation/go/challenge/common.go: -------------------------------------------------------------------------------- 1 | package challenge 2 | 3 | import ( 4 | "strconv" 5 | "strings" 6 | ) 7 | 8 | func findValueN(instr string, threshold int) int { 9 | var inp []int 10 | for _, x := range strings.Split(strings.TrimSpace(instr), ",") { 11 | i, err := strconv.Atoi(x) 12 | if err != nil { 13 | panic(err) 14 | } 15 | inp = append(inp, i) 16 | } 17 | 18 | indexes := make(map[int]int) 19 | 20 | for i, n := range inp { 21 | indexes[n] = i 22 | } 23 | 24 | for len(inp) < threshold { 25 | c := len(inp) - 1 26 | previousNumber := inp[c] 27 | 28 | var previousOccuranceIndex int 29 | val, found := indexes[previousNumber] 30 | if !found { 31 | previousOccuranceIndex = -1 32 | } else { 33 | previousOccuranceIndex = val 34 | } 35 | 36 | var newNumber int 37 | 38 | if previousOccuranceIndex != -1 { 39 | newNumber = c - previousOccuranceIndex 40 | } 41 | 42 | indexes[previousNumber] = c 43 | inp = append(inp, newNumber) 44 | } 45 | 46 | return inp[len(inp)-1] 47 | } 48 | -------------------------------------------------------------------------------- /challenges/2020/15-rambunctiousRecitation/go/challenge/partOne.go: -------------------------------------------------------------------------------- 1 | package challenge 2 | 3 | func PartOne(instr string) int { 4 | return findValueN(instr, 2020) 5 | } 6 | -------------------------------------------------------------------------------- /challenges/2020/15-rambunctiousRecitation/go/challenge/partTwo.go: -------------------------------------------------------------------------------- 1 | package challenge 2 | 3 | func PartTwo(instr string) int { 4 | return findValueN(instr, 30000000) 5 | } 6 | -------------------------------------------------------------------------------- /challenges/2020/15-rambunctiousRecitation/info.json: -------------------------------------------------------------------------------- 1 | { 2 | "year": "2020", 3 | "day": "15", 4 | "title": "Rambunctious Recitation", 5 | "testCases": { 6 | "one": [ 7 | { 8 | "input": "0,3,6", 9 | "expected": 436 10 | }, 11 | { 12 | "input": "1,3,2", 13 | "expected": 1 14 | }, 15 | { 16 | "input": "1,2,3", 17 | "expected": 27 18 | }, 19 | { 20 | "input": "2,3,1", 21 | "expected": 78 22 | }, 23 | { 24 | "input": "3,2,1", 25 | "expected": 438 26 | }, 27 | { 28 | "input": "3,1,2", 29 | "expected": 1836 30 | } 31 | ], 32 | "two": [ 33 | { 34 | "input": "0,3,6", 35 | "info": "other test cases ommitted because part two takes quite a while", 36 | "expected": 175594 37 | } 38 | ] 39 | } 40 | } -------------------------------------------------------------------------------- /challenges/2020/15-rambunctiousRecitation/python/common.py: -------------------------------------------------------------------------------- 1 | from typing import List, Tuple 2 | 3 | 4 | def find_value_n(instr: str, threshold: int) -> Tuple[int, List[int]]: 5 | inp = [int(x) for x in instr.strip().split(",")] 6 | 7 | indexes = {} 8 | 9 | for i, n in enumerate(inp): 10 | indexes[n] = i 11 | 12 | while len(inp) < threshold: 13 | c = len(inp) - 1 14 | previous_number = inp[c] 15 | 16 | previous_occurance_index = indexes.get(previous_number, None) 17 | new_number = 0 18 | 19 | if previous_occurance_index is not None: 20 | new_number = c - previous_occurance_index 21 | 22 | indexes[previous_number] = c 23 | 24 | inp.append(new_number) 25 | 26 | return inp[-1], inp 27 | -------------------------------------------------------------------------------- /challenges/2020/15-rambunctiousRecitation/python/partOne.py: -------------------------------------------------------------------------------- 1 | from common import * 2 | 3 | 4 | def partOne(instr: str) -> int: 5 | x, _ = find_value_n(instr, 2020) 6 | return x 7 | -------------------------------------------------------------------------------- /challenges/2020/15-rambunctiousRecitation/python/partTwo.py: -------------------------------------------------------------------------------- 1 | from common import * 2 | 3 | 4 | def partTwo(instr: str) -> int: 5 | x, _ = find_value_n(instr, 30000000) 6 | return x 7 | -------------------------------------------------------------------------------- /challenges/2020/15-rambunctiousRecitation/python/visualise.py: -------------------------------------------------------------------------------- 1 | import common 2 | import matplotlib.pyplot as plt 3 | from typing import List 4 | 5 | 6 | def make_graph(data: List[int], n: int): 7 | line_colour = "#3572a5" 8 | plt.plot(list(range(len(data))), data, color=line_colour) 9 | plt.title(f"AoC 2020, day 15 part {n}") 10 | plt.xlabel("Iteration number") 11 | plt.ylabel("Value") 12 | 13 | 14 | def visualise(instr: str): 15 | print("Running part one...") 16 | _, one = common.find_value_n(instr, 2020) 17 | print("Making graph") 18 | make_graph(one, 1) 19 | print("Saving") 20 | plt.savefig("0.png") 21 | plt.clf() 22 | print("Running part two...") 23 | _, two = common.find_value_n(instr, 30000000) 24 | print("Making graph") 25 | make_graph(two, 2) 26 | print("Saving low resolution") 27 | plt.savefig("1-lores.png") 28 | print("Saving high resolution") 29 | fig = plt.gcf() 30 | fig.set_size_inches(20.48, 10.8) 31 | fig.savefig("1-hires.png", dpi=100) 32 | -------------------------------------------------------------------------------- /challenges/2020/16-ticketTranslation/README.md: -------------------------------------------------------------------------------- 1 | # [Day 16: Ticket Translation](https://adventofcode.com/2020/day/16) 2 | 3 | It took me a long while to realise each column could have multiple different possibilities for which ticket field it could be. 4 | 5 |
Script output 6 | 7 | ``` 8 | ❯ python .\python\ 9 | AoC 2020: day 16 - Ticket Translation 10 | Python 3.8.5 11 | 12 | Test cases 13 | 1.1 pass 14 | 2.1 pass 15 | 16 | Answers 17 | Part 1: 29019 18 | Part 2: 517827547723 19 | 20 | ❯ go run .\go\ 21 | AoC 2020: day 16 - Ticket Translation 22 | Go go1.15.2 23 | 24 | Test cases 25 | 1.1 pass 26 | 2.1 pass 27 | 28 | Answers 29 | Part 1: 29019 30 | Part 2: 517827547723 31 | ``` 32 | 33 |
34 | -------------------------------------------------------------------------------- /challenges/2020/16-ticketTranslation/go/challenge/partOne.go: -------------------------------------------------------------------------------- 1 | package challenge 2 | 3 | func PartOne(instr string) int { 4 | rules, _, tickets := parse(instr) 5 | invalidValues, _ := findInvalid(rules, tickets) 6 | 7 | var sigma int 8 | for _, v := range invalidValues { 9 | sigma += v 10 | } 11 | 12 | return sigma 13 | } 14 | -------------------------------------------------------------------------------- /challenges/2020/16-ticketTranslation/info.json: -------------------------------------------------------------------------------- 1 | { 2 | "year": "2020", 3 | "day": "16", 4 | "title": "Ticket Translation", 5 | "testCases": { 6 | "one": [ 7 | { 8 | "input": "class: 1-3 or 5-7\nrow: 6-11 or 33-44\nseat: 13-40 or 45-50\n\nyour ticket:\n7,1,14\n\nnearby tickets:\n7,3,47\n40,4,50\n55,2,20\n38,6,12", 9 | "expected": 71 10 | } 11 | ], 12 | "two": [ 13 | { 14 | "input":"departure class: 0-1 or 4-19\nrow: 0-5 or 8-19\nseat: 0-13 or 16-19\n\nyour ticket:\n11,12,13\n\nnearby tickets:\n3,9,18\n15,1,5\n5,14,9\n", 15 | "expected": 12 16 | } 17 | ] 18 | } 19 | } -------------------------------------------------------------------------------- /challenges/2020/16-ticketTranslation/python/partOne.py: -------------------------------------------------------------------------------- 1 | from common import * 2 | 3 | 4 | def partOne(instr: str) -> int: 5 | rules, _, tickets = parse(instr) 6 | 7 | invalid_values, _ = find_invalid(rules, tickets) 8 | 9 | return sum(invalid_values) 10 | -------------------------------------------------------------------------------- /challenges/2020/17-conwayCubes/README.md: -------------------------------------------------------------------------------- 1 | # [Day 17: Conway Cubes](https://adventofcode.com/2020/day/17) 2 | 3 | I would not have got this if it wasn't for [this Reddit comment](https://www.reddit.com/r/adventofcode/comments/kf5mzc/2020_day_17_i_am_now_sad/gg6u25j). 4 | 5 |
Script output 6 | 7 | ``` 8 | ❯ python .\python\ 9 | AoC 2020: day 17 - Conway Cubes 10 | Python 3.8.5 11 | 12 | Test cases 13 | 1.1 pass 14 | 2.1 pass 15 | 16 | Answers 17 | Part 1: 232 18 | Part 2: 1620 19 | ``` 20 | 21 |
-------------------------------------------------------------------------------- /challenges/2020/17-conwayCubes/info.json: -------------------------------------------------------------------------------- 1 | { 2 | "year": "2020", 3 | "day": "17", 4 | "title": "Conway Cubes", 5 | "testCases": { 6 | "one": [ 7 | { 8 | "input": ".#.\n..#\n###\n", 9 | "expected": 112 10 | } 11 | ], 12 | "two": [ 13 | { 14 | "input": ".#.\n..#\n###\n", 15 | "expected": 848 16 | } 17 | ] 18 | } 19 | } -------------------------------------------------------------------------------- /challenges/2020/17-conwayCubes/python/common.py: -------------------------------------------------------------------------------- 1 | from typing import Dict, Tuple, Callable 2 | import itertools 3 | 4 | 5 | active_marker = "#" 6 | inactive_marker = "." 7 | 8 | 9 | translation_vectors_3d = [ 10 | p for p in itertools.product([-1, 0, 1], repeat=3) if p != (0, 0, 0) 11 | ] 12 | translation_vectors_4d = [ 13 | p for p in itertools.product([-1, 0, 1], repeat=4) if p != (0, 0, 0, 0) 14 | ] 15 | 16 | 17 | def parse( 18 | instr: str, key: Callable[[int, int], int] 19 | ) -> Dict[Tuple[int, int, int], str]: 20 | input_lists = [[x for x in y] for y in instr.strip().split("\n")] 21 | 22 | rtvl = {} 23 | 24 | for y, row in enumerate(input_lists): 25 | for x, col in enumerate(row): 26 | if col != inactive_marker: 27 | rtvl[key(x, y)] = col 28 | 29 | return rtvl 30 | -------------------------------------------------------------------------------- /challenges/2020/18-operationOrder/info.json: -------------------------------------------------------------------------------- 1 | { 2 | "year": "2020", 3 | "day": "18", 4 | "title": "Operation Order", 5 | "testCases": { 6 | "one": [ 7 | {"input":"1 + 2 * 3 + 4 * 5 + 6", "expected":71}, 8 | {"input":"1 + (2 * 3) + (4 * (5 + 6))", "expected":51}, 9 | {"input":"2 * 3 + (4 * 5)", "expected":26}, 10 | {"input":"5 + (8 * 3 + 9 + 3 * 4 * 3)", "expected":437}, 11 | {"input":"5 * 9 * (7 * 3 * 3 + 9 * 3 + (8 + 6 * 4))", "expected":12240}, 12 | {"input":"((2 + 4 * 9) * (6 + 9 * 8 + 6) + 6) + 2 + 4 * 2", "expected":13632} 13 | ], 14 | "two": [ 15 | {"input":"1 + 2 * 3 + 4 * 5 + 6", "expected":231}, 16 | {"input":"1 + (2 * 3) + (4 * (5 + 6))", "expected": 51}, 17 | {"input":"2 * 3 + (4 * 5)", "expected": 46}, 18 | {"input":"5 + (8 * 3 + 9 + 3 * 4 * 3)", "expected": 1445}, 19 | {"input":"5 * 9 * (7 * 3 * 3 + 9 * 3 + (8 + 6 * 4))", "expected": 669060}, 20 | {"input":"((2 + 4 * 9) * (6 + 9 * 8 + 6) + 6) + 2 + 4 * 2", "expected": 23340} 21 | ] 22 | } 23 | } -------------------------------------------------------------------------------- /challenges/2020/18-operationOrder/python/test.py: -------------------------------------------------------------------------------- 1 | # This file is a proof of concept for using the implementation in part one to complete part two 2 | # after added extra brackets to evert expression. 3 | 4 | import partOne 5 | 6 | instr = open("../input.txt").read() 7 | expressions = instr.strip().split("\n") 8 | 9 | expressions = [ 10 | partOne.parse_expression( 11 | list(("( " + x.replace("*", ") * (") + " )").replace(" ", "")) 12 | )[0] 13 | for x in instr.strip().split("\n") 14 | ] 15 | 16 | sigma = 0 17 | 18 | for expression in expressions: 19 | sigma += partOne.calculate(expression) 20 | 21 | print(sigma) 22 | -------------------------------------------------------------------------------- /challenges/2020/19-monsterMessages/go/challenge/partOne.go: -------------------------------------------------------------------------------- 1 | package challenge 2 | 3 | import "regexp" 4 | 5 | func PartOne(instr string) int { 6 | rules, messages := parse(instr) 7 | ruleRegex := regexp.MustCompile(makeRulesetRegex(rules)) 8 | return run(messages, ruleRegex) 9 | } 10 | -------------------------------------------------------------------------------- /challenges/2020/19-monsterMessages/go/challenge/partTwo.go: -------------------------------------------------------------------------------- 1 | package challenge 2 | 3 | import ( 4 | "regexp" 5 | "strings" 6 | ) 7 | 8 | func PartTwo(instr string) int { 9 | 10 | // patch input 11 | instr = strings.ReplaceAll(instr, "8: 42", "8: 42 | 42 8") 12 | instr = strings.ReplaceAll(instr, "11: 42 31", "11: 42 31 | 42 11 31") 13 | 14 | rules, messages := parse(instr) 15 | 16 | // Since we have sections of our ruleset, we have markers in the regex returned by `make_ruleset_regex` 17 | // that denote where we need to insert a copy of the rule 11 regular expression (which also happens to 18 | // have one of those markers in it) 19 | 20 | rr := makeRulesetRegex(rules) 21 | elevenRegex := generateRuleRegex(rules, 11) 22 | for i := 0; i < 10; i += 2 { 23 | rr = strings.ReplaceAll(rr, replaceMarker, elevenRegex) 24 | } 25 | 26 | // run as usual 27 | ruleRegex := regexp.MustCompile(rr) 28 | return run(messages, ruleRegex) 29 | } 30 | -------------------------------------------------------------------------------- /challenges/2020/19-monsterMessages/python/partOne.py: -------------------------------------------------------------------------------- 1 | from common import * 2 | import re 3 | 4 | 5 | def partOne(instr: str) -> int: 6 | rules, messages = parse(instr) 7 | rule_regex = re.compile(make_ruleset_regex(rules)) 8 | return run(messages, rule_regex) 9 | -------------------------------------------------------------------------------- /challenges/2020/19-monsterMessages/python/partTwo.py: -------------------------------------------------------------------------------- 1 | from common import * 2 | import re 3 | 4 | 5 | def partTwo(instr: str) -> int: 6 | 7 | # patch input 8 | instr = instr.replace( 9 | "8: 42", "8: 42 | 42 8" 10 | ) # the new rule 8 can be expressed as 42 | 42+ 11 | instr = instr.replace("11: 42 31", "11: 42 31 | 42 11 31") 12 | 13 | rules, messages = parse(instr) 14 | 15 | # Since we have sections of our ruleset, we have markers in the regex returned by `make_ruleset_regex` 16 | # that denote where we need to insert a copy of the rule 11 regular expression (which also happens to 17 | # have one of those markers in it) 18 | 19 | rr = make_ruleset_regex(rules) 20 | eleven_regex = generate_rule_regex(rules, 11) 21 | for _ in range(10): 22 | rr = rr.replace(replace_marker, eleven_regex) 23 | 24 | # run as usual 25 | rule_regex = re.compile(rr) 26 | return run(messages, rule_regex) 27 | -------------------------------------------------------------------------------- /challenges/2020/20-jurassicJigsaw/README.md: -------------------------------------------------------------------------------- 1 | # [Day 20: Jurassic Jigsaw](https://adventofcode.com/2020/day/20) 2 | 3 | ~~Gave up on this one. I was struggling to find a decent logical way to do it manually, yet alone write a set of rules to get a computer to do it.~~ 4 | 5 | ~~Okay, so I had a lightbulb moment and came back to take another look at part one, which I got pretty easily. I'm going to take another crack on part two, since tiles have certain properties that I didn't realise were present.~~ 6 | 7 | No. 8 | 9 |
Script output 10 | 11 | ``` 12 | ❯ python .\python\ 13 | AoC 2020: day 20 - Jurassic Jigsaw 14 | Python 3.8.5 15 | 16 | Test cases 17 | 1.1 pass 18 | 2.1 fail (got 0, expected 273) 19 | 20 | Answers 21 | Part 1: 83775126454273 22 | Part 2: 0 23 | ``` 24 | 25 |
-------------------------------------------------------------------------------- /challenges/2020/20-jurassicJigsaw/python/partOne.py: -------------------------------------------------------------------------------- 1 | from common import * 2 | from pprint import pprint 3 | 4 | 5 | def partOne(instr: str) -> int: 6 | tiles = parse(instr) 7 | 8 | _, shared_edge_count = get_edge_information(tiles) 9 | 10 | # find the product of all tile numbers that have 2 matching edges 11 | 12 | c = 1 13 | for x in shared_edge_count: 14 | if shared_edge_count[x] == 2: 15 | c *= x 16 | 17 | return c 18 | -------------------------------------------------------------------------------- /challenges/2020/20-jurassicJigsaw/python/partTwo.py: -------------------------------------------------------------------------------- 1 | from common import * 2 | 3 | 4 | def partTwo(instr: str) -> int: 5 | tiles_list = parse(instr) 6 | edges, shared_edge_count = get_edge_information(tiles_list) 7 | 8 | # from here onwards, it's going to make more sense to use a dictionary that has tile numbers to the tile object 9 | tiles = {} 10 | for tile in tiles_list: 11 | tiles[tile.number] = tile 12 | 13 | used_tiles = [] 14 | matrix = {} 15 | 16 | # get a single corner, set that as the start point 17 | for tile_id in shared_edge_count: 18 | if shared_edge_count[tile_id] == 2: 19 | matrix[(0, 0)] = tiles[tile_id].components 20 | 21 | print(matrix) 22 | 23 | return 0 24 | -------------------------------------------------------------------------------- /challenges/2020/21-allergenAmusement/README.md: -------------------------------------------------------------------------------- 1 | # [Day 21: Allergen Amusement](https://adventofcode.com/2020/day/21) 2 | 3 | This one isn't going to be translated to go because **a)** Go has no sets and **b)** Go is statically typed and I cannot be bothered to try and tweak the return type for part two. 4 | 5 | *I made the assumption we'd only ever have numeric solutions when I built the boilerplate, goddamnit!* 6 | 7 |
Script output 8 | 9 | ``` 10 | ❯ python .\python\ 11 | AoC 2020: day 21 - Allergen Amusement 12 | Python 3.8.5 13 | 14 | Test cases 15 | 1.1 pass 16 | 2.1 pass 17 | 18 | Answers 19 | Part 1: 2307 20 | Part 2: cljf,frtfg,vvfjj,qmrps,hvnkk,qnvx,cpxmpc,qsjszn 21 | ``` 22 | 23 |
-------------------------------------------------------------------------------- /challenges/2020/21-allergenAmusement/info.json: -------------------------------------------------------------------------------- 1 | { 2 | "year": "2020", 3 | "day": "21", 4 | "title": "Allergen Amusement", 5 | "testCases": { 6 | "one": [ 7 | { 8 | "input": "mxmxvkd kfcds sqjhc nhms (contains dairy, fish)\ntrh fvjkl sbzzf mxmxvkd (contains dairy)\nsqjhc fvjkl (contains soy)\nsqjhc mxmxvkd sbzzf (contains fish)\n", 9 | "expected": 5 10 | } 11 | ], 12 | "two": [ 13 | { 14 | "input": "mxmxvkd kfcds sqjhc nhms (contains dairy, fish)\ntrh fvjkl sbzzf mxmxvkd (contains dairy)\nsqjhc fvjkl (contains soy)\nsqjhc mxmxvkd sbzzf (contains fish)\n", 15 | "expected": "mxmxvkd,sqjhc,fvjkl" 16 | } 17 | ] 18 | } 19 | } -------------------------------------------------------------------------------- /challenges/2020/21-allergenAmusement/python/partOne.py: -------------------------------------------------------------------------------- 1 | from common import * 2 | 3 | 4 | def partOne(instr: str) -> int: 5 | foods, allergens = parse(instr) 6 | possibilities = get_possibilities(foods, allergens) 7 | 8 | bad_ingredients = set() 9 | for x in possibilities: 10 | bad_ingredients.update(possibilities[x]) 11 | 12 | count = 0 13 | for food in foods: 14 | for ingredient in food.ingredients: 15 | if ingredient not in bad_ingredients: 16 | count += 1 17 | 18 | return count 19 | -------------------------------------------------------------------------------- /challenges/2020/22-crabCombat/README.md: -------------------------------------------------------------------------------- 1 | # [Day 22: Crab Combat](https://adventofcode.com/2020/day/22) 2 | 3 |
Script output 4 | 5 | ``` 6 | ❯ python .\python\ ft 7 | AoC 2020: day 22 - Crab Combat 8 | Python 3.8.5 9 | 10 | Test cases 11 | 1.1 pass in 0.0 seconds 12 | 2.1 pass in 0.0 seconds 13 | 14 | Answers 15 | Part 1: 35397 in 0.0005002021789550781 seconds 16 | Part 2: 33889 in 2.854492425918579 seconds 17 | ``` 18 | 19 |
20 | -------------------------------------------------------------------------------- /challenges/2020/22-crabCombat/info.json: -------------------------------------------------------------------------------- 1 | { 2 | "year": "2020", 3 | "day": "22", 4 | "title": "Crab Combat", 5 | "testCases": { 6 | "one": [ 7 | { 8 | "input": "Player 1:\n9\n2\n6\n3\n1\n\nPlayer 2:\n5\n8\n4\n7\n10\n", 9 | "expected": 306 10 | } 11 | ], 12 | "two": [ 13 | { 14 | "input": "Player 1:\n9\n2\n6\n3\n1\n\nPlayer 2:\n5\n8\n4\n7\n10\n", 15 | "expected": 291 16 | } 17 | ] 18 | } 19 | } -------------------------------------------------------------------------------- /challenges/2020/22-crabCombat/python/common.py: -------------------------------------------------------------------------------- 1 | from typing import List, Tuple 2 | 3 | 4 | def parse(instr: str) -> Tuple[List[int], List[int]]: 5 | 6 | deck_one_str, deck_two_str = instr.strip().split("\n\n") 7 | 8 | deck_one = [int(x) for x in deck_one_str.split("\n")[1:]] 9 | deck_two = [int(x) for x in deck_two_str.split("\n")[1:]] 10 | 11 | return deck_one, deck_two 12 | 13 | 14 | def calc_score(deck: List[int]) -> int: 15 | score = 0 16 | 17 | deck_len = len(deck) 18 | for i, v in enumerate(deck): 19 | score += v * (deck_len - i) 20 | 21 | return score 22 | -------------------------------------------------------------------------------- /challenges/2020/22-crabCombat/python/partOne.py: -------------------------------------------------------------------------------- 1 | from common import * 2 | import time 3 | 4 | 5 | def play_round(deck_one: List[int], deck_two: List[int]) -> None: 6 | 7 | top_one = deck_one.pop(0) 8 | top_two = deck_two.pop(0) 9 | 10 | if top_one > top_two: 11 | deck_one.append(top_one) 12 | deck_one.append(top_two) 13 | elif top_two > top_one: 14 | deck_two.append(top_two) 15 | deck_two.append(top_one) 16 | 17 | 18 | def partOne(instr: str) -> int: 19 | deck_one, deck_two = parse(instr) 20 | 21 | while len(deck_one) > 0 and len(deck_two) > 0: 22 | play_round(deck_one, deck_two) 23 | 24 | return calc_score(deck_one if len(deck_one) != 0 else deck_two) 25 | -------------------------------------------------------------------------------- /challenges/2020/23-crabCups/README.md: -------------------------------------------------------------------------------- 1 | # [Day 23: Crab Cups](https://adventofcode.com/2020/day/23) 2 | 3 | The point at which I was unable to debug my solution because the sample solution didn't extend to 100 iterations was the point at which I gave up. 4 | 5 | This challenge seemed so simple, yet somehow managed to break me. Oh well. Fingers crossed the final two days are more doable. 6 | 7 | Here is a crab in place of anything actually useful written here. 8 | 9 | ![crab](crab.jpg) 10 | 11 |
Script output 12 | 13 | ``` 14 | There is none. 15 | ``` 16 | 17 |
18 | -------------------------------------------------------------------------------- /challenges/2020/23-crabCups/crab.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codemicro/adventOfCode/569c26b209f4f0a8879cac902fc926f0f9515703/challenges/2020/23-crabCups/crab.jpg -------------------------------------------------------------------------------- /challenges/2020/23-crabCups/info.json: -------------------------------------------------------------------------------- 1 | { 2 | "year": "2020", 3 | "day": "23", 4 | "title": "Crab Cups", 5 | "testCases": { 6 | "one": [ 7 | { 8 | "input": "389125467", 9 | "expected": 67384529 10 | } 11 | ], 12 | "two": [] 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /challenges/2020/23-crabCups/python/common.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | def parse(instr: str) -> List[int]: 5 | return [int(x) for x in instr.strip()] 6 | -------------------------------------------------------------------------------- /challenges/2020/23-crabCups/python/partTwo.py: -------------------------------------------------------------------------------- 1 | from common import * 2 | 3 | 4 | def partTwo(instr: str) -> int: 5 | input_list = parse(instr) 6 | return 0 7 | -------------------------------------------------------------------------------- /challenges/2020/24-lobbyLayout/python/partOne.py: -------------------------------------------------------------------------------- 1 | from common import * 2 | 3 | 4 | def partOne(instr: str) -> int: 5 | tiles_locations = parse(instr) 6 | tiles = make_initial_state(tiles_locations) 7 | return count_black_tiles(tiles) 8 | -------------------------------------------------------------------------------- /challenges/2020/25-comboBreaker/README.md: -------------------------------------------------------------------------------- 1 | # [Day 25: Combo Breaker](https://adventofcode.com/2020/day/25) 2 | 3 | Merry Christmas! 4 | 5 | That's Advent of Code done for this year. At the time of writing this, I've not gotten all 49 stars up to this point, so I've got no way to get the 50th star. Even so, I feel slightly cheated out of a part two haha. 6 | 7 | I might go back and try some of the other challenges from this year that I didn't complete. 8 | 9 |
Script output 10 | 11 | ``` 12 | ❯ python python ft 13 | AoC 2020: day 25 - Combo Breaker 14 | Python 3.8.5 15 | 16 | Test cases 17 | 1.1 pass in 0.0 seconds 18 | 19 | Answers 20 | Part 1: 297257 in 7.089499235153198 seconds 21 | Part 2: 0 in 0.0 seconds 22 | 23 | ❯ go run .\go\ ft 24 | AoC 2020: day 25 - Combo Breaker 25 | Go go1.15.2 26 | 27 | Test cases 28 | 1.1 pass in 0.00000000 seconds 29 | 30 | Answers 31 | Part 1: 297257 in 0.13749980 seconds 32 | Part 2: 0 in 0.00000000 seconds 33 | ``` 34 | 35 |
36 | -------------------------------------------------------------------------------- /challenges/2020/25-comboBreaker/go/challenge/common.go: -------------------------------------------------------------------------------- 1 | package challenge 2 | 3 | import ( 4 | "strconv" 5 | "strings" 6 | ) 7 | 8 | func parse(instr string) []int { 9 | var o []int 10 | for _, x := range strings.Split(strings.TrimSpace(instr), "\n") { 11 | i, err := strconv.Atoi(x) 12 | if err != nil { 13 | panic(err) 14 | } 15 | o = append(o, i) 16 | } 17 | return o 18 | } 19 | -------------------------------------------------------------------------------- /challenges/2020/25-comboBreaker/go/challenge/partOne.go: -------------------------------------------------------------------------------- 1 | package challenge 2 | 3 | import "errors" 4 | 5 | func singleTransformation(v, subjectNumber int) int { 6 | return (v * subjectNumber) % 20201227 7 | } 8 | 9 | func transform(loopSize, subjectNumber int) int { 10 | v := 1 11 | for i := 0; i < loopSize; i += 1 { 12 | v = singleTransformation(v, subjectNumber) 13 | } 14 | return v 15 | } 16 | 17 | func findLoopSize(targetPubkey int) int { 18 | var c int 19 | v := 1 20 | for { 21 | c += 1 22 | v = singleTransformation(v, 7) 23 | if v == targetPubkey { 24 | return c 25 | } 26 | } 27 | } 28 | 29 | func PartOne(instr string) int { 30 | inputSlice := parse(instr) 31 | 32 | pubkeyOne := inputSlice[0] 33 | pubkeyTwo := inputSlice[1] 34 | 35 | loopSizeOne := findLoopSize(pubkeyOne) 36 | loopSizeTwo := findLoopSize(pubkeyTwo) 37 | 38 | encryptionKey := transform(loopSizeTwo, pubkeyOne) 39 | if encryptionKey != transform(loopSizeOne, pubkeyTwo) { 40 | panic(errors.New("encryption keys do not match")) 41 | } 42 | 43 | return encryptionKey 44 | } 45 | -------------------------------------------------------------------------------- /challenges/2020/25-comboBreaker/go/challenge/partTwo.go: -------------------------------------------------------------------------------- 1 | package challenge 2 | 3 | func PartTwo(instr string) int { 4 | return 0 5 | } 6 | -------------------------------------------------------------------------------- /challenges/2020/25-comboBreaker/info.json: -------------------------------------------------------------------------------- 1 | { 2 | "year": "2020", 3 | "day": "25", 4 | "title": "Combo Breaker", 5 | "testCases": { 6 | "one": [ 7 | { 8 | "input": "5764801\n17807724", 9 | "expected": 14897079 10 | } 11 | ], 12 | "two": [] 13 | } 14 | } -------------------------------------------------------------------------------- /challenges/2020/25-comboBreaker/python/common.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | def parse(instr: str) -> List[int]: 5 | return [int(x) for x in instr.strip().split("\n")] 6 | -------------------------------------------------------------------------------- /challenges/2020/25-comboBreaker/python/partOne.py: -------------------------------------------------------------------------------- 1 | from common import * 2 | 3 | 4 | def single_transformation(v:int, subject_number:int=7) -> int: 5 | return (v * subject_number) % 20201227 6 | 7 | 8 | def transform(loop_size:int, subject_number:int=7) -> int: 9 | v = 1 10 | for _ in range(loop_size): 11 | v = single_transformation(v, subject_number=subject_number) 12 | return v 13 | 14 | 15 | def find_loop_size(target_pubkey:int) -> int: 16 | c = 0 17 | v = 1 18 | while True: 19 | c += 1 20 | v = single_transformation(v) 21 | if v == target_pubkey: 22 | return c 23 | 24 | 25 | def partOne(instr: str) -> int: 26 | pubkey_one, pubkey_two = parse(instr) 27 | 28 | loop_size_one = find_loop_size(pubkey_one) 29 | loop_size_two = find_loop_size(pubkey_two) 30 | 31 | encryption_key = transform(loop_size_two, subject_number=pubkey_one) 32 | assert encryption_key == transform(loop_size_one, subject_number=pubkey_two), "encryption keys do not match" 33 | 34 | return encryption_key 35 | -------------------------------------------------------------------------------- /challenges/2020/25-comboBreaker/python/partTwo.py: -------------------------------------------------------------------------------- 1 | def partTwo(instr: str) -> int: 2 | return 0 3 | -------------------------------------------------------------------------------- /challenges/2020/clocgraph.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codemicro/adventOfCode/569c26b209f4f0a8879cac902fc926f0f9515703/challenges/2020/clocgraph.png -------------------------------------------------------------------------------- /challenges/2021/01-sonarSweep/README.md: -------------------------------------------------------------------------------- 1 | # [Day 1: Sonar Sweep](https://adventofcode.com/2021/day/1) 2 | 3 | ``` 4 | ➜ adventOfCode git:(master) go run github.com/codemicro/adventOfCode/runtime -y 2021 5 | Selecting year 2021 6 | Automatically selecting day 1 (Sonar Sweep) 7 | ? Which implementation do you want to use? Python 8 | 9 | Running... 10 | 11 | Test 1.0: pass in 0.0000 seconds 12 | Test 2.0: pass in 0.0000 seconds 13 | Part 1: in 0.0005 seconds 14 | Part 2: in 0.0008 seconds 15 | ``` -------------------------------------------------------------------------------- /challenges/2021/01-sonarSweep/benchmark.json: -------------------------------------------------------------------------------- 1 | { 2 | "day": 1, 3 | "dir": "challenges/2021/01-sonarSweep", 4 | "implementations": { 5 | "Golang": { 6 | "part.1.avg": 0.0002590258829999999, 7 | "part.1.max": 0.01844078, 8 | "part.1.min": 0.000056368, 9 | "part.2.avg": 0.00041728208699999965, 10 | "part.2.max": 0.025912989, 11 | "part.2.min": 0.000067722 12 | }, 13 | "Nim": { 14 | "part.1.avg": 0.001190464674, 15 | "part.1.max": 0.012474971, 16 | "part.1.min": 0.000310218, 17 | "part.2.avg": 0.0012603544370000013, 18 | "part.2.max": 0.019855291, 19 | "part.2.min": 0.000310509 20 | }, 21 | "Python": { 22 | "part.1.avg": 0.0013292949199676513, 23 | "part.1.max": 0.0059168338775634766, 24 | "part.1.min": 0.0004954338073730469, 25 | "part.2.avg": 0.0022176058292388916, 26 | "part.2.max": 0.016942262649536133, 27 | "part.2.min": 0.0008616447448730469 28 | } 29 | }, 30 | "numRuns": 1000 31 | } -------------------------------------------------------------------------------- /challenges/2021/01-sonarSweep/info.json: -------------------------------------------------------------------------------- 1 | { 2 | "inputFile": "input.txt", 3 | "testCases": { 4 | "one": [ 5 | { 6 | "input": "199\n200\n208\n210\n200\n207\n240\n269\n260\n263", 7 | "expected": "7" 8 | } 9 | ], 10 | "two": [ 11 | { 12 | "input": "199\n200\n208\n210\n200\n207\n240\n269\n260\n263", 13 | "expected": "5" 14 | } 15 | ] 16 | } 17 | } -------------------------------------------------------------------------------- /challenges/2021/01-sonarSweep/nim/challenge.nim: -------------------------------------------------------------------------------- 1 | import std/strutils 2 | import std/sequtils 3 | 4 | proc parseInput(instr: string): seq[int] = 5 | result = instr. 6 | splitLines. 7 | toSeq. 8 | filter(proc(x: string): bool = x != ""). 9 | map(parseInt) 10 | 11 | proc countIncreases(data: seq[int]): int = 12 | for i in 1..data.high: 13 | if data[i] > data[i-1]: 14 | result = result + 1 15 | 16 | proc partOne*(instr: string): int = 17 | let input = parseInput(instr) 18 | return countIncreases(input) 19 | 20 | proc partTwo*(instr: string): int = 21 | let input = parseInput(instr) 22 | var sums: seq[int] 23 | for i in countup(0, len(input)-3): 24 | sums.add(input[i] + input[i+1] + input[i+2]) 25 | # sums.add( 26 | # (@input[i..i+2]).foldl(a+b), 27 | # ) 28 | return countIncreases(sums) 29 | -------------------------------------------------------------------------------- /challenges/2021/01-sonarSweep/py/__init__.py: -------------------------------------------------------------------------------- 1 | from typing import List, Any 2 | from aocpy import BaseChallenge 3 | 4 | 5 | def parse(instr: str) -> List[int]: 6 | return [int(x) for x in instr.splitlines() if x != ""] 7 | 8 | 9 | def count_increases(data: List[int]) -> int: 10 | c = 0 11 | for i in range(1, len(data)): 12 | if data[i] > data[i - 1]: 13 | c += 1 14 | return c 15 | 16 | 17 | class Challenge(BaseChallenge): 18 | @staticmethod 19 | def one(instr: str) -> int: 20 | data = parse(instr) 21 | return count_increases(data) 22 | 23 | @staticmethod 24 | def two(instr: str) -> int: 25 | data = parse(instr) 26 | sums = [sum(data[i : i + 3]) for i in range(len(data) - 2)] 27 | return count_increases(sums) 28 | -------------------------------------------------------------------------------- /challenges/2021/02-dive/README.md: -------------------------------------------------------------------------------- 1 | # [Day 2: Dive!](https://adventofcode.com/2021/day/2) 2 | 3 | -------------------------------------------------------------------------------- /challenges/2021/02-dive/benchmark.json: -------------------------------------------------------------------------------- 1 | { 2 | "day": 2, 3 | "dir": "challenges/2021/02-dive", 4 | "implementations": { 5 | "Golang": { 6 | "part.1.avg": 0.00043523502199999955, 7 | "part.1.max": 0.008638925, 8 | "part.1.min": 0.000157245, 9 | "part.2.avg": 0.0004556505770000001, 10 | "part.2.max": 0.014578633, 11 | "part.2.min": 0.000159105 12 | }, 13 | "Python": { 14 | "part.1.avg": 0.002370833396911621, 15 | "part.1.max": 0.024700403213500977, 16 | "part.1.min": 0.0007102489471435547, 17 | "part.2.avg": 0.002402855157852173, 18 | "part.2.max": 0.019526958465576172, 19 | "part.2.min": 0.0007097721099853516 20 | } 21 | }, 22 | "numRuns": 1000 23 | } -------------------------------------------------------------------------------- /challenges/2021/02-dive/info.json: -------------------------------------------------------------------------------- 1 | { 2 | "inputFile": "input.txt", 3 | "testCases": { 4 | "one": [ 5 | { 6 | "input": "forward 5\ndown 5\nforward 8\nup 3\ndown 8\nforward 2\n", 7 | "expected": "150" 8 | } 9 | ], 10 | "two": [ 11 | { 12 | "input": "forward 5\ndown 5\nforward 8\nup 3\ndown 8\nforward 2\n", 13 | "expected": "900" 14 | } 15 | ] 16 | } 17 | } -------------------------------------------------------------------------------- /challenges/2021/03-binaryDiagnostic/README.md: -------------------------------------------------------------------------------- 1 | # [Day 3: Binary Diagnostic](https://adventofcode.com/2021/day/3) 2 | 3 | The Nim code is a direct translation of the Python code - see the Python code for descriptive comments. -------------------------------------------------------------------------------- /challenges/2021/03-binaryDiagnostic/benchmark.json: -------------------------------------------------------------------------------- 1 | { 2 | "day": 3, 3 | "dir": "challenges/2021/03-binaryDiagnostic", 4 | "implementations": { 5 | "Nim": { 6 | "part.1.avg": 0.0005255849699999996, 7 | "part.1.max": 0.003743778, 8 | "part.1.min": 0.000228979, 9 | "part.2.avg": 0.0005072320390000003, 10 | "part.2.max": 0.002042921, 11 | "part.2.min": 0.000207734 12 | }, 13 | "Python": { 14 | "part.1.avg": 0.004413741111755371, 15 | "part.1.max": 0.012727022171020508, 16 | "part.1.min": 0.0021619796752929688, 17 | "part.2.avg": 0.0034146361351013186, 18 | "part.2.max": 0.0129547119140625, 19 | "part.2.min": 0.0016372203826904297 20 | } 21 | }, 22 | "numRuns": 1000 23 | } -------------------------------------------------------------------------------- /challenges/2021/03-binaryDiagnostic/info.json: -------------------------------------------------------------------------------- 1 | { 2 | "inputFile": "input.txt", 3 | "testCases": { 4 | "one": [ 5 | { 6 | "input": "00100\n11110\n10110\n10111\n10101\n01111\n00111\n11100\n10000\n11001\n00010\n01010\n", 7 | "expected": "198" 8 | } 9 | ], 10 | "two": [ 11 | { 12 | "input": "00100\n11110\n10110\n10111\n10101\n01111\n00111\n11100\n10000\n11001\n00010\n01010\n", 13 | "expected": "230" 14 | } 15 | ] 16 | } 17 | } -------------------------------------------------------------------------------- /challenges/2021/04-giantSquid/README.md: -------------------------------------------------------------------------------- 1 | # [Day 4: Giant Squid](https://adventofcode.com/2021/day/4) 2 | 3 | -------------------------------------------------------------------------------- /challenges/2021/04-giantSquid/benchmark.json: -------------------------------------------------------------------------------- 1 | { 2 | "day": 4, 3 | "dir": "challenges/2021/04-giantSquid", 4 | "implementations": { 5 | "Python": { 6 | "part.1.avg": 0.017204525232315065, 7 | "part.1.max": 0.09171009063720703, 8 | "part.1.min": 0.0072062015533447266, 9 | "part.2.avg": 0.0352356481552124, 10 | "part.2.max": 0.13428831100463867, 11 | "part.2.min": 0.015462875366210938 12 | } 13 | }, 14 | "numRuns": 1000 15 | } -------------------------------------------------------------------------------- /challenges/2021/04-giantSquid/info.json: -------------------------------------------------------------------------------- 1 | { 2 | "inputFile": "input.txt", 3 | "testCases": { 4 | "one": [ 5 | { 6 | "input": "7,4,9,5,11,17,23,2,0,14,21,24,10,16,13,6,15,25,12,22,18,20,8,19,3,26,1\n\n22 13 17 11 0\n 8 2 23 4 24\n21 9 14 16 7\n 6 10 3 18 5\n 1 12 20 15 19\n\n 3 15 0 2 22\n 9 18 13 17 5\n19 8 7 25 23\n20 11 10 24 4\n14 21 16 12 6\n\n14 21 17 24 4\n10 16 15 9 19\n18 8 23 26 20\n22 11 13 6 5\n 2 0 12 3 7", 7 | "expected": "4512" 8 | } 9 | ], 10 | "two": [ 11 | { 12 | "input": "7,4,9,5,11,17,23,2,0,14,21,24,10,16,13,6,15,25,12,22,18,20,8,19,3,26,1\n\n22 13 17 11 0\n 8 2 23 4 24\n21 9 14 16 7\n 6 10 3 18 5\n 1 12 20 15 19\n\n 3 15 0 2 22\n 9 18 13 17 5\n19 8 7 25 23\n20 11 10 24 4\n14 21 16 12 6\n\n14 21 17 24 4\n10 16 15 9 19\n18 8 23 26 20\n22 11 13 6 5\n 2 0 12 3 7", 13 | "expected": "1924" 14 | } 15 | ] 16 | } 17 | } -------------------------------------------------------------------------------- /challenges/2021/05-hydrothermalVenture/README.md: -------------------------------------------------------------------------------- 1 | # [Day 5: Hydrothermal Venture](https://adventofcode.com/2021/day/5) 2 | 3 | ### Part one 4 | 5 | * Parse input and output a list of pairs of points. 6 | * Remove diagonal lines by filtering the list using the condition that `p1.x == p2.x or p1.y == p2.y` 7 | * Count overlapping points 8 | * Create a dictionary that uses the point coordinate as a key and contains an integer `n` for each key 9 | * Iterate over each line in the input, adding 1 to `n` for each coordinate in the line 10 | * The coordinates were founid by computing the x and y deltas between the two points that made up the line 11 | * The sign of the deltas determines the direction we step in 12 | * We then step through each point in the line based on the step directions until the final point is encountered 13 | * Iterate over all keys in the dictionary and count every point where `n > 1` 14 | 15 | ### Part two 16 | 17 | The same as part one, but without the list filtering step. 18 | 19 | --- 20 | 21 | Involved literal napkin maths. 22 | 23 | ![napkin math](napkinmath.jpg) 24 | -------------------------------------------------------------------------------- /challenges/2021/05-hydrothermalVenture/benchmark.json: -------------------------------------------------------------------------------- 1 | { 2 | "day": 5, 3 | "dir": "challenges/2021/05-hydrothermalVenture", 4 | "implementations": { 5 | "Golang": { 6 | "part.1.avg": 0.053760980892, 7 | "part.1.max": 0.144833474, 8 | "part.1.min": 0.038262183, 9 | "part.2.avg": 0.08442973864, 10 | "part.2.max": 0.192854485, 11 | "part.2.min": 0.061950775 12 | }, 13 | "Nim": { 14 | "part.1.avg": 0.014279042672000008, 15 | "part.1.max": 0.078472313, 16 | "part.1.min": 0.01031939, 17 | "part.2.avg": 0.021206030867999978, 18 | "part.2.max": 0.097470179, 19 | "part.2.min": 0.014612315 20 | }, 21 | "Python": { 22 | "part.1.avg": 0.26107834911346434, 23 | "part.1.max": 0.8465554714202881, 24 | "part.1.min": 0.15942978858947754, 25 | "part.2.avg": 0.43654474210739136, 26 | "part.2.max": 1.4235708713531494, 27 | "part.2.min": 0.26850223541259766 28 | } 29 | }, 30 | "numRuns": 500 31 | } -------------------------------------------------------------------------------- /challenges/2021/05-hydrothermalVenture/info.json: -------------------------------------------------------------------------------- 1 | { 2 | "inputFile": "input.txt", 3 | "testCases": { 4 | "one": [ 5 | { 6 | "input": "0,9 -> 5,9\n8,0 -> 0,8\n9,4 -> 3,4\n2,2 -> 2,1\n7,0 -> 7,4\n6,4 -> 2,0\n0,9 -> 2,9\n3,4 -> 1,4\n0,0 -> 8,8\n5,5 -> 8,2\n", 7 | "expected": "5" 8 | } 9 | ], 10 | "two": [ 11 | { 12 | "input": "0,9 -> 5,9\n8,0 -> 0,8\n9,4 -> 3,4\n2,2 -> 2,1\n7,0 -> 7,4\n6,4 -> 2,0\n0,9 -> 2,9\n3,4 -> 1,4\n0,0 -> 8,8\n5,5 -> 8,2\n", 13 | "expected": "12" 14 | } 15 | ] 16 | } 17 | } -------------------------------------------------------------------------------- /challenges/2021/05-hydrothermalVenture/napkinmath.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codemicro/adventOfCode/569c26b209f4f0a8879cac902fc926f0f9515703/challenges/2021/05-hydrothermalVenture/napkinmath.jpg -------------------------------------------------------------------------------- /challenges/2021/06-lanternfish/benchmark.json: -------------------------------------------------------------------------------- 1 | { 2 | "day": 6, 3 | "dir": "challenges/2021/06-lanternfish", 4 | "implementations": { 5 | "Python": { 6 | "part.1.avg": 0.00020124888420104982, 7 | "part.1.max": 0.0004673004150390625, 8 | "part.1.min": 0.0001266002655029297, 9 | "part.2.avg": 0.0004714465141296387, 10 | "part.2.max": 0.0010838508605957031, 11 | "part.2.min": 0.00030684471130371094 12 | } 13 | }, 14 | "numRuns": 1000 15 | } -------------------------------------------------------------------------------- /challenges/2021/06-lanternfish/info.json: -------------------------------------------------------------------------------- 1 | { 2 | "inputFile": "input.txt", 3 | "testCases": { 4 | "one": [ 5 | { 6 | "input": "3,4,3,1,2", 7 | "expected": "5934" 8 | } 9 | ], 10 | "two": [ 11 | { 12 | "input": "3,4,3,1,2", 13 | "expected": "26984457539" 14 | } 15 | ] 16 | } 17 | } -------------------------------------------------------------------------------- /challenges/2021/06-lanternfish/whiteboard.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codemicro/adventOfCode/569c26b209f4f0a8879cac902fc926f0f9515703/challenges/2021/06-lanternfish/whiteboard.jpg -------------------------------------------------------------------------------- /challenges/2021/07-theTreacheryOfWhales/README.md: -------------------------------------------------------------------------------- 1 | # [Day 7: The Treachery of Whales](https://adventofcode.com/2021/day/7) 2 | 3 | -------------------------------------------------------------------------------- /challenges/2021/07-theTreacheryOfWhales/benchmark.json: -------------------------------------------------------------------------------- 1 | { 2 | "day": 7, 3 | "dir": "challenges/2021/07-theTreacheryOfWhales", 4 | "implementations": { 5 | "Python": { 6 | "part.1.avg": 0.0003524906635284424, 7 | "part.1.max": 0.0011348724365234375, 8 | "part.1.min": 0.00024008750915527344, 9 | "part.2.avg": 0.033716694355010984, 10 | "part.2.max": 0.08556342124938965, 11 | "part.2.min": 0.025210857391357422 12 | } 13 | }, 14 | "numRuns": 1000 15 | } -------------------------------------------------------------------------------- /challenges/2021/07-theTreacheryOfWhales/info.json: -------------------------------------------------------------------------------- 1 | { 2 | "inputFile": "input.txt", 3 | "testCases": { 4 | "one": [ 5 | { 6 | "input": "16,1,2,0,4,2,7,1,2,14", 7 | "expected": "37" 8 | } 9 | ], 10 | "two": [ 11 | { 12 | "input": "16,1,2,0,4,2,7,1,2,14", 13 | "expected": "168" 14 | } 15 | ] 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /challenges/2021/08-sevenSegmentSearch/README.md: -------------------------------------------------------------------------------- 1 | # [Day 8: Sevent Segment Search](https://adventofcode.com/2021/day/8) 2 | 3 | -------------------------------------------------------------------------------- /challenges/2021/08-sevenSegmentSearch/benchmark.json: -------------------------------------------------------------------------------- 1 | { 2 | "day": 8, 3 | "dir": "challenges/2021/08-seventSegmentSearch", 4 | "implementations": { 5 | "Golang": { 6 | "part.1.avg": 0.0011630151239999996, 7 | "part.1.max": 0.002068547, 8 | "part.1.min": 0.000927415, 9 | "part.2.avg": 0.326909703884, 10 | "part.2.max": 0.398817152, 11 | "part.2.min": 0.296369163 12 | }, 13 | "Python": { 14 | "part.1.avg": 0.0018209447860717772, 15 | "part.1.max": 0.0030808448791503906, 16 | "part.1.min": 0.0014312267303466797, 17 | "part.2.avg": 0.7365821332931518, 18 | "part.2.max": 0.8698751926422119, 19 | "part.2.min": 0.6725485324859619 20 | } 21 | }, 22 | "numRuns": 250 23 | } -------------------------------------------------------------------------------- /challenges/2021/09-smokeBasin/README.md: -------------------------------------------------------------------------------- 1 | # [Day 9: Smoke Basin](https://adventofcode.com/2021/day/9) 2 | 3 | The key to solving part two is knowing that you don't need to itelligently think about the depths of the basins. 4 | 5 | Because we know that 6 | 7 | > Locations of height `9` do not count as being in any basin, and all other locations will always be part of exactly one basin 8 | 9 | we can determine that a given basin is bounded by `9`s or the edge of the board. For example, the sample input looks like this if you remove all digits apart from `9`. 10 | 11 | ``` 12 | --999----- 13 | -9---9-9-- 14 | 9-----9-9- 15 | -----9---9 16 | 9-999----- 17 | ``` 18 | 19 | We can find every lowest point, and work outwards from that point to find the entire basin. 20 | 21 | --- 22 | 23 | [Part two visualisation](partTwo.mp4) 24 | 25 | To run the visualisation, use the following command: 26 | 27 | ``` 28 | PYTHONPATH=/lib python3 -B -c "import py;inp=open('input.txt').read();py.Challenge.vis(inp,'visdir')" 29 | ``` -------------------------------------------------------------------------------- /challenges/2021/09-smokeBasin/benchmark.json: -------------------------------------------------------------------------------- 1 | { 2 | "day": 9, 3 | "dir": "challenges/2021/09-smokeBasin", 4 | "implementations": { 5 | "Python": { 6 | "part.1.avg": 0.04718727922439575, 7 | "part.1.max": 0.19989562034606934, 8 | "part.1.min": 0.01859116554260254, 9 | "part.2.avg": 0.10986182379722595, 10 | "part.2.max": 0.3891136646270752, 11 | "part.2.min": 0.041121721267700195 12 | } 13 | }, 14 | "numRuns": 1000 15 | } -------------------------------------------------------------------------------- /challenges/2021/09-smokeBasin/info.json: -------------------------------------------------------------------------------- 1 | { 2 | "inputFile": "input.txt", 3 | "testCases": { 4 | "one": [ 5 | { 6 | "input": "2199943210\n3987894921\n9856789892\n8767896789\n9899965678\n", 7 | "expected": "15" 8 | } 9 | ], 10 | "two": [ 11 | { 12 | "input": "2199943210\n3987894921\n9856789892\n8767896789\n9899965678\n", 13 | "expected": "1134" 14 | } 15 | ] 16 | } 17 | } -------------------------------------------------------------------------------- /challenges/2021/09-smokeBasin/partTwo.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codemicro/adventOfCode/569c26b209f4f0a8879cac902fc926f0f9515703/challenges/2021/09-smokeBasin/partTwo.mp4 -------------------------------------------------------------------------------- /challenges/2021/10-syntaxScoring/README.md: -------------------------------------------------------------------------------- 1 | # [Day 10: Syntax Scoring](https://adventofcode.com/2021/day/10) 2 | 3 | -------------------------------------------------------------------------------- /challenges/2021/10-syntaxScoring/benchmark.json: -------------------------------------------------------------------------------- 1 | { 2 | "day": 10, 3 | "dir": "challenges/2021/10-syntaxScoring", 4 | "implementations": { 5 | "Python": { 6 | "part.1.avg": 0.001248321533203125, 7 | "part.1.max": 0.004151821136474609, 8 | "part.1.min": 0.0008554458618164062, 9 | "part.2.avg": 0.0030763609409332274, 10 | "part.2.max": 0.028047800064086914, 11 | "part.2.min": 0.002079486846923828 12 | } 13 | }, 14 | "numRuns": 1000 15 | } -------------------------------------------------------------------------------- /challenges/2021/10-syntaxScoring/info.json: -------------------------------------------------------------------------------- 1 | { 2 | "inputFile": "input.txt", 3 | "testCases": { 4 | "one": [ 5 | { 6 | "input": "[({(<(())[]>[[{[]{<()<>>\n[(()[<>])]({[<{<<[]>>(\n{([(<{}[<>[]}>{[]{[(<()>\n(((({<>}<{<{<>}{[]{[]{}\n[[<[([]))<([[{}[[()]]]\n[{[{({}]{}}([{[{{{}}([]\n{<[[]]>}<{[{[{[]{()[[[]\n[<(<(<(<{}))><([]([]()\n<{([([[(<>()){}]>(<<{{\n<{([{{}}[<[[[<>{}]]]>[]]\n", 7 | "expected": "26397" 8 | } 9 | ], 10 | "two": [ 11 | { 12 | "input": "[({(<(())[]>[[{[]{<()<>>\n[(()[<>])]({[<{<<[]>>(\n{([(<{}[<>[]}>{[]{[(<()>\n(((({<>}<{<{<>}{[]{[]{}\n[[<[([]))<([[{}[[()]]]\n[{[{({}]{}}([{[{{{}}([]\n{<[[]]>}<{[{[{[]{()[[[]\n[<(<(<(<{}))><([]([]()\n<{([([[(<>()){}]>(<<{{\n<{([{{}}[<[[[<>{}]]]>[]]\n", 13 | "expected": "288957" 14 | } 15 | ] 16 | } 17 | } -------------------------------------------------------------------------------- /challenges/2021/11-dumboOctopus/README.md: -------------------------------------------------------------------------------- 1 | # [Day 11: Dumbo Octopus](https://adventofcode.com/2021/day/11) 2 | 3 | -------------------------------------------------------------------------------- /challenges/2021/11-dumboOctopus/benchmark.json: -------------------------------------------------------------------------------- 1 | { 2 | "day": 11, 3 | "dir": "challenges/2021/11-dumboOctopus", 4 | "implementations": { 5 | "Nim": { 6 | "part.1.avg": 0.002156735096000002, 7 | "part.1.max": 0.006734169, 8 | "part.1.min": 0.001474201, 9 | "part.2.avg": 0.008079303889999999, 10 | "part.2.max": 0.038707332, 11 | "part.2.min": 0.005537803 12 | }, 13 | "Python": { 14 | "part.1.avg": 0.008022420167922973, 15 | "part.1.max": 0.022809743881225586, 16 | "part.1.min": 0.005808591842651367, 17 | "part.2.avg": 0.031094204664230348, 18 | "part.2.max": 0.08413910865783691, 19 | "part.2.min": 0.023587465286254883 20 | } 21 | }, 22 | "numRuns": 1000 23 | } -------------------------------------------------------------------------------- /challenges/2021/11-dumboOctopus/info.json: -------------------------------------------------------------------------------- 1 | { 2 | "inputFile": "input.txt", 3 | "testCases": { 4 | "one": [ 5 | { 6 | "input": "11111\n19991\n19191\n19991\n11111\n", 7 | "expected": "259" 8 | }, 9 | { 10 | "input": "5483143223\n2745854711\n5264556173\n6141336146\n6357385478\n4167524645\n2176841721\n6882881134\n4846848554\n5283751526\n", 11 | "expected": "1656" 12 | } 13 | ], 14 | "two": [ 15 | { 16 | "input": "5483143223\n2745854711\n5264556173\n6141336146\n6357385478\n4167524645\n2176841721\n6882881134\n4846848554\n5283751526\n", 17 | "expected": "195" 18 | } 19 | ] 20 | } 21 | } -------------------------------------------------------------------------------- /challenges/2021/12-passagePathing/README.md: -------------------------------------------------------------------------------- 1 | # [Day 12: Passage Pathing](https://adventofcode.com/2021/day/12) 2 | 3 | -------------------------------------------------------------------------------- /challenges/2021/12-passagePathing/benchmark.json: -------------------------------------------------------------------------------- 1 | { 2 | "day": 12, 3 | "dir": "challenges/2021/12-passagePathing", 4 | "implementations": { 5 | "Golang": { 6 | "part.1.avg": 0.004089135783000003, 7 | "part.1.max": 0.015094977, 8 | "part.1.min": 0.002771765, 9 | "part.2.avg": 0.090934005394, 10 | "part.2.max": 0.250616487, 11 | "part.2.min": 0.065061159 12 | } 13 | }, 14 | "numRuns": 1000 15 | } -------------------------------------------------------------------------------- /challenges/2021/12-passagePathing/graph.py: -------------------------------------------------------------------------------- 1 | import networkx as nx 2 | import matplotlib.pyplot as plt 3 | 4 | edges = [] 5 | nodes = [] 6 | with open("input.txt") as f: 7 | for line in f.read().strip().splitlines(): 8 | f, t = line.split("-") 9 | edges.append((f,t)) 10 | for x in [f, t]: 11 | if x not in nodes: 12 | nodes.append(x) 13 | 14 | graph = nx.Graph() 15 | graph.add_edges_from(edges) 16 | pos = nx.kamada_kawai_layout(graph) 17 | nx.draw_networkx_nodes(graph, pos, nodelist=nodes) 18 | nx.draw_networkx_labels(graph, pos) 19 | nx.draw_networkx_edges(graph, pos, edgelist=graph.edges()) 20 | plt.show() -------------------------------------------------------------------------------- /challenges/2021/13-transparentOrigami/README.md: -------------------------------------------------------------------------------- 1 | # [Day 13: Transparent Origami](https://adventofcode.com/2021/day/13) 2 | 3 | -------------------------------------------------------------------------------- /challenges/2021/13-transparentOrigami/benchmark.json: -------------------------------------------------------------------------------- 1 | { 2 | "day": 13, 3 | "dir": "challenges/2021/13-transparentOrigami", 4 | "implementations": { 5 | "Nim": { 6 | "part.1.avg": 0.0015621956039999975, 7 | "part.1.max": 0.003880651, 8 | "part.1.min": 0.00031427, 9 | "part.2.avg": 0.002502785954, 10 | "part.2.max": 0.005894322, 11 | "part.2.min": 0.000524984 12 | }, 13 | "Python": { 14 | "part.1.avg": 0.0020371160507202148, 15 | "part.1.max": 0.007749795913696289, 16 | "part.1.min": 0.0005323886871337891, 17 | "part.2.avg": 0.005764168262481689, 18 | "part.2.max": 0.01631307601928711, 19 | "part.2.min": 0.0014383792877197266 20 | } 21 | }, 22 | "numRuns": 1000 23 | } -------------------------------------------------------------------------------- /challenges/2021/13-transparentOrigami/info.json: -------------------------------------------------------------------------------- 1 | { 2 | "inputFile": "input.txt", 3 | "testCases": { 4 | "one": [ 5 | { 6 | "input": "6,10\n0,14\n9,10\n0,3\n10,4\n4,11\n6,0\n6,12\n4,1\n0,13\n10,12\n3,4\n3,0\n8,4\n1,10\n2,14\n8,10\n9,0\n\nfold along y=7\nfold along x=5", 7 | "expected": "17" 8 | } 9 | ], 10 | "two": [] 11 | } 12 | } -------------------------------------------------------------------------------- /challenges/2021/14-extendedPolymerization/README.md: -------------------------------------------------------------------------------- 1 | # [Day 14: Extended Polymerization](https://adventofcode.com/2021/day/14) 2 | 3 | -------------------------------------------------------------------------------- /challenges/2021/14-extendedPolymerization/benchmark.json: -------------------------------------------------------------------------------- 1 | { 2 | "day": 14, 3 | "dir": "challenges/2021/14-extendedPolymerization", 4 | "implementations": { 5 | "Python": { 6 | "part.1.avg": 0.0009306585788726807, 7 | "part.1.max": 0.002932310104370117, 8 | "part.1.min": 0.0006134510040283203, 9 | "part.2.avg": 0.0037261221408843993, 10 | "part.2.max": 0.008280754089355469, 11 | "part.2.min": 0.0021991729736328125 12 | } 13 | }, 14 | "numRuns": 1000 15 | } -------------------------------------------------------------------------------- /challenges/2021/14-extendedPolymerization/info.json: -------------------------------------------------------------------------------- 1 | { 2 | "inputFile": "input.txt", 3 | "testCases": { 4 | "one": [ 5 | { 6 | "input": "NNCB\n\nCH -> B\nHH -> N\nCB -> H\nNH -> C\nHB -> C\nHC -> B\nHN -> C\nNN -> C\nBH -> H\nNC -> B\nNB -> B\nBN -> B\nBB -> N\nBC -> B\nCC -> N\nCN -> C", 7 | "expected": "1588" 8 | } 9 | ], 10 | "two": [ 11 | { 12 | "input": "NNCB\n\nCH -> B\nHH -> N\nCB -> H\nNH -> C\nHB -> C\nHC -> B\nHN -> C\nNN -> C\nBH -> H\nNC -> B\nNB -> B\nBN -> B\nBB -> N\nBC -> B\nCC -> N\nCN -> C", 13 | "expected": "2188189693529" 14 | } 15 | ] 16 | } 17 | } -------------------------------------------------------------------------------- /challenges/2021/15-chiton/README.md: -------------------------------------------------------------------------------- 1 | # [Day 15: Chiton](https://adventofcode.com/2021/day/15) 2 | 3 | -------------------------------------------------------------------------------- /challenges/2021/15-chiton/benchmark.json: -------------------------------------------------------------------------------- 1 | { 2 | "day": 15, 3 | "dir": "challenges/2021/15-chiton", 4 | "implementations": { 5 | "Python": { 6 | "part.1.avg": 0.10024118185043335, 7 | "part.1.max": 0.26880645751953125, 8 | "part.1.min": 0.04713582992553711, 9 | "part.2.avg": 4.993094868659973, 10 | "part.2.max": 10.088721990585327, 11 | "part.2.min": 2.554753065109253 12 | } 13 | }, 14 | "numRuns": 100 15 | } -------------------------------------------------------------------------------- /challenges/2021/15-chiton/info.json: -------------------------------------------------------------------------------- 1 | { 2 | "inputFile": "input.txt", 3 | "testCases": { 4 | "one": [ 5 | { 6 | "input": "1163751742\n1381373672\n2136511328\n3694931569\n7463417111\n1319128137\n1359912421\n3125421639\n1293138521\n2311944581\n", 7 | "expected": "40" 8 | } 9 | ], 10 | "two": [ 11 | { 12 | "input": "1163751742\n1381373672\n2136511328\n3694931569\n7463417111\n1319128137\n1359912421\n3125421639\n1293138521\n2311944581\n", 13 | "expected": "315" 14 | } 15 | ] 16 | } 17 | } -------------------------------------------------------------------------------- /challenges/2021/16-packetDecoder/README.md: -------------------------------------------------------------------------------- 1 | # [Day 16: Packet Decoder](https://adventofcode.com/2021/day/16) 2 | 3 | -------------------------------------------------------------------------------- /challenges/2021/16-packetDecoder/benchmark.json: -------------------------------------------------------------------------------- 1 | { 2 | "day": 16, 3 | "dir": "challenges/2021/16-packetDecoder", 4 | "implementations": { 5 | "Python": { 6 | "part.1.avg": 0.002915963888168335, 7 | "part.1.max": 0.011673688888549805, 8 | "part.1.min": 0.0016696453094482422, 9 | "part.2.avg": 0.0029851856231689453, 10 | "part.2.max": 0.019982337951660156, 11 | "part.2.min": 0.0017099380493164062 12 | } 13 | }, 14 | "numRuns": 1000 15 | } -------------------------------------------------------------------------------- /challenges/2021/20-trenchMap/README.md: -------------------------------------------------------------------------------- 1 | # [Day 20: Trench Map](https://adventofcode.com/2021/day/20) 2 | 3 | [Part two visualisation](./part2.mp4) -------------------------------------------------------------------------------- /challenges/2021/20-trenchMap/benchmark.json: -------------------------------------------------------------------------------- 1 | { 2 | "day": 20, 3 | "dir": "challenges/2021/20-trenchMap", 4 | "implementations": { 5 | "Nim": { 6 | "part.1.avg": 0.019850478899999996, 7 | "part.1.max": 0.048351829, 8 | "part.1.min": 0.008844087, 9 | "part.2.avg": 1.18194288576, 10 | "part.2.max": 2.369594795, 11 | "part.2.min": 0.635431931 12 | }, 13 | "Python": { 14 | "part.1.avg": 0.18487148761749267, 15 | "part.1.max": 0.3699030876159668, 16 | "part.1.min": 0.09880661964416504, 17 | "part.2.avg": 10.631744318008423, 18 | "part.2.max": 18.34923243522644, 19 | "part.2.min": 5.976168155670166 20 | } 21 | }, 22 | "numRuns": 50 23 | } -------------------------------------------------------------------------------- /challenges/2021/20-trenchMap/part2.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codemicro/adventOfCode/569c26b209f4f0a8879cac902fc926f0f9515703/challenges/2021/20-trenchMap/part2.mp4 -------------------------------------------------------------------------------- /challenges/2021/21-diracDice/README.md: -------------------------------------------------------------------------------- 1 | # [Day 21: Dirac Dice](https://adventofcode.com/2021/day/21) 2 | 3 | -------------------------------------------------------------------------------- /challenges/2021/21-diracDice/benchmark.json: -------------------------------------------------------------------------------- 1 | { 2 | "day": 21, 3 | "dir": "challenges/2021/21-diracDice", 4 | "implementations": { 5 | "Python": { 6 | "part.1.avg": 0.0007445704936981201, 7 | "part.1.max": 0.00394892692565918, 8 | "part.1.min": 0.0004050731658935547, 9 | "part.2.avg": 0.000006680965423583984, 10 | "part.2.max": 0.000054836273193359375, 11 | "part.2.min": 0.0000011920928955078125 12 | } 13 | }, 14 | "numRuns": 1000 15 | } -------------------------------------------------------------------------------- /challenges/2021/21-diracDice/info.json: -------------------------------------------------------------------------------- 1 | { 2 | "inputFile": "input.txt", 3 | "testCases": { 4 | "one": [ 5 | { 6 | "input": "Player 1 starting position: 4\nPlayer 2 starting position: 8\n", 7 | "expected": "739785" 8 | } 9 | ], 10 | "two": [ 11 | { 12 | "input": "Player 1 starting position: 4\nPlayer 2 starting position: 8\n", 13 | "expected": "444356092776315" 14 | } 15 | ] 16 | } 17 | } -------------------------------------------------------------------------------- /challenges/2021/22-reactorReboot/README.md: -------------------------------------------------------------------------------- 1 | # [Day 22: Reactor Reboot](https://adventofcode.com/2021/day/22) 2 | 3 | Today's solution is a little weird... 4 | 5 | I solved part one using the easy, store every point method. However, for part two, I didn't want to go to the trouble of writing code to work out the intersections of all the cubes. Instead, I chose to do the following: 6 | 7 | * Wrote some Python code (`openscad-generate.py`) to generate some [OpenSCAD](http://openscad.org/) code based on the challenge input 8 | * This made liberal use of nested `union()`, `difference()`, `translate()` and `cube()` functions 9 | * Ran this code in OpenSCAD and exported the resultant model as an STL 10 | * Imported this STL file into Blender and used the 3D-Print Toolbox addon to calculate the total volume of the object 11 | * Typed this number into the AoC website 12 | * Obtained the 2nd star ★ :D 13 | 14 | ![openscad](openscad-part-2.png) 15 | 16 | ![blender](blender-part-2.png) -------------------------------------------------------------------------------- /challenges/2021/22-reactorReboot/blender-part-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codemicro/adventOfCode/569c26b209f4f0a8879cac902fc926f0f9515703/challenges/2021/22-reactorReboot/blender-part-2.png -------------------------------------------------------------------------------- /challenges/2021/22-reactorReboot/openscad-part-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codemicro/adventOfCode/569c26b209f4f0a8879cac902fc926f0f9515703/challenges/2021/22-reactorReboot/openscad-part-2.png -------------------------------------------------------------------------------- /challenges/2021/25-seaCucumber/README.md: -------------------------------------------------------------------------------- 1 | # [Day 25: Sea Cucumber](https://adventofcode.com/2021/day/25) 2 | 3 | -------------------------------------------------------------------------------- /challenges/2021/25-seaCucumber/benchmark.json: -------------------------------------------------------------------------------- 1 | { 2 | "day": 25, 3 | "dir": "challenges/2021/25-seaCucumber", 4 | "implementations": { 5 | "Python": { 6 | "part.1.avg": 1.2896365237236023, 7 | "part.1.max": 1.4006781578063965, 8 | "part.1.min": 1.2583773136138916, 9 | "part.2.avg": 0.000003247261047363281, 10 | "part.2.max": 0.000013828277587890625, 11 | "part.2.min": 0.0000016689300537109375 12 | } 13 | }, 14 | "numRuns": 100 15 | } -------------------------------------------------------------------------------- /challenges/2021/25-seaCucumber/info.json: -------------------------------------------------------------------------------- 1 | { 2 | "inputFile": "input.txt", 3 | "testCases": { 4 | "one": [ 5 | { 6 | "input": "v...>>.vv>\n.vv>>.vv..\n>>.>v>...v\n>>v>>.>.v.\nv>v.vv.v..\n>.>>..v...\n.vv..>.>v.\nv.v..>>v.v\n....v..v.>", 7 | "expected": "58" 8 | } 9 | ], 10 | "two": [] 11 | }, 12 | "incorrect": { 13 | "one": ["406", "312"] 14 | } 15 | } -------------------------------------------------------------------------------- /challenges/2021/running-times.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codemicro/adventOfCode/569c26b209f4f0a8879cac902fc926f0f9515703/challenges/2021/running-times.png -------------------------------------------------------------------------------- /challenges/2022/01-calorieCounting/README.md: -------------------------------------------------------------------------------- 1 | # [Day 1: Calorie Counting](https://adventofcode.com/2022/day/1) 2 | -------------------------------------------------------------------------------- /challenges/2022/01-calorieCounting/benchmark.json: -------------------------------------------------------------------------------- 1 | { 2 | "day": 1, 3 | "dir": "challenges/2022/01-calorieCounting", 4 | "implementations": { 5 | "Nim": { 6 | "part.1.avg": 0.001049538246, 7 | "part.1.max": 0.010881062, 8 | "part.1.min": 0.000266989, 9 | "part.2.avg": 0.0011080301140000003, 10 | "part.2.max": 0.003602068, 11 | "part.2.min": 0.000278025 12 | }, 13 | "Python": { 14 | "part.1.avg": 0.001036302089691162, 15 | "part.1.max": 0.0028290748596191406, 16 | "part.1.min": 0.00023937225341796875, 17 | "part.2.avg": 0.0011057097911834717, 18 | "part.2.max": 0.003584623336791992, 19 | "part.2.min": 0.0002548694610595703 20 | } 21 | }, 22 | "numRuns": 1000 23 | } -------------------------------------------------------------------------------- /challenges/2022/01-calorieCounting/info.json: -------------------------------------------------------------------------------- 1 | { 2 | "inputFile": "input.txt", 3 | "testCases": { 4 | "one": [ 5 | { 6 | "input": "1000\n2000\n3000\n\n4000\n\n5000\n6000\n\n7000\n8000\n9000\n\n10000\n", 7 | "expected": "24000" 8 | } 9 | ], 10 | "two": [ 11 | { 12 | "input": "1000\n2000\n3000\n\n4000\n\n5000\n6000\n\n7000\n8000\n9000\n\n10000\n", 13 | "expected": "45000" 14 | } 15 | ] 16 | } 17 | } -------------------------------------------------------------------------------- /challenges/2022/01-calorieCounting/java/src/Main.java: -------------------------------------------------------------------------------- 1 | import java.io.FileNotFoundException; 2 | 3 | public class Main { 4 | public static void main(String[] args) throws FileNotFoundException { 5 | Challenge c = new Challenge("input.txt"); 6 | System.out.println(c.partOne()); 7 | System.out.println(c.partTwo()); 8 | } 9 | } -------------------------------------------------------------------------------- /challenges/2022/01-calorieCounting/nim/challenge.nim: -------------------------------------------------------------------------------- 1 | import std/strutils 2 | import std/sequtils 3 | import std/algorithm 4 | 5 | proc parseInput(instr: string): seq[seq[int]] = 6 | result = instr. 7 | strip. 8 | split("\n\n"). 9 | map(proc(x: string): seq[int] = x.splitLines.map(parseInt)) 10 | 11 | proc sum(x: openArray[int]): int = 12 | for i in 0.. List[List[int]]: 6 | return [map(int, x.split("\n")) for x in instr.strip().split("\n\n")] 7 | 8 | 9 | class Challenge(BaseChallenge): 10 | @staticmethod 11 | def one(instr: str) -> int: 12 | parsed = parse(instr) 13 | x = [sum(y) for y in parsed] 14 | return max(x) 15 | 16 | @staticmethod 17 | def two(instr: str) -> int: 18 | parsed = parse(instr) 19 | x = [sum(y) for y in parsed] 20 | x = list(sorted(x, reverse=True)) 21 | return sum(x[:3]) 22 | -------------------------------------------------------------------------------- /challenges/2022/02-rockPaperScissors/README.md: -------------------------------------------------------------------------------- 1 | # [Day 2: Rock Paper Scissors](https://adventofcode.com/2022/day/2) 2 | -------------------------------------------------------------------------------- /challenges/2022/02-rockPaperScissors/benchmark.json: -------------------------------------------------------------------------------- 1 | { 2 | "day": 2, 3 | "dir": "challenges/2022/02-rockPaperScissors", 4 | "implementations": { 5 | "Nim": { 6 | "part.1.avg": 0.0006056322499999992, 7 | "part.1.max": 0.002023021, 8 | "part.1.min": 0.000160608, 9 | "part.2.avg": 0.000544890418, 10 | "part.2.max": 0.002167248, 11 | "part.2.min": 0.000143214 12 | }, 13 | "Python": { 14 | "part.1.avg": 0.005041266918182373, 15 | "part.1.max": 0.049498796463012695, 16 | "part.1.min": 0.001485586166381836, 17 | "part.2.avg": 0.002977017641067505, 18 | "part.2.max": 0.0347900390625, 19 | "part.2.min": 0.0008869171142578125 20 | } 21 | }, 22 | "numRuns": 1000 23 | } -------------------------------------------------------------------------------- /challenges/2022/02-rockPaperScissors/info.json: -------------------------------------------------------------------------------- 1 | { 2 | "inputFile": "input.txt", 3 | "testCases": { 4 | "one": [ 5 | { 6 | "input": "A Y\nB X\nC Z\n", 7 | "expected": "15" 8 | } 9 | ], 10 | "two": [ 11 | { 12 | "input": "A Y\nB X\nC Z\n", 13 | "expected": "12" 14 | } 15 | ] 16 | } 17 | } -------------------------------------------------------------------------------- /challenges/2022/03-rucksackReorganization/README.md: -------------------------------------------------------------------------------- 1 | # [Day 3: Rucksack Reorganization](https://adventofcode.com/2022/day/3) 2 | -------------------------------------------------------------------------------- /challenges/2022/03-rucksackReorganization/benchmark.json: -------------------------------------------------------------------------------- 1 | { 2 | "day": 3, 3 | "dir": "challenges/2022/03-rucksackReorganization", 4 | "implementations": { 5 | "Nim": { 6 | "part.1.avg": 0.001724590531000001, 7 | "part.1.max": 0.004034478, 8 | "part.1.min": 0.000354275, 9 | "part.2.avg": 0.001641240340999998, 10 | "part.2.max": 0.003942411, 11 | "part.2.min": 0.000368459 12 | }, 13 | "Python": { 14 | "part.1.avg": 0.0012067508697509765, 15 | "part.1.max": 0.0058939456939697266, 16 | "part.1.min": 0.0003886222839355469, 17 | "part.2.avg": 0.000901190996170044, 18 | "part.2.max": 0.0058858394622802734, 19 | "part.2.min": 0.0002906322479248047 20 | } 21 | }, 22 | "numRuns": 1000 23 | } -------------------------------------------------------------------------------- /challenges/2022/03-rucksackReorganization/info.json: -------------------------------------------------------------------------------- 1 | { 2 | "inputFile": "input.txt", 3 | "testCases": { 4 | "one": [ 5 | { 6 | "input": "vJrwpWtwJgWrhcsFMMfFFhFp\njqHRNqRjqzjGDLGLrsFMfFZSrLrFZsSL\nPmmdzqPrVvPwwTWBwg\nwMqvLMZHhHMvwLHjbvcjnnSBnvTQFn\nttgJtRGJQctTZtZT\nCrZsJsPPZsGzwwsLwLmpwMDw", 7 | "expected": "157" 8 | } 9 | ], 10 | "two": [ 11 | { 12 | "input": "vJrwpWtwJgWrhcsFMMfFFhFp\njqHRNqRjqzjGDLGLrsFMfFZSrLrFZsSL\nPmmdzqPrVvPwwTWBwg\nwMqvLMZHhHMvwLHjbvcjnnSBnvTQFn\nttgJtRGJQctTZtZT\nCrZsJsPPZsGzwwsLwLmpwMDw", 13 | "expected": "70" 14 | } 15 | ] 16 | } 17 | } -------------------------------------------------------------------------------- /challenges/2022/03-rucksackReorganization/nim/challenge.nim: -------------------------------------------------------------------------------- 1 | import std/sets 2 | import std/strutils 3 | 4 | proc parse(instr: string): seq[string] = instr.strip.splitlines 5 | 6 | proc getPriority(ch: char): int = 7 | let co = ch.ord 8 | if ord('a') <= co and co <= ord('z'): 9 | return (co - ord('a')) + 1 10 | return (co - ord('A')) + 27 11 | 12 | proc partOne*(instr: string): int = 13 | let inp = parse(instr) 14 | 15 | var sigma = 0 16 | for x in inp: 17 | assert x.len mod 2 == 0 18 | let l = x.len div 2 19 | var y = intersection( 20 | toHashSet(x[0.. int: 6 | for i in range(len(instr) - length): 7 | if len(set(instr[i : i + length])) == length: 8 | return i + length 9 | raise ValueError("cannot solve") 10 | 11 | 12 | class Challenge(BaseChallenge): 13 | @staticmethod 14 | def one(instr: str) -> int: 15 | return find_unique_sequence(instr, 4) 16 | 17 | @staticmethod 18 | def two(instr: str) -> int: 19 | return find_unique_sequence(instr, 14) 20 | -------------------------------------------------------------------------------- /challenges/2022/07-noSpaceLeftOnDevice/README.md: -------------------------------------------------------------------------------- 1 | # [Day 7: No Space Left On Device](https://adventofcode.com/2022/day/7) 2 | -------------------------------------------------------------------------------- /challenges/2022/07-noSpaceLeftOnDevice/benchmark.json: -------------------------------------------------------------------------------- 1 | { 2 | "day": 7, 3 | "dir": "challenges/2022/07-noSpaceLeftOnDevice", 4 | "implementations": { 5 | "Nim": { 6 | "part.1.avg": 0.005115992285999994, 7 | "part.1.max": 0.020854849, 8 | "part.1.min": 0.002606261, 9 | "part.2.avg": 0.0051005765810000015, 10 | "part.2.max": 0.018048126, 11 | "part.2.min": 0.002556105 12 | }, 13 | "Python": { 14 | "part.1.avg": 0.00848755979537964, 15 | "part.1.max": 0.0318598747253418, 16 | "part.1.min": 0.0057828426361083984, 17 | "part.2.avg": 0.008544703245162964, 18 | "part.2.max": 0.03149008750915527, 19 | "part.2.min": 0.005964994430541992 20 | } 21 | }, 22 | "numRuns": 1000 23 | } -------------------------------------------------------------------------------- /challenges/2022/07-noSpaceLeftOnDevice/info.json: -------------------------------------------------------------------------------- 1 | { 2 | "inputFile": "input.txt", 3 | "testCases": { 4 | "one": [ 5 | { 6 | "input": "$ cd /\n$ ls\ndir a\n14848514 b.txt\n8504156 c.dat\ndir d\n$ cd a\n$ ls\ndir e\n29116 f\n2557 g\n62596 h.lst\n$ cd e\n$ ls\n584 i\n$ cd ..\n$ cd ..\n$ cd d\n$ ls\n4060174 j\n8033020 d.log\n5626152 d.ext\n7214296 k\n", 7 | "expected": "95437" 8 | } 9 | ], 10 | "two": [ 11 | { 12 | "input": "$ cd /\n$ ls\ndir a\n14848514 b.txt\n8504156 c.dat\ndir d\n$ cd a\n$ ls\ndir e\n29116 f\n2557 g\n62596 h.lst\n$ cd e\n$ ls\n584 i\n$ cd ..\n$ cd ..\n$ cd d\n$ ls\n4060174 j\n8033020 d.log\n5626152 d.ext\n7214296 k\n", 13 | "expected": "24933642" 14 | } 15 | ] 16 | }, 17 | "not": { 18 | "one": ["1366030"] 19 | } 20 | } -------------------------------------------------------------------------------- /challenges/2022/08-treetopTreeHouse/README.md: -------------------------------------------------------------------------------- 1 | # [Day 8: Treetop Tree House](https://adventofcode.com/2022/day/8) 2 | -------------------------------------------------------------------------------- /challenges/2022/08-treetopTreeHouse/benchmark.json: -------------------------------------------------------------------------------- 1 | { 2 | "day": 8, 3 | "dir": "challenges/2022/08-treetopTreeHouse", 4 | "implementations": { 5 | "Nim": { 6 | "part.1.avg": 0.006382409829000001, 7 | "part.1.max": 0.026628604, 8 | "part.1.min": 0.004007148, 9 | "part.2.avg": 0.007344551142000002, 10 | "part.2.max": 0.034047325, 11 | "part.2.min": 0.004595712 12 | }, 13 | "Python": { 14 | "part.1.avg": 0.0385476336479187, 15 | "part.1.max": 0.09098124504089355, 16 | "part.1.min": 0.025599002838134766, 17 | "part.2.avg": 0.04808542013168335, 18 | "part.2.max": 0.1426246166229248, 19 | "part.2.min": 0.031610965728759766 20 | } 21 | }, 22 | "numRuns": 1000 23 | } -------------------------------------------------------------------------------- /challenges/2022/08-treetopTreeHouse/info.json: -------------------------------------------------------------------------------- 1 | { 2 | "inputFile": "input.txt", 3 | "testCases": { 4 | "one": [ 5 | { 6 | "input": "30373\n25512\n65332\n33549\n35390", 7 | "expected": "21" 8 | } 9 | ], 10 | "two": [ 11 | { 12 | "input": "30373\n25512\n65332\n33549\n35390", 13 | "expected": "8" 14 | } 15 | ] 16 | } 17 | } -------------------------------------------------------------------------------- /challenges/2022/09-ropeBridge/README.md: -------------------------------------------------------------------------------- 1 | # [Day 9: Rope Bridge](https://adventofcode.com/2022/day/9) 2 | -------------------------------------------------------------------------------- /challenges/2022/09-ropeBridge/benchmark.json: -------------------------------------------------------------------------------- 1 | { 2 | "day": 9, 3 | "dir": "challenges/2022/09-ropeBridge", 4 | "implementations": { 5 | "Nim": { 6 | "part.1.avg": 0.002931661109000006, 7 | "part.1.max": 0.007730762, 8 | "part.1.min": 0.000887947, 9 | "part.2.avg": 0.004008995328999999, 10 | "part.2.max": 0.011666485, 11 | "part.2.min": 0.001218443 12 | }, 13 | "Python": { 14 | "part.1.avg": 0.015390190362930298, 15 | "part.1.max": 0.03382277488708496, 16 | "part.1.min": 0.010709762573242188, 17 | "part.2.avg": 0.0444308967590332, 18 | "part.2.max": 0.14687561988830566, 19 | "part.2.min": 0.03348994255065918 20 | } 21 | }, 22 | "numRuns": 1000 23 | } -------------------------------------------------------------------------------- /challenges/2022/09-ropeBridge/info.json: -------------------------------------------------------------------------------- 1 | { 2 | "inputFile": "input.txt", 3 | "testCases": { 4 | "one": [ 5 | { 6 | "input": "R 4\nU 4\nL 3\nD 1\nR 4\nD 1\nL 5\nR 2", 7 | "expected": "13" 8 | } 9 | ], 10 | "two": [ 11 | { 12 | "input": "R 4\nU 4\nL 3\nD 1\nR 4\nD 1\nL 5\nR 2", 13 | "expected": "1" 14 | }, 15 | { 16 | "input": "R 5\nU 8\nL 8\nD 3\nR 17\nD 10\nL 25\nU 20\n", 17 | "expected": "36" 18 | } 19 | ] 20 | } 21 | } -------------------------------------------------------------------------------- /challenges/2022/10-cathodeRayTube/README.md: -------------------------------------------------------------------------------- 1 | # [Day 10: Cathode Ray Tube](https://adventofcode.com/2022/day/10) 2 | -------------------------------------------------------------------------------- /challenges/2022/10-cathodeRayTube/benchmark.json: -------------------------------------------------------------------------------- 1 | { 2 | "day": 10, 3 | "dir": "challenges/2022/10-cathodeRayTube", 4 | "implementations": { 5 | "Python": { 6 | "part.1.avg": 0.0004485485553741455, 7 | "part.1.max": 0.0012202262878417969, 8 | "part.1.min": 0.00010895729064941406, 9 | "part.2.avg": 0.0006327939033508301, 10 | "part.2.max": 0.0017185211181640625, 11 | "part.2.min": 0.0001571178436279297 12 | } 13 | }, 14 | "numRuns": 1000 15 | } -------------------------------------------------------------------------------- /challenges/2022/11-monkeyInTheMiddle/README.md: -------------------------------------------------------------------------------- 1 | # [Day 11: Monkey In The Middle](https://adventofcode.com/2022/day/11) 2 | -------------------------------------------------------------------------------- /challenges/2022/11-monkeyInTheMiddle/benchmark.json: -------------------------------------------------------------------------------- 1 | { 2 | "day": 11, 3 | "dir": "challenges/2022/11-monkeyInTheMiddle", 4 | "implementations": { 5 | "Python": { 6 | "part.1.avg": 0.0008889389038085938, 7 | "part.1.max": 0.002737283706665039, 8 | "part.1.min": 0.0006763935089111328, 9 | "part.2.avg": 0.46039318370819093, 10 | "part.2.max": 0.6005921363830566, 11 | "part.2.min": 0.3884415626525879 12 | } 13 | }, 14 | "numRuns": 250 15 | } -------------------------------------------------------------------------------- /challenges/2022/12-hillClimbingAlgorithm/README.md: -------------------------------------------------------------------------------- 1 | # [Day 12: Hill Climbing Algorithm](https://adventofcode.com/2022/day/12) 2 | -------------------------------------------------------------------------------- /challenges/2022/12-hillClimbingAlgorithm/benchmark.json: -------------------------------------------------------------------------------- 1 | { 2 | "day": 12, 3 | "dir": "challenges/2022/12-hillClimbingAlgorithm", 4 | "implementations": { 5 | "Python": { 6 | "part.1.avg": 2.804302930831909, 7 | "part.1.max": 2.804302930831909, 8 | "part.1.min": 2.804302930831909, 9 | "part.2.avg": 191.0712034702301, 10 | "part.2.max": 191.0712034702301, 11 | "part.2.min": 191.0712034702301 12 | } 13 | }, 14 | "numRuns": 1 15 | } -------------------------------------------------------------------------------- /challenges/2022/12-hillClimbingAlgorithm/info.json: -------------------------------------------------------------------------------- 1 | { 2 | "inputFile": "input.txt", 3 | "testCases": { 4 | "one": [ 5 | { 6 | "input": "Sabqponm\nabcryxxl\naccszExk\nacctuvwj\nabdefghi\n", 7 | "expected": "31" 8 | } 9 | ], 10 | "two": [ 11 | { 12 | "input": "Sabqponm\nabcryxxl\naccszExk\nacctuvwj\nabdefghi\n", 13 | "expected": "29" 14 | } 15 | ] 16 | } 17 | } -------------------------------------------------------------------------------- /challenges/2022/13-distressSignal/README.md: -------------------------------------------------------------------------------- 1 | # [Day 13: Distress Signal](https://adventofcode.com/2022/day/13) 2 | -------------------------------------------------------------------------------- /challenges/2022/13-distressSignal/benchmark.json: -------------------------------------------------------------------------------- 1 | { 2 | "day": 13, 3 | "dir": "challenges/2022/13-distressSignal", 4 | "implementations": { 5 | "Python": { 6 | "part.1.avg": 0.002429138422012329, 7 | "part.1.max": 0.013918876647949219, 8 | "part.1.min": 0.0013120174407958984, 9 | "part.2.avg": 0.008559255361557007, 10 | "part.2.max": 0.03811001777648926, 11 | "part.2.min": 0.004506111145019531 12 | } 13 | }, 14 | "numRuns": 1000 15 | } -------------------------------------------------------------------------------- /challenges/2022/13-distressSignal/info.json: -------------------------------------------------------------------------------- 1 | { 2 | "inputFile": "input.txt", 3 | "testCases": { 4 | "one": [ 5 | { 6 | "input": "[1,1,3,1,1]\n[1,1,5,1,1]\n\n[[1],[2,3,4]]\n[[1],4]\n\n[9]\n[[8,7,6]]\n\n[[4,4],4,4]\n[[4,4],4,4,4]\n\n[7,7,7,7]\n[7,7,7]\n\n[]\n[3]\n\n[[[]]]\n[[]]\n\n[1,[2,[3,[4,[5,6,7]]]],8,9]\n[1,[2,[3,[4,[5,6,0]]]],8,9]\n", 7 | "expected": "13" 8 | } 9 | ], 10 | "two": [ 11 | { 12 | "input": "[1,1,3,1,1]\n[1,1,5,1,1]\n\n[[1],[2,3,4]]\n[[1],4]\n\n[9]\n[[8,7,6]]\n\n[[4,4],4,4]\n[[4,4],4,4,4]\n\n[7,7,7,7]\n[7,7,7]\n\n[]\n[3]\n\n[[[]]]\n[[]]\n\n[1,[2,[3,[4,[5,6,7]]]],8,9]\n[1,[2,[3,[4,[5,6,0]]]],8,9]\n", 13 | "expected": "140" 14 | } 15 | ] 16 | } 17 | } -------------------------------------------------------------------------------- /challenges/2022/14-regolithReservoir/README.md: -------------------------------------------------------------------------------- 1 | # [Day 14: Regolith Reservoir](https://adventofcode.com/2022/day/14) 2 | -------------------------------------------------------------------------------- /challenges/2022/14-regolithReservoir/benchmark.json: -------------------------------------------------------------------------------- 1 | { 2 | "day": 14, 3 | "dir": "challenges/2022/14-regolithReservoir", 4 | "implementations": { 5 | "Python": { 6 | "part.1.avg": 0.052977256774902344, 7 | "part.1.max": 0.059580087661743164, 8 | "part.1.min": 0.04468560218811035, 9 | "part.2.avg": 3.079384412765503, 10 | "part.2.max": 3.293449640274048, 11 | "part.2.min": 2.7332167625427246 12 | } 13 | }, 14 | "numRuns": 25 15 | } -------------------------------------------------------------------------------- /challenges/2022/14-regolithReservoir/info.json: -------------------------------------------------------------------------------- 1 | { 2 | "inputFile": "input.txt", 3 | "testCases": { 4 | "one": [ 5 | { 6 | "input": "498,4 -> 498,6 -> 496,6\n503,4 -> 502,4 -> 502,9 -> 494,9\n", 7 | "expected": "24" 8 | } 9 | ], 10 | "two": [ 11 | { 12 | "input": "498,4 -> 498,6 -> 496,6\n503,4 -> 502,4 -> 502,9 -> 494,9\n", 13 | "expected": "93" 14 | } 15 | ] 16 | } 17 | } -------------------------------------------------------------------------------- /challenges/2022/15-beaconExclusionZone/README.md: -------------------------------------------------------------------------------- 1 | # [Day 15: Beacon Exclusion Zone](https://adventofcode.com/2022/day/15) 2 | 3 | Here's some of my whiteboard doodles (don't mind that they're wrong in places) 4 | 5 | ![whiteboard doodles](doodles.jpg) -------------------------------------------------------------------------------- /challenges/2022/15-beaconExclusionZone/benchmark.json: -------------------------------------------------------------------------------- 1 | { 2 | "day": 15, 3 | "dir": "challenges/2022/15-beaconExclusionZone", 4 | "implementations": { 5 | "Python": { 6 | "part.1.avg": 2.488755464553833, 7 | "part.1.max": 2.488755464553833, 8 | "part.1.min": 2.488755464553833, 9 | "part.2.avg": 295.4520, 10 | "part.2.max": 295.4520, 11 | "part.2.min": 295.4520 12 | } 13 | }, 14 | "numRuns": 1 15 | } -------------------------------------------------------------------------------- /challenges/2022/15-beaconExclusionZone/doodles.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codemicro/adventOfCode/569c26b209f4f0a8879cac902fc926f0f9515703/challenges/2022/15-beaconExclusionZone/doodles.jpg -------------------------------------------------------------------------------- /challenges/2022/16-proboscideaVolcanium/README.md: -------------------------------------------------------------------------------- 1 | # [Day 16: Proboscidea Volcanium](https://adventofcode.com/2022/day/16) 2 | 3 | [This solution was used to end up with my solution](https://github.com/davearussell/advent2022/blob/master/day16/solve.py). -------------------------------------------------------------------------------- /challenges/2022/16-proboscideaVolcanium/benchmark.json: -------------------------------------------------------------------------------- 1 | { 2 | "day": 16, 3 | "dir": "challenges/2022/16-proboscideaVolcanium", 4 | "implementations": { 5 | "Python": { 6 | "part.1.avg": 3.520505666732788, 7 | "part.1.max": 3.520505666732788, 8 | "part.1.min": 3.520505666732788, 9 | "part.2.avg": 18.672574281692505, 10 | "part.2.max": 18.672574281692505, 11 | "part.2.min": 18.672574281692505 12 | } 13 | }, 14 | "numRuns": 1 15 | } -------------------------------------------------------------------------------- /challenges/2022/17-pyroclasticFlow/README.md: -------------------------------------------------------------------------------- 1 | # [Day 17: Pyroclastic Flow](https://adventofcode.com/2022/day/17) 2 | -------------------------------------------------------------------------------- /challenges/2022/17-pyroclasticFlow/benchmark.json: -------------------------------------------------------------------------------- 1 | { 2 | "day": 17, 3 | "dir": "challenges/2022/17-pyroclasticFlow", 4 | "implementations": { 5 | "Python": { 6 | "part.1.avg": 0.5983425378799438, 7 | "part.1.max": 0.6658821105957031, 8 | "part.1.min": 0.5308029651641846, 9 | "part.2.avg": 12.261357307434082, 10 | "part.2.max": 12.877821207046509, 11 | "part.2.min": 11.644893407821655 12 | } 13 | }, 14 | "numRuns": 2 15 | } -------------------------------------------------------------------------------- /challenges/2022/17-pyroclasticFlow/info.json: -------------------------------------------------------------------------------- 1 | { 2 | "inputFile": "input.txt", 3 | "testCases": { 4 | "one": [ 5 | { 6 | "input": ">>><<><>><<<>><>>><<<>>><<<><<<>><>><<>>", 7 | "expected": "3068" 8 | } 9 | ], 10 | "two": [ 11 | { 12 | "input": ">>><<><>><<<>><>>><<<>>><<<><<<>><>><<>>", 13 | "expected": "1514285714288" 14 | } 15 | ] 16 | } 17 | } -------------------------------------------------------------------------------- /challenges/2022/18-boilingBoulders/README.md: -------------------------------------------------------------------------------- 1 | # [Day 18: Boiling Boulders](https://adventofcode.com/2022/day/18) 2 | -------------------------------------------------------------------------------- /challenges/2022/18-boilingBoulders/benchmark.json: -------------------------------------------------------------------------------- 1 | { 2 | "day": 18, 3 | "dir": "challenges/2022/18-boilingBoulders", 4 | "implementations": { 5 | "Python": { 6 | "part.1.avg": 0.02251845836639404, 7 | "part.1.max": 0.03545045852661133, 8 | "part.1.min": 0.018925189971923828, 9 | "part.2.avg": 0.12088701725006104, 10 | "part.2.max": 0.1763911247253418, 11 | "part.2.min": 0.10623359680175781 12 | } 13 | }, 14 | "numRuns": 200 15 | } -------------------------------------------------------------------------------- /challenges/2022/18-boilingBoulders/info.json: -------------------------------------------------------------------------------- 1 | { 2 | "inputFile": "input.txt", 3 | "testCases": { 4 | "one": [ 5 | { 6 | "input": "2,2,2\n1,2,2\n3,2,2\n2,1,2\n2,3,2\n2,2,1\n2,2,3\n2,2,4\n2,2,6\n1,2,5\n3,2,5\n2,1,5\n2,3,5\n", 7 | "expected": "64" 8 | } 9 | ], 10 | "two": [ 11 | { 12 | "input": "2,2,2\n1,2,2\n3,2,2\n2,1,2\n2,3,2\n2,2,1\n2,2,3\n2,2,4\n2,2,6\n1,2,5\n3,2,5\n2,1,5\n2,3,5\n", 13 | "expected": "58" 14 | } 15 | ] 16 | } 17 | } -------------------------------------------------------------------------------- /challenges/2022/18-boilingBoulders/openscad-generate.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | inp = sys.stdin.read() 4 | 5 | print(len(inp), file=sys.stderr) 6 | 7 | print("union(){") 8 | 9 | for line in inp.strip().splitlines(): 10 | print(f"\ttranslate([{line}]) cube(1);") 11 | 12 | print("};") 13 | -------------------------------------------------------------------------------- /challenges/2022/19-notEnoughMinerals/README.md: -------------------------------------------------------------------------------- 1 | # [Day 19: Not Enough Minerals](https://adventofcode.com/2022/day/19) 2 | 3 | My part 2 took 48 minutes to run. ***48!!*** Even though part 1 only took 17 seconds! aaaaaaaaaaa 4 | -------------------------------------------------------------------------------- /challenges/2022/19-notEnoughMinerals/benchmark.json: -------------------------------------------------------------------------------- 1 | { 2 | "day": 19, 3 | "dir": "challenges/2022/19-notEnoughMinerals", 4 | "implementations": { 5 | "Python": { 6 | "part.1.avg": 17.7188, 7 | "part.1.max": 17.7188, 8 | "part.1.min": 17.7188, 9 | "part.2.avg": 2903.2192, 10 | "part.2.max": 2903.2192, 11 | "part.2.min": 2903.2192 12 | } 13 | }, 14 | "numRuns": 1 15 | } -------------------------------------------------------------------------------- /challenges/2022/19-notEnoughMinerals/info.json: -------------------------------------------------------------------------------- 1 | { 2 | "inputFile": "input.txt", 3 | "testCases": { 4 | "one": [ 5 | { 6 | "input": "Blueprint 1: Each ore robot costs 4 ore. Each clay robot costs 2 ore. Each obsidian robot costs 3 ore and 14 clay. Each geode robot costs 2 ore and 7 obsidian.\nBlueprint 2: Each ore robot costs 2 ore. Each clay robot costs 3 ore. Each obsidian robot costs 3 ore and 8 clay. Each geode robot costs 3 ore and 12 obsidian.\n", 7 | "expected": "33" 8 | } 9 | ], 10 | "two": [ 11 | { 12 | "input": "Blueprint 1: Each ore robot costs 4 ore. Each clay robot costs 2 ore. Each obsidian robot costs 3 ore and 14 clay. Each geode robot costs 2 ore and 7 obsidian.\nBlueprint 2: Each ore robot costs 2 ore. Each clay robot costs 3 ore. Each obsidian robot costs 3 ore and 8 clay. Each geode robot costs 3 ore and 12 obsidian.\n", 13 | "expected": "3472" 14 | } 15 | ] 16 | } 17 | } -------------------------------------------------------------------------------- /challenges/2022/20-grovePositioningSystem/README.md: -------------------------------------------------------------------------------- 1 | # [Day 20: Grove Positioning System](https://adventofcode.com/2022/day/20) 2 | -------------------------------------------------------------------------------- /challenges/2022/20-grovePositioningSystem/benchmark.json: -------------------------------------------------------------------------------- 1 | { 2 | "day": 20, 3 | "dir": "challenges/2022/20-grovePositioningSystem", 4 | "implementations": { 5 | "Python": { 6 | "part.1.avg": 0.6482098897298177, 7 | "part.1.max": 0.6944289207458496, 8 | "part.1.min": 0.5697693824768066, 9 | "part.2.avg": 12.018423795700073, 10 | "part.2.max": 12.624868154525757, 11 | "part.2.min": 11.30324387550354 12 | } 13 | }, 14 | "numRuns": 3 15 | } -------------------------------------------------------------------------------- /challenges/2022/20-grovePositioningSystem/info.json: -------------------------------------------------------------------------------- 1 | { 2 | "inputFile": "input.txt", 3 | "testCases": { 4 | "one": [ 5 | { 6 | "input": "1\n2\n-3\n3\n-2\n0\n4\n", 7 | "expected": "3" 8 | } 9 | ], 10 | "two": [ 11 | { 12 | "input": "1\n2\n-3\n3\n-2\n0\n4\n", 13 | "expected": "1623178306" 14 | } 15 | ] 16 | } 17 | } -------------------------------------------------------------------------------- /challenges/2022/21-monkeyMath/README.md: -------------------------------------------------------------------------------- 1 | # [Day 21: Monkey Math](https://adventofcode.com/2022/day/21) 2 | -------------------------------------------------------------------------------- /challenges/2022/21-monkeyMath/benchmark.json: -------------------------------------------------------------------------------- 1 | { 2 | "day": 21, 3 | "dir": "challenges/2022/21-monkeyMath", 4 | "implementations": { 5 | "Python": { 6 | "part.1.avg": 0.004400461912155151, 7 | "part.1.max": 0.018651485443115234, 8 | "part.1.min": 0.003258943557739258, 9 | "part.2.avg": 0.007683101415634155, 10 | "part.2.max": 0.03519558906555176, 11 | "part.2.min": 0.005395650863647461 12 | } 13 | }, 14 | "numRuns": 1000 15 | } -------------------------------------------------------------------------------- /challenges/2022/21-monkeyMath/info.json: -------------------------------------------------------------------------------- 1 | { 2 | "inputFile": "input.txt", 3 | "testCases": { 4 | "one": [ 5 | { 6 | "input": "root: pppw + sjmn\ndbpl: 5\ncczh: sllz + lgvd\nzczc: 2\nptdq: humn - dvpt\ndvpt: 3\nlfqf: 4\nhumn: 5\nljgn: 2\nsjmn: drzm * dbpl\nsllz: 4\npppw: cczh / lfqf\nlgvd: ljgn * ptdq\ndrzm: hmdt - zczc\nhmdt: 32\n", 7 | "expected": "152" 8 | } 9 | ], 10 | "two": [ 11 | { 12 | "input": "root: pppw + sjmn\ndbpl: 5\ncczh: sllz + lgvd\nzczc: 2\nptdq: humn - dvpt\ndvpt: 3\nlfqf: 4\nhumn: 5\nljgn: 2\nsjmn: drzm * dbpl\nsllz: 4\npppw: cczh / lfqf\nlgvd: ljgn * ptdq\ndrzm: hmdt - zczc\nhmdt: 32\n", 13 | "expected": "301" 14 | } 15 | ] 16 | } 17 | } -------------------------------------------------------------------------------- /challenges/2022/22-monkeyMap/README.md: -------------------------------------------------------------------------------- 1 | # [Day 22: Monkey Map](https://adventofcode.com/2022/day/22) 2 | 3 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAa -------------------------------------------------------------------------------- /challenges/2022/22-monkeyMap/benchmark.json: -------------------------------------------------------------------------------- 1 | { 2 | "day": 22, 3 | "dir": "challenges/2022/22-monkeyMap", 4 | "implementations": { 5 | "Python": { 6 | "part.1.avg": 0.3011732864379883, 7 | "part.1.max": 0.4757208824157715, 8 | "part.1.min": 0.23815560340881348, 9 | "part.2.avg": 0.07583048105239869, 10 | "part.2.max": 0.1293351650238037, 11 | "part.2.min": 0.062180280685424805 12 | } 13 | }, 14 | "numRuns": 100 15 | } -------------------------------------------------------------------------------- /challenges/2022/22-monkeyMap/info.json: -------------------------------------------------------------------------------- 1 | { 2 | "inputFile": "input.txt", 3 | "testCases": { 4 | "one": [ 5 | { 6 | "input": " ...#\n .#..\n #...\n ....\n...#.......#\n........#...\n..#....#....\n..........#.\n ...#....\n .....#..\n .#......\n ......#.\n\n10R5L5R10L4R5L5\n", 7 | "expected": "6032" 8 | } 9 | ] 10 | } 11 | } -------------------------------------------------------------------------------- /challenges/2022/23-unstableDiffusion/README.md: -------------------------------------------------------------------------------- 1 | # [Day 23: Unstable Diffusion](https://adventofcode.com/2022/day/23) 2 | -------------------------------------------------------------------------------- /challenges/2022/23-unstableDiffusion/benchmark.json: -------------------------------------------------------------------------------- 1 | { 2 | "day": 23, 3 | "dir": "challenges/2022/23-unstableDiffusion", 4 | "implementations": { 5 | "Python": { 6 | "part.1.avg": 0.5044037818908691, 7 | "part.1.max": 0.6002228260040283, 8 | "part.1.min": 0.4217519760131836, 9 | "part.2.avg": 39.05081315040589, 10 | "part.2.max": 41.361868143081665, 11 | "part.2.min": 38.02052927017212 12 | } 13 | }, 14 | "numRuns": 5 15 | } -------------------------------------------------------------------------------- /challenges/2022/23-unstableDiffusion/info.json: -------------------------------------------------------------------------------- 1 | { 2 | "inputFile": "input.txt", 3 | "testCases": { 4 | "one": [ 5 | { 6 | "input": ".....\n..##.\n..#..\n.....\n..##.\n.....", 7 | "expected": "25" 8 | }, 9 | { 10 | "input": "....#..\n..###.#\n#...#.#\n.#...##\n#.###..\n##.#.##\n.#..#..\n", 11 | "expected": "110" 12 | } 13 | ], 14 | "two": [ 15 | { 16 | "input": ".....\n..##.\n..#..\n.....\n..##.\n.....", 17 | "expected": "4" 18 | }, 19 | { 20 | "input": "....#..\n..###.#\n#...#.#\n.#...##\n#.###..\n##.#.##\n.#..#..\n", 21 | "expected": "20" 22 | } 23 | ] 24 | } 25 | } -------------------------------------------------------------------------------- /challenges/2022/24-blizzardBasin/README.md: -------------------------------------------------------------------------------- 1 | # [Day 24: Blizzard Basin](https://adventofcode.com/2022/day/24) 2 | -------------------------------------------------------------------------------- /challenges/2022/24-blizzardBasin/benchmark.json: -------------------------------------------------------------------------------- 1 | { 2 | "day": 24, 3 | "dir": "challenges/2022/24-blizzardBasin", 4 | "implementations": { 5 | "Python": { 6 | "part.1.avg": 3.8155926863352456, 7 | "part.1.max": 3.83038330078125, 8 | "part.1.min": 3.801712989807129, 9 | "part.2.avg": 11.761492411295572, 10 | "part.2.max": 11.78315782546997, 11 | "part.2.min": 11.74697995185852 12 | } 13 | }, 14 | "numRuns": 3 15 | } -------------------------------------------------------------------------------- /challenges/2022/24-blizzardBasin/info.json: -------------------------------------------------------------------------------- 1 | { 2 | "inputFile": "input.txt", 3 | "testCases": { 4 | "one": [ 5 | { 6 | "input": "#.######\n#>>.<^<#\n#.<..<<#\n#>v.><>#\n#<^v^^>#\n######.#\n", 7 | "expected": "18" 8 | } 9 | ], 10 | "two": [ 11 | { 12 | "input": "#.######\n#>>.<^<#\n#.<..<<#\n#>v.><>#\n#<^v^^>#\n######.#\n", 13 | "expected": "54" 14 | } 15 | ] 16 | } 17 | } -------------------------------------------------------------------------------- /challenges/2022/25-fullOfHotAir/README.md: -------------------------------------------------------------------------------- 1 | # [Day 25: Full Of Hot Air](https://adventofcode.com/2022/day/25) 2 | -------------------------------------------------------------------------------- /challenges/2022/25-fullOfHotAir/benchmark.json: -------------------------------------------------------------------------------- 1 | { 2 | "day": 25, 3 | "dir": "challenges/2022/25-fullOfHotAir", 4 | "implementations": { 5 | "Python": { 6 | "part.1.avg": 0.001312760591506958, 7 | "part.1.max": 0.003961801528930664, 8 | "part.1.min": 0.0003647804260253906, 9 | "part.2.avg": 0.0000055599212646484376, 10 | "part.2.max": 0.000046253204345703125, 11 | "part.2.min": 0.000001430511474609375 12 | } 13 | }, 14 | "numRuns": 1000 15 | } -------------------------------------------------------------------------------- /challenges/2022/25-fullOfHotAir/info.json: -------------------------------------------------------------------------------- 1 | { 2 | "inputFile": "input.txt", 3 | "testCases": { 4 | "one": [ 5 | { 6 | "input": "1=-0-2\n12111\n2=0=\n21\n2=01\n111\n20012\n112\n1=-1=\n1-12\n12\n1=\n122\n", 7 | "expected": "2=-1=0" 8 | }, 9 | {"input": "1", "expected": "1"}, 10 | {"input": "2", "expected": "2"}, 11 | {"input": "1=", "expected": "1="}, 12 | {"input": "1-", "expected": "1-"}, 13 | {"input": "10", "expected": "10"}, 14 | {"input": "11", "expected": "11"}, 15 | {"input": "12", "expected": "12"}, 16 | {"input": "2=", "expected": "2="}, 17 | {"input": "2-", "expected": "2-"}, 18 | {"input": "20", "expected": "20"}, 19 | {"input": "1=0", "expected": "1=0"}, 20 | {"input": "1-0", "expected": "1-0"}, 21 | {"input": "1=11-2", "expected": "1=11-2"}, 22 | {"input": "1-0---0", "expected": "1-0---0"}, 23 | {"input": "1121-1110-1=0", "expected": "1121-1110-1=0"} 24 | ] 25 | } 26 | } -------------------------------------------------------------------------------- /challenges/2022/running-times.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codemicro/adventOfCode/569c26b209f4f0a8879cac902fc926f0f9515703/challenges/2022/running-times.png -------------------------------------------------------------------------------- /challenges/2023/01-trebuchet/README.md: -------------------------------------------------------------------------------- 1 | # [Day 1: Trebuchet?!](https://adventofcode.com/2023/day/1) 2 | 3 | The Haskell implementation included here is only partial, mostly because I ran out of patience with it after taking an age to implement the CLI required. 4 | -------------------------------------------------------------------------------- /challenges/2023/01-trebuchet/tests.json: -------------------------------------------------------------------------------- 1 | { 2 | "1": [ 3 | {"input": "1abc2\npqr3stu8vwx\na1b2c3d4e5f\ntreb7uchet", "is": "142"} 4 | ], 5 | "2": [ 6 | {"input": "two1nine\neightwothree\nabcone2threexyz\nxtwone3four\n4nineeightseven2\nzoneight234\n7pqrstsixteen", "is": "281"}, 7 | {"input": "eighthree", "is": "83"}, 8 | {"input": "sevenine", "is": "79"} 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /challenges/2023/02-cubeConundrum/README.md: -------------------------------------------------------------------------------- 1 | # [Day 2: Cube Conundrum](https://adventofcode.com/2023/day/2) 2 | -------------------------------------------------------------------------------- /challenges/2023/02-cubeConundrum/tests.json: -------------------------------------------------------------------------------- 1 | { 2 | "1": [ 3 | {"input": "Game 1: 3 blue, 4 red; 1 red, 2 green, 6 blue; 2 green\nGame 2: 1 blue, 2 green; 3 green, 4 blue, 1 red; 1 green, 1 blue\nGame 3: 8 green, 6 blue, 20 red; 5 blue, 4 red, 13 green; 5 green, 1 red\nGame 4: 1 green, 3 red, 6 blue; 3 green, 6 red; 3 green, 15 blue, 14 red\nGame 5: 6 red, 1 blue, 3 green; 2 blue, 1 red, 2 green", "is": "8"} 4 | ], 5 | "2": [ 6 | {"input": "Game 1: 3 blue, 4 red; 1 red, 2 green, 6 blue; 2 green\nGame 2: 1 blue, 2 green; 3 green, 4 blue, 1 red; 1 green, 1 blue\nGame 3: 8 green, 6 blue, 20 red; 5 blue, 4 red, 13 green; 5 green, 1 red\nGame 4: 1 green, 3 red, 6 blue; 3 green, 6 red; 3 green, 15 blue, 14 red\nGame 5: 6 red, 1 blue, 3 green; 2 blue, 1 red, 2 green", "is": "2286"} 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /challenges/2023/03-gearRatios/README.md: -------------------------------------------------------------------------------- 1 | # [Day 3: Gear Ratios](https://adventofcode.com/2023/day/3) 2 | -------------------------------------------------------------------------------- /challenges/2023/03-gearRatios/tests.json: -------------------------------------------------------------------------------- 1 | { 2 | "1": [ 3 | {"is": "4361", "input": "467..114..\n...*......\n..35..633.\n......#...\n617*......\n.....+.58.\n..592.....\n......755.\n...$.*....\n.664.598.."} 4 | ], 5 | "2": [ 6 | {"is": "467835", "input": "467..114..\n...*......\n..35..633.\n......#...\n617*......\n.....+.58.\n..592.....\n......755.\n...$.*....\n.664.598.."} 7 | ] 8 | } -------------------------------------------------------------------------------- /challenges/2023/04-scratchcards/README.md: -------------------------------------------------------------------------------- 1 | # [Day 4: Scratchcards](https://adventofcode.com/2023/day/4) 2 | -------------------------------------------------------------------------------- /challenges/2023/04-scratchcards/tests.json: -------------------------------------------------------------------------------- 1 | { 2 | "1": [ 3 | {"is": "13", "input": "Card 1: 41 48 83 86 17 | 83 86 6 31 17 9 48 53\nCard 2: 13 32 20 16 61 | 61 30 68 82 17 32 24 19\nCard 3: 1 21 53 59 44 | 69 82 63 72 16 21 14 1\nCard 4: 41 92 73 84 69 | 59 84 76 51 58 5 54 83\nCard 5: 87 83 26 28 32 | 88 30 70 12 93 22 82 36\nCard 6: 31 18 13 56 72 | 74 77 10 23 35 67 36 11\n"} 4 | ], 5 | "2": [ 6 | {"is": "30", "input": "Card 1: 41 48 83 86 17 | 83 86 6 31 17 9 48 53\nCard 2: 13 32 20 16 61 | 61 30 68 82 17 32 24 19\nCard 3: 1 21 53 59 44 | 69 82 63 72 16 21 14 1\nCard 4: 41 92 73 84 69 | 59 84 76 51 58 5 54 83\nCard 5: 87 83 26 28 32 | 88 30 70 12 93 22 82 36\nCard 6: 31 18 13 56 72 | 74 77 10 23 35 67 36 11\n"} 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /challenges/2023/05-ifYouGiveASeedAFertilizer/README.md: -------------------------------------------------------------------------------- 1 | # [Day 5: If You Give A Seed A Fertilizer](https://adventofcode.com/2023/day/5) 2 | -------------------------------------------------------------------------------- /challenges/2023/05-ifYouGiveASeedAFertilizer/tests.json: -------------------------------------------------------------------------------- 1 | { 2 | "1": [ 3 | {"is": "35", "input": "seeds: 79 14 55 13\n\nseed-to-soil map:\n50 98 2\n52 50 48\n\nsoil-to-fertilizer map:\n0 15 37\n37 52 2\n39 0 15\n\nfertilizer-to-water map:\n49 53 8\n0 11 42\n42 0 7\n57 7 4\n\nwater-to-light map:\n88 18 7\n18 25 70\n\nlight-to-temperature map:\n45 77 23\n81 45 19\n68 64 13\n\ntemperature-to-humidity map:\n0 69 1\n1 0 69\n\nhumidity-to-location map:\n60 56 37\n56 93 4"} 4 | ], 5 | "2": [ 6 | {"is": "46", "input": "seeds: 79 14 55 13\n\nseed-to-soil map:\n50 98 2\n52 50 48\n\nsoil-to-fertilizer map:\n0 15 37\n37 52 2\n39 0 15\n\nfertilizer-to-water map:\n49 53 8\n0 11 42\n42 0 7\n57 7 4\n\nwater-to-light map:\n88 18 7\n18 25 70\n\nlight-to-temperature map:\n45 77 23\n81 45 19\n68 64 13\n\ntemperature-to-humidity map:\n0 69 1\n1 0 69\n\nhumidity-to-location map:\n60 56 37\n56 93 4"} 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /challenges/2023/06-waitForIt/README.md: -------------------------------------------------------------------------------- 1 | # [Day 6: Wait For It](https://adventofcode.com/2023/day/6) 2 | -------------------------------------------------------------------------------- /challenges/2023/06-waitForIt/tests.json: -------------------------------------------------------------------------------- 1 | { 2 | "1": [ 3 | {"is": "288", "input": "Time: 7 15 30\nDistance: 9 40 200\n"} 4 | ], 5 | "2": [ 6 | {"is": "71503", "input": "Time: 7 15 30\nDistance: 9 40 200\n"} 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /challenges/2023/07-camelCards/README.md: -------------------------------------------------------------------------------- 1 | # [Day 7: Camel Cards](https://adventofcode.com/2023/day/7) 2 | -------------------------------------------------------------------------------- /challenges/2023/07-camelCards/tests.json: -------------------------------------------------------------------------------- 1 | { 2 | "1": [ 3 | {"is": "6440", "input": "32T3K 765\nT55J5 684\nKK677 28\nKTJJT 220\nQQQJA 483"} 4 | ], 5 | "2": [ 6 | {"is": "5905", "input": "32T3K 765\nT55J5 684\nKK677 28\nKTJJT 220\nQQQJA 483"} 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /challenges/2023/08-hauntedWasteland/README.md: -------------------------------------------------------------------------------- 1 | # [Day 8: Haunted Wasteland](https://adventofcode.com/2023/day/8) 2 | 3 | A generic solution is implemented in commit 208114cb6222064c1a174b69e737c7cd051defa2 -------------------------------------------------------------------------------- /challenges/2023/08-hauntedWasteland/tests.json: -------------------------------------------------------------------------------- 1 | { 2 | "1": [ 3 | {"is": "2", "input": "RL\n\nAAA = (BBB, CCC)\nBBB = (DDD, EEE)\nCCC = (ZZZ, GGG)\nDDD = (DDD, DDD)\nEEE = (EEE, EEE)\nGGG = (GGG, GGG)\nZZZ = (ZZZ, ZZZ)\n"}, 4 | {"is": "6", "input": "LLR\n\nAAA = (BBB, BBB)\nBBB = (AAA, ZZZ)\nZZZ = (ZZZ, ZZZ)\n"} 5 | ], 6 | "2": [ 7 | {"is": "6", "input": "LR\n\n11A = (11B, XXX)\n11B = (XXX, 11Z)\n11Z = (11B, XXX)\n22A = (22B, XXX)\n22B = (22C, 22C)\n22C = (22Z, 22Z)\n22Z = (22B, 22B)\nXXX = (XXX, XXX)\n"} 8 | ] 9 | } 10 | -------------------------------------------------------------------------------- /challenges/2023/09-mirageMaintenance/README.md: -------------------------------------------------------------------------------- 1 | # [Day 9: Mirage Maintenance](https://adventofcode.com/2023/day/9) 2 | -------------------------------------------------------------------------------- /challenges/2023/09-mirageMaintenance/tests.json: -------------------------------------------------------------------------------- 1 | { 2 | "1": [ 3 | {"is": "114", "input": "0 3 6 9 12 15\n1 3 6 10 15 21\n10 13 16 21 30 45\n"}, 4 | {"is": "36", "input": "30 26 24 24 26 30"} 5 | ], 6 | "2": [ 7 | {"is": "2", "input": "0 3 6 9 12 15\n1 3 6 10 15 21\n10 13 16 21 30 45\n"}, 8 | {"is": "36", "input": "30 26 24 24 26 30"} 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /challenges/2023/10-pipeMaze/README.md: -------------------------------------------------------------------------------- 1 | # [Day 10: Pipe Maze](https://adventofcode.com/2023/day/10) 2 | -------------------------------------------------------------------------------- /challenges/2023/11-cosmicExpansion/README.md: -------------------------------------------------------------------------------- 1 | # [Day 11: Cosmic Expansion](https://adventofcode.com/2023/day/11) 2 | -------------------------------------------------------------------------------- /challenges/2023/11-cosmicExpansion/tests.json: -------------------------------------------------------------------------------- 1 | { 2 | "1": [ 3 | { 4 | "is": "374", 5 | "input": "...#......\n.......#..\n#.........\n..........\n......#...\n.#........\n.........#\n..........\n.......#..\n#...#.....\n\n" 6 | } 7 | ] 8 | } -------------------------------------------------------------------------------- /challenges/2023/12-hotSprings/README.md: -------------------------------------------------------------------------------- 1 | # [Day 12: Hot Springs](https://adventofcode.com/2023/day/12) 2 | 3 | Before optimisation: 17.13 seconds for part 1 4 | 5 | ![Part 1 before optimisation](p1before.svg) 6 | 7 | After optimisation: 0.80 seconds for part 2 8 | 9 | ![Part 2 after optimisation](p2after.svg) -------------------------------------------------------------------------------- /challenges/2023/12-hotSprings/tests.json: -------------------------------------------------------------------------------- 1 | { 2 | "1": [ 3 | { 4 | "is": "1", 5 | "input": "???.### 1,1,3" 6 | }, 7 | { 8 | "is": "4", 9 | "input": ".??..??...?##. 1,1,3" 10 | }, 11 | { 12 | "is": "1", 13 | "input": "?#?#?#?#?#?#?#? 1,3,1,6" 14 | }, 15 | { 16 | "is": "1", 17 | "input": "????.#...#... 4,1,1" 18 | }, 19 | { 20 | "is": "4", 21 | "input": "????.######..#####. 1,6,5" 22 | }, 23 | { 24 | "is": "10", 25 | "input": "?###???????? 3,2,1" 26 | }, 27 | { 28 | "is": "0", 29 | "input": "#?? 2,1" 30 | } 31 | ], 32 | "2": [ 33 | { 34 | "is": "525152", 35 | "input": "???.### 1,1,3\n.??..??...?##. 1,1,3\n?#?#?#?#?#?#?#? 1,3,1,6\n????.#...#... 4,1,1\n????.######..#####. 1,6,5\n?###???????? 3,2,1\n\n" 36 | } 37 | ] 38 | } -------------------------------------------------------------------------------- /challenges/2023/13-pointOfIncidence/README.md: -------------------------------------------------------------------------------- 1 | # [Day 13: Point of Incidence](https://adventofcode.com/2023/day/13) 2 | 3 | I've got a function that checks vertical lines of symmetry, and to check horizontal ones I just swap the `(x, y)` coords in the grid to `(y, x)` then run it again. 4 | 5 | For each candidate line of symmetry, work out a range that values we need to check (based on which side goes out of bounds first), then for each row in the full height of the grid, count how many rocks are `x` steps away from the line (eg. `.#.|.#.` has 2 rocks 1 step away, assuming the pipe is the line we're checking around). 6 | 7 | For part 1, we just check that no single row has any step within it that doesn't have 0 or 2 rocks. 8 | 9 | For part 2, we make the same check but allow any grid where only a single row fouls that condition. This gives us multiple candidate lines of symmetry for each grid, so we diff it with the as-is case from part 1 and use whatever is new. -------------------------------------------------------------------------------- /challenges/2023/13-pointOfIncidence/tests.json: -------------------------------------------------------------------------------- 1 | { 2 | "1": [ 3 | { 4 | "is": "405", 5 | "input": "#.##..##.\n..#.##.#.\n##......#\n##......#\n..#.##.#.\n..##..##.\n#.#.##.#.\n\n#...##..#\n#....#..#\n..##..###\n#####.##.\n#####.##.\n..##..###\n#....#..#\n" 6 | } 7 | ], 8 | "2": [ 9 | { 10 | "is": "400", 11 | "input": "#.##..##.\n..#.##.#.\n##......#\n##......#\n..#.##.#.\n..##..##.\n#.#.##.#.\n\n#...##..#\n#....#..#\n..##..###\n#####.##.\n#####.##.\n..##..###\n#....#..#\n" 12 | } 13 | ] 14 | } -------------------------------------------------------------------------------- /challenges/2023/14-parabolicReflectorDish/README.md: -------------------------------------------------------------------------------- 1 | # [Day 14: Parabolic Reflector Dish](https://adventofcode.com/2023/day/14) 2 | 3 | Visualisation exists as `out.mp4` -------------------------------------------------------------------------------- /challenges/2023/14-parabolicReflectorDish/digits.txt: -------------------------------------------------------------------------------- 1 | xxx 2 | x x 3 | x x 4 | x x 5 | x x 6 | x x 7 | xxx 8 | 9 | x 10 | xxx 11 | x 12 | x 13 | x 14 | x 15 | xxxxx 16 | 17 | xxx 18 | x x 19 | x 20 | x 21 | x 22 | x 23 | xxxxx 24 | 25 | xxx 26 | x x 27 | x 28 | xx 29 | x 30 | x x 31 | xxx 32 | 33 | x 34 | xx 35 | x x 36 | x x 37 | xxxxx 38 | x 39 | x 40 | 41 | xxxxx 42 | x 43 | x 44 | xxxx 45 | x 46 | x x 47 | xxx 48 | 49 | xxx 50 | x x 51 | x 52 | xxxx 53 | x x 54 | x x 55 | xxx 56 | 57 | xxxxx 58 | x 59 | x 60 | x 61 | x 62 | x 63 | x 64 | 65 | xxx 66 | x x 67 | x x 68 | xxx 69 | x x 70 | x x 71 | xxx 72 | 73 | xxx 74 | x x 75 | x x 76 | xxxx 77 | x 78 | x x 79 | xxx 80 | -------------------------------------------------------------------------------- /challenges/2023/14-parabolicReflectorDish/generate-vis.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -ex 4 | 5 | cat input.txt | python3 vis.py 6 | ffmpeg -y -framerate 30 -pattern_type glob -i 'frames/*.png' -c:v libx264 -pix_fmt yuv420p out.mp4 7 | -------------------------------------------------------------------------------- /challenges/2023/14-parabolicReflectorDish/out.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codemicro/adventOfCode/569c26b209f4f0a8879cac902fc926f0f9515703/challenges/2023/14-parabolicReflectorDish/out.mp4 -------------------------------------------------------------------------------- /challenges/2023/14-parabolicReflectorDish/tests.json: -------------------------------------------------------------------------------- 1 | { 2 | "1": [ 3 | { 4 | "is": "136", 5 | "input": "O....#....\nO.OO#....#\n.....##...\nOO.#O....O\n.O.....O#.\nO.#..O.#.#\n..O..#O..O\n.......O..\n#....###..\n#OO..#....\n\n" 6 | } 7 | ], 8 | "2": [ 9 | { 10 | "is": "64", 11 | "input": "O....#....\nO.OO#....#\n.....##...\nOO.#O....O\n.O.....O#.\nO.#..O.#.#\n..O..#O..O\n.......O..\n#....###..\n#OO..#....\n\n" 12 | } 13 | ] 14 | } -------------------------------------------------------------------------------- /challenges/2023/15-lensLibrary/README.md: -------------------------------------------------------------------------------- 1 | # [Day 15: Lens Library](https://adventofcode.com/2023/day/15) 2 | 3 | * 2 not 315986 -------------------------------------------------------------------------------- /challenges/2023/15-lensLibrary/tests.json: -------------------------------------------------------------------------------- 1 | { 2 | "1": [ 3 | { 4 | "is": "1320", 5 | "input": "rn=1,cm-,qp=3,cm=2,qp-,pc=4,ot=9,ab=5,pc-,pc=6,ot=7\n" 6 | } 7 | ], 8 | "2": [ 9 | { 10 | "is": "145", 11 | "input": "rn=1,cm-,qp=3,cm=2,qp-,pc=4,ot=9,ab=5,pc-,pc=6,ot=7\n" 12 | } 13 | ] 14 | } -------------------------------------------------------------------------------- /challenges/2023/16-theFloorWillBeLava/README.md: -------------------------------------------------------------------------------- 1 | # [Day 16: The Floor Will Be Lava](https://adventofcode.com/2023/day/16) 2 | -------------------------------------------------------------------------------- /challenges/2023/16-theFloorWillBeLava/test.txt: -------------------------------------------------------------------------------- 1 | .|...\.... 2 | |.-.\..... 3 | .....|-... 4 | ........|. 5 | .......... 6 | .........\ 7 | ..../.\\.. 8 | .-.-/..|.. 9 | .|....-|.\ 10 | ..//.|.... 11 | -------------------------------------------------------------------------------- /challenges/2023/16-theFloorWillBeLava/tests.json: -------------------------------------------------------------------------------- 1 | { 2 | "1": [ 3 | { 4 | "is": "46", 5 | "input": ".|...\\....\n|.-.\\.....\n.....|-...\n........|.\n..........\n.........\\\n..../.\\\\..\n.-.-/..|..\n.|....-|.\\\n..//.|....\n" 6 | } 7 | ], 8 | "2": [ 9 | { 10 | "is": "51", 11 | "input": ".|...\\....\n|.-.\\.....\n.....|-...\n........|.\n..........\n.........\\\n..../.\\\\..\n.-.-/..|..\n.|....-|.\\\n..//.|....\n" 12 | } 13 | ] 14 | } -------------------------------------------------------------------------------- /challenges/2023/17-clumsyCrucible/README.md: -------------------------------------------------------------------------------- 1 | # [Day 17: Clumsy Crucible](https://adventofcode.com/2023/day/17) 2 | -------------------------------------------------------------------------------- /challenges/2023/17-clumsyCrucible/tests.json: -------------------------------------------------------------------------------- 1 | { 2 | "1": [ 3 | { 4 | "is": "102", 5 | "input": "2413432311323\n3215453535623\n3255245654254\n3446585845452\n4546657867536\n1438598798454\n4457876987766\n3637877979653\n4654967986887\n4564679986453\n1224686865563\n2546548887735\n4322674655533\n\n" 6 | } 7 | ], 8 | "2": [ 9 | { 10 | "is": "94", 11 | "input": "2413432311323\n3215453535623\n3255245654254\n3446585845452\n4546657867536\n1438598798454\n4457876987766\n3637877979653\n4654967986887\n4564679986453\n1224686865563\n2546548887735\n4322674655533\n\n" 12 | }, 13 | { 14 | "is": "71", 15 | "input": "111111111111\n999999999991\n999999999991\n999999999991\n999999999991\n\n" 16 | } 17 | ] 18 | } -------------------------------------------------------------------------------- /challenges/2023/18-lavaductLagoon/README.md: -------------------------------------------------------------------------------- 1 | # [Day 18: Lavaduct Lagoon](https://adventofcode.com/2023/day/18) 2 | -------------------------------------------------------------------------------- /challenges/2023/18-lavaductLagoon/tests.json: -------------------------------------------------------------------------------- 1 | { 2 | "1": [ 3 | { 4 | "is": "62", 5 | "input": "R 6 (#70c710)\nD 5 (#0dc571)\nL 2 (#5713f0)\nD 2 (#d2c081)\nR 2 (#59c680)\nD 2 (#411b91)\nL 5 (#8ceee2)\nU 2 (#caa173)\nL 1 (#1b58a2)\nU 2 (#caa171)\nR 2 (#7807d2)\nU 3 (#a77fa3)\nL 2 (#015232)\nU 2 (#7a21e3)\n\n" 6 | }, 7 | { 8 | "is": "20", 9 | "input": "R 2 (#000000)\nD 1 (#000000)\nR 2 (#000000)\nU 1 (#000000)\nR 2 (#000000)\nD 2 (#000000)\nL 6 (#000000)\nU 2 (#000000)\n" 10 | } 11 | ], 12 | "2": [ 13 | { 14 | "is": "952408144115", 15 | "input": "R 6 (#70c710)\nD 5 (#0dc571)\nL 2 (#5713f0)\nD 2 (#d2c081)\nR 2 (#59c680)\nD 2 (#411b91)\nL 5 (#8ceee2)\nU 2 (#caa173)\nL 1 (#1b58a2)\nU 2 (#caa171)\nR 2 (#7807d2)\nU 3 (#a77fa3)\nL 2 (#015232)\nU 2 (#7a21e3)\n\n" 16 | } 17 | ] 18 | } -------------------------------------------------------------------------------- /challenges/2023/19-aplenty/README.md: -------------------------------------------------------------------------------- 1 | # [Day 19: Aplenty](https://adventofcode.com/2023/day/19) 2 | 3 | This is not a problem I expected to be able to first-try part 2 for. -------------------------------------------------------------------------------- /challenges/2023/19-aplenty/tests.json: -------------------------------------------------------------------------------- 1 | { 2 | "1": [ 3 | { 4 | "is": "19114", 5 | "input": "px{a<2006:qkq,m>2090:A,rfg}\npv{a>1716:R,A}\nlnx{m>1548:A,A}\nrfg{s<537:gd,x>2440:R,A}\nqs{s>3448:A,lnx}\nqkq{x<1416:A,crn}\ncrn{x>2662:A,R}\nin{s<1351:px,qqz}\nqqz{s>2770:qs,m<1801:hdj,R}\ngd{a>3333:R,R}\nhdj{m>838:A,pv}\n\n{x=787,m=2655,a=1222,s=2876}\n{x=1679,m=44,a=2067,s=496}\n{x=2036,m=264,a=79,s=2244}\n{x=2461,m=1339,a=466,s=291}\n{x=2127,m=1623,a=2188,s=1013}\n\n" 6 | } 7 | ], 8 | "2": [ 9 | { 10 | "is": "167409079868000", 11 | "input": "px{a<2006:qkq,m>2090:A,rfg}\npv{a>1716:R,A}\nlnx{m>1548:A,A}\nrfg{s<537:gd,x>2440:R,A}\nqs{s>3448:A,lnx}\nqkq{x<1416:A,crn}\ncrn{x>2662:A,R}\nin{s<1351:px,qqz}\nqqz{s>2770:qs,m<1801:hdj,R}\ngd{a>3333:R,R}\nhdj{m>838:A,pv}\n\n{x=787,m=2655,a=1222,s=2876}\n{x=1679,m=44,a=2067,s=496}\n{x=2036,m=264,a=79,s=2244}\n{x=2461,m=1339,a=466,s=291}\n{x=2127,m=1623,a=2188,s=1013}\n\n" 12 | } 13 | ] 14 | } -------------------------------------------------------------------------------- /challenges/2023/20-pulsePropagation/README.md: -------------------------------------------------------------------------------- 1 | # [Day 20: Pulse Propagation](https://adventofcode.com/2023/day/20) 2 | -------------------------------------------------------------------------------- /challenges/2023/20-pulsePropagation/tests.json: -------------------------------------------------------------------------------- 1 | { 2 | "1": [ 3 | { 4 | "is": "32000000", 5 | "input": "broadcaster -> a, b, c\n%a -> b\n%b -> c\n%c -> inv\n&inv -> a\n\n" 6 | }, 7 | { 8 | "is": "11687500", 9 | "input": "broadcaster -> a\n%a -> inv, con\n&inv -> b\n%b -> con\n&con -> output\n" 10 | } 11 | ] 12 | } -------------------------------------------------------------------------------- /challenges/2023/21-stepCounter/README.md: -------------------------------------------------------------------------------- 1 | # [Day 21: Step Counter](https://adventofcode.com/2023/day/21) 2 | -------------------------------------------------------------------------------- /challenges/2023/21-stepCounter/tests.json: -------------------------------------------------------------------------------- 1 | { 2 | "1": [ 3 | { 4 | "is": "16", 5 | "input": "...........\n.....###.#.\n.###.##..#.\n..#.#...#..\n....#.#....\n.##..S####.\n.##..#...#.\n.......##..\n.##.#.####.\n.##..##.##.\n...........\n\n" 6 | } 7 | ] 8 | } -------------------------------------------------------------------------------- /challenges/2023/22-sandSlabs/README.md: -------------------------------------------------------------------------------- 1 | # [Day 22: Sand Slabs](https://adventofcode.com/2023/day/22) 2 | -------------------------------------------------------------------------------- /challenges/2023/22-sandSlabs/tests.json: -------------------------------------------------------------------------------- 1 | { 2 | "1": [ 3 | { 4 | "is": "5", 5 | "input": "1,0,1~1,2,1\n0,0,2~2,0,2\n0,2,3~2,2,3\n0,0,4~0,2,4\n2,0,5~2,2,5\n0,1,6~2,1,6\n1,1,8~1,1,9\n\n" 6 | } 7 | ], 8 | "2": [ 9 | { 10 | "is": "7", 11 | "input": "1,0,1~1,2,1\n0,0,2~2,0,2\n0,2,3~2,2,3\n0,0,4~0,2,4\n2,0,5~2,2,5\n0,1,6~2,1,6\n1,1,8~1,1,9\n\n" 12 | } 13 | ] 14 | } -------------------------------------------------------------------------------- /challenges/2023/23-aLongWalk/README.md: -------------------------------------------------------------------------------- 1 | # [Day 23: A Long Walk](https://adventofcode.com/2023/day/23) 2 | 3 | Part 2 is *not*: 4 | * 4717 (too low) 5 | * 4826 (too low) 6 | * 5350 (too low) -------------------------------------------------------------------------------- /challenges/2023/24-neverTellMeTheOdds/README.md: -------------------------------------------------------------------------------- 1 | # [Day 24: Never Tell Me The Odds](https://adventofcode.com/2023/day/24) 2 | 3 | Part 1 is not: 4 | * 1344 (too low) 5 | * 48384 (too high) 6 | 7 | Running this solution requires `z3-solver` to be installed. -------------------------------------------------------------------------------- /challenges/2023/24-neverTellMeTheOdds/tests.json: -------------------------------------------------------------------------------- 1 | { 2 | "1": [ 3 | { 4 | "is": "2", 5 | "input": "19, 13, 30 @ -2, 1, -2\n18, 19, 22 @ -1, -1, -2\n20, 25, 34 @ -2, -2, -4\n12, 31, 28 @ -1, -2, -1\n20, 19, 15 @ 1, -5, -3\n\n" 6 | } 7 | ], 8 | "2": [ 9 | { 10 | "is": "47", 11 | "input": "19, 13, 30 @ -2, 1, -2\n18, 19, 22 @ -1, -1, -2\n20, 25, 34 @ -2, -2, -4\n12, 31, 28 @ -1, -2, -1\n20, 19, 15 @ 1, -5, -3\n\n" 12 | } 13 | ] 14 | } -------------------------------------------------------------------------------- /challenges/2023/25-snowverload/README.md: -------------------------------------------------------------------------------- 1 | # [Day 25: Snowverload](https://adventofcode.com/2023/day/25) 2 | -------------------------------------------------------------------------------- /challenges/2023/25-snowverload/tests.json: -------------------------------------------------------------------------------- 1 | { 2 | "1": [ 3 | { 4 | "is": "54", 5 | "input": "jqt: rhn xhk nvd\nrsh: frs pzl lsr\nxhk: hfx\ncmg: qnr nvd lhk bvb\nrhn: xhk bvb hfx\nbvb: xhk hfx\npzl: lsr hfx nvd\nqnr: nvd\nntq: jqt hfx bvb xhk\nnvd: lhk\nlsr: lhk\nrzs: qnr cmg lsr rsh\nfrs: qnr lhk lsr\n\n" 6 | } 7 | ] 8 | } -------------------------------------------------------------------------------- /challenges/2023/benchmark-graph.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codemicro/adventOfCode/569c26b209f4f0a8879cac902fc926f0f9515703/challenges/2023/benchmark-graph.png -------------------------------------------------------------------------------- /challenges/2024/01-historianHysteria/README.md: -------------------------------------------------------------------------------- 1 | # [Day 1: Historian Hysteria](https://adventofcode.com/2024/day/1) 2 | -------------------------------------------------------------------------------- /challenges/2024/01-historianHysteria/tests.json: -------------------------------------------------------------------------------- 1 | { 2 | "1": [ 3 | { 4 | "is": "11", 5 | "input": "3 4\n4 3\n2 5\n1 3\n3 9\n3 3\n\n" 6 | } 7 | ], 8 | "2": [ 9 | { 10 | "is": "31", 11 | "input": "3 4\n4 3\n2 5\n1 3\n3 9\n3 3\n\n" 12 | } 13 | ] 14 | } -------------------------------------------------------------------------------- /challenges/2024/02-redNosedReports/README.md: -------------------------------------------------------------------------------- 1 | # [Day 2: Red Nosed Reports](https://adventofcode.com/2024/day/2) 2 | -------------------------------------------------------------------------------- /challenges/2024/02-redNosedReports/tests.json: -------------------------------------------------------------------------------- 1 | { 2 | "1": [ 3 | { 4 | "is": "2", 5 | "input": "7 6 4 2 1\n1 2 7 8 9\n9 7 6 2 1\n1 3 2 4 5\n8 6 4 4 1\n1 3 6 7 9\n" 6 | } 7 | ], 8 | "2": [ 9 | { 10 | "is": "4", 11 | "input": "7 6 4 2 1\n1 2 7 8 9\n9 7 6 2 1\n1 3 2 4 5\n8 6 4 4 1\n1 3 6 7 9\n" 12 | } 13 | ] 14 | } -------------------------------------------------------------------------------- /challenges/2024/03-mullItOver/README.md: -------------------------------------------------------------------------------- 1 | # [Day 3: Mull It Over](https://adventofcode.com/2024/day/3) 2 | -------------------------------------------------------------------------------- /challenges/2024/03-mullItOver/tests.json: -------------------------------------------------------------------------------- 1 | { 2 | "1": [ 3 | { 4 | "is": "161", 5 | "input": "xmul(2,4)%&mul[3,7]!@^do_not_mul(5,5)+mul(32,64]then(mul(11,8)mul(8,5))\n" 6 | } 7 | ], 8 | "2": [ 9 | { 10 | "is": "48", 11 | "input": "xmul(2,4)&mul[3,7]rundon't()_mul(5,5)+mul(32,64](mul(11,8)undo()?mul(8,5))\n" 12 | } 13 | ] 14 | } -------------------------------------------------------------------------------- /challenges/2024/04-ceresSearch/README.md: -------------------------------------------------------------------------------- 1 | # [Day 4: Ceres Search](https://adventofcode.com/2024/day/4) 2 | 3 | Part two is: 4 | * less than 1976 5 | * also, somewhat obviously, less than 1978 6 | 7 | Heatmap of the most overlapped locations 8 | 9 | | Part 1 | Part 2 | 10 | |--------|--------| 11 | | ![heatmap 1](heatmap-1.png) | ![heatmap 2](heatmap-2.png) | -------------------------------------------------------------------------------- /challenges/2024/04-ceresSearch/generate-vis.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -ex 4 | 5 | cat input.txt | PYTHONPATH=../../../ python3 vis.py 6 | -------------------------------------------------------------------------------- /challenges/2024/04-ceresSearch/heatmap-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codemicro/adventOfCode/569c26b209f4f0a8879cac902fc926f0f9515703/challenges/2024/04-ceresSearch/heatmap-1.png -------------------------------------------------------------------------------- /challenges/2024/04-ceresSearch/heatmap-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codemicro/adventOfCode/569c26b209f4f0a8879cac902fc926f0f9515703/challenges/2024/04-ceresSearch/heatmap-2.png -------------------------------------------------------------------------------- /challenges/2024/04-ceresSearch/tests.json: -------------------------------------------------------------------------------- 1 | { 2 | "1": [ 3 | { 4 | "is": "18", 5 | "input": "MMMSXXMASM\nMSAMXMSMSA\nAMXSXMAAMM\nMSAMASMSMX\nXMASAMXAMM\nXXAMMXXAMA\nSMSMSASXSS\nSAXAMASAAA\nMAMMMXMMMM\nMXMXAXMASX\n\n" 6 | } 7 | ], 8 | "2": [ 9 | { 10 | "is": "9", 11 | "input": "MMMSXXMASM\nMSAMXMSMSA\nAMXSXMAAMM\nMSAMASMSMX\nXMASAMXAMM\nXXAMMXXAMA\nSMSMSASXSS\nSAXAMASAAA\nMAMMMXMMMM\nMXMXAXMASX\n\n" 12 | } 13 | ] 14 | } -------------------------------------------------------------------------------- /challenges/2024/05-printQueue/README.md: -------------------------------------------------------------------------------- 1 | # [Day 5: Print Queue](https://adventofcode.com/2024/day/5) 2 | -------------------------------------------------------------------------------- /challenges/2024/05-printQueue/tests.json: -------------------------------------------------------------------------------- 1 | { 2 | "1": [ 3 | { 4 | "is": "143", 5 | "input": "47|53\n97|13\n97|61\n97|47\n75|29\n61|13\n75|53\n29|13\n97|29\n53|29\n61|53\n97|53\n61|29\n47|13\n75|47\n97|75\n47|61\n75|61\n47|29\n75|13\n53|13\n\n75,47,61,53,29\n97,61,53,29,13\n75,29,13\n75,97,47,61,53\n61,13,29\n97,13,75,29,47\n\n" 6 | } 7 | ], 8 | "2": [ 9 | { 10 | "is": "123", 11 | "input": "47|53\n97|13\n97|61\n97|47\n75|29\n61|13\n75|53\n29|13\n97|29\n53|29\n61|53\n97|53\n61|29\n47|13\n75|47\n97|75\n47|61\n75|61\n47|29\n75|13\n53|13\n\n75,47,61,53,29\n97,61,53,29,13\n75,29,13\n75,97,47,61,53\n61,13,29\n97,13,75,29,47\n\n" 12 | } 13 | ] 14 | } -------------------------------------------------------------------------------- /challenges/2024/06-guardGallivant/README.md: -------------------------------------------------------------------------------- 1 | # [Day 6: Guard Gallivant](https://adventofcode.com/2024/day/6) 2 | 3 | Part 2 is: 4 | * higher than 456 5 | * less than 1689 6 | 7 | The first implementation of part 2 took 15 minutes to run. 8 | 9 | * Turning `visited_sequence` in `trace` into a set instead of a list cut this to 60 seconds 10 | * Starting immediately in front of the new obstacle when testing positions to put said new obstacle in cut this to 20 seconds 11 | * Removing a load of maps and type wranging to turn the fully generic `gridutil.add` (and counterparts) into a more limited but much faster function took this to ~16 seconds 12 | 13 | Before: 14 | 15 | ```py 16 | def _coordmap(a: AnyCoordinate, b: AnyCoordinate, fn: Callable) -> AnyCoordinate: 17 | at = type(a) 18 | return at(*map(fn, zip(a, b))) 19 | 20 | def add(a: AnyCoordinate, b: AnyCoordinate) -> AnyCoordinate: 21 | return _coordmap(a, b, lambda x: x[0] + x[1]) 22 | ``` 23 | 24 | After: 25 | 26 | 27 | ```py 28 | def add(a: Coordinate, b: Coordinate) -> Coordinate: 29 | return Coordinate(a.x + b.x, a.y + b.y) 30 | ``` -------------------------------------------------------------------------------- /challenges/2024/06-guardGallivant/tests.json: -------------------------------------------------------------------------------- 1 | { 2 | "1": [ 3 | { 4 | "is": "41", 5 | "input": "....#.....\n.........#\n..........\n..#.......\n.......#..\n..........\n.#..^.....\n........#.\n#.........\n......#...\n\n" 6 | } 7 | ], 8 | "2": [ 9 | { 10 | "is": "6", 11 | "input": "....#.....\n.........#\n..........\n..#.......\n.......#..\n..........\n.#..^.....\n........#.\n#.........\n......#...\n" 12 | } 13 | ] 14 | } -------------------------------------------------------------------------------- /challenges/2024/07-bridgeRepair/README.md: -------------------------------------------------------------------------------- 1 | # [Day 7: Bridge Repair](https://adventofcode.com/2024/day/7) 2 | 3 | Part 1 is: 4 | * greater than 450054910499 5 | 6 | Before optimisation (pregenerating then testing operator combiantions using `itertools.product("*+|", length=n)`), run time looks something like this: 7 | 8 | ``` 9 | Part 1: min 0.2671 seconds, max 0.2818 seconds, avg 0.2755 10 | Part 2: min 23.2387 seconds, max 24.8753 seconds, avg 23.8805 11 | ``` 12 | 13 | It also appeared that using string concatenation as opposed to pure mathematical functions for the concatenation operator was marginally faster in Python. 14 | 15 | After optimisation (recursive solves working backwards through the numbers), the run time looks something like this: 16 | 17 | ``` 18 | Part 1: min 0.0214 seconds, max 0.041 seconds, avg 0.0233 19 | Part 2: min 0.0215 seconds, max 0.0273 seconds, avg 0.0229 20 | ``` 21 | 22 | The intial version of this solve is in commit `b2fa4b7`. -------------------------------------------------------------------------------- /challenges/2024/07-bridgeRepair/tests.json: -------------------------------------------------------------------------------- 1 | { 2 | "1": [ 3 | { 4 | "is": "3749", 5 | "input": "190: 10 19\n3267: 81 40 27\n83: 17 5\n156: 15 6\n7290: 6 8 6 15\n161011: 16 10 13\n192: 17 8 14\n21037: 9 7 18 13\n292: 11 6 16 20\n" 6 | } 7 | ], 8 | "2": [ 9 | { 10 | "is": "11387", 11 | "input": "190: 10 19\n3267: 81 40 27\n83: 17 5\n156: 15 6\n7290: 6 8 6 15\n161011: 16 10 13\n192: 17 8 14\n21037: 9 7 18 13\n292: 11 6 16 20\n" 12 | } 13 | ] 14 | } -------------------------------------------------------------------------------- /challenges/2024/08-resonantCollinearity/README.md: -------------------------------------------------------------------------------- 1 | # [Day 8: Resonant Collinearity](https://adventofcode.com/2024/day/8) 2 | 3 | Part 1 is: 4 | * less than 298 5 | 6 | This is not a fully generic solution as, in a situation where the differences between x and y dimensions of pairs of coordinates are not coprime, this implementation would skip steps. 7 | 8 | Visualisation exists as `out.mp4` 9 | -------------------------------------------------------------------------------- /challenges/2024/08-resonantCollinearity/generate-vis.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -ex 4 | 5 | cat input.txt | PYTHONPATH=../../../ python3 vis.py 6 | ffmpeg -y -framerate 30 -pattern_type glob -i 'frames/*.png' -c:v libx264 -pix_fmt yuv420p out.mp4 7 | -------------------------------------------------------------------------------- /challenges/2024/08-resonantCollinearity/out.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codemicro/adventOfCode/569c26b209f4f0a8879cac902fc926f0f9515703/challenges/2024/08-resonantCollinearity/out.mp4 -------------------------------------------------------------------------------- /challenges/2024/08-resonantCollinearity/tests.json: -------------------------------------------------------------------------------- 1 | { 2 | "1": [ 3 | { 4 | "is": "14", 5 | "input": "............\n........0...\n.....0......\n.......0....\n....0.......\n......A.....\n............\n............\n........A...\n.........A..\n............\n............\n\n" 6 | }, 7 | { 8 | "is": "2", 9 | "input": "..........\n..........\n..........\n....a.....\n..........\n.....a....\n..........\n..........\n..........\n..........\n\n" 10 | }, 11 | { 12 | "is": "4", 13 | "input": "..........\n..........\n..........\n....a.....\n........a.\n.....a....\n..........\n..........\n..........\n..........\n" 14 | } 15 | ], 16 | "2": [ 17 | { 18 | "is": "34", 19 | "input": "............\n........0...\n.....0......\n.......0....\n....0.......\n......A.....\n............\n............\n........A...\n.........A..\n............\n............\n\n" 20 | }, 21 | { 22 | "is": "9", 23 | "input": "T.........\n...T......\n.T........\n..........\n..........\n..........\n..........\n..........\n..........\n..........\n" 24 | } 25 | ] 26 | } -------------------------------------------------------------------------------- /challenges/2024/09-diskFragmenter/README.md: -------------------------------------------------------------------------------- 1 | # [Day 9: Disk Fragmenter](https://adventofcode.com/2024/day/9) 2 | 3 | Part 2 is: 4 | * less than 6277851188082 5 | 6272188244509 -------------------------------------------------------------------------------- /challenges/2024/09-diskFragmenter/tests.json: -------------------------------------------------------------------------------- 1 | { 2 | "1": [ 3 | { 4 | "is": "1928", 5 | "input": "2333133121414131402\n" 6 | } 7 | ], 8 | "2": [ 9 | { 10 | "is": "2858", 11 | "input": "2333133121414131402\n" 12 | } 13 | ] 14 | } -------------------------------------------------------------------------------- /challenges/2024/benchmark-graph.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codemicro/adventOfCode/569c26b209f4f0a8879cac902fc926f0f9515703/challenges/2024/benchmark-graph.png -------------------------------------------------------------------------------- /gridutil/__init__.py: -------------------------------------------------------------------------------- 1 | import gridutil.grid 2 | import gridutil.coord 3 | -------------------------------------------------------------------------------- /runners/buildGo.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | TEMPFILE=$(mktemp) 6 | go build -o "$TEMPFILE" "$1" 7 | echo $TEMPFILE 8 | -------------------------------------------------------------------------------- /runners/buildKotlin.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | TEMPDIR="$(mktemp -d)" 6 | FNAME=$(basename $1 | sed 's/\.kt$/.jar/') 7 | FULLPATH="$TEMPDIR/$FNAME" 8 | kotlinc "$1" -include-runtime -d "$FULLPATH" 9 | echo $FULLPATH 10 | -------------------------------------------------------------------------------- /runners/jar.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | java -jar $@ -------------------------------------------------------------------------------- /runners/py.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | PYTHONPATH=. python3 $@ 6 | -------------------------------------------------------------------------------- /templates/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "io" 6 | "os" 7 | "strings" 8 | ) 9 | 10 | func parse(instr string) any { 11 | return nil 12 | } 13 | 14 | func one(instr string) int { 15 | return -1 16 | } 17 | 18 | func two(instr string) int { 19 | return -1 20 | } 21 | 22 | func main() { 23 | if len(os.Args) < 2 || !(os.Args[1] == "1" || os.Args[1] == "2") { 24 | debug("Missing day argument") 25 | os.Exit(1) 26 | } 27 | 28 | inp, err := io.ReadAll(os.Stdin) 29 | if err != nil { 30 | panic(err) 31 | } 32 | inpStr := strings.TrimSpace(string(inp)) 33 | 34 | switch os.Args[1] { 35 | case "1": 36 | fmt.Println(one(inpStr)) 37 | case "2": 38 | fmt.Println(two(inpStr)) 39 | } 40 | } 41 | 42 | func debug(f string, sub ...any) { 43 | fmt.Fprintf(os.Stderr, f, sub...) 44 | } 45 | -------------------------------------------------------------------------------- /templates/main.hs: -------------------------------------------------------------------------------- 1 | import System.Environment 2 | import System.Exit 3 | import System.IO 4 | import Data.Maybe 5 | 6 | type ChallengeReturn = String 7 | 8 | one :: String -> ChallengeReturn 9 | one inp = undefined 10 | 11 | two :: String -> ChallengeReturn 12 | two inp = undefined 13 | 14 | main :: IO () 15 | main = do args <- getArgs 16 | inp <- getContents 17 | _runFn (_selectFn args) inp 18 | 19 | _selectFn :: [String] -> Maybe (String -> ChallengeReturn) 20 | _selectFn ["1"] = Just one 21 | _selectFn ["2"] = Just two 22 | _selectFn _ = Nothing 23 | 24 | _runFn :: Maybe (String -> ChallengeReturn) -> String -> IO () 25 | _runFn Nothing _ = _debug "Missing or invalid day argument" >> exitWith (ExitFailure 1) 26 | _runFn (Just fn) inp = putStrLn (fn inp) >> exitWith ExitSuccess 27 | 28 | _debug :: String -> IO () 29 | _debug x = do hPutStrLn stderr x 30 | -------------------------------------------------------------------------------- /templates/main.kt: -------------------------------------------------------------------------------- 1 | import java.lang.System 2 | import kotlin.system.* 3 | import kotlin.sequences.generateSequence 4 | import kotlin.text.trim 5 | 6 | fun parse(instr: String) { 7 | 8 | } 9 | 10 | fun one(instr: String): Int { 11 | return 0 12 | } 13 | 14 | fun two(instr: String): Int { 15 | return 0 16 | } 17 | 18 | fun main(args: Array) { 19 | if (args.size < 1 || !(args[0] == "1" || args[0] == "2")) { 20 | debug("Missing or invalid day argument") 21 | exitProcess(1) 22 | } 23 | val inp = generateSequence(::readLine).joinToString("\n").trim() 24 | if (args[0] == "1") { 25 | println("${one(inp)}") 26 | } else { 27 | println("${two(inp)}") 28 | } 29 | } 30 | 31 | fun debug(msg: String) { 32 | System.err.println(msg) 33 | } -------------------------------------------------------------------------------- /templates/main.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | 4 | def parse(instr: str) -> None: 5 | return 6 | 7 | 8 | def one(instr: str): 9 | return 10 | 11 | 12 | def two(instr: str): 13 | return 14 | 15 | 16 | def _debug(*args, **kwargs): 17 | kwargs["file"] = sys.stderr 18 | print(*args, **kwargs) 19 | 20 | 21 | if __name__ == "__main__": 22 | if len(sys.argv) < 2 or sys.argv[1] not in ["1", "2"]: 23 | print("Missing day argument", file=sys.stderr) 24 | sys.exit(1) 25 | inp = sys.stdin.read().strip() 26 | if sys.argv[1] == "1": 27 | print(one(inp)) 28 | else: 29 | print(two(inp)) --------------------------------------------------------------------------------