Compare commits

...

10 commits

Author SHA1 Message Date
0ed8ae54de day 9 2022-12-09 15:13:38 +01:00
80e67c2517 day 8 2022-12-08 14:11:09 +01:00
5b62118782 day 7 2022-12-08 12:57:35 +01:00
fa85d1e093 day 6 2022-12-06 10:23:57 +01:00
a6193bfff2 day 5 2022-12-05 23:12:35 +01:00
80a6434956 refactor: use string as output type 2022-12-05 23:04:06 +01:00
7f9ce3e21f day 4 2022-12-04 15:03:15 +01:00
e26bd81389 day 3 2022-12-03 14:14:00 +01:00
346c556ee9 refactor: use shared read_input funtion 2022-12-03 13:21:58 +01:00
eb168b1532 day 2 2022-12-02 20:20:28 +01:00
25 changed files with 8852 additions and 32 deletions

137
Cargo.lock generated
View file

@ -6,11 +6,148 @@ version = 3
name = "adventofcode22"
version = "0.1.0"
dependencies = [
"itertools",
"once_cell",
"path_macro",
"regex",
"rstest",
]
[[package]]
name = "aho-corasick"
version = "0.7.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac"
dependencies = [
"memchr",
]
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "either"
version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797"
[[package]]
name = "itertools"
version = "0.10.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473"
dependencies = [
"either",
]
[[package]]
name = "memchr"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
[[package]]
name = "once_cell"
version = "1.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860"
[[package]]
name = "path_macro"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a6e819bbd49d5939f682638fa54826bf1650abddcd65d000923de8ad63cc7d15"
[[package]]
name = "proc-macro2"
version = "1.0.47"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179"
dependencies = [
"proc-macro2",
]
[[package]]
name = "regex"
version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e076559ef8e241f2ae3479e36f97bd5741c0330689e217ad51ce2c76808b868a"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax",
]
[[package]]
name = "regex-syntax"
version = "0.6.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848"
[[package]]
name = "rstest"
version = "0.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b07f2d176c472198ec1e6551dc7da28f1c089652f66a7b722676c2238ebc0edf"
dependencies = [
"rstest_macros",
"rustc_version",
]
[[package]]
name = "rstest_macros"
version = "0.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7229b505ae0706e64f37ffc54a9c163e11022a6636d58fe1f3f52018257ff9f7"
dependencies = [
"cfg-if",
"proc-macro2",
"quote",
"rustc_version",
"syn",
"unicode-ident",
]
[[package]]
name = "rustc_version"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366"
dependencies = [
"semver",
]
[[package]]
name = "semver"
version = "1.0.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e25dfac463d778e353db5be2449d1cce89bd6fd23c9f1ea21310ce6e5a1b29c4"
[[package]]
name = "syn"
version = "1.0.105"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "60b9b43d45702de4c839cb9b51d9f529c5dd26a4aff255b42b1ebc03e88ee908"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "unicode-ident"
version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3"

View file

@ -3,7 +3,11 @@ name = "adventofcode22"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
itertools = "0.10.5"
once_cell = "1.16.0"
path_macro = "1.0.0"
regex = "1.7.0"
[dev-dependencies]
rstest = { version = "0.16.0", default-features = false }

23
example/day7.txt Normal file
View file

@ -0,0 +1,23 @@
$ cd /
$ ls
dir a
14848514 b.txt
8504156 c.dat
dir d
$ cd a
$ ls
dir e
29116 f
2557 g
62596 h.lst
$ cd e
$ ls
584 i
$ cd ..
$ cd ..
$ cd d
$ ls
4060174 j
8033020 d.log
5626152 d.ext
7214296 k

5
example/day8.txt Normal file
View file

@ -0,0 +1,5 @@
30373
25512
65332
33549
35390

8
example/day9.txt Normal file
View file

@ -0,0 +1,8 @@
R 4
U 4
L 3
D 1
R 4
D 1
L 5
R 2

2
input/day0.txt Normal file
View file

@ -0,0 +1,2 @@
123
456

2500
input/day2.txt Normal file

File diff suppressed because it is too large Load diff

300
input/day3.txt Normal file
View file

