예제 #1
0
        static void Main(string[] args)
        {
            var map = new OrbitMap();

            Console.WriteLine(map.Part1());
            Console.WriteLine(map.Part2());
        }
예제 #2
0
        public void Example01()
        {
            // Arrange
            var input = @"COM)B
B)C
C)D
D)E
E)F
B)G
G)H
D)I
E)J
J)K
K)L";

            // Act
            var map = OrbitMap.LoadMap(input);

            // Assert
            Assert.AreEqual("COM", map.Root.Name);
            Assert.AreEqual(12, map.Orbits.Count);
            Assert.AreEqual(0, map.TotalNumberOfOrbits("COM"));
            Assert.AreEqual(3, map.TotalNumberOfOrbits("D"));
            Assert.AreEqual(7, map.TotalNumberOfOrbits("L"));
            Assert.AreEqual(42, map.TotalNumberOfOrbits());
        }
예제 #3
0
        public void TestFindMinOrbitPath(string[] inputOrbitStrings, string orbitA, string orbitB, int expected)
        {
            var map        = new OrbitMap(inputOrbitStrings);
            var mapResults = map.FindMinOrbitPath(orbitA, orbitB);

            mapResults.Should().Be(expected);
        }
예제 #4
0
        public void TestRootOnlyChecksum()
        {
            OrbitMap om       = new OrbitMap();
            int      checksum = om.GetChecksum();

            Assert.That(checksum, Is.EqualTo(0));
        }
예제 #5
0
 public void Builds_a_map_of_planets_from_input()
 {
     using (var sr = new StreamReader(TestContext.CurrentContext.TestDirectory + "\\TestData\\day6.unit.txt"))
     {
         var map = new OrbitMap(sr);
         Assert.That(map.TotalOrbits(), Is.EqualTo(42));
     }
 }
예제 #6
0
        public void Example2_CountsHopsCorrectly()
        {
            var orbits = Input.Day06Parse(Example2);

            var map = new OrbitMap(orbits);

            map.GetHopsBetween("SAN", "YOU").Should().Be(4);
        }
예제 #7
0
        public void Puzzle2_CountsHopsBetweenYOUAndSAN()
        {
            var orbits = Input.Day06Parse(Input.Day06);

            var map = new OrbitMap(orbits);

            map.GetHopsBetween("SAN", "YOU").Should().Be(286);
        }
예제 #8
0
        public void Puzzle1_CountConnections()
        {
            var orbits = Input.Day06Parse(Input.Day06);

            var map = new OrbitMap(orbits);

            map.Connections.Should().Be(139597);
        }
예제 #9
0
 public void Calculates_transfer_from_one_planet_to_another()
 {
     using (var sr = new StreamReader(TestContext.CurrentContext.TestDirectory + "\\TestData\\day6.unit.txt"))
     {
         var map = new OrbitMap(sr);
         Assert.That(map.GetTransferCount("K", "I"), Is.EqualTo(4));
     }
 }
예제 #10
0
        public void Direct_Satellite_To_COM_Equals_1()
        {
            var sut = new OrbitMap();

            sut.AddOrbit("COM", "AAA");

            Assert.Equal(1, sut.Checksum("AAA"));
        }
예제 #11
0
 public void Part_one_solution()
 {
     using (var sr = new StreamReader(TestContext.CurrentContext.TestDirectory + "\\TestData\\Day6.txt"))
     {
         var map = new OrbitMap(sr);
         Assert.That(map.TotalOrbits(), Is.EqualTo(453028));
     }
 }
예제 #12
0
        public void TestOrbits(IEnumerable <string> relations, int expectedOrbits)
        {
            var map = new OrbitMap(relations);

            var orbits = map.GetNumberOfOrbits();

            Assert.IsTrue(orbits == expectedOrbits);
        }
예제 #13
0
        public void TestFindPlanetFromOrbit(string[] inputOrbitStrings, string inputPlanet, string expected)
        {
            var map = new OrbitMap(inputOrbitStrings);

            var mapResults = map.FindPlanetFromOrbit(inputPlanet);

            mapResults.Should().Equals(expected);
        }
예제 #14
0
 public void Part_two_solution()
 {
     using (var sr = new StreamReader(TestContext.CurrentContext.TestDirectory + "\\TestData\\Day6.txt"))
     {
         var map = new OrbitMap(sr);
         Assert.That(map.GetTransferCount("YOU", "SAN") - 2, Is.EqualTo(562));
     }
 }
