Update advent of code

This commit is contained in:
Jed
2022-04-13 11:59:45 -04:00
parent 01ee3a759c
commit 76ece98351
14 changed files with 2284 additions and 0 deletions

83
2021/22-1.py Normal file
View File

@@ -0,0 +1,83 @@
def parse_input(s):
for line in s.splitlines():
state, rest = line.split()
x, y, z = rest.split(',')
x0, x1 = x[2:].split('..')
xrange = range(int(x0), int(x1)+1)
y0, y1 = y[2:].split('..')
yrange = range(int(y0), int(y1)+1)
z0, z1 = z[2:].split('..')
zrange = range(int(z0), int(z1)+1)
yield state, xrange, yrange, zrange
def get_subrange(crange, low, high):
c0 = crange[0]
c1 = crange[-1]
if c1 < low:
return []
elif c0 > high:
return []
c0 = max(c0, low)
c1 = max(c1, low)
c0 = min(c0, high)
c1 = min(c1, high)
return range(c0, c1+1)
def part1(s):
data = list(parse_input(s))
cubes = {}
for idx, item in enumerate(data):
state, xr, yr, zr = item
for x in get_subrange(xr, -50, 50):
for y in get_subrange(yr, -50, 50):
for z in get_subrange(zr, -50, 50):
cubes[x,y,z] = state
answer = sum(1 for s in cubes.values() if s == 'on')
print(f'The answer to part one is {answer}')
def count_uninterrupted(item, rest):
_, xr, yr, zr = item
total = len(xr) * len(yr) * len(zr)
conflicts = []
ref_val = 0
for item in rest:
state, xr2, yr2, zr2 = item
cxr = get_subrange(xr2, xr[0], xr[-1])
cyr = get_subrange(yr2, yr[0], yr[-1])
czr = get_subrange(zr2, zr[0], zr[-1])
if len(cxr) == 0 or len(cyr) == 0 or len(czr) == 0:
continue
conflicts.append((state, cxr, cyr, czr))
ref_val += len(cxr) * len(cyr) * len(czr)
for idx, item in enumerate(conflicts):
total -= count_uninterrupted(item, conflicts[idx+1:])
return total
def part2(s):
data = list(parse_input(s))
answer = 0
for idx, item in enumerate(data):
state, xr, yr, zr = item
if state == 'off':
continue
answer += count_uninterrupted(item, data[idx+1:])
print(f'The answer to part two is {answer}')
with open("./2021/22.input") as input_file:
INPUT = input_file.read()
part1(INPUT)
part2(INPUT)

420
2021/22.input Normal file
View File

