Glærferyn 6 年之前
父節點
當前提交
9898941ee8
共有 5 個文件被更改,包括 197 次插入3 次删除
  1. 8 2
      Adv2018.sln
  2. 1 1
      D16.1/Properties/launchSettings.json
  3. 9 0
      D16.2/D16.2.csproj
  4. 171 0
      D16.2/Program.cs
  5. 8 0
      D16.2/Properties/launchSettings.json

+ 8 - 2
Adv2018.sln

@@ -65,9 +65,11 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "D14.2", "D14.2\D14.2.csproj
 EndProject
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "D15.1", "D15.1\D15.1.csproj", "{2D30E380-C7F1-4F28-B4E8-7BE19430C6F1}"
 EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "D15.2", "D15.2\D15.2.csproj", "{B3178FFF-996C-4876-96A1-68DA9590A7D3}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "D15.2", "D15.2\D15.2.csproj", "{B3178FFF-996C-4876-96A1-68DA9590A7D3}"
 EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "D16.1", "D16.1\D16.1.csproj", "{12EF2505-6012-4829-B24A-9BD683915DBC}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "D16.1", "D16.1\D16.1.csproj", "{12EF2505-6012-4829-B24A-9BD683915DBC}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "D16.2", "D16.2\D16.2.csproj", "{DE1A36E4-F467-4345-BB97-93E2A1F2B186}"
 EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -207,6 +209,10 @@ Global
 		{12EF2505-6012-4829-B24A-9BD683915DBC}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{12EF2505-6012-4829-B24A-9BD683915DBC}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{12EF2505-6012-4829-B24A-9BD683915DBC}.Release|Any CPU.Build.0 = Release|Any CPU
+		{DE1A36E4-F467-4345-BB97-93E2A1F2B186}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{DE1A36E4-F467-4345-BB97-93E2A1F2B186}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{DE1A36E4-F467-4345-BB97-93E2A1F2B186}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{DE1A36E4-F467-4345-BB97-93E2A1F2B186}.Release|Any CPU.Build.0 = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE

+ 1 - 1
D16.1/Properties/launchSettings.json

@@ -2,7 +2,7 @@
   "profiles": {
     "D16.1": {
       "commandName": "Project",
-      "commandLineArgs": "\"D:\\adv\\Adv2018\\D16.1\\input.txt\" "
+      "commandLineArgs": "\"..\\..\\..\\..\\D16.1\\input.txt\" "
     }
   }
 }

+ 9 - 0
D16.2/D16.2.csproj

@@ -0,0 +1,9 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>
+    <OutputType>Exe</OutputType>
+    <TargetFramework>netcoreapp2.1</TargetFramework>
+    <RootNamespace>D16._2</RootNamespace>
+  </PropertyGroup>
+
+</Project>

+ 171 - 0
D16.2/Program.cs

