Update advent of code
This commit is contained in:
83
2021/22-1.py
Normal file
83
2021/22-1.py
Normal 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
420
2021/22.input
Normal 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
74
2021/22.py
Normal 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
4
2021/22.test
Normal 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
7
2021/23.input
Normal 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
963
2021/23.py
Normal 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
164
2021/23.rs
Normal 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
23
2021/23.test
Normal 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
252
2021/24.input
Normal 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
99
2021/24.py
Normal 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
0
2021/24.test
Normal file
137
2021/25.input
Normal file
137
2021/25.input
Normal 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
49
2021/25.py
Normal 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
9
2021/25.test
Normal 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.>
|
||||
Reference in New Issue
Block a user