題目:Advent of Code 2019 Day 5
  使用語言:C#
  
  
  第五天的題目也讓我卡很久……主體就是拿第二天寫的IntcodeProgram加功能,除了增加數字指令外,每個指令也增加了position mode和immediate mode的參數。
  但我邊寫邊試答案的時候,卻覺得不是所有指令都要判斷position mode和immediate mode,可是題目上也似乎沒有特別說明哪些不需要判斷這兩種模式,我最後也是直接用試的試出答案……
  Part1試出來之後Part2就順了。
  然後IntcodeProgram的部分一直有在思考是不是不要用switch,因為聽說後面還有要增加指令的樣子,總覺得用switch寫以程式架構的角度來說很糟,但我的進度都Delay這麼多了,也就先作罷。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
using System;
using System.Collections.Generic;
public class Program
{
	public static List<int> opCodeList = new List<int>() {1,2,3,4,5,6,7,8};
	public static int input = 5; //P2
	//public static int input = 1; //P1
	public static void Main()
	{
		// P1 Answer = 15097178
		var inputArray = new int[] {3,225,1,225,6,6,1100,1,238,225,104,0,2,106,196,224,101,-1157,224,224,4,224,102,8,223,223,1001,224,7,224,1,224,223,223,1002,144,30,224,1001,224,-1710,224,4,224,1002,223,8,223,101,1,224,224,1,224,223,223,101,82,109,224,1001,224,-111,224,4,224,102,8,223,223, 1001,224,4,224,1,223,224,223,1102,10,50,225,1102,48,24,224,1001,224,-1152,224,4,224,1002,223,8,223,101,5,224,224,1,223,224,223,1102,44,89,225, 1101,29,74,225,1101,13,59,225,1101,49,60,225,1101,89,71,224,1001,224,-160,224,4,224,1002,223,8,223,1001,224,6,224,1,223,224,223,1101,27,57,225,102,23,114,224,1001,224,-1357,224,4,224,102,8,223,223,101,5,224,224,1,224,223,223,1001,192,49,224,1001,224,-121,224,4,224,1002,223,8,223,101,3, 224,224,1,223,224,223,1102,81,72,225,1102,12,13,225,1,80,118,224,1001,224,-110,224,4,224,102,8,223,223,101,2,224,224,1,224,223,223,4,223,99,0,0, 0,677,0,0,0,0,0,0,0,0,0,0,0,1105,0,99999,1105,227,247,1105,1,99999,1005,227,99999,1005,0,256,1105,1,99999,1106,227,99999,1106,0,265,1105,1,99999,1006,0,99999,1006,227,274,1105,1,99999,1105,1,280,1105,1,99999,1,225,225,225,1101,294,0,0,105,1,0,1105,1,99999,1106,0,300,1105,1,99999,1, 225,225,225,1101,314,0,0,106,0,0,1105,1,99999,7,677,226,224,102,2,223,223,1005,224,329,101,1,223,223,108,226,226,224,102,2,223,223,1006,224,344, 101,1,223,223,1108,226,677,224,102,2,223,223,1006,224,359,1001,223,1,223,107,677,677,224,1002,223,2,223,1005,224,374,1001,223,1,223,1107,226,677,224,102,2,223,223,1005,224,389,1001,223,1,223,107,677,226,224,1002,223,2,223,1005,224,404,101,1,223,223,8,226,677,224,102,2,223,223,1005, 224,419,101,1,223,223,7,226,677,224,1002,223,2,223,1005,224,434,101,1,223,223,1007,677,677,224,102,2,223,223,1006,224,449,1001,223,1,223,107,226,226,224,1002,223,2,223,1006,224,464,1001,223,1,223,1007,226,226,224,102,2,223,223,1006,224,479,1001,223,1,223,1008,226,226,224,102,2,223, 223,1006,224,494,101,1,223,223,7,677,677,224,102,2,223,223,1005,224,509,1001,223,1,223,108,677,226,224,102,2,223,223,1005,224,524,101,1,223,223, 1108,677,226,224,1002,223,2,223,1006,224,539,101,1,223,223,1108,677,677,224,102,2,223,223,1005,224,554,101,1,223,223,8,677,226,224,102,2,223,223,1005,224,569,101,1,223,223,8,677,677,224,102,2,223,223,1005,224,584,101,1,223,223,1107,226,226,224,102,2,223,223,1006,224,599,101,1,223,223,108,677,677,224,102,2,223,223,1006,224,614,101,1,223,223,1008,677,226,224,1002,223,2,223,1005,224,629,1001,223,1,223,1107,677,226,224,102,2,223,223,1005,224,644,101,1,223,223,1008,677,677,224,1002,223,2,223,1005,224,659,101,1,223,223,1007,677,226,224,1002,223,2,223,1005,224,674,1001,223,1,223,4,223,99,226};
		//TEST
		//var inputArray = new int[] {3,21,1008,21,8,20,1005,20,22,107,8,21,20,1006,20,31,1106,0,36,98,0,0,1002,21,125,20,4,20,1105,1,46,104,999,1105,1,46,1101,1000,1,20,4,20,1105,1,46,98,99};
		var result = IntcodeProgram(inputArray);
		Console.WriteLine("Result = " + result);
	}
	public static string IntcodeProgram(int[] inputArray)
	{
		int i = 0;
		string outputValue = string.Empty;
		while(i < inputArray.Length)
		{
			var opCodeDigit =  inputArray[i];
			var opCode = opCodeDigit % 100;
			var firstValueParameterMode = opCodeDigit / 100 % 10;
			var secondValueParameterMode = opCodeDigit / 1000 % 10;
			var ouputValueParameterMode = opCodeDigit / 10000 % 10;
			if(opCode.Equals(99) || (!opCodeList.Contains(opCode))) break;
			int outputPosition = 0;
			int firstValue = 0;
			int secondValue = 0;
			firstValue = GetValue(firstValueParameterMode, inputArray[i+1], inputArray);
			if(!opCode.Equals(3) && !opCode.Equals(4))
				secondValue = GetValue(secondValueParameterMode, inputArray[i+2], inputArray);
			switch(opCode)
			{
				case 1:
					outputPosition = inputArray[i+3];
					inputArray[outputPosition] = firstValue + secondValue;
					i+=4;
					break;
				case 2:
					outputPosition = inputArray[i+3];
					inputArray[outputPosition] = firstValue * secondValue;
					i+=4;
					break;
				case 3:
					firstValue = inputArray[i+1];
					inputArray[firstValue] = input;
					i+=2;
					break;
				case 4:
					outputValue = outputValue + " " + firstValue.ToString();
					i+=2;
					break;
				case 5:
					if(!firstValue.Equals(0)) i = secondValue;
					else i+=3;
					break;
				case 6:
					if(firstValue.Equals(0)) i = secondValue;
					else i+=3;
					break;
				case 7:
					outputPosition = inputArray[i+3];
					if(firstValue < secondValue) inputArray[outputPosition] = 1;
					else inputArray[outputPosition] = 0;
					i+=4;
					break;
				case 8:
					outputPosition = inputArray[i+3];
					if(firstValue.Equals(secondValue)) inputArray[outputPosition] = 1;
					else inputArray[outputPosition] = 0;
					i+=4;
					break;
			}
		}
		return outputValue;
	}
	public static int GetValue(int mode, int value, int[] dataSource)
	{
		if(mode.Equals(0))
			return dataSource[value];
		return value;
	}
}
    
    
Comments