@ -0,0 +1,300 @@
qFdBBvtHHfvRlfvsqldvqjPpQmnQmjnjjjTRTLGRNG
ZCWhhCsJCzSJzSbzgsmPTGNNPPNGjgLTLjgn
WJZsbJMwJcszJcScwhVltFwBFBlqddvFdHDfqq
crtTsGTtqFThGQGCrsjTwdNJwpRdnJJwffRClpSf
PWVBPVHLvHHVgvZWBzmPpnfRSJJRQnSRflRPSNSl
gmzBzDgzmZQWLDLLgVmDrqGhsscrqDMGhcqtqcFr
HsbcdVrsbVbcLfPqqQsqqtPj
mMBFzZRnmFMRBDnDFBGZDGdDqLjtdQtPtgfPfttgtqgq
BZvZZdJMBFdJhSvhbhchcHll
GNRSqRfcNTpfGCcqjfzBpDQPWBzgDpQsPWzW
rrSdnVHlbMdLdBDzgtBtBmQt
rbFwwnLFLFwlMLrFwFhMVLrGNSTfZTRhfTqjGJRRZTCNcf
QWTnQCnWNNWmTnSPQwmqDbcscbpcjPjVPbrjpq
vJhzZNlNNgdzgzJdlGzHHcHDpjsHqrvbVrbvrD
RzRdRlhLgtCwCWSLnN
SFTJFTTwTVVSJBnSTdvNNfWbZCZWNZCNNhBv
srLrcHDcsjtLcLLcrLctjlcvbDNhmWCvNhZWGZZhNvhZmb
rclgtMPrrSgVTgJCng
DbrhDzcDffbzNbZvZWSSqSTNSVWv
gCPltPmCPglFnPFwtGPhGPwTCTdZZWZVRvWqdRqVVdTdvR
hLBhlmlstcffBzrpfj
wFLLmhMfwZLDwmMNRhZwRLDvJgldbJHPdQvcQHHJQPgH
bjrVrTSSJdQHcVll
CGCSsCCBpspBrqbSttpbqWmWZRmfFRZhZMNNLFqFLm
zWGjjBHGjzzTWMjhtDDWtPPlJZPJpvqQrmZTqQQpmr
RFbVLcBVLRcRVcCsCCqvpCZqmplqQJmPrlvQ
FLNRRSSRgScSVLLLNdFdwjHjnftBtGMgMjzHgzjWjj
znVSqnqbqzSbzTHqDDZmlcFcnhDMnDmn
LtjsvdvLJdjfFwRRCCMlChwCpMcclCcZ
LgvjjfjFQVgNTgWq
SJRJRFFCMSsGRMMwtZJRCVTgqgTVgTBCVpjTjmmWlB
ccvnnpnDVqTcBVTV
vPHprdHdpnzHSMsSrMRZJGws
GddGrcGNHnGvnCHddvCSWqTSWsTwTWShbHlhhb
gDPzLRVZgQfpRRFQDDVFDfzhSzsTBqqqnqbhnWTSSlST
QVFfFgRQQgLtgffZRfpFPfntjrcrjCmtCdMMmjMdJJJNtm
jjmNcpGCNmDqqsBfnZnGGGRLsZ
lrmlVWlQQtWllgtbQVrWBnZsJgsRLfZLhZBBBffL
rWMVQtrFlbFlSSMHVSdHHNHdcdDcddzppzzm
bTpjpjcVTLmphbLppJwqzqwJLqqzzzgRLJ
sdHNbrvNHrqPvZZZPRww
bNQCrCNtNsSlhffhVhpVWFCW
lpNnpMMZZDbNbnBjcrbjvScFmbGj
wqhdqVqdscrjdLsv
HQftVqWCfhwqtCCjWwfqzzVPZRJQgMlggZMMMZTNMNTnNRTN
fvvGbFtVmtTwgtMT
WcCcClzPCCcczJJScPWWZzBDmwbhBBHSghgDDMTHMDBD
nWPljWzZWnbcbRsNFjFFdFdVjFsj
NQrcLNmQGRfGLHHLZgbbnpjZJJJndbgnlv
DWtThDWtzzhltWTwjbdpvjbgqjgg
VtSPFWtBPBFSFBWCStshWBmlRfHfMRcfQLQLLlmCrCcN
pbmwqJnqSJVwwDPCjZZzrZfD
QtssBTvNdNvNtQvQGpGhdjPjDjczZDfjhgPPDcgjgr
GltptQpMGNNpRWlWFVFHJFHLWH
ZLLsDGGVhZcQQLhrLshrVFwHnWqJnWMnJJJnqfWfGn
jMlPdTlPlgCgFpngFWFnJfpw
TlTNbdSSTSTmTjPMTCdBPjBMrLDczsZcNrDhRNDRQRLLRVVz
HDLpBqDVVTvwGDDNRT
PlVWjfhsPMMmWtlFNTrhrrvCCCTNNbvw
lsglfgVJmsfMjJfSqSzdZnLgqcnLnp
pfCDJWBpfDffpJLgQJzzVzNrgNgNgNhNzmVr
ZnnGZbGTPZnsnRFdTlbrwdrNzrrmmWwmwVwttH
GbPGRvTnZljWnpqSMMCjqJQSCf
ZgnFgwggznFrfrwfHhNMMr
pctLCLRhPHBLMLWfBL
JJcdJcQCCJmQJppmlgndnFslsVnsvghZ
WpMgTppWGSWWJmJDpJcJJhqm
zZzjZNHvNjPvNsbZLbRLzsPcqhVJSVttdwhwmdRhtdJRVd
sLbvvCZCPSSSbbPfNlQQTQGBllCTnMnWQn
fwbwswddwSbBfDBggMBPDPhHcPWDmhHhmWnWPC
FQFlzLCzQTlrTTzvltFqFrmhPHjnhhnnchcJWcRRmRRq
lpLzlFZzCltrTNlTztQLZfSMGBNdSBVwbBNVSMSbVs
FMmgbTFdgLSgFQdjrRPrQBPDdj
ZqqWRvsfGrrPvvPC
wZzwnqccRwRNNpRSMztSMMFbgzLTFS
qTwBPfTfqQDMDrssHdvtRHccHMjR
gWSZGWzGFhnFFgnhNsRHtRdsVjZcRjHs
jgplhpJJFgnDrrwfqprwDP
CWhMSRfWhVVnRSZnVVdsLQqQMzGqLBvGMQqczv
PHbpNwrjJplttvcclLlQzzDszc
NrJbJrFNNJNPrmwrtbjtNmCfSWfWhSZZfSWCsfShfFVR
VLhRPLGLRPRSStRRLwfGqfmDwbmqbqqDlD
rBSFvppnzTbwDwlDcFWm
MJrnJTMvMsrTsPtshRNPZdSLhL
BZBrRCrnCQBBnZfGqhGGMMRcthMhMG
TLjsCdDCPTvNssjdsPsDgsgqGcPHczchtHczWzPWzzlWhG
gsTpsdNbvNNjNSpsNDTsmCnSVQFmSFwZnQBnmnQQ
llbsNsWrmbrGbWCNtBjcCFBzQFZBCFjF
LdSpwgdqSgzwJdRdLMRHLjQQjHjFHctjHBDTZj
gSppgpSJMhpzwrhblfbhhlWlnW
DwhTvvsJZWsBnDzPpBLbFp
GHtNGRGNdzbMBBtmBt
NljlCSVSHdjGSQRGlCQSCswqfWzhZfTcfzcJvshJ
lmsGNFsDGqCbFQBbffjjwpzptw
hRQdvdrvrvSngWnvnHrTMfzfzRtftzwVTwwpzB
HnSSWrvLJvWJGFDsmFLPDFcQ
bwwpGphpLghpTvpWphvJlFLJqqltjSjVlSStSR
cmszZdDdBZzcNcDCDcNsmNMcqVjMJStFRJltVPVrlVPjVJll
HcdmcCzzzQcHNcsCdpnGnhwGgnRggHvbbR
CfMBbwBGbMbDCFrDvhFFDT
mjzRjjRdSmjPnzFZgnnrTT
cmSsVcHjLHTwMfLBpBpBwM
whqqfZzgHvhSzzVNVDbpDbmbVbNpJD
GcQFntGTCCcCTMCTGBlJsJsDDWpRbWBsJpNS
FnPcrGFFdddMnCnTqgqgqPHfLjLqgSzz
zMSzzjssFdGnszRtNftqqwFHbbZw
RRPLVrgrwHqBqgwt
rPWmLCTCQlCQQmmrWLrQShJshhzdhhJjcSjlzRds
lvgvCDfPqLHppqpCCDJncbntttbBtBBVHjwtrB
TdddszSQsWcngjzVbcVZ
hRWsTRTGQhNRGhRTFSWmlpgfqlvLmplPqvvGgv
LbWFLQdWWPwWSjSHPHRfppHHDRpggR
zmqqNNzlzmnzzNCmVCmtBzpfGsfpBgDgspprcfcfsrRB
qNNVNJtNmmmNzznVJzvCTDZWhvZZjZFbWQQhFhbZSw
DjdHqJVVhHVZjhDHPWtDtZLFBRBFmSRTFSbwmRRTffTTJf
NNznnGlgMQsnQzNclzpfSRSMRmfPMmFRwBwB
vzrcGcNcPPvHvHPt
wLCcmZwWTNtZNdMSMGSCnJGGMB
RFbHsPhVvFPRjlshhrnQnGjQGSdSqJfqnQBM
HhzVlFHhPwzScmSTgL
TNlBhDNvNBFpJgpPPpDQ
jjfCdCZZqsCZsbdqPgFGGMRzSFMqQMRS
jnWPtWssCtWcmZbbtstvnrrvhVBhTNNhBHlBlL
DZwNWPDzPVWbJngrQjrNnrQcMg
GRRfttLBhhvTvmLmFcFcgFFSnjWrnsrG
TLthBWtTRLHqhlLLfmhBqVPDJVdPwzJCPPZHwdDdVd
GGVhrVSMQwQqfVssVvnWFgvgWn
jtlcRBBtQRmpWsjzFCvzWnvF
QPcRbpppDmNDtPPblZMfhZdDwdMrqSSGrq
ZRrdtBdQvQsWnnfWFZsF
bJLcMzNDLbMgwfnGMWFv
lpvhmzNDmDmlNbzbmrVVPrHRCPHQBVCP
rZllQrsRWrlQswccMVbGbVbTdcQQ
NtJCntLSHCjznfLTcGGGqWMdWM
jCtzzSFthhSSSjPJrFDlvWrlDZRpwpRZ
mQmbLjbrLQjLmTtwwWBTTvWjtt
BHSqdHclHHNFlppNqWPwfwDvTfDPPtCw
ddSGMGHcdcMhMZnBbmbZmgGJJg
lvvBzvDnlzjfPnfjnQPlldRbVbRqbqqCgsqqVpQQgVqc
NNFtGNMtTNFmJNGNZtZMwVRTTcsCpVTbbgCbgRhscp
FGNGZMtNLWmmJWGFWJGLSNtPrPnBfDzzvjnDBzpnvDBLnv
fwvQRFQvQqwpwNJrwN
BstDnBjhjBhnshSptpJzWqNppbfr
CsDjCdZcBCDcjnfDHfhnfggZMGlgQVmgMTRmgVGMMl
MwlBVqVlsgnmzwJsvjhWZhGPvjvRRWzG
QNQpQpftHdHHCHGfSpCrQNdSrDRDhchhjvjcPrRRWrPvhZjv
LtLSCTSGfHGdGwswnqsggssTqV
qDDCHjzjznTvWshZQWfnZZ
PFFmmNMMtNMVFtczcFPJNrLhZwQZQsSvvSvWvGQQJQssss
tFzrrPPNNFlzVrpRTpblRDqjTpDC
DWDrrBdpmdpBrCgDthdtfcHsqJsCqscqwfsjzHcq
TNLNFNSTQNQTSnlMcczVJjVzsqLDDfJJ
TFPZQRvvlMSPPtRWDtmDRWrBGr
LWGVZdrvWdpLGWRsjPMsHmdHdHldlj
zJzznChzzzCSfTgMhCPDmlDCbmlsmjDDQj
nSTTJhJtnShNtzwhgNrGRRWZZRvMWMtVrqGp
PbPmtNmBbPlqBvqlDJBT
LpGVDzVpVZqqSTvq
pMnWGLRLRppnGpGndrGPtgDCjMPmbPgCQmPPNN
sqcZcbZZpcZspcCCRMmznWGWdLWhwDRGTTWggT
NjFSJgVHrvfVtrGzWdSznDwLSTLn
jFrBNVVjBFNvHrFHBlBFFpMslPgPcpMPmcQPPZCgpP
frddqsThtsTfTbPcvhsrbsRLpRBNRpmDpGmRGcRNLpGp
QWJHCJwWzlHZQZHQCJJRzRqnLDGRGpnGBRnNDN
CVwHCClJjQgWCZVZQgMwSdthjrqvrSPPhdbqtPhs
TvdphBBhhhCgdLNNJJJLWz
fVcsqRVrPcnJWgDnJN
JlqsRJtssZwqwVtPwltRPsHHbFTwTFbpjHhQjTQbvpTF
cQSnPDDQJGNzwnNpZb
RHDrssVRDHRgsRFHRlrVwzzpNGZlfZdppZdwGNZb
sHCHtDgtCjVVLFChqPMhBCMcSTqB
hdbQbqcCCQcqFbCbVdcWCQQlRMBtGlRHBtBMpHhpHThZMR
LLsSLLfgJPrgPnssnmlZtlZpHGHVGfZVtZpl
PvmvgmvvnzmrSsSLJDqDNzqFDQdDwzWWbV
HNNjnLbpLGHvWJDhdWWPpWDW
lVcSNgcSVclhRlPZPRCDCR
cqmSQrwwrrVSrtQFqVNmFwjQnvjHzBbLLGjfjzHTzvnH
QmvWVppPHQQvbbvmSHSpPzfzwnWMTZFFzwFMCzLnwT
jGBljlNNjgDtGDrNjjtjqqDRnMzRLnFzCFnMfRfMzCnttF
jqNrrGdJcdgLjqDqBrDQbbmhdQQmmpPbphmbVv
ZHQCggVHHRDWvbfjGptVtLvL
nnFwnwrDDMShnhFrFLLLpjvPlPGGtLGb
dcNSMhrrTDCBCsWgCTQW
HqDDLGtDdCnhfDnwnV
PmlJsJTPlbdBTzTnzhnnCCWWzV
lSPjMScggsScgjSMMbqHLFGrRLGHRZZtdrcG
ZVVtNNppdZSdLtCPqnHhqJJFtb
zgwwQBfwmGgSrDfgrrGBggzHCnbJbqbCJFnqhHBhnHHCqJ
rvrzfmlRrgDgmrzfggvwzvdjjcccLjMjVcVcsVLjVSZR
dppcLRHpphchhNhSddjzHzWQWQLtrMsrWQCWCsMZssCZ
JGfBfJJfBqvGVlVbDBwDBDBfZnrQsMQtssMttssDsQMWZncn
qPVwlgPBmjpPhcmS
zGPnzBgPzPnPlHZlDDHnZBNCvrtcjcjmMcFzNcNFmFdc
qQpfsLTTSspqTfJdmdCtMjdtjvJcmr
bfQqqSrswLLrfpLTqprfTnDVDVBBbgHPDHnhDPgDbV
JssTnsdFztZLdNJnNtTsLNZGqlbGFBqrGMHqHBcFBqMFMH
CCgSfgPSvSfhpShSRppCdfrlqGHGGcHmclmqbbqbqlPc
wvVSVjQSSQhRVvfQChvZZsdtJstjLNLZDJnLss
CmfNNNZNqDrnDjMhZM
gdczzGtdFcddtWQgGGMnVhnjJwnrJFDPTwMP
dlvcdzdHtzQSLRSfmhLSqv
ZpFFLcHFZZRRmJVZgD
PzhrtQntzcrjCRJtbtRgBsBRVR
zdzWfCzhQzlhWfWhlvpFNlpSqcMSHHMv
NrrMgMhNQhNjQrtqtPtwVtZpggPw
TfRLndnLFCRFTFbbRDHwpVqqBBwsHwZsfH
TJFRdLlRThrlcvZcvQ
scrwRVjbQvQBzsBC
gMfVqNnVmnCBQDTvdn
SMqhWqVlmWSmqMVRSJjjpcFrcLpJrR
HtSQHQntHsHMrtHnGfHQVVzLvSBSVvVVSFNJzzVN
cmPRmpqlpPmcgTlTpjJNjjVDvDRFNVVBFD
hlmCpmqmpgqpZTlcdQHFQfbHHZttwMQwtr
VpWgbgfwCjbftwVPPpGQFQhzTBQTBGPzqFTS
dbRbDcRrsnsRrLZmLRDZldDZqTNTGqqFFzGGhSTNTFTzNmNT
MlLdHlDDHrHclMMrCwgHCCwWwCbCCjjg
GGNLhfDMVcVrcGsT
jSJQFjHbwPFSvQSHwZFvHSHrqCCrrTsqBwNBrcBNsVTsqq
QjZSjZJZPvNRZJQPnSZbJZRWLfnmgDlmhdhWgWLdMdfmhM
CgGnzPNggCJtNTgTZTPZzZZvvcDcDDdqDFcJssJDHDqvHq
jhhrrLVlmLRRnRflfVbFHHHqdVsDqcvbHVDb
jWfWwrlmRRnQmPzZNGZPBNCQTB
NzDDhwNmhvtrGmNCvWRVbcRRVTcHHcVFTbwV
LgsPlLsQgQdJsLdldtpgFFTMbnFqTcMbHqFcPncq
dgsJsLLLggljrhtGNNtSjvGm
ptzSrZtzhsmmtPrhLFRFnjnnLMsnfLRL
HvwVDHwWWgGDGdHgqVDWDMnRnTjFNTNjfLJvRRRRRR
DwDgWgQbDDDHwBBBWdwQGVHhlhlZZSSmztfcppSBhzZcZp
CWmWRzlMJqWDWqCJbqDlCBBVLMQHVMGrfMVtQZrsLL
SnhPdFFPNZsBBdHtVQ
SSPcFFgnwnSpwvcSjwzCqRzTmJbpJCRBmbbD
wQbqGWWSqwrbGWWWGjbNMJPfgfnnDmPnPNLfjN
tJFztRZCvVRCztZFZRVgmMhmgNLfRfnmDPNPhm
BFCVZzpVFlHCdbQqcTcGlJbbSG
tttfLPZZQZTlZPHHPWgMVvBnjmvjnjgGBQ
FzcNDDDrNzprrrshprhFJtVGVnjtjGvnhvVnnjnjGM
RDqJNszDPfdqPtlT
QCJdMjCQbdBjSbTHDsbWDDwHTP
zlvlmqzqGfgdNzLldrHwwPGpWDrPGZWprr
gfVfRczVqcRzmdcSQMjQSQCSjQCQ
RhhCGhRBShjjRfpwppFTfFHZHZZD
qzdqzlnPPctPdmtPdTZbwQvvwqvHHvZpwZ
nVTVTcsWmWSRhhRVrGVB
GmshRMnzqRGsPNwMwcrrpcVV
CDCbFCLvCgfDSFLslgDpwpLtTwwcPtNNtTTprt
JvSFbSbbFllJlgDvlJbgdRhRdqzBGnzshZnRRRnHBZ
ShJhtcsvvvQbnnsccVTLVTppWqddpVnLWp
NdzPrPZgPMNNrmzpTzpTCjWfzCpzVL
dZgHmZRPPZRlZmrPDtDRccvbtQQbJbRS
wqjLjwhznhBLqLWGfvSlvcmlrJsqrtJTJJ
PwbpFPQDRCDrDJTrTmvs
gbZVFbZHgwHbCdpCRMnffNLhWnnzMdzLLW
RVVGSNTTRlNqHblBNB
JfwJMvLLZwLsMJwWMJfwLHBqzFlvzpBQcqzblFbBqblq
wMCZJsgJCCCnsMHrgLLjSPSVTgShtRjTPhRRmt
lmQSSWdMHHLWgWqD
ZZtVGGGJrJvGVCwfgHNLccmNFFcqtc
vrCGPhvrTPdRBnsRTmmp
dDMDDjzCQjwCCcDgjSLLLsLNlmpplN
FqrHFTFRLCLVFBmS
JhHJhHRThrfPZPvhnTZZbWdwdwDDWtDzJDtbMtCW
ghwDzJRDwHmPthncSPncLLsPcvnv
MWCrNTCHrMVjQQMQcSdnpTLnFFdTcnTc
qbWMfWfNrWVQWfbjVBbqMfwDtqzmhmRRzGhtHhHhRwZh
fmSmnjTjrlzGlTzJdH
BrhRRQMrgQvgFFhQQbwpFvGGdZqZJqpJqHVpJGJLHdLJ
ggbDwQMsvsMQrFMFcWSPSCPmSsPfnnmP
cmNVbMrrrjcHDRcvfW
wQGdFfSThFsLhhHWvDCWDCJRCCjd
LtpStGhqrrpnfnpp
bvcccTqbgvpGndJtgdsgNd
wDQwQhtQhQRmSmjsJndJdBBJBJnlLS
hwhmRrzFVjtwzDmrVFrvPCcCMVPPvfqpCCTVVb
jRrRNPNRWjPRWPRQNjQjThTCzBBzDCFBGzgDFGGQ
dnppLwmwCnvtlqltvtnTGBThGhdFZhgzDzGccD
MvnqpLlMqCqCHMjWPPHMSHSs
NNpNNvpvBdtTrMFFMhSSwzjzchzwhzwL
VVndHqflQZZZgHSLLhjzRSmZRhcR
glGgnqbQlngnWCGJpJprtrtFrdPPGs
WqwRjzGtRzZZRRGjWBJzjwmfMTHGGssTTDsrLmmmQLMD
SNdvSdFlSNNhSPFFcPFclbQQslHmfHTDsTQMLgDTmHQQ
CNcCFvpdnWpjWwJf
PVPnVHcnRncGZqbVzHVPnnLbSMjwrzWMjSwDtWwWtwWhwDWz
pTfsQCshCllpglWWSjBMSQSrMrjM
hvpvppggCpJTvTmshgfsmZRRHqbcLPHZmPLRnmPZ
LQbhVZZmZhZjBdbGmgHqnHTmvqgnnWHr
SzCfDFFNRfsSFFMFfvprvpWzqzgqTwHTvp
CDNDFJgMDSQhjVdPJLQG
plpdLdpjjrrHJJjLrrHLFdbzzCcvzgFgcwggzPMFvvcMhM
GRtSBQNsQlMPRzRlzw
ZSTtsmBlmjLLpnpH
hglGNVSdNSghzSgCBhDFLBMBtFMMFtHtbtLL
frQZccRcqGFmFHrJ
nvfGZwvTwGTfQwvfTwfgnCSlpdnzgzslppCsCV
snTSPbQnTTnQgbmsTJsLfZwjffhpLnGRjpGfjL
dcNWcNHHlNtWHHlCtltWNFNMLZwjpGfpmrZfrFprrRGpwZfp
HmdNWCmDMVvQPDgqJs
GGFtSngQLfnSnQffgPnRgFRGRwmRJvwbBbJDwjvTbjrwhJvJ
WHClslcNNWcqNWlCZdcHsVrThBwBjbhDTDBhrvDZJTwm
NWVqqcHHNpsNcNVdVlhCMlHQQMQQzLfzQPttFGPMLSLgtF