@@ -0,0 +1,420 @@
on x=-10..44,y=-47..3,z=-30..20
on x=-48..6,y=-21..28,z=-13..39
on x=-41..11,y=-19..32,z=-36..11
on x=-3..44,y=-48..0,z=-14..39
on x=-22..27,y=-49..3,z=-48..0
on x=-19..34,y=-9..40,z=-30..22
on x=-29..25,y=-5..48,z=-39..13
on x=-24..29,y=-36..8,z=-22..24
on x=-27..26,y=-38..9,z=-9..44
on x=-35..11,y=-47..2,z=-27..24
off x=-34..-15,y=3..12,z=8..19
on x=-18..29,y=-33..17,z=-16..34
off x=22..40,y=-5..8,z=1..16
on x=-49..5,y=-16..34,z=-12..35
off x=-29..-16,y=-23..-10,z=-8..10
on x=-34..13,y=-22..26,z=-4..46
off x=-6..5,y=-11..4,z=29..45
on x=-40..8,y=-31..18,z=-4..45
off x=-19..-1,y=-39..-25,z=37..49
on x=-43..7,y=-34..19,z=-20..29
on x=52279..63368,y=-43330..-15454,z=-51521..-36520
on x=-13477..22658,y=46396..60011,z=-67255..-47648
on x=-20150..-12220,y=8781..18859,z=58945..95230
on x=-15215..-7315,y=-42846..-24274,z=-77751..-67800
on x=-64250..-55011,y=-65414..-39445,z=-5401..-2278
on x=-32061..2119,y=46245..75065,z=-46091..-39820
on x=34704..55341,y=-82647..-64723,z=8310..39494
on x=18480..51353,y=50561..81371,z=24851..31205
on x=68199..89682,y=24017..38713,z=2572..21295
on x=38237..55195,y=-57784..-32231,z=-62296..-34958
on x=-28056..-7851,y=-40595..-24600,z=-75668..-52450
on x=58065..80456,y=25672..37183,z=-33953..-14627
on x=-24679..-16787,y=64650..74723,z=-29870..-13701
on x=37975..53348,y=26147..42942,z=55828..73924
on x=61596..81184,y=-11699..12359,z=5647..34640
on x=19475..42683,y=-75957..-60280,z=-7894..4622
on x=21410..46536,y=-47399..-30227,z=-63823..-42527
on x=-91211..-64685,y=18766..31035,z=-22907..4204
on x=-26004..-7858,y=41565..55664,z=42861..69602
on x=46342..62696,y=20618..47479,z=-60164..-45369
on x=4189..29340,y=58375..88316,z=-10803..-3498
on x=-16908..15477,y=-86440..-77392,z=-7364..13051
on x=-25502..-396,y=-62370..-37571,z=44371..75211
on x=6973..35683,y=57696..87795,z=23420..34534
on x=17488..36356,y=12612..29174,z=57385..81005
on x=67722..87911,y=-32381..-9954,z=-28529..-15260
on x=-55080..-35026,y=48563..61363,z=-62109..-30891
on x=44869..62302,y=-36709..-21049,z=-75575..-43980
on x=28823..56328,y=-72680..-62918,z=9119..29589
on x=20975..45413,y=29852..47618,z=53186..65282
on x=19496..29169,y=-65815..-47940,z=-62684..-46121
on x=-34874..-10114,y=18159..31262,z=55179..76115
on x=-66470..-45666,y=36879..60325,z=14369..20412
on x=-75692..-64290,y=-42022..-20129,z=-10712..-5313
on x=46865..68368,y=-48923..-23859,z=46545..68177
on x=-16520..9529,y=132..16483,z=-94183..-68733
on x=-59657..-38565,y=14658..29243,z=37518..56297
on x=-47760..-23709,y=33858..69842,z=-56903..-33373
on x=-26040..-11204,y=44498..65828,z=47974..67516
on x=-10379..17919,y=-43833..-5240,z=-75694..-74482
on x=-44440..-29405,y=56816..86465,z=9853..24150
on x=-27756..2416,y=-49089..-20596,z=57673..86227
on x=-45356..-38089,y=-77117..-49326,z=-12469..4813
on x=24477..45592,y=-78855..-60472,z=-19777..-327
on x=17294..48579,y=-50773..-32615,z=-65752..-40558
on x=28540..39556,y=-87588..-59521,z=2511..34680
on x=-36132..-17282,y=-4113..3923,z=-94231..-58221
on x=-89627..-70676,y=-13120..21560,z=-18769..-5340
on x=58040..83835,y=4100..33912,z=-30189..-13615
on x=71828..83682,y=-28449..-10536,z=8249..12160
on x=-65615..-32704,y=-39765..-9106,z=-76151..-40314
on x=-17423..-1927,y=57486..92267,z=13797..35884
on x=-54416..-41775,y=-81861..-62840,z=7749..22179
on x=-83597..-48572,y=36803..46540,z=-19938..-12515
on x=11436..24726,y=63116..92364,z=16531..40464
on x=-14084..15244,y=-88079..-57696,z=-43594..-8718
on x=40851..63265,y=-64247..-51136,z=27978..37352
on x=-72760..-38547,y=-60429..-41775,z=-1241..6359
on x=30318..48134,y=-33781..-18182,z=60465..87983
on x=-27195..-25169,y=13889..39349,z=-83081..-68154
on x=-81044..-53545,y=11924..39180,z=-13255..559
on x=-5890..4042,y=57026..75676,z=41269..66473
on x=8283..18297,y=-88329..-58621,z=28019..39355
on x=-24736..1619,y=-36319..-22062,z=-77271..-56320
on x=-28357..4887,y=52006..76645,z=44808..58688
on x=-5620..21494,y=48846..66777,z=48433..70491
on x=-63977..-58117,y=-62455..-36917,z=17771..36033
on x=-19413..9463,y=-59668..-50075,z=54566..64506
on x=-78563..-61950,y=27393..48778,z=-33167..-18069
on x=20227..55632,y=-10667..4653,z=51970..86177
on x=-55915..-37654,y=-43237..-32225,z=30156..65627
on x=-21602..-137,y=-76688..-54794,z=-46703..-29485
on x=1361..12183,y=52047..69854,z=-38565..-35864
on x=-46559..-36979,y=20362..37193,z=-70824..-55074
on x=-31107..-12945,y=-69852..-45582,z=39087..63105
on x=73717..79968,y=-24128..-15303,z=-29248..-11963
on x=-18030..-469,y=54064..68776,z=-67769..-32254
on x=-26180..5793,y=59555..72459,z=36665..46922
on x=-74477..-62663,y=-41910..-16089,z=30000..42332
on x=-22393..9147,y=58205..72661,z=33085..55795
on x=-60179..-34779,y=5350..20585,z=-70834..-55182
on x=29067..47458,y=29226..45037,z=51770..64710
on x=30939..46188,y=64553..89553,z=-26702..7980
on x=20450..41026,y=67843..88176,z=-11853..11177
on x=-23447..-8466,y=32875..65000,z=52023..61715
on x=-39164..-16290,y=-51932..-34009,z=52581..73692
on x=6235..11843,y=66309..89114,z=3019..17169
on x=5127..35019,y=-4527..21342,z=66162..88541
on x=4664..15364,y=66136..86998,z=-6789..20000
on x=40148..46981,y=-58574..-28523,z=-53478..-39274
on x=15446..43845,y=-29118..708,z=-86808..-58898
on x=-35809..-14020,y=-55269..-35520,z=43162..59800
on x=-81079..-41513,y=-54041..-36809,z=12452..22370
on x=-43650..-15828,y=1929..22671,z=57385..79965
on x=-52522..-29639,y=-85456..-65487,z=-2284..17209
on x=39477..66083,y=36219..57677,z=-41497..-11991
on x=-83220..-66072,y=-6239..15384,z=12022..32422
on x=-92193..-60190,y=-12572..2685,z=-20290..-13797
on x=18790..41104,y=23391..42361,z=48144..60900
on x=28122..46241,y=-85084..-71267,z=-24667..3727
on x=13148..31460,y=-56133..-47961,z=-77082..-38542
on x=-17356..-10824,y=-81198..-65300,z=13294..36133
on x=-23050..9443,y=65959..75260,z=-43930..-32281
on x=-25202..-5672,y=-90608..-65365,z=-25346..13203
on x=32972..50308,y=-86282..-67318,z=-28540..-11303
on x=26147..60302,y=-69181..-46864,z=-55921..-32961
on x=-40112..-13645,y=-56191..-46527,z=51921..75498
on x=-10121..11971,y=37668..61085,z=52334..69917
on x=74488..87302,y=-28799..-3950,z=-2283..7147
on x=-32174..-20975,y=-16734..15643,z=65236..83087
on x=48653..64217,y=-74293..-43709,z=-30617..-3362
on x=36726..51635,y=-74500..-56124,z=10207..37959
on x=2568..22512,y=-12249..18274,z=-86306..-75108
on x=31158..35260,y=29166..52761,z=-74849..-61138
on x=5207..42773,y=-9581..-3998,z=-94304..-69931
on x=-68662..-62167,y=42096..58917,z=9628..19051
on x=-42810..-13107,y=20840..46672,z=53100..71101
on x=367..10990,y=-83638..-69000,z=-5390..10987
on x=-7900..14302,y=74875..91231,z=7990..23842
on x=-59312..-41132,y=25748..52380,z=39211..50709
on x=50124..84531,y=25031..47169,z=-38380..-3007
on x=62179..83456,y=19996..47791,z=2157..27194
on x=18344..49844,y=-10344..5585,z=55608..77701
on x=77668..87261,y=-6589..5524,z=5328..28365
on x=-1137..19012,y=31102..65506,z=58248..82406
on x=39967..62750,y=-44303..-12301,z=-52508..-37304
on x=-45688..-26440,y=-46669..-41654,z=47358..75186
on x=-65370..-50570,y=-19720..-875,z=36193..59207
on x=-65849..-40212,y=20285..29318,z=37609..56718
on x=-47255..-24138,y=-78980..-73228,z=-16001..14373
on x=-47669..-22654,y=-77905..-53142,z=26042..36817
on x=12989..44381,y=60030..70485,z=-50407..-21117
on x=67262..75963,y=33946..49799,z=2482..25295
on x=19931..38499,y=-78850..-58488,z=-41546..-17402
on x=27552..54137,y=-40389..-14804,z=47733..62009
on x=10535..31282,y=9538..23844,z=-86683..-59264
on x=64101..82098,y=-4630..3098,z=-42025..-28753
on x=59565..81790,y=32449..57646,z=-19763..-9748
on x=18811..26857,y=2964..32957,z=67319..92470
on x=-75918..-56473,y=-56317..-37417,z=9735..27796
on x=-71751..-38665,y=-45994..-22567,z=36304..41748
on x=-37291..-22744,y=66227..77704,z=8520..29887
on x=-23682..918,y=39456..71670,z=49997..64923
on x=-30397..-6850,y=-30104..-9107,z=72862..76798
on x=44284..54494,y=42423..60240,z=-37938..-10526
on x=-57146..-42078,y=-67041..-49697,z=7293..28182
on x=-53150..-27843,y=-70540..-37936,z=-61469..-36379
on x=28680..52508,y=-82151..-58696,z=-30123..5559
on x=-8084..6263,y=-29537..-13619,z=-91258..-60146
on x=59870..76367,y=35209..49198,z=19430..37634
on x=15494..26376,y=50604..58446,z=-54038..-36325
on x=-12733..139,y=67040..90621,z=-45470..-27326
on x=-25233..-5590,y=-17848..-4165,z=75978..92182
on x=-7863..12169,y=29114..60173,z=-70999..-53438
on x=45212..54321,y=-63484..-47543,z=-14714..-5817
on x=1366..25107,y=-7742..24060,z=65603..79002
on x=-8427..6618,y=39945..63467,z=58041..66945
on x=-80477..-67793,y=-21767..-17859,z=1542..16025
on x=-59493..-32400,y=-41189..-23078,z=-56421..-49022
on x=8394..29467,y=-12574..8571,z=-82733..-77056
on x=27195..44304,y=61949..67824,z=-47665..-32527
on x=38239..64154,y=4839..44088,z=53052..74565
on x=-26339..-6185,y=-39260..-24710,z=53090..90155
on x=-10204..12576,y=34116..40669,z=53864..77591
on x=17149..46947,y=-63614..-58392,z=-60632..-32964
on x=54568..71448,y=12865..37396,z=-62544..-39028
on x=5781..42339,y=1342..37753,z=67386..91536
on x=-61506..-47037,y=-34709..-19521,z=-62974..-39386
on x=-74490..-63536,y=12640..25569,z=-36289..-8839
on x=-79160..-49175,y=36552..50474,z=-18210..3546
on x=49901..70567,y=50485..64337,z=-5647..1613
on x=29189..63940,y=-66730..-59251,z=-2513..26790
on x=-67471..-62793,y=7654..42201,z=25340..44391
on x=-87975..-66127,y=-25798..-8071,z=20658..28207
on x=64589..75427,y=-25474..-7774,z=13958..27117
on x=-6574..26814,y=-85040..-57576,z=-41355..-27217
on x=-13441..8227,y=-76327..-53091,z=32256..52761
on x=-15778..10499,y=-82408..-71218,z=18213..42905
on x=24512..40177,y=-80939..-61956,z=-27609..8685
on x=-41574..-21852,y=-51342..-45978,z=45117..64951
on x=39522..65282,y=31701..49355,z=-56505..-48884
on x=31626..54084,y=45347..68708,z=28900..31149
on x=-49056..-22827,y=-42486..-20420,z=62111..64723
on x=53814..77563,y=-55588..-27321,z=23244..39613
on x=10677..37329,y=18393..44957,z=53706..85346
on x=16690..20536,y=9668..37086,z=-73175..-58740
on x=-49862..-24751,y=66705..80881,z=18013..34200
on x=-50210..-21156,y=60590..84814,z=-34011..-14345
on x=-53691..-33583,y=10410..48701,z=-72447..-59719
on x=-40315..-11440,y=71578..82150,z=-27207..-14860
on x=15150..47071,y=67411..77333,z=-1399..11620
on x=69467..86379,y=-23836..10038,z=-9532..-39
on x=-27060..7287,y=14822..30549,z=56331..81572
on x=67920..82589,y=-50105..-25579,z=-9826..12756
on x=4109..30283,y=30296..41993,z=63667..79719
on x=-28460..-6413,y=53416..68285,z=39510..65226
on x=40429..64353,y=-52892..-36718,z=23946..43953
on x=24833..54808,y=-38051..-20548,z=39129..75757
on x=-90314..-64214,y=-20424..-15046,z=17975..34257
on x=1837..22791,y=41595..56529,z=-64276..-59226
on x=-34726..-5732,y=-77777..-59658,z=15202..33685
off x=-82162..-64956,y=-14975..-2292,z=-3957..13401
off x=54240..85363,y=-55056..-17889,z=-29664..-14500
off x=58639..86677,y=-30782..-9070,z=-54906..-27238
off x=-61466..-38924,y=-16327..17659,z=-66658..-60136
off x=-6204..3991,y=-6111..10553,z=62111..80300
off x=-92154..-67933,y=-29847..-8432,z=15117..28930
off x=-82610..-49176,y=-6091..3538,z=-57839..-23160
off x=22529..43761,y=50879..88298,z=-20965..-10175
on x=-19299..7161,y=68531..91988,z=-4547..8035
off x=-68985..-55995,y=-52974..-30848,z=-52464..-37215
off x=-8835..16935,y=51115..79603,z=22667..42888
off x=-37188..-3039,y=-87897..-66043,z=-16001..-5311
off x=12863..29819,y=-37057..-9635,z=-90843..-54221
off x=-63767..-37062,y=-55489..-44482,z=-50776..-24115
off x=-67731..-47540,y=-70104..-45240,z=-30788..-4345
on x=-34341..-8060,y=7684..24517,z=67505..88768
on x=-52292..-21424,y=-68987..-33458,z=42792..63312
off x=-45569..-23119,y=56912..78106,z=20284..34976
on x=30077..52363,y=-15542..8085,z=-79955..-55732
on x=39163..63226,y=31232..53693,z=-47278..-32631
off x=-65244..-28067,y=-41044..-8153,z=50458..67615
off x=-56968..-29110,y=62321..74283,z=-9803..18017
off x=-8063..8872,y=-88475..-77383,z=-25710..2575
on x=-30821..4307,y=55741..69818,z=-47170..-34785
off x=38913..53489,y=-81832..-57499,z=13905..24217
on x=59983..81432,y=-44994..-15168,z=-4094..26741
on x=16855..28719,y=-2946..20301,z=72979..85396
on x=-4549..22799,y=-701..5013,z=60027..80152
off x=-36775..-10107,y=-72848..-58737,z=43174..50822
on x=-6517..16122,y=48989..72321,z=-65046..-50678
on x=-30693..-17712,y=33427..57476,z=-78785..-57131
on x=34792..48298,y=-37146..-17997,z=-77643..-52936
on x=37688..55824,y=-74305..-47981,z=-24510..-5000
off x=14478..27024,y=-91322..-57083,z=5179..34405
on x=-77540..-41204,y=39558..69535,z=-18237..-7013
off x=13558..32862,y=56244..91047,z=14919..26765
off x=24813..47674,y=-74833..-54846,z=-24239..-15683
off x=48425..82384,y=-37609..-3039,z=-45626..-22739
on x=-68965..-40155,y=-60679..-45242,z=20129..38236
on x=57999..77972,y=4544..32819,z=32574..43386
on x=-19887..-7096,y=69234..78775,z=-20455..-14820
off x=-43698..-12560,y=28763..41528,z=-76261..-65485
on x=-69423..-60838,y=-48549..-41121,z=-5324..-1588
off x=-10540..8968,y=66636..79103,z=-54339..-32952
off x=19404..33663,y=-56454..-33939,z=46648..65313
on x=-18159..-9151,y=-30658..2568,z=-78922..-70131
off x=-44318..-21138,y=48442..83141,z=-29965..-7375
on x=-18088..2737,y=-64608..-28790,z=-78912..-54851
off x=-87479..-56576,y=-21916..6778,z=18917..30613
on x=-73889..-42383,y=32083..45851,z=35104..49609
on x=2500..34601,y=-378..7350,z=64332..82586
on x=-81122..-57855,y=-39119..-31062,z=1893..6223
on x=12539..33350,y=60198..86111,z=12623..35589
off x=-42673..-38401,y=-1900..31315,z=50455..82374
on x=49890..66459,y=23568..49622,z=20972..39964
off x=-5067..4144,y=-87944..-65363,z=30077..54630
on x=-19607..140,y=54664..79266,z=38472..65221
on x=-7822..14269,y=-34615..3362,z=76569..89203
off x=-69467..-51550,y=-59718..-46870,z=-25455..-8198
off x=-34072..-5672,y=54250..69094,z=-56316..-44495
on x=48551..69647,y=-73805..-56743,z=-2654..4327
off x=-36422..-28045,y=-52791..-23652,z=-68488..-47764
off x=2043..7907,y=-50512..-29683,z=58683..71568
off x=-3898..8140,y=34178..53920,z=-77621..-42273
off x=-55335..-41342,y=21440..41934,z=39877..60078
on x=-1720..15904,y=51077..66785,z=43927..67103
on x=16104..40346,y=22018..48194,z=49163..68276
off x=20762..40936,y=47206..61813,z=37663..50699
off x=-58815..-41759,y=55741..76065,z=-12078..7466
off x=28910..39598,y=-48060..-29802,z=52635..68948
off x=-14..17864,y=-92006..-64539,z=14974..33022
on x=-20437..10240,y=-85184..-71538,z=-14720..5722
on x=65758..86382,y=664..23984,z=7906..41220
on x=75577..80156,y=-14343..15012,z=-19970..2758
off x=-35971..-12362,y=-78930..-64162,z=-443..18953
on x=10717..33425,y=-67861..-34060,z=49145..71342
on x=-17131..9181,y=-95154..-65114,z=-3865..19850
off x=-63031..-26114,y=-50983..-27219,z=48169..55400
off x=-87607..-50040,y=9965..19918,z=33971..46254
on x=-68797..-48968,y=40934..63082,z=-41632..-25963
on x=25444..41708,y=59568..69538,z=3427..36334
on x=-23648..-10986,y=52784..81687,z=30781..46710
on x=-60110..-34216,y=-44782..-27509,z=-67565..-33572
on x=41796..48955,y=30608..50615,z=39643..46532
off x=62617..69251,y=-55893..-27557,z=-41294..-14608
on x=-17777..-12850,y=-86703..-68635,z=-33623..-11003
off x=-10581..7963,y=15177..34607,z=-81745..-65941
on x=-42044..-20969,y=37983..66376,z=30562..58476
off x=-25589..-16536,y=-67627..-41604,z=43575..71149
off x=-58097..-31753,y=49623..75925,z=4923..27324
on x=-10002..26223,y=-80044..-67148,z=-8657..27992
on x=28902..47236,y=-70518..-37584,z=17208..37927
off x=-72000..-42102,y=15237..37770,z=35192..53266
off x=-2004..24437,y=64141..85543,z=-56802..-31558
on x=-74289..-47306,y=-5440..32095,z=50628..55488
off x=28413..44924,y=11666..42462,z=-76468..-49537
on x=-998..5496,y=-73216..-51962,z=-58914..-49401
on x=68854..79859,y=23282..26907,z=-24111..-18349
off x=-32369..-16926,y=67506..85568,z=-18887..-1011
on x=-85971..-52430,y=-47429..-24505,z=5401..38368
on x=-4701..16278,y=-9169..1410,z=-99277..-64806
off x=16335..45570,y=-63053..-36548,z=43167..56703
on x=-15551..8748,y=45692..61038,z=51765..67651
off x=16650..39492,y=-82384..-52703,z=-33756..-11351
off x=-41621..-24903,y=-84875..-60223,z=-50349..-12184
on x=19540..36309,y=-39629..-1760,z=-77931..-60956
off x=-3633..28038,y=26638..62578,z=63800..83098
off x=23113..47496,y=25347..43935,z=-73252..-52249
off x=-36880..-16273,y=25708..50233,z=53726..76349
on x=50353..76339,y=-31893..-8779,z=19496..40652
off x=-41452..-13373,y=40666..64000,z=-64937..-30965
on x=61737..66349,y=-48841..-35778,z=-13868..6434
off x=-51263..-33482,y=7595..27677,z=-66937..-45763
on x=-47082..-11771,y=-37..18678,z=-74941..-73966
on x=62727..87651,y=5312..19737,z=-42396..-30989
off x=-21120..-10081,y=49549..82374,z=-51647..-23803
off x=4482..15932,y=52105..87492,z=-43635..-24319
on x=44172..59482,y=-19911..-2275,z=-78621..-58162
off x=59468..86038,y=-14536..2739,z=10450..29483
on x=35202..63524,y=41597..52608,z=25750..50621
off x=43477..57153,y=-70672..-51768,z=-29231..-12944
off x=-76042..-40379,y=-63623..-34713,z=9361..34739
on x=5214..23322,y=-40957..-21165,z=62349..85212
off x=-47881..-40665,y=63458..78742,z=-18329..14224
on x=-10247..17311,y=-4099..16337,z=65482..85909
on x=41208..65414,y=-61506..-44899,z=-3099..15002
off x=34668..49554,y=-73174..-48408,z=-36961..-19729
on x=-11336..14169,y=-80558..-60447,z=-29959..-8195
off x=39163..59951,y=36360..55948,z=-21398..-1332
on x=-19138..7036,y=-25645..-1276,z=-86758..-68226
on x=10154..32952,y=29767..57557,z=-75950..-50512
on x=-53060..-37510,y=-25418..2290,z=-66221..-47902
off x=-19792..1895,y=-56560..-51122,z=48767..62438
off x=-2692..17518,y=-55069..-25680,z=55131..76195
off x=-403..29582,y=-47043..-17464,z=67050..74642
on x=-24534..-4330,y=-80643..-68648,z=23136..41818
on x=29991..59992,y=-69775..-49447,z=20027..52143
off x=57071..88621,y=153..27695,z=-32070..-13600
off x=-10777..7658,y=43167..79977,z=-68573..-34353
on x=-78741..-67652,y=22621..56471,z=-33254..-13641
off x=51790..78277,y=-32886..-21363,z=-37243..-18415
on x=-22218..-4799,y=-21448..5765,z=74942..94702
on x=-45892..-28800,y=47095..56026,z=41577..60550
off x=25599..58677,y=50234..69465,z=-14149..2299
on x=-54021..-23346,y=-3221..15812,z=-72254..-52418
on x=-68585..-49653,y=-3360..17174,z=-67528..-36092
on x=16696..26792,y=-75308..-53537,z=36269..52362
on x=-52626..-32643,y=56995..81168,z=-2061..14624
off x=-34862..1836,y=74583..96574,z=-367..23648
off x=-77850..-71223,y=-17599..-8196,z=-27723..2191
on x=-50069..-29253,y=-76351..-52375,z=-2578..13565
off x=47611..58555,y=-30695..-15461,z=52202..63608
on x=42345..65794,y=-61356..-30932,z=-49888..-34781
off x=20536..35976,y=55157..89859,z=-17928..5034
off x=62071..86210,y=-7472..2887,z=19369..52417
on x=28251..34989,y=-72267..-51993,z=-29702..-25256
on x=-10007..8937,y=28869..48792,z=-86417..-57724
on x=-61096..-38315,y=-55464..-37721,z=38304..52565
off x=-21873..11058,y=-95410..-69205,z=17631..33685
on x=68901..96097,y=14891..22014,z=-31598..1877
on x=2861..30004,y=-27756..-12416,z=-80665..-75501
on x=-38513..-2607,y=51602..79901,z=44490..46797
on x=-73322..-50785,y=-31178..371,z=48908..67489
on x=39892..77398,y=32300..56261,z=30717..50973
on x=42522..63479,y=-11037..1169,z=48074..76460
off x=19424..35734,y=-56271..-34475,z=53748..78224
off x=9192..33410,y=-30142..-12590,z=-71893..-56225
off x=-19114..14002,y=-93621..-60070,z=19829..21803
off x=59640..82497,y=15521..24299,z=-6270..16821
on x=-12231..1492,y=-84407..-60795,z=-31290..-10555
off x=-72894..-66717,y=14296..43197,z=-20686..-7104
on x=63568..68026,y=-37281..-35097,z=21251..44468
on x=-1844..13737,y=-2621..25330,z=63727..79864
on x=18228..42835,y=-6896..25052,z=67548..81521
off x=-23212..-1750,y=66983..93557,z=-5596..8275
on x=-12455..23249,y=-89159..-77661,z=-9529..-1875
on x=-33152..52,y=-93382..-74489,z=-32975..15
off x=29589..37600,y=58848..76555,z=13896..39941
on x=-11024..8831,y=54371..67738,z=30983..51427
on x=-61198..-28583,y=405..29404,z=57300..74608
off x=1214..32152,y=22420..43546,z=-81049..-65072
on x=-34012..-30792,y=-78156..-47672,z=-35960..-20496
on x=23962..53915,y=30616..47898,z=44821..70152
off x=39076..61792,y=33969..63786,z=12614..34152
on x=24771..56965,y=-70333..-53939,z=-30592..-25403
off x=55670..85161,y=19250..47583,z=-19687..-35
on x=61402..80219,y=4975..20655,z=-18161..1814
on x=-63528..-40613,y=-54656..-51615,z=-18568..-7770
off x=21952..44859,y=28549..43996,z=-67616..-44529
off x=349..11389,y=34235..65301,z=-69339..-52128
off x=27055..34708,y=-14438..8061,z=68787..74936
on x=6776..28116,y=-33442..-17136,z=60533..79764
on x=54681..86337,y=-52321..-17455,z=-30821..-8065
on x=-60712..-31055,y=-47034..-21985,z=-70329..-52980
on x=53378..65013,y=1739..17704,z=43369..64000
on x=-21771..369,y=56025..64514,z=46505..57641
off x=-3256..15577,y=8710..41297,z=65810..87150
on x=54452..90336,y=-44681..-27689,z=-3182..19982
off x=55359..89314,y=25058..37589,z=-28802..-8718