예제 #15
0
        public void TestBuildMap(string[] inputOrbitStrings)
        {
            var map = new OrbitMap(inputOrbitStrings);

            map.PrintMap();
            Console.WriteLine($"DirectOrbitCount: {map.DirectOrbitCount()}");
            Console.WriteLine($"IndirectOrbitCount: {map.TotalOrbitCount()}");
        }
예제 #16
0
        public void COM_CheckSum_WithSatellite_Equals_0()
        {
            var sut = new OrbitMap();

            sut.AddOrbit("COM", "AAA");

            Assert.Equal(0, sut.Checksum("COM"));
        }
예제 #17
0
        public string SolvePartTwo(string[] input)
        {
            List <string[]> orbits = input.Select(x => x.Split(")")).ToList();
            OrbitMap        om     = new OrbitMap();

            om = PopulateOrbitMap("COM", om, orbits);

            return(om.GetOrbitalDistance("YOU", "SAN").ToString());
        }
예제 #18
0
        public void Example1_MapsOrbitsCorrectly()
        {
            var orbits = Input.Day06Parse(Example1);

            var map = new OrbitMap(orbits);

            map.Should().HaveCount(12);
            map.Connections.Should().Be(42);
        }
예제 #19
0
        public void TestNavigation(IEnumerable <string> relations, int expectedTransfers, string from, string to)
        {
            var map  = new OrbitMap(relations);
            var objA = map.SpaceObjects.FirstOrDefault(so => so.Id == from);
            var objB = map.SpaceObjects.FirstOrDefault(so => so.Id == to);

            var(transfers, path) = objA.GetTransfersToReach(objB);
            Assert.IsTrue(transfers == expectedTransfers);
        }
예제 #20
0
        public string SolvePartOne(string[] input)
        {
            List <string[]> orbits = input.Select(x => x.Split(")")).ToList();
            OrbitMap        om     = new OrbitMap();

            om = PopulateOrbitMap("COM", om, orbits);

            return(om.GetChecksum().ToString());
        }
예제 #21
0
        public void One_LevelIndirect_To_COM_Equals_2()
        {
            var sut = new OrbitMap();

            sut.AddOrbit("COM", "AAA");
            sut.AddOrbit("AAA", "BBB");

            Assert.Equal(2, sut.Checksum("BBB"));
        }
예제 #22
0
        public void Part1()
        {
            string[] input = new string[] { "COM)BBB", "BBB)CCC", "CCC)DDD", "DDD)EEE", "EEE)FFF", "BBB)GGG", "GGG)HHH", "DDD)III", "EEE)JJJ", "JJJ)KKK", "KKK)LLL" };
            var      map   = new OrbitMap(input);

            int count = map.CountAllOrbits();

            Assert.Equal(42, count);
        }
예제 #23
0
        public void SolvePart1()
        {
            string[] input = System.IO.File.ReadAllLines("../../../input/day_06.txt");
            var      map   = new OrbitMap(input);

            int count = map.CountAllOrbits();

            Assert.Equal(387356, count);
        }
예제 #24
0
        public void TestAddDirectOrbit()
        {
            OrbitMap om = new OrbitMap();

            Assert.That(om.AddOrbit("COM", "A"), Is.EqualTo(true));

            int checksum = om.GetChecksum();

            Assert.That(checksum, Is.EqualTo(1));
        }
예제 #25
0
        public void Order_Of_Adding_Orbits_Doesnt_Affect_Checksum()
        {
            var sut = new OrbitMap();

            sut.AddOrbit("BBB", "CCC");
            sut.AddOrbit("AAA", "BBB");
            sut.AddOrbit("COM", "AAA");

            Assert.Equal(3, sut.Checksum("CCC"));
        }
예제 #26
0
        public void Two_Level_Indirect_To_COM_Equals_3()
        {
            var sut = new OrbitMap();

            sut.AddOrbit("COM", "AAA");
            sut.AddOrbit("AAA", "BBB");
            sut.AddOrbit("BBB", "CCC");

            Assert.Equal(3, sut.Checksum("CCC"));
        }
예제 #27
0
        public void TestAddIndirectOrbit()
        {
            OrbitMap om = new OrbitMap();

            Assert.That(om.AddOrbit("COM", "A"), Is.EqualTo(true));
            Assert.That(om.AddOrbit("A", "B"), Is.EqualTo(true));
            Assert.That(om.AddOrbit("NOTFOUND", "B"), Is.EqualTo(false));

            int checksum = om.GetChecksum();

            Assert.That(checksum, Is.EqualTo(3));
        }