1000
input/day4.txt Normal file

File diff suppressed because it is too large Load diff

511
input/day5.txt Normal file
View file

@ -0,0 +1,511 @@
[J] [B] [T]
[M] [L] [Q] [L] [R]
[G] [Q] [W] [S] [B] [L]
[D] [D] [T] [M] [G] [V] [P]
[T] [N] [N] [N] [D] [J] [G] [N]
[W] [H] [H] [S] [C] [N] [R] [W] [D]
[N] [P] [P] [W] [H] [H] [B] [N] [G]
[L] [C] [W] [C] [P] [T] [M] [Z] [W]
1 2 3 4 5 6 7 8 9
move 6 from 6 to 5
move 2 from 5 to 9
move 8 from 9 to 1
move 3 from 5 to 4
move 9 from 1 to 8
move 2 from 1 to 5
move 1 from 1 to 8
move 14 from 8 to 2
move 1 from 1 to 2
move 2 from 6 to 8
move 2 from 5 to 7
move 6 from 8 to 6
move 4 from 4 to 2
move 2 from 4 to 9
move 5 from 7 to 4
move 2 from 7 to 5
move 6 from 2 to 4
move 2 from 4 to 7
move 4 from 5 to 8
move 1 from 5 to 2
move 3 from 3 to 5
move 3 from 8 to 3
move 4 from 3 to 7
move 2 from 9 to 8
move 1 from 3 to 7
move 1 from 6 to 8
move 5 from 7 to 1
move 3 from 7 to 2
move 1 from 6 to 3
move 2 from 5 to 9
move 5 from 4 to 2
move 3 from 5 to 9
move 5 from 9 to 6
move 2 from 1 to 3
move 4 from 4 to 1
move 2 from 8 to 1
move 18 from 2 to 5
move 3 from 4 to 1
move 1 from 1 to 2
move 1 from 6 to 8
move 1 from 7 to 1
move 10 from 1 to 5
move 1 from 1 to 5
move 3 from 8 to 1
move 2 from 1 to 5
move 3 from 6 to 5
move 8 from 2 to 9
move 2 from 9 to 7
move 3 from 3 to 8
move 1 from 4 to 8
move 3 from 5 to 3
move 15 from 5 to 8
move 4 from 6 to 1
move 2 from 7 to 4
move 9 from 5 to 7
move 1 from 6 to 8
move 5 from 3 to 5
move 5 from 7 to 5
move 3 from 1 to 5
move 2 from 4 to 8
move 3 from 1 to 6
move 20 from 5 to 4
move 1 from 7 to 6
move 21 from 8 to 2
move 1 from 3 to 7
move 2 from 4 to 2
move 1 from 7 to 1
move 18 from 2 to 8
move 3 from 9 to 2
move 1 from 6 to 4
move 1 from 1 to 9
move 8 from 8 to 6
move 4 from 8 to 2
move 1 from 2 to 6
move 7 from 8 to 5
move 2 from 5 to 3
move 1 from 9 to 5
move 5 from 2 to 4
move 1 from 3 to 7
move 2 from 5 to 7
move 4 from 4 to 9
move 2 from 5 to 9
move 6 from 2 to 8
move 3 from 7 to 3
move 2 from 5 to 4
move 4 from 8 to 2
move 2 from 7 to 4
move 7 from 6 to 4
move 1 from 8 to 4
move 3 from 6 to 7
move 2 from 7 to 2
move 7 from 9 to 7
move 1 from 9 to 2
move 3 from 3 to 6
move 3 from 7 to 4
move 2 from 7 to 9
move 6 from 4 to 1
move 3 from 7 to 9
move 1 from 8 to 5
move 1 from 3 to 6
move 3 from 9 to 4
move 2 from 6 to 4
move 3 from 9 to 1
move 4 from 2 to 8
move 1 from 8 to 5
move 9 from 1 to 2
move 1 from 6 to 5
move 1 from 7 to 2
move 1 from 8 to 1
move 2 from 8 to 9
move 1 from 9 to 8
move 1 from 5 to 7
move 1 from 7 to 6
move 1 from 9 to 8
move 1 from 6 to 3
move 26 from 4 to 3
move 1 from 5 to 8
move 3 from 6 to 3
move 7 from 4 to 3
move 1 from 1 to 3
move 1 from 4 to 8
move 13 from 3 to 1
move 1 from 3 to 4
move 12 from 2 to 5
move 20 from 3 to 2
move 1 from 4 to 1
move 4 from 5 to 7
move 1 from 7 to 8
move 9 from 5 to 2
move 5 from 1 to 5
move 21 from 2 to 8
move 5 from 8 to 4
move 4 from 5 to 2
move 6 from 1 to 7
move 1 from 5 to 4
move 4 from 3 to 1
move 6 from 1 to 3
move 1 from 1 to 9
move 6 from 8 to 7
move 4 from 8 to 2
move 4 from 2 to 7
move 5 from 4 to 1
move 8 from 8 to 4
move 1 from 9 to 6
move 18 from 7 to 6
move 15 from 6 to 5
move 2 from 6 to 8
move 2 from 6 to 3
move 8 from 3 to 7
move 15 from 5 to 7
move 3 from 4 to 9
move 12 from 2 to 3
move 3 from 9 to 4
move 6 from 7 to 9
move 9 from 4 to 5
move 10 from 3 to 5
move 9 from 5 to 2
move 14 from 7 to 8
move 14 from 8 to 5
move 4 from 2 to 4
move 1 from 4 to 6
move 2 from 8 to 4
move 3 from 8 to 9
move 18 from 5 to 1
move 1 from 5 to 9
move 1 from 7 to 4
move 5 from 5 to 9
move 3 from 2 to 4
move 13 from 9 to 2
move 13 from 2 to 6
move 1 from 7 to 3
move 3 from 3 to 1
move 9 from 6 to 5
move 1 from 7 to 8
move 20 from 1 to 8
move 2 from 2 to 8
move 5 from 6 to 9
move 15 from 8 to 7
move 3 from 5 to 3
move 5 from 1 to 3
move 2 from 3 to 4
move 3 from 9 to 5
move 4 from 5 to 2
move 4 from 5 to 7
move 3 from 4 to 9
move 10 from 7 to 8
move 2 from 9 to 4
move 1 from 5 to 6
move 8 from 7 to 9
move 1 from 6 to 7
move 6 from 3 to 4
move 12 from 9 to 8
move 1 from 1 to 5
move 2 from 7 to 8
move 1 from 7 to 5
move 1 from 9 to 5
move 2 from 2 to 9
move 11 from 8 to 1
move 7 from 1 to 5
move 3 from 1 to 6
move 5 from 8 to 9
move 8 from 4 to 3
move 4 from 4 to 6
move 5 from 9 to 3
move 4 from 4 to 5
move 2 from 6 to 7
move 1 from 9 to 5
move 2 from 7 to 4
move 12 from 5 to 2
move 8 from 8 to 9
move 8 from 8 to 6
move 9 from 6 to 2
move 4 from 9 to 2
move 1 from 5 to 1
move 5 from 2 to 1
move 2 from 5 to 4
move 5 from 2 to 5
move 5 from 5 to 6
move 3 from 4 to 7
move 11 from 2 to 7
move 2 from 2 to 1
move 4 from 3 to 7
move 2 from 2 to 4
move 6 from 1 to 4
move 1 from 2 to 8
move 2 from 9 to 5
move 4 from 4 to 3
move 5 from 4 to 1
move 2 from 2 to 1
move 1 from 8 to 5
move 14 from 7 to 6
move 3 from 9 to 2
move 15 from 6 to 8
move 4 from 1 to 3
move 2 from 2 to 3
move 1 from 1 to 7
move 2 from 3 to 5
move 4 from 5 to 4
move 1 from 3 to 5
move 5 from 1 to 6
move 12 from 6 to 7
move 7 from 8 to 4
move 12 from 7 to 9
move 4 from 7 to 9
move 1 from 2 to 8
move 12 from 9 to 4
move 23 from 4 to 3
move 1 from 6 to 5
move 3 from 9 to 3
move 1 from 7 to 9
move 1 from 9 to 1
move 1 from 9 to 7
move 42 from 3 to 1
move 3 from 5 to 4
move 5 from 1 to 3
move 3 from 4 to 7
move 1 from 1 to 9
move 4 from 3 to 8
move 1 from 3 to 7
move 1 from 9 to 1
move 2 from 7 to 8
move 8 from 1 to 6
move 2 from 7 to 5
move 9 from 1 to 2
move 5 from 2 to 3
move 3 from 2 to 4
move 20 from 1 to 2
move 1 from 1 to 5
move 1 from 6 to 7
move 3 from 4 to 7
move 2 from 3 to 6
move 3 from 6 to 1
move 1 from 6 to 4
move 2 from 1 to 6
move 3 from 5 to 9
move 1 from 4 to 3
move 2 from 7 to 4
move 6 from 8 to 4
move 1 from 1 to 9
move 1 from 2 to 9
move 2 from 8 to 7
move 3 from 6 to 2
move 5 from 7 to 5
move 4 from 2 to 5
move 4 from 4 to 6
move 3 from 9 to 6
move 4 from 3 to 1
move 1 from 9 to 2
move 7 from 8 to 9
move 4 from 2 to 4
move 2 from 1 to 7
move 3 from 4 to 5
move 4 from 2 to 4
move 1 from 7 to 4
move 4 from 2 to 9
move 7 from 4 to 3
move 1 from 7 to 3
move 6 from 2 to 3
move 2 from 1 to 5
move 10 from 3 to 6
move 2 from 6 to 1
move 2 from 2 to 7
move 2 from 3 to 1
move 1 from 7 to 8
move 11 from 5 to 3
move 2 from 3 to 1
move 4 from 6 to 1
move 1 from 4 to 6
move 8 from 3 to 4
move 2 from 5 to 6
move 3 from 3 to 5
move 1 from 8 to 4
move 1 from 4 to 9
move 2 from 6 to 1
move 1 from 5 to 1
move 9 from 4 to 3
move 5 from 6 to 9
move 5 from 6 to 7
move 13 from 9 to 3
move 5 from 1 to 8
move 4 from 8 to 4
move 10 from 3 to 2
move 3 from 6 to 1
move 2 from 7 to 9
move 1 from 8 to 3
move 1 from 7 to 3
move 1 from 9 to 5
move 1 from 6 to 3
move 7 from 2 to 4
move 3 from 5 to 2
move 8 from 3 to 5
move 7 from 4 to 3
move 5 from 9 to 7
move 1 from 7 to 1
move 9 from 1 to 8
move 9 from 5 to 8
move 2 from 7 to 8
move 3 from 8 to 1
move 10 from 3 to 6
move 1 from 1 to 6
move 5 from 1 to 7
move 3 from 2 to 8
move 7 from 8 to 6
move 7 from 8 to 6
move 1 from 3 to 5
move 5 from 7 to 9
move 4 from 8 to 4
move 3 from 2 to 8
move 1 from 7 to 8
move 3 from 3 to 9
move 3 from 7 to 4
move 1 from 7 to 2
move 9 from 9 to 1
move 5 from 1 to 9
move 4 from 8 to 6
move 1 from 2 to 7
move 1 from 5 to 3
move 1 from 3 to 7
move 1 from 1 to 9
move 1 from 1 to 7
move 5 from 9 to 6
move 2 from 7 to 6
move 10 from 4 to 8
move 1 from 4 to 2
move 1 from 4 to 1
move 1 from 9 to 2
move 3 from 1 to 2
move 1 from 7 to 3
move 1 from 2 to 1
move 16 from 6 to 3
move 9 from 6 to 1
move 6 from 6 to 1
move 5 from 6 to 1
move 3 from 8 to 1
move 11 from 3 to 4
move 1 from 6 to 2
move 3 from 8 to 2
move 4 from 1 to 6
move 5 from 3 to 2
move 1 from 2 to 5
move 1 from 8 to 5
move 5 from 8 to 3
move 4 from 6 to 9
move 2 from 9 to 6
move 3 from 3 to 9
move 1 from 5 to 7
move 5 from 1 to 6
move 3 from 6 to 4
move 2 from 2 to 9
move 8 from 4 to 2
move 9 from 1 to 7
move 3 from 3 to 5
move 3 from 5 to 7
move 12 from 7 to 1
move 5 from 4 to 6
move 1 from 4 to 5
move 7 from 1 to 8
move 5 from 9 to 3
move 1 from 7 to 4
move 10 from 1 to 8
move 1 from 4 to 8
move 4 from 6 to 8
move 1 from 6 to 9
move 2 from 5 to 1
move 4 from 3 to 4
move 1 from 1 to 8
move 4 from 4 to 7
move 2 from 1 to 8
move 4 from 6 to 1
move 3 from 9 to 5
move 1 from 6 to 5
move 1 from 3 to 7
move 24 from 8 to 6
move 3 from 6 to 5
move 4 from 6 to 7
move 1 from 1 to 7
move 7 from 7 to 6
move 7 from 5 to 3
move 13 from 6 to 8
move 3 from 1 to 2
move 7 from 6 to 3
move 12 from 2 to 4
move 4 from 6 to 9
move 6 from 3 to 1
move 1 from 2 to 4
move 2 from 8 to 7
move 2 from 2 to 9
move 6 from 3 to 4
move 12 from 8 to 2
move 18 from 2 to 5
move 10 from 4 to 3
move 4 from 7 to 3
move 5 from 4 to 7
move 3 from 5 to 2
move 4 from 7 to 9
move 1 from 5 to 4
move 3 from 2 to 1
move 4 from 3 to 6
move 7 from 5 to 6
move 2 from 5 to 7
move 5 from 1 to 7
move 9 from 7 to 6
move 8 from 9 to 8
move 1 from 1 to 3
move 1 from 3 to 1
move 10 from 3 to 9
move 8 from 8 to 4
move 1 from 3 to 8
move 1 from 1 to 3
move 6 from 9 to 1
move 5 from 5 to 3
move 5 from 3 to 6
move 1 from 8 to 9
move 19 from 6 to 2
move 13 from 4 to 1
move 4 from 1 to 5
move 6 from 2 to 1
move 2 from 9 to 4
move 1 from 3 to 1
move 9 from 2 to 3
move 4 from 5 to 1
move 5 from 9 to 6
move 4 from 3 to 4
move 3 from 2 to 7
move 2 from 4 to 8
move 6 from 1 to 9
move 1 from 8 to 6
move 4 from 1 to 5
move 3 from 4 to 5
move 1 from 7 to 2
move 11 from 1 to 6
move 1 from 2 to 7
move 5 from 3 to 7
move 1 from 3 to 4
move 1 from 4 to 8
move 3 from 5 to 6
move 8 from 1 to 7
move 1 from 8 to 9
move 1 from 6 to 9
move 1 from 8 to 5
move 11 from 6 to 5
move 12 from 5 to 2
move 1 from 5 to 2
move 8 from 7 to 3
move 1 from 5 to 6
move 2 from 5 to 6
move 3 from 7 to 1
move 6 from 2 to 6
move 1 from 3 to 1
move 1 from 4 to 1
move 4 from 6 to 2
move 5 from 1 to 5
move 10 from 2 to 3
move 2 from 9 to 4
move 4 from 5 to 8
move 2 from 2 to 7
move 12 from 6 to 7
move 1 from 8 to 2
move 10 from 3 to 4
move 2 from 3 to 5
move 1 from 3 to 1