74
2021/22.py Normal file
View File

@@ -0,0 +1,74 @@
# with open("./2021/22.test") as input_file:
with open("./2021/22.input") as input_file:
input_data = input_file.read()
instructions_raw = input_data.split("\n")
print(instructions_raw)
instructions_parsed = []
for one_instruction in instructions_raw:
one_parsed = {}
one_parsed['instruction'] = one_instruction.split(" ")[0]
one_parsed['x_min'] = int(one_instruction.split(" ")[1].split(",")[0].split('=')[1].split('..')[0])
one_parsed['x_max'] = int(one_instruction.split(" ")[1].split(",")[0].split('=')[1].split('..')[1])
one_parsed['y_min'] = int(one_instruction.split(" ")[1].split(",")[1].split('=')[1].split('..')[0])
one_parsed['y_max'] = int(one_instruction.split(" ")[1].split(",")[1].split('=')[1].split('..')[1])
one_parsed['z_min'] = int(one_instruction.split(" ")[1].split(",")[2].split('=')[1].split('..')[0])
one_parsed['z_max'] = int(one_instruction.split(" ")[1].split(",")[2].split('=')[1].split('..')[1])
print(one_parsed)
instructions_parsed.append(one_parsed)
on_counter = 0
on_array = {}
for one_instruction in instructions_parsed:
print(one_instruction)
instruction_counter = 0
x_min = one_instruction['x_min']
x_max = one_instruction['x_max']
y_min = one_instruction['y_min']
y_max = one_instruction['y_max']
z_min = one_instruction['z_min']
z_max = one_instruction['z_max']
# # Constrain to -50..50
# x_min = max(one_instruction['x_min'], -50)
# x_max = min(one_instruction['x_max'], 50)
# y_min = max(one_instruction['y_min'], -50)
# y_max = min(one_instruction['y_max'], 50)
# z_min = max(one_instruction['z_min'], -50)
# z_max = min(one_instruction['z_max'], 50)
for x in range(x_min, x_max + 1):
for y in range(y_min, y_max + 1):
for z in range(z_min, z_max + 1):
if x not in on_array.keys():
on_array[x] = {}
if y not in on_array[x].keys():
on_array[x][y] = {}
if z not in on_array[x][y].keys():
on_array[x][y][z] = ""
if one_instruction['instruction'] == 'on' and on_array[x][y][z] != 'on':
on_counter += 1
instruction_counter += 1
if one_instruction['instruction'] == 'off' and on_array[x][y][z] == 'on':
on_counter -= 1
instruction_counter -= 1
on_array[x][y][z] = one_instruction['instruction']
print(f'''Processing ({x:6}, {y:6}, {z:6}) {on_counter:6}''', end="\r")
print("\r", instruction_counter)
# on_counter = 0
# for x in on_array.keys():
# for y in on_array[x].keys():
# for z in on_array[x][y][z].keys():
# print(f'''Counting ({x:6}, {y:6}, {z:6})''', end="\r")
# on_counter += 1
print(on_counter)

4
2021/22.test Normal file
View File

@@ -0,0 +1,4 @@
on x=10..12,y=10..12,z=10..12
on x=11..13,y=11..13,z=11..13
off x=9..11,y=9..11,z=9..11
on x=10..10,y=10..10,z=10..10

7
2021/23.input Normal file
View File

@@ -0,0 +1,7 @@
#############
#...........#
###C#A#B#D###
#D#C#B#A#
#D#B#A#C#
#B#A#D#C#
#########

963
2021/23.py Normal file
View File

