示例#1
0
        private static int PaintHull(IntCode intcode, Dictionary <long, bool> hull)
        {
            intcode.Reset();
            BlockingCollection <long> output = new BlockingCollection <long>();
            var task = Task.Run(() => {
                intcode.Run(o => output.Add(o));
                output.CompleteAdding();
            });

            int loc            = 0;
            int dir            = 0;
            int panels_painted = 0;

            hull.TryGetValue(loc, out bool iswhite);
            intcode.Write(iswhite ? 1 : 0);
            while (output.TryTake(out long paint, 1000))
            {
                if (!hull.ContainsKey(loc))
                {
                    panels_painted++;
                }
                hull[loc] = paint == 1;
                long turn = output.Take();
                if (turn == 0)
                {
                    dir = (dir + 3) % 4;
                }
                else
                {
                    dir = (dir + 1) % 4;
                }
                if (dir == 0)
                {
                    loc--;
                }
                else if (dir == 1)
                {
                    loc += 100;
                }
                else if (dir == 2)
                {
                    loc++;
                }
                else if (dir == 3)
                {
                    loc -= 100;
                }
                hull.TryGetValue(loc, out iswhite);
                intcode.Write(iswhite ? 1 : 0);
            }

            return(panels_painted);
        }
示例#2
0
        public static void Day2()
        {
            Console.WriteLine("Day2: ");
            long[] prog = "1,12,2,3,1,1,2,3,1,3,4,3,1,5,0,3,2,10,1,19,1,19,6,23,2,13,23,27,1,27,13,31,1,9,31,35,1,35,9,39,1,39,5,43,2,6,43,47,1,47,6,51,2,51,9,55,2,55,13,59,1,59,6,63,1,10,63,67,2,67,9,71,2,6,71,75,1,75,5,79,2,79,10,83,1,5,83,87,2,9,87,91,1,5,91,95,2,13,95,99,1,99,10,103,1,103,2,107,1,107,6,0,99,2,14,0,0"
                          .Split(',').Select(c => long.Parse(c)).ToArray();
            // part 1
            var intcode = new IntCode(prog);
            var result  = intcode.Reset().SetParams(12, 2).Run().ReadMemory(0);

            Console.WriteLine(result);
            // part 2
            for (int p1 = 0; p1 <= 99; p1++)
            {
                for (int p2 = 0; p2 <= 99; p2++)
                {
                    result = intcode.Reset().SetParams(p1, p2).Run().ReadMemory(0);
                    if (result == 19690720)
                    {
                        Console.WriteLine(100 * p1 + p2);
                    }
                }
            }
        }
示例#3
0
        public static void Day5()
        {
            Console.WriteLine("Day5: ");

            long[] prog = File.ReadAllText("Aoc2019\\Day05\\input.txt").Split(',').Select(c => long.Parse(c)).ToArray();

            // part 1
            List <long> output  = new List <long>();
            var         intcode = new IntCode(prog);

            intcode.Write(1).Run(o => output.Add(o));
            Console.WriteLine(string.Join(',', output));

            // part 2
            output.Clear();
            intcode.Reset().Write(5).Run(o => output.Add(o));
            Console.WriteLine(string.Join(',', output));
        }