1
input/day6.txt Normal file
View file

@ -0,0 +1 @@
jfnjjwbbqttplpvllqgllmdllfmllscssqmqzmmwzznqnwqnwnqnjjbdbpbtbdbzzzljljzjjpccrmmppzfpzfpfnfccfbbcqcrcffblfbftbfbtbwwwmgwmgmnngnllnfllhghcghhjppchcfcnfffllmmqbmmpwwwwlqwwqgqcqsqjqpqzqqdzdtztltslsljjfqfcqqgbqqqghqgqvgvrggqwggrgjgmmnrmmzgmzgzpzjjctcmtcmcnndppcvpvrrwvrvhrvhrhjhnjnvjnjrjggccvffnqqvfqvvnmvmqmfmfqqzfzbfzzzgpzpllrwwnpwpnwnwgwhhrrdnrrdjjzjszsjjbddcdbbvmbmqbqnbqbsqbsqqwbwhwggssdnnmttvnnvmnmhmfhhjchcttzdzdqqszzcwwhhwzhwhphqhcqqsggddfmmvzmzwmwfwzwrrbmrrnwnfnwnlwnwrwfwnnmtnnzwnwdnnbhhrphrhlhwllpmmbcbtbffmqffddjnjwwzpzfpptbbqqwbwzbzjbjmjljblbtlblqqhqbqggrngrgllbmbccmhmqmqwwqcqssqzzfjzjrjnnqrqssfnsnvvtgvvmsvsqqljjbsbrrjllvfvzfzmzhzzhthjhshlslfljfjqjpqpvvmpmhpmhmqqmmdwmddppjlplhlsstlssgnggrbblggffcdfdzzwqqtztqtwqtwtzzsjsbszsbsvbvwwjqjnnpdpccwssvdsdzzqbqbtbtqtmtltltvlvddzwzzfpzpjpgphprpgpqqwppdwpdplddvffcdffvpvqqgvqgvvrfvrvqrrcjcpjjpttftqqvjqvqsvqsvqssdpdbbbmcmscsddbhhgttwhhjlltqllnqntqtsscnntwwhswswlwggldltlttsjszsnznsznzccbtbblplnnmfmqmrrvjvhjhzhnzzgnnhrrdrllblpbllfdfjjssvnssvlsllnqqhwqhhhsgstsjstthrrhrghrhhfmhmwhwrwwsrwrfwwdnntqnnsvnvmnnfvnntztqzqhqnqjnnjfflbfllrsllqhqdqccgvgnvvcwcfccmssqnqhhqrrfrtrvvnjnpjnjjpplmlppvmpphjhppvhvdvssjcjrrtrdrrsvvbbjzzrtztgzghzhccwmccshhzbhhdwdwsdswwlcwllpblpphrppfhfnffrbbcgcmggnvnzzmvvcrrftrftrffcscvcsslbljlglzgzbzczszmsmbmnbbhdhvvsqvqhvvfrfddbpwgvztwwqcpzhhwnhphnrwldjmztsptbbgsqbqqccwbdqzvhfjlfldgphzbfprclgpfztbrgvsvfpghmdchscbdqjqgzvmrtdrfzbhgdvgznjcsmglcfwhdtpsljnvvzjcbbrczwtgpdmgpzhctvbbmvsjzthffsjqhfsdrclpqslbhnmpczwvggpzbjcchfjzjhhgtrmlgnzlndfvzrccgggrpmprbmjbfjjhzrhrtwgqdbgdlqghssrnmtmpvttcqwnwdzhgfnddgbqcsdvzvwqdnmmpwrwhfbqtcpqhvwbczrmjqzsntvdrncwjsmvvwcngrtlwtjmnctwrrtvphbjhlqmgzfsfsrblzzvmzlbhzjhwbdfpncdrfchmrqhspdszcjrnvwtmjzmsmzcdphsdzjgqswwrpdvlpvrdnhplnlmswvcrzlcmbtqtscjfwrnrctrvdqcqzwcvgvpdgrndrgsrvzftwpqjjgjhzwhvrjlqntdtcjdrqzhqlqqdffcgvttlhvwgggnwmdlvghfgjpsmntbvbjbbttrwsljwsrvtmznvqdptpwtdcwtcsfdjlmdqthqggjcptrqhbsbjzqqmvvjmgmppqmjmnjdqvspzlbgzjsjshpslmszqnzghsszpsmpzfcrqqjdwvtbnzstvvjzvtzgpptcmvmbvmpvpzvgfnwtlmdzhvhshtwvnbgwmtzqhcptflpqsqvmptchpfcbwhvjzdcnsnqrgdwfcthqfssnbqnvgvvhlzqfqmdlcwnshtvhhhpghjbmhdbfbqcvbnbvwbzcbbmjnrqmsdqnmnbsrvhggzsrlbwtfmgwrnlhrbrrrqdcspnrpnppngrtdqtbmbhcbjrlhpfjpdnfndmqvwvhlgmsntpwrlrwwqhwvzbpzqqggnbqlsjjqtbqjcdpmndgmtdhfbqrpdzzsnmhzmqqnbdqftqmnhfbdzdlfwgjsjhrcsmtfzgwbvbbzdrlbmcgmppqfppmbqrnsmrmhrdsvgcfmzpfnvrbbgfccfcbphszwdbnnwcjjvvlpdtfzgtslvgqwmsvlpzjcbqwqclrjrsgthhtqrqrhvsdfjntgllsvslrvdtnsdmrgtqcmswnqwlrwlfmcfftbjpvdnmczqzldsssszhjtqtqvqtwhjcqchjvqvntvzzzprbmjcctsqfdcvpbtsgnnsqtqnmjhrgqcjnzrdsgrbtdpqjbgcmnfwhnsrfwcdmncjzwcngfbmmrsbvgvvqpvrdjfsqwjdmqjdpzcbjjfmzjjgbnwqgrvpmbzdhsgtldrzvglscfwbmjltcrzrgdslgprwscwbrhtdtglznjdcvfjzjjqzntdqdbcrcbbmvnzdshjzcsfsgpghmgdqdwsnwjtvtbqbqccbcwjpnhdhzcvdssvnvqtvzwprhpgftdwwvgsbnlzzjppcrrwmrsthvjjrvrsdrbdqfgsjsmwfplpstrbnpdhhcblhjfwzngmhlwbvnfcbgwshspsbbgbldrvmcnczszpgnddrfwrtgcqjggrrcbjwrdjlrvtspbftrtjbzjwchpfnjctcjtwtpmtblczcftqlphdjczfrvtzlsglpvhqsqqblttdjrlczhrqsgpggmvnhpqtrfbpgvzftwtsmwhwswtpvtwnsshmlcffpcjshqhqqsjtpbgszscmcbnhjjtjmpgfdhgmljqmmwlfptstjjvqhcbjpjpwzwqflhslclzzjlmcttbsncqmfzhgnzwbdtnvfwbtztwbhtfsqjfzwmfflmbwnqzqhcjwdpbvngsgzlwvwcqhqjsndznbbdcqqhmjjpqjbsnvwztgmqwdcbbjvcndmhsbvbjnzlbscmgnjcrrwrfdljtcsgmwtffgcjflpzzdcnzvmrbnrjbbmhzqqjtgsrwqmmrhpndwlbnrtrhhpqlmdrcrtdmzsslrmffpftdjvfcpvvhzhjhqtrrsclvtbsccgmmqrjbqgbmpnbzlsncssdhmjppjptvddfgbbnjzjjldjlqjzhhttsclrmsgzctwjqqvtjlfzwgtffgrdjzwdcnrprlcswffghngrqcgsbzqhhvbfjtwcjlrrmbtqjdrgpnbftnmzqnndnqwgrqndlwmjnnspbhjlnzrnptnrmcjhpbfcqpvbchvdwthjlcrfpssgtfbsgfrftcrwttrspbsvzpvcczmdqslcdgfljvtjsdpjnwmdvfzfllrdrbgvpltzlqcrlwbncswhfvrdthspmhfhfdlvpbcqlmjfznhnqblffftgzqrtswnmtnvjprqqhhhvrscvbbzgmnlnprghfdjqbgjppjzjrnclfdssbmgspwcscnlcrrqmtlljrmcwgdgcqwvvjzvsjdjvsspszlcthwzrwqtzdgmqvnlvvzrvrpqqwswzcchncrpnjdmflvmhhwvrrstpvnszfrmvpdtpqpbdmwvvbbpjnwmtststtlcvqdnvqqphzlhhzbbbjssgdcnhlmwrzwvwmcmgrcngqzcnffqzfnvldpdjmsspgpbrzhnszfnljfcrgsjvqjjbstvghlcslhqlzhltpglwffrzfgjghssfgrptbnpbhqnhhfbjsnmsvltqpthdmzzrhrhhmzlplvrtdqfrfrppdpqnllblcfjqpdwznsbrhcncdpmztcrjrfnlwtznrmpbzqsbrqrbnthgfpshrdhnwjmrnsmsfqwdjsmsvhfrbdpjrwcvmdvvmdtfqjgmdsrqtctsdmznngbsrfjvhllgwt