@@ -0,0 +1,963 @@
#region Imports
import collections
import copy
import functools
import heapq
import itertools
import math
import operator
import re
import sys
import typing
from collections import Counter, defaultdict, deque
from copy import deepcopy
from functools import reduce
from pprint import pprint
#endregion
sys.setrecursionlimit(100000)
T = typing.TypeVar("T")
# Copy a function if you need to modify it.
AIR = "."
WALL = "#"
#region Strings, lists, dicts
def lmap(func, *iterables):
return list(map(func, *iterables))
def make_grid(*dimensions: typing.List[int], fill=None):
"Returns a grid such that 'dimensions' is juuust out of bounds."
if len(dimensions) == 1:
return [fill for _ in range(dimensions[0])]
next_down = make_grid(*dimensions[1:], fill=fill)
return [copy.deepcopy(next_down) for _ in range(dimensions[0])]
def min_max(l):
return min(l), max(l)
def max_minus_min(l):
return max(l) - min(l)
def partial_sum(l):
"out[i] == sum(in[:i])"
out = [0]
for i in l:
out.append(out[-1] + i)
return out
cum_sum = partial_sum
def list_diff(x):
return [b-a for a, b in zip(x, x[1:])]
def flatten(l):
return [i for x in l for i in x]
def every_n(l,n):
return list(zip(*[iter(l)]*n))
def windows(l, n):
return list(zip(*[l[i:] for i in range(n)]))
def ints(s: str) -> typing.List[int]:
assert isinstance(s, str), f"you passed in a {type(s)}!!!"
return lmap(int, re.findall(r"(?:(?<!\d)-)?\d+", s)) # thanks mserrano!
def positive_ints(s: str) -> typing.List[int]:
assert isinstance(s, str), f"you passed in a {type(s)}!!!"
return lmap(int, re.findall(r"\d+", s)) # thanks mserrano!
def floats(s: str) -> typing.List[float]:
assert isinstance(s, str), f"you passed in a {type(s)}!!!"
return lmap(float, re.findall(r"-?\d+(?:\.\d+)?", s))
def positive_floats(s: str) -> typing.List[float]:
assert isinstance(s, str), f"you passed in a {type(s)}!!!"
return lmap(float, re.findall(r"\d+(?:\.\d+)?", s))
def words(s: str) -> typing.List[str]:
assert isinstance(s, str), f"you passed in a {type(s)}!!!"
return re.findall(r"[a-zA-Z]+", s)
def keyvalues(d):
return list(d.items()) # keep on forgetting this...
def make_hashable(l):
if isinstance(l, list):
return tuple(map(make_hashable, l))
if isinstance(l, dict):
l = set(l.items())
if isinstance(l, set):
return frozenset(map(make_hashable, l))
return l
def invert_dict(d, single=True):
out = {}
if single:
for k, v in d.items():
v = make_hashable(v)
if v in out:
print("[invert_dict] WARNING WARNING: duplicate key", v)
out[v] = k
else:
for k, v in d.items():
v = make_hashable(v)
out.setdefault(v, []).append(k)
return out
#endregion
#region Algorithms
class RepeatingSequence:
def __init__(self, generator, to_hashable=lambda x: x):
"""
generator should yield the things in the sequence.
to_hashable should be used if things aren't nicely hashable.
"""
self.index_to_result = []
self.hashable_to_index = dict()
for i, result in enumerate(generator):
self.index_to_result.append(result)
hashable = to_hashable(result)
if hashable in self.hashable_to_index:
break
else:
self.hashable_to_index[hashable] = i
else:
raise Exception("generator terminated without repeat")
self.cycle_begin = self.hashable_to_index[hashable]
self.cycle_end = i
self.cycle_length = self.cycle_end - self.cycle_begin
self.first_repeated_result = self.index_to_result[self.cycle_begin]
self.second_repeated_result = self.index_to_result[self.cycle_end]
def cycle_number(self, index):
"""
Returns which 0-indexed cycle index appears in.
cycle_number(cycle_begin) is the first index to return 0,
cycle_number(cycle_end) is the first index to return 1,
and so on.
"""
if index < self.cycle_begin:
print("WARNING: Index is before cycle!!")
return 0
return (index - self.cycle_begin) // self.cycle_length
def __getitem__(self, index):
"""
Gets an item in the sequence.
If index >= cycle_length, returns the items from the first occurrence
of the cycle.
Use first_repeated_result and second_repeated_result if needed.
"""
if index < 0:
raise Exception("index can't be negative")
if index < self.cycle_begin:
return self.index_to_result[index]
cycle_offset = (index - self.cycle_begin) % self.cycle_length
return self.index_to_result[self.cycle_begin + cycle_offset]
def bisect(f, lo=0, hi=None, eps=1e-9):
"""
Returns a value x such that f(x) is true.
Based on the values of f at lo and hi.
Assert that f(lo) != f(hi).
"""
lo_bool = f(lo)
if hi is None:
offset = 1
while f(lo+offset) == lo_bool:
offset *= 2
hi = lo + offset
else:
assert f(hi) != lo_bool
while hi - lo > eps:
mid = (hi + lo) / 2
if f(mid) == lo_bool:
lo = mid
else:
hi = mid
if lo_bool:
return lo
else:
return hi
def binary_search(f, lo=0, hi=None):
"""
Returns a value x such that f(x) is true.
Based on the values of f at lo and hi.
Assert that f(lo) != f(hi).
"""
lo_bool = f(lo)
if hi is None:
offset = 1
while f(lo+offset) == lo_bool:
offset *= 2
hi = lo + offset
else:
assert f(hi) != lo_bool
best_so_far = lo if lo_bool else hi
while lo <= hi:
mid = (hi + lo) // 2
result = f(mid)
if result:
best_so_far = mid
if result == lo_bool:
lo = mid + 1
else:
hi = mid - 1
return best_so_far
# Graphs
def topsort(out_edges: typing.Dict[T, typing.List[T]]) -> typing.List[T]:
temp = set() # type: typing.Set[T]
seen = set() # type: typing.Set[T]
out = []
def dfs(n):
nonlocal temp,seen,out
if n in seen:
return
if n in temp:
raise Exception("not a DAG")
temp.add(n)
if n in out_edges:
for other in out_edges[n]:
dfs(other)
temp.remove(n)
seen.add(n)
out.append(n)
for n in out_edges:
dfs(n)
out.reverse()
return out
def path_from_parents(parents: typing.Dict[T, T], end: T) -> typing.List[T]:
out = [end]
while out[-1] in parents:
out.append(parents[out[-1]])
out.reverse()
return out
def dijkstra(
from_node: T,
expand: typing.Callable[[T], typing.Iterable[typing.Tuple[int, T]]],
to_node: typing.Optional[T] = None,
heuristic: typing.Optional[typing.Callable[[T], int]] = None,
) -> typing.Tuple[typing.Dict[T, int], typing.Dict[T, T]]:
"""
expand should return an iterable of (dist, successor node) tuples.
Returns (distances, parents).
Use path_from_parents(parents, node) to get a path.
"""
if heuristic is None:
heuristic = lambda _: 0
seen = set() # type: typing.Set[T]
g_values = {from_node: 0} # type: typing.Dict[T, int]
parents = {} # type: typing.Dict[T, T]
# (f, g, n)
todo = [(0 + heuristic(from_node), 0, from_node)] # type: typing.List[typing.Tuple[int, int, T]]
while todo:
f, g, node = heapq.heappop(todo)
assert node in g_values
assert g_values[node] <= g
if node in seen:
continue
assert g_values[node] == g
if to_node is not None and node == to_node:
break
seen.add(node)
for cost, new_node in expand(node):
new_g = g + cost
if new_node not in g_values or new_g < g_values[new_node]:
parents[new_node] = node
g_values[new_node] = new_g
heapq.heappush(todo, (new_g + heuristic(new_node), new_g, new_node))
return (g_values, parents)
def a_star(
from_node: T,
expand: typing.Callable[[T], typing.Iterable[typing.Tuple[int, T]]],
to_node: T,
heuristic: typing.Optional[typing.Callable[[T], int]] = None,
) -> typing.Tuple[int, typing.List[T]]:
"""
expand should return an iterable of (dist, successor node) tuples.
Returns (distance, path).
"""
g_values, parents = dijkstra(from_node, to_node=to_node, expand=expand, heuristic=heuristic)
if to_node not in g_values:
raise Exception("couldn't reach to_node")
return (g_values[to_node], path_from_parents(parents, to_node))
def bfs(
from_node: T,
expand: typing.Callable[[T], typing.Iterable[T]],
to_node: typing.Optional[T] = None
) -> typing.Tuple[typing.Dict[T, int], typing.Dict[T, T]]:
"""
expand should return an iterable of successor nodes.
Returns (distances, parents).
"""
g_values = {from_node: 0} # type: typing.Tuple[typing.Dict[T, int]]
parents = {} # type: typing.Dict[T, T]
todo = [from_node] # type: typing.List[T]
dist = 0
while todo:
new_todo = []
dist += 1
for node in todo:
for new_node in expand(node):
if new_node not in g_values:
new_todo.append(new_node)
parents[new_node] = node
g_values[new_node] = dist
todo = new_todo
if to_node is not None and to_node in g_values:
break
return (g_values, parents)
def bfs_single(
from_node: T,
expand: typing.Callable[[T], typing.Iterable[T]],
to_node: T,
) -> typing.Tuple[int, typing.List[T]]:
"""
expand should return an iterable of successor nodes.
Returns (distance, path).
"""
g_values, parents = bfs(from_node, to_node=to_node, expand=expand)
if to_node not in g_values:
raise Exception("couldn't reach to_node")
return (g_values[to_node], path_from_parents(parents, to_node))
# Distances
BLANK = object()
def hamming_distance(a, b) -> int:
return sum(i is BLANK or j is BLANK or i != j for i, j in itertools.zip_longest(a, b, fillvalue=BLANK))
def edit_distance(a, b) -> int:
n = len(a)
m = len(b)
dp = [[None] * (m+1) for _ in range(n+1)]
dp[n][m] = 0
def aux(i, j):
assert 0 <= i <= n and 0 <= j <= m
if dp[i][j] is not None:
return dp[i][j]
if i == n:
dp[i][j] = 1 + aux(i, j+1)
elif j == m:
dp[i][j] = 1 + aux(i+1, j)
else:
dp[i][j] = min((a[i] != b[j]) + aux(i+1, j+1), 1 + aux(i+1, j), 1 + aux(i, j+1))
return dp[i][j]
return aux(0, 0)
#endregion
#region Data Structures
class Linked(typing.Generic[T], typing.Iterable[T]):
"""
Represents a node in a doubly linked lists.
Can also be interpreted as a list itself.
Consider this to be first in the list.
"""
# item: T
# forward: "Linked[T]"
# backward: "Linked[T]"
def __init__(self, item: T) -> None:
self.item = item
self.forward = self
self.backward = self
@property
def val(self): return self.item
@property
def after(self): return self.forward
@property
def before(self): return self.backward
def _join(self, other: "Linked[T]") -> None:
self.forward = other
other.backward = self
def concat(self, other: "Linked[T]") -> None:
"""
Concatenates other AFTER THE END OF THE LIST,
i.e. before this current node.
"""
first_self = self
last_self = self.backward
first_other = other
last_other = other.backward
# self ++ other
# consider last_self and first_other
last_self._join(first_other)
last_other._join(first_self)
def concat_immediate(self, other: "Linked[T]") -> None:
"""
Concatenates other IN THE "SECOND" INDEX OF THE LIST
i.e. after this current node.
"""
self.forward.concat(other)
def append(self, val: T) -> None:
"""
Appends an item AFTER THE END OF THE LIST,
i.e. before this current node.
"""
self.concat(Linked(val))
def append_immediate(self, val: T) -> None:
"""
Appends an item IN THE "SECOND" INDEX OF THE LIST
i.e. after this current node.
"""
self.concat_immediate(Linked(val))
def pop(self, n: int = 1) -> None:
"""
Pops this node, as well as n others, off from the "parent list"
into its own list.
"""
assert n > 0
first_self = self
last_self = self.move(n-1)
first_other = last_self.forward
last_other = first_self.backward
last_other._join(first_other)
last_self._join(first_self)
def pop_after(self, after: int, n: int = 1) -> None:
"""
Pops the node n nodes after this node, as well as n others, into its
own list.
Returns the node n nodes after this node (in its new list).
"""
to_return = self.move(after)
to_return.pop(n) # music
return to_return
def delete(self) -> None:
"""
Deletes this node from the "parent list" into its own list.
"""
self.pop()
def delete_other(self, n: int) -> None:
"""
Deletes a node n nodes forward, or backwards if n is negative.
"""
to_delete = self.move(n)
if to_delete is self:
raise Exception("can't delete self")
to_delete.delete()
del to_delete
def move(self, n: int) -> "Linked[T]":
"""
Move n nodes forward, or backwards if n is negative.
"""
out = self
if n >= 0:
for _ in range(n):
out = out.forward
else:
for _ in range(-n):
out = out.backward
return out
def iterate_nodes_inf(self) -> typing.Iterator["Linked[T]"]:
cur = self
while True:
yield cur
cur = cur.forward
def iterate_nodes(self, count=1) -> typing.Iterator["Linked[T]"]:
for node in self.iterate_nodes_inf():
if node is self:
count -= 1
if count < 0:
break
yield node
def iterate_inf(self) -> typing.Iterator[T]:
return map(lambda node: node.item, self.iterate_nodes_inf())
def iterate(self, count=1) -> typing.Iterator[T]:
return map(lambda node: node.item, self.iterate_nodes(count))
def to_list(self):
return list(self.iterate())
def check_correctness(self) -> None:
assert self.forward.backward is self
assert self.backward.forward is self
def check_correctness_deep(self) -> None:
for node in self.iterate_nodes():
node.check_correctness()
def __iter__(self) -> typing.Iterator[T]:
return self.iterate()
def __repr__(self) -> str:
return "Linked({})".format(self.to_list())
@classmethod
def from_list(cls, l: typing.Iterable[T]) -> "Linked[T]":
it = iter(l)
out = cls(next(it))
for i in it:
out.concat(cls(i))
return out
class UnionFind:
# n: int
# parents: List[Optional[int]]
# ranks: List[int]
# num_sets: int
def __init__(self, n: int) -> None:
self.n = n
self.parents = [None] * n
self.ranks = [1] * n
self.num_sets = n
def find(self, i: int) -> int:
p = self.parents[i]
if p is None:
return i
p = self.find(p)
self.parents[i] = p
return p
def in_same_set(self, i: int, j: int) -> bool:
return self.find(i) == self.find(j)
def merge(self, i: int, j: int) -> None:
i = self.find(i)
j = self.find(j)
if i == j:
return
i_rank = self.ranks[i]
j_rank = self.ranks[j]
if i_rank < j_rank:
self.parents[i] = j
elif i_rank > j_rank:
self.parents[j] = i
else:
self.parents[j] = i
self.ranks[i] += 1
self.num_sets -= 1
class Grid(typing.Generic[T]):
"""2D only!!!"""
def __init__(self, grid: typing.List[typing.List[T]]) -> None:
self.grid = grid
self.rows = len(self.grid)
self.cols = len(self.grid[0])
def coords(self) -> typing.List[typing.List[int]]:
return [[r, c] for r in range(self.rows) for c in range(self.cols)]
def get_row(self, row: int):
assert 0 <= row < self.rows, f"row {row} is OOB"
def in_bounds(self, row: int, col: int) -> bool:
return 0 <= row < self.rows and 0 <= col < self.cols
def __contains__(self, coord: typing.Union[typing.Tuple[int, int], typing.List[int]]) -> bool:
return self.in_bounds(*coord)
def __getitem__(self, coord: typing.Union[typing.Tuple[int, int], typing.List[int]]) -> T:
return self.grid[coord[0]][coord[1]]
#endregion
#region List/Vector operations
GRID_DELTA = [[-1, 0], [1, 0], [0, -1], [0, 1]]
OCT_DELTA = [[1, 1], [-1, -1], [1, -1], [-1, 1]] + GRID_DELTA
CHAR_TO_DELTA = {
"U": [-1, 0],
"R": [0, 1],
"D": [1, 0],
"L": [0, -1],
"N": [-1, 0],
"E": [0, 1],
"S": [1, 0],
"W": [0, -1],
}
DELTA_TO_UDLR = {
(-1, 0): "U",
(0, 1): "R",
(1, 0): "D",
(0, -1): "L",
}
DELTA_TO_NESW = {
(-1, 0): "N",
(0, 1): "E",
(1, 0): "S",
(0, -1): "W",
}
def turn_180(drowcol):
drow, dcol = drowcol
return [-drow, -dcol]
def turn_right(drowcol):
# positive dcol -> positive drow
# positive drow -> negative dcol
drow, dcol = drowcol
return [dcol, -drow]
def turn_left(drowcol):
drow, dcol = drowcol
return [-dcol, drow]
def dimensions(grid: typing.List) -> typing.List[int]:
out = []
while isinstance(grid, list):
out.append(len(grid))
grid = grid[0]
return out
def neighbours(coord, dimensions, deltas) -> typing.List[typing.List[int]]:
out = []
for delta in deltas:
new_coord = padd(coord, delta)
if all(0 <= c < c_max for c, c_max in zip(new_coord, dimensions)):
out.append(new_coord)
return out
def lget(l, i):
if len(l) == 2: return l[i[0]][i[1]]
for index in i: l = l[index]
return l
def lset(l, i, v):
if len(l) == 2:
l[i[0]][i[1]] = v
return
for index in i[:-1]: l = l[index]
l[i[-1]] = v
def points_sub_min(points):
m = [min(p[i] for p in points) for i in range(len(points[0]))]
return [psub(p, m) for p in points]
def points_to_grid(points, sub_min=True, flip=True):
if sub_min:
points = points_sub_min(points)
if not flip:
points = [(y, x) for x, y in points]
grid = make_grid(max(map(snd, points))+1, max(map(fst, points))+1, fill='.')
for x, y in points:
grid[y][x] = '#'
return grid
def print_grid(grid):
for line in grid:
print(*line, sep="")
def fst(x):
return x[0]
def snd(x):
return x[1]
def padd(x, y):
return [a+b for a, b in zip(x, y)]
def pneg(v):
return [-i for i in v]
def psub(x, y):
return [a-b for a, b in zip(x, y)]
def pmul(m: int, v):
return [m * i for i in v]
def pdot(x, y):
return sum(a*b for a, b in zip(x, y))
def pdist1(x, y=None):
if y is not None: x = psub(x, y)
return sum(map(abs, x))
def pdist2sq(x, y=None):
if y is not None: x = psub(x, y)
return sum(i*i for i in x)
def pdist2(v):
return math.sqrt(pdist2sq(v))
def pdistinf(x, y=None):
if y is not None: x = psub(x, y)
return max(map(abs, x))
def signum(n: int) -> int:
if n > 0:
return 1
elif n == 0:
return 0
else:
return -1
#endregion
#region Matrices
def matmat(a, b):
n, k1 = len(a), len(a[0])
k2, m = len(b), len(b[0])
assert k1 == k2
out = [[None] * m for _ in range(n)]
for i in range(n):
for j in range(m): out[i][j] = sum(a[i][k] * b[k][j] for k in range(k1))
return out
def matvec(a, v):
return [j for i in matmat(a, [[x] for x in v]) for j in i]
def matexp(a, k):
n = len(a)
out = [[int(i==j) for j in range(n)] for i in range(n)]
while k > 0:
if k % 2 == 1: out = matmat(a, out)
a = matmat(a, a)
k //= 2
return out
#endregion
#region Running
def parse_samples(l):
samples = [thing.strip("\n") for thing in l]
while samples and not samples[-1]: samples.pop()
return samples
def get_actual(day=None, year=None):
try:
this_file = __file__
except NameError:
this_file = "./utils.py"
try:
actual_input = open("./2021/23.input").read()
return actual_input
except FileNotFoundError:
pass
from pathlib import Path
cur_folder = Path(this_file).resolve().parent
input_path = cur_folder.joinpath("input.txt")
search_path = cur_folder
try:
if day is None:
day = int(search_path.name)
if year is None:
year = int(search_path.parent.name)
except Exception:
print("Can't get day and year.")
print("Backup: save 'input.txt' into the same folder as this script.")
return ""
print("{} day {} input not found.".format(year, day))
# is it time?
from datetime import datetime, timezone, timedelta
est = timezone(timedelta(hours=-5))
unlock_time = datetime(year, 12, day, tzinfo=est)
cur_time = datetime.now(tz=est)
delta = unlock_time - cur_time
if delta.days >= 0:
print("Remaining time until unlock: {}".format(delta))
return ""
while (not list(search_path.glob("*/token.txt"))) and search_path.parent != search_path:
search_path = search_path.parent
token_files = list(search_path.glob("*/token.txt"))
if not token_files:
assert search_path.parent == search_path
print("Can't find token.txt in a parent directory.")
print("Backup: save 'input.txt' into the same folder as this script.")
return ""
with token_files[0].open() as f:
token = f.read().strip()
# importing requests takes a long time...
# let's do it without requests.
import urllib.request
import urllib.error
import shutil
opener = urllib.request.build_opener()
opener.addheaders = [("Cookie", "session={}".format(token)), ("User-Agent", "python-requests/2.19.1")]
print("Sending request...")
url = "https://adventofcode.com/{}/day/{}/input".format(year, day)
try:
with opener.open(url) as r:
with input_path.open(mode="wb") as f:
shutil.copyfileobj(r, f)
print("Input saved! First few lines look like:")
actual = input_path.open().read()
lines = actual.splitlines()
for line in lines[:16]:
print(line[:80] + "" * (len(line) > 80))
return actual
except urllib.error.HTTPError as e:
status_code = e.getcode()
if status_code == 400:
print("Auth failed!")
elif status_code == 404:
print("Day is not out yet????")
else:
print("Request failed with code {}??".format(status_code))
return ""
def run_samples_and_actual(samples, do_case):
samples = parse_samples(samples)
for sample in samples:
print("running {}:".format(repr(sample)[:100]))
print("-"*10)
do_case(sample, True)
print("-"*10)
print("#"*10)
actual_input = get_actual().strip("\n")
if actual_input:
print("!! running actual ({} lines): !!".format(actual_input.count("\n")+1))
print("-"*10)
do_case(actual_input, False)
print("-"*10)
#endregion
import sys; sys.dont_write_bytecode = True; from utils import *
WAITING_ROW = 1
WAITING_COLS = [1, 2, 4, 6, 8, 10, 11]
ROOM_COLS = [3, 5, 7, 9]
COST = {"A": 1, "B": 10, "C": 100, "D": 1000}
def do_case(inp: str, sample=False):
# READ THE PROBLEM FROM TOP TO BOTTOM OK
def sprint(*a, **k): sample and print(*a, **k)
lines: typing.List[str] = inp.splitlines()
out = 0
FINAL_NODE = tuple()
def expand(node):
# (weight, node)
out = []
# I wrote this line of code first before doing anything else
# with the problem. It's good to know your search space!
cur_waitings, cur_rooms = node
if all(all(chr(ord('A')+i) == x for x in room) for i, room in enumerate(cur_rooms)):
return [(0, FINAL_NODE)]
def is_blocked(col_1, col_2):
if col_1 > col_2:
col_1, col_2 = col_2, col_1
for blocked_col in range(col_1+1, col_2):
# This could really be improved...
if blocked_col in WAITING_COLS and cur_waitings[WAITING_COLS.index(blocked_col)] != "":
return True
return False
# Move from a room to a waiting spot.
for room_idx, room in enumerate(cur_rooms):
# The below uses the fact that:
# - loop variables are still in-scope after the loop is finished, and
# - you can add an "else" to a for loop which is run if it's not `break`ed from.
for room_position, to_move in enumerate(room):
if to_move == "":
continue
to_move_row = 2+room_position
break
else:
continue
for waiting_idx, waiting_col in enumerate(WAITING_COLS):
if cur_waitings[waiting_idx] == "":
if is_blocked(waiting_col, ROOM_COLS[room_idx]):
continue
new_waitings = list(cur_waitings)
new_rooms = list(map(list, cur_rooms))
# To get the cost of moving, I used the Manhattan distance
# between the source and destination as it should always work
# for this with a single corridor.
# If the corridor was expanded, this wouldn't be as simple...
cost = pdist1((to_move_row, ROOM_COLS[room_idx]), (WAITING_ROW, waiting_col)) * COST[to_move]
new_waitings[waiting_idx] = to_move
new_rooms[room_idx][room_position] = ""
out.append((cost, (tuple(new_waitings), tuple(map(tuple, new_rooms)))))
# Move from a waiting spot to a room.
for waiting_idx, waiting_col in enumerate(WAITING_COLS):
to_move = cur_waitings[waiting_idx]
if to_move == "":
continue
target_room_idx = ord(to_move) - ord('A')
target_room = cur_rooms[target_room_idx]
if target_room[0] == "" and all(x == "" or x == to_move for x in target_room[1:]):
for room_position in range(len(target_room))[::-1]:
if target_room[room_position] != "":
continue
room_row = room_position + 2
break
else:
assert False
room_col = ROOM_COLS[target_room_idx]
if is_blocked(waiting_col, room_col):
continue
cost = pdist1((room_row, room_col), (WAITING_ROW, waiting_col)) * COST[to_move]
new_waitings = list(cur_waitings)
new_rooms = list(map(list, cur_rooms))
new_waitings[waiting_idx] = ""
new_rooms[target_room_idx][room_position] = to_move
out.append((cost, (tuple(new_waitings), tuple(map(tuple, new_rooms)))))
return out
rooms = []
PART2 = ["DD", "CB", "BA", "AC"]
for i, room_col in enumerate(ROOM_COLS):
a, b = [lines[row][room_col] for row in [2, 3]]
rooms.append(tuple(a+PART2[i]+b))
# Replace the above with the below for part 1.
# This also came in handy for testing my generalised part 2 code
# to make sure that it works with part 1.
# rooms.append(tuple(a+b))
rooms = tuple(rooms)
print(rooms)
waitings = ("",)*len(WAITING_COLS)
# "A*" here is actually "Dijkstra, with a target node".
# My internal implementation also returns a path from start to finish,
# but I don't use it here.
out, _ = a_star((waitings, rooms), expand, FINAL_NODE)
if out:
print("out: ", out)
return # RETURNED VALUE DOESN'T DO ANYTHING, PRINT THINGS INSTEAD
run_samples_and_actual([
r"""
#############
#...........#
###C#A#B#D###
#B#A#D#C#
#########
""",r"""
""",r"""
""",r"""
""",r"""
""",r"""
""",r"""
"""], do_case)