示例#4
0
        public static void Day15()
        {
            Console.WriteLine("Day15: ");

            long[] prog    = File.ReadAllText("Aoc2019\\Day15\\input.txt").Split(',').Select(c => long.Parse(c)).ToArray();
            var    intcode = new IntCode(prog);

            // part 1
            // we need to explore the game space; and then count the steps to the origin.
            // idea1: wall following
            // idea2: traverse to the nearest unexplored space (also could be used to get back to origin)
            // idea3: keep track of min distance to origin at each square.

            int[,] board = new int[100, 100];
            BlockingCollection <int> game = new();
            int  x = 25, y = 25, dx = 0, dy = -1, dist = 1, max_dist = 0;
            bool hitWall = false, findOxygen;
            bool show_board = false;

            if (show_board)
            {
                Console.WindowHeight = 50;
                //Console.WindowWidth = 100;
                for (int cy = 0; cy < Console.WindowHeight; cy++)
                {
                    Console.WriteLine();
                }
                Console.CursorVisible = false;
            }

            // part 1
            findOxygen  = true;
            board[x, y] = dist;
            intcode.Reset();
            Task.Run(() => {
                intcode.Run(o => game.Add((int)o));
                game.CompleteAdding();
            });
            RunSimulation(show_board, autoplay: FollowWall);

            if (show_board)
            {
                Console.SetCursorPosition(0, Console.WindowTop + Console.WindowHeight - 1);
            }

            Console.Write($"Found Oxygen at {x},{y} dist to origin = {dist}");

            // part 2
            findOxygen = false;
            // reset dists
            dist     = 0;
            max_dist = 0;
            ClearDists(board);
            RunSimulation(show_board, autoplay: FollowWall);

            if (show_board)
            {
                Console.SetCursorPosition(0, Console.WindowTop + Console.WindowHeight);
                Console.CursorVisible = true;
            }
            Console.WriteLine($"Max time for oxygen dispersion: {max_dist}");

            void RunSimulation(bool show_board, Action autoplay)
            {
                while (true)
                {
                    if (show_board && board[x, y] != -2)
                    {
                        Console.SetCursorPosition(x, y + Console.WindowTop);
                        Console.Write('D');
                        Thread.Sleep(10);
                    }
                    autoplay?.Invoke();
                    if (!game.TryTake(out int r, -1))
                    {
                        break;
                    }
                    if (show_board && board[x, y] != -2)
                    {
                        Console.SetCursorPosition(x, y + Console.WindowTop);
                        Console.Write('.');
                    }
                    hitWall = false;
                    x      += dx;
                    y      += dy;
                    if (show_board)
                    {
                        Console.SetCursorPosition(x, y + Console.WindowTop);
                    }
                    if (r == 0)
                    {
                        if (show_board)
                        {
                            Console.Write('▓');
                        }
                        board[x, y] = -1;
                        x          -= dx;
                        y          -= dy;
                        hitWall     = true;
                    }
                    else if (r == 1)
                    {
                        if (board[x, y] == 0)
                        {
                            board[x, y] = ++dist;
                        }
                        else
                        {
                            dist = board[x, y];
                        }
                        if (dist > max_dist)
                        {
                            max_dist = dist;
                        }
                    }
                    else if (r == 2)
                    {
                        if (show_board)
                        {
                            Console.Write('@');
                        }
                        board[x, y] = -2;
                        if (findOxygen)
                        {
                            break;
                        }
                    }
                    if (!findOxygen && x == 25 && y == 25) // back to the starting position
                    {
                        break;
                    }
                }
            }

            void FollowWall()
            {
                if (hitWall)   // we smacked into a wall, turn right
                {
                    var ox = dx;
                    dx = -dy;
                    dy = ox;
                }
                else if (board[x + dy, y - dx] != -1)     // no wall to left - turn left
                {
                    var ox = dx;
                    dx = dy;
                    dy = -ox;
                }
                else
                {
                    while (board[x + dx, y + dy] == -1)   // wall ahead - turn right
                    {
                        var ox = dx;
                        dx = -dy;
                        dy = ox;
                    }
                }
                int next = (dy < 0) ? 1 : (dy > 0) ? 2 : (dx < 0) ? 3 : 4;

                intcode.Write(next);
            }

            void ClearDists(int[,] board)
            {
                for (int x = 0; x < board.GetLength(0); x++)
                {
                    for (int y = 0; y < board.GetLength(1); y++)
                    {
                        if (board[x, y] > 0)
                        {
                            board[x, y] = 0;
                        }
                    }
                }
            }

            void PlayManually()
            {
                var k = Console.ReadKey(true);

                dx = dy = 0;
                if (k.Key == ConsoleKey.UpArrow)
                {
                    dy = -1;
                    intcode.Write(1);
                }
                else if (k.Key == ConsoleKey.DownArrow)
                {
                    dy = 1;
                    intcode.Write(2);
                }
                else if (k.Key == ConsoleKey.LeftArrow)
                {
                    dx = -1;
                    intcode.Write(3);
                }
                else if (k.Key == ConsoleKey.RightArrow)
                {
                    dx = 1;
                    intcode.Write(4);
                }
                else if (k.Key == ConsoleKey.Q)
                {
                    intcode.Write(0);
                }
            }
        }