1101
input/day7.txt Normal file

File diff suppressed because it is too large Load diff

99
input/day8.txt Normal file
View file

@ -0,0 +1,99 @@
222322213033345255533423306545562424165440655115256171674620442636621123532003623343351021112300040
110200134424131544435511513034235114207220346712122743100173142606016164253614600344452542043234001
130241122341034230060506400411050451436457131115555076655121366640166143420114243260041315245140033
044201155341204150154421223651421072455456424262034065175730703125367662022422056423113110423033043
341242043015141323013444355403421162464354167412604633147554242145501111651130260045523542142405124
104105335542011255154624541673170452421201174751065233125053535203606402110631631303264231443334523
022251232401442443240604013073567051751261046006060310057162723056356047312301014332262320405344224
005045010303234050011604134516553223421500156708426287011206217044163376565240420066564035322425031
433400302252163605112001002152533254526577025774185772532522645162112005222006334211222615202150023
514421532420126245053363421750507267400406222575606338538284336516406721212651434025136363121253314
145500111514555142462447264776571468434327564631361615475570716477174343523375640422633224154214330
450422253465464405163267335560338812657620448402661157163042574016476542116027110002556401004144041
315250435323412100266435752414460614818523238015312045767348145251346503446110002404643412031033110
335554260614516260275514014501773808684115234652573523444781127146772327147027164546041361322264113
552212024666234517403145053462886425015423537515312180012163268455035077313422213613314122403623422
554116462330326333717726071743410713076038127356572547895446465004382875747801510560161030046236534
105512113261674505476760210308840028176731611387575863387841328453867641286570312570624613101433450
201620055416403673411402684861111672134437556816818962692824522386258176417471541216750515352320263
100064152502471121126620147804267474177133917793419871348867649139837456117360472552512240365464543
434125501030234366461354647212882961264276372277577656415297827484543874788435871670574372006541656
354231632241763433421115602887827646148345796776349994375746935256394267608007744846602344220506426
320055542235452511286776246551436249838211357522914296165427513242286591157867047217062671166212220
630533311432024274286282747578525892839185272964722232382686773975896514921876068064231003115130640
054351445323650230374860016787334957865672953893647532392634515193476444753234751431776670673443625
122161643553043361465661234215425777375428328842756826885237348622679574815841302214422454334622455
310361643547534388254741787957515835394388424384634948237897787328779899668951118145613227272341123
553203043313014483116602739588328966436465926583287463393949837268357287783771610187112515346661056
361112773030626240167311193287631239264325599932928434546936456455966294955629721437363071113555100
223116444062065127823414995768335224963787626949338374537976548374532595386885887817322311512135354
165533456256685465133638322212456677839479985883969576788652889447966945526287513125252251227266360
050427105764654780569971719539982722683736488643647867988885285677254929533615456260111805471544762
612564200420147420768231643572583337363778975687346456978779493453467879471982875321111751612056704
154715031561015145153929571787325853755436888933888338496548994492842954225615713257348715562770051
042706406641878154761493925944579827297695668447479695968796749364665547438536956376866503052450261
111103621158778860687333696596964667768654674764978799646936368489433243322422814121081720104310375
256106134082036385674358835842774753667963458466356667369999749769462758256568366264544861030650514
412372400235780556155749924663448584664436986744984487994753564686643982758245295828805442657020150
316402420685442228837832744963276587378457659649458546869353576749393683736838444639170007152747441
343664452531110164851537867349623666557879764884856546986489797534353938689749649842383748067621444
004444326256452015911854963372679986857738459895764946977798848396957278774226377383181551011246332
324213275444575144439872496886847394968576968689979497664689986774356463883323582931740408774664723
167274127524542565635816457474433733785665667989859545577574597555588393452438866921746374545730347
312523103467383946589439238265777486435445747964954446957896799994745579737227145455742444466763354
042101230038108485461717949225836749699798599445858954785786668636987937236256346361252208168136312
447311762287744692475573737395565466544999496459956989976897778946499374824747773197595161266172226
371671376376358926187663595697867739555794587855655786889854499686796363666939989643254552166201754
305514713774776948141752365256767736786987588655596589796495868756859657723267975757697551713050730
505672367783107579727693596546487757757799568755578685859899884563658799498726941257953878711714017
457520154136801497456138426564536866785654498777579675857476597474753988679778543462582232418154231
050570576377124118562748278969974597659546757999795788577798949457569458597349739399679324147816176
064032506374261599382993468784374444687579995969557585785777758755334674823733669516557164016427124
346565566106489839877287435227877647875697657779798687889989777455747976752522588271842557284604304
320630184267887846149779595575797453867985966985895787576699496556963977669453525683498188461017663
155470636481748966932554775295985386984477788779777769886686888674939686949557211549684318562843364
355422032736165249425585822655654853976657576675655856568867858693534395443986997713966364825241516
014307615355116598362643769888978393745848466775686878856446548776874844332797955528420388441472072
434677415171655145937867232795798374659889895676897986696777754584999873398343952258322518308312370
614462625176544968398772979677993886597595888444699849445968855456666794598363878647397472370611124
342426038105820512291673236242588648634466744646845777477557645589764482986857645122398666420720742
303446222610437533389493227477389695959868644577787974876888684975836425953723362621837202318302515
101334031274541867475755424764549646588488959767847459756867963388465874367294735519312864601156672
311162646802122687272848655359448638774475595989694889897479694563583798875942767189780830474311553
670525052313105734222877229995545497896735689799858955459867784679684938565425586596166033035473164
625002126405824409197545328243248943664786877896564684896757759666544465836966863943043883874535107
304504507410725215339562444778866968394554865956559998446945777964348595952748915112623570510705144
447671532535258771129625534992686968475466769559485845995386695599378847572918425825332176641466062
022123400381035622672492659655854245887594385374756573547685957733982636227675215225616456802746606
143231134353837650051751146983252488977634698367786398395985875992826958228379769214124442703715262
135170610171160182526139534726928582959959837673658879565485535346824864319872955144130017452466064
102646524660025304032183156274795333553888848798733487439766887562335538983732625811202053035706412
105313211023023674376715267861525696823925879646687867997695888347896781494452164804031634615425042
256205106513734680231582333362957987973927998375834773457684994689349817858524813244430142704015520
021404347726028733646641268434424287525532769279452643745555528837589599615841240070086220361652546
224024214320367157758819746327682985953929797339659337579259325447482167689237531580534124157434533
432614136036164731080370551893833148799729789672732794952993828437433612152513202747342230044776363
314003554513122735473322134512738781597463362529856243299295546734985494922406881657630707442021510
514504073756450312710340856355119778239528232648473554453443349559599228483527304806846455610024545
424156167665132531871223763346631626522767446256444526857773846279396461782420177025261412610600431
440544203354025350033001226782826234581598745799586998494951719551921447963680834604761003456033433
030261134056327505538138763401733512835785873969133667323138843188738957384853306401550446745105426
524041041607103210643621736677777415881386586134322795167285489925353353273682055677320161701632002
532513043015722226170325461521708421659348265984277116386737884679183833325305770247107056515000632
450631113064541102213228045638208741315429696459599317816954821479256672633762880514531576001505104
214165164302237003505054233882824157688219632493411326562973319962407073638136757124756516600661503
304465104303261562212345808766401574871933592693641614758134144886301815682807153126027453244204015
135203445204521251600013125103586202465438696331861292616228156657585723603452536740112103314030555
514516400551406327564011243567833388064737417461387480870726483204868682076024701011125332602254113
421341053633214625706123464303687686511262673301412775315212752511877023033424215721261615303053012
022044105062611536144720566574153723272833357078078000286705430350220142407371067103103416226230555
410213236064223263635201443404636873030520630316216081306535811175741246467466645353201136163050545
303520211553166661506232367472736401455544832872162057805076267517121166516261355403030034621243454
203254222143353045650002244735005340271145025041572764542706827413452562704066262265323455430133504
441232355335366123446141420412727113134404853821274587121188823260264625415453362560311464455210441
414115054424201303442043777071262633223473236654360080370734624214365605172654033011620153152523134
412115334452334460565220356727405160520263276133202400177553665136056247040612461135000421154322204
041335455114425155032554320512112112454416721273507036712353407602170012763156424133043141034050241
030023102524414043125455041405115606664661260240725146305660271437703406461522205621551001134541002
404443532404034526430106366644217325436253634242603222554235163606432511155652343363021250505540430
324114252001344342204144440320420641222766650735522654115551234652234245431600152550532022520100132