164
2021/23.rs Normal file
View File

@@ -0,0 +1,164 @@
use std::collections::HashMap;
enum RegOrVal {
Reg(usize),
Val(i64),
}
impl RegOrVal {
fn to_val(&self, reg: &[i64; 4]) -> i64 {
match self {
RegOrVal::Reg(i) => reg[*i],
RegOrVal::Val(v) => *v,
}
}
}
enum Instruction {
Inp(usize),
Add(usize, RegOrVal),
Mul(usize, RegOrVal),
Div(usize, RegOrVal),
Mod(usize, RegOrVal),
Eql(usize, RegOrVal),
}
impl Instruction {
fn exec(&self, reg: &mut [i64; 4], input: Option<i64>) {
match self {
Instruction::Inp(a) => {
reg[*a] = input.unwrap();
}
Instruction::Add(a, b) => {
reg[*a] += b.to_val(reg);
}
Instruction::Mul(a, b) => {
reg[*a] *= b.to_val(reg);
}
Instruction::Div(a, b) => {
reg[*a] /= b.to_val(reg);
}
Instruction::Mod(a, b) => {
reg[*a] %= b.to_val(reg);
}
Instruction::Eql(a, b) => {
reg[*a] = if reg[*a] == b.to_val(reg) { 1 } else { 0 };
}
}
}
}
fn reg_idx(reg: char) -> usize {
match reg {
'w' => 0,
'x' => 1,
'y' => 2,
'z' => 3,
_ => panic!(),
}
}
fn best(
program: &[Instruction],
pc: usize,
reg: [i64; 4],
visited: &mut HashMap<([i64; 4], usize), Option<i64>>,
smallest: bool,
) -> Option<i64> {
assert!(matches!(program[pc], Instruction::Inp(_)));
if let Some(answer) = visited.get(&(reg, pc)) {
return *answer;
}
let range = if smallest {
[1, 2, 3, 4, 5, 6, 7, 8, 9]
} else {
[9, 8, 7, 6, 5, 4, 3, 2, 1]
};
'inputs: for input in range {
let mut reg = reg;
let mut pc = pc;
program[pc].exec(&mut reg, Some(input));
pc += 1;
while let Some(inst) = program.get(pc) {
if matches!(program[pc], Instruction::Inp(_)) {
if let Some(best) = best(program, pc, reg, visited, smallest) {
visited.insert((reg, pc), Some(best * 10 + input));
return Some(best * 10 + input);
} else {
continue 'inputs;
}
} else {
inst.exec(&mut reg, None);
pc += 1;
}
}
if reg[3] == 0 {
visited.insert((reg, pc), Some(input));
return Some(input);
}
}
visited.insert((reg, pc), None);
None
}
pub fn solve(input: &str, smallest: bool) -> i64 {
let mut program = Vec::new();
for line in input.trim().split('\n') {
let mut parts = line.split(' ');
let instruction = parts.next().unwrap();
let reg: char = parts.next().unwrap().parse().unwrap();
let b_value = parts.next().map(|a| {
a.parse::<i64>()
.map(RegOrVal::Val)
.unwrap_or_else(|_| RegOrVal::Reg(reg_idx(a.parse::<char>().unwrap())))
});
let reg = reg_idx(reg);
program.push(match (instruction, reg, b_value) {
("inp", reg, None) => Instruction::Inp(reg),
("add", a, Some(b)) => Instruction::Add(a, b),
("mul", a, Some(b)) => Instruction::Mul(a, b),
("div", a, Some(b)) => Instruction::Div(a, b),
("mod", a, Some(b)) => Instruction::Mod(a, b),
("eql", a, Some(b)) => Instruction::Eql(a, b),
_ => {
panic!();
}
});
}
let mut memo = HashMap::new();
let answer = best(&program, 0, [0; 4], &mut memo, smallest);
format!("{}", answer.unwrap())
.chars()
.rev()
.collect::<String>()
.parse()
.unwrap()
}
#[cfg(test)]
mod tests {
#[test]
fn part_a() {
assert_eq!(
super::solve(include_str!("./2021/24.input"), false),
79997391969649
);
}
#[test]
fn part_b() {
assert_eq!(
super::solve(include_str!("./2021/24.input"), true),
16931171414113
);
}
}

23
2021/23.test Normal file
View File

@@ -0,0 +1,23 @@
#############
#...........#
###C#A#B#D###
#D#C#B#A#
#D#B#A#C#
#B#A#D#C#
#########
############# 5
#A..........#
###C#.#B#D###
#D#C#B#A#
#D#B#A#C#
#B#A#D#C#
#########
############# 50
#AC.B.......#
###C#.#B#D###
#D#.#B#A#
#D#.#A#C#
#B#A#D#C#
#########

252
2021/24.input Normal file
View File

@@ -0,0 +1,252 @@
inp w
mul x 0
add x z
mod x 26
div z 1
add x 12
eql x w
eql x 0
mul y 0
add y 25
mul y x
add y 1
mul z y
mul y 0
add y w
add y 4
mul y x
add z y
inp w
mul x 0
add x z
mod x 26
div z 1
add x 11
eql x w
eql x 0
mul y 0
add y 25
mul y x
add y 1
mul z y
mul y 0
add y w
add y 11
mul y x
add z y
inp w
mul x 0
add x z
mod x 26
div z 1
add x 13
eql x w
eql x 0
mul y 0
add y 25
mul y x
add y 1
mul z y
mul y 0
add y w
add y 5
mul y x
add z y
inp w
mul x 0
add x z
mod x 26
div z 1
add x 11
eql x w
eql x 0
mul y 0
add y 25
mul y x
add y 1
mul z y
mul y 0
add y w
add y 11
mul y x
add z y
inp w
mul x 0
add x z
mod x 26
div z 1
add x 14
eql x w
eql x 0
mul y 0
add y 25
mul y x
add y 1
mul z y
mul y 0
add y w
add y 14
mul y x
add z y
inp w
mul x 0
add x z
mod x 26
div z 26
add x -10
eql x w
eql x 0
mul y 0
add y 25
mul y x
add y 1
mul z y
mul y 0
add y w
add y 7
mul y x
add z y
inp w
mul x 0
add x z
mod x 26
div z 1
add x 11
eql x w
eql x 0
mul y 0
add y 25
mul y x
add y 1
mul z y
mul y 0
add y w
add y 11
mul y x
add z y
inp w
mul x 0
add x z
mod x 26
div z 26
add x -9
eql x w
eql x 0
mul y 0
add y 25
mul y x
add y 1
mul z y
mul y 0
add y w
add y 4
mul y x
add z y
inp w
mul x 0
add x z
mod x 26
div z 26
add x -3
eql x w
eql x 0
mul y 0
add y 25
mul y x
add y 1
mul z y
mul y 0
add y w
add y 6
mul y x
add z y
inp w
mul x 0
add x z
mod x 26
div z 1
add x 13
eql x w
eql x 0
mul y 0
add y 25
mul y x
add y 1
mul z y
mul y 0
add y w
add y 5
mul y x
add z y
inp w
mul x 0
add x z
mod x 26
div z 26
add x -5
eql x w
eql x 0
mul y 0
add y 25
mul y x
add y 1
mul z y
mul y 0
add y w
add y 9
mul y x
add z y
inp w
mul x 0
add x z
mod x 26
div z 26
add x -10
eql x w
eql x 0
mul y 0
add y 25
mul y x
add y 1
mul z y
mul y 0
add y w
add y 12
mul y x
add z y
inp w
mul x 0
add x z
mod x 26
div z 26
add x -4
eql x w
eql x 0
mul y 0
add y 25
mul y x
add y 1
mul z y
mul y 0
add y w
add y 14
mul y x
add z y
inp w
mul x 0
add x z
mod x 26
div z 26
add x -5
eql x w
eql x 0
mul y 0
add y 25
mul y x
add y 1
mul z y
mul y 0
add y w
add y 14
mul y x
add z y

