Equd

AOC 2020 Day 08

Dec 8th, 2020
740
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 3.13 KB | None | 0 0
  1. #load "xunit"
  2. #load "..\AOC Connector"
  3. #load "..\AOC 2d Array"
  4.  
  5. void Main()
  6. {  
  7.     RunTests();  // Call RunTests() or press Alt+Shift+T to initiate testing.
  8.  
  9.     //get aoc data
  10.     var aoc = new AdventOfCode(2020, 8);   
  11.            
  12.     //solve A  
  13.     aoc.SubmitAnswer(SolveA(aoc.InputLines), Part.A);
  14.    
  15.     //solve B
  16.     aoc.SubmitAnswer(SolveB(aoc.InputLines), Part.B);
  17. }
  18.  
  19. public int SolveA(string[] input = null)
  20. {
  21.     //create and run game
  22.     var game = new GameBoy(input); 
  23.     game.Go();     
  24.     //answer
  25.     return game.Accumulator;
  26. }
  27.  
  28. public int SolveB(string[] input)
  29. {
  30.     var game = new GameBoy(input);
  31.  
  32.     for (int i = 0; i < game.Program.Count; i++)
  33.     {
  34.         var step = game.Program[i];
  35.         if(step.instruction is Argument.nop or Argument.jmp)
  36.         {
  37.            
  38.                 //switch the instruction
  39.                 game.Program[i] = (step.instruction == Argument.jmp ? Argument.nop : Argument.jmp, step.value);
  40.                
  41.                 //run the program
  42.                 if(game.Go())                              
  43.                     return game.Accumulator; //SUCCES
  44.                
  45.                 //restore the old instruction  
  46.                 game.Program[i] = step;            
  47.         }
  48.     }
  49.     throw new Exception("Nothing found");  
  50. }
  51.  
  52. public enum Argument
  53. {
  54.     nop, acc, jmp
  55. }
  56.  
  57.  
  58. public class GameBoy
  59. {
  60.     /// <summary> Contains all the steps in the program </summary>
  61.     public List<(Argument instruction, int value)> Program;
  62.  
  63.     public int StepsDoneCounter  {get; private set;}
  64.     public int Accumulator {get; private set;}
  65.     public int ProgramPosition  {get; private set;}
  66.  
  67.     /// <summary> Constructor </summary>
  68.     public GameBoy(string[] lines)
  69.     {
  70.         this.Program = lines
  71.             .Select(x => x.Split(' ', StringSplitOptions.RemoveEmptyEntries)) //split entries and remove empty
  72.             .Select(x=> ((Argument)Enum.Parse(typeof(Argument), x[0]), int.Parse(x[1]))) //create instruction
  73.             .ToList();
  74.     }
  75.    
  76.     /// <summary> Track seen items </summary>
  77.     HashSet<int > StepsSeen = new HashSet<int>();
  78.    
  79.     public bool Go()
  80.     {
  81.         //remove seen
  82.         StepsSeen.Clear();
  83.        
  84.         //create counters
  85.         StepsDoneCounter = 0;
  86.         Accumulator = 0;
  87.         ProgramPosition = 0;
  88.        
  89.         //loop through the program
  90.         while(ProgramPosition < this.Program.Count)
  91.         {                      
  92.             StepsDoneCounter++;
  93.            
  94.             var step = Program[ProgramPosition];
  95.             //$"[{stepsDoneCounter:D3}] [{position:D2}] {step.instruction} {step.value}".Dump();
  96.  
  97.             //check if we havent seen this address before
  98.             if (StepsSeen.Contains(ProgramPosition))
  99.             {
  100.                 //finished in a infinite loop
  101.                 return false;
  102.             }
  103.             StepsSeen.Add(ProgramPosition);
  104.            
  105.             //what todo
  106.             switch (step.instruction)
  107.             {
  108.                 case Argument.acc: Accumulator += step.value; break;
  109.                 case Argument.jmp: ProgramPosition += step.value; continue;
  110.                 case Argument.nop: break;
  111.             }
  112.             //next instruction
  113.             ProgramPosition++;
  114.         }
  115.         //finished properly
  116.         return true;
  117.     }
  118. }
  119.  
  120. #region private::Tests
  121. #region test data
  122. string[] testData = new []
  123. {
  124. "nop +0",
  125. "acc +1",
  126. "jmp +4",
  127. "acc +3",
  128. "jmp -3",
  129. "acc -99",
  130. "acc +1",
  131. "jmp -4",
  132. "acc +6",
  133. };
  134.  
  135. #endregion
  136. //tests
  137. [Fact] void TestA1() => Assert.Equal(005, SolveA(testData));
  138. [Fact] void TestB1() => Assert.Equal(008, SolveB(testData));
  139. //[Fact] void TestB2() => Assert.Equal(126, SolveB(testdata2));
  140. #endregion
  141.  
  142.  
  143.  
Advertisement
Add Comment
Please, Sign In to add comment