示例#5
0
        public static void Day21()
        {
            Console.WriteLine("Day21: ");

            long[] prog    = File.ReadAllText("Aoc2019\\Day21\\input.txt").Split(',').Select(c => long.Parse(c)).ToArray();
            var    intcode = new IntCode(prog);

            bool show_space = false;

            // part 1
            int damage       = 0;
            var springscript = @"
NOT A J
NOT B T
OR T J
NOT C T
OR T J
AND D J

WALK
";

            RunScript(intcode, springscript);

            // part 2
            springscript = @"
NOT A J
NOT B T
OR T J
NOT C T
OR T J
AND D J

NOT E T
NOT T T
OR H T
AND T J

RUN
";
            RunScript(intcode, springscript);

            void RunScript(IntCode intcode, string springscript)
            {
                intcode.Reset();
                foreach (var instr in springscript.Split("\r\n").Select(s => s.Trim()).Where(s => s != ""))
                {
                    foreach (var c in instr + "\n")
                    {
                        intcode.Write(c);
                    }
                }
                intcode.Run(o => {
                    if (o > 128)
                    {
                        damage = (int)o;
                    }
                    else if (show_space)
                    {
                        Console.Write((char)o);
                    }
                });
                Console.WriteLine($"Damage: {damage}");
            }
        }
示例#6
0
        public static void Day17()
        {
            Console.WriteLine("Day17: ");

            long[] prog    = File.ReadAllText("Aoc2019\\Day17\\input.txt").Split(',').Select(c => long.Parse(c)).ToArray();
            var    intcode = new IntCode(prog);

            bool show_space = false;

            // part 1
            char[,] space = new char[100, 100];
            int x = 0, y = 0;
            int maxx = 0;
            int maxy = 0;

            intcode.Run(o => {
                space[x, y] = (char)o;
                if (show_space)
                {
                    Console.Write(space[x, y]);
                }
                x++;
                if (o == 10)
                {
                    maxx = Math.Max(maxx, x);
                    x    = 0;
                    y++;
                }
                else
                {
                    maxy = y;
                }
            });
            //Console.WriteLine($"{maxx} x {y}");

            // count intersections, calc aligment sum
            int sum = 0;

            for (x = 1; x < maxx - 1; x++)
            {
                for (y = 1; y < maxy - 1; y++)
                {
                    if (space[x, y] == '#' && space[x - 1, y] == '#' && space[x + 1, y] == '#' && space[x, y - 1] == '#' && space[x, y + 1] == '#')
                    {
                        sum += x * y;
                    }
                }
            }
            Console.WriteLine(sum);

            // part 2
            // figured it out manually
            // R6L12R6 R6L12R6 L12R6L8L12 R12L10L10 L12R6L8L12 R12L10L10 L12R6L8L12 R12L10L10 L12R6L8L12 R6L12R6
            // A A B C B C B C B A
            string main     = "A,A,B,C,B,C,B,C,B,A";
            string progA    = "R,6,L,12,R,6";
            string progB    = "L,12,R,6,L,8,L,12";
            string progC    = "R,12,L,10,L,10";
            string combined = $"{main}\n{progA}\n{progB}\n{progC}\nn\n";

            intcode.Reset().WriteMemory(0, 2);
            foreach (char c in combined)
            {
                intcode.Write((long)c);
            }
            long dust = 0, last = 0;

            intcode.Run(o => {
                if (last == 10 && o == 10)
                {
                    if (show_space)
                    {
                        Console.SetCursorPosition(0, Console.WindowTop);
                    }
                }
                if (show_space)
                {
                    Console.Write((char)o);
                }
                last = o;
                if (o != 10)
                {
                    dust = o;
                }
            });
            Console.WriteLine(dust);
        }