@@ -0,0 +1,171 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+
+namespace D16._2
+{
+    public class Computer
+    {
+        public ProcessUnit CPU { get; private set; }
+
+        public Computer() => CPU = new ProcessUnit();
+
+        public class ProcessUnit
+        {
+            public delegate void OpCode(ushort a, ushort b, ushort c);
+
+            public Register[] Registers = new Register[4] { 0, 0, 0, 0 };
+
+            public (string name, OpCode op)[] OpCodes;
+
+            public void SetRegisters(ushort[] registers)
+            {
+                for (var i = 0; i < Registers.Length; ++i)
+                    Registers[i] = registers[i];
+            }
+
+            public ProcessUnit()
+            {
+                OpCodes = new (string, OpCode)[]
+                {
+                    ("addr", (a, b, c) => { Registers[c] = Registers[a] + Registers[b]; }),
+                    ("addi", (a, b, c) => { Registers[c] = Registers[a] + b; }),
+                    ("mulr", (a, b, c) => { Registers[c] = Registers[a] * Registers[b]; }),
+                    ("muli", (a, b, c) => { Registers[c] = Registers[a] * b; }),
+                    ("banr", (a, b, c) => { Registers[c] = Registers[a] & Registers[b]; }),
+                    ("bani", (a, b, c) => { Registers[c] = Registers[a] & b; }),
+                    ("borr", (a, b, c) => { Registers[c] = Registers[a] | Registers[b]; }),
+                    ("bori", (a, b, c) => { Registers[c] = Registers[a] | b; }),
+                    ("setr", (a, b, c) => { Registers[c] = Registers[a]; }),
+                    ("seti", (a, b, c) => { Registers[c] = a; }),
+                    ("gtir", (a, b, c) => { Registers[c] = a > Registers[b] ? 1 : 0; }),
+                    ("gtri", (a, b, c) => { Registers[c] = Registers[a] > b ? 1 : 0; }),
+                    ("gtrr", (a, b, c) => { Registers[c] = Registers[a] > Registers[b] ? 1 : 0; }),
+                    ("eqir", (a, b, c) => { Registers[c] = a == Registers[b] ? 1 : 0; }),
+                    ("eqri", (a, b, c) => { Registers[c] = Registers[a] == b ? 1 : 0; }),
+                    ("eqrr", (a, b, c) => { Registers[c] = Registers[a] == Registers[b] ? 1 : 0; }),
+                };
+            }
+
+            public class Register
+            {
+                public ushort Value { get; private set; }
+
+                public Register() { }
+                public Register(ushort value) => Value = value;
+
+                public static implicit operator Register(ushort a) => new Register { Value = a };
+                public static implicit operator ushort(Register a) => a.Value;
+                public static implicit operator Register(int a) => new Register { Value = (ushort)a };
+                public static bool operator >(Register a, Register b) => a.Value > b.Value;
+                public static bool operator <(Register a, Register b) => a.Value < b.Value;
+                public static bool operator ==(Register a, Register b) => a.Value == b.Value;
+                public static bool operator !=(Register a, Register b) => a.Value != b.Value;
+
+                public override bool Equals(object obj)
+                {
+                    var register = obj as Register;
+                    return register is null == false &&
+                           Value == register.Value;
+                }
+
+                public override int GetHashCode() => HashCode.Combine(Value);
+            }
+        }
+    }
+
+    class Program
+    {
+        static void Main(string[] args)
+        {
+            if (args.Length < 1) return;
+            if (File.Exists(args[0]) == false) return;
+            var file = File.OpenText(args[0]);
+
+            var pc = new Computer();
+
+            var candidates = new Dictionary<int, List<int>>();
+            for (int i = 0; i < pc.CPU.OpCodes.Length; ++i)
+                candidates.Add(i, new List<int>() { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 });
+
+            bool prevIsBlank = false;
+            do
+            {
+                var line = file.ReadLine();
+                if (line == null) break;
+
+                if (line == string.Empty || line.StartsWith("//"))
+                {
+                    if (prevIsBlank) break;
+                    prevIsBlank = true;
+                    continue;
+                }
+                else prevIsBlank = false;
+
+                string before = line;
+                string op = file.ReadLine();
+                string after = file.ReadLine();
+
+                var regBefore = before.Substring(9, before.Length - 10).Split(", ").Select(s => ushort.Parse(s)).ToArray();
+                var regAfter = after.Substring(9, after.Length - 10).Split(", ").Select(s => new Computer.ProcessUnit.Register(ushort.Parse(s))).ToArray();
+                var opParams = op.Split(" ").Select(s => ushort.Parse(s)).ToArray();
+
+                var opCodeId = 0;
+                foreach (var opc in pc.CPU.OpCodes)
+                {
+                    pc.CPU.SetRegisters(regBefore);
+
+                    opc.op(opParams[1], opParams[2], opParams[3]);
+
+                    bool isSame = pc.CPU.Registers[3] == regAfter[3];
+                    if (!isSame)
+                    {
+                        var testedOpCode = opParams[0];
+                        candidates[testedOpCode].Remove(opCodeId);
+                    }
+
+                    opCodeId++;
+                }
+            } while (true);
+
+            var opConversion = new Dictionary<int, int>();
+            while (opConversion.Count < 16)
+            {
+                var first = candidates.First(c => c.Value.Count == 1);
+                var value = first.Value[0];
+
+                foreach (var c in candidates) c.Value.Remove(value);
+
+                opConversion.Add(first.Key, value); 
+                candidates.Remove(first.Key);
+            }
+
+            pc.CPU.SetRegisters(new ushort[] { 0, 0, 0, 0 });
+
+            Console.WriteLine($"[ { string.Join(", ", pc.CPU.Registers.Select(r => r.Value)) } ]");
+            Console.WriteLine("==== EXECUTING PROGRAM ===");
+
+            do
+            {
+                var line = file.ReadLine();
+                if (line == null) break;
+
+                if (line == string.Empty) continue;
+
+                var opParams = line.Split(" ").Select(s => ushort.Parse(s)).ToArray();
+
+                var op = opConversion[opParams[0]];
+                var opc = pc.CPU.OpCodes[op];
+
+                Console.WriteLine($"{opc.name} {string.Join(" ", opParams.Skip(1))}");
+
+                opc.op(opParams[1], opParams[2], opParams[3]);
+
+            } while (true);
+
+            Console.WriteLine("=== PROGRAM ENDED ===");
+            Console.WriteLine($"[ { string.Join(", ", pc.CPU.Registers.Select(r => r.Value)) } ]");
+        }
+    }
+}

+ 8 - 0
D16.2/Properties/launchSettings.json

@@ -0,0 +1,8 @@
+{
+  "profiles": {
+    "D16.2": {
+      "commandName": "Project",
+      "commandLineArgs": "\"..\\..\\..\\..\\D16.1\\input.txt\" "
+    }
+  }
+}