Refactor framework to support more years

This commit is contained in:
Tristan 2021-12-09 22:41:22 +01:00
parent d3cd95aed2
commit 9891975d0f
Signed by: trizz
GPG Key ID: 0A93DEC67165EB47
56 changed files with 1257 additions and 1084 deletions

View File

@ -28,7 +28,7 @@ jobs:
strategy:
fail-fast: false
matrix:
php-versions: ['8.0']
php-versions: ['8.1']
steps:
- name: Checkout code
@ -40,14 +40,14 @@ jobs:
- name: Run PHPUnit tests
run: composer test
psalm:
name: Psalm (PHP ${{ matrix.php-versions }})
phpstan:
name: phpstan (PHP ${{ matrix.php-versions }})
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
php-versions: ['8.0']
php-versions: ['8.1']
steps:
- name: Checkout code
@ -56,5 +56,5 @@ jobs:
- name: Composer install
uses: php-actions/composer@v5
- name: Run Psalm
run: composer psalm -- --output-format=github
- name: Run phpstan
run: composer phpstan

1
.gitignore vendored
View File

@ -2,3 +2,4 @@
/.idea/
/.php-cs-fixer.cache
.DS_Store
/.phpunit.cache/

View File

@ -1,4 +1,4 @@
# Advent of Code 2021
# Advent of Code
In this repository, you'll find my solutions.
@ -6,17 +6,17 @@ In this repository, you'll find my solutions.
## 🛠 Setup and running
- Run `composer install` to install the dependencies.
- Run `./aoc21 {day}` to run the solution for a specific day (for example `./aoc21 1` to run the code for day 1)
- Run `./aoc21 puzzle {day}` to get the description of the puzzle for the specific day.
- Run `./aoc {day} {year?}` to run the solution for a specific day. If year is not given, use the current year (for example `./aoc 1` to run the code for day 1 2021)
- Run `./aoc21 puzzle {day} {year?}` to get the description of the puzzle for the specific day.
- Run `composer test` to automatically validate the solutions.
## 🧩 Add a new puzzle/solution
- Create a directory in `./data` with the correct name.
- Create a directory in `./data/Y??/day?` with the correct name.
- Create `example.txt` with the example values from the puzzle.
- Create `data.txt` with your personal input.
- Create `puzzle.md` with the puzzle. You can use [this plugin](https://github.com/kfarnung/aoc-to-markdown) to easily convert the puzzle to markdown.
- Create a new class in the `src` directory and make sure it has the structure defined below.
- Add this class to the `./aoc21` file, and you can run it.
- Create a new class in the `src/Y??/` directory and make sure it has the structure defined below.
- Add this class to the `./aoc` file, and you can run it.
- Add a new test in `./tests` with structure defined below.
- Run `composer test` to run all the tests.
@ -26,14 +26,19 @@ In this repository, you'll find my solutions.
```php
<?php
namespace AdventOfCode21;
namespace trizz\AdventOfCode\Y21;
// Make sure the classname is correct.
class Day1 extends AbstractCommand
class Day1 extends Solution
{
// Update this to the day number.
protected static int $day = 1;
// Provide the expected results for part 1.
public static int $part1ExampleResult = null;
public static int $part1Result = null;
// Provide the expected results for part 2.
public static int $part2ExampleResult = null;
public static int $part2Result = null;
protected function part1(array $data): int
{
// Solution for part 1.
@ -47,34 +52,3 @@ class Day1 extends AbstractCommand
```
</details>
<details>
<summary>Solution test structure</summary>
```php
<?php
namespace Tests;
// Make sure the classname is correct.
class Day1Test extends AbstractTestCase
{
// Provide the expected results for part 1.
public static int $part1ExampleResult = 7;
public static int $part1Result = 1688;
// Provide the expected results for part 2.
public static int $part2ExampleResult = 5;
public static int $part2Result = 1728;
// Make a new instance of the command with the 'ReturnTestableResults' trait.
public function setupDay(): Day1
{
return new class() extends Day1 {
use ReturnTestableResults;
};
}
}
```
</details>

17
aoc Executable file
View File

@ -0,0 +1,17 @@
#!/usr/bin/env php
<?php
require __DIR__.'/vendor/autoload.php';
use NunoMaduro\Collision\Provider as CollisionProvider;
use Symfony\Component\Console\Application;
use trizz\AdventOfCode\ExecuteDay;
use trizz\AdventOfCode\Puzzle;
(new CollisionProvider)->register();
$application = new Application();
$application->add(new Puzzle());
$application->add(new ExecuteDay());
$application->run();

24
aoc21
View File

@ -1,24 +0,0 @@
#!/usr/bin/env php
<?php
require __DIR__.'/vendor/autoload.php';
use AdventOfCode21\Day1;
use AdventOfCode21\Day2;
use AdventOfCode21\Day3;
use AdventOfCode21\Day4;
use AdventOfCode21\Day6;
use AdventOfCode21\Day7;
use AdventOfCode21\Puzzle;
use Symfony\Component\Console\Application;
$application = new Application();
$application->add(new Puzzle());
$application->add(new Day1());
$application->add(new Day2());
$application->add(new Day3());
$application->add(new Day4());
$application->add(new Day6());
$application->add(new Day7());
$application->run();

View File

@ -1,6 +1,6 @@
{
"name": "trizz/adventofcode21",
"description": "My Advent of Code 2021 solutions",
"name": "trizz/adventofcode",
"description": "My Advent of Code solutions",
"type": "project",
"license": "MIT",
"authors": [
@ -10,21 +10,22 @@
}
],
"require": {
"php": "^8.0",
"php": "^8.1",
"ext-mbstring": "*",
"symfony/console": "^5",
"cebe/markdown": "^1.2"
},
"require-dev": {
"friendsofphp/php-cs-fixer": "^3.3",
"jetbrains/phpstorm-attributes": "^1.0",
"nunomaduro/collision": "^5.10",
"phpstan/phpstan": "^1.2",
"phpunit/phpunit": "^9.5",
"symfony/var-dumper": "^6.0",
"vimeo/psalm": "^4.13",
"jetbrains/phpstorm-attributes": "^1.0"
"symfony/var-dumper": "^6.0"
},
"autoload": {
"psr-4": {
"AdventOfCode21\\": "src/"
"trizz\\AdventOfCode\\": "src/"
}
},
"autoload-dev": {
@ -33,9 +34,9 @@
}
},
"scripts": {
"test": "vendor/bin/phpunit ./tests --testdox",
"style": "vendor/bin/php-cs-fixer fix",
"psalm": "vendor/bin/psalm --no-cache"
"test": "vendor/bin/phpunit",
"style": "PHP_CS_FIXER_IGNORE_ENV=true vendor/bin/php-cs-fixer fix",
"phpstan": "vendor/bin/phpstan analyse"
},
"config": {
"sort-packages": true,

790
composer.lock generated

File diff suppressed because it is too large Load Diff

200
data/Y21/day8/data.txt Normal file
View File

@ -0,0 +1,200 @@
dacefg fegab de dceb bedag dae bcgaefd bdacg fbgcad bgedca | acfebgd de dbagc deagcb
cfgda fdebgc bfcdeag dbg afgedb efbad bg cdfeab gabdf abeg | dbg fbedgca gbea gbae
dgcbe egdafcb bgcfe dgbf cgbafe db ecbfad deb agcde gdbfec | edb bcefgd gdfb edb
fbgad bgedafc dcageb gcfbed bgdfca ebfag df fdg fcad bcagd | gdecfb dbfgac cgabd fd
bacgd dbceg acedgf dgefb dcfbag cgbead edc ce abce bgecfad | abec gdcfea cbdga agbcde
gcbfde gbdfeca ec afcbge egafb cdagb dbegfa ecaf bcaeg egc | egfcdb cgbdfe ebafgc cdfgeb
fgcab efb afgbed deafbgc efgda dbgfce gbaef be fecdga deab | gfbdec bef agdef dabegf
bcaegfd cbgd gb gfb bgdacf egfbad afdcb baecdf cfagb cagfe | gdcb defacb bg baefdg
fgaecb fbad fgdae bedgacf defgc fa fga adcbeg gdeabf egdba | af agfdbce egcfd cgfed
edfa dfbgac egabcf fbadce bcdaf cea gbfceda ae edacb bgced | ae eac dfae aefd
decafb ae dbecg bdgae edfbgc bafgd egbcad fgcadeb cega eba | aedcbf ea eab gcae
bfcge afdc bgaedc egdfc efcagbd fd dgfbae gfd dcgea defgac | ecdfabg efbgc edcfg gcfbe
cgdfa cdaebg acedf egfc cae cfgdba ce bgfedac efbda dfcgea | afegdc fdeca debgac ace
bcef abgec fabeg afbecg bfagd edbcgfa fe egadfc cagdeb efa | bgcdae gcdabe fgbae fe
dgbaf faecbd cafebdg ade cdbfag ae abgdfe agdbe gecdb gfae | ae aed ebdcg dae
bcgdfa bgaf bcf gabcd cfegadb cdfeg degbca bfcead dcbfg bf | acgbdf gabf bcf fcb
cgdfae gfaebd dgfbca cdg dbgca cg cabde fdbga fcbg cdbfega | eagdfc gc egdcfa cbadfeg
gdea acedfgb de deafc fbdca dfe ecdbgf cfage fceagb daegcf | dfeca edf fde gabfce
abecg efc dgbace edcgabf bafec begf edgfac fe cfdab fcbage | defagc dbcaf begf fe
gdecfa ebafc egbfacd fec fdeb geacb ef cabdgf fbdeac cbdfa | cdafb fegcda fagcbde caefb
efgcd abfgedc cgeb eacdfb cdegbf cgf egadf dbgacf dcbfe cg | gcf fgc bcdefg cbaegdf
baefdg egdfc gebcda dae aegcbfd gbadc dgafbc cabe ae geacd | eadgc ea cdgba ae
ba feadcb bedcfga gacef bac egadcf ebgacf cbfgd ebga afbgc | acbegf gcaebfd cagfb fbgac
afdeg fb defb geabc gacbdf ebgadf bfa dacgfeb bfgea fadecg | gbcae fb faecbgd fgdcae
bgedfca agfcbd cbfeg afde dfbage gacebd aedbg debgf dfb fd | cbgdae efbgd gaefbdc cegbdaf
cbeda fgcead dfe ef ecfg cedaf bfdegac fabgde cagdf fdgcba | fecda dgebfac def gfadbe
fde dgecf begcd gfcbae geacf fd efgbcad cadefg cdfa fdegab | df def dcfaeg gfaebd
agecbd fbdag caebdf gefdabc fagbc cbfea fceg agfbce cg gbc | eagfbc dcaebg cbdeaf gc
dbega gbefa aedcgb cebdg dcea ad gda cebdfga gfbced bcafgd | gad cdeabg gda aedc
ebfgac cdbegaf facged dge caegbd gbeda agcbe de dbfga ecbd | dbce dge dcefag defbgac
dfabce dacbeg gfbed bcgeaf afebd fdac debca egdabcf fa afb | abcde cbdaef gabecd dfgbe
cgb fcdab fgeabc bedcgf dceg gcbfd cg defbg bfgdae gcfdeab | gced gdabcfe bdcgf bfagcde
dgcb cdafb bgafd cgfdab adgcfbe cfdae agcfbe cb cab adebgf | dacef baedcgf cdefa cbdaf
ebagcf bgaf gabec daefcgb gcefb fabdce begdca cfb fb defcg | edagbc bfgce bdeacf eabfdgc
eadbcgf bcd befcd fcegd bd agcbfd cbefa fcbeda cafgbe ebda | bdacef efcabdg db dbae
gdecf acfedb fgac degcb gfdea abdfeg fc cfdage fec bdafgce | gcfed fgca cf agfc
bafecg gefac cegfb cea efba dcgbfe dbecga gadfc cbadefg ea | gfcae ea gefcbd afegc
bafe ba dbcae fgcabde bda ebcfdg gcdae gabfdc bcfed fedacb | adegcbf abd eacfgdb cfadgb
afcd geadb bcaedgf acfgb fgdabc cdbefg fbd gdfba fd egfcab | gdeba cdaf gcfba fcdgba
edbgfac bceg fagedb ebfca eb cdeaf gdcfab gcbfea fcbga bea | bedcafg eb abe adecf
cbdfge gabfce edabc bdfcag bcfdg gdef fce fe gbedacf bedcf | ef defg ecf cdbgaf
bafge de ebcdgf dbega bde cadebfg cagfbe acdgb efad gdfabe | decbgfa bfgae gdeacbf ceafgb
cgfdeb adfegc dce ce fgcdb cgdafb cdefgba cdebf gbec dafbe | ce egdfca ec fabde
eabcgf fcgbed bfaedc cabfedg fd gcdfe cdeag fcgbe gdfb def | fde df gfbd efd
aed ebfa gdefab bgfda dacgfb cdgfae ea bgaed debcg gefadbc | bdgfcae dfbga gdebc bfedag
eafdb ceadf fac ebacfg ecdabf fdcabge badc egfadb ca ecgfd | eacdf gfdce bcda cfa
adgecb cf cagf cfdgab abfdc cbf dfagbec cadgb fcgdbe adefb | dbcfa fabdc cfga bcdaeg
bgdcfa fdc bfcaeg gfdea dc gacdfbe fadgc fgbca fbceda bgdc | cd cabgf bcagfd acgfd
defbc gcfbae efg aedg eg cgfbdae cgefd daefgc bafdcg fadgc | gfe gcdfa gfdcba befcgad
bfgeca gcade bec begac afcgbd beaf cgabf be fecdbg deabgfc | eb cbe efgbcd afbe
ebfcd dce fadceb cd gdbafe fedab aedgfc dfbgcae acbd efbcg | edcfb bdaefgc cbegf cefbd
fgbc egcfda bga abcedg cabfgd dbefa abgfd bg dacfg cfdgeba | fcgb aefdb eafcgd agdecbf
dcega dacgbef gbadc dcafeg gdebaf ead ae gbfced faec efdgc | cegfadb acdeg ae dgecf
afgcb adebcg bgdec bcgea dacbefg aeb febcgd egda ae defcba | edcafb gfdceab ea gabfedc
adcge bge agbfcde eafdcb facgeb aecgb gabf fdcegb acebf bg | dcbefg gabcef cbfdge gfcbed
cebdag ace gfdbec gcebd agcde gfacd ae aebg defcab gbdafec | ea fbedcg dbgce eadgfcb
bdaegc eabgcf bgfae bfcag edcbgfa ebg eb geafd gcabfd cbfe | aefgb bge be ebafgdc
cbedgf eabfc gacf gfe bedag gefbcda cedbfa fcbeag fegab fg | fabeg bcefgd fg egfabdc
bdce dfcebg cbf fbgcea bc edcafg dcegf bfgeacd cdbfg adgfb | bfc acbgfe edgfc gfcbd
cedafg ae gfbed eaf dace gdfac dgcbaf caebfgd faegd eabcfg | aedfcg dfgbe ae edbgf
fgcde cdebg cfage dbcf gafdeb baegdc df gcbdfe fed dacgbfe | fd dfe debgc geacf
ed deb dabgf gade aegdfcb cefba abefd dfcgeb bfdagc afdegb | dbe gbadfe gdea de
gbadc gde agced ecagdb ge ecgbdaf cebdgf aebg fadec bacgdf | gde adbgcf aefcbdg cbagd
eadgc gae geadfc cafe ae gdcfa cgebd bcfadg bcdegaf befgda | ecadfg fadgc gedbc gaecfdb
geca ac abgfedc edfcg fdgbce eadcf fagbdc feadb fdeagc afc | dbfea efacd egca cgbadf
fbdca ebcdaf feca fcgbde fba dfeabg gcdab fcebd gefadbc af | dbacf dfecb af bcdag
bfdegc afdgec defgab fcade fdc ebcad cf fbgecad gadef acfg | dcf gfac fcd cgaf
dgfbc badefc cbe aebf dgeabc eb cadef fabedcg ebdfc gdecfa | be dcfbg afced ebgfadc
dfcg degfab dg gcdea cgbefda deacf bceag afdcbe agd edacfg | faedbg gebafd afecd dcaef
fdbe cfeabdg acfbde df dagecf dfabc cagbd fad egfcab efcba | cbfda efbdac bfdca fd
aefdcg bgcda cgedbf eb gdcbaef bdeag geabfd aedfg bge fabe | fgcebd geb ebfa fadegb
aedb dbfca caebf adf ad gbcafed bcdeaf ebcgfa acgedf cfdgb | acefb daf aedb fbcad
ecgdabf fdcge begfca bg dabfec bgfdca abgd bcfda cdfbg cbg | agdb cagefbd cfgdb afdebc
cga ecadfgb gfcd gc fagcbe aedgcf dgfabe bedac fadeg cadeg | gdfc cdgf gcbfae fdgc
ga acdg egfbcd fegcad aeg dbafe fdage eabfcg degfc dafbegc | cdgfbe fegda fbade fcbdage
agdfe dgcaef eb fcdbgae gcdbf deafgb bgfeca bfe egdbf bdea | ebf ebf abde bdgfe
agbef egdf baegdf cdfbag df ebcad bafecgd fedab afd acfbeg | fd decab bedfa feabd
dabcfge ab abge acfeb fdecb bac aebfgc cgdbaf aefgc cadgef | bca fbecga ebcfd ba
feagcb cgdbfe cefdbag dg gdabec dcg ecbga ecdga dgab ecfda | dgc cabegd bdga gebcad
dbfaec gac cgdeab efgcd dfagbce cfabe ag acbgef afegc afbg | ga acebdg bcdefa ag
aegcbd cgfba gbdafce agcdb bfg afgbdc fg fgabed bcefa cdfg | bfg bafgdc dgcf bgf
edcbf gceafd dfbaeg cgefba dafeg daecf aec agdc bfadcge ac | cfbedag eac febdc dagbef
fgadcbe daecg abfd af afg bgfcae fabged gedfa dbefg bgedfc | afg gaf dgfbe gacebf
fgbca cdbfa fgedac cfegb ag agbfdc bgfaedc gac acebfd gabd | dfeacb acg cfdagb eadcbf
fcgeabd beac cfgdba cgfeda bfcdea bfa gefbd ab bfdae dceaf | ab bfdge fdecag dcefab
dafeg bdefac gcebaf gcfbed fdcea cd aecfb dcf ecgbadf acdb | eafgd dfeca acbd egbfdc
cdgfe egc abdefg agfc adecbgf aefdg gc gecdab ebfcd efcdag | gdecf cbefd gecfd gbdafe
edbf fdgbac bcd ecbda bfcead dafcbeg cfeba egbcfa db eagdc | ecdfabg faecb bcdea abfcde
ecfag fcdba cbg adegcf bgef badcge ecafbdg gb fgacb cfbeag | cbg bacfd gacefb cfbga
gafed gbefca bfe badcfge fb dcebga abegc gfabe abcf edbcfg | afbc feb cebga afbc
fedga ecbdgf acef degba dfabgce cdfaeg cgdfe acbfdg af daf | fda gdefac eadfgbc bfeacgd
cd cfd afcged eacfg dfegb cfdeba dagc ecgbaf efdgc cegfadb | cgda fgdbe dcf cfaeg
bdfceg aefgcd bgade gbf acfb bgcadf gfacd bf fdgbace gfbad | bf efgcda ecgdfb dfgace
abecg fdaegcb acdgb cbde edacgf gbdace ec aec cgfdab fbgae | gacedfb eagdfc gaedfc bdcgea
gf cbfeag ebcag bdacge cafed ebgafdc gcabfd begf afg gfcae | fbeg facbdg bgecdaf dcgefba
gfcda gcaefb ad cfedga adc daeg fecbagd dabefc cfbdg gfeac | ad ecafg cdfeag cdbfg
cdbfg deb ebgfd bgfdce cfbgda dcef egfab edbcga gacfbed ed | efdgb fgbcd gcadfeb fdce
fbcaed bgcf fbgdcea gbaec fdebga geb gb caegd cbafe gaebfc | cfgb egb gb dcbfaeg
bged fgdbc ebfcad efacg fed dcgafb dbgcef cgdef cebadgf de | fcdeg gdeb ecfgd gcbedf
adebgf agefd abdgcf dg acfde gaecfbd egbd agd efgab cfebag | fcebagd dagbcf gefda adg
ae fbdea defgb bfecgd bgedcfa eadgfb ebdacg fadbc eab egaf | gfedbc acebgdf bcgade bdgfec
adbfc eacbf abgcef dgfcea eaf faecgbd efgbc dfecgb ae gbae | gafdce gbea ea cdbgfe
cdefg ecbafg fgda cfgea cafbegd acdebg dfceag gd ecdbf cgd | efdcg agfd ecfdg dg
cbdeafg ed bafgde efcd dabfc dfcabe ecdba ead cbeag bagcfd | de cabfed ade eda
dbefagc dfgacb cfegbd fbgdc gbe edbc degfa efbacg eb gebdf | fagbcd bcfdg gbfcad dbce
bfdce de dgaebcf begcf acfdb ecgbfa cedg fbedcg afedgb bed | cbefd fdgbae de bde
ca ace cbdega ecgfd eagbfd acbg bcafde dcgfbea aedgb agecd | ca eca acgb adgce
bc cgb acfb dbcgfea bdecgf gfadbe abgfd eacdg fbcdag bdgac | fcegbd bcg cbedfg badgcfe
ag gbefac cdebg bdceaf cdbfaeg gcadfb gaceb gab agef cabfe | fcgadbe cagfedb ebfacd ga
fg gaced gdcafb egacf cbafge fgdabce fbge bfaced cabfe gcf | beafcd eafgc bfcea bgcedaf
eafdc cedbfa dcaegf fcg fcbega ecfgd bgcdfea afgd fg ecdbg | facged fg ecfda dgfa
fb badcg eadgfb bdgeac fdbcg bfg fcdagb bgcdefa efgdc abcf | bgf bf gaedfb bcaf
dbcag da bgdce afcd gacdbfe cagfb gabcfe adg cbdagf begdaf | da cgdba bagfec da
dgcbf cfbe egf ecdgfa bcedgf adbcfge degab fe bedgf cfdbga | fcdgbe agdcfb fe fe
dacegbf afgec fgbdec degfa eacfgd gdbfae gec gc efcba gcda | dbagef cdbgef dfaceg degcfba
ecbdf gfced bcaf fabgecd egbcda gfbade bc bce cbeadf debaf | bdface afdgbec cb aefgbd
gefab cafdge db edfgc bcgd fegbd cabedf cabefgd cbedfg bed | bgcd fcdeg gafbedc fcbgeda
cdbgfe gadcb afbdeg gfdbc gedfb dcfgea fbagdec befc cf dfc | bfdge acgebdf cdf decbfg
egdc fgcbae cbg adbgc gbcdeaf cg aedfgb bdafc ebdag abecdg | daebgc gbdeca gc gdabce
fdb fbacgde befda fb bfec cdgaeb aedcb afbcde agcdbf fegda | bfd fdb bcfaed eafgd
eagfc dgba faged gdf gadfcbe dg dafeb cedfgb ebadgf edabcf | egadfb agbd bagd badgfe
cgdbfe cfdabeg fcdbga edabg af bdecaf aecf daf fdbea cebfd | af af af ecaf
cdgabe dafegbc gbedc cbaed gbe ecdfg bg gdab baegcf deafbc | bg bge cebgafd dabg
ef afe facbged adcfg cfebad dgef gfcdba acdgef fgeac aebgc | badecf dfge gdacf gedf
fedcbg gcdb gbecf dbagef fdb cabgedf aecgfb dfceb adecf bd | cgeabf egfcb db fbecga
ceadgb fadbe fdbgea ac cdfa afdegcb abcef ecfbad eac cbefg | fabde ac bafcde abdfe
dcg dgfab beadc fgac dcgefb dafbgec agdcb cg facdbg afgbde | gdc cfga dgfebac adebc
ecgab eacbf acf dafbe edbgca gedfcba caefbg cf fcgb fcdgea | fbdaecg gdeabc cfa gbfc
acgbf cedbg cfebg fecagb fcgeda ef gfe befa fagecdb gfcadb | egbfc gedcfa egdcb egcbd
abecd bf acfegd dafcb cfb gcafdb fbgd cgfad befcdag fgeabc | bfc dfagce cfdba acebfdg
gdf egabfc ebgfa gaedfb acbfd agde fbeadgc gbdcfe gabdf gd | agbcef fbgdace gfd gd
bdge ge fcdgeba gaceb cdabef bcfga aegfcd egc bdcage adecb | eg dbfgcea ge ceg
gefbd gce cedf becgfa acbdg bgcfde bcedg egbadf ce gacbefd | gbfde ecagbfd cge cdef
fed dfbegca gdaec abdgce fgedac ef afcdb faeg ecbgfd dface | dfagec gefa cebagd faeg
acbfd facbdg badgcef ecb fdegb cdea bdfce cbfade ec afbgce | bagecf ebc dcbfe efcabdg
be cdgeaf bfcgd gcfabed gcabed abgedf bdgce aecgd caeb edb | gdfcb eadcg gabdce ebd
bfegcad abdgc cebdag cg caeg cfdebg gcb degbaf adegb dcafb | bgc aceg cabdge debfgac
eg fcbae fgabe fgcade gbfad dgbe edacbgf fgdbac fge dfeagb | gadbf abdgf gadbef fabeg
aegfcd eba fbacd be ecgb aegcd cdgeba aedcb agcebdf fgedab | ebgadc dfagbec cdgae bdfeagc
fcdgeab aef bedfag fbadc gaebdc dgaecf feacd fe egcf dcgae | gaced fe ecdgab bfdca
egdba baecfgd debcaf gb gcfbed gecda fdgbea bgaf bdfae egb | gfdeab gb gbe ecgda
ecgab adbceg cegfbd ceg gacd ecgbdaf fgeba acbde cdfabe cg | dabecf cgbdea fdabecg bfaecgd
fcbg egdaf dbecfa abgec feb begadc eagcfb gbefa cgfdeba fb | fedga dfbceag cegafb efb
fe agdbcfe eafgdb fae dceabg eafgcb fcadb agedb dafeb fgde | fdeg adcgeb fe deabcgf
ebfgd ad abdgf ebcgfa fdaebc dba cadegfb gcda bafdcg cabgf | gdfab cbdgaf abgfc fagdb
eadgfc gdbfca fgcbaed bcdg cg cgf gdbfa egfbda fcabe cbfga | gc gabfd fcg afecb
acbefgd fgcdab bcga fgdbc fdabe fdbceg acd fcbad eafdcg ac | ca aebcfgd cfbdg cbga
beacfg ecafgd fdcbg fd gcbfe dcf efdb fcgdaeb adgcb ebdgcf | fecagbd dabcg fd fd
ecfga fcdbae afgebc egdfa cae fcgedba bgac ca bfceg cdfbeg | agdfe gcebf afegc bacgfe
cafebd gfebca dceaf eabfc efbagd faedgbc abdc adf ad fcgde | cbad badc gcefd cbegfa
fgdbc beca adc cbgead bdgae cfagde dfgecab gcdab afbedg ca | agbefd ac dac abce
ecbdaf geadbc cfdbe fcdgabe adfcg ge ceg gcdef fegb fbcegd | cfdabe gdfce ecbfd ge
baegfd cadgb gdcfb agec dcgaefb bcagde edgab acb ac ebfdac | agdbef bdaecf ac egca
dbaec eadcg ga gadceb gcedf cga ecbfagd acbdgf bgea eafbcd | daegc ag cga afcgbd
daefbc bdeacg bacdg gdcfe egab becdg bce acdebfg fbadgc be | cagbed ebcadg aecbgd dbgafce
bfedagc gbafcd fead eafgc ef cfadg edfcga fce dgcbfe caebg | ef fcadg ef edaf
fadgce egc fegda dafgbe dcabg gceda ce gcfbdea agbfce defc | egacd gecadf febcgda abcgd
egcdf cagedf bacef bdcgefa bd cbfdga ebdcf fbd bdefgc gdbe | becaf efbdagc cdaebgf cfbed
faebd ebdfga fagced fe gbfad dcbfga eaf egfb cgedafb ebacd | eaf efgb baecd efa
bdega edaf fabdge fe dfebg cgefab gfbdc dcabge gcedbfa fge | cegbda defa feg agbed
gdecaf defbg acgdeb badc gcaed fbaceg afdebgc ebc cb gdbce | cb bdceag bc dcbge
bgfc agdefc dgabcef fegca eadcb bg gbfdae gbe cagbe cefagb | gb ceafg bcega gb
cgb cg efabc dbaecfg cbedfg bcefg ebagdf gfdc debgf deabcg | fgbed ebgcad fedgcab cgbfe
fecad egdfbc gadcfe eagfc aebcg fdag feg fecdab aedbgfc gf | gfe dfag cgbdfe gfcdeb
gadfce bcadegf fcged cafbg bd dcgbfe dgb dbec dgbfc beagdf | bgd cgfbde bcfga gfdbc
gdecbf efg fbcgae cfeadbg geab cagef gadfc eg bafedc cafeb | egf fgaec becfa gcefa
bcf eadcbf dcfeb cegbd bfea gdcafb efcad cadefg gfbeacd fb | fb cfgaed eabf afebcd
ebcdag bgaefdc aegf eg fgebc dbecaf abcef beg cbafeg fbgcd | afecbg feag efag bdfcea
cadfbe cgba cb cgadfe acgdf fbdcg bcf fcabegd fedbg gbafdc | eadgbfc faegcd bfc cabg
bcgefd fcabg dafgcb cadfe fadcb dbf bd gcdebfa cfgabe dagb | cadfb eabcfg gbafce gcabdf
dcegfb efadbc fceabgd dcab db beafc abefgc agdfe fbaed bdf | dcegafb dfb bfd fbd
abe be faced fegb cabedg dfabe adfbge cfaebdg gbdaf fcgbda | eagdfcb egadfbc adfebg agfbd
cgaefdb cedgfb dcfbe gef gabfde fbagc fgbec gcde ge bdafce | dafecb ge gfe efg
edgaf defbagc edcbfa cd cbgd cegad cde afegbc gcebda abegc | badcfeg cde fadge fbdcae
abgfec abfe acf ceagf baecdg dfecabg fa afgdbc agbec dfgec | acf fa af afceg
ebgfda deafbc bcedg adcgbf fagdb afcg gdbfc fdc cf fdgaceb | feacdb fcag fcd dbefac
gdfba de dbgefc ecdf dceagb dgefb cbgfe dbe gabfced ecgfba | efdgb feacgb egabfcd gfbde
fgad gac bgcfae dgcfbae ga dfgcb begdcf abgcd cdeba bafgdc | agdf ag cdgfb ag
efbcd efda fdbacg fe bdcaf feb gdcbe bgaecf dcfbgea fcbeda | fe ef becgd cebgd
dgefbac de decb abfdg dacegf gde cbegf efbgd gfbdec cafebg | fecgab dbec de dafgb
gec bdcfea gbdfe gc fdabgec bgedac adbec agbc ebgdc afgcde | cagb gecabd bfedac abcg
cf cgdea cdgfe egdfb dcf dafcbg fbce eagfdb dcfegb bdcgeaf | fceb fdc fcbe efcb
bcdga cgb bacf gcafdb cfgbade baegd bdcfeg cdafg gaecfd bc | dbgae gbcfda acgdb fbac
fgcdae geacfb gd cdefb dbfgea bdga defgbac fgd febga gfbed | gfd ebcfag dfgbe dbag
bdeag fedab cafgeb gb decbag gbe bgcd dcgea fgdcae ceagfbd | cfgebda ebg cfaegdb gdbc
fdebac cb bface agbcfde befcgd ecb dacb efcad bagef caefgd | eadbgfc dbac ecb egfab
bdcea cbgfead dfc ecfb efgdac fc bfdac edbcaf dfbag cgdaeb | fc edbgacf cf dagecf
bdgfca abegfdc fdg abfceg dafbge gacde agcdf fdcb df bagcf | fbcga ecgabf bcfd df
befcadg ce bdfgce cbed fce fecgb gefacd bafeg gfdcb gbafcd | ebdc bgfce gfedca ecbd
fbgce abgefd ecdfga abfc efcgba bdecagf abfeg dbgce cf cfe | fec bgdaef bcfge ebdfcga
cgfdba dbcegf gac fadeg ca fcab gdaceb dafgc bdgfeca gdbfc | adcfbge gdfca ecgabd ebadcg
dcaebf gfdceab bd ecbgd egacb cedgf bed dfgb fgadce ecfgdb | bgdcfe cdebg gebdc dbe
dcbae aecgbd daebcf cbefag adgc ag dabeg aedgbcf gea egbfd | badcefg gefdb dacbe dgac
fgcdbae cagfd de eagcbf cbaedf gebd edf dgecf cgbdfe ecfbg | afcdeb fed dbeg efd
adbec bdecfg adbcegf fd ebfcd gdbaef efd cbfgea cdgf cfbeg | befgc ebdfc gcbfe bgefc
fadbg aebgfcd edgafc ebdfac dbe efcad be agcdbe fceb dfbae | agcdeb bfec fceb cbef
fcged gfbdec adebf adc cage adbefcg caefd ac cbfagd efagcd | ecgafbd dac ca gfcbed
gcdba fecgd gfdceb dgeabf af facgd feca aegfdc ecabfdg dfa | fcdga adbgef cadbfge daf
afdec faebc bdea fgbcad efdgca ba egdbfac fcegb cba acfebd | cebfda bdae adeb abde
defgca efgbadc ecgba gecbfd db dabegf aebdg gdfae deb adfb | dcgaef edb bed becgdfa

10
data/Y21/day8/example.txt Normal file
View File

@ -0,0 +1,10 @@
be cfbegad cbdgef fgaecd cgeb fdcge agebfd fecdb fabcd edb | fdgacbe cefdb cefbgd gcbe
edbfga begcd cbg gc gcadebf fbgde acbgfd abcde gfcbed gfec | fcgedb cgb dgebacf gc
fgaebd cg bdaec gdafb agbcfd gdcbef bgcad gfac gcb cdgabef | cg cg fdcagb cbg
fbegcd cbd adcefb dageb afcb bc aefdc ecdab fgdeca fcdbega | efabcd cedba gadfec cb
aecbfdg fbg gf bafeg dbefa fcge gcbea fcaegb dgceab fcbdga | gecf egdcabf bgf bfgea
fgeab ca afcebg bdacfeg cfaedg gcfdb baec bfadeg bafgc acf | gebdcfa ecba ca fadegcb
dbcfg fgd bdegcaf fgec aegbdf ecdfab fbedc dacgb gdcebf gf | cefg dcbef fcge gbcadfe
bdfegc cbegaf gecbf dfcage bdacg ed bedf ced adcbefg gebcd | ed bcgafe cdgba cbgef
egadfb cdbfeg cegd fecab cgb gbdefca cg fgcdab egfdb bfceg | gbdfcae bgc cg cgb
gcafb gcf dcaebfg ecagb gf abcdeg gaef cafbge fdbac fegbdc | fgae cfgab fg bagce

136
data/Y21/day8/puzzle.md Normal file
View File

@ -0,0 +1,136 @@
# Day 8: Seven Segment Search
[https://adventofcode.com/2021/day/8](https://adventofcode.com/2021/day/8)
## Description
### Part One
You barely reach the safety of the cave when the whale smashes into the cave mouth, collapsing it. Sensors indicate another exit to this cave at a much greater depth, so you have no choice but to press on.
As your submarine slowly makes its way through the cave system, you notice that the four-digit [seven-segment displays](https://en.wikipedia.org/wiki/Seven-segment_display) in your submarine are malfunctioning; <span title="Yes, just the four-digit seven-segment ones. Whole batch must have been faulty.">they must have been damaged</span> during the escape. You'll be in a lot of trouble without them, so you'd better figure out what's wrong.
Each digit of a seven-segment display is rendered by turning on or off any of seven segments named `a` through `g`:
0: 1: 2: 3: 4:
aaaa .... aaaa aaaa ....
b c . c . c . c b c
b c . c . c . c b c
.... .... dddd dddd dddd
e f . f e . . f . f
e f . f e . . f . f
gggg .... gggg gggg ....
5: 6: 7: 8: 9:
aaaa aaaa aaaa aaaa aaaa
b . b . . c b c b c
b . b . . c b c b c
dddd dddd .... dddd dddd
. f e f . f e f . f
. f e f . f e f . f
gggg gggg .... gggg gggg
So, to render a `1`, only segments `c` and `f` would be turned on; the rest would be off. To render a `7`, only segments `a`, `c`, and `f` would be turned on.
The problem is that the signals which control the segments have been mixed up on each display. The submarine is still trying to display numbers by producing output on signal wires `a` through `g`, but those wires are connected to segments _randomly_. Worse, the wire/segment connections are mixed up separately for each four-digit display! (All of the digits _within_ a display use the same connections, though.)
So, you might know that only signal wires `b` and `g` are turned on, but that doesn't mean _segments_ `b` and `g` are turned on: the only digit that uses two segments is `1`, so it must mean segments `c` and `f` are meant to be on. With just that information, you still can't tell which wire (`b`/`g`) goes to which segment (`c`/`f`). For that, you'll need to collect more information.
For each display, you watch the changing signals for a while, make a note of _all ten unique signal patterns_ you see, and then write down a single _four digit output value_ (your puzzle input). Using the signal patterns, you should be able to work out which pattern corresponds to which digit.
For example, here is what you might see in a single entry in your notes:
acedgfb cdfbe gcdfa fbcad dab cefabd cdfgeb eafb cagedb ab |
cdfeb fcadb cdfeb cdbaf
(The entry is wrapped here to two lines so it fits; in your notes, it will all be on a single line.)
Each entry consists of ten _unique signal patterns_, a `|` delimiter, and finally the _four digit output value_. Within an entry, the same wire/segment connections are used (but you don't know what the connections actually are). The unique signal patterns correspond to the ten different ways the submarine tries to render a digit using the current wire/segment connections. Because `7` is the only digit that uses three segments, `dab` in the above example means that to render a `7`, signal lines `d`, `a`, and `b` are on. Because `4` is the only digit that uses four segments, `eafb` means that to render a `4`, signal lines `e`, `a`, `f`, and `b` are on.
Using this information, you should be able to work out which combination of signal wires corresponds to each of the ten digits. Then, you can decode the four digit output value. Unfortunately, in the above example, all of the digits in the output value (`cdfeb fcadb cdfeb cdbaf`) use five segments and are more difficult to deduce.
For now, _focus on the easy digits_. Consider this larger example:
be cfbegad cbdgef fgaecd cgeb fdcge agebfd fecdb fabcd edb |
fdgacbe cefdb cefbgd gcbe
edbfga begcd cbg gc gcadebf fbgde acbgfd abcde gfcbed gfec |
fcgedb cgb dgebacf gc
fgaebd cg bdaec gdafb agbcfd gdcbef bgcad gfac gcb cdgabef |
cg cg fdcagb cbg
fbegcd cbd adcefb dageb afcb bc aefdc ecdab fgdeca fcdbega |
efabcd cedba gadfec cb
aecbfdg fbg gf bafeg dbefa fcge gcbea fcaegb dgceab fcbdga |
gecf egdcabf bgf bfgea
fgeab ca afcebg bdacfeg cfaedg gcfdb baec bfadeg bafgc acf |
gebdcfa ecba ca fadegcb
dbcfg fgd bdegcaf fgec aegbdf ecdfab fbedc dacgb gdcebf gf |
cefg dcbef fcge gbcadfe
bdfegc cbegaf gecbf dfcage bdacg ed bedf ced adcbefg gebcd |
ed bcgafe cdgba cbgef
egadfb cdbfeg cegd fecab cgb gbdefca cg fgcdab egfdb bfceg |
gbdfcae bgc cg cgb
gcafb gcf dcaebfg ecagb gf abcdeg gaef cafbge fdbac fegbdc |
fgae cfgab fg bagce
Because the digits `1`, `4`, `7`, and `8` each use a unique number of segments, you should be able to tell which combinations of signals correspond to those digits. Counting _only digits in the output values_ (the part after `|` on each line), in the above example, there are _`26`_ instances of digits that use a unique number of segments (highlighted above).
_In the output values, how many times do digits `1`, `4`, `7`, or `8` appear?_
### Part Two
Through a little deduction, you should now be able to determine the remaining digits. Consider again the first example above:
acedgfb cdfbe gcdfa fbcad dab cefabd cdfgeb eafb cagedb ab |
cdfeb fcadb cdfeb cdbaf
After some careful analysis, the mapping between signal wires and segments only make sense in the following configuration:
dddd
e a
e a
ffff
g b
g b
cccc
So, the unique signal patterns would correspond to the following digits:
* `acedgfb`: `8`
* `cdfbe`: `5`
* `gcdfa`: `2`
* `fbcad`: `3`
* `dab`: `7`
* `cefabd`: `9`
* `cdfgeb`: `6`
* `eafb`: `4`
* `cagedb`: `0`
* `ab`: `1`
Then, the four digits of the output value can be decoded:
* `cdfeb`: _`5`_
* `fcadb`: _`3`_
* `cdfeb`: _`5`_
* `cdbaf`: _`3`_
Therefore, the output value for this entry is _`5353`_.
Following this same process for each entry in the second, larger example above, the output value of each entry can be determined:
* `fdgacbe cefdb cefbgd gcbe`: `8394`
* `fcgedb cgb dgebacf gc`: `9781`
* `cg cg fdcagb cbg`: `1197`
* `efabcd cedba gadfec cb`: `9361`
* `gecf egdcabf bgf bfgea`: `4873`
* `gebdcfa ecba ca fadegcb`: `8418`
* `cefg dcbef fcge gbcadfe`: `4548`
* `ed bcgafe cdgba cbgef`: `1625`
* `gbdfcae bgc cg cgb`: `8717`
* `fgae cfgab fg bagce`: `4315`
Adding all of the output values in this larger example produces _`61229`_.
For each entry, determine all of the wire/segment connections and decode the four-digit output values. _What do you get if you add up all of the output values?_

100
data/Y21/day9/data.txt Normal file
View File

@ -0,0 +1,100 @@
0198954334976942239109321545998999878998764656978999349899965478954987432389012356989932123998432123
1997943129865890198998910239867899967999873249865988998799896567899876543478925689879899019896421012
9886895997654789987987891998756898656987654598774877897545697878912988654567934598767688998789432123
8765789869763567996545789876545999768998798797653656796536789989543499867688955697654567897678954235
9876898753212456989434679987976789879239899898542348987421568997699989878999896898753656797569765376
0987899854901345678923478998987999989998975959643459876542456789988978989998789999842349899678997487
2398959769892957789012467899898999899897654345987678987543567999876767897987678898761018999789998598
3599549898769898993123458987639998789789532123498989898654698999965459975698545789983567899899987679
4989432999656799654364667996521989598678944234989796789765789798754368964679657899894589989999898791
9879949897545678967975878989432978436567954349876535699977997679854234943569869998765999879989769890
9867898765434589878989999578999767323457895456995323798989543569542123899699878909879876768678953989
8757989987645678989092123489987656212345889679899213997999432198654235678989989212998875654569769979
7645678998656789299297334569876543101345678998778939876898954569764345989678994323497964323468998767
1534578999767899198986586679987764512387989876567898765457895678985469994569765434596543212356789156
0123467899898978987897898899998975643478995965479986543234999789876598989678998645987632103568993245
4235678979979569876789919968999997856569654987567895432155679896987897878989679876898545314789754766
5546789765765459984568923459987898768679653498689976621019989954398986567893498989987695424898769889
7856797654432397213467894698876569878789432398798986543198895432129875456912987698998986546789878996
9768899843101976434688999987766456989998953789897897654987789843299764347799654567899797656789989645
9878998754233987549789988996651238898767895678956798969976699754987643235678965678987659878999993234
7999899965654797679895677965430356789456976799347679998764568967999654016889986789876542989569892129
6986789876795698989923456894321246794239897893234578976543487898998765127999999899987821093459789098
5435667987986999999874567896534356789949789921015679895322346789019976238989899999876542912998678997
4323459899897898998965678997647467997898679933234599797401367898923987349976678989987669899876467896
3212998789789987987989789398766567896976568899545988689212456897945698967895457978999798767987679965
4309875646678996556899891249877899954320446798959876578999567976899789879964349865789899654598989334
3219554234569219434989954398988921967431234567898765467678978965789893989998599974899999543499793212
4997432123678998999879765987699999876546346788999985336589989994896902498987678989989998932987654329
9876543245989987889968999876543989987687897899999896213467999876895213567898789299765987821298775678
8987854556894345678956789998679876999798998999889798101578910987894394678939891019873496532999896799
7698976677954234599745699998798884899899329998765689313489421598965989899423932198921987649899989890
6549987988943123689656789899987653668993210987654569986578932349896978989214949997532398999768878921
7756798999431012698769998789776542557989421297643467899789543456799869878929898889543459987653567992
8987899998999243459898789698654421345678932398654578979899956789987659767898787678999767998542456789
9898968997988954568965698598793210156899645469767699467989897899897745656989654589988978987631375699
8769656986567897679654596439987921367998756899878789359878789998765432345679543598767899997410134789
9954249987456898989768987521986434456789867987989992198767678999876521349889901987543339876321245679
9865198765345689199979765430987545768999998946797893987654597898765435478999893976432129865434357889
9991029984296891019999876542398969899998999235986789976543656799876556569998769896554239876545667998
8789129876989932998945989653989898989987898949875696989652345789987987678987657789665445987676878957
8688999999878949877896798799765787679896767898754245799921235689298998789876546678989589998989989545
7567989987857899765679979987654567589765456789876126999832367893109459899997434568997678999898998734
5499879765436987654569865598743423469876877896521099898753456954212345999998528678998789987787899949
6987656976524599543678954329832102378989988965433987659864869896793469998999838989899899876576999898
9998767897434598956789765497643236899993499977654976540975998789954598987898646898765998765445899656
8999879976545987997899876987654345678901943988779765321986989697899987876789757999954239654325678945
7786989997659576889978998998785459789219892399889898732399878545678976745699768998932199867214589656
6565799989897465679567899999897878994329789902999987543498767435699765434567978987893987654323578997
5444679878986323493456789988998999789998678893498998684569854324589854315779989876789998875634699398
6323498759875437894667899976549446699876558789976439795698765416678952104567899865698999987849893249
3212989643986556789988999895432234579987345679765429898789876527899543212388998764587992198967910123
5459876532398767993299998794320123992392136789975212969899998678987656623499987653376789349978921235
6597954321239878932134987689321399889989015699894353459999598789798787536567899762165567999989932446
7986543210157989321029876578932988779678923456789877678998439896689876547679959854013456789299873457
9797676521238996432134965489549976567567894578897998989987510975468989658789749862134567892198765678
4598997432347896543549876379698765456456789679986549999899329876349898778895539879345679943999986899
3569986543456789656867976568999866331345678989995434987679949983299769899984320987656997899892197975
2345698754578999767979498689987653210234899998976219876569898654987653969865421498767896798789998944
1236999885679789998989239795498769329946789877894398765498789769765432358977432389878975434569899432
0349899976789678999894349892349898998897898966965987654397689879877841237898743467999664313467789901
1239798999894589998765956901467997987789956645899899765298797989998930356789654569876543201234569892
2998667899923458929879899892568985465678943234789678953129896595699321268898789678987654562365698789
9876545798912347912998789789879875323489432123596567891012999434987532379999898799498765684578987678
9988432977893456894989645678998763218796543034789437789234678929876543456789959989329876795789876567
9895431866789579999876534569899953105689656546797645678945799101987854579899349878912989897899865456
8765310145689998999998321345798767214578998687899856789996893212398965699998969769653499998912976367
7654321234567896789874210127789874323789998788967967892987894323569879789987898758994689579201985458
8765432365679944598765331235699985434899999899459878921998995437689989891976789347889793459399876769
9878944456989533459876452346789996546789896912345989439899986568789299932987894236778965998988987878
0999876567895421246986567487997897657899774101236799598788997679892109893498956124568999876267898989
1989998698996730178987878998976798768987653212345678987697898793999298789569743013456789994348939996
9878999789987541359998989659365679899987654323657799986576799892398997678998652124567893986789129895
8767899893496432499899997643234899999998765434567899975425678901986554599998543236899964799891098796
7654698921297543987789999832123789998799886865678949876534799999876423678987654545678975678942989689
9543567890987665996578898753435678987689997976789421987646789987654213589998778659899986789659876548
8912478999998789875466789766576789986579999987896610198757891098785344567999899789967997898998998957
7894567898999896984345678987687898765459892199965423459868989129887895678999929892158998987897899868
6789789987899934986456789298998949654328789013986594569879578934999976899889012999349989675876789979
4899998756789915698567899129989939869212578923987989978989459899653987897678929998959876543365679989
5999897647897896987678988999867899998923459994699677899392398798942398928568998997899985432124567890
6898765530146789999789567989654678987995767989987566789210987687890999312456987976899899321013479931
7919654321237898989892379878943569895789999878976455899391296566799889202369876345697778934154567899
8929865445356987579954998769892398784679889767895324988989987434789768943459965237986567953245679978
9934986656767893467899877555679989613498767856991015976568986523598546899698954356975468967456789767
9899997768978922279923965434568976501987845345689129896459876434987656998987895479864357978697997656
8767898989989210189109874323457898319876431234568999765345987845699767897796989599865267899789996545
7656899591095332398998765446568987634986545489679988653236798956789878986675978987654356789899989326
8767999432986745567899976757678976545697657567989876542124569979892989965434567898865468993999878939
9898998993987857898967987878789989656789967979399986321013456989901399876512367899979878921298769998
2999987789998969999458998989896799778999878989298765442134567895313567985403456897989989942987657897
1298986678999878998569769997955459889901989892129876653485698989494579875314567896998796899996545956
0987854567999999987678956976545368999892398763012989764578789876989989994323698965789545678989434345
9876783456889323498789543989631259999789987653135699876689992345678999985554789654678924579879921267
9965432345679212589896532398920345987678998774256789987799101256799339876765896532467896798768895348
9876543456798954679987421987934599793589998765345678998898942349989212989876897651278999986545789458
3998654567897799798899910986899987654678939978458799769987895498968999995989965432345698765435679567
2198777679976687987678891965678999769899212989569897654216789987654678954399877643567899654323569678
1019888789465456986546779878999239878989103498678998765345678999543789967894998654689998795434578989
2123999994312349876534567989654347989378915679789329876557789987654567898923498765891019986795989295
3235986543201456987677678999987656896567923899893212998768994399765678999434569978943523987886892123

View File

@ -0,0 +1,5 @@
2199943210
3987894921
9856789892
8767896789
9899965678

78
data/Y21/day9/puzzle.md Normal file
View File

@ -0,0 +1,78 @@
# Day 9: Smoke Basin
[https://adventofcode.com/2021/day/9](https://adventofcode.com/2021/day/9)
## Description
### Part One
These caves seem to be [lava tubes](https://en.wikipedia.org/wiki/Lava_tube). Parts are even still volcanically active; small hydrothermal vents release smoke into the caves that slowly <span title="This was originally going to be a puzzle about watersheds, but we're already under water.">settles like rain</span>.
If you can model how the smoke flows through the caves, you might be able to avoid it and be that much safer. The submarine generates a heightmap of the floor of the nearby caves for you (your puzzle input).
Smoke flows to the lowest point of the area it's in. For example, consider the following heightmap:
2199943210
3987894921
9856789892
8767896789
9899965678
Each number corresponds to the height of a particular location, where `9` is the highest and `0` is the lowest a location can be.
Your first goal is to find the _low points_ - the locations that are lower than any of its adjacent locations. Most locations have four adjacent locations (up, down, left, and right); locations on the edge or corner of the map have three or two adjacent locations, respectively. (Diagonal locations do not count as adjacent.)
In the above example, there are _four_ low points, all highlighted: two are in the first row (a `1` and a `0`), one is in the third row (a `5`), and one is in the bottom row (also a `5`). All other locations on the heightmap have some lower adjacent location, and so are not low points.
The _risk level_ of a low point is _1 plus its height_. In the above example, the risk levels of the low points are `2`, `1`, `6`, and `6`. The sum of the risk levels of all low points in the heightmap is therefore _`15`_.
Find all of the low points on your heightmap. _What is the sum of the risk levels of all low points on your heightmap?_
### Part Two
Next, you need to find the largest basins so you know what areas are most important to avoid.
A _basin_ is all locations that eventually flow downward to a single low point. Therefore, every low point has a basin, although some basins are very small. Locations of height `9` do not count as being in any basin, and all other locations will always be part of exactly one basin.
The _size_ of a basin is the number of locations within the basin, including the low point. The example above has four basins.
The top-left basin, size `3`:
2199943210
3987894921
9856789892
8767896789
9899965678
The top-right basin, size `9`:
2199943210
3987894921
9856789892
8767896789
9899965678
The middle basin, size `14`:
2199943210
3987894921
9856789892
8767896789
9899965678
The bottom-right basin, size `9`:
2199943210
3987894921
9856789892
8767896789
9899965678
Find the three largest basins and multiply their sizes together. In the above example, this is `9 * 14 * 9 = 1134`.
_What do you get if you multiply together the sizes of the three largest basins?_

5
phpstan.neon Normal file
View File

@ -0,0 +1,5 @@
parameters:
level: 8
paths:
- src
- tests

28
phpunit.xml Normal file
View File

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.5/phpunit.xsd"
bootstrap="vendor/autoload.php"
cacheResultFile=".phpunit.cache/test-results"
executionOrder="depends,defects"
forceCoversAnnotation="false"
beStrictAboutCoversAnnotation="false"
beStrictAboutOutputDuringTests="true"
beStrictAboutTodoAnnotatedTests="true"
convertDeprecationsToExceptions="true"
failOnRisky="false"
failOnWarning="true"
verbose="true"
printerClass="NunoMaduro\Collision\Adapters\Phpunit\Printer">
<testsuites>
<testsuite name="default">
<directory>tests</directory>
</testsuite>
</testsuites>
<coverage cacheDirectory=".phpunit.cache/code-coverage"
processUncoveredFiles="true">
<include>
<directory suffix=".php">src</directory>
</include>
</coverage>
</phpunit>

View File

@ -1,18 +0,0 @@
<?xml version="1.0"?>
<psalm
errorLevel="1"
reportMixedIssues="false"
resolveFromConfigFile="true"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="https://getpsalm.org/schema/config"
xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd"
>
<projectFiles>
<directory name="src" />
<ignoreFiles>
<directory name="vendor" />
<!-- Skip for now -->
<file name="src/Utils/SymfonyConsoleMarkdown.php" />
</ignoreFiles>
</projectFiles>
</psalm>

View File

@ -1,125 +0,0 @@
<?php
namespace AdventOfCode21;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
abstract class AbstractCommand extends Command
{
/**
* @var int The day number.
*/
protected static int $day = -1;
/**
* @var string[] The data to use.
* @psalm-suppress PropertyNotSetInConstructor
*/
protected ?array $data = null;
/**
* @var string[] The example data.
* @psalm-suppress PropertyNotSetInConstructor
*/
protected ?array $exampleData = null;
/**
* @var string The title.
*/
private string $title;
/**
* Configure the command.
*/
protected function configure(): void
{
$this
->setName((string) static::$day)
->setDescription('Run day '.static::$day);
}
/**
* Initializes the command after the input has been bound and before the input
* is validated.
*/
protected function initialize(InputInterface $input, OutputInterface $output): void
{
$this->title = 'Advent of Code - Day '.static::$day;
$dataFile = sprintf('%s/../data/day%d/data.txt', __DIR__, static::$day);
$dataExampleFile = sprintf('%s/../data/day%d/example.txt', __DIR__, static::$day);
if (file_exists($dataFile)) {
$this->data = array_filter(explode(PHP_EOL, file_get_contents($dataFile)));
}
if (file_exists($dataExampleFile)) {
$this->exampleData = array_filter(explode(PHP_EOL, file_get_contents($dataExampleFile)));
}
$output->writeln('');
$output->writeln($this->title);
$output->writeln(str_repeat('-', strlen($this->title)));
}
/**
* Executes the current command.
*
* @return int 0 if everything went fine, or an exit code
*/
protected function execute(InputInterface $input, OutputInterface $output): int
{
// Solve the examples if available.
$resultPart1Example = 'n/a';
$resultPart2Example = 'n/a';
if ($this->exampleData) {
$resultPart1Example = $this->part1($this->exampleData);
$resultPart2Example = $this->part2($this->exampleData);
}
// Solve the real puzzle if available.
$resultPart1 = 'n/a';
$resultPart2 = 'n/a';
if ($this->data) {
$resultPart1 = $this->part1($this->data);
$resultPart2 = $this->part2($this->data);
}
// Output all the results.
$output->writeln('<fg=bright-green>Part 1</>');
$output->writeln(sprintf('<fg=blue>Example:</> <comment>%s</comment>', $resultPart1Example));
$output->writeln(sprintf('<fg=blue>Result: </> <comment>%s</comment>', $resultPart1));
$output->writeln(str_repeat('-', strlen($this->title)));
$output->writeln('<fg=bright-green>Part 2</>');
$output->writeln(sprintf('<fg=blue>Example:</> <comment>%s</comment>', $resultPart2Example));
$output->writeln(sprintf('<fg=blue>Result: </> <comment>%s</comment>', $resultPart2));
return Command::SUCCESS;
}
/**
* Solve the given data for part one of the puzzle.
*
* @param string[] $data The data to process.
*
* @return int|string The result or null if not (yet?) implemented.
*/
protected function part1(array $data): int|string
{
return 'n/a';
}
/**
* Solve the given data for part one of the puzzle.
*
* @param string[] $data The data to process.
*
* @return int|string The result or null if not (yet?) implemented.
*/
protected function part2(array $data): int|string
{
return 'n/a';
}
}

View File

@ -1,66 +0,0 @@
<?php
namespace AdventOfCode21;
class Day3 extends AbstractCommand
{
/**
* {@inheritdoc}
*/
protected static int $day = 3;
/**
* {@inheritdoc}
*/
protected function part1(array $data): int
{
$bits = [];
foreach ($data as $binary) {
$split = str_split($binary);
foreach ($split as $position => $value) {
$bits[$position][] = $value;
}
}
$gammaRate = '';
$epsilonRate = '';
foreach ($bits as $values) {
$zeros = array_filter($values, static fn ($value) => $value === '0');
$ones = array_filter($values, static fn ($value) => $value === '1');
$gammaRate .= ($ones > $zeros) ? '1' : '0';
$epsilonRate .= ($ones < $zeros) ? '1' : '0';
}
return (int) (bindec($gammaRate) * bindec($epsilonRate));
}
/**
* @param string[] $data
* @param int $position
* @param bool $highest
*
* @return string
*
* @psalm-return '0'|'1'
*/
private function valueAtPosition(array $data, int $position, bool $highest = true): string
{
$zeros = count(array_filter($data, static fn ($value) => $value[$position] === '0'));
$ones = count(array_filter($data, static fn ($value) => $value[$position] === '1'));
if ($highest) {
return $zeros > $ones ? '0' : '1';
}
if ($zeros === $ones) {
return '0';
}
// If there are more zeros, return 1 (as that is the lowest).
return $zeros > $ones ? '1' : '0';
}
}

86
src/ExecuteDay.php Normal file
View File

@ -0,0 +1,86 @@
<?php
namespace trizz\AdventOfCode;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
class ExecuteDay extends Command
{
/**
* @var string The title.
*/
private string $title;
protected int $day;
protected int $year;
/**
* Configure the command.
*/
protected function configure(): void
{
$this
->setName('day')
->setDescription('Run day')
->addArgument('day', InputArgument::REQUIRED, 'The day number')
->addArgument('year', InputArgument::OPTIONAL, 'The year', date('y'));
}
/**
* Initializes the command after the input has been bound and before the input
* is validated.
*/
protected function initialize(InputInterface $input, OutputInterface $output): void
{
$this->day = $input->getArgument('day');
$this->year = $input->getArgument('year');
$this->title = sprintf("Advent of Code '%d - Day %d", $this->year, $this->day);
$output->writeln('');
$output->writeln($this->title);
$output->writeln(str_repeat('-', strlen($this->title)));
}
/**
* Executes the current command.
*
* @return int 0 if everything went fine, or an exit code
*/
protected function execute(InputInterface $input, OutputInterface $output): int
{
$className = sprintf("%s\\Y%d\\Day%d", __NAMESPACE__, $this->year, $this->day);
/** @var Solution $class */
$class = new $className();
$class->loadData();
// Solve the examples if available.
$resultPart1Example = 'n/a';
$resultPart2Example = 'n/a';
if ($class->hasExampleData()) {
['part1' => $resultPart1Example, 'part2' => $resultPart2Example] = $class->results(useExampleData: true);
}
// Solve the real puzzle if available.
$resultPart1 = 'n/a';
$resultPart2 = 'n/a';
if ($class->hasData()) {
['part1' => $resultPart1, 'part2' => $resultPart2] = $class->results(useExampleData: false);
}
// Output all the results.
$output->writeln('<fg=bright-green>Part 1</>');
$output->writeln(sprintf('<fg=blue>Example:</> <comment>%s</comment>', $resultPart1Example));
$output->writeln(sprintf('<fg=blue>Result: </> <comment>%s</comment>', $resultPart1));
$output->writeln(str_repeat('-', strlen($this->title)));
$output->writeln('<fg=bright-green>Part 2</>');
$output->writeln(sprintf('<fg=blue>Example:</> <comment>%s</comment>', $resultPart2Example));
$output->writeln(sprintf('<fg=blue>Result: </> <comment>%s</comment>', $resultPart2));
return Command::SUCCESS;
}
}

View File

@ -1,8 +1,8 @@
<?php
namespace AdventOfCode21;
namespace trizz\AdventOfCode;
use AdventOfCode21\Utils\SymfonyConsoleMarkdown;
use trizz\AdventOfCode\Utils\SymfonyConsoleMarkdown;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;

120
src/Solution.php Normal file
View File

@ -0,0 +1,120 @@
<?php
namespace trizz\AdventOfCode;
use JetBrains\PhpStorm\ArrayShape;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
abstract class Solution
{
public static int|string|null $part1ExampleResult = null;
public static int|string|null $part1Result = null;
public static int|string|null $part2ExampleResult = null;
public static int|string|null $part2Result = null;
/**
* @var string[] The data to use.
* @psalm-suppress PropertyNotSetInConstructor
*/
public ?array $data = null;
/**
* @var string[] The example data.
* @psalm-suppress PropertyNotSetInConstructor
*/
public ?array $exampleData = null;
/**
* Solve the given data for part one of the puzzle.
*
* @param string[] $data The data to process.
*
* @return int|string The result or null if not (yet?) implemented.
*/
public function part1(array $data): int|string
{
return 'n/a';
}
/**
* Solve the given data for part one of the puzzle.
*
* @param string[] $data The data to process.
*
* @return int|string The result or null if not (yet?) implemented.
*/
public function part2(array $data): int|string
{
return 'n/a';
}
public function loadData()
{
$dataFile = sprintf('%s/../data/Y%d/day%d/data.txt', __DIR__, $this->year(), $this->day());
$dataExampleFile = sprintf('%s/../data/Y%d/day%d/example.txt', __DIR__, $this->year(), $this->day());
if (file_exists($dataFile)) {
$data = file_get_contents($dataFile);
if ($data !== false) {
$this->data = array_filter(explode(PHP_EOL, $data));
}
}
if (file_exists($dataExampleFile)) {
$data = file_get_contents($dataExampleFile);
if ($data !== false) {
$this->exampleData = array_filter(explode(PHP_EOL, $data));
}
}
}
public function year(): int
{
return (int) substr(explode('\\', static::class)[2], 1);
}
public function day(): int
{
return (int) substr(explode('\\', static::class)[3], 3);
}
public function hasData()
{
return !empty($this->data);
}
public function hasExampleData()
{
return !empty($this->exampleData);
}
#[ArrayShape(['part1' => "int|string", 'part2' => "int|string"])]
public function results(bool $useExampleData = true): array
{
$data = $useExampleData ? $this->exampleData : $this->data;
return [
'part1' => $this->part1($data ?? []),
'part2' => $this->part2($data ?? []),
];
}
public function part1Data(bool $useExampleData = true): int|string
{
$data = $useExampleData ? $this->exampleData : $this->data;
return $this->part1($data ?? []);
}
public function part2Data(bool $useExampleData = true): int|string
{
$data = $useExampleData ? $this->exampleData : $this->data;
return $this->part2($data ?? []);
}
}

8
src/Utils/Arr.php Normal file
View File

@ -0,0 +1,8 @@
<?php
namespace AdventOfCode21\Utils;
class Arr
{
}

View File

@ -2,7 +2,7 @@
declare(strict_types=1);
namespace AdventOfCode21\Utils;
namespace trizz\AdventOfCode\Utils;
use cebe\markdown\GithubMarkdown;
use function explode;

View File

@ -1,18 +1,21 @@
<?php
namespace AdventOfCode21;
namespace trizz\AdventOfCode\Y21;
class Day1 extends AbstractCommand
use trizz\AdventOfCode\Solution;
class Day1 extends Solution
{
/**
* {@inheritdoc}
*/
protected static int $day = 1;
public static int|string|null $part1ExampleResult = 7;
public static int|string|null $part1Result = 1688;
public static int|string|null $part2ExampleResult = 5;
public static int|string|null $part2Result = 1728;
/**
* {@inheritdoc}
*/
protected function part1(array $data): int
public function part1(array $data): int
{
$previous = null;
$increases = 0;
@ -32,7 +35,7 @@ class Day1 extends AbstractCommand
/**
* {@inheritdoc}
*/
protected function part2(array $data): int
public function part2(array $data): int
{
$previousSum = null;
$increases = 0;

View File

@ -1,18 +1,21 @@
<?php
namespace AdventOfCode21;
namespace trizz\AdventOfCode\Y21;
class Day2 extends AbstractCommand
use trizz\AdventOfCode\Solution;
class Day2 extends Solution
{
/**
* {@inheritdoc}
*/
protected static int $day = 2;
public static int|string|null $part1ExampleResult = 150;
public static int|string|null $part1Result = 1654760;
public static int|string|null $part2ExampleResult = 900;
public static int|string|null $part2Result = 1956047400;
/**
* {@inheritdoc}
*/
protected function part1(array $data): int
public function part1(array $data): int
{
$depth = 0;
$horizontal = 0;
@ -28,6 +31,7 @@ class Day2 extends AbstractCommand
'forward' => $horizontal += $distance,
'down' => $depth += $distance,
'up' => $depth -= $distance,
default => null,
};
}
@ -37,7 +41,7 @@ class Day2 extends AbstractCommand
/**
* {@inheritdoc}
*/
protected function part2(array $data): int
public function part2(array $data): int
{
$aim = 0;
$depth = 0;

40
src/Y21/Day3.php Normal file
View File

@ -0,0 +1,40 @@
<?php
namespace trizz\AdventOfCode\Y21;
use trizz\AdventOfCode\Solution;
class Day3 extends Solution
{
public static int|string|null $part1ExampleResult = 198;
public static int|string|null $part1Result = 3309596;
/**
* {@inheritdoc}
*/
public function part1(array $data): int
{
$bits = [];
foreach ($data as $binary) {
$split = str_split($binary);
foreach ($split as $position => $value) {
$bits[$position][] = $value;
}
}
$gammaRate = '';
$epsilonRate = '';
foreach ($bits as $values) {
$zeros = array_filter($values, static fn ($value) => $value === '0');
$ones = array_filter($values, static fn ($value) => $value === '1');
$gammaRate .= ($ones > $zeros) ? '1' : '0';
$epsilonRate .= ($ones < $zeros) ? '1' : '0';
}
return (int) (bindec($gammaRate) * bindec($epsilonRate));
}
}

View File

@ -1,13 +1,16 @@
<?php
namespace AdventOfCode21;
namespace trizz\AdventOfCode\Y21;
class Day4 extends AbstractCommand
use trizz\AdventOfCode\Solution;
class Day4 extends Solution
{
/**
* {@inheritdoc}
*/
protected static int $day = 4;
public static int|string|null $part1ExampleResult = 4512;
public static int|string|null $part1Result = 60368;
public static int|string|null $part2ExampleResult = 1924;
public static int|string|null $part2Result = 17435;
/**
* @param int[] $winningCard
@ -30,7 +33,7 @@ class Day4 extends AbstractCommand
/**
* {@inheritdoc}
*/
protected function part1(array $data): int|string
public function part1(array $data): int|string
{
return $this->playBingo($data, firstWins: true);
}
@ -38,7 +41,7 @@ class Day4 extends AbstractCommand
/**
* {@inheritdoc}
*/
protected function part2(array $data): int|string
public function part2(array $data): int|string
{
return $this->playBingo($data, firstWins: false);
}

View File

@ -1,15 +1,17 @@
<?php
namespace AdventOfCode21;
namespace trizz\AdventOfCode\Y21;
use trizz\AdventOfCode\Solution;
use JetBrains\PhpStorm\Immutable;
class Day6 extends AbstractCommand
class Day6 extends Solution
{
/**
* {@inheritdoc}
*/
protected static int $day = 6;
public static int|string|null $part1ExampleResult = 5934;
public static int|string|null $part1Result = 350917;
public static int|string|null $part2ExampleResult = 26984457539;
public static int|string|null $part2Result = 1592918715629;
/**
* @var int[]
@ -31,7 +33,7 @@ class Day6 extends AbstractCommand
/**
* {@inheritdoc}
*/
protected function part1(array $data): int
public function part1(array $data): int
{
return $this->processPuzzle(80, $data[0]);
}
@ -39,7 +41,7 @@ class Day6 extends AbstractCommand
/**
* {@inheritdoc}
*/
protected function part2(array $data): int
public function part2(array $data): int
{
return $this->processPuzzle(256, $data[0]);
}

View File

@ -1,18 +1,22 @@
<?php
namespace AdventOfCode21;
namespace trizz\AdventOfCode\Y21;
class Day7 extends AbstractCommand
use trizz\AdventOfCode\ExecuteDay;
use trizz\AdventOfCode\Solution;
class Day7 extends Solution
{
/**
* {@inheritdoc}
*/
protected static int $day = 7;
public static int|string|null $part1ExampleResult = 37;
public static int|string|null $part1Result = 344297;
public static int|string|null $part2ExampleResult = 168;
public static int|string|null $part2Result = 97164301;
/**
* {@inheritdoc}
*/
protected function part1(array $data): int
public function part1(array $data): int
{
return $this->calculateFuel($data[0], forPart2: false);
}
@ -20,7 +24,7 @@ class Day7 extends AbstractCommand
/**
* {@inheritdoc}
*/
protected function part2(array $data): int
public function part2(array $data): int
{
return $this->calculateFuel($data[0], forPart2: true);
}

View File

@ -1,30 +0,0 @@
<?php
namespace Tests;
use AdventOfCode21\AbstractCommand;
use PHPUnit\Framework\TestCase;
abstract class AbstractTestCase extends TestCase
{
public AbstractCommand $command;
protected function setUp(): void
{
$this->command = $this->setupDay();
}
public function testPart1(): void
{
$this->assertSame(static::$part1ExampleResult, $this->command->part1ExampleResult());
$this->assertSame(static::$part1Result, $this->command->part1Result());
}
public function testPart2(): void
{
$this->assertSame(static::$part2ExampleResult, $this->command->part2ExampleResult());
$this->assertSame(static::$part2Result, $this->command->part2Result());
}
abstract public function setupDay(): AbstractCommand;
}

View File

@ -1,24 +0,0 @@
<?php
namespace Tests;
use AdventOfCode21\Day1;
/**
* @internal
*/
class Day1Test extends AbstractTestCase
{
public static int $part1ExampleResult = 7;
public static int $part1Result = 1688;
public static int $part2ExampleResult = 5;
public static int $part2Result = 1728;
public function setupDay(): Day1
{
return new class() extends Day1 {
use ReturnTestableResults;
};
}
}

View File

@ -1,24 +0,0 @@
<?php
namespace Tests;
use AdventOfCode21\Day2;
/**
* @internal
*/
class Day2Test extends AbstractTestCase
{
public static int $part1ExampleResult = 150;
public static int $part1Result = 1654760;
public static int $part2ExampleResult = 900;
public static int $part2Result = 1956047400;
public function setupDay(): Day2
{
return new class() extends Day2 {
use ReturnTestableResults;
};
}
}

View File

@ -1,24 +0,0 @@
<?php
namespace Tests;
use AdventOfCode21\Day3;
/**
* @internal
*/
class Day3Test extends AbstractTestCase
{
public static int $part1ExampleResult = 198;
public static int $part1Result = 3309596;
public static string $part2ExampleResult = 'n/a';
public static string $part2Result = 'n/a';
public function setupDay(): Day3
{
return new class() extends Day3 {
use ReturnTestableResults;
};
}
}

View File

@ -1,24 +0,0 @@
<?php
namespace Tests;
use AdventOfCode21\Day4;
/**
* @internal
*/
class Day4Test extends AbstractTestCase
{
public static int $part1ExampleResult = 4512;
public static int $part1Result = 60368;
public static int $part2ExampleResult = 1924;
public static int $part2Result = 17435;
public function setupDay(): Day4
{
return new class() extends Day4 {
use ReturnTestableResults;
};
}
}

View File

@ -1,24 +0,0 @@
<?php
namespace Tests;
use AdventOfCode21\Day6;
/**
* @internal
*/
class Day6Test extends AbstractTestCase
{
public static int $part1ExampleResult = 5934;
public static int $part1Result = 350917;
public static int $part2ExampleResult = 26984457539;
public static int $part2Result = 1592918715629;
public function setupDay(): Day6
{
return new class() extends Day6 {
use ReturnTestableResults;
};
}
}

View File

@ -1,24 +0,0 @@
<?php
namespace Tests;
use AdventOfCode21\Day7;
/**
* @internal
*/
class Day7Test extends AbstractTestCase
{
public static int $part1ExampleResult = 37;
public static int $part1Result = 344297;
public static int $part2ExampleResult = 168;
public static int $part2Result = 97164301;
public function setupDay(): Day7
{
return new class() extends Day7 {
use ReturnTestableResults;
};
}
}

View File

@ -1,37 +0,0 @@
<?php
namespace Tests;
use Symfony\Component\Console\Input\StringInput;
use Symfony\Component\Console\Output\NullOutput;
trait ReturnTestableResults
{
public function part1ExampleResult(): int|string|null
{
$this->initialize(new StringInput(''), new NullOutput());
return $this->part1($this->exampleData);
}
public function part1Result(): int|string|null
{
$this->initialize(new StringInput(''), new NullOutput());
return $this->part1($this->data);
}
public function part2ExampleResult(): int|string|null
{
$this->initialize(new StringInput(''), new NullOutput());
return $this->part2($this->exampleData);
}
public function part2Result(): int|string|null
{
$this->initialize(new StringInput(''), new NullOutput());
return $this->part2($this->data);
}
}

82
tests/SolutionsTest.php Normal file
View File

@ -0,0 +1,82 @@
<?php
namespace Tests;
use trizz\AdventOfCode\ExecuteDay;
use PHPUnit\Framework\TestCase;
use trizz\AdventOfCode\Solution;
class SolutionsTest extends TestCase
{
/**
* @dataProvider loadSolutions
*/
public function testSolutionPart1Example(Solution $class): void
{
$this->runPart($class, part: 1, testExample: true);
}
/**
* @dataProvider loadSolutions
* @depends testSolutionPart1Example
*/
public function testSolutionPart1(Solution $class): void
{
$this->runPart($class, part: 1, testExample: false);
}
/**
* @dataProvider loadSolutions
* @depends testSolutionPart1
*/
public function testSolutionPart2Example(Solution $class): void
{
$this->runPart($class, part: 2, testExample: true);
}
/**
* @dataProvider loadSolutions
* @depends testSolutionPart2Example
*/
public function testSolutionPart2(Solution $class): void
{
$this->runPart($class, part: 2, testExample: false);
}
private function runPart(Solution $class, int $part, bool $testExample): void
{
if (
($testExample && $class->hasExampleData())
|| (!$testExample && $class->hasData())
) {
$expectedResult = $class::${'part'.$part.($testExample ? 'Example' : null).'Result'};
if ($expectedResult) {
$result = $class->{'part'.$part.'Data'}(useExampleData: $testExample);
self::assertSame($expectedResult, $result);
} else {
$this->markTestSkipped('No '.($testExample ? 'example' : 'expected').' data for part '.$part.'.');
}
} else {
$this->markTestSkipped('No example and expected data for part '.$part.'.');
}
}
public function loadSolutions(): array
{
$classes = [];
for ($year = 15; $year <= date('y'); $year++) {
if (is_dir(__DIR__.'/../src/Y'.$year)) {
for ($day = 1; $day < 26; $day++) {
$className = sprintf("trizz\\AdventOfCode\\Y%d\\Day%d", $year, $day);
if (class_exists($className)) {
$class = new $className();
$class->loadData();
$classes['Year \''.$year.' / Day '.$day] = [$class];
}
}
}
}
return $classes;
}
}