99
2021/24.py Normal file
View File

@@ -0,0 +1,99 @@
import functools
import sys
inf = './2021/24.input'
ll = [x for x in open(inf).read().strip().split('\n')]
# BEGIN <UNUSED SECTION>
vs = 'wxyz'
def simulate(line, state):
state = list(state)
cmd = line.split(" ")[0]
if cmd == 'inp':
raise Exception("")
a = line.split(" ")[1]
b = line.split(" ")[2]
def parse(x):
if x in vs:
return state[vs.index(x)]
return int(x)
if cmd == 'add':
state[vs.index(a)] += parse(b)
if cmd == 'mul':
state[vs.index(a)] *= parse(b)
if cmd == 'div':
state[vs.index(a)] //= parse(b)
if cmd == 'mod':
state[vs.index(a)] %= parse(b)
if cmd == 'eql':
state[vs.index(a)] = int(state[vs.index(a)] == parse(b))
return tuple(state)
@functools.lru_cache(maxsize=None)
def run2(ch, zstart, w):
state = (w, 0, 0, zstart)
for i in range(ch*18+1, ch*18+18):
state = simulate(ll[i], state)
r = state[3]
print(run(ch, zstart, w) == r)
return r
# END </UNUSED SECTION>
# my input
#AX = [13, 11, 15, -11, 14, 0, 12, 12, 14, -6, -10, -12, -3, -5]
#DZ = [1, 1, 1, 26, 1, 26, 1, 1, 1, 26, 26, 26, 26, 26]
#AY = [13, 10, 5, 14, 5, 15, 4, 11, 1, 15, 12, 8, 14, 9]
AX = []
DZ = []
AY = []
for lineno, line in enumerate(ll):
if "add x " in line and "add x z" not in line:
AX.append(int(line.split()[2]))
if "div z " in line:
DZ.append(int(line.split()[2]))
if "add y " in line and lineno%18 == 15:
AY.append(int(line.split()[2]))
print("Extracted from input", AX, DZ, AY)
if len(AX) != 14 or len(DZ) != 14 or len(AY) != 14:
raise Exception("couldn't understand your input")
def run(ch, z, w):
x = AX[ch] + (z % 26)
z = z // DZ[ch]
if x != w:
z *= 26
z += w + AY[ch]
return z
Zbudget = [26**len([x for x in range(len(DZ)) if DZ[x]==26 and x >= i]) for i in range(len(DZ))]
print("Threshold for giving up due to Z being too high, at each stage has been calculated as", Zbudget)
CANDIDATES = list(range(1, 10))
@functools.lru_cache(maxsize=None)
def search(ch, zsofar):
if ch == 14:
if zsofar == 0:
return [""]
return []
if zsofar > Zbudget[ch]:
return []
xwillbe = AX[ch] + zsofar % 26
wopts = CANDIDATES
if xwillbe in range(1, 10):
wopts = [xwillbe]
ret = []
for w in wopts:
znext = run(ch, zsofar, w)
nxt = search(ch + 1, znext)
for x in nxt:
ret.append(str(w) + x)
return ret
solns = search(0, 0)
solns = [int(x) for x in solns]
print("num solutions", len(solns))
print(max(solns), min(solns))

0
2021/24.test Normal file
View File

137
2021/25.input Normal file
View File