2000
input/day9.txt Normal file

File diff suppressed because it is too large Load diff

View file

@ -1,9 +1,24 @@
//! Dummy challenge for testing
pub fn part1() -> i64 {
123
pub fn part1(input: Vec<String>) -> String {
input[0].to_owned()
}
pub fn part2() -> i64 {
456
pub fn part2(input: Vec<String>) -> String {
input[1].to_owned()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn t_part1() {
assert_eq!(part1(crate::read_input(0)), "123");
}
#[test]
fn t_part2() {
assert_eq!(part2(crate::read_input(0)), "456");
}
}

View file

@ -1,20 +1,6 @@
//! Day 1: Calorie counting
use std::{
fs::File,
io::{BufRead, BufReader, Lines},
};
use path_macro::path;
fn read_input() -> std::iter::Flatten<Lines<BufReader<File>>> {
let f = File::open(path!("input" / "day1.txt")).unwrap();
BufReader::new(f).lines().flatten()
}
fn get_elves() -> Vec<u32> {
let input = read_input();
fn get_elves(input: Vec<String>) -> Vec<u32> {
let mut elves = Vec::new();
let mut buf = 0;
@ -31,18 +17,33 @@ fn get_elves() -> Vec<u32> {
elves
}
pub fn part1() -> i64 {
let elves = get_elves();
*elves.iter().max().unwrap() as i64
pub fn part1(input: Vec<String>) -> String {
let elves = get_elves(input);
elves.iter().max().unwrap().to_string()
}
pub fn part2() -> i64 {
let mut elves = get_elves();
pub fn part2(input: Vec<String>) -> String {
let mut elves = get_elves(input);
elves.sort();
let mut acc = 0;
for i in 1..=3 {
acc += elves[elves.len() - i];
}
acc as i64
acc.to_string()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn t_part1() {
assert_eq!(part1(crate::read_input(1)), "69177");
}
#[test]
fn t_part2() {
assert_eq!(part2(crate::read_input(1)), "207456");
}
}

137
src/day2.rs Normal file
View file

@ -0,0 +1,137 @@
//! Day 2: Rock Paper Scissors
use std::cmp::Ordering;
fn get_rounds(input: Vec<String>) -> Vec<(Sign, Sign)> {
input
.into_iter()
.filter_map(|line| {
line.split_once(' ')
.map(|(a, b)| (Sign::from_str(b), Sign::from_str(a)))
})
.collect()
}
fn get_rounds2(input: Vec<String>) -> Vec<(Sign, Ordering)> {
input
.into_iter()
.filter_map(|line| {
line.split_once(' ').map(|(a, b)| {
(
Sign::from_str(a),
match b {
"X" => Ordering::Less,
"Y" => Ordering::Equal,
"Z" => Ordering::Greater,
_ => panic!("could not parse sign `{}`", b),
},
)
})
})
.collect()
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
enum Sign {
Rock = 1,
Paper = 2,
Scissors = 3,
}
impl Sign {
fn from_str(s: &str) -> Self {
match s {
"A" | "X" => Self::Rock,
"B" | "Y" => Self::Paper,
"C" | "Z" => Self::Scissors,
_ => panic!("could not parse sign: `{}`", s),
}
}
}
fn round_result(you: Sign, opp: Sign) -> Ordering {
if you == opp {
Ordering::Equal
} else {
let won = match you {
Sign::Rock => opp == Sign::Scissors,
Sign::Paper => opp == Sign::Rock,
Sign::Scissors => opp == Sign::Paper,
};
if won {
Ordering::Greater
} else {
Ordering::Less
}
}
}
fn round_score(you: Sign, opp: Sign) -> i64 {
let score_shape = you as i64;
let score_result = match round_result(you, opp) {
Ordering::Less => 0,
Ordering::Equal => 3,
Ordering::Greater => 6,
};
score_shape + score_result
}
fn your_sign(opp: Sign, result: Ordering) -> Sign {
match result {
Ordering::Less => match opp {
Sign::Rock => Sign::Scissors,
Sign::Paper => Sign::Rock,
Sign::Scissors => Sign::Paper,
},
Ordering::Equal => opp,
Ordering::Greater => match opp {
Sign::Rock => Sign::Paper,
Sign::Paper => Sign::Scissors,
Sign::Scissors => Sign::Rock,
},
}
}
pub fn part1(input: Vec<String>) -> String {
let rounds = get_rounds(input);
rounds
.into_iter()
.map(|(you, opp)| round_score(you, opp))
.sum::<i64>()
.to_string()
}
pub fn part2(input: Vec<String>) -> String {
let rounds = get_rounds2(input);
rounds
.into_iter()
.map(|(opp, result)| round_score(your_sign(opp, result), opp))
.sum::<i64>()
.to_string()
}
#[cfg(test)]
mod tests {
use rstest::rstest;
use super::*;
#[rstest]
#[case(Sign::Paper, Sign::Rock, 8)]
#[case(Sign::Rock, Sign::Paper, 1)]
#[case(Sign::Scissors, Sign::Scissors, 6)]
fn t_round_score(#[case] you: Sign, #[case] opp: Sign, #[case] expect: i64) {
let score = round_score(you, opp);
assert_eq!(score, expect);
}
#[test]
fn t_part1() {
assert_eq!(part1(crate::read_input(2)), "14827");
}
#[test]
fn t_part2() {
assert_eq!(part2(crate::read_input(2)), "13889");
}
}

111
src/day3.rs Normal file
View file

@ -0,0 +1,111 @@
//! Day 3: Rucksack Reorganization
use itertools::Itertools;
fn priority(item: char) -> i64 {
match item {
'a'..='z' => item as i64 - 'a' as i64 + 1,
'A'..='Z' => item as i64 - 'A' as i64 + 27,
_ => panic!("priority undefined for item `{}`", item),
}
}
fn get_rucksack_compartments(rucksack: &str) -> [String; 2] {
[
rucksack[..rucksack.len() / 2].to_owned(),
rucksack[rucksack.len() / 2..].to_owned(),
]
}
fn get_common_item(compartments: &[String]) -> char {
compartments[0]
.chars()
.find(|item| {
compartments[1..]
.iter()
.all(|comp| comp.chars().any(|it| &it == item))
})
.unwrap()
}
pub fn part1(input: Vec<String>) -> String {
input
.into_iter()
.map(|rucksack| {
let compartments = get_rucksack_compartments(&rucksack);
let common_item = get_common_item(&compartments);
priority(common_item)
})
.sum::<i64>()
.to_string()
}
pub fn part2(input: Vec<String>) -> String {
input
.into_iter()
.tuples::<(String, String, String)>()
.map(|group| {
let common_item = get_common_item(&[group.0, group.1, group.2]);
priority(common_item)
})
.sum::<i64>()
.to_string()
}
#[cfg(test)]
mod tests {
use super::*;
use rstest::rstest;
#[rstest]
#[case('p', 16)]
#[case('L', 38)]
#[case('P', 42)]
#[case('v', 22)]
#[case('t', 20)]
#[case('s', 19)]
fn t_priority(#[case] item: char, #[case] expect: i64) {
assert_eq!(priority(item), expect)
}
#[test]
fn t_compartments() {
let compartments = get_rucksack_compartments("vJrwpWtwJgWrhcsFMMfFFhFp");
assert_eq!(compartments[0], "vJrwpWtwJgWr");
assert_eq!(compartments[1], "hcsFMMfFFhFp");
assert_eq!(get_common_item(&compartments), 'p');
}
#[test]
fn t_common_items3() {
assert_eq!(
get_common_item(&[
"vJrwpWtwJgWrhcsFMMfFFhFp".to_owned(),
"jqHRNqRjqzjGDLGLrsFMfFZSrLrFZsSL".to_owned(),
"PmmdzqPrVvPwwTWBwg".to_owned()
]),
'r'
);
assert_eq!(
get_common_item(&[
"wMqvLMZHhHMvwLHjbvcjnnSBnvTQFn".to_owned(),
"ttgJtRGJQctTZtZT".to_owned(),
"CrZsJsPPZsGzwwsLwLmpwMDw".to_owned()
]),
'Z'
);
}
#[test]
fn t_part1() {
assert_eq!(part1(crate::read_input(3)), "8039");
}
#[test]
fn t_part2() {
assert_eq!(part2(crate::read_input(3)), "2510");
}
}

76
src/day4.rs Normal file
View file

@ -0,0 +1,76 @@
//! Day 4: Camp Cleanup
use std::ops::RangeInclusive;
fn get_ranges(input: Vec<String>) -> Vec<(RangeInclusive<u32>, RangeInclusive<u32>)> {
// 31-31,32-40
input
.into_iter()
.map(|line| {
let (r1, r2) = line.split_once(',').unwrap();
(parse_range(r1), parse_range(r2))
})
.collect()
}
fn parse_range(s: &str) -> RangeInclusive<u32> {
let (a, b) = s.split_once('-').unwrap();
RangeInclusive::new(a.parse().unwrap(), b.parse().unwrap())
}
pub fn part1(input: Vec<String>) -> String {
let ranges = get_ranges(input);
ranges
.iter()
.filter(|(a, b)| {
(b.start() >= a.start() && b.end() <= a.end())
|| (a.start() >= b.start() && a.end() <= b.end())
})
.count()
.to_string()
}
pub fn part2(input: Vec<String>) -> String {
let ranges = get_ranges(input);
ranges
.iter()
.filter(|(a, b)| {
a.contains(b.start())
|| a.contains(b.end())
|| b.contains(a.start())
|| b.contains(a.end())
})
.count()
.to_string()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn t_example() {
let input = vec![
"2-4,6-8".to_owned(),
"2-3,4-5".to_owned(),
"5-7,7-9".to_owned(),
"2-8,3-7".to_owned(),
"6-6,4-6".to_owned(),
"2-6,4-8".to_owned(),
];
assert_eq!(part1(input.clone()), "2");
assert_eq!(part2(input), "4");
}
#[test]
fn t_part1() {
assert_eq!(part1(crate::read_input(4)), "556");
}
#[test]
fn t_part2() {
assert_eq!(part2(crate::read_input(4)), "876");
}
}

134
src/day5.rs Normal file
View file

@ -0,0 +1,134 @@
//! Day 5: Supply Stacks
use once_cell::sync::Lazy;
use regex::Regex;
type Stacks = Vec<Vec<char>>;
fn split_input(input: &[String]) -> (&[String], &[String]) {
let mut parts = input.split(|i| i.is_empty());
(parts.next().unwrap(), parts.next().unwrap())
}
fn parse_stacks(stacks: &[String]) -> Stacks {
let mut lines = stacks.iter().rev();
let index_line = lines.next().unwrap();
let n_stacks = index_line.trim().split_ascii_whitespace().count();
let mut stacks = (0..n_stacks).map(|_| Vec::new()).collect::<Vec<_>>();
for line in lines {
for (i, stack) in stacks.iter_mut().enumerate() {
let char_i = i * 4 + 1;
if let Some(char_str) = line.get(char_i..char_i + 1) {
let c = char_str.chars().next().unwrap();
if c != ' ' {
if !c.is_ascii_uppercase() {
panic!("invalid crate char: `{}`", c)
}
stack.push(c);
}
}
}
}
stacks
}
struct Instruction {
n: usize,
from: usize,
to: usize,
}
fn parse_instruction(instr: &str) -> Instruction {
static INSTR_REGEX: Lazy<Regex> =
Lazy::new(|| Regex::new("move (\\d+) from (\\d+) to (\\d+)").unwrap());
let cap = INSTR_REGEX.captures(instr).unwrap();
let n = cap.get(1).unwrap().as_str().parse::<usize>().unwrap();
let from = cap.get(2).unwrap().as_str().parse::<usize>().unwrap() - 1;
let to = cap.get(3).unwrap().as_str().parse::<usize>().unwrap() - 1;
Instruction { n, from, to }
}
fn apply_instruction(stacks: &mut Stacks, instr: &str) {
let instr = parse_instruction(instr);
for _ in 0..instr.n {
let c = stacks[instr.from].pop().unwrap();
stacks[instr.to].push(c);
}
}
fn apply_instruction2(stacks: &mut Stacks, instr: &str) {
let instr = parse_instruction(instr);
let si = stacks[instr.from].len() - instr.n;
let mut crates = stacks[instr.from].split_off(si);
stacks[instr.to].append(&mut crates);
}
pub fn part1(input: Vec<String>) -> String {
let (stacks, instr) = split_input(&input);
let mut stacks = parse_stacks(stacks);
instr.iter().for_each(|i| apply_instruction(&mut stacks, i));
stacks
.iter()
.map(|stack| stack.last().copied().unwrap_or(' '))
.collect()
}
pub fn part2(input: Vec<String>) -> String {
let (stacks, instr) = split_input(&input);
let mut stacks = parse_stacks(stacks);
instr
.iter()
.for_each(|i| apply_instruction2(&mut stacks, i));
stacks
.iter()
.map(|stack| stack.last().copied().unwrap_or(' '))
.collect()
}
#[cfg(test)]
mod tests {
use super::*;
fn example_input() -> Vec<String> {
const EXAMPLE: &str = r#" [D]
[N] [C]
[Z] [M] [P]
1 2 3
move 1 from 2 to 1
move 3 from 1 to 3
move 2 from 2 to 1
move 1 from 1 to 2"#;
EXAMPLE.lines().map(str::to_owned).collect()
}
#[test]
fn t_example_1() {
assert_eq!(part1(example_input()), "CMZ");
}
#[test]
fn t_example_2() {
assert_eq!(part2(example_input()), "MCD");
}
#[test]
fn t_part1() {
assert_eq!(part1(crate::read_input(5)), "TWSGQHNHL");
}
#[test]
fn t_part2() {
assert_eq!(part2(crate::read_input(5)), "JNRSCDWPP");
}
}

57
src/day6.rs Normal file
View file

@ -0,0 +1,57 @@
//! Day 6: Tuning Trouble
use itertools::Itertools;
fn get_input(input: &[String]) -> Vec<char> {
input.iter().next().unwrap().chars().collect()
}
fn find_header(input: &[char], n_unique: usize) -> usize {
let (i_start, _) = input
.windows(n_unique)
.enumerate()
.find(|(_, window)| window.iter().all_unique())
.unwrap();
i_start + n_unique
}
pub fn part1(input: Vec<String>) -> String {
let input = get_input(&input);
find_header(&input, 4).to_string()
}
pub fn part2(input: Vec<String>) -> String {
let input = get_input(&input);
find_header(&input, 14).to_string()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn t_example1() {
assert_eq!(
part1(vec!["mjqjpqmgbljsphdztnvjfqwrcgsmlb".to_owned()]),
"7"
);
}
#[test]
fn t_example2() {
assert_eq!(
part2(vec!["mjqjpqmgbljsphdztnvjfqwrcgsmlb".to_owned()]),
"19"
);
}
#[test]
fn t_part1() {
assert_eq!(part1(crate::read_input(6)), "1300");
}
#[test]
fn t_part2() {
assert_eq!(part2(crate::read_input(6)), "3986");
}
}

143
src/day7.rs Normal file
View file

@ -0,0 +1,143 @@
//! Day 7: No Space Left On Device
use std::collections::HashMap;
enum TermLine<'a> {
CdRoot,
CdUp,
Cd(&'a str),
Dir(&'a str),
File(u32),
None,
}
fn parse_line(line: &str) -> TermLine {
match line.strip_prefix("$ ") {
Some(cmd) => match cmd.strip_prefix("cd ") {
Some(dir) => match dir {
"/" => TermLine::CdRoot,
".." => TermLine::CdUp,
_ => TermLine::Cd(dir),
},
// Ignore ls command
None => TermLine::None,
},
None => {
let (i_size, i_name) = line.split_once(' ').unwrap();
if i_size == "dir" {
TermLine::Dir(i_name)
} else {
TermLine::File(i_size.parse().unwrap())
}
}
}
}
fn get_dir_size<S: AsRef<str>>(input: &[S], dir_path: &[&str]) -> u32 {
let mut path = Vec::new();
let mut size = 0;
for line in input {
match parse_line(line.as_ref()) {
TermLine::CdRoot => path.clear(),
TermLine::CdUp => {
path.pop();
}
TermLine::Cd(dir) => path.push(dir),
TermLine::Dir(name) => {
if path == dir_path {
let mut i_path = path.clone();
i_path.push(name);
size += get_dir_size(input, &i_path);
}
}
TermLine::File(i_size) => {
if path == dir_path {
size += i_size
}
}
TermLine::None => {}
}
}
size
}
fn get_dir_sizes<S: AsRef<str>>(input: &[S]) -> HashMap<Vec<&str>, u32> {
let mut dir_sizes: HashMap<Vec<&str>, u32> = HashMap::new();
let mut path = Vec::new();
for line in input.iter() {
let path_upd = match parse_line(line.as_ref()) {
TermLine::CdRoot => {
path.clear();
true
}
TermLine::CdUp => {
path.pop();
true
}
TermLine::Cd(dir) => {
path.push(dir);
true
}
_ => false,
};
if path_upd && !dir_sizes.contains_key(&path) {
let dir_size = get_dir_size(input, &path);
dir_sizes.insert(path.clone(), dir_size);
}
}
dir_sizes
}
pub fn part1(input: Vec<String>) -> String {
let dir_sizes = get_dir_sizes(&input);
dir_sizes
.values()
.filter(|size| size <= &&100_000)
.sum::<u32>()
.to_string()
}
pub fn part2(input: Vec<String>) -> String {
let dir_sizes = get_dir_sizes(&input);
let total_size = dir_sizes[&Vec::new()];
let unused = 70_000_000 - total_size;
let to_free = 30_000_000 - unused;
dir_sizes
.values()
.filter(|size| size >= &&to_free)
.min()
.unwrap()
.to_string()
}
#[cfg(test)]
mod tests {
use super::*;
const DAY: u8 = 7;
#[test]
fn t_example1() {
assert_eq!(part1(crate::read_example(DAY)), "95437");
}
#[test]
fn t_example2() {
assert_eq!(part2(crate::read_example(DAY)), "24933642");
}
#[test]
fn t_part1() {
assert_eq!(part1(crate::read_input(DAY)), "1084134");
}
#[test]
fn t_part2() {
assert_eq!(part2(crate::read_input(DAY)), "6183184");
}
}

151
src/day8.rs Normal file
View file

@ -0,0 +1,151 @@
//! Day 8: Treetop Tree House
type Grid = Vec<Vec<u8>>;
fn parse_grid(input: &[String]) -> Grid {
let mut grid = Grid::new();
for line in input {
let mut grid_ln = Vec::new();
for tree in line.chars() {
let tree_h = tree.to_digit(10).unwrap() as u8;
grid_ln.push(tree_h);
}
grid.push(grid_ln);
}
grid
}
fn is_tree_visible(grid: &Grid, x: usize, y: usize) -> bool {
let h = grid.len();
let w = grid[0].len();
let tree_height = grid[y][x];
if x == 0 || x == w - 1 || y == 0 || y == h - 1 {
return true;
}
if (0..x).all(|xi| grid[y][xi] < tree_height) {
return true;
}
if (x + 1..w).all(|xi| grid[y][xi] < tree_height) {
return true;
}
if (0..y).all(|yi| grid[yi][x] < tree_height) {
return true;
}
if (y + 1..h).all(|yi| grid[yi][x] < tree_height) {
return true;
}
false
}
fn scenic_score(grid: &Grid, x: usize, y: usize) -> usize {
let h = grid.len();
let w = grid[0].len();
let tree_height = grid[y][x];
let side_score = |start: i64, end: i64, coord: usize, is_x: bool| {
let mut coord2 = start;
let mut n = 1;
while coord2 != end {
let h = if is_x {
grid[usize::try_from(coord2).unwrap()][coord]
} else {
grid[coord][usize::try_from(coord2).unwrap()]
};
if h >= tree_height {
return n;
}
if start < end {
coord2 += 1;
} else {
coord2 -= 1;
}
n += 1;
}
start.abs_diff(end)
};
let left = side_score(x as i64 - 1, -1, y, false);
let right = side_score(x as i64 + 1, w as i64, y, false);
let up = side_score(y as i64 - 1, -1, x, true);
let down = side_score(y as i64 + 1, h as i64, x, true);
(left * right * up * down).try_into().unwrap()
}
pub fn part1(input: Vec<String>) -> String {
let grid = parse_grid(&input);
let mut n: u32 = 0;
for (y, row) in grid.iter().enumerate() {
for x in 0..row.len() {
if is_tree_visible(&grid, x, y) {
n += 1;
}
}
}
n.to_string()
}
pub fn part2(input: Vec<String>) -> String {
let grid = parse_grid(&input);
let mut max_score = 0;
for (y, row) in grid.iter().enumerate() {
for x in 0..row.len() {
max_score = max_score.max(scenic_score(&grid, x, y));
}
}
max_score.to_string()
}
#[cfg(test)]
mod tests {
use super::*;
const DAY: u8 = 8;
#[test]
fn t_example1() {
let input = crate::read_example(DAY);
let grid = parse_grid(&input);
assert!(is_tree_visible(&grid, 4, 0));
assert!(is_tree_visible(&grid, 1, 1));
assert!(!is_tree_visible(&grid, 3, 1));
assert_eq!(part1(input), "21");
}
#[test]
fn tmp() {
let input = crate::read_example(DAY);
let grid = parse_grid(&input);
dbg!(scenic_score(&grid, 2, 3));
}
#[test]
fn t_example2() {
assert_eq!(part2(crate::read_example(DAY)), "8");
}
#[test]
fn t_part1() {
assert_eq!(part1(crate::read_input(DAY)), "1533");
}
#[test]
fn t_part2() {
assert_eq!(part2(crate::read_input(DAY)), "345744");
}
}

258
src/day9.rs Normal file
View file

@ -0,0 +1,258 @@
//! Day 9: Rope Bridge
use std::{collections::HashSet, fmt::Debug};
use itertools::Itertools;
#[derive(Default, Clone, Copy, PartialEq, Eq, Hash)]
struct Position {
x: i32,
y: i32,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
enum Direction {
U,
D,
R,
L,
}
impl Position {
fn move_dir(self, dir: Direction) -> Self {
match dir {
Direction::U => Self {
x: self.x,
y: self.y + 1,
},
Direction::D => Self {
x: self.x,
y: self.y - 1,
},
Direction::R => Self {
x: self.x + 1,
y: self.y,
},
Direction::L => Self {
x: self.x - 1,
y: self.y,
},
}
}
fn dx(self, p2: Position) -> i32 {
self.x - p2.x
}
fn dy(self, p2: Position) -> i32 {
self.y - p2.y
}
}
impl Debug for Position {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_fmt(format_args!("{}|{}", self.x, self.y))
}
}
fn update_rope_pos(hpos: Position, tpos: Position) -> (Position, Position) {
let dx = hpos.dx(tpos);
let dy = hpos.dy(tpos);
match (dx.abs() < 2, dy.abs() < 2) {
(true, true) => (hpos, tpos),
(true, false) => (
hpos,
Position {
x: hpos.x,
y: hpos.y - dy + dy.signum(),
},
),
(false, true) => (
hpos,
Position {
x: hpos.x - dx + dx.signum(),
y: hpos.y,
},
),
(false, false) => (
hpos,
Position {
x: hpos.x - dx + dx.signum(),
y: hpos.y - dy + dy.signum(),
},
),
}
}
fn parse_line(line: &str) -> (Direction, i32) {
let (d_str, n_str) = line.split_once(' ').unwrap();
let d = match d_str {
"U" => Direction::U,
"D" => Direction::D,
"R" => Direction::R,
"L" => Direction::L,
_ => panic!("invalid dir: {}", d_str),
};
(d, n_str.parse().unwrap())
}
fn print_rope(rope: &[Position]) {
let (min_x, max_x) = match rope.iter().map(|p| p.x).minmax() {
itertools::MinMaxResult::NoElements => return,
itertools::MinMaxResult::OneElement(x) => (x, x),
itertools::MinMaxResult::MinMax(min_x, max_x) => (min_x, max_x),
};
let (min_y, max_y) = match rope.iter().map(|p| p.y).minmax() {
itertools::MinMaxResult::NoElements => return,
itertools::MinMaxResult::OneElement(y) => (y, y),
itertools::MinMaxResult::MinMax(min_y, max_y) => (min_y, max_y),
};
for y in (min_y..=max_y).rev() {
for x in min_x..=max_x {
if let Some((n, _)) = rope.iter().find_position(|p| p == &&Position { x, y }) {
print!("{}", n)
} else {
print!(".");
}
}
println!();
}
println!();
}
pub fn part1(input: Vec<String>) -> String {
let mut visited = HashSet::new();
let mut hpos = Position::default();
let mut tpos = Position::default();
visited.insert(tpos);
for (dir, n) in input.iter().map(|line| parse_line(line)) {
for _ in 0..n {
(hpos, tpos) = update_rope_pos(hpos.move_dir(dir), tpos);
visited.insert(tpos);
}
}
visited.len().to_string()
}
pub fn part2(input: Vec<String>) -> String {
let mut visited = HashSet::new();
let rope_len = 10;
// head of the rope first
let mut rope = (0..rope_len)
.map(|_| Position::default())
.collect::<Vec<_>>();
visited.insert(rope[rope_len - 1]);
for (dir, n) in input.iter().map(|line| parse_line(line)) {
for _ in 0..n {
let mut new_rope = Vec::with_capacity(rope_len);
let mut rope_iter = rope.iter();
let mut hpos = rope_iter.next().copied().unwrap().move_dir(dir);
for tpos in rope_iter {
let (n_hpos, n_tpos) = update_rope_pos(hpos, *tpos);
new_rope.push(n_hpos);
// Tail pos of this section will be head pos of next section
hpos = n_tpos;
}
new_rope.push(hpos);
rope = new_rope;
visited.insert(rope[rope_len - 1]);
// print_rope(&rope);
}
}
print_rope(&rope);
visited.len().to_string()
}
#[cfg(test)]
mod tests {
use super::*;
use rstest::rstest;
const DAY: u8 = 9;
#[rstest]
#[case(
Position {x: 0, y: 0},
Position {x: 0, y: 0},
Direction::R,
Position {x: 0, y: 0},
)]
#[case(
Position {x: 1, y: 0},
Position {x: 0, y: 0},
Direction::R,
Position {x: 1, y: 0},
)]
#[case(
Position {x: 4, y: 1},
Position {x: 3, y: 0},
Direction::U,
Position {x: 4, y: 1},
)]
#[case(
Position {x: 4, y: 4},
Position {x: 4, y: 3},
Direction::L,
Position {x: 4, y: 3},
)]
#[case(
Position {x: 3, y: 4},
Position {x: 4, y: 3},
Direction::L,
Position {x: 3, y: 4},
)]
fn rope_pos(
#[case] hpos: Position,
#[case] tpos: Position,
#[case] dir: Direction,
#[case] exp: Position,
) {
let (_, tpos) = update_rope_pos(hpos.move_dir(dir), tpos);
assert_eq!(tpos, exp);
}
#[test]
fn t_example1() {
assert_eq!(part1(crate::read_example(DAY)), "13");
}
#[test]
fn t_example2() {
assert_eq!(part2(crate::read_example(DAY)), "1");
}
#[test]
fn t_example2b() {
let input = vec![
"R 5".to_owned(),
"U 8".to_owned(),
"L 8".to_owned(),
"D 3".to_owned(),
"R 17".to_owned(),
"D 10".to_owned(),
"L 25".to_owned(),
"U 20".to_owned(),
];
assert_eq!(part2(input), "36");
}
#[test]
fn t_part1() {
assert_eq!(part1(crate::read_input(DAY)), "6332");
}
#[test]
fn t_part2() {
assert_eq!(part2(crate::read_input(DAY)), "2511");
}
}