예제 #28
0
        private OrbitMap PopulateOrbitMap(string oName, OrbitMap om, List <string[]> orbits)
        {
            List <string[]> availableOrbits = orbits.Where(x => oName == x[0]).ToList();

            foreach (string[] orbit in availableOrbits)
            {
                om.AddOrbit(orbit[0], orbit[1]);
                PopulateOrbitMap(orbit[1], om, orbits);
                orbits.Remove(orbit);
            }

            return(om);
        }
예제 #29
0
        public void TestGetOrbitalDistance()
        {
            OrbitMap om = new OrbitMap();

            Assert.That(om.AddOrbit("COM", "A"), Is.EqualTo(true));
            Assert.That(om.AddOrbit("A", "B"), Is.EqualTo(true));
            Assert.That(om.AddOrbit("B", "C"), Is.EqualTo(true));
            Assert.That(om.AddOrbit("C", "START"), Is.EqualTo(true));
            Assert.That(om.AddOrbit("A", "END"), Is.EqualTo(true));

            Assert.That(om.GetOrbitalDistance("START", "END"), Is.EqualTo(2));
            Assert.That(om.GetOrbitalDistance("END", "START"), Is.EqualTo(2));
        }
예제 #30
0
        public void OrbitMapBuildsCorrectly()
        {
            // Arrange
            var orbits   = new[] { "COM)B", "B)C", "C)D", "D)E", "E)F", "B)G", "G)H", "D)I", "E)J", "J)K", "K)L" };
            var orbitMap = new OrbitMap();

            // Act
            orbitMap.Build(orbits);

            // Assert
            orbitMap.CenterOfMass.ShouldNotBeNull();
            orbitMap.CenterOfMass.Name.ShouldBe("COM");
            orbitMap.OrbitChecksum.ShouldBe(42);
        }
        public override OrbitMap Calculate(CalculationOptions options)
        {
            // Needs finetuning - a fast internet connection would benefit from smaller tasks (better utilization of computing cores),
            // but a slow one might become too slow from the overhead
            Queue<CalculationOptions> tasks = new Queue<CalculationOptions>(RenderTaskHelper.Split(options, 8 * HostSelector.EffectiveWorkers));

            OrbitMap full = new OrbitMap();
            List<RendererConnection> connections = new List<RendererConnection>();

            while (tasks.Count > 0) // While there are still tasks left
            {
                // Distribute tasks to available renderers
                DistributeTasks(HostSelector, tasks, connections);

                // While we have running render tasks
                while (connections.Count > 0)
                {
                    // Wait for one task to finish
                    WaitHandle[] handles = connections.Select(c => c.WaitHandle).ToArray();
                    int h = WaitHandle.WaitAny(handles);

                    RendererConnection conn = connections[h];
                    connections.RemoveAt(h);

                    HostSelector.ConnectionCompleted(conn);

                    if (conn.Success)
                    {
                        // If it was a success, extend the OrbitMap with these results
                        full.Extend(conn.Result);
                    }
                    else
                    {
                        // TODO error handling, retry?
                        tasks.Enqueue(conn.Task);             // Re-enqueue it until it succeeds (maybe have to do something about that)
                    }

                    // Got an available renderer - fill it with a task
                    DistributeTasks(HostSelector, tasks, connections);
                }
            }
            return full; // Return the combined orbit map
        }
예제 #32
0
        public unsafe override Bitmap DrawBitmap(OrbitMap m, RenderOptions rp, CalculationOptions co, Constraints[] orbitConstraints)
        {
            Bitmap b = new Bitmap(rp.CanvasWidth, rp.CanvasHeight, PixelFormat.Format32bppRgb);
            BitmapData bd = b.LockBits(new Rectangle(0, 0, rp.CanvasWidth, rp.CanvasHeight), ImageLockMode.ReadWrite, PixelFormat.Format32bppRgb);

            uint maxIter = m.Max(o => o.Iterations);

            uint* pixels = (uint*)bd.Scan0.ToPointer();
            foreach (Orbit o in m)
            {
                if (o.X >= 0 && o.X < b.Width &&
                    o.Y >= 0 && o.Y < b.Height)
                {
                    uint gray = ColorFunc(o.Iterations, co.IterationCount);

                    pixels[o.Y * bd.Stride / 4 + o.X] = (gray << 24) | (gray << 16) | (gray << 8) | gray;
                }
            }

            b.UnlockBits(bd);
            return b;
        }