@@ -0,0 +1,137 @@
vv.vv...v>>>.v.>vv.>v>..>.....>.v>.>......v.>vvv.v.>.v.v>>>..v...>.v>.vv>..v>.>.>...>.v.v.>>>v>.>>>>........>..v>v.>v>>.....>.vv.>v..>....v
.>>v>vv.>v..>>vv.....>....v>>.vv>.>.v.>>v.v>.vvvvv.>.>>>>v.v...>.vv.vvvvv.>vv..>.v>..>..>>...vv....>>.v.>v>>v..v.>....vv....>.v.....>.v>>..
>..vvv...v>v>....v.>>v.......>v.....v.v....v.....vv.>>>.vv..>..>v....v...>.vv..>.v>>..>...v..v.....>..v>>....>v>v..v...v>......>..vv...>..>
.>.>.>..v>...>>vvv..v..>...>.v.v.vv>>vv..v.v..>..>vv>v....vv.v.v..>v.>..v.>>..v...v..v>v....vvv.>>.>.v.>vv>v.>vvv.>v>>...v>v..>.>.>...v.>>>
..>v.v..vv>.>v>..v.>>>>vvv..>.vv.v.v>>..>>>v>.>>>v.>>..vv.v...>>..v..v>v..>>vv..>v>>>v.v...>>.>.v.>.vv.>vv.>>.v>v.>v...v.v.>vv..>>....v>..v
v.>vv.>>..v>v..>v.v..>.>..vv.v.>...>>.>v..v..>>v.>v..vv>v.>v.>..vv....v>v..>>>....v>...>>..v.>.v>.v.v.>>..>..>...vv>..vv...v.>v.>.>.v..v.vv
>v..v.>v>>>..>v...>>..>....v.>....v.vv>..>v>.>>.>.....>>.vv>...>vv.v.>>v..v...>...vv...v>..v>>.>>.>..v.>....>.vv.v>.>.>..v..>v>v>>v.>>...>v
.vv.>v>>....>>..>v..v.v>...>v>.v..v.>.>>....>...>..vv.>>v>>v...v>.>.>.v.v...>...v>.v>>.>...>.v>...v....>..>v.>.v.>>..>vv>.v>..v.v.v..>>.>>.
v.v......v.>>.>.>vv>..v..>v........>..v.>>>>v>>>>.>v..>>.v>v>.v..v..vv..>..v...v.>v..vv........v..>v.>..v..v....>.v>v..>v.>.>>....v>..v>.vv
>v..v......>...>>..>.v..v>..v.>..>v....vv...v.v.>.>v.>...>>.v...>.>........>....>.>>..>....v..>..>v>...vv.v...>>.>v>>vvv.v>.>>....v...v....
v>.v>>>v>>>...>>>>.>..v>vv>v>.v>>.....>....>.....v.v>v>v....>>>v>v..v.....vv..v.v.>...>>>vv..>.vv.....v..>v.vv.v..vvvv.v>.>..v>>>>v>v>..>v.
>.>.>vv..>.>.v>>.v...>>v..v.v>...vv....v>.>.>.....vv>>vv>>v....vv...v.vv.v....>>.>v>>vv..>>..v...>..>.v>...v...v.>>.>v.>v..>v....v>.v>..v>.
>.vv.>.v>.>..>v>..vv>.>vv>.>..>v>v.>>vvvv...>..>..v>...>vv>vv.v.>.....>..v>.v>vv.v.>.>>.v.v.v>.>>..>vv..v.>...vv>>>v.......v.>..v.v..>.v.>v
....>.v>v..v.v.vv.v...>>v>.>>>...vvvv..>.....>..v..v....vvv....>..v.v.v.>...>v.>>..>v....v.....vv..v>..vv....v.>>vv.>..>vv...>>.v....>.>>..
.>..>vv.....>v>...vv>..>..>..>.>.>v.>v>.>.vv>vvv.v..v...>>>>v>..v>.>v>vv.>v.>..v>....>.v>vv.v.....v..>.v...v...>.vv.v.v.....v.>.>.>.>.v>v..
v.>vv.>vv.>v.v...>>...vv>..>v..>>....v.>>>.....vvv...vvv.....v>v..vv.v...v>...v....>.v..v..v>vv>>vv...>..v>.vv>..>>..>>.....>.>....v>.>.vv.
v.>.....vv...v>v>>v..v.>>vvvvv..vvv>v..v..>..v>..>>..v.vv>>vvv>>.>.>>v..>....vv.>v.>.v..v.>v>.v.v.......v>..vvv>.>v.>.>vvv>..v.v.>>.v>v>>>.
v>..v>>>.>>>.>v>>..v.>..v.v.>v....>v.>...>>..>..>.v..>>..vvv...>v>>vvvv..v.v....v>.>...vv.>.v.>.......v>.v.>v...>.>v>.v.vv>>.v..>v.>.v.v.v.
...>.v...v...v.vv>..>.>v..v..>v...>>v.>..v>.>...v.>.....>.>......>v.v..v..>..>>>...>.>>.>>.>.vv.>...>.vv.>.v..v.>.vvvv...>v..v.vv>>..vv>>v.
>>>>..v.>.....>..v.v>...vvv>..v.v>...>v..>>>v.....v>..v..>.v.v.>>>v..v..v>>v....vv>v...v>...>v...>.....>v..>vvv..v.....v....>.>..>..>v>v.>.
>...vv>..>>>v.v>..>.>>>.vv>>.>v>..v.v.v..v.vv.....>>vv>.>.>.v.v.>.>.>.v..>...v.v>....v>>.vv>>v.>v....v.v>.v...>.>>v...>vv..>.vv.v.vv..v>>v.
vv>v.>>v...>>>.v.v.vv>>..>.>.v....v..>.>v>...>>v>v..v.vv.v..v..>v>.>..v..vv.v..v.v.v.vv>v..vvv.vv..v...v>.>>.>....v.v..>..v>v..v..v.vvv.>..
..v.v>......>>...v..>.>v.>..>vv.....>>..v.v.>v.>.v.>vv.v..vv.>..v>v..>.>...v..v>v>..v.>>.>>>vv..>vvvvv>>vv.....>>>v>>vv..v>>v..v.v.v>>>v>v.
.>vv...>...>...v.v>.v.>v.>.v.....>>>.>v....v...v>>>v..>>v..>....>>vv.>>vv.>vvvv>.>..v........vv.>.v.>v..vvv..>..v..>v.v>.>.>.>>..>.>.>..>>.
v.>...>v>.>.vv>.v>>v..v.....>>vv.v..v.>vvv>..v......>v>...v>..v..v...>v.v>>..v..v.v..>.>>v......vv..vv.>>v>>vv...>..>.>......>.>>v.>.....v.
...vv..v...vv....>>...>.....>.v>>>>>>.vv....>.v.>.>>..>v.v.....>v....v.>....>.v.v>>.v.v..>>.>..v>>.>>v.v>...v.v..>vv.>v...>>.v.v.>.vv.vv>..
>.>.>v..v>....>.>.v>v.......vv.v.v..>.>.>...vv.>.>>vvv>..>v..vvv>..>..v>v>..v..v>>>.v.>....>v..vv.>.>.>..>>.>>v>>.vv>vv...vv.>v>.v.v>.>vvv.
>>...v..v.>..vv.v...>.>..>>v.>.....>v.v.v>.v>v......>vv>>v....v>.....v........v>.>..v......>v.>v>..>vv..>....v...vvv.>v>.>>v.vv.>..>...vvvv
..v..vvv..>..>v>.>>..>v>..v..>v...>>v.....>>.>>>v.......v..>.>.vv.v..>v>.v.....vvv..vv.v...>.v..>v...>vv..v.>v.v.>..>.>>v>.>>.>.>v>v..v.>.v
.>vv>>v>>..v>vv....>.>..v.>..v>.v..v.vv.>>vv>vvv>...v.>>.v..>v.vv.>v.>v.>v>v.vv......>..>.....v>.>.v>v.>.......v>>>......>v.>.v..v>.>v..vv.
>...v.v>...>>..vvv.>>.>v.>.vv.v.>.>.vv>.vv>.v>>.>.v...vvv.>.v..vvv.>.v.vv.v..v.>>.v>v..vv>.>..vv.v.v.>vv..v>>>vvv>...>.v..>..v>..v.>>.vv.>.
.>....v..>.>...v......vv>>.>..>>>....>>.vvv>>v>....v.>vv>..v>vvv>.vv>>....v......>.>......v.>..v..v.vv...v>.>......v.v..v.>.vv....vv>.v>.>>
.v..vv>.>>v.>>>>>>.>v.v.>..>>.v...>.....>.>....v.v>>vvvvv.>..>.>...>...>..v...v>>..>>.>.....>.v.>.>v.....>.>v......v>vv..>>..vv..v..>.v...>
v..v.v.>vvv.>.>>>>vvv.>vv..v.vv>.>vv..>.v>>.>..v....v>.>.v..>..vv.v..>>>.>..v>>>..v>..>v.v>v....>>....v......>>..>>>...>.v.v...>>...>>.vv.>
...v>.>...v.>v..>.>>>..>v....vvv>vv.vvv..>v>v.>v..>vv>...vv.>...v.>>vv...vv>v>vv>vvv.>>vv>>>.v..v.>.>...>.v>v...v>.>>.......>>.>...v..v..vv
....vv.vv....>.v..v...v...v.v.v>v.v.vvvv>..v..vvvv>>>.v.v.>vv.>v.>>..>..>>.>..>....v>...>v>v.>vv.v>>v.>.>.>.v.>....v>>v...vv.>..>>v>...v..v
>>>.v>..v>v.v.>.v.v.....vv.vvvv>v.v..>vvv>.>vv......v...>v...>>.......v>v.v...vv.>>v>>v.>.>..>...v...>....>.v.>.....>..>vv>.v.>.>..v>vvvvv.
v>v..v..>>.>v......v.v>vv...vv.v>...vv>>.v>.vv>>v>v>......>v.v.v..>>..>.>>.>.>..v>..v..>.v>v...v>.v.v.v.>.>>vv..v.v.>....>.>>......>>>>v>..
>.vv>.v.>..v.vvvvv>v>>..vv>...>v>.v..v>.v>v.v>....v.v>>>.v...v...v>.v>>>v.>.>v.v.....v>>>v.>.>..v.v..>vv>v..>..v......v.>...v.>>v...>.v..v>
v.v>>>>>..>..v.>vv.v.>..>.>>...>v.>...v.v...>v.>..vv.>...v>.>.>vv.vv...>>>.>.....>...>.>.vv.>.>..>.v>.>..>...v.vv...v.v..vv>>.>.v..v.>v.>>.
.....vv>.....v.>.v......>.v.>v..>..vv.vv>>>>>..>v.....vv.v...v>v>.>.>v>...>v..>>....>>>>v..>.v>>..>...>>v>v.vvv....v>>v...>.v....v>.....>>.
.>>...vv>....>.v>...>v..vvvvvvv.>...>.v>vv.>>...>>v.>>..vv....v...>...v>.>>.....vv.>..>..v>v.v>.vv.vvv.>v>>>.vvvv.>...>.v....v.>...>v..vvv.
.......v>>v.v..vv>>v..v......vv.v....v.v>.>>.>...v>..v.v>......>v>..>>...>>..>.v.>>....vv.v.>.>>.>....>.v>v..v>..>..>...v.vvv.>.vvv.>v...>.
.v.v...>>v>..>.>>>.v.>.>v.v.>v.>>>.>.vv.v>v.>.>.>...v>>....>..v>.....v.>............v....vv.v...v>.v>>v..vv..v>.v....>.....v..v.v>.>>>...>.
vv..>>vvvv....v..v>v.>..v>v..v.....v>....>.>vvv...>>>v>vv.v>....v>vv.v>.v>.>vv..v>>.v..vv..>v..>.>.v..>..vv>>.>vv..........vv.>v..v.v>...v.
v>.......v>v.>v..>...>>..v.v.>v......v>v.>..v>...v..>>v.>.v..v....v..v>.>...vv>v>.>v..v>v.>..>..v.v.>>v.>..v>.>>vvv...v>>v>>.v.>v>v..>.>v.>
.>>....v.v...>.vv>..>....>...>>>..>vv>v>v..>>..>v.>..v..>>.>vv.......>..>>.>v.v>v.vv>.....vvv..v>.v>..v.vv>..>..vv.>>.v>.....v.v.>v>>v>>>v.
v>vv...vv.>v>..>.v..>.v...v.>v..>vv.>>...>>>>.v..>...vv>>vv.>.vv>..v>>v>>.>>v.v..>.>.v>...>.......>>.....vvv>.v.>..>>>.........v>.v.>v.....
...>>>vv.>>.>.vv>..v.>.v>...>>>..>.....v>>..>..>..v>..v>>v..v.>.v...>.>>.>>.>>v....>..>.>.vv....>....v.v...>>>.v...v.v.>>..>>.>.>.>v>v>>>>v
.v.....vv..>.>v>...v.v.>.v..vv.>vvv..>..>v.>vvv.>>.>.v>.v>v.v..>>..>>>.v>.vv..v.v>>v>v...>..>..>..>>..vvvv...>.vv.vvv>.>.>....v..>..>>.vvv>
>vv.>v>...v.>vvv..>v>v...v.vvv.>vv.>vv..>vv.v..v.v........>..vv>..v>v>...>.>...>v..>.v>vvv...>...>.>........>.>.v.>vvv>v>....vv>v...>..>..>
>..>>..>...v...vvv.>.>.v>vv>>v>>..v>>..vvv.>vv>>v..v.......v.>.v.>v>...>>.>>.>v.v>v.v>>.vv.>>.>>v>...v.v>...vv.vvv...vv..>.v>...v>.>..>>vv>
...>>>v>..v.v>.vvv.v.>...v..>......v.>.v..>>..>>.v.>v.>...v..v.>..vv>>vv...>vv.v..vv..vv>>v.>...v>.....v.>.>v>>.v.>v>.>...>.vvv....>.......
.>v>.>....>...>>vv..v..>...v.....>v..>...v.v.vvv>.vv..>.>>>vv>v....>....>v>v..........v.>.>.>.>..>v>.vvv..v>..>.vv>.v>.>>>v>.....>.v..>v...
.vv..v..>.>..v.>.>..v>..>>v>v...v.v.vv>.>v>.>v>>v..v.v...>.v..v>>v.v>>.>....v.>..v>>....v>>.>>....v....v..>...>.>>..v>>v........>v.v.v>>.>.
....>>....>.v>v.>...v..>.vv.v.v>v>>....vv.v..v.v>.>v..>..v...>.>>>...v.>vv>.vvv.>..vvvvvv.>>v.>v....v>..vv.v...>..vv>>..v.....>>>.v.....>>.
v.v..>...v..>v...v..>v..v.vv.>vvv...vv..vv.v...v.v>.>.v.v>.>>.v>.>.>>>.>>....v.........>.....>.v>.vvv...vvv>......>.....>v..>...>..>......>
v>...vv....vv.vv.>v..>>..>..>.>....v.vvv>.>v>vv>>.....>>...v>v.>>...vv>vvv.v.>>.v.......v..>vv>.>.....vvv.v.vv..v>>v.v.vv.v>...v.v..>v..>>v
.v.>v.v>.>.vv..>.>vvv..v>>vvv...>vv>v>v>>..v>>>>>.>.v.>........>..>.vv.vvv>>v.....v.>>vv>>vv...vvv>.>.....>.v..vv>.>v..v...vvv>.v>v..v>>.v>
..v.....v>v...vv..v...v.vv>.>>>vvvv......v>.....v>v>>...v..v..v>.>v>.>..>v....v>.>..>.>.>.v...>>v>.v>...v..>>.>v..vvvv>vvv>v.>.>vvv>>>v...>
v>vvvv>.v...>>.>>.>v>.>v.>v..>>>vv>>vv.>>>.>>.v.v..v...>.vv.>.>.>>...v>>.v.>v.>>....v>.....>v..v........>>>>..>....vv.>>.>..vvv...v.v.>>..v
....v.>>v>.v.v..>v..>...v....>>.....>.v>.v>v..v.>.>>v.>.v..v..v..vv>>.vv>...vv>..>vv.>vv.>>.v>.>.>..>>>...>.>.v.v.>>.v>>.>.v.v>.vv..v.>>>>>
..>>..>..>>..>v.v>.>..v...>..vvvv....v....v.>>vv....v.v>v>....>>..>>>v.v>.v>.....v..v.>>..>.v>v>.v..>vvvv..>v....v.....v>....>.>...v.vv...>
v.v>>v......vv.vv>>..>.v.v>..>>v...>v..vvvv>.v>v>v.v.vv..v...>..vv.v>.>vv...v...v..>..v..>v..vv...vvvvv>v..>v..v....v.>>.>v>v...>.........v
..v.v.>..v>vvv.>.>>.>>v.>.>>v..vvvv>>>v>.>..v...>>..>>..v.>.>>v>....>...>.v.>.>.>>vv.>>..>>>...vv.v.v.>..>.>.vv>.>v..>vv...>..>>.v..>vvv>..
.>.v...>..v>>>>.>...v>.v.>..>...>..>vv.vvv.v.v....v..>v>>...v.v.>vv>>>.>.>.>>.vv>>..>v.v.vv...v..vv>...........v>.v>.v.v.>...v..v.vv..vv>.v
v>v....v.....v>>..>..v.....>.v.>v>.v.vvvvv..>v.vv....>.v.>.v...v....>>..v......vv.>.vv>..vvv..v.>.v.>..>v.>..vv>..vv....>.......v>>>...vv>v
........v.>...v.>>>..v.v>vv>v.>..v>.vv..>>.v>.v>v>..v>......v.>...v.>>v>...v.vv..>>..vv.>v.>.v...vv.>.>.....v....v.v.v..v>v>..>>...v>>>v>>>
.v>.v.>..>v..>v.v>..>v>..v...vv>.v.>vv>.v..v.>...>>....>>vv...>v>.v>.....v.....v>....>.v..v..v..v....>v...>.>.....v.v...>>...vv.>v.v.v...v.
....>....>>....>.>>..>v..>......>.v>.>.>>>.v.....>>.>v..vvv.v.....>.v.>.>.>>v.>v.>vv...>>vvvv>.v>.v.>v.>.v>v...vv.......>>.>.>.>vvv.>..v.>.
..v..>..v>.>..v.>>..vvv>.>v>>.v>>>>>...>>>.>>....>v.v>v.>v.>>.v>.v.>>>v>.v>v.v>vvv.vv..>v..>>v>>.....>>>.>vv..>v..>v>....v>>v.vv>..>...v...
v.>..v...v....>vv..v...>.v>....v>v.v>.v.>>.vvv.v...>.vv.>v..>v.v>....>.v.v>.>>.>.vv..v>.v..>>v...v>>..v>>..>v.>....v>>vvv>>.>..v..>..v.....
v>.vv.>...v>v.>.v...>....v.>.v.v.>.v..>>.v>>.>>vv>vvv..>.vvv>v.>.>..>..v>.>..>>..>v>.vv.>...vv.v.>>.v.>..v>.v>......>v>v.>.vvv..>>.vvvvvv.>
>vv.vv..vv..>vv..vv.>>..vv.>v..>>>vv.vvv.v.>.vv.vv......>....>.vv.v>.v.vv>.>.>>>vvvv.>vv>>.v..>>..vv..v..>v.>v...vv>>>v.v>>v..v..>>.v..>v..
.>v..>.>.v.v>>>>.v.v..v..vv.>v>v..>.....>...vv....>.v..>>.>.....vvvv..vv.vv...v>v.v>....>v.......vvv>..v....vv.>.>>.v>..v..>..>..v>v....v.>
>>.v....>v........v>..>v...>vv>v>>...>.v.v.>>.v.>v>v..>.v.vv..>>..v>>.vv>v>v.>...>>v>v.v>>....>.>>v.>..v>.>>v...>...v>..v>>v..v>.>>.v.>..v>
.....>.>.>..>>>>.v...>>v>vv.>.v>.>..>v...>>.>v........>vvvv.>v..vvv.>>..>.v..v..>.vvv>>.v>>.>>.>>..>.....v.v..>>>.v.>v....>.v..v.>v.>>vvvv>
...>v>>>>>>v>.>>v.v>>vvv.v.>....>>.v....vvvv..>...>.....v..>>....v.v>..>v.>.v.>>...>v....>>>.>..>v..v.v.>..v.>>......v..v..>v.v..v.>.v..>..
.v.vvv...v..>.vvv.v..>>>.>v.v>.v>..v....v..>v..v.>.>>vv..v..v..v>.vv....>>>>..>.v>.v>v>v.v..v..>.>.>.v>>.v....>>vv>.>....>>.v.v.v.>.>.>>.vv
.>vvv.>.>>vv>>>v.>......>v..v>v....v...>>>>..>.>..>v.>>.v...>...v.>v..>.v>.>.vvvv..v.v.>>.v...v....>vvvv.v>vv.>>.vv>>.v.v>..>.vv.>...>v.v>v
vvvv>.v>.>vv....>vv>>.v.>>...>v>vv>...>v.>.v.>>..>v.v..v.>...>vv>...>...v..>>....>v>>v....v.v.>....v>v..>v>v..vv>vvvv.v.v>.>.v.>.>.vv>v..>v
..>..v>v>>.v.>...vvv.v>v.vvv.>>.vv.>.v.v>.>.v>...vv.>v.>.v>.>.v.....v.....>vv>...v..v.>>..>.vv.v..v...>>..>v...vv>>.vv.v>...vv..vv..v.>>vv.
>.>....v..>v>>>.>>.v>v>v..>v.>>v.vv...>...v>.vvv.>v.>.v>v.>.v>.....v..>...>v.>....vv>...v.>...v...>vv..>.>v.vvv>>>>.>....>vv..>.v.>...vv>.>
v.v>>.v>..>>.vv>.v>..>.v.v.>.....>>.>v>..>>...v..>..v..>>>..v.>..vv...v.>..v..v..vv..>>>v>..>...v>>>..vvv>>..v...>..v..vv>v...>.>.v..>v....
v.>>>.>v......v>vv...>vvv.v.>.v.v.....v>.>.v>>.>v.>v.>.>.>>>>vv...v..vv>.>....>...>....>>>..v.vv>v.v.>v..v...>vv>..>...v.>..>..v>..>.>..v.v
vv>.v..v>.v.>...v..vv.>v...>..>.>>..vvvvv>.>>>>.>.....vv..>>...>v...>..>v.>>..v>>.>.vv.>>.>vv>>.>v..vv..>>>.....>....v.......vvv>>v....vv.v
v......vv.vvv.v.vv..>>>.v.v>vv>vvvvvv..>.>..>v>>>....v.v..>.>.>.>...>>.>..>.>v....v.v.>...>.v........>v.>>..>v.>...v>vv>.....v>.v..v.....>.
>.>.>>>.>>v..>..v.....>v.vvv>v.>.....>.v..v...v...vv.v....v>..v>v...vv.v..v>.v>...v....>>....v>v.v>.>v>v..v...v.....v.v>>>..>...>..........
...v.vvv..>>>..v.v>>.......v>>>...>>>.v.v>.v...v.>v>v.v>>>v>>>.>..v...>.vv>>......v.>.>>..>v..vv>.>.v.vv.v>..v..>....v.v>v.....>>v.v.>>v>>v
v>v.v>>.v>>.v.v.v.>.v>vvv>>>.>>vv.v>...v>>>.>v>v..>v.v>>.>.....>>vv..v..>>v>.v....v.vvv...v>vv>...>>..v>v..>>>>v>>...>>v..v>.v.>vv>.v..>.v.
.>v..>...v...v.>....>>>.v...v>vv....v.>...v>.>>.>.......v>>..v>..v....>vv..v..............>.v..v>>.v..>v.v..>.>..>v>.>.vv>..v>.....>>>.v.v.
...>v.v.v.vvv>.>..>>.vvv..>v..v..>>v....v>.>>.v.v....>>.>>.>>.....v.......v>.....v...>v>v.>...v>...v>.v>.>>>...>..>>>v.vv.v>.....v.>.......
vvvv>vv.v.v.>..>vvv......>v.v>vv...vvv.....v>vv...v.vv..>vv.v.vv.>.v>v>..v>.vv.>v>>.v.v..vv.v..v..vv..>v.v.v.>>v.v..v.....>....v.>......>>.
...vv...>.>>......v..v>..v>.v.vv.v..>..vv...>..v.v>...>.>.........>v.>.>...v...v>.>v>.vvv.v>..vv>>.>...>vvv.....>....v.vv.>>>v......>....vv
vvv>>...>.>>vv...v>>>vv>v>>.vv.v>>.>.v....>v>.v>>.vv.>.>.v.v...>>>..v.v.v..>v.>..vv....>.vv>.>v.>>>.vvv.>..v>.vv.>...>......>>v...>vv....>.
.>...>.>v>>.......>..>v>v..>>..v.vv>>>....>>.v......v...>.v...>>>v....>.....>..vv>.v.v.>...>..v>vv>.>.v>v.v...>v..>.......>..v>....v>....v>
>>v..>.v.>.>...v.vv.v>>v>>.>.>.v>.....>..>>.vv>v>vv...v>.v>...v.v.....>.>...>.>.v.vv...>>>v.....>.v....v.>...vv>..v.>v.>.>........>...>...v
.......v>>..>......>v.>..vv...>.>.>vv>>v.>>v.>..>vv>..v.>...>vv.>>..>v>>>>vvv>.v.vv>.>....>v..>v..>vv.>v>.>...>....vv......vv...>vv...vv...
.>v>..>.....v>..>.....>>>...vvvv>..v.vv>.v.>vv>>v>v>.>>>v.vv...>>>>.>.vvv.>>.>..v>.v>v.v>>>>..vv.>.>.........>.vvv.>.v.......v.>......v>..>
.vvv.v.....v.......v>v.vvvv.v>.v>>v>>..>....v>.vv...>v>.v>>>>..v..>>....>.>.v>vvv.vv.vv.vv>.>...vv.v..>v.vv>>>>.v.vv>......v>v>....>...>>.v
...v...>v>vvv>..>>>.>>.>.>>v...vv.v>...v..>v...v.>>.v>>.>.v>.>...v.v.v>...v.>>.....v.v.v>v>v...>..v..>.v.>>v.v..>>.>>..v.vv.>...v>v.>..vvv.
.>.>......>.>..v..>...v.>v>.>......v.vvvv>.>>>.vv.>..>v..>..>..>>...vv>v.>>......vvvv>v...>>..>>>..>vv>..>.>.v...>vvv>>.>>..v>vv>>>vv.vv>>.
...>>>v.>v.v.>.vv.vvv>.v>>.vvv>....>v.v..v.>>v...>v>..vv..>.>>...>v>..vv.>.>v.vvv.v..vv.....vv..>vv>>>>>.vv>.>>>v..>v.v>...>.>>.>>v..vv.>>>
.>v...vv.....>v>.v>>.v....>.....v>.v>.>v>>.....v..v..>>>......>>>.....vv..v...vvv..vv>......>.....>>>...>..vvv....>v.>.>.>.v....v..>...>v>.
v>vvv...>...>>>..v..>....v.v....v>>v>v.>.>>>vv.>.v..>>>.vv....v>>>......v>v.v.>>.v....vv...v>>.v>.>..v..>v.>vv>..v.v.>.vvv..vvvvvv>.>v.>.v.
.vv.vv..vv....>v>.v>>...v.>v>.v>.>..v...>.>.vvv.>.v>..>v.>>v..v.....>vvv.vv.v..>..>v..>..>....v......>.v....>v.>.v>.>v.vvv.v.v..v>>>..>....
.>v>vvv>.>..v...>>.>>v.v..>>...>vv..>vvv.vvv.v.vv.vv..v.>>v.>>>....>>.v.>.....>.>....>>v>......>>..>v....v>...v.......>vv..>.v.v.v.v.v.vv..
>v..v....v>.>v>>...>v....vv>vvv>v..>vvv.v..>vv>.v>..>>vvvv>>.>...>>>>.>.v..>..v...>>..v>>>>.v.>vvv>>.v..v.v.vv.>>v>.>v...v>>...v.v.v....vv.
>.vv>...v.>.>.>.v.vvv>v.>>.>vvv>>.>v>v.v.>>>.>>>v.vv...>..>.>>..>vv...>..v.v.>......>.....vv>v.....vv.>v.>>>vv..v.....v>.v......v>.....v>>v
v..v>>.vv>>>.>>.v..>.vv>.....v>.....vv.>..>v.vv>.>>>.>.>v.v>>.v.>v....>v.vv.......>.>..v>>>....v...>..>>..>..v..>....>>..>..vv.v.>.v.>>>.v>
.>>>>>.>...>>...vv.v>...>>>..>v.vv....>.vv>.>>>>v..vvv.......v...vv...>.v.>....v..v>v>..v.>...>vvvvvv>v...v>.>..>vv..v>v>>..>.>v.v.>>..v...
>vvv>...>v...v>..v..>.>>..vvv.>.v.>>>...>.vv...>v......>>>>vvv>>.>.........>vv.vv..>vv.>>>..>>v>.>.v..v..v.>.>.>.vv.>..>>..v>>.v.>...>...v.
.v..v.>.>>...>>v.v.>.>.>>...>......vv>v..>.v>vvv.vv...>...v.v>>v..v....v.vv>vv>.>>...v.>v>v>.>.v..>v.....>....v.v>.vv.>.v.>v>>.>>....vv.v..
>...v.v.>..v..v>.>.vvv>....>.vv..>v>..>v.>..>>>.>v>>v...v.vv>>v.>v.vv...>v.>vvv..v.>>>.>.v>.>..>>..>..>.>.v....v>..>>.v>v.>...v>>v>...v.>.>
>..v>....>.v>.>vvv.>...>.v....>....>>v..v.v.>.vv>..>.vv>>.v>vv.v>.>v>.>v>>vv.>...vv..>v.>..>..>.....v.v>.>..vvvv.>.vv.vv>.>>..>.vvv..vv.v.v
.>v>v...>..vv..>vv>>..>v...v>>v.>>v..>v>vv...vv..>...vvvvv.....>.>>.>v..>>.>...>.>.v..>.>...>v.....vvv>.>>..>v>>>>.v.>.vvv>.>.>>v>v..v>v..v
..v.vv.v>...v..>.>vv....v.>>.vvv..v.v.v.v.>.v...v>>.>.>>.....>........>vv.>..>>v.>.vv>.v>.vv.....>....>v.v>>.......>.vv..v..v..>.>v..>..v>>
.v>v.>>>v>v....>>vv>....v.>..v>v.v.v>>>v..vv.v>...v>.....v.>..v.>vvvv>v.v.>>v>>vvvv>>>.>.v.>.>...>..v>>...v....>.v..v..v.vvv>.v.>v..v..>>>>
...>v>....>......>>.>..>.>>>.v>.vv.......>..>>>v...>.>.>v>>.>..>v>.>>>>.>...>.>>v>.v.>.vv.v.vv.>.vv....v.vv.v.......>.>>..v.v.vv.>v.vvv>>>.
>.>v.>...>.v>>.>.>........>.v.v.v.>>.....>v.>..v.>.v>>.....>v..vv......v..v.v>vv.v.........v>...>vv..>>>..>v.v.....>vv>....>vv.vv.>v.v..>.>
....>v>>...v.v.v>...>>>v..vv..>.v.v...v>.....>>>..>..>..>.>.>v>v.v.vvv>.......vv.>.>v.v..>>...>..>.v>v.v..v>vvv.....vv..>...>>vv>>>v....>.v
.>v.>v...v..v...>..vvvv.>>....>...>..v..>..>..vvv..v...vv.>..>v.>.....v.v.....v>..>.v.vv..>...vvvv.v...>>>v>.>v>vv>v...>..>>.>>vv..v.vvv.>.
.v>.>v.vv.>.v.v..v.v>v..v>v..>.v...........>.>....>>>...>>>..vvv.>.>.>.>>...v.v>..v>.>>v>.>vvv.>>.>..v..>>>v......>.>.>.v...v>v..v.v>v..>v.
>vv>>v..v..>>v..vv..>.>..>>>.>>vv.v..>v.v.>vvvv>v....>.>.v...v>..v.v....>.>.>vv....>v>v.v.v..v>>>.>>......v..>v>v.v.>>.v>......v..>.vvv>vv.
>>v.>.v>>.>.>.vvv..>v..>.....v.>....vvvv.v>>>.>v>>>v.v...>v.v>..>v..>v..v.vv.>...>v>..v>..v..>>.....>.>.>>.v.v.v>v>.v.vv.v.....v...>v..>>v.
.v.>.....>...>..v.>>.vvv..>v>..>>..>>..>.v......v>>..>v.>vv.....v...v.>>.v....v>.v>.v...vv.v>v.v.vv>vv>vvvv.v.>>.....v>v>...>.v>..>.v.vv>..
.vv.v>>>.vv>.>>.v.v.....>>.....vv.v.>>..v>..v...>...v..v.v.v>..>.v>>...v.v>...v.v>>v.>.v>.>v>>>v.v.>v>v..vv>....>vv.>.v>vvvvv.>v..>v>>...>v
v......v.....>..v>..v>>v..>v.>..>>.v.....v...v.v..>.v.>v>>>>...v>vv....v>.v.v>.vvv...v>>..v>.vv>vv>v.>>...v...>v>>>v>v.>...>.v>v..vv.vv.>..
..>vv.>.....v..v.v>..>..>..>..>v>.>>.>v.v>..>.v.....>v..>v.v..>...v...v>>...>>v..>vv>v......>..v>..>v.>..v.vv.v.v.>>....v..vvvv.>v>>...>>.v
vvv.>v>>v>>>vv>..v.v.>.vv>v.>>v.v...>vvv......>..vv..>v.>>>v....>.>.>>.>.vvvvv.....v>vv.v.vvv>..>vvv..>>>.>......>>v.v.>..>...>.>v.v.....>.
>>.>>...>v..vv.>.vv.v>..v..vv......v>.v>.v>>>>..>v.v..vv.>>>..>.v>.vv>...v.>>v..v>.vv...vv>>.>>.v.>v.>..v..vvvvv..>>v...>v>>vv.vv..v>.>..>.
>vv>>..v>.v>v..>v>>.....>...>..v....vv......>..v...>>v.v>>....>.v.>..vv.v..v>.>....v>>.......vv>..>>>......v.vv...v>>>.>.v>.v>.>..vv..v...v
vv>v...vv.v....>>v.vv.v...vv.>v>.>>>v>.v>v>v......v>.>>..vv.>v>...v.>.v>..>....>.>..>.>.v>....>>..>v.v.....v.vv.>..>.>v.>..v>v>...vv...vv..
.vvvv>..v...v>..>v.v.>>.vv>..v..vv.v>v..v>v...v...v.v>>..v.v....>>>>>vv>>.vvv.....v>v>v>vv.>.v>v>..>>.v.>>.>...>v..>.v..>>.vvv..v.>v.......
v>>vv>.v.v>.vv...>vv...>..v>..vv.>.....v.>>....>..v>..>..vv.>>.>v.vv>>.>..>>vv..>v..>....>>..v.>...v..v.>v>vv.v.......v>>.>>>v.....>>v...vv
vv......v>v>.vvv.>..>v...>...vv...v..>.>..>v>.v...vv.v>..v>v>vv..>v>>vv>..v....v..>v>>>.>.v>.>>v..v...v..v>.>v.>.>>v>....>.>.>.v>.>vv....v>
.>.>>v.>v>..v>v>.>.>..>>v..>...v...>.v>..>>..vv.v.>....v...>>v>>v..>..vv..vv.>.>..v...v>..v.v.>..v.>.vv.>>..vvv.>.>.>>..v.>...>v>.v>>.>.v>v