示例#7
0
        public static void Day13()
        {
            Console.WriteLine("Day13: ");

            long[] prog    = File.ReadAllText("Aoc2019\\Day13\\input.txt").Split(',').Select(c => long.Parse(c)).ToArray();
            var    intcode = new IntCode(prog);

            // part 1
            BlockingCollection <int> game = new();

            Task.Run(() => {
                intcode.Run(o => game.Add((int)o));
                game.CompleteAdding();
            });
            int num_blocks = 0;
            int max_x = 0, max_y = 0;

            while (true)
            {
                if (!game.TryTake(out int x, 10000))
                {
                    break;
                }
                int y = game.Take();
                int t = game.Take();
                max_x = Math.Max(max_x, x);
                max_y = Math.Max(max_y, y);
                if (t == 2)
                {
                    num_blocks++;
                }
            }
            Console.WriteLine(num_blocks);

            // part 2
            game = new();
            bool show_board = false;

            if (show_board)
            {
                for (int y = 0; y < Console.WindowHeight + 2; y++)
                {
                    Console.WriteLine();
                }
                Console.CursorVisible = false;
            }
            int high_score = 0;

            intcode.Reset();
            intcode.WriteMemory(0, 2); // play game
            Task.Run(() => {
                intcode.Run(o => game.Add((int)o));
                game.CompleteAdding();
            });
            bool play_manually = false;

            if (play_manually)   // play manually
            {
                Task.Run(() => {
                    while (!game.IsCompleted)
                    {
                        var k = Console.ReadKey();
                        if (k.Key == ConsoleKey.LeftArrow)
                        {
                            intcode.Write(-1);
                        }
                        else if (k.Key == ConsoleKey.RightArrow)
                        {
                            intcode.Write(1);
                        }
                        else
                        {
                            intcode.Write(0);
                        }
                    }
                });
            }
            int  last_x    = -1;
            int  paddle_x  = 0;
            bool auto_play = false;

            while (true)
            {
                if (!game.TryTake(out int x, -1))
                {
                    break;
                }
                int y = game.Take();
                int t = game.Take();
                if (x == -1)
                {
                    if (show_board)
                    {
                        Console.SetCursorPosition(0, Console.WindowTop);
                    }
                    if (show_board)
                    {
                        Console.Write("Score: " + t + "            ");
                    }
                    high_score = t;
                    continue;
                }
                if (show_board)
                {
                    Console.SetCursorPosition(x, y + Console.WindowTop + 1);
                }
                if (t == 0)
                {
                    if (show_board)
                    {
                        Console.Write(' ');
                    }
                }
                else if (t == 1)
                {
                    if (show_board)
                    {
                        Console.Write('▓');
                    }
                }
                else if (t == 2)
                {
                    if (show_board)
                    {
                        Console.Write('░');
                    }
                }
                else if (t == 3)
                {
                    if (show_board)
                    {
                        Console.Write('▀');
                    }
                    paddle_x = x;
                }
                else if (t == 4)
                {
                    if (show_board)
                    {
                        Console.Write('o');
                    }
                    if (!play_manually)
                    {
                        if (paddle_x == last_x)
                        {
                            auto_play = true;
                        }
                        if (!auto_play)
                        {
                            intcode.Write(0);
                        }
                        else if (last_x > x)
                        {
                            intcode.Write(-1);
                        }
                        else if (last_x < x)
                        {
                            intcode.Write(1);
                        }
                        last_x = x;
                        //Thread.Sleep(10);
                    }
                }
            }
            if (show_board)
            {
                Console.SetCursorPosition(0, Console.WindowTop + max_y + 2);
            }
            Console.WriteLine("Game Over!  High Score = " + high_score);
            Console.CursorVisible = true;
        }
示例#8
0
        public static void Day25()
        {
            Console.WriteLine("Day25: ");

            long[] prog    = File.ReadAllText("Aoc2019\\Day25\\input.txt").Split(',').Select(c => long.Parse(c)).ToArray();
            var    intcode = new IntCode(prog);

            // part 1
            bool play_manually = false;
            bool done          = false;

            intcode.Reset();
            List <char> line     = new List <char>();
            string      lastline = "";

            Task.Run(() => {
                intcode.Run(o => {
                    if (play_manually)
                    {
                        Console.Write((char)o);
                    }
                    else if (o == 10)
                    {
                        lastline = new string(line.ToArray());
                        line.Clear();
                    }
                    else
                    {
                        line.Add((char)o);
                    }
                });
                done = true;
            });
            if (!play_manually)
            {
                string cmds = @"north
north
north
take astrolabe
south
south
take sand
south
west
north
take shell
south
south
west
take ornament
west
south
south
";
                cmds = cmds.Trim().Replace("\r", "");
                for (int i = 0; i < cmds.Length; i++)
                {
                    intcode.Write(cmds[i]);
                }
                intcode.Write(10);
                while (!done)
                {
                    Thread.Sleep(10);
                }
                Console.WriteLine(lastline);
            }
            else
            {
                while (!done)
                {
                    var cmd = Console.ReadLine().Trim();
                    if (cmd == "n")
                    {
                        cmd = "north";
                    }
                    if (cmd == "s")
                    {
                        cmd = "south";
                    }
                    if (cmd == "e")
                    {
                        cmd = "east";
                    }
                    if (cmd == "w")
                    {
                        cmd = "west";
                    }

                    for (int i = 0; i < cmd.Length; i++)
                    {
                        intcode.Write(cmd[i]);
                    }
                    intcode.Write(10);
                }
            }
        }
