diff --git a/inputs/14/real.txt b/inputs/14/real.txt new file mode 100644 index 0000000..7adbeba --- /dev/null +++ b/inputs/14/real.txt @@ -0,0 +1,500 @@ +p=80,58 v=-80,-45 +p=80,4 v=-4,-91 +p=40,2 v=29,39 +p=38,45 v=3,-25 +p=95,68 v=82,33 +p=75,37 v=44,-31 +p=53,27 v=-20,-99 +p=47,11 v=-75,93 +p=11,14 v=-37,-22 +p=3,43 v=76,60 +p=21,50 v=-3,-23 +p=41,6 v=23,81 +p=83,62 v=34,54 +p=78,63 v=74,45 +p=71,63 v=-58,-56 +p=86,19 v=16,20 +p=40,46 v=72,79 +p=96,15 v=59,11 +p=63,69 v=57,25 +p=96,28 v=-7,29 +p=36,63 v=17,32 +p=1,40 v=-50,68 +p=50,5 v=31,-74 +p=70,61 v=87,31 +p=43,71 v=75,-69 +p=20,73 v=-93,-42 +p=69,13 v=-79,81 +p=68,90 v=19,-32 +p=39,32 v=-52,-7 +p=74,82 v=-27,24 +p=36,1 v=8,61 +p=12,6 v=-25,-77 +p=92,96 v=-16,-12 +p=49,59 v=50,-47 +p=14,80 v=-25,-19 +p=79,25 v=-79,88 +p=67,61 v=13,-96 +p=37,55 v=-47,-21 +p=40,95 v=-6,32 +p=92,88 v=-90,-22 +p=35,79 v=52,-62 +p=27,40 v=-22,-8 +p=22,73 v=61,-27 +p=44,84 v=-26,31 +p=64,9 v=-47,38 +p=82,87 v=-7,-45 +p=36,40 v=-43,87 +p=100,17 v=-68,-48 +p=91,93 v=-53,-82 +p=27,66 v=-66,67 +p=65,66 v=-78,-18 +p=65,75 v=34,67 +p=96,71 v=88,84 +p=73,75 v=-50,24 +p=90,100 v=68,39 +p=48,22 v=83,-33 +p=79,80 v=-49,45 +p=5,53 v=-9,-94 +p=53,101 v=11,22 +p=63,18 v=-18,2 +p=31,98 v=-98,56 +p=16,42 v=-83,-68 +p=23,101 v=-69,99 +p=72,102 v=-4,-21 +p=27,87 v=-45,-10 +p=22,49 v=21,-87 +p=3,2 v=-11,-98 +p=84,76 v=22,50 +p=48,43 v=83,10 +p=59,37 v=-18,40 +p=23,24 v=-66,-49 +p=4,88 v=-86,99 +p=77,57 v=90,10 +p=37,20 v=-49,-23 +p=11,56 v=6,16 +p=49,14 v=-32,12 +p=55,86 v=2,58 +p=37,79 v=-20,75 +p=63,25 v=65,-79 +p=81,92 v=96,-7 +p=66,58 v=-66,37 +p=11,17 v=-22,-47 +p=63,7 v=37,21 +p=57,17 v=-78,-5 +p=84,7 v=74,-98 +p=77,51 v=-12,15 +p=90,95 v=22,-5 +p=8,72 v=12,-70 +p=35,81 v=3,23 +p=66,96 v=80,56 +p=29,87 v=-52,67 +p=18,6 v=41,-55 +p=25,0 v=10,84 +p=93,49 v=-91,-69 +p=12,19 v=9,-82 +p=100,21 v=4,79 +p=47,24 v=-93,98 +p=89,52 v=-50,-56 +p=20,54 v=18,-59 +p=78,86 v=74,-30 +p=61,80 v=40,15 +p=79,35 v=-36,2 +p=95,13 v=-56,2 +p=57,11 v=-78,90 +p=55,47 v=14,93 +p=79,16 v=-53,-83 +p=4,46 v=27,60 +p=49,50 v=-6,-95 +p=26,84 v=-41,-36 +p=55,98 v=34,91 +p=51,72 v=-23,94 +p=19,53 v=-40,-99 +p=69,102 v=83,3 +p=68,27 v=-35,-64 +p=30,64 v=53,-60 +p=95,47 v=-16,-1 +p=22,7 v=-92,21 +p=3,78 v=1,41 +p=34,97 v=-49,13 +p=100,27 v=44,-16 +p=76,53 v=37,-33 +p=81,17 v=-10,37 +p=21,36 v=9,19 +p=3,57 v=79,-44 +p=78,11 v=19,21 +p=29,42 v=-23,70 +p=85,61 v=-33,34 +p=80,45 v=48,1 +p=28,55 v=9,86 +p=30,62 v=13,-30 +p=83,71 v=74,48 +p=78,17 v=-79,97 +p=41,91 v=28,11 +p=66,73 v=-67,-27 +p=89,24 v=58,-34 +p=84,102 v=76,70 +p=43,98 v=-61,72 +p=26,57 v=57,96 +p=34,85 v=35,15 +p=52,41 v=9,-76 +p=4,15 v=59,36 +p=82,21 v=42,-41 +p=33,42 v=-66,-16 +p=55,11 v=-90,4 +p=5,87 v=76,31 +p=43,0 v=6,-40 +p=30,18 v=-95,3 +p=47,75 v=-20,-20 +p=19,85 v=12,40 +p=94,60 v=-91,42 +p=68,6 v=-30,-92 +p=26,77 v=58,83 +p=75,85 v=10,-83 +p=65,48 v=-67,-60 +p=39,94 v=-88,72 +p=36,79 v=-98,75 +p=36,96 v=-3,-72 +p=23,86 v=99,99 +p=93,22 v=-91,-23 +p=12,17 v=-28,20 +p=0,80 v=1,92 +p=84,39 v=94,71 +p=41,55 v=35,-8 +p=83,46 v=-79,37 +p=6,1 v=18,-81 +p=34,22 v=87,-57 +p=95,3 v=-16,24 +p=36,66 v=-17,-60 +p=68,22 v=-70,86 +p=26,55 v=21,35 +p=70,59 v=-70,68 +p=95,66 v=6,-43 +p=38,64 v=-26,24 +p=92,12 v=-21,40 +p=26,23 v=35,62 +p=12,87 v=40,48 +p=76,98 v=-15,2 +p=37,14 v=-78,-65 +p=20,67 v=-21,35 +p=76,81 v=-53,6 +p=40,79 v=-12,83 +p=90,2 v=65,39 +p=99,93 v=-59,81 +p=7,92 v=-5,14 +p=97,56 v=-80,34 +p=68,69 v=-47,-10 +p=48,8 v=-9,72 +p=65,71 v=-33,89 +p=85,32 v=2,45 +p=32,101 v=-19,-26 +p=46,26 v=-50,-54 +p=10,46 v=-87,-86 +p=15,54 v=49,57 +p=20,15 v=41,-31 +p=78,65 v=-56,59 +p=32,38 v=-39,95 +p=41,55 v=29,86 +p=100,98 v=82,72 +p=15,16 v=-34,30 +p=17,1 v=38,64 +p=45,29 v=20,-72 +p=42,65 v=-90,82 +p=23,30 v=-14,36 +p=14,64 v=-31,-26 +p=53,7 v=-26,-98 +p=94,62 v=55,53 +p=26,66 v=9,24 +p=80,11 v=-75,48 +p=32,56 v=9,43 +p=26,69 v=-80,77 +p=68,39 v=25,-50 +p=24,85 v=13,-92 +p=75,26 v=48,-93 +p=42,26 v=69,28 +p=62,98 v=11,-64 +p=76,62 v=-39,94 +p=56,30 v=-58,-92 +p=91,58 v=33,51 +p=38,2 v=-49,39 +p=92,91 v=-39,-47 +p=97,46 v=33,-16 +p=39,37 v=-87,-86 +p=71,86 v=-47,-55 +p=4,17 v=53,97 +p=39,73 v=17,-52 +p=41,72 v=49,33 +p=75,44 v=71,61 +p=54,43 v=-58,-33 +p=75,18 v=-53,-14 +p=32,76 v=-2,76 +p=18,30 v=-86,96 +p=41,62 v=-72,9 +p=73,74 v=-90,-19 +p=1,35 v=56,-59 +p=51,62 v=-96,-35 +p=42,30 v=-26,19 +p=89,9 v=22,-81 +p=99,25 v=56,2 +p=95,79 v=10,-54 +p=17,100 v=90,64 +p=97,18 v=81,29 +p=31,78 v=-8,-45 +p=27,31 v=73,4 +p=1,31 v=93,52 +p=89,2 v=-83,23 +p=91,27 v=34,94 +p=49,86 v=49,92 +p=13,1 v=-5,-27 +p=96,38 v=27,77 +p=34,72 v=-58,-2 +p=31,83 v=-69,-2 +p=85,49 v=-44,59 +p=32,24 v=52,-40 +p=8,86 v=-88,-15 +p=58,43 v=-60,-98 +p=24,26 v=-63,-49 +p=64,78 v=43,6 +p=87,40 v=-30,-9 +p=39,57 v=14,-27 +p=61,66 v=-24,5 +p=92,71 v=-88,-71 +p=100,74 v=-97,-1 +p=79,88 v=-58,6 +p=41,22 v=-26,-58 +p=35,88 v=72,24 +p=48,90 v=-84,-12 +p=0,62 v=1,50 +p=76,50 v=-24,69 +p=93,60 v=-13,-9 +p=85,2 v=-13,13 +p=16,47 v=21,-51 +p=10,32 v=99,-15 +p=94,95 v=-30,82 +p=25,1 v=-26,-12 +p=62,73 v=17,-34 +p=36,39 v=-75,53 +p=60,54 v=46,77 +p=63,48 v=-77,-30 +p=64,62 v=-21,75 +p=63,99 v=-4,-90 +p=75,99 v=-75,25 +p=27,62 v=9,75 +p=44,102 v=47,75 +p=57,21 v=40,28 +p=87,57 v=14,83 +p=30,77 v=9,72 +p=60,24 v=3,56 +p=93,71 v=25,-71 +p=41,7 v=3,-30 +p=26,55 v=49,-86 +p=49,20 v=-81,29 +p=8,59 v=-5,8 +p=97,56 v=98,8 +p=53,102 v=-61,12 +p=6,96 v=-2,-48 +p=71,11 v=14,70 +p=25,10 v=-17,72 +p=43,78 v=-81,-19 +p=70,61 v=-54,-45 +p=55,99 v=-90,-21 +p=55,6 v=-80,53 +p=22,36 v=84,70 +p=84,57 v=28,86 +p=89,2 v=68,-90 +p=6,72 v=-91,57 +p=86,100 v=-13,65 +p=97,31 v=-7,-16 +p=55,58 v=40,42 +p=65,59 v=-21,59 +p=33,79 v=81,32 +p=11,84 v=-60,58 +p=60,85 v=-27,-54 +p=36,8 v=-49,3 +p=94,85 v=-71,-88 +p=27,96 v=-46,-48 +p=67,50 v=83,-26 +p=99,53 v=96,-16 +p=50,7 v=-32,-39 +p=77,42 v=-13,8 +p=97,99 v=-7,40 +p=81,20 v=68,20 +p=55,23 v=83,-83 +p=48,4 v=-84,-65 +p=10,1 v=61,-56 +p=40,23 v=-59,-55 +p=38,44 v=-96,-6 +p=97,18 v=82,54 +p=68,72 v=43,-61 +p=61,31 v=-61,28 +p=83,68 v=-59,84 +p=46,77 v=-78,-79 +p=72,102 v=-47,-4 +p=72,61 v=-27,51 +p=66,102 v=19,64 +p=90,101 v=-27,39 +p=44,73 v=-29,76 +p=60,82 v=89,83 +p=39,23 v=-87,2 +p=4,87 v=-34,67 +p=68,93 v=-33,-63 +p=31,56 v=-88,-67 +p=99,12 v=-66,52 +p=11,58 v=50,-78 +p=98,90 v=7,41 +p=79,90 v=93,80 +p=62,3 v=-18,-4 +p=67,10 v=-56,-28 +p=14,8 v=51,-76 +p=48,51 v=46,-9 +p=90,75 v=-40,-78 +p=41,33 v=-55,-24 +p=73,48 v=-50,56 +p=57,26 v=66,11 +p=51,80 v=5,50 +p=80,99 v=65,-74 +p=48,60 v=-49,95 +p=13,49 v=-15,16 +p=52,75 v=-36,-44 +p=7,73 v=-22,7 +p=63,22 v=-70,-6 +p=97,99 v=-91,56 +p=22,5 v=-89,-99 +p=83,36 v=-4,60 +p=16,30 v=79,44 +p=34,70 v=48,56 +p=38,10 v=-31,-68 +p=26,17 v=3,12 +p=19,78 v=67,-3 +p=99,53 v=17,8 +p=88,66 v=91,-95 +p=34,99 v=-72,-89 +p=30,19 v=52,63 +p=23,31 v=97,-51 +p=63,36 v=-67,-93 +p=15,70 v=50,-63 +p=25,19 v=-16,23 +p=44,74 v=46,-27 +p=21,51 v=12,-68 +p=39,41 v=56,80 +p=98,83 v=-79,-96 +p=75,13 v=-50,72 +p=33,64 v=41,58 +p=38,25 v=23,62 +p=39,97 v=-46,22 +p=59,33 v=-1,-23 +p=43,96 v=11,98 +p=2,2 v=-48,-74 +p=72,33 v=-82,86 +p=77,60 v=-56,-61 +p=6,73 v=2,-62 +p=42,88 v=48,-6 +p=68,82 v=77,76 +p=86,60 v=-24,85 +p=43,2 v=67,35 +p=79,5 v=71,99 +p=53,7 v=89,-73 +p=26,71 v=13,-6 +p=1,45 v=14,67 +p=40,71 v=-85,-91 +p=1,85 v=65,57 +p=26,87 v=81,23 +p=58,58 v=11,8 +p=73,96 v=6,84 +p=43,86 v=92,-37 +p=7,27 v=-91,-6 +p=30,45 v=-66,19 +p=81,13 v=21,-2 +p=16,16 v=55,-59 +p=22,59 v=38,94 +p=60,71 v=-15,25 +p=98,16 v=-33,72 +p=29,68 v=52,-43 +p=53,31 v=98,-20 +p=34,46 v=84,79 +p=35,8 v=58,4 +p=95,83 v=36,-88 +p=18,99 v=44,18 +p=75,83 v=-73,61 +p=97,65 v=79,-54 +p=56,76 v=66,91 +p=59,32 v=79,-53 +p=0,54 v=-22,26 +p=14,23 v=-80,2 +p=97,33 v=7,18 +p=6,18 v=24,47 +p=95,40 v=-65,1 +p=92,8 v=-65,30 +p=93,72 v=10,-71 +p=77,51 v=65,70 +p=57,39 v=-6,71 +p=88,73 v=-76,-35 +p=26,23 v=-14,28 +p=39,26 v=41,-23 +p=36,10 v=49,-91 +p=74,4 v=-34,-74 +p=88,83 v=25,-29 +p=89,1 v=10,-82 +p=73,38 v=84,26 +p=37,42 v=26,60 +p=4,61 v=7,78 +p=54,101 v=17,99 +p=16,3 v=74,27 +p=96,51 v=-48,-51 +p=55,94 v=-26,-73 +p=80,4 v=-29,-31 +p=89,57 v=4,-19 +p=46,67 v=17,-35 +p=92,16 v=85,-6 +p=61,36 v=11,-59 +p=80,97 v=62,-74 +p=5,72 v=-28,-87 +p=57,47 v=11,9 +p=99,73 v=-34,63 +p=66,84 v=-24,93 +p=90,78 v=13,57 +p=23,12 v=-86,-82 +p=33,91 v=32,40 +p=83,75 v=19,-11 +p=76,39 v=-17,64 +p=49,18 v=69,89 +p=90,50 v=25,4 +p=41,17 v=-23,-74 +p=16,16 v=-86,54 +p=55,48 v=34,-60 +p=37,55 v=49,67 +p=11,33 v=70,-93 +p=82,36 v=-21,-34 +p=76,29 v=23,-94 +p=90,61 v=92,89 +p=88,0 v=2,-67 +p=20,52 v=21,95 +p=49,41 v=-78,51 +p=82,72 v=-33,57 +p=99,3 v=34,50 +p=17,101 v=12,-20 +p=12,72 v=85,32 +p=91,51 v=-94,69 +p=23,43 v=-82,-13 +p=64,34 v=-94,1 +p=87,11 v=-52,-97 +p=11,2 v=2,-59 +p=12,49 v=9,27 +p=84,28 v=-36,-41 +p=64,62 v=43,8 +p=27,98 v=12,-21 +p=37,35 v=-86,23 +p=53,31 v=-12,-16 +p=100,2 v=27,99 +p=17,24 v=-36,36 +p=94,81 v=-30,40 +p=76,0 v=62,65 +p=72,48 v=-24,94 +p=19,25 v=9,34 +p=41,74 v=-52,-10 +p=87,71 v=-22,67 +p=61,44 v=60,63 +p=47,61 v=-93,-19 +p=0,82 v=-42,-45 +p=83,43 v=-90,28 +p=40,26 v=89,-93 \ No newline at end of file diff --git a/inputs/14/test.txt b/inputs/14/test.txt new file mode 100644 index 0000000..72a324a --- /dev/null +++ b/inputs/14/test.txt @@ -0,0 +1,12 @@ +p=0,4 v=3,-3 +p=6,3 v=-1,-3 +p=10,3 v=-1,2 +p=2,0 v=2,-1 +p=0,0 v=1,3 +p=3,0 v=-2,-2 +p=7,6 v=-1,-3 +p=3,0 v=-1,-2 +p=9,3 v=2,3 +p=7,3 v=-1,2 +p=2,4 v=2,-3 +p=9,5 v=-3,-3 \ No newline at end of file diff --git a/inputs/15/real.txt b/inputs/15/real.txt new file mode 100644 index 0000000..1cdc009 --- /dev/null +++ b/inputs/15/real.txt @@ -0,0 +1,71 @@ +################################################## +#.#...........O.O....#..O.#O.O#.O....OOO.O...O...# +#.#O......O...O..#...........#...#.....#...##....# +#O.OO..O.OO.O..OO.....O...#...O...#O.O.#..O...##.# +#...OOO..#..OO.....O.O.#OO#.OO#....O.......#..OO## +#.O......OO.O.O...OOO.O#......##..O.O..O......O### +##.......#.O.OO..O.....O....#..........O..O.O...O# +#.....OO..##.O.#...#....#......OO.....O.O...O....# +#OO.OOO...#..#O.....O#O...O.#...........O..#..##O# +#OO##......O.O.#OO.O.OO..#O.O.O.O.O.O.....O.OOO.O# +#O.....#OOO...O.O...#.#O....#......OOO...O.OO....# +#O.O...O.........#..##..O..#.O...O...O..O.OO..#.O# +#.......O..O#....OO.O.O#...O..O.#O..O.O#.....OO..# +#OO.O#O...O#..#...#O.#....O#O..#.O..O#...O..##..O# +#O......O.#..O.......O.O.OO..O#.......O..O#..#..O# +#....O...OO...O.O..##....O.#..O.O..O..O....OOOO..# +#.....O.O.O..O.O.O.O.O.OO....O..OO..O.O...O.O#..O# +#O......OO.O......#O.O.OO#......O....OO..O...O..O# +#O......OO..O....O...O.....OOO.O....OO.O..O#...OO# +#..OOOOOO.O..OO..O...O.....#......OO.#.O...#O.O.O# +#...O..#O..O.OO.......O...##OO.#.........#O.#...O# +#...OO.#O..OO....##....#...OO..#...O.O..O...O..OO# +##...O.#..#O.#OO......O..OO.O#..O.....O.#..O.OOOO# +##.....#......O.OO#O.O..O....O..O.OOO.O..O...O.#O# +#........O.O..OO..O.....@....#..O...OOOO#.O......# +#O....O....O...OO.OOO...O.OO.....OO#..O......O.O.# +#...O..O...O.OOOO.....#...O.O....O##O.....O.#...O# +#...O.....O...#.......O.OO..O..#.#OO.OO........#.# +##.O........#.......#O#.............O...O#..#.O#.# +#O.....O.OOOO.....O.O...OO.O...O.O...OO..O...O.O.# +#...........O...OOOOOO....O.O.#.OO...O.O..OO.....# +#..O##.......OO.OO.##..#..O...#.O..O#O...O.O#..O.# +#...OO...OO.O.......#.....OOO.O..O..O.....O...O..# +#..OO.......OO.....#......OO.O..O..#....OO....O..# +#...OO..OO...O.OO.O#.O...#.O..........OOO...OO..## +#..#O..O#....O....#....O.#...OO.O.#...#.........O# +#O.......O..OO...O.O.O...OO#O.#..O.#O..#..O.#O..O# +#..O..O...#OO...O..O.#OO.O.O...O.......##..O#..#.# +#.O..#....O..O.O..O..O.O..#....O..#...O.OO#.O....# +##OOO.O.O.................O.O..##OO.O.O.O.OO.O.O.# +#..O..................OO...O....OOO#...O....O.#..# +#..#.O#..#...OO....#....OO......#......O..OO..O.O# +#.O..OO...OO.#.OO..OOOOO#.O.OO...O.O.#...O..#.OO.# +#...O..#O#...#..............OO.#.#.....OO.......O# +#.O#.....O#..OO.#..O......#..#O.O#.O.OO........O.# +#OO.O#...O#.O......OO......O...........##.O..#...# +#..O#...O.#...O.O...O...OO.O#OOO..OO#..O..OOOO.O.# +#...O.O#..OO........O#.OO.....#O.O.O#......#O.O#.# +#........O....O....O#..#.....O..O..OO#.OOO....O..# +################################################## + +^v<<><><<^><><>vv><^^v><>v><^^^vvv^^><<^v^>^^<>>v>v<^<^^>v^v>^vv^v><>>vv>^^><>^>v<^^><>^^^^<<v>^>v>v^v>^<>^v^vv^<^^<<<<<^v<>>v^vv^^>^^^^><<<^^^v<^^v>^^vv<>><<>v>v<^^v>v^^<^>^^<<>^>^<<<^vv^>>v<><>^^><^>>^^^vv^v<>v^v<^v^vv<^<^<<>v<^<<><^<>><^<>^v^><<^<<^>><>>><^vv<>vv<^>v><>vvvvv<><>>v>>^vvv^v<><<^><>^<<>>vv<<>>>>v<<>v<>vv>^v>>^v^<^<<>v<>^>^^>^vv>v^^>^vvv<^^vv^^^>vv<^^>vv<^^<<>v^vvv^<^><^<>^>^^^<<>^vv<<><>^^<><^vv>^^^>^<<^^<><<<^^v><>^<^v>>^>^^v<>^v^<^v^^v>>v<^>>>>>vv^v>^>>v^><^v>^v<^^<><^v>>^>>>^v^^<<^^^>v>v^^v^>>^^<^vv<^>vv^<^>v<>v<<<<^v^^<>^^>^>vv<>^v>^v<<>^><^v<<>>^vv<>v>>^>>^>v>^>^v>v^>^><<><^<<^<>^v>v<^>v^v^>v^><>>><^<>>v<>vv><^v<^>v>^^>^>v^><^><^<^vvvvv^v^v^^<<^vv>^vv^<^v><v>v><<^v^^^<>^>^<^vvv^>vv^<>>>^^v^>v>vv<>>>>>v>^<>v><^<<^^>>v>^^vv^vv^>>^^>><<>^<>^<<<><^<<^>vvv^>v^<>>^<>v<<>>^>>^^>vv^vvvvvv<<<^>^<^^vv>^>>^>v<^>^>^v<^^^<>><<<>vv>>v>>>>v^^>^vvvv>^>><>vv^>v^v<<><>>><><><>><^^^<<>>^^^>^^<>>v^<><<^vv><>v<^vv>>>^<v><^^vv>^><>>v<^^^^<^>^^v^<^v<^><^^<>^<^^^vv>>>>>vv^^^v^>^^<^^^>^v>><>vvv>^v>^^v<<>vv>^^>>vv>>^>>vv^^>^^vv<>^>vv^^>^v^>>>v<^>^v^vv>><>>^<^vvv^^>^>^^><>v><>^v^><>v>vv<^v>^vv^v><>v^^^^^>>^v>vvvvv^>>vv^v^v^^^>^v^^^>v>v>v>v<^<<<<^>^v<^>^^^^>>v^><>>>^>>^vv><^>v^^^<>^>>v><<>>^^<<<^v<<>^<^>>>><>v^vv<<<>>>^><v^^v^>^^>>v^vvv>>>v^^vv>v<^<><>^v<<<>v^><<><<>>>^v^v^^>^vvv>^<>^v><>vvv^v<<<^^<^v>v<<>vv^vvvvv>vvv>><^^^v^v^><^v<^<>^>^v^<^>^>^vv>vv<<><<>^<><><<>v>^><^^v<>><>v^>v<^^^^>^vv>^^v>>vvv>v<^v>>><>^<<<v<<^>>>v<>v<<<^v^><^<><><>>^^<<^>^>vv>>v^^< +>v>><><>v<>v>^>>>>vv<^>^vv<<><>^v>^<>>>^^^^v>><>^^v<v<><<^vv>v^^><<<<>^><^<^^>vv^v>>^>^><^<<^<^^><^v<^<<>^^v><^^<<^<^vv^<><>^<<><>^>v>vv^>v>^<>vv>>v>^<>vv^>>>^v<^vv^>vvv^v^vv<^<>vv>^>>>>^<><^>v<<<>>vv>>^^v<>v^v>v><<>vvvv>vv<<>^^^><^<><<<>^^>^>^vv^^^vv>^>>vv<>^v<^<<>^>>>^<^v^<><<^vvv^<<^v><^vv^v>v<>^v^>>>v<^^<>^^>^>vvv>>^^><>>>v^^v>^v^v>^>^>^>^<<^^^>v>^<^><<<>^v><<>vvv>^>>v<^<^<>v^<<><^<><^><^^v<<>^>^v<^^>v^^v^>>v<^^v>^^v^><^>^>>v^^^>^vv>vvvv>v>v>><^^>>vv<^v>>>vvv^<^vv><>>>>^v<^><>v>v^>^>>>v>v^<>v^^>^>^>><><^>v^^v><>^v^^v<><>>^v>v^^^v^<^<>^v^v^>>vvv>vv^^>>^^<><>^>>vv>>><^v^>>^v^<>^>>^>v<<<<^^v<<^^>>v<^v^<<vv>v><^^<>>^^^v^v^v><>^<><^<>^><v<^v>v>^><>><><>v><>>v<^<<><><^v>>^<^>>^^vv>>><^>^^^<>^<<^>^><^< +>v<<<v^<>^v^>v<^>v>>>vv^>>vv><^^v<<^vvv^v>><^>^>><^^>v^^^^^v^<^>v>^v<<>^v<><^<^^<^<>v^>>^<<^v^vv^^^>v<^^><>^^>^<<<<^v><^>^^^<<>v<>><<^v^v>^>><>>vv<^<<^^v^^<^vv>^v<^^^v^<^>><^v^>>v<>v^^^>^^><<<^<>^v^v>v><>^^<<v<^<^><>^>v>vv<><>^v><>^^^<^>v><<<^v^<<>v^<^><><^<^^>^^<<>^<<<<^<<<^^vv<><^^^<<^^^><^<<<>>><><<^^>v><^v<>^<>>^>v>v>^<^^v>v^v^v>v>^^^^<<>^vv^v><^<>^v>v>>>vv>vv<>v^<<^<><<^><>>>vvv<^<<^^^vv^>^^^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^>vv^>><>^^>v>v^v<>^^<^^<><><^<>>>><^^vv^>vv^vvv>vvvv^^v>>><^>^><^<^>v><^><^^<<><<v>^v^>^<^v<<<^v^^<^<>>>v<^<^<>v<><^>><<>>^^>>^>>v^>>>>>>v +<>>>>>><<<<^^vv>^v^<^>><><v<>^<^<^>v^^<^v<^v<>>vv^><<^><<<v>v<v^^^>><>^vv^>vv><<>>vvv^<>vv>>><<>>v>v^v>^v^>^<^^<^<^<^vv>v><>vvv^<>vv>>>^<<>><<^<vvv^>>v^^>>>^^v>v>>v^^v><^^v^^^v<^>v><^vvvvv^<^v^^>>^<^^<<^>^v<>^><<>>^v>>>v^v>^^<>^vvv<>>^^^v^<>>^><>v^<<^v^^<^<^^^<><>v^^>v^><<>v^<^v<>v<>vv^^<>>^>^<^>>^>>^^><>>vv<>vv^v>>vv<<>^<>vv<^^v<>v><^^vv>vv^^<>><^<<^vv><^><^v^v>>^^v>>^v<^^^^^<>^<<^v>vvv>^v<^vvvv<<><^^>>>v^^v>v>^v<>v^>v^v>vv^><>^^^<^<<>v<>^v<^<<><^^v^<>v<>v>^v<^v><>>^v^v^^vvvv^<>^>^v>v^^^^>^v>vvv>v^>vv^v>^<^<^^>^v<><><^>^><^v<^^<>>^^<<><>^<<><<^vvvv>^><>^>^v<>^^><^<>v>^>^v^<^>>vv>>^^^v^<<<^v^><>v>>>^>^<^>^<^v<^>^vv>v^^>^>><><>>><>vv^><>><>>>>v>v>v>^v<^>v>^<<^^>>v^^>>>>>^v>v>><<<^^vv^<<>v^<>>><^^v^>^<>v^v>vv<>v^^vv>v>^v^^^v^^><<><<^<<>^vvv<<^^<^<<><^<^>^<><>>v^v^v<>>vv<>><>^<<^v^><>^v<^<<>v^^<<<^v>^^vv<^>vv^>vv><>^>v>><<<<>>>>>v^vvv<^^^<<<><<^^<>^>^v<>>^^>v>v^<<>>^v^>>v>>><>^>v^^<<^^>vv<v<^<>^<>>^v^>vv>^^v>^vvv>v<<>>v<^>v^v^<>><<><<>><^>>v^^vvv^v>>^<>vv^>>^v<<^^vv><^<<<<^^><>^>^v<<^<^v>>>^v>>v<<^v^<<^v>^^<^^>v<><>^>vv^^<<>>v^>>^<>v>^v^^<^^<<>v^>^v^>vvv><>^>>v^<^^><<^<<>v>v<^^vv^^<^^<^v^v^v<>v^><<^<^^^v<<^<^^>><<^^^v^vvvv>v<>v<<<>^v>^<^^v>^><<<<>^vvv^^v^>v^v<<^^v^^vv^<^^^v>^vv^<^>>^^^v^^<><^^v^^v>>>^^><^><^><>v><<>>^<>^>vv><^v^^v^>^<<>v<^>v>^>v>v>>>vv>vv>^v^^^>>vv^v^>^vvvvv<>v<^><^<<vv>v>vv^<<^>v^^^vv>v><>vv^^v>^>>vv>v^^^v>vvv^^<<^<^^<^>^<<>vv^v^v<>^<^^>^>>v><^v^v^<^>>>>v<^><><>^ +vv<>><>^>vv>>v<<^^v^v><<vv<>>>^^^vvv><>^v><>^>^<>^^^><^>^><>>^^<>><><<^v>v^<<^v^>v^^>>^vv^^v^^>v^^v>>^v<<<>v>>>vv>^^>><<^>vvv^<<<<>vv<<>^<<^<<>>v>^>>^>^vv^^^><<<><<<<^^^>>^^^v><>>v^v>v^^>v^v><<>>>>^<>v><^v^v^v<>v<^^^<^>^<^><>v<^<>vvvv^v^vv^^v>><<v>v<^^v><^<>^>v^>^v^^^>>v<^<<><^^vv<<>>^v<^<^<<^vv>^^>v>>><>^>v^v^v><>^vvvv^>vv>>>^<><^<^<>^<>v>>>vv<<^<<^v>>vvvv><^^v>^v>^><<>vv>^><<>>>^^^v>^^<>>v<^^v><<^<>>>v<^<^<<>>^^>^>^>v^^v<^^v>><>^vvvvv<><^^<^>><<><^<>^>^>v^>^vvvv<^><^^><^v>v<^vvv^<^^^<>><<<<><^^vv^><><^<^<^>v><<<^>>>^^^>>^^>v<><<^^>v><v<>>^><^v^v>^^<<^>v<^^>v<<^^><>v>vv<v^^^^^v^>>^v<>^>>v>v<<^^>>^<><^>v^>><^<^>>>^vv>>v>^^vvv>^v^>>>v<><>^>v^>^>v>>v>^>^>>v><^<^><><^<>v^v>^^vv><^^v^vv>^v^<>^><>^<<><<^^>>v>><<^<^>v<^vv^>v><><^^v^v>^<>>^<v>^^v^>^^>><<<^v^v^<^^v^<>>vvv>>^>^^^^vv^<^^^^<>>vvv<>^>>v^^^v>><^<><^^<^vv><>v>vv>vvv^^<>>v^<>vv><<^^><>v^><>>>><^^v^>>><^vv><>>v>^><<^>^>^>>v<^<><>^>^vv>^v<^<<^<><><^>^^^v^^<^vv^v<><^>>^^^>^<<^<>>>^><<^>>^v^>>v<<>>>v>>^^^^^v>>v>^><^<>^vv>v>vvv><>vv<>v<>>vv^<<^v^>vvv>><>>^v^^>>>v<^^^^>>vvv^v<><<>>v^>>v>>v>^<<^^><^^<>v^v^^vvv<^>^><^<^^<>>v>^^v^<<>^v>^><^^>>^<<^^>>vv^v^v>vv>>><^>^^v^><>^>v^<^v<^>^^^>v>v^<^v><<^^<>^<>>v>^<^v>^^v<><^v^^^<^^v^v<<><<<v^<<<>><^^v>>v<^>vv^^v<>^>^vv>v>>>vvvvv><<^<^><><^vv><>v<<><>^<>vv<<^v^>^v^<>^^vvvv^<><<<v^v>>^<^vv<<^>vvv^<><^vv^<^^><<^v^vv><>v^^<^^^>v><<v>v<<><>v^<^v><^>>>>v>>^^^>>^>v><>>^v<>>vv^^>^<^v<<<^>^>>^v<v>^^v>>vv^<^><^>vv^<<>>^^^<<>>v>^^>^^v^>>^>< +<<<^v<^>^>vv>^>v^^^<>^vvv^>v<<>v<<<^^>^^>><^<^<<>>^<<<<<>^v^>^^^>vv^<><>^>^v>v^><<>>^>>v^><^^^^<<^^vv^^<<>^>^v<<<^^>vv>>^>^^^<^^^><>^>v<>vvvv<>^^<^<><<<>^vv>>^>^<>^v>>v<<vvv>^v^<^><^v<^^<^<<^<>>^^<^v>vv><^^v<^v^<^v>v>^<^^^v<>vvvv<^<<><><>^>>>>vv<^<<><<^^<<^^^<<><>>^v<>>^<^^v^^<>><>>>><^^^v^^vv>^><><vv<>>^v>v>vv^<>vv^^>^vv>^v^<^>^^^>>^^v^>^vv^^>vv^v<<>>vv<>^>^^^^<^>>^vvvv>>>>>v^>^v^>>^>^v^^vv>><<^<^<^^v^>>v<>^><<<<>>><<^^^>v<^<^v>^<<>vv^v^>>^^<^v^v^vvvvv^vvv<^v^<>v>v>v<>^^<^v<<^v^<>>^>vvv<^<^^<>^vv^>v>^^v^<>><>vvv<<^v<<^v<^^vvv<<<>v>v>>^v^^<>>v^>>^^<>^^vv<>vvv>>^v^^<>>^><^^>>^><<<<>^v<>^>>v<^^>^v>^>vvvv^^^vv<^^^v><<>v^>v^>^<<>v>^>^^^>>vv>vvv^>^>^<>v>vvv>>>>^^^>v<<^<>vv<^<^>>^<^<>>><<^v<><><<v<> +<^v>>>^<^v^v^>>>^^vv^<>^^>^<>vv^>>v<^>>>vvvv<<^^^v^v>>>vvv<^^vv<^>><>vv^<><><^^^^<>vv^^<<>^>^vv^>^vv<<^<^>v>>^>v^v^v<>>>v>^>>^^<<>>>><^^v>>vv<>vvv^^^><^>^vv^v^vv<><^v>>>>>>>^^vv<>>>^>><>>>>v<>><><>^^>^^v^>^^vv<><vvv>v><<^v>^^^>v>^>>v<<<<^<>>v<><<><>^^^vv<<^<<^><^^^v>^<>>^^v^>^vvv^^<>^><>><>>v^>^<^vvvv><>^<<>>><v<^<>^^<^^>v^^<>^<<<>vvv>v><^>v<<^v>>^<><^vvvv<<^>^v>v^><<^vv^><>><>v^^^^<>^v^>^>v^^^>v<>>>>v>>v>v><>v<^^^^>v^<^^>><^><^>v^^^<><^vv<<>v^<>^vv<<^vvvv^<>v>v^<><^^>v<>v^<^^v<^v^^vv>>>^^^v>v><^^^<>v^v>vvvvvv><>v^^>^^<<>vv><^v^^>^^v<^v>><^><v<>>^<^vv^>>>>>^<^vvv<>>v<^v<^>^v<>vv^>>>v<>>vvvv><^^<^vv^v>v><^vv^>v^v^^v^>vv<v<^<^><>v^^v<^^^<><^>><<^<<<^>vvv^^>>^> +>>v^^vv^^>^^^^v^>>^vv<^^^^^>v>>><>^<>>>v<<><>^^<^<<^>^<>^v<<>>vvv>^<>^^^v<^^^^^<<v>>><><^<^v>^>>>>^v>v^v^<>v>><<><^>^v^^^<^<><<>>^>^^vvv<><v><^v^<^<^^v>vvvv>v><<^vv^^<<^^^>v^>>>^^^^^>>^<>v<><<^<<<<^^v<>>v>vv^>><>vv^>vvv^^<<>>>v<^<^^^^<><>><^^>v<<^><^^v<^^<<^vv><>v<<^>v<>v><<^^^>v<^<^vvv>^^<><><>^<>^^>>>v>>>^vv^^^>>^<>>>^<>^>^>^vv^vvv^v>vvv<^^^^<>^vv<><>>v>><>>>^vvvv>><>>vvv^vv<^vv>><^<^^<><<^^<><>v^<^>v^<^^>^^^v^^<>>v>^<^^v<<>v^v>>v<^v^<^^<^>v^vv^^v^>>v>v>vvvvv<<><>>^v^^^^>>v<^>><^^>^^<^^v>>v^^<^<^>>v^^^^^^v><<>^<<^<<^v^^^v<<>^v>v^^^^>v^>^vv^^>v^^>^<>^v<^^v>^v>^^^vv^v^^<><^v>><^^>v<^<>v^>v>><>v<^>v><^^>^>^^<>v<>vv^v<^<<^v>vv^^<<v^^<<^<>^>vvv><>>^>>> +><<>^v>>>v><<><<^>v^^<>v>v<<^>^vv><>v<>v^v>>>v><<>>vv<<<^<^<<<>>^>^vv^^<<^<><<>^<^><^v^vv<<^>^^^v^v>>><>v^vv^>><>v>v<^^v^<^>v^v>vv<<>v^v><><>vvv<<>><^v<<<^<><>vv<<>^^^<>^^>^^^^v>v^<>>v>v>>>vvv<<>^<^<<>vvv><^<^^>>v<^^^<>v>^v<^><^<<>^<^<^^>>^>^vv^v^<>^<^v>>vv^vvv<<<<<^>v<<>v^>v^v^^>^<^^>^vv>^<>v><>>v^>v^><><<<^^^v<^v^>^<^^>><^vv^^><<^^v^>v>>v>^>v<^^v^>><>v<^^<>^<>^^>><vvv^><>^v<^^>><^^v>v>>>>>^>>vvv><^^>^<>v^<<<<<<>v<^vv^<<<<^v^v^<<<^^v>^vvv>v<^v<^>>v^v><^^>^<^>^v>><^><<<^vv<^><>^v^><^>^>^>>^<^<<<^vvvv>>>>>v>^^>>v^<<>^v^><<>^><^^<^>vvvv>^v^>^^>^>^><<<<>><^<^>vv^vv^v>v><>vv^<>v>^v>v^<>>v>v<^v><>^v^>>^>^<<>vvv><>v>^v>^v<>>vvv<^<^<^vv<>>^^<^>><<^v^<>>v<>v^v^>v><>^>^vv<<>>>vv>^>>^v^<<^><<<>>><^<>v^>><^>>^<^<^<^<>^v +^v>vv<^><^^^<^<<<<<<>v^vvv>>>><vvvv>^<>v>v<>vvvv>v>>^>^v>v<><<^v<<><<^<^v>^^v>vvv<>v^v<<>v>>>>v>>><><><^v><^<<>>>><^>>>v^>>>>v^><<^<<<^v^vv<^><^>^vvvv^vv>^v>><>v^<>^^^^^vv^<^v<^^>^^<<vv><<>vv^^^^v^<<<<^^<<>v>^^vv^v<<>>^<^^v^v>>><^>^>v^<>^>v<<>><^<>^>><^<^><>>^<>v^vv^v^<^<^vv>^v<<><<><>>vvv<>>v>>^<>^>^>^v^>>^>vv^^<>v^>>>^v^v>^>^v^>v^vv<>v^^<>^^<>^<>><>^<>^^>^>^^<v<<^>>>^^v<>v<>v>^^<^><^v^><>^>v<>vv^<>v>^^<^^^>v^^v^v<<>^v^<>>><>>^^^v>v^vv><<>v^v^^><><>^v^<>v<>><^>^>>^^vvvv>vvv^>v^v<^v<<>^<^>vvvv<^v<>^^v^v<<>>^vvv>^^v>v<<>^^v<^><^^>v^<^><><>>^<<><><<<<><^v>^^^v><^^>^<<^>>^^<^v>^>v^vv^><vv^>><^<^<^v^>^^vv^^^<>v<^v^^vv><<<<^^v^^^vvv<<<><^>>v<<^>><^v<<^>>^vv<^<^v<>>^>v>>v^<>^^>^<>^>v>>v^>>>^<<>v^v<<>v<<>^>>v>>^^<>^><^^v<>^>^v<>v^^><<<^>v^v<^>^>^><<<^v^^^v>>vv<^v^^^^v +v^>v^vv>vv>vv^>v^<>v^vv><>>^v<>v>^><^<^>>^^>><<vv>v>><<^v>^^v<>v>^>vvv^vv>v>^vv>^<^^>>v^v<<>^<>^v><><^^^<v><<<>>^v>^vv^^^^><>^vv>^v^^<^v>v^>^^v^>>v>v^>vv>v^>vv<^vv>>v<^>^^>v><>^vv<<>v^v<<<<<^v>^<^^v^v<<^>>>>><^v^>^<><><>vv<>^><>><v^><>>>^vv<>^>>v>>^^<^^^>>^vvv<<>>><>^>>v^v<>v>vvv^><^^^^<>vv><^>^^v<^v<<><^<>vv>^^v>^>>^^>^>>><<^^vv^vvv^><><^v>^<^v>^^v>vv>^>vvvvv>>><>^v>v>>>vv>^v<><>v^v^>^^<^^^^^^>>v>>^>v^^><<<^<^<>v>v>^vv^vvv^v^>^vv^vv>^>>^>v^^v<<><><>>v>>vv<>vv^>vv>^>v>><<<<^>v>v^>v><>v<<<^>^^>>><>v>^<^><<v<<>>^<>><^^>^^vv<>>><<^^>><>><^><<>^^^vv^<<^>>>vvv>^v>^^>v^>vvvv>^^>v<^<>v^>^v<>>>>><>^<^v^>v>^>vvv^^>v^<<v><><>>^>>^^<<>^vvv^vv>>^^>v^v>v<><^<^<><<>v<<>>>v<^>v<^^^><<^v><^<^<>^^^^^>vv^v^<<^<^^<<<>^>^v^^>>>vvv^<^v>^v^<> +>^^>^>v^^^vvv>>v^^v>^v>^<^<^^v><>^<<<^v^v^<^><<^<^v>v><^^<>^<><><^v>^^<^<>>><>>^>^v>>>vv><^><>vvvv<<^<<<>><^vvv^vv>v>^^^<<><>^vv>^>^v>^^v^>vvvv>><^^<^>vv>^<><>^^^^><>><^>vv><^<>><>v<>>^v>^v^^<^v^<^^<^>^^<>^^^^v<><>v>>^>v>^>>>v^v^v^^v>><<<>^v>^>>>v^v><^>v>vv<^^><^>^^>v^^vv>vv>vv^^^^v^<^vv^<^v^v>^<^><^>>v>^>>>vv^^v<>>^^<>><^>vv>v>>v<<<>v><<>^^^vv>^^vv>^v^<>^>>>>><>^><^>^<>v<<^^v^^vvv>^>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>v^^^>v^v^>><^^v>v<^vvv^<><^^v^^<>>v^<>^>^v^<^^<<^v<<<^<^<>^^>v^>^^v>^v^v^<>>^<^^<<><^^>^^vv^<^vv><>^>v<>v>>v^<^>^^>v^v><><<>v^>^v< +^<><<^^>vv<^^<<<^>v>v>>vv>>^<^<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<^>>^>vv>v<>>>vvv><>^^^v<^<<^>^^<>v>^>vv^v>>><<^<<<>^>^v^v<<<^^^<<<><>><^v>^<<^v>^<^^^<>>>>^^^>^^>v<>v^^<^<^<<^>>v>^v<><>^<>^v<^<>v^v^v>^vvv^v>v<^^v>^^<>^^^^^^^^^v>^v>v<^^>v><<><<^^<<<^^v>^^vv>v^>^<><<^<^><>v^^>^>v><<<^<^>>^<>^><>^><><>^<<^^>v><^<>^>v<^v<>^^<<^>^vv^v^vvvv^v^^>^vv<^>^^v^^v>>v>v<><^vv<><^vv^<<^^<^^^>^>>^v><^>^<^<^>>^>v^^>^vv^^^<>^v>>>>^v<^^>vvv>v<>v<><<>^^>vv^<^<>>v><^<^^^>v^<<^>vv>^v<<<^>>><<<^^>^^^^v^>^^ +v><<^^^<>>^^<>v^^vv^vv^>v^>^>>v>><>>>^^v^^v>v>^<>>^<^v<>>>v^<^>v<^vv^<<^<>v>>^^v^^v^^v^v><>vv>^^v<^^><^>^^^>^^^>>v<>v^^vv<^><^>>>>v^><^v>^^><^v<^><<^<<>>>^<^><<>vvv><^^^^v^<>>^^v^^v>>>>^vv>>vv<<^^<^<^<>^>v<>^^v>>^vv^^<<>vvv<>><>vv^<^v<>^>v<>><<^>^<^<<><^vv<><^<^vv^^<<>>^vvvv^>^^>>^<>v><<^v>>^<^v^vv>vv^v^vv<^v^^v<^>>^v<^^v>v^<>><^>^<><>><^v^^<>>^^v<^v>>^^>v^<^>v<<<^^v^^vv^v>^v>^>vvvv>^<^>v>>v<><v>^>^<>^>v<^>vv><<>v^<^>^>v>^^><^>^^>^>>>^<<<<<>vvvv>vv^>v^>>v^^<>>vv>^v^>v^<<^v>^>>><^^^^>^vvv<>vvv^>^>>v^<><^>>vvv^^>v<>>>>v^^>^<v^<<<<>v^<^v<><<^^>vvv>^<^^^<<^<^<>>^<^vvv>>^><><<><>>>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^<<>vvv<^^>v>><>v>>v^vv>><^^>^<>>^<^v>v^>>>>^^v>>^vvv<>vv<>v>>v><^^vv>>v>>^<^^v<>v<>v>>v<>>>v^^v>v<^v^<>>><^^^vv>>vv<>v>>^^vv^v^v>>v>vv>^^<^<^><<>vv<^>^v><^^^v^>>^>vv><>^<>v<^^^v^v<><<>>^vv>^v>>^>v<>v^<<^^>><<^><^^>^vv^v^>>^>^^^>>v^<^<><^>vv>^vv<<>v>>>v^^vv^><<^>>v>v<<>^<^^<><>^vv><>v>^<<>^^vv^^>v^v>>>^v^^^vvv^^v^<^>^^v<<<^>v>v^><<>v<>>><><><>>v>v>^<>v^>^><<>>>^<<<^>>><>>>^v<><>^vvv<>^<<><>v>v>^v<<><>v^>^^^>v><<<>v^>>v<>^>^>^>v>><<^>>^vv^v<^<<>>>>^v<<^>>vv><^v^^^vv>>v>>>v^>^>>^^>v^^vv^^v^^>v>><><>><^>>vvv^^^^>><<>^vv^^>^>><^>>v><>v^<v>v><>^vvvvv^>^^^^v<vvvv>^^^><>^^>^v^ +>>^>>>v<>v^><^^vv>v^>v>^v<>>v>^v<^<<<^<<>vvv^v>^^^<^>>>v<^>>^>^v^^>v>^<>v<<^^><^v<<^^><<><<><<^<^^><^><<^>>vvvv<<>v><>v^>^<^>v>^^^>><^vv^>^>^<^<^v<><^^^v^v><^>>^^><^<^^>vv^>v>>>v<>^vv^^vv<>^vv^<>v>^^v^>>><^><>vv<<><^^>vv<^vv^<^<<^^>vv>>>>>^^<><v^v>^>^<>>v<^vvv^v<<<^<^><<>^v<<>v^^>>^<>v^vv>><^v>>^^v^v>^>><<<>><<>v>^><<<>>vvvvv^>vv^<>vv>v>>v><^v^v^>>v^>^v>^^<<^<<^^^vvv^<^^v^>v^vv^^>vvv^<>^<>v<<<>vv<>v^>^<>^v>v^v<>^>^>>v><^v>^v^^<^>>v^><>^^<^><<^<^vv<v>>v<>v><v^^^^>vv^vv>^v^>><<^>v^v^v>><^^^^^>^>>>^>^>vv<<^<><<^^<^v>v>v<>v^vv>><<<^<<>>>^>^^<>v^vvv^v><<<>^vv<<^^<>>vv<^><^<>v>vv>><^<^^v^vv^>^^^<^^>>v><>^>>><<^>^^>v<<^><>>^^vv<<>>^^><>v>>v^<^v^^v^vvv^^^^^v^<>>vv^^>^^<>>>^<>>>>^^^<^<<<<^<><^>vv>>v>v>>>^>^v>v^>^^<^^v>^^><^v^^^^<^>^>^>^v<^v^vv^vv>>>><^v<<^><<>>v<<>v><>v><^v^^>v>^>><><<^<>>v>^>^v^^^v^<^<^vv^>>^^<>><<>vvv>>^^v>>>^>>>^><><<^v><^^v>v^>v>^^<<>^v^v>><^v<>^>^^<^>^>v>vv^<>^<>^<<<^<<^v<^>>><^v^v>^v^v>vv^<<<<>vv<^<>v>>>>^^^<^>^v<<^<^><^>>^^vvv^^>>>v^>vv^^>v^>v<<^v><>^<<^>vv^<^^>^v><<<^><<>v^^vv>>vvv>>>^>>^^vv<^<>>v^v^>>>v<>>><^v><<>vv>v>v^^vv>v^>^v<<><<<>>^^><^>>>v^^vv>>v><^>v>v^^v<<^>>^><>v^v<<<>v<^<>^<<<^v>^><^>^^v^^><>vv>v^^<^v<^><>^vv>v^^v>>^v^<>>>vv>^>^>^v<<>^vv<<>v^^^v>><<<>><>^^v<<v^^^^^<><^<>>^^<>^<>v^>><^v^>^<^v^vv>v>>vv>><^v><<^<^^^^v<>vv^>^><^>^><<^><>^^v^^<><<<<>vv^v>^^><>^v^^vv^^>^v^>>^vv>^^vvv^<^^^<>v<^^vvv>>v^vvvv<><>^v<>><>v>^<^v<^v^><<^<>^>>>v<>vv>>^^vv<>>>><<<><>><^^^v<<^><^<><<<v>><>v<>>><^<>^>>v^vv^vv<>^v^v>^<>^><>v>^^<< \ No newline at end of file diff --git a/inputs/15/test.txt b/inputs/15/test.txt new file mode 100644 index 0000000..c6138ff --- /dev/null +++ b/inputs/15/test.txt @@ -0,0 +1,10 @@ +######## +#..O.O.# +##@.O..# +#...O..# +#.#.O..# +#...O..# +#......# +######## + +<^^>>>vv>v<< \ No newline at end of file diff --git a/solutions/14.zig b/solutions/14.zig new file mode 100644 index 0000000..c575835 --- /dev/null +++ b/solutions/14.zig @@ -0,0 +1,215 @@ +const std = @import("std"); +const print = std.debug.print; +const util = @import("util.zig"); +const expect = std.testing.expect; + +pub fn main() !void { + // const response = try part_one(false); + // print("{}\n", .{response}); + try part_two(); +} + +const Point = struct { x: u32, y: u32 }; + +const Velocity = struct { x: i32, y: i32 }; + +const Robot = struct { + position: Point, + velocity: Velocity, + + pub fn move(self: *Robot, width: usize, height: usize) void { + // I wish it were possible to put this on multiple lines, but it appears to be a syntax error + const new_x: u32 = @intCast(if (self.velocity.x >= 0) (self.position.x + util.magnitude(self.velocity.x)) % width else (self.position.x + (width - util.magnitude(self.velocity.x))) % width); + + const new_y: u32 = @intCast(if (self.velocity.y >= 0) (self.position.y + util.magnitude(self.velocity.y)) % height else (self.position.y + (height - util.magnitude(self.velocity.y))) % height); + + self.position = Point{ .x = new_x, .y = new_y }; + } + + pub fn move_iterated(self: *Robot, width: usize, height: usize, move_count: u32) void { + for (0..move_count) |_| { + // Technically inefficient in that it does the modulo operation on every movement, but the alternative would + // be having to deal with Zig's bullshit integer limits, so... :shrug: + self.move(width, height); + } + } + + pub fn from_line(line: []const u8) !Robot { + // print("DEBUG - parsing line {s}\n", .{line}); + const start_pos_x: usize = 2; + const end_pos_x: usize = std.mem.indexOf(u8, line, ",").?; + // print("DEBUG - end_pos_x is {}\n", .{end_pos_x}); + const start_pos_y: usize = end_pos_x + 1; + const end_pos_y: usize = std.mem.indexOf(u8, line, " ").?; + // print("DEBUG - end_pos_y is {}\n", .{end_pos_y}); + + const start_vel_x: usize = std.mem.indexOf(u8, line, "v").? + 2; + // print("DEBUG - start_vel_x is {}\n", .{start_vel_x}); + const end_vel_x: usize = std.mem.indexOf(u8, line[end_pos_y..], ",").? + end_pos_y; + // print("DEBUG - end_vel_x is {}\n", .{end_vel_x}); + const start_vel_y: usize = end_vel_x + 1; + const end_vel_y: usize = line.len; + + const x = try std.fmt.parseInt(u32, line[start_pos_x..end_pos_x], 10); + const y = try std.fmt.parseInt(u32, line[start_pos_y..end_pos_y], 10); + const vel_x = try std.fmt.parseInt(i32, line[start_vel_x..end_vel_x], 10); + const vel_y = try std.fmt.parseInt(i32, line[start_vel_y..end_vel_y], 10); + + print("DEBUG - x, y, vel_x, vel_y are {}, {}, {}, {}\n", .{ x, y, vel_x, vel_y }); + + return Robot{ .position = Point{ .x = x, .y = y }, .velocity = Velocity{ .x = vel_x, .y = vel_y } }; + } +}; + +fn part_one(is_test_case: bool) anyerror!u32 { + var gpa = std.heap.GeneralPurposeAllocator(.{}){}; + defer _ = gpa.deinit(); + const allocator = gpa.allocator(); + + const input_file = try util.getInputFile("14", is_test_case); + const data = try util.readAllInputWithAllocator(input_file, allocator); + defer allocator.free(data); + + var it = std.mem.splitScalar(u8, data, '\n'); + var robots = std.ArrayList(Robot).init(allocator); + defer robots.deinit(); + + const height: u32 = if (is_test_case) 7 else 103; + const width: u32 = if (is_test_case) 11 else 101; + + while (it.next()) |line| { + try robots.append(try Robot.from_line(line)); + } + + var first_quadrant_count: u32 = 0; + var second_quadrant_count: u32 = 0; + var third_quadrant_count: u32 = 0; + var fourth_quadrant_count: u32 = 0; + // I don't know why this has to be `*robot` - see question [here](https://ziggit.dev/t/how-to-get-a-non-const-pointer-to-a-structs-field-from-within-a-function-of-the-struct/7639/13?u=scubbo) + for (robots.items) |*robot| { + robot.move_iterated(width, height, 100); + print("DEBUG - robot in position {}/{}\n", .{ robot.position.x, robot.position.y }); + // Can't use a `switch`, here, as `width/2` and `height/2` are not comptime expressions + if (robot.position.x < width / 2 and robot.position.y < height / 2) { + first_quadrant_count += 1; + } + if (robot.position.x > width / 2 and robot.position.y < height / 2) { + second_quadrant_count += 1; + } + if (robot.position.x < width / 2 and robot.position.y > height / 2) { + third_quadrant_count += 1; + } + if (robot.position.x > width / 2 and robot.position.y > height / 2) { + fourth_quadrant_count += 1; + } + } + print("DEBUG - quadrant counts are {}, {}, {}, {}\n", .{ first_quadrant_count, second_quadrant_count, third_quadrant_count, fourth_quadrant_count }); + return first_quadrant_count * second_quadrant_count * third_quadrant_count * fourth_quadrant_count; +} + +// ...wtf!? How on earth are you meant to do this without visual inspection? +// ...ok, giving up on this. I stepped through the output (run `zig run solutions 14.zig > /tmp/output 2>&1`, then open in vim and do: +// `qt/Iterationztqq` (to record a macro on key `t` which will bring the next iteration to the top of the screen), then repeatedly do +// `@t`) but can't see anything resembling a christmas tree. +// Iterations 12 and 35 both show some structure, but nothing like a tree (and those are both rejected as answers) +fn part_two() anyerror!void { + var gpa = std.heap.GeneralPurposeAllocator(.{}){}; + defer _ = gpa.deinit(); + const allocator = gpa.allocator(); + + const input_file = try util.getInputFile("14", false); + const data = try util.readAllInputWithAllocator(input_file, allocator); + defer allocator.free(data); + + var it = std.mem.splitScalar(u8, data, '\n'); + var robots = std.ArrayList(Robot).init(allocator); + defer robots.deinit(); + + const height: u32 = if (false) 7 else 103; + const width: u32 = if (false) 11 else 101; + + while (it.next()) |line| { + try robots.append(try Robot.from_line(line)); + } + for (0..100) |iteration| { + for (robots.items) |*robot| { + robot.move(width, height); + } + + var lines = std.ArrayList([]u32).init(allocator); + for (0..height) |_| { + var line = std.ArrayList(u32).init(allocator); + for (0..width) |_| { + try line.append(0); + } + try lines.append(try line.toOwnedSlice()); + } + const lines_owned = try lines.toOwnedSlice(); + + for (robots.items) |*robot| { + lines_owned[robot.position.y][robot.position.x] += 1; + } + + // Print out display + print("Iteration count: {}\n", .{iteration + 1}); + for (lines_owned) |line| { + for (line) |val| { + if (val > 0) { + print("X", .{}); + } else { + print(" ", .{}); + } + } + print("|\n", .{}); // I'm cheating by putting this trailing pipe to stop Vim from giving ugly red highlights on trailing whitespace + } + print("\n\n", .{}); + + for (lines_owned) |line| { + allocator.free(line); + } + allocator.free(lines_owned); + std.time.sleep(1000000); + } +} + +test "robot movement" { + var robot = Robot{ .position = Point{ .x = 2, .y = 4 }, .velocity = Velocity{ .x = 2, .y = -3 } }; + robot.move(11, 7); + print("DEBUG - robot position after one iteration is {}/{}\n", .{ robot.position.x, robot.position.y }); + try expect(robot.position.x == 4); + try expect(robot.position.y == 1); + + robot.move(11, 7); + print("DEBUG - robot position after two iterations is {}/{}\n", .{ robot.position.x, robot.position.y }); + try expect(robot.position.x == 6); + try expect(robot.position.y == 5); + + robot.move(11, 7); + print("DEBUG - robot position after three iterations is {}/{}\n", .{ robot.position.x, robot.position.y }); + try expect(robot.position.x == 8); + try expect(robot.position.y == 2); + + robot.move(11, 7); + print("DEBUG - robot position after four iterations is {}/{}\n", .{ robot.position.x, robot.position.y }); + try expect(robot.position.x == 10); + try expect(robot.position.y == 6); + + robot.move(11, 7); + print("DEBUG - robot position after five iterations is {}/{}\n", .{ robot.position.x, robot.position.y }); + try expect(robot.position.x == 1); + try expect(robot.position.y == 3); +} + +test "iterated movement" { + var robot = Robot{ .position = Point{ .x = 2, .y = 4 }, .velocity = Velocity{ .x = 2, .y = -3 } }; + robot.move_iterated(11, 7, 3); + print("DEBUG - robot position after three iterations (in one go) is {}/{}\n", .{ robot.position.x, robot.position.y }); + try expect(robot.position.x == 8); + try expect(robot.position.y == 2); +} + +test "part_one" { + const part_one_response = try part_one(true); + print("DEBUG - part_one_response is {}\n", .{part_one_response}); + try expect(part_one_response == 12); +} diff --git a/solutions/15.zig b/solutions/15.zig new file mode 100644 index 0000000..f619862 --- /dev/null +++ b/solutions/15.zig @@ -0,0 +1,190 @@ +const std = @import("std"); +const print = std.debug.print; +const util = @import("util.zig"); +const expect = std.testing.expect; + +// OMG come on part two does not seem fun at all. + +pub fn main() !void { + const response = try part_one(false); + print("{}\n", .{response}); +} + +const Point = struct { + x: usize, + y: usize, + + pub fn left(self: Point) Point { + return Point{ .x = self.x - 1, .y = self.y }; + } + + pub fn up(self: Point) Point { + return Point{ .x = self.x, .y = self.y - 1 }; + } + + pub fn right(self: Point) Point { + return Point{ .x = self.x + 1, .y = self.y }; + } + + pub fn down(self: Point) Point { + return Point{ .x = self.x, .y = self.y + 1 }; + } +}; + +fn part_one(is_test_case: bool) anyerror!u32 { + var gpa = std.heap.GeneralPurposeAllocator(.{}){}; + defer _ = gpa.deinit(); + const allocator = gpa.allocator(); + + const input_file = try util.getInputFile("15", is_test_case); + const data = try util.readAllInputWithAllocator(input_file, allocator); + defer allocator.free(data); + + var map_list = std.ArrayList([]u8).init(allocator); + + var it = std.mem.splitScalar(u8, data, '\n'); + var robot_position: Point = undefined; + var line_counter: usize = 0; + while (it.next()) |line| : (line_counter += 1) { + if (std.mem.eql(u8, line, "")) { + break; + } + // There _must_ be a better way of doing this - why can't we just copy the data in as a slice rather than having + // to copy character-by-character? + // (I know that "under-the-hood" those are the same operations, but it should be easier for a developer to + // write) + var line_list = std.ArrayList(u8).init(allocator); + for (line) |c| { + try line_list.append(c); + } + try map_list.append(try line_list.toOwnedSlice()); + + const index_of_at = std.mem.indexOf(u8, line, "@"); + if (index_of_at != null) { + print("DEBUG - found the robot at {}/{}\n", .{ index_of_at.?, line_counter }); + robot_position = Point{ .x = index_of_at.?, .y = line_counter }; + } + } + const map = try map_list.toOwnedSlice(); + defer allocator.free(map); + defer { + for (map) |line| { + allocator.free(line); + } + } + print("DEBUG - finished setting up the map, now reading and executing move instructions\n", .{}); + + // The rest of `it` are lines of instructions + while (it.next()) |instructions_line| { + print("DEBUG - instructions line is {s}\n", .{instructions_line}); + for (instructions_line) |direction| { + robot_position = try move(map, robot_position, direction, allocator); + } + } + + return calculate_score(map); +} + +const MoveError = error{ RobotMislocated, UnexpectedDirection, UnexpectedValue }; + +// Returns the new position that the robot is at +fn move(map: [][]u8, robot_position: Point, direction: u8, allocator: std.mem.Allocator) anyerror!Point { + if (map[robot_position.y][robot_position.x] != '@') { + // Could give some more debugging info - but, string-construction in Zig is such a pain, I'll add that if and + // when it's needed + print("DEBUG - something has gone wrong - the robot is not at the expected position\n", .{}); + return MoveError.RobotMislocated; + } + print("DEBUG - trying to move the robot (at position {}/{}) in direction {c}\n", .{ robot_position.x, robot_position.y, direction }); + const move_direction_function = switch (direction) { + '^' => &Point.up, + '>' => &Point.right, + 'v' => &Point.down, + '<' => &Point.left, + else => { + print("Encountered an unexpected direction: {c}\n", .{direction}); + return MoveError.UnexpectedDirection; + }, + }; + const response = try try_move(map, robot_position, move_direction_function, allocator); + defer allocator.free(response); + if (response.len == 0) { + // I.e. could not push boxes because they form a line into a wall + // debugPrintTheMap(map); + return robot_position; + } + + for (response) |box_filled_point| { + map[box_filled_point.y][box_filled_point.x] = 'O'; + } + map[robot_position.y][robot_position.x] = '.'; + const new_robot_position = move_direction_function(robot_position); + map[new_robot_position.y][new_robot_position.x] = '@'; + + // debugPrintTheMap(map); + + return new_robot_position; +} + +fn debugPrintTheMap(map: [][]u8) void { + print("DEBUG - printing the map\n\n", .{}); + for (map) |line| { + for (line) |c| { + print("{c} ", .{c}); + } + print("\n", .{}); + } +} + +// Attempt a move using the move_direction_function given. +// If successful, return a slice of the points that should be updated to hold boxes. +// If unsuccessful (i.e. if the boxes form a line into a wall), return an empty slice +// +// (Note that this actually leads to some weird intermediate situations, in that the space that the robot is about to +// move into will _still_ have a box in (or, in the case where the robot's not pushing a box, will have a box created +// in it) - but that will then get overriden by the robot itself, anyway, leading to a correct eventual outcome) +fn try_move(map: [][]u8, robot_position: Point, move_direction_function: *const fn (self: Point) Point, allocator: std.mem.Allocator) error{ RobotMislocated, UnexpectedValue, OutOfMemory }![]Point { + var ret = std.ArrayList(Point).init(allocator); + var variable_robot_position = robot_position; + while (true) { + variable_robot_position = move_direction_function(variable_robot_position); + switch (map[variable_robot_position.y][variable_robot_position.x]) { + 'O' => { + try ret.append(variable_robot_position); + }, + '.' => { + try ret.append(variable_robot_position); + return ret.toOwnedSlice(); + }, + '#' => { + ret.deinit(); + return allocator.alloc(Point, 0); + }, + else => { + ret.deinit(); + print("Found unexpected value {c} at {}/{}\n", .{ map[variable_robot_position.y][variable_robot_position.x], variable_robot_position.y, variable_robot_position.x }); + return MoveError.UnexpectedValue; + }, + } + } +} + +fn calculate_score(map: [][]u8) u32 { + var return_value: u32 = 0; + for (map, 0..) |line, i| { + for (line, 0..) |c, j| { + if (c == 'O') { + const increment: u32 = @intCast((100 * i) + j); + print("DEBUG - found a box at {}/{}, so adding {} to the score\n", .{ i, j, increment }); + return_value += increment; + } + } + } + return return_value; +} + +test "part_one" { + const part_one_response = try part_one(true); + print("DEBUG - part_one_response is {}\n", .{part_one_response}); + try expect(part_one_response == 2028); +} diff --git a/solutions/util.zig b/solutions/util.zig index 9a39fe8..bd48ab3 100644 --- a/solutions/util.zig +++ b/solutions/util.zig @@ -85,6 +85,14 @@ pub fn readAllInputWithAllocator(path: []u8, alloc: std.mem.Allocator) ![]const return try file.reader().readAllAlloc(alloc, stat.size); } +pub fn magnitude(num: i32) u32 { + if (num >= 0) { + return @intCast(num); + } else { + return @intCast(-num); + } +} + const expect = @import("std").testing.expect; test { @@ -110,3 +118,9 @@ test "Test Diffing Numbers" { try expect(diffOfNumbers(26, 35) == 9); try expect(diffOfNumbers(5, 5) == 0); } + +test "Magnitude" { + try expect(magnitude(2) == 2); + try expect(magnitude(-2) == 2); + try expect(magnitude(-365) == 365); +}