49
2021/25.py Normal file
View File

@@ -0,0 +1,49 @@
#!/usr/bin/python3
import sys
import heapq
import itertools
import re
import ast
from collections import defaultdict, Counter, deque
from copy import deepcopy
#submit(len(G), part="a", day=25, year=2021)
infile = sys.argv[1] if len(sys.argv)>1 else './2021/25.input'
data = open(infile).read().strip()
G = []
for line in data.split('\n'):
assert line.strip() == line
G.append(line)
R = len(G)
C = len(G[0])
t = 0
while True:
t += 1
moved = False
G2 = [[G[r][c] for c in range(C)] for r in range(R)]
for r in range(R):
for c in range(C):
if G[r][c] == '>':
if G[r][(c+1)%C] == '.':
moved = True
G2[r][(c+1)%C] = '>'
G2[r][c] = '.'
G3 = [[G2[r][c] for c in range(C)] for r in range(R)]
for r in range(R):
for c in range(C):
if G2[r][c] == 'v' and G2[(r+1)%R][c] == '.':
moved = True
G3[(r+1)%R][c] = 'v'
G3[r][c] = '.'
if not moved:
print(t)
sys.exit(0)
G = G3
#print(t, moved)
#for r in range(R):
# row = ''
# for c in range(C):
# row += G[r][c]
# print(row)

9
2021/25.test Normal file
View File

@@ -0,0 +1,9 @@
v...>>.vv>
.vv>>.vv..
>>.>v>...v
>>v>>.>.v.
v>v.vv.v..
>.>>..v...
.vv..>.>v.
v.v..>>v.v
....v..v.>