示例#9
0
        public static void Day19()
        {
            Console.WriteLine("Day19: ");

            long[] prog    = File.ReadAllText("Aoc2019\\Day19\\input.txt").Split(',').Select(c => long.Parse(c)).ToArray();
            var    intcode = new IntCode(prog);

            bool IsBeam(int x, int y)
            {
                bool isBeam = false;

                intcode.Reset().Write(x).Write(y).Run(o => isBeam = (o == 1));
                return(isBeam);
            }

            // part 1
            int  x = 0, y = 0;
            long count = 0;

            for (y = 0; y < 50; y++)
            {
                for (x = 0; x < 50; x++)
                {
                    if (IsBeam(x, y))
                    {
                        count++;
                    }
                }
            }
            Console.WriteLine(count);

            // part 2
            x = 0;
            y = 100; // skip some of the start - the beam is not contiguous there
            while (true)
            {
                //Console.WriteLine($"{x},{y} = {x * 10000 + y}");
                if (!IsBeam(x, y))
                {
                    x++;
                }
                else if (!IsBeam(x + 99, y))
                {
                    y++;
                }
                else if (!IsBeam(x, y + 99))
                {
                    x++;
                }
                else if (!IsBeam(x + 99, y + 99))
                {
                    y++; // shouldn't happen!
                }
                else
                {
                    // found it
                    break;
                }
            }
            Console.WriteLine($"{x},{y} = {x * 10000 + y}");
        }
示例#10
0
        public static void Day7()
        {
            Console.WriteLine("Day7: ");

            long[] prog    = File.ReadAllText("Aoc2019\\Day07\\input.txt").Split(',').Select(c => long.Parse(c)).ToArray();
            var    intcode = new IntCode(prog);

            // part 1
            long   max_thrust = 0;
            string best       = "?";

            for (int A = 0; A <= 4; A++)
            {
                for (int B = 0; B <= 4; B++)
                {
                    for (int C = 0; C <= 4; C++)
                    {
                        for (int D = 0; D <= 4; D++)
                        {
                            for (int E = 0; E <= 4; E++)
                            {
                                if (A == B || A == C || A == D || A == E || B == C || B == D || B == E || C == D || C == E || D == E)
                                {
                                    continue;
                                }
                                Stack <long> inp    = new Stack <long>();
                                long         thrust = 0;
                                intcode.Reset().Write(A).Write(thrust).Run(o => thrust = o);
                                intcode.Reset().Write(B).Write(thrust).Run(o => thrust = o);
                                intcode.Reset().Write(C).Write(thrust).Run(o => thrust = o);
                                intcode.Reset().Write(D).Write(thrust).Run(o => thrust = o);
                                intcode.Reset().Write(E).Write(thrust).Run(o => thrust = o);
                                if (thrust > max_thrust)
                                {
                                    max_thrust = thrust;
                                    best       = $"{A}{B}{C}{D}{E}";
                                }
                            }
                        }
                    }
                }
            }
            Console.WriteLine(max_thrust);

            // part 2
            var ampA = new IntCode(prog);
            var ampB = new IntCode(prog);
            var ampC = new IntCode(prog);
            var ampD = new IntCode(prog);
            var ampE = new IntCode(prog);

            max_thrust = 0;
            for (int A = 5; A <= 9; A++)
            {
                for (int B = 5; B <= 9; B++)
                {
                    for (int C = 5; C <= 9; C++)
                    {
                        for (int D = 5; D <= 9; D++)
                        {
                            for (int E = 5; E <= 9; E++)
                            {
                                if (A == B || A == C || A == D || A == E || B == C || B == D || B == E || C == D || C == E || D == E)
                                {
                                    continue;
                                }
                                ampA.Reset().Write(A).Write(0);
                                ampB.Reset().Write(B);
                                ampC.Reset().Write(C);
                                ampD.Reset().Write(D);
                                ampE.Reset().Write(E);
                                Task.WaitAll(
                                    Task.Run(() => ampA.Run(o => ampB.Write(o))),
                                    Task.Run(() => ampB.Run(o => ampC.Write(o))),
                                    Task.Run(() => ampC.Run(o => ampD.Write(o))),
                                    Task.Run(() => ampD.Run(o => ampE.Write(o))),
                                    Task.Run(() => ampE.Run(o => ampA.Write(o))));
                                long thrust = ampA.PopInput();
                                if (thrust > max_thrust)
                                {
                                    max_thrust = thrust;
                                    best       = $"{A}{B}{C}{D}{E}";
                                }
                            }
                        }
                    }
                }
            }
            Console.WriteLine(max_thrust);
        }