예제 #33
0
        public override Bitmap DrawBitmap(OrbitMap m, RenderOptions rp, CalculationOptions co, Constraints[] orbitConstraints)
        {
            Bitmap b = new Bitmap(rp.CanvasWidth, rp.CanvasHeight, PixelFormat.Format32bppRgb);
            BitmapData bd = b.LockBits(new Rectangle(0, 0, rp.CanvasWidth, rp.CanvasHeight), ImageLockMode.ReadWrite, PixelFormat.Format32bppRgb);

            uint maxIter = m.Max(o => o.Iterations);

            foreach (Orbit o in m)
            {
                if (o.X >= 0 && o.X < b.Width &&
                    o.Y >= 0 && o.Y < b.Height)
                {
                    uint gray = ColorFunc(o.Iterations, co.IterationCount);

                    Marshal.WriteInt32(bd.Scan0 + o.Y * bd.Stride + o.X * 4,
                                       unchecked((int)((gray << 24) | (gray << 16) | (gray << 8) | gray)));
                }
            }

            b.UnlockBits(bd);
            return b;
        }
예제 #34
0
        private void Work(object arg)
        {
            CalculationOptions opt = arg as CalculationOptions;
            NetworkStream ns = null;
            Success = false;
            try
            {
                ns = TcpHelper.OpenStream(Host, 1);

                byte[] magic = new byte[4];
                ns.Read(magic, 0, 4);
                uint v = BitConverter.ToUInt32(magic, 0);

                bool be = (v == 0xAFDE0000); // Renderer sends 00 00 DE AF, if its reversed all is in big endian

                EndianBitConverter ec;
                if (be) ec = new BigEndianBitConverter();
                else ec = new LittleEndianBitConverter();

                using (EndianBinaryWriter bw = new EndianBinaryWriter(ec, ns))
                using (EndianBinaryReader br = new EndianBinaryReader(ec, ns))
                {
                    bw.Write((uint)0x0000FEED);

                    // Write rational coordinates
                    foreach (BigRational r in new[] { opt.MinRe, opt.MaxRe, opt.MinIm, opt.MaxIm })
                    {
                        int sign = r.Numerator.Sign;
                        byte[] num = BigInteger.Abs(r.Numerator).ToByteArray();
                        bw.Write(sign);
                        bw.Write(num.Length);
                        bw.Write(num);

                        num = BigInteger.Abs(r.Denominator).ToByteArray();
                        bw.Write(num.Length);
                        bw.Write(num);
                    }
                    bw.Write(opt.IterationCount);
                    bw.Write(opt.Width);
                    bw.Write(opt.Height);
                    bw.Write(opt.XOff);
                    bw.Write(opt.XSkip);
                    bw.Write(opt.XMax);
                    bw.Write(opt.YOff);
                    bw.Write(opt.YSkip);
                    bw.Write(opt.YMax);
                    bw.Write(opt.OrbitStart);
                    bw.Write(opt.OrbitLength);
                    bw.Write(opt.BulbChecking ? 1U : 0U);

                    int ok = br.ReadInt32();
                    if (ok != 200)
                        throw new InvalidOperationException();  // TODO Proper exception

                    // Sent parameters, now read all orbits
                    OrbitMap map = new OrbitMap();

                    int orbitsComing = 0;
                    while ((orbitsComing = br.ReadInt32()) >= 0)
                    {
                        for (int i = 0; i < orbitsComing; i++)
                        {
                            int o_x = br.ReadInt32();
                            int o_y = br.ReadInt32();

                            BigRational re, im;
                            re = ReadRational(br);
                            im = ReadRational(br);
                            BigComplex o_c = new BigComplex(re, im);

                            uint o_iter = br.ReadUInt32(); // Number of iterations before escape
                            uint o_orbs = br.ReadUInt32(); // Offset of the orbit
                            uint o_orbl = br.ReadUInt32(); // Length of the orbit

                            Orbit orbit = new Orbit(o_x, o_y, o_c, o_iter, o_orbs, o_orbl);

                            for (uint j = 0; j < o_orbl; j++)
                            {
                                re = ReadRational(br);
                                im = ReadRational(br);
                                orbit.Add(re, im);
                            }

                            map.AddOrbit(orbit);
                        }
                    }

                    Result = map; // Set the result so it can be combined with work from the other threads
                }

                ns.Close();
                Success = true;
            }
            catch (Exception) // TODO error handling ? Just log the message and be done
            {
                Success = false;
            }
            finally
            {
                if (ns != null)
                    ns.Close();

                (WaitHandle as ManualResetEvent).Set(); // Public signal that I'm done
            }
        }
예제 #35
0
 public abstract Bitmap DrawBitmap(OrbitMap m, RenderOptions rp, CalculationOptions co, Constraints[] orbitConstraints);