View file

@ -1,14 +1,52 @@
use std::{
fs::File,
io::{BufRead, BufReader},
path::Path,
};
use path_macro::path;
mod day0;
mod day1;
mod day2;
mod day3;
mod day4;
mod day5;
mod day6;
mod day7;
mod day8;
mod day9;
pub(crate) fn read_input(day: u8) -> Vec<String> {
read_input_file(path!("input" / format!("day{}.txt", day)))
}
#[cfg(test)]
pub(crate) fn read_example(day: u8) -> Vec<String> {
read_input_file(path!("example" / format!("day{}.txt", day)))
}
fn read_input_file<P: AsRef<Path>>(path: P) -> Vec<String> {
let f = File::open(path).expect("could not read input file");
let mut input = BufReader::new(f).lines().flatten().collect::<Vec<_>>();
if let Some(last) = input.last() {
if last.is_empty() {
input.pop();
}
}
input
}
macro_rules! days {
( $($n:expr, $module:ident),* ) => {
fn get_result(day: u8, part: u8) -> i64 {
( $($n:expr, $module:ident,)* ) => {
fn get_result(day: u8, part: u8) -> String {
let input = read_input(day);
match day {
$(
$n => match part {
2 => $module::part2(),
_ => $module::part1(),
2 => $module::part2(input),
_ => $module::part1(input),
}
)*
_ => panic!("day {} missing", day),
@ -19,7 +57,15 @@ macro_rules! days {
days! {
0, day0,
1, day1
1, day1,
2, day2,
3, day3,
4, day4,
5, day5,
6, day6,
7, day7,
8, day8,
9, day9,
}
fn main() {