From f856b284cb94259a1cd29b871ee5e1b11b01ef06 Mon Sep 17 00:00:00 2001 From: Russell Champoux Date: Wed, 4 Dec 2024 17:45:14 -0500 Subject: [PATCH] day 4 pt 1 & 2 some parts stolen from the internet but i learned a lot --- Cargo.lock | 23 +++ Cargo.toml | 2 + README.md | 10 ++ data/examples/04-2.txt | 9 ++ data/examples/04-99.txt | 140 ++++++++++++++++++ data/examples/04.txt | 10 ++ src/bin/04-broken.rs | 312 ++++++++++++++++++++++++++++++++++++++++ src/bin/04.rs | 68 +++++++++ 8 files changed, 574 insertions(+) create mode 100644 data/examples/04-2.txt create mode 100644 data/examples/04-99.txt create mode 100644 data/examples/04.txt create mode 100644 src/bin/04-broken.rs create mode 100644 src/bin/04.rs diff --git a/Cargo.lock b/Cargo.lock index ea560a5..480d6e8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -23,8 +23,10 @@ version = "0.11.0" dependencies = [ "chrono", "dhat", + "itertools", "pico-args", "regex", + "tap", "tinyjson", ] @@ -136,6 +138,12 @@ dependencies = [ "thousands", ] +[[package]] +name = "either" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" + [[package]] name = "gimli" version = "0.28.1" @@ -165,6 +173,15 @@ dependencies = [ "cc", ] +[[package]] +name = "itertools" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.9" @@ -424,6 +441,12 @@ dependencies = [ "libc", ] +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + [[package]] name = "thousands" version = "0.2.0" diff --git a/Cargo.toml b/Cargo.toml index 5d5c7af..21c042e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,8 +24,10 @@ test_lib = [] # Template dependencies chrono = { version = "0.4.38", optional = true } dhat = { version = "0.3.3", optional = true } +itertools = "0.13.0" pico-args = "0.5.0" regex = "1.11.1" +tap = "1.0.1" tinyjson = "2.5.1" # Solution dependencies diff --git a/README.md b/README.md index 4f86328..d043bd9 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,16 @@ Solutions for [Advent of Code](https://adventofcode.com/) in [Rust](https://www. | [Day 3](https://adventofcode.com/2024/day/3) | ⭐ | ⭐ | + +## Benchmarks + +| Day | Part 1 | Part 2 | +| :---: | :---: | :---: | +| [Day 1](./src/bin/01.rs) | `153.0µs` | `237.3µs` | +| [Day 2](./src/bin/02.rs) | `205.7µs` | `530.7µs` | +| [Day 3](./src/bin/03.rs) | `615.8µs` | `743.8µs` | + +**Total: 2.49ms** --- diff --git a/data/examples/04-2.txt b/data/examples/04-2.txt new file mode 100644 index 0000000..7af12ae --- /dev/null +++ b/data/examples/04-2.txt @@ -0,0 +1,9 @@ +XMAS..... +SAMX..... +.X.X..... +.MM...... +.A.A..... +SS..S.... +.A.AA.... +..M.M.... +.X.XX.... \ No newline at end of file diff --git a/data/examples/04-99.txt b/data/examples/04-99.txt new file mode 100644 index 0000000..6eccfd7 --- /dev/null +++ b/data/examples/04-99.txt @@ -0,0 +1,140 @@ +MSAMXXMASXSXMMSASXMASMXMASXSXSSMSSSMMMSSSSMSAMXASAMXXAXMSMMMAXMAMSAMXAMXMXXMXMASMXSAXMXMAMXSXSXXMSSXMSSMMSSMMMMXSXAXMXMAMMASMSXSXSSXMSSMSSMM +MSASASAAXSMAMMSAMXSXXMAMXSASAAAASMSASAASAAAMMMSXXMMMSMMXAAASMMMMSAMXSAXASMMSSMMXAXXMSSXXMSMMASMXMASXAAXAAAAAAMAASXSAMAXSMSMMASAXAXAAAAAMAAAS +ASAMASMMMASXMAMAMXXAXSMSAMAMMMMMMAMMMMXXMMMMSASXXMAXAASXSSMSASAMXMSAMXSASAMAASAMXMAAAMXMASAMAMXMMASMMMSMMSSMMMMMSAAASMSMAAMSAMAMXMXMMXSMXXMM +MMAMAMAAAMAMMASMMXMMMXAAMMXMMXXXMXSXASXSMSXXMASAMSSSMSMAAMASXMASAAMASXSAMXMSSMMXSMMMXSAXAXAMSSMAMASXMASXMAMMSMMASAMXMMAMMMMMXSXMSMXMASMXSASA +XSAMAXSMSXAMSASASXMAAXSSMXXXAXMXSAAXXSAAASASMAMAXAXAMXMSMMMMMSAMMMSXMMMAMXAXAAAAMXMSAXMSSMSMASASMAMXMASXMAXAAAMMSAXXSSXMXSXMXXAMXMMMSMAASMMS +MSXMMXMXXMMMMASAMMSMXXAAXXSASMMAMAMMXMMMMMAMMASAMMSAMSXMASXXXSAXSXSMSAMASXMSSMMSXAXMASMXMAXMMXSAMSSSMXSASAMXSSMXSASAMXMAXMASMSSMASAXAMMMSMAM +XMAMSAMMSAMXMMMMMAASMMSAMXXMMAMASMXSAMASXMXMXASASXAAASASAMMMASXMSXMASXSASAMAMXAMMSMMXMXAMAMAMSMMSAMAAMSAMXSAAXMASAMXMXMASMXMASASASXSMAXAXMAS +SMAMXASAMAMXMMXAMSSSXAMASXXXXXSASAAXASASXMAXMXXXMMXMXSAMXSXAXSMMMAMAMAMMSXMMSMASAAAMXSSMMXSXMAAXMASMMMMAMAMMMMMXSXXAAASAMXAXXSAMXSAMXSMMXSAS +XSXSSMMXSAMXMMMMMMAMMXSAMMMMSXMAMMMSAMASASMSSSXAXMAMXMMMMMXSAMAAXAMASXSAMXXSAMXMMSMMAXASAAMASXSMSMMMAAXAMSMSAMSASXSMSMSAMSMMMMMMSMMMAMASXMAS +MAMXAAAAXMMAMAAMAMSMSXMASAAAAAMXMAASXMMMMMAAAXSXASAXMXMAXSAMXSSMSSSXSXMXSAXXMSAMXXXMXSAMMMSAMAAAAMASXMXMMMAMAMSAMAXAMASMMAMASAMXAAAMAMAMAMAM +SAAMSMMSSXXAXSMSAXXASXMXSXMMSAMXMMMSXSXSAMMMSMMSMMAXSASASMAMAXAAAAAAMMSXMXSXASMSAMAMAMAMXAMAXXXMAMASAMASAMAMMAMAMSMMMAMASXSASASAMSMSMSSSSMAM +SXMAAXXAAMSXXAASMMMMMAXMSAMXXAMXXMXMXXAXAXXMAAMXXMSMSASXXMSMMSAMMSMAMAMAMAMMXMXMAXAMASAMMMXSMXMASMMSASASASXSMMMMAAAXMASMSAMXXAMMXAXAMXMAMSAS +SAASAXSMXMAMMMMMMAXASXMASMMMSAMMSMAMSMSMSMAMSXXASMMAMMMMSMMAMSXXAXXXMMSAMASASXSXMMXMAMASAMAAMMMAAAASXMASMMXXXXAASXXMXAAXMMMSMMSAMXSMSSMAMSXS +SAMAAMSXSMMSMAAXMMSMMMAMSXAAXSMSASASXAAAMSSMMMSXSAMXMAMASASAMXMMMSAMXAMASXXASMSAMSSMSSXMAMSSSXMXSMMSXXXSAMXAXMMMMASXSMMXXSAMXAAAMAAXAXMAXXAM +MAXXSXSAMMXAXMSSMMMXMMSMMMSSXXXSAXXXMXMXMAXXAXMASMMSSSMASMMAMAAMAXAMMSSMMXMMMAMAMAAAAXAMMMXAMMMMXXAMXMMSAMMMMAMSMAMAAAMMMMAMMXSMMMXMASMMSMAM +XMMMXMMAMSSMSXAXMAASMAXAXAAXMMMMSMASXXSAMAMSMSMAMXSXAAMAMMXMSSMSMSAMAAXAAXMASMSAMSMMMXMMAXMAMAAMMMXXAAAXXMAMMAXXMASMMMMAMMAMSMMAAXSAMXXAAMXM +AMAXAMSMMMAASMMSXMXMMAMMMSXMAAAAMMMMAASASAAAAAMXXXMMMMMSMSAMXMAAXSAMMSSMMSSMMAXXMAMASAXMMMSAXMSSMAAXSXMSASXSMMXSAMXMXSXSMMAMXASXMSXXMAMXXSXM +XXAMXMAAASMMMAMAMSMSMSSXAXMASXMSMMXMXMXASASMSMSSXSMSXSAXXXASAMXMMMAMAMXAXAMXMASXSMSASXSAAXSMSMXAMMSXMAXXMAMAAAMAMXASXSAXAMMSMXMAXXMSMSSSSMAX +MXSXMMSSMSAMXSMMMAASAXMMXSAMAAMAXSAMXXMAMAXAXAAXAXAAAMXSMSMMASAMXSXMASXSMSMXMMSAAAMASASMMMMAAXMXMMMAMXMASMSSMSSSMSXSAMAMMXMAMXXMMSMSAAAMXSMM +SAMAAAAAXSXMAXAXSMSMXMASMSXSXXMAXSASMSXMMSMAMMMMMMMMSMMXMAMXAMASAAXSSSMMAMAAMXMMMMMAMXMAAASXMMXMMXMXMSMXAAAAAXAMXXAMAMAMXXSASMMXAMAMAMSAAAMA +MASXMMXSMMMMMSXMASXMMAAXASAMXSXSASAMMXXAAAASXMMXMXMAXAAASASMASXMXSXXAXAMAMSSSSSXMAMAMAXSMXXAASMASAXMXAXAXXMXSMSMXMSMASXSAXMASAAASMXMXXXMSSMS +MAMMXSAMASXAMXASMMMASMSMMMXMMMAMMMAMAMSMSSXXAXSAMMSMMSSMSASXXSMSAMMMMMSSXXAMMAXMMMXAXXXXMMSMMAASMXXAXMSMSXSAMMXSXXXSMSAMMSMAMMMSMAMXXMSXMAXA +MMSMAMXMXMMMMMAMAXMAXMAMXSXSAMMMXSAMAMXAMXASAMSASAMXAXAMXXMASMAMMMMAXXXMMMASMSMMXMASMSXSAAXASMSMSMMXAXAXMXMASXAAMXMMMMXMSXMXMMXXXXSXASMASMMM +MSAMMSMSSSXSAAAXXMMAMSAMASASAMMSXMXSAMMAMMMMMXSAMXAMXSAMXMXXXMSMXXMMSMSMXSSMAXAXAMAMAXAXMMSXMXAMAMASASMXSAXMMMMSMASAMXAXXAMASMMSMMSXMXSXMXAX +MXASAAAXAAASXXMXSAMXAMASXMMMXSSMMSASAXSSMSXASMMXMMXMMSAMMXSMMMXMAXSAAAAAAMAMMMMSASXMSMSMMAXXXMXSAXMAMXMASMMMXAMAXXSXSXMASAMASAAAAAMAMMMMMSSM +SSMMXXSMMMMMAMSASXSMMSASXMAMMMXAASMMSMAAXASAXASXSMSXASASAMXAMSAXAMMSMSMSXXAAMXXMAXAAMMMAMXSSSSMSMXMAMAMMMXAXSXSASMSAMXXAMAXASMMMSMXAMAAAXAAS +XAMXMMMAXXXMXMMASAXAAMXMASMSASMMMSXAXMSMMMAXSAMXSAXMXSAMMMSXMXMXASAXXAAAXSSSMXXXMMMMMASAMXAAMSASASXSSSSMSMMXAAMASXSAXAMMSSMMSMSXMMSSSSSSMMSM +SAMXSASXSXSMMXMAMAMMMSASXMASMSAAAMMSSMXAMXAAMAMAMXMMMXXMAMXSAAMSXMASXMSMMMMAMXMMMASXSMSASXMXMMXMAMAAXAAAAASMXMMXMASXMMSMAMAXMAMAXMAMXMAMXXAM +MMSMMMSASAMXAXMASXSXSAMXAMMMXSXMMXAXAAXMAXMXMAMASAMMASASXXAAXMMASMAMAXXXAASAMASASASAXXXXMAXSMSMMMMMMMSMMMAMAAXMSAMXMXAAMMSSMMAXMMMASMMSMSMMS +MAAXAXMAMXMASXMXMMXMAXXSAMXSMSMMMMXXMMMSSSMXXASAXXXAMXAXAMSSMSXASMXSXMXASMXASMSASAMXMMSMSXMMAAXAXXXMAXXXMASMMSAMMMAXMASMMMASXAASASASMAMASAMX +MSSMMSXXAAMXXXMAAMMSSXMMXXMSAXMAASMSMXXAAAASMMMMSMSSSMXMMMMAAXMASXMAMXMMMXMAMXMMMMXMSXAASXSMSMSMSSMMSMMXMAXMASASXSMSXAXAASAMXXSAAMASMXMASAMM +XAMAXMMXSXSASMMSSMAAMXMAASAMMMMSXMAAXAMMSMMMAXMXAAXAAXMAMASMMMMXMASXSXXSAXXAMXSXASAAMMMMMASAMASAAAMMAAMSSMMAMSXMAMSSXMMSMMASMMMMAMXMXAMAMASX +MAXSASXAMAMMSSMXAMMSSXMAMMAMXXAXAMSMSXXAMAXSXMASMSMSMMMXSASASAXASXMAMAMMASAAMAXSAMMSMMAAXAMAMAMMSSMSMSMAAAXSXSAMMMASASAXXSAMXSASMSAMSMSMSAMX +MMMMAXMMMAMASAXSAMAMMMMXSSSMMMMSMMAAMAMASMMMMMXXAMAMAMSAMMSASMSASAMAMAMXAMMSMAMSMSMXASMSMASXMAMMAMAXAAXSSMMMASMMXMASXMASAMSSMSASASAMSXAMMASX +SASMSMAAMXMXSAMSAMXXAAAMMAMMMAMAASMMMAAXMAMAAXMMXMASAMMASAMMMAXAMAMXSMSMSSXMMXXMAAASAMAAMAXXSXXMAMSMSMXMMMAMXMXMXMASAMAMAMMXMMXMMSAMMMSXSMMM +MASAXSSMXSMAMMMMXAXSSXXAMAMXSSSSMMAMSMSSSXSSSSMSASXSASMXMMSAMSMMSASASXAXAMAXMMMMSMXMSMSMSMSASAXSXMMMMMMSXSASXXAMSMMSAMXMXMMMSXSAXMAMAAXMMSAS +MSMMMMMSAAMXXAAMAMXXMAXSSMSMMMAMXMAMAMAAXAMXAXAMMSXSXMASXXMAAMAMSAMASXMMMMMMMAXAXXSAMXXAMAMAMXMMAMXAASAAASASAMASXAXMXXSXSMSAMAMXMSSMMMSAMMXM +SAAXXAAMSSMMSSSSSMXMMMMMAMXAMMSMASXSSSSMMSMMSMSMXMAXASAMMASAMMAMMAMAMAMAXAAMXXMASAMXMXMAMSMAMMMSAMXSSSMMMMXMMSMXXMMASMSAMAAXMSMAMAXAMAMAMAAM +ASMMSMXMAMXAAAAAMXAMAXASXMMSXAAMXSAAAAMXAXASXAAXMASXXMASMMMSMSMXSAMXXAMXMSMSASMMSAMXSXSXMXSAXAMSXMXMAMAMSMSSXAMMMSMMMAMSMAMSMAXAMMSMMAMXMSAS +MMMXXXXAASMSMMMMMMXSMSASAAAMMSMSAMMMMMMMSXMMMSMSMAMXMXXMAAAMMAAXMMXXXASAMMASMXAASXMXSAMAMAMMMSMMMSMMAMAAAAXASASAASAMMMAAXAMAMMSMMXAXMSSMXMAA +XMMXMASMXSAXMXMXSAMAAMXSXMXSAXAMMXXASXSAXAMXAAMAMXMAMMSMSMMXSMMMAMAXMMMMXSASXMMMMAMAMAMAMSSMAAAAAXXMASMSMMMMSXMAMSAMAMSSSXSXXXAXASMSMMAMAMXM +AMXMSAAXAMXMSXSASAXXXXXXMSMMMMAMSSMXSAMASAMSSMSXSASASAXAASMMSAXSSMSMXAAXAMXMAXSXSAMMSMSMSXAMSSSMSSXAMAMXAMSXMASXMSAMXMXAXASAMSAMXSXAMSAMAMMX +SAAMMSSMMSASXSMASMMSSMMSAMXAMSSMMAMAMXMASAMAXXAMSASASMMSMXSAMXMMAAAASXMMMSAMXMAASXSXAAAMMMAMXMMAXMAXSAMXSAXMAMXMASXMXXMMMMMAMMMMMMMAXMXMAMXM +MXMMAMXAXSXSXAMAMAXAAAAASMMAXAXXXAMXSXSASXMASXSMMAMAMXAAAXMMMAAXMMMMMAAMASXSMAMXMMMXMSMSAMMSMSMMMSAXSASAMMMSAMAAMMMMXMMMSMMMMMAAASXMMSMMAMAA +SAMMSMXAMXMMXAMASMMSXMXSMMMSMASMSMSASMMASMSAMXMAMSMMMMASAMXSMXSXSMXXXSMMASXMAXMXMAAAXMAMXSAAMMASAMXMSAMXSXAXAMSSXAASAAAASAAAAXMXMMAAAAMMSSXS +SAMMAASXMSAXSXXXAMAXXMMXASAAMAMMAXMASAMAMMXXMASAMAAAXMAMAXAXSAXMASXMAXAMXMAXXASXSMSSSMAMAMXXSSMMXSXMMMMMSMMSSXMXMSSXMMMXSAMSASXSSSSMMXXMXAMX +SAMMMMMAASMMXASMXMASAMXXAMSMMSXSXSMMMXMXSSSMSASMXSSMAMASMMSSMXXAMXMAMXAXSSSMMMAAXMAXXMAMMXSXAAXAXSMMAAAMXAAAMXAMMMAMMASAMXMMXXAAAMXXSMSXMASX +SMMXSASMMMAMMMMXAMAXAMXMSMMXAXAXAMXSAXXSMAMAMXMAAXAMXSXSXAMAXSMSXXXASMSMAAMXASMAMMMSSSXMSASMSMMMSMASXSSSSMMSSMMMAXMASASASMXXMMMMMMMAAAAXSAMM +SAMXSAXAASAMAMASXMASXSSXAASMMMXMASAMXSMMMAMSMAMMMXAMASASMSSMMSAMASMAMAAMMMMSASAAMAMMAMAAMAMAAAMMMMMMAAAMAASXMAXSMSXAMASAMAAXXAAAAAXXMXMMMASA +SAMXMAMSMSSXXMMAMXXMAAASMSMASAMSMMASMMXMAMMXMXSASXMMMMMXAXMAAMAMAMMSMSMMMAASXSXMMAXSAMXMMMMSSMMMAMXMXXSXSMMASMMMASXMMAMAMSMSMMMXXSSXMXSASAMX +SSMXMAMAAXAXSMSMSMMMMMMXMXMAMMMAAXXMAXMAASMSXMXXMASMSMXMSMXMMSAMXSAAAAXMXMXMAMXSSSXSASMSASAAAAMMAXXXMXMAMXMXMAMMAMAXMAXXMAMSASMSMAMXMAXMXMAS +SAXMMMSXSMMMXAAAAAASXSASMAMMMASXSMSSSMASMSAMASXMSMMAAMAMAMXXMXASMMMSSMXSAMXMSMAXAMASAMAAAMMSSMMSSSMASAMXMSSMSMMMASMMSASAMXXSAMAAMAMMMASMXSSM +SMMSAMXMMAXAMSMSMSMSASAMMXSASMSAXAXXXAXXAMMSAMMAAMMSMSXXAXXMSSMMAMMMAXAMAXMMMAMMMMMMAMMMMMAMXXMAMAAMMASMAAAAAAASXMXMXMAXMMASMMXMSMXSMASMAMAM +SXASMSAMSSMSAMAMAXAMXMAMAXSXSAMMMXMXMSMMMMAMASXMASAXXAASMSMAAXMASAASXMMSAMSASAMAAAXSAMASXMASMMAMMMMXMAMMMMMSMSMSAMXMAMAAXSASMSMXMMAXMXMMAXMM +XMAMXMAMAXAXMMAMXSAXXAMMMXMASASMSAAXAAXAXMXSMMAMMMXSXMAMAAMMMMXAASAMXAMMMMSASMMXMXXSASAMASXSAMMMASXMSSXXAXXXMMASAMAMAMXMMMAXAASAAMMSSMMSSSXS +SSMMSSSMMSXMASXMASAMSSMAXASASAMAMXXXSSSMXAMXXMMSAAAXAXMMSAMXSMMMMMSSMSAXAAMMMAASXMMSMMXSXMASMMASMSAMAMASMSMAMMMMSSMSMSAXMMSMSMSMSAAMAAXAASMS +AAAXAAXMAXAAXXAMXMAMAAXXMAMXMMMAMMMMAAAMMSASAMAMMSMMMMXAMASAMXAMXAAXXAMMMMXAMXAAAAMXMAXXAMAMASAMXSAMAMXMAAMAMAMMASMAASAMXAMXMAXAMMXSSMMMSMXX +SXMMMMMMMSSSXSXXXMAMMSMXAAMAAAXAXSAAXMAMAAMSAMASXMXAMXMAMAMASMSSMMSSSMXAAMSMSMSMSXMAMMMSMMASXMMSMMXMAMAXXMSSSMSMAXSMXMMMMAMAMMMMMAXMASASAMMS +MASAMXAXXAAXXAMXSMMMAAAXMASMXMSMSAMMMXMMSSMSAMXXAAMMSAXXMSSMMAMXMAMXMXAXMXAAXXXAXMMXSAAAASASMSMAASMSSSSMMXMXAAAMSMXXMASXXAMSMSAMMSMMASXSASAX +SAMASXMMMMSMSXMASAAMSSSMSMXMXXAMAMSXSAXAAAAXXAMSMMMXMASXXAAAMSSSSSSSSXSSSSMSXMMSMMSAMMMSMMASAAXMXMAAXSAASMXSMMMAMASXMXAAMMMXASXSAAMMXSMSMMXS +MXSAMMSAAXMAMXMAXAMXXAXAXXAMXMASAXAAMAMMSMMMSXMAMASXMASXMMSXMMAAXAAAXAXAAXMMAMMAASXSMAXXAMXMMMXSAMMMMSSMMMASXMXASMMAMXMMAAAMXMMMMSSMXSAMAMAS +MMMMSASXSMMAMMMMSSXSSMMMMMSMSSMMMMXMMAXMAXSAXAMMSASAMSMMAXAAMMMMMMMMMXMMSMASAMSMSMAMMXMXAMMMMSAMMXXMXMAXAMASASMMSXXAMAXXSMMSMMXSAMXMAMSMAMAS +AAAMMASXXASAMMAMXMAXAXAXSAAAAMSAXMMMSXSMXMMMSSMMMMXAMAAXSMMSMMASAMAXAMXXXMASXMAXAMXMSSSSSMAAAMAXSAMSMMMSMMASMMAMSMMMMXMMXMXXAMASAMXMMMAXSXMS +SMSSMSXMMAMAXSXSAMSMXMMMAXMXMMSMMSAMAMXMAMXMAMAXAMSSSMSMAMAAMMASASXMXAXSXMASASAXMAMXSAXAAXXMXXXMMASAAAAAAMAXMSSMMAASMMXSAMXSSMASMSMMMMMSMAAX +XAMXMMAMSSXMAAASMXAAASXSSSSXXXXAASXSSSMSSSMMASMMSAAAMAMXAMSSSMASAMXXASAMAMAMMMMSXAASMMMSMMSMSMAMSMMXSMSSSMSSXAXMMMMMAAAMASMAXMASAAAAAASAMAMS +MAMAMSMMAXAMXMXMASMSMSAXMAMMMSMMMSAXXAMXAAAMAMAAMMSMSMSSXXXAMMAMASAXMMASAMMMSAASMSMMAXAXMXAAASXMAXMAMMMAMAMAMMSMMSMSMMMSAMMMMMAMMMSMSXSAXSSM +AXSAMAMMMMXMMMMSMMXAAMMMMAMAAXAASMMMSMMMSMMMASMXMAMASAAMXMMMMMMSAMMMXSAMASXAXMXSAXAMXMMSSSMMMSXMMMMMMXMAMSMXMXAMXAAAAMXMMMAMXMSXXMAXXMMMMXAX +SASMSXSAAMSMMAASXSSMSMSXSXSMSSSMSAAMMAMMMMXSXSXXMMSAMMMMAMMXSAMMASXMAMMSXMMXSXMMMMMASMMAAAASXMAMAASXMASXMAMMXMAMSMSMMSAMSSSXMAMAAASAMXASXSSM +XXSXMMSMSMSAXMMXAAAAAAMXXMSAMAAAMXMMSAMMAMASAMAXSMMASXMXMSAASAMSAMAMASAAXSMXAXMAXSMAAAMMSMMMAAXMAMSAXXSASXSAAMXMSXMAAMXXAXMAMAMSMMMXSSSSXAXX +MMSAMASMMAMAMSMMSMMSMSMAXAMAMSMMMAMMSXMMAXAMAMMMSASAMXSAMMMXSAMMSSXMXSMMMAMMMXXAAXMAXXXAXMASMMMAMSMXMAMASAMMXSAMXAMMMSMSMSSXMAXAAASAMMMMMMMM +AAMXMASAMMMSMMAAXAXXAMAMXSMMMMXAMAXAXSSSSMSXMMMXSAMASAMMSXMMMXMAMMMSAMXXSAMAAMASXMSSMMMSSSMMMASXMAAAMXMSMAMAMSASMSMSXAAAXAAXSSSSSMSAMXAMAAAX +SSMAMAMMXSAXAMMMSMMMSMMXAXAXXXMMMSMMMMMAXAMXSAMMMMSXMASAMXSSXMMMSAAMAXXASMSMMSAMAMAAAAXAAXAXSASXSMSMSXMAMXMAXSAMAAAMAMXMMMMMAMXXMASAMXMXSSSX +AAXSMXMXXMASXMSXSXMAXAMMMSSMMAASAXASXAAAMXMAXASMAAAAMAMMSAAMSMAAMMMSAMSXMXAXMMASXMMSMMMMSMMMMASXMXXAMMXAMMSXMXMMSMSMXMAAAAXXXXAMXASXMASAMAMX +SSMMAMSMSMAMAMSAMXSASAMSMAMXASMSASAMXMMXMAMMSMXMMXSAMASXMMMMASMSSMAMAXMASXMSXSAMXSXXXAXXAAXXXMSAMAMASMSXMAXSXAMXXAXMASXSMSSSMMSSMXMASASAMAMM +MMAMXMAASMSXSMMAMAMXSXMXMASMXXAXAMAMXSAXSAMXAMSMMMXMXMXAXSXSAMSAXMXMXAXXMAAAXMASAASMSSSMMSMSAMXAMMSAMMAXASMMSXMAMMMMXAMXMXAAXAAAXSMMSMMMMMSS +MMMMSSMSMAXSMASXMXSASAASMXSAMMMMMMXXXAAXMMSSMXAAAAMAAMXMMMAMASAMXASXMMSSSMMMSXAXXAMXAASAAMASMASAMXMASMSMMXAMSMSXSASXSMSASASMMMSSMSAMMAXMSAAA +MAAAAXXMMAMAXXMXAAMASXMAXMXXMAXMSAMXSMMMMAAMMSSSMSSSMXAAAXSMMMMXXMASAAAAMMMXXMMSMXAMMSSSMMAMMMAAXAXXMAXXXSAMXASXSASXAASMSAAXMAMAASMXMSMAXMAS +SSSMMSSMMSSMMSMXMXMAMASXSSSMSSSXMASAXXSXMSSMAAMXAAAAAXSXMSMMSAXSASASMMMMMASASXAAASMSMAMAMMXMASMMMSMAMMMMMSXMASMAMMMMMMMAMMMMMMSMMMXMSMAMAXSM +XAAXXAMAAXAXAAXAMSMMSAMMAAAAAAMXSAMXSAMXAAAMMSXXMMXMMMMASAMAMASXXMASXSXXMAXMXMMXMAAAMAMAXXMMXMAMAXMASAAAMXMAMAMXMASAMMMMMMXAAMXXXMAMAASXMSAS +MSMMMASMMSMMSSSXSAAXMASAMSMMMXMAMXMAMXAMMMSMMAXXASXAMSSMMAMXMMSAMXXMASMMMSSMAMSSMXMMSSSXSAXXASAMXXSASMSSSMXMMSMXSASMSAAMAXSXMSASMSSSSSMAMAMX +AAXMAMMXMAXAXXMXAXXMMXMXMXMXMAMAMAMSSSXSAAXMMSSMAMXSXAAXSAMXSMMMSSMMXMSXAAAXASAAXSXXMAAASMMMXSXSAAMXSAMAAAASXXAAMMSXSXSSMXSASMAMAXMAMXMXMMXX +XSAMXMXSMMSMMMXXMAMMMXXAMAMASASASAMAAXAMMMMAAAAMAMMMMSSMSASXSAAAXMAMXXAMMSXMMMXSMMASMMMMMXSXMMMSXXXAMXMSMSMSASMMSXMASXMAMAMMMAMMSMMSAMXMXXXX +MXXMASASAMMMAMMMXSAASMSASASMSXSMSASMSMMMSMSMMSMSASXAAXAMXXMASMMMSSSMSSMSAMMSXAAMAMAMAXXXXAXAAAAXAXMXSAAXAXXMXMASXASAMASXMASAMXMAXXXMMMAMXMMM +MMSMXMASXMSMXSASAMSMAASASASASAMASAMAXXXXAAAXXMASASXMSSMSAAMXMASXMAAAMMXMAMASMMXSAMASXMSXMASXMMSMMXMASMSMSMXXASMMSXMAMXMAMXMXXSMXXSXMASAMXASX +AAAAAMXMMXSAASMMXMASMAMAMXMXMMMAMMMSMMMAMSMMAMXMAMAMXMASXXSASAMAMSMMMXMMAMMMAAAXASASAMXAMASASMXAXASAMAAAAXMXXMSAMXMSSMMSMMMSMMMMMSASASAXSAMX +MMSSXSMMSAMMMMMSMXMSXAMSMSMSMXMXSXAAAAXXXMMSSSMMXSAMXMXMMMSXMASAMAMSMAXSAMXSMMSSMMASMMASMASMMAMMXMMAXSMSMMMSMMMMSAMAAXAAMAAAAAAAXSAMAMXXMASX +SXMMASAXMMSMXAXXASMMXSSXAXAAMASMMMSSSMSXAXAAAAXSASASXMMAAAXMAMXMXMXAMAMSASXSXAMAXMMMASAXXXMMMSMSSMMSMXAMXSASAAAASAMXSMSSXMSSXSSSMMMMMMSXMMSA +XAASAMSXXXMXSMSMXMXAAXMMMMSMSASAXXAAXAMMMMMMMSMSASAMASMXMXSAMXXMASXMXSASAMAMMMSMMMXSAMMSMMSMXMAMAAAMAXXMXMAXSMMMSAMXXAXAAXAMAMAMAMXMSAMASAMM +SXMMAMMMMSXAMSAXASMXMMXAAXXAMMSXMMMXMXMAXAXMMXASXMAMAMMMSAMXMXMMAXAXXMAMAMAMSAAMASAMSSMAMMAMMMAMXMMSSMXAXMSMXMSAXMSSMMMSMMASXMAMASAXMASXMASX +AMSXSMAAAAMXSAMSXSAAMMMSMSMAMASASXXXAASASXSXAMAMAMXMAXAMXXMASAAMXSSMSMAMXSSXMSAXAMASAXXASXASXSMMXSAMAMMXSAMXAXMMMMSXASAMXMMMMSMSAMXSXAXASAMA +SASAXXSMSXAXAXMAAXXSAAAAXMMMMMSAMAMMSMMMAMMMXMAMAMXXMSMSMMSASMSMMXMAMSASAMXAMMXMASMMMMMMMMAMXAMXAMXSAMMMSAMMMSASXMXXAMXAAXAAXAAMMSMMMMSMMMSS +MAMAMAXAMXSASXMSSMMXAMSSSMSMMMMMMXMAAXMMMXAMAXSMSMSMAAMAAAMASAXXAAMAMMXSAMSMMAAXMMXAAAASXSASXSAMXSAMASAAXAMXAXAXMASMSSMSMSMSSSSMAAAXAMAMAXAA +MXMSMSMSAAXSMAXAAAXSSXAMMAAAAAMMSXMSSXMASMSSSXMAXASMSMSMMMSASASASMXMXSXMXMAMMMXAAASXMSAXXMAMAMMXMXMSMSMSSSMXMMSSMXMAMAMXXXXAXAMMXXXXMMMMXSSM +MXMXAXAMMMSASMMSSMMMMMXSMSMXMXXASAMXAMSSMAAAMAMXMXMAXAXXXXSAXAAMXMASAAAAMSXMAAMMMMSAMMMMMMSMMMMSMMXAMXAAAAAXXAAAAXMMSSMXXSMSSMXMSSSSMXSAMXAX +MXMMMMXMMXMMAMXAXAMXXMMMAMAMSSMMSAMMMMXAMXMAMMMXAXMXMXMMSMMMMMMXMSXMASXMAMMSMXSXAAMMXAAMMAAAASAAAXSMSMMMSMXSMMSSMMSAAXMXMMAAXXXMAAAXAAMAMXMX +SXMAMSMXXMMMSAMXSXMXAMXSMMAMAAAMMAMMXMSXMASMXAMXSAMASAXMAXAMXAXAXXAMAMXAXXAAXAXXMMMXXMMMMSMSMSXSMMXXAAAAXAAAMAMAAASMSMSAMMMMSSSMMSMMMMMAAAMM +AMMAMMXXASMAMXSXMASMMAAXMSXMSSMMSSMSAMXAMASAMXAMXMSASMSSMXXSSSSMASAMSSMSMMSSMMMAMXXSXXAXMMMMASAXMSSSXSMSSMMXMASMMMXAAMMAMXMASMAAAAXXXAXSSMSA +MSSMSAAMSMMMSMMASAMASAMXMMMMAAAXAMASXSXSMMSMAMAXAXMXSAXAMSMXMMAMMAMMMAAMXXAMXXAMXSMSASMMMAAMAMAXMAAMMMXMXMSXSASXSMMMMSSSMMMSSSSMMMXAMMXMAMAX +XMAMXMASXAAAAAXXMASXMMMAAXSSSMXSAMXMASAMAMXXMASMMXSAMXMAMAAAMSXMMMXAXAMXXMSMASXMMXAMAMAASMMSAMXMMMSMASAXMXMAMAMAAXMAXXAAAMSMMXXAXXMXXMAMAMMS +SMMMSXMAXXMMXMXSSMMASASXSMAAAXASAMXAASASMMSXMAMAMXMMSXSAMMSSXMASXXSXXSAMXSAMXXAAMXMMAMXMMAASAMXSMMMXAMAXXSMMMXMSMSXMXMXMMMMAMXSXMXMASMMSMSAS +MAAAXMAMAMSXSMXMAASMMAAAMMMMMMASAMXMAMAMAXXAMASAMMSXXAXAXXMAXSAMMXMASMAAXSMSXSSMMMASXSASMXMSAMAAAAAMMXSASAAXXMAMAAXAMSAMXMXAMMMSAXMXXAAXAMAM +SAMSSXXXMAMAAXAMMMMXMSMAMAAMXSASXXXXXXSSMMMXMASAMASAMXMMMSAMXXSXXAMXMSMSMMXAAXMASXMMASASAMASXMASMMSSMAMXAXMMMSAMXMXXAXMXASMXSAXXSXSMSMMMMMSM +MXAAMMMXMAMXMSXSXMASAMXXMXMSASAMXSMMMMMAMMSAMXSAMSXMXAXMAXXXMMMMSSSSXMXAAMMMMMSXMAXMAMASAMXMXMAXAAAXMXMSXXSXMASAXSMSSXMMMXAASXMXMXMAAXMXSAMX +MMMASXSSSSSSXAASXSAMASXSSMAMAXAMAMMAAAXXMASASASXMAMXSMSMSSXXMASASAAMMSMSXMAAAAXMMXMMXSASXMSSMXAXMMSMMSXMAXXAMXMMSXAAXAMASMMMMXMASAMXMSAXMASA +XASAMAMAAXAAMMSMAMXSAMAAAMAMMXMMXXASMMSAMXXMMMMXSSMXAAXXMXMXMSSSMMMMAXMMMMSSMSSSMSAXAMAMAAAAAMSSXAMAAXAMXMSSMMAXMMMMSXSAMAAMXSMMSASAAMMMMXMX +SXMMMAMMMMMMXSAMXMMMXMMSMMMSMXSASAAXAXMASAXSASXMAMASXAMXAAAXMAMMMMMMSSXSAXAXXAAAASXMMSSSMMMMMMMAMSSMMSSMXMAMASXXAAAXXMMMSSMSAAMAXAMMXMXASAMX +MMSASXSAMXMMXMXXXSXMXSAMXSAXAAMAMMXMMMSAMXMMASMMAXAAXAAMSMSMMASAAMAMXMASXMMSAMMMMMXSXAAAAMXMAXXAXXAAXAMXXMXXMSMSSSSSMXAMAXXMASMSSMMMMMSXXASX +AAXAMASMSMSMMMSSMMAMASAMXMMMMMSASXXMXAMXSSSMAMXSMMSSSMSMMMAASMSMSMSSMMAMAMAXMXSXXXSAMSSXMMXXAMSXMSXMMSSMMMSXXMAXAAXAXSSSMSMSXXAMXXAXAAMXSAMA +MMSAMXMXAAAXXAAAASXMASAMXXAAAASXSASAMXSXMAAMMMXAXAMAMXAAXSSXMMSXMAXXAMXSAMXXXASXMMXMAXMASMSMXXMAMAASAMAAAAXXAMXMMMMSMMXAXSAMXMAMXSSSXSAAMAMX +XXAXXXMSMSMSMMSSMMAMXXXAMXSMMMSMMAMSAMXAMXMMMSSMMMMMAXXMMXXXMASAMMMSMMXSMSMSMMMAXAAXMXMASAAXMASXMSSMASMMMSSXSMMXXXAAAXSXMMSMXSAMXMXSAMXXSAMM +XMASMAMMXMXXXAXXMSXSMSXMXAAMMAMAMXMXXMXAMAXAXAAASASXSSSSXMAXSXMMMAAAAAAMXMAAMXSMMSMMSASAMXMMSAMXXXAMXMXMSAMAXASXSMSSSMXASAMXMSXSMSAMXMSASASM +MXAXMAMMMSXMMMMMXXAAXMASMSSXMASXMMSXXMASXMSMSSSMMASAAAAXMXSXMAXAMXMMSMXXAMSMSMMSAAMAXXXASXMAMMSSXXMMSMAMMAMMXAMMAAMMXMSSMMSSMMXMAMAXSAMXSAMX +SXMSSMXSAAAAASASMMMMAMXMAAAASXMXMASXMASXAXAAMMMAMSMMMMMMAAXASMSMSXSAXXXXMXAMXMAASXMASMSMMAMXSXAXASAMXMASMXMXMSMMMXMMAMXMASAMAXSMASMMXXSAMXMX +SASAMXAMMXXMAMASMAAXSSSMSMSMMASXMASMAXMSMMMMMASAMAMSMMMSMMSAMAAXAAMMMXSAMSAMAMXMXXMAMXAMXXSSMMXSMAAMXSMSAASXMAAXXMASASMSMMMSMMAXAXXAMMMXSMSS +SXMASMMXXXSXSMAMMSSMMAMAAXMASAMAAXSMMMMXXAAASXXMMAXMAAAAAXMXMMMMMSMSAMXAMAASMSMSSXMXSSMMSMMAAMAMXAAXMSAMMMSASMXMSSMMAMMAXAAAXAMMSXSAAASXMMAS +SMSAMAXMSMMAMMXMAXXASAMMMMSAMMSMMMMXAAMSMXSMSAMXMMSMMMXXSMMASXSAXAAMSSMSMMXMAAAXMXSAAAXAAAMSXMXSMSSXAXXXXXSMMSAAAMXMSMSSMMSXSSXAMMSXSMSASMAM +SAMXSSMMSAMXMASMMSSXMAMXAMMASASMSMAXMSMAMMMAMMMAASAMXXSAMXSXSAASXMXMMXAXMAXMSMMMMAMMSMMSSMMMSMMXMAMMSMSMSMXSAXMMMSAMXASAAAAXSXMXSAMMXASAMMSS +MAMXAXMASMMMAMMAAXMMSAMSSMMAMXMAXMMSMAXXSAMAMAMSSMASAAMMMXMMMMMMMMMXMMSMAXXMXXMXMASAMXXMAASAMXAAMASMAXAAAXMMSSMSXSASXMMSMMSSMAMAMMMAMMMXMAMX +SAMMMXMAMAMMAMSMMSAAMAXMAAMSSSMSMMAAXMASMMSSMMXMAMAMMSMAMSASXSXAAAXMMAXXASMMAXAASXMASMSMSMMASMSXSAXXMMMSMMSAAMXMASMMAMXXXXXXMAMASXMXSXMSMSMM +XAXASXMASAMSAXAAMMMMSMMMMXMAAXAMAMSMSMMAMXAAXXASXMXSXAXAXSAMAMXMSMSASAMSXSASAMSASAMXXAXXMASAMXMAMMSMSAAAAAMMMSAMMMAMAMAMMASMXXSAXAMAMAAMAAMA +SMSMSASASAMSXSMSMXAAXAAXXSAMXMAMSMMAAXXMMMMSMSXSAMXMXMMMXMSMSMAMAMSXMAMAAMMMXXXAMMSSMMMMXMAMXAMAMSAASMSMMMSAXSXSMSSMASASXASASXMMSMMASAMMMMSS +AXAAXAMXSXMSAXMMMMMSSSMSAMAXMMXMAAMSMMXXAAMXAMXMAMASAXASAMXMAXMMAMMXSXMMMMASXSMSMAAXAAASAMMMMMXAMMMMMAAXXXMMXMXSXAXXXMAAMAMXAXSAAASASXXSAAXX +MSMSMXMXSMMMXMAMSASAMXAAASAMXSASMSMMXMSMSMSMSMSSMSASASASASXSMSXSXMXAMMMSXSAMAMAMMMMSSMXXASXMASMMSXMAMMMXSMMSXMASMMMMMMSMMASAMXMMSXMASXAXMXMX +XAXAAXMASAXAMMXAAMMSSMMSMMMMXSASAMXMAMAMMAMAXXMAMSXSXMASMMAAAAXAXSMSXSAAXMASAMAMASMMMSMSMMMMXSAAAASXSMXAAAAXAMASXXAAMAXXMASAXAXMMMMXMMMXMAAX +SSSMSXSAXXMMMSAMMXMAXAXMASXSMMAXXAAMSSSXSAMAMXSXMMAMXMXMXMSMMMSMSMAMAMMSSMXAMSASASASAMXAXAMSASMMMMMMAAMSSMMSAMXSMMMSMASXSMSMSMSMAAAAXAXAXXSA +MAMAMMMAXSAMASXXAAMXXSASMXAAXMAMMSXAAAMASASMMASMMMAMMMMSAMXMAMAXAMAMXMAXAXMAXAXXXSAMXSSMXMSMASASXXAMMMMXAXAAASAMASAAMXMASAMAMXAMMMXMMMMAASMX +MAMAMAMAMXAMASXMSXSMMMASXMSMMXXMMAAMMSMASMMAMAXAASASAASMMMXSAXSSSMSSSMSSSMSAMXMXMMMMXMXXAMAMXMASMSSSXXSXMMXXXMAMAMSSSSMMMAMAMMSSMSAMSSSMMXAX +SXMAXMMASXMMMXMAAAXAAMAMAXXAAAMSXMMSAXMASMSASMSSMSASMSMMXSAXMSMAAAXAMAMAMAXMAAMAAAAMSMSAMMAMXSAXMAXMAMSXSASMSSSMAMAMAAASMXMXSXAAAMASAAAXXMXM +SMSMSASAMAMAMSXXMSMMSSMSSMMSXXAAAAAMXXMXSASXMAXMASXXMMXXSMAXSAMMMMMAMXMAMMMMMSSMSSXSAAXASXSMMMASMMXSMMMXMASAAAMAXMASMXMMAAXAMMMMMSSMMSMASMMM +MAAAAAMMMASASAAMXMAXAAXAMXAXMASXSMMSMSMXMAMAMXMMMMMSXMASMMMMMASMMSMSMMSAMMASAMAXAAMMMXMAMAAMSMMMMMASAXSAMAMMMMSSMSMMXSMXXMMASAXXAXAAMAMAXXAX +MXMSMMMSSXMXXMXAAXXMSSMSSMMSSMXAMMMAAAAMMXMMSMAMMAAXAAXAMASXSMMAMSAAAASAMSAMASXMMSSMASAMMSMMXAXSAMMSAMMAMXSAMXAAAXXSAMSAAMSAXMSMMXMXSASMSSSS +XSXXXXAXMMSSSXSSSSMMXMAMAXMAASMMMMXMSMSAMXMAAXMMSMSSSMSMSASAAXMAMMMMMMSAMMASAMAAXAMXMMMSAMAXSMMSASAMAMSXMAXAMXSMMXXMAMXSSMMMSXAASAXMSXSAAXAA +MAAMAMXXAXAAAAAXMAMMAMMMAXMSMMXMASAMXMAXXAMXMMSAAXXAMAAXMASMMMSSSMSSSMXAMSMMMXSXMMSMSMXMASMMMAASXMMSMMAMMSSMMMXAMAMSSMAMXMASAMXMMASAMXMMMMMM +AMXSMMXSMMMSMMMMMAMXAMAMASXMAAMMASASAMXMSMSSXAMXSSMMMMMMSASASAXAAMAAMASAMXMAMMMASXMAAAASMMXAXSMSMMAMAXMXAAXAAASAMXAAXXXMASXMXSSSSXMXXMMAXASX +SXAAXMAAAAMAAAXAMSSSXSXSSMMSMMSMASAMXMAMXAAXMMMXXMAXAXSXMASXMAMMMMSSMMMXMASASMSAMMMMMSMMSASMMXAXAMAXMMXMMSXXMXSMASMSXMMMMMSMXAAXAXAXMMSAMXSS +MMXMAMSSSMSSSMXSXXAMAAXSAMAXAAXMAMXMASXMMMMXSAAMSSMMMXMAMXMASXMSXAAXAXMASMSASAMXMASXMMAAMMMMSMSMSSMSAMXAAMMSMMMXAXXMASASAAMXMMXMMMXSXAMXMMXX +MSMSMAAXAXMXMMSMMMAMXMXSAMSMMMMMAMXXAMAXXMAASAAXXAXMMASAMASAMAASMMSSMAXASAMXMAMXSAMXSSMMMSAAAAAAAAXSAMXMXSAXAAAMMSMXMMASMXMAXXASXSMAMXMSAMXM +SAAAAMMSMMSAMXAAASAMAXAXXMAMASASMSSMSSMMSMMXSMSXSAMXSASASMSAMMMMAMMAMAMSMMMXSXMMMXSMXASAAMMSSSMSMSMMAMAMMMASMMMMSAAAMSASASMSMMASAMAMSMAMXMSM +SMSMSMAAXAMASXSSMSASXMMSMSMSASXSAAMAMAXAAASAXAAXXMAMMASAMXSAMXAASMXAMASAAAMAMAAASAMXSAMMMSAAAAAXMAXSASASAMXMMAAXSMSMXAAXASAMXMAMAMSXXMASAXAX +XMAXXMMSMMSXMXMAXSXMXXXAXSXMXSXMMMMASXMASAMXMXMMAXSAMXMXMASAMSSSXASXSXSMSMMXSMMSMXSAMXMSAAMMSMMMXAASXSXSXSMMSMMMMXAXAMXMXMAMXMASAMAXXMASXSAS diff --git a/data/examples/04.txt b/data/examples/04.txt new file mode 100644 index 0000000..1f4eda2 --- /dev/null +++ b/data/examples/04.txt @@ -0,0 +1,10 @@ +MMMSXXMASM +MSAMXMSMSA +AMXSXMAAMM +MSAMASMSMX +XMASAMXAMM +XXAMMXXAMA +SMSMSASXSS +SAXAMASAAA +MAMMMXMMMM +MXMXAXMASX diff --git a/src/bin/04-broken.rs b/src/bin/04-broken.rs new file mode 100644 index 0000000..ad9dbc6 --- /dev/null +++ b/src/bin/04-broken.rs @@ -0,0 +1,312 @@ +advent_of_code::solution!(4); +use std::fs::File; +use std::io::Write; + +pub fn part_one(input: &str) -> Option { + let result = word_search(input, "XMAS"); + Some(result as u32) +} + +pub fn part_two(input: &str) -> Option { + None +} + +fn word_search(input: &str, needle: &str) -> usize { + // for every character if every line, check in each of 8 directions for a match + + // 1) RIGHT + let total_right = match_forward(input, needle); + // println!(" R: Found {} in {:?}", total_right, input); + File::create("04-data-R.txt").expect("Error creating").write_all(input.as_bytes()).expect("Error writing"); + + // Reverse the grid and check it forward + // 1 2 3 3 2 1 + // 4 5 6 ===> 6 5 4 + // 7 8 9 9 8 7 + + // 2) LEFT + let reverse_input = reverse_string(input); + let total_left = match_forward(&reverse_input, needle); + // println!(" L: Found {} in {:?}", total_left, reverse_input); + File::create("04-data-L.txt").expect("Error creating").write_all(reverse_input.as_bytes()).expect("Error writing"); + + // DOWN & UP-RIGHT + // SKEW the grid to get the DOWN check, TRANSPOSE the SKEWED grid to get the UP-RIGHT check + // (0,0) (0,1) (0,2) (0,3) (0,0) (1,0) (2,0) (3,0) - - - (0,0) - - - + // (1,0) (1,1) (1,2) (1,3) - (0,1) (1,1) (2,1) (3,1) - - (1,0) (0,1) - - + // (2,0) (2,1) (2,2) (2,3) ==> - - (0,2) (1,2) (2,2) (3,2) - ==> (2,0) (1,1) (0,2) - + // (3,0) (3,1) (3,2) (3,3) - - - (0,3) (1,3) (2,3) (3,3) (3,0) (2,1) (1,2) (0,3) + // - (3,1) (2,2) (1,3) + // - - (3,2) (2,3) + // - - - (3,3) + // Eg the "Up-right" check starting from (3,0) and going to (0,3) is now in a row in the skewed grid + // Eg the "Down" check starting from (0,1) to (3,1) + + let char_vec = vecify_string(&String::from(input)); + + // 3) DOWN + let skewed_vec = skew_vec_bottom(&char_vec); + let skewed_input = stringify_vec(&skewed_vec); + let total_down = match_forward(&skewed_input, needle); + // println!("D : Found {} in {:?}", total_down, skewed_input); + File::create("04-data-D.txt").expect("Error creating").write_all(skewed_input.as_bytes()).expect("Error writing"); + + // 4) UP - Reverse the DOWN vec + let reversed_skewed_input = reverse_string(&skewed_input); + let total_up = match_forward(&reversed_skewed_input, needle); + // println!("U : Found {} in {:?}", total_up, reversed_skewed_input); + File::create("04-data-U.txt").expect("Error creating").write_all(reversed_skewed_input.as_bytes()).expect("Error writing"); + + // 5) UP-RIGHT + let transposed_skewed_vec = transpose(skewed_vec); + let transposed_skewed_input = stringify_vec(&transposed_skewed_vec); + let total_upright = match_forward(&transposed_skewed_input, needle); + // println!("UR: Found {} in {:?}", total_upright, transposed_skewed_input); + File::create("04-data-UR.txt").expect("Error creating").write_all(transposed_skewed_input.as_bytes()).expect("Error writing"); + + // 6) DOWN-LEFT - Reverse the UP-RIGHT vec + let reversed_transposed_skewed_vec = reverse_string(&transposed_skewed_input); + let total_downleft = match_forward(&reversed_transposed_skewed_vec, needle); + // println!("DL: Found {} in {:?}", total_downleft, reversed_transposed_skewed_vec); + File::create("04-data-DL.txt").expect("Error creating").write_all(reversed_transposed_skewed_vec.as_bytes()).expect("Error writing"); + + // Skew in the reverse direction and transpose it + // SKEW the grid to get the DOWN check, TRANSPOSE the SKEWED grid to get the UP-RIGHT check + // (0,0) (0,1) (0,2) (0,3) - - - (0,0) (1,0) (2,0) (3,0) - - - (0,3) + // (1,0) (1,1) (1,2) (1,3) - - (0,1) (1,1) (2,1) (3,1) - - - (0,2) (1,3) + // (2,0) (2,1) (2,2) (2,3) ==> - (0,2) (1,2) (2,2) (3,2) - - ==> - (0,1) (1,2) (2,3) + // (3,0) (3,1) (3,2) (3,3) (0,3) (1,3) (2,3) (3,3) - - - (0,0) (1,1) (2,2) (3,3) + // (1,0) (2,1) (3,2) - + // (2,0) (3,1) - - + // (3,0) - - - + // Eg the "DOWN-RIGHT" check starting from (0,0) and going to (3,3) is now in a row in the skewed grid + + // 7) DOWN-RIGHT + let top_skewed_vec = skew_vec_top(&char_vec); + let top_skewed_input = stringify_vec(&top_skewed_vec); + let total_downright = match_forward(&top_skewed_input, needle); + // println!("DR: Found {} in {:?}", total_downright, top_skewed_input); + File::create("04-data-DR.txt").expect("Error creating").write_all(top_skewed_input.as_bytes()).expect("Error writing"); + + // 7) UP-LEFT - Reverse the DOWN-RIGHT vec + let reversed_top_skewed_input = reverse_string(&top_skewed_input); + let total_upleft = match_forward(&reversed_top_skewed_input, needle); + // println!("UL: Found {} in {:?}", total_upleft, reversed_top_skewed_input); + File::create("04-data-UL.txt").expect("Error creating").write_all(reversed_top_skewed_input.as_bytes()).expect("Error writing"); + + let total = total_right + total_left + total_down + total_up + total_upright + total_downleft + total_downright + total_upleft; + + println!("Right: {total_right}"); + println!("Left: {total_left}"); + println!("Down: {total_down}"); + println!("Up: {total_up}"); + println!("Up-Right: {total_upright}"); + println!("Down-Left: {total_downleft}"); + println!("Down-Right: {total_downright}"); + println!("Up-Left: {total_upleft}"); + println!("Total: {total}"); + + total +} + + +fn match_forward(input: &str, needle: &str) -> usize { + input.match_indices(needle).count() +} + +fn reverse_string(input: &str) -> String { + input.chars().rev().collect::() +} + +// shamelessly copied from the internets +fn transpose(v: Vec>) -> Vec> +where + T: Clone, +{ + assert!(!v.is_empty()); + (0..v[0].len()) + .map(|i| v.iter().map(|inner| inner[i].clone()).collect::>()) + .collect() +} + +fn stringify_vec(grid: &Vec>) -> String { + let lines: Vec = grid.iter().map(|l| String::from_iter(l)).collect(); + lines.join("\n") +} + +fn vecify_string(str_value: &String) -> Vec> { + str_value.split('\n').filter_map(|l| { + let chars: Vec = l.chars().collect(); + if chars.len() > 0 { Some(chars) } else { None } + }).collect() +} + +fn skew_vec_bottom(grid: &Vec>) -> Vec> { + // (0,0) (0,1) (0,2) (0,3) (0,0) (1,0) (2,0) (3,0) - - - + // (1,0) (1,1) (1,2) (1,3) - (0,1) (1,1) (2,1) (3,1) - - + // (2,0) (2,1) (2,2) (2,3) ==> - - (0,2) (1,2) (2,2) (3,2) - + // (3,0) (3,1) (3,2) (3,3) - - - (0,3) (1,3) (2,3) (3,3) + + let col_count = grid.len(); + let row_count = grid[0].len(); + let skewed_width = row_count + col_count - 1; + + let mut skewed_vec: Vec> = vec![vec![' '; skewed_width]; row_count]; + + for row_idx in 0..row_count { + for col_idx in 0..col_count { + // swap and skew + skewed_vec[row_idx][col_idx+row_idx] = grid[col_idx][row_idx]; + } + } + skewed_vec +} + +fn skew_vec_top(grid: &Vec>) -> Vec> { + // (0,0) (0,1) (0,2) (0,3) - - - (0,0) (1,0) (2,0) (3,0) + // (1,0) (1,1) (1,2) (1,3) - - (0,1) (1,1) (2,1) (3,1) - + // (2,0) (2,1) (2,2) (2,3) ==> - (0,2) (1,2) (2,2) (3,2) - - + // (3,0) (3,1) (3,2) (3,3) (0,3) (1,3) (2,3) (3,3) - - - + + + let col_count = grid.len(); + let row_count = grid[0].len(); + let skewed_width = row_count + col_count - 1; + + let mut skewed_vec: Vec> = vec![vec![' '; skewed_width]; row_count]; + + for row_idx in 0..row_count { + for col_idx in 0..col_count { + // swap and skew + assert!(col_idx + col_count - row_idx - 1 < skewed_width); + skewed_vec[row_idx][col_idx + col_count - row_idx - 1] = grid[row_idx][col_idx]; + } + } + skewed_vec +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_skew_vec_bottom() { + let input_vec = vec![ + vec!['0', '1', '2', '3'], + vec!['4', '5', '6', '7'], + vec!['8', '9', 'a', 'b'], + vec!['c', 'd', 'e', 'f'] + ]; + + let skewed_vec = skew_vec_bottom(&input_vec); + + let expected_vec = vec![ + vec!['0', '4', '8', 'c', ' ', ' ', ' '], + vec![' ', '1', '5', '9', 'd', ' ', ' '], + vec![' ', ' ', '2', '6', 'a', 'e', ' '], + vec![' ', ' ', ' ', '3', '7', 'b', 'f'] + ]; + assert_eq!(skewed_vec, expected_vec); + } + + #[test] + fn test_skew_vec_top() { + let input_vec = vec![ + vec!['0', '1', '2', '3'], + vec!['4', '5', '6', '7'], + vec!['8', '9', 'a', 'b'], + vec!['c', 'd', 'e', 'f'] + ]; + + let skewed_vec = skew_vec_top(&input_vec); + + let expected_vec = vec![ + vec![' ', ' ', ' ', '0', '1', '2', '3'], + vec![' ', ' ', '4', '5', '6', '7', ' '], + vec![' ', '8', '9', 'a', 'b', ' ', ' '], + vec!['c', 'd', 'e', 'f', ' ', ' ', ' '] + ]; + assert_eq!(skewed_vec, expected_vec); + } + + #[test] + fn test_transpose_square_vec() { + let input_vec = vec![ + vec!['0', '1', '2', '3'], + vec!['4', '5', '6', '7'], + vec!['8', '9', 'a', 'b'], + vec!['c', 'd', 'e', 'f'] + ]; + + let transposed_vec = transpose(input_vec); + + let expected_vec = vec![ + vec!['0', '4', '8', 'c'], + vec!['1', '5', '9', 'd'], + vec!['2', '6', 'a', 'e'], + vec!['3', '7', 'b', 'f'] + ]; + assert_eq!(transposed_vec, expected_vec); + } + + #[test] + fn test_transpose_long_vec() { + let input_vec = vec![ + vec!['0', '1', '2', '3'], + vec!['4', '5', '6', '7'] + ]; + + let transposed_vec = transpose(input_vec); + + let expected_vec = vec![ + vec!['0', '4'], + vec!['1', '5'], + vec!['2', '6'], + vec!['3', '7'] + ]; + assert_eq!(transposed_vec, expected_vec); + } + + #[test] + fn test_transpose_tall_vec() { + let input_vec = vec![ + vec!['0', '1'], + vec!['2', '3'], + vec!['4', '5'], + vec!['6', '7'], + ]; + + let transposed_vec = transpose(input_vec); + + let expected_vec = vec![ + vec!['0', '2', '4', '6'], + vec!['1', '3', '5', '7'] + ]; + assert_eq!(transposed_vec, expected_vec); + } + + #[test] + fn test_match_forward() { + let input = "abcXMASXMASxyz"; + let count = match_forward(input, "XMAS"); + + assert_eq!(count, 2); + } + + #[test] + fn test_part_one() { + let result = part_one(&advent_of_code::template::read_file_part("examples", DAY, 99)); + assert_eq!(result, Some(18)); + } + #[test] + fn test_part_one_2() { + let result = part_one(&advent_of_code::template::read_file_part("examples", DAY, 2)); + assert_eq!(result, Some(8)); + } + + #[test] + fn test_part_two() { + let result = part_two(&advent_of_code::template::read_file("examples", DAY)); + assert_eq!(result, None); + } +} diff --git a/src/bin/04.rs b/src/bin/04.rs new file mode 100644 index 0000000..21879d0 --- /dev/null +++ b/src/bin/04.rs @@ -0,0 +1,68 @@ +advent_of_code::solution!(4); +use itertools::Itertools; +use tap::Pipe; + +pub fn part_one(input: &str) -> Option { + let grid = input.lines().map(|l| l.chars().collect_vec()).collect_vec(); + let row_size = grid.len() as isize; + let col_size = grid[0].len() as isize; + let is_valid = |row_idx, col_idx| (0..row_size).contains(&row_idx) && (0..col_size).contains(&col_idx); + let get_value = |row_idx, col_idx| is_valid(row_idx, col_idx).then(|| grid[row_idx as usize][col_idx as usize]); + + let total: i32 = Itertools::cartesian_product(0..row_size, 0..col_size) + .flat_map(|(row_idx, col_idx)| { + [(0, -1), (-1, 0), (-1, -1), (-1, 1)] + .into_iter() + .map(move |(row_direction, col_direction)| { + (0..=3) + .filter_map( + |magnitude| get_value(row_idx + row_direction * magnitude, col_idx + col_direction * magnitude) + ) + .collect::() + .pipe(|s| ["XMAS", "SAMX"].contains(&s.as_ref()) as i32) + }) + }).sum(); + + Some(total as u32) +} + +pub fn part_two(input: &str) -> Option { + let grid = input.lines().map(|l| l.chars().collect_vec()).collect_vec(); + let row_size = grid.len() as isize; + let col_size = grid[0].len() as isize; + let is_valid = |row_idx, col_idx| (0..row_size).contains(&row_idx) && (0..col_size).contains(&col_idx); + let get_value = |row_idx, col_idx| is_valid(row_idx, col_idx).then(|| grid[row_idx as usize][col_idx as usize]); + + let total= Itertools::cartesian_product(0..row_size, 0..col_size) + .filter_map(|(row_idx, col_idx)| { + if get_value(row_idx, col_idx) != Some('A') { return None } + + let first = [(row_idx - 1, col_idx - 1), (row_idx, col_idx), (row_idx+1, col_idx+1)].iter().filter_map(|(row, col)| get_value(*row, *col)).collect::(); + if !["MAS", "SAM"].contains(&first.as_ref()) { return None } + + let second = [(row_idx - 1, col_idx + 1), (row_idx, col_idx), (row_idx+1, col_idx-1)].iter().filter_map(|(row, col)| get_value(*row, *col)).collect::(); + if !["MAS", "SAM"].contains(&second.as_ref()) { return None } + + Some(true) + }).count(); + + Some(total as u32) +} + + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_part_one() { + let result = part_one(&advent_of_code::template::read_file("examples", DAY)); + assert_eq!(result, Some(18)); + } + + #[test] + fn test_part_two() { + let result = part_two(&advent_of_code::template::read_file("examples", DAY)); + assert_eq!(result, Some(9)); + } +}