Advertisement
eltea

Advent of Code Day 09 Parts 1 and 2

Dec 10th, 2020 (edited)
215
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 4.39 KB | None | 0 0
  1. //Advent of Code 2020 Day 9 Parts 1 and 2 solution by Mike LeSauvage
  2. public class XMASAttacker : MonoBehaviour
  3. {
  4.     [SerializeField] TextAsset XMASCode = null;   //Hooked up in the input text in the Unity editor.
  5.     [SerializeField] int PREAMBLE_LEN = 25;       //The portion of the numbers identified in the challenge as the preamble; change for testing smaller sample sets.
  6.  
  7.     // Start is a Unity method called once per program execution.
  8.     void Start()
  9.     {
  10.         string[] data = XMASCode.text.Split('\n');
  11.  
  12.         //Part One
  13.         long invalidNum = FindInvalidNumber(data);
  14.         Debug.Log($"The first number encountered that is not the sum of two preceeding {PREAMBLE_LEN} numbers is: {invalidNum}");
  15.  
  16.         //Part Two
  17.         long encryptionWeakness =  FindEncryptionWeakness(data, invalidNum);
  18.         Debug.Log($"Encryption Weakness: {encryptionWeakness}");
  19.     }
  20.  
  21.     // Working backwards through the list *should* be faster as with smaller numbers the sums should fail faster.
  22.     // Sum numbers until the target is met or exceeded.
  23.     // Once the range is found, add all numbers making the sum to a list; sort the list; add the smallest and largest
  24.     //   numbers to find the encryption weakness.
  25.     long FindEncryptionWeakness(string[] data, long targetSum)
  26.     {
  27.         for(int i=data.Length-1; i>=1; i--) //Outer loop.
  28.         {
  29.             long sum = 0;
  30.  
  31.             for(int j=i; j>=0; j--)  //Inner loop starts where the outer loop is pointing and works from there to the start.
  32.             {
  33.                 sum += long.Parse(data[j]);
  34.  
  35.                 if(sum > targetSum) //If we exceed the target move on to the next position in the data to check.
  36.                 {
  37.                     break;
  38.                 }
  39.                 else if (sum == targetSum) //Found the target (with one exception, see next)
  40.                 {
  41.                     //Only one number made the sum (it was the targetSum), which is not a vlid answer.
  42.                     if(i==j)
  43.                     {
  44.                         break;
  45.                     }
  46.  
  47.                     //Add the numbers that make the sum to a list so they can be sorted.
  48.                     List<long> numbersInSum = new List<long>();
  49.                     int start = j;
  50.                     int end = i;
  51.  
  52.                     for (int k=start; k<=end; k++)
  53.                     {
  54.                         numbersInSum.Add(long.Parse(data[k]));
  55.                     }
  56.  
  57.                     numbersInSum.Sort();
  58.  
  59.                     return numbersInSum[0] + numbersInSum[numbersInSum.Count - 1];
  60.                 }
  61.             }
  62.         }
  63.  
  64.         return -1; //Error condition.
  65.     }
  66.  
  67.  
  68.     //Core of part one solution.
  69.     long FindInvalidNumber(string[] data)
  70.     {
  71.         for (int i = PREAMBLE_LEN; i < data.Length; i++) //Loop through the data past the preamble.
  72.         {
  73.             long currentData = long.Parse(data[i]);
  74.             bool sumFound = false;
  75.  
  76.             //Loop across a preamble-sized chunk of data prior to the current data
  77.             //looking for two numbers that sum to the current data.
  78.             for (int checkIndexOuter = i - PREAMBLE_LEN; checkIndexOuter < i - 1; checkIndexOuter++)
  79.             {
  80.                 long outerNum = long.Parse(data[checkIndexOuter]);
  81.  
  82.                 for (int checkIndexInner = checkIndexOuter + 1; checkIndexInner < i; checkIndexInner++)
  83.                 {
  84.                     long innerNum = long.Parse(data[checkIndexInner]);
  85.                     long sum = outerNum + innerNum;
  86.  
  87.                     //If the sum adds up, no need to continue the loop. Break out of the inner loop.
  88.                     if (sum == currentData)
  89.                     {
  90.                         sumFound = true;
  91.                         break;
  92.                     }
  93.  
  94.                 }
  95.  
  96.                 //Sum found, break out of the outer loop so the algorithm can inspect the next piece of data.
  97.                 if(sumFound)
  98.                 {
  99.                     break;
  100.                 }
  101.  
  102.             }
  103.  
  104.             //The outer/inner loop did not find a sum that matches the current data point, so return with its value.
  105.             if (!sumFound)
  106.             {
  107.                 return long.Parse(data[i]);
  108.             }
  109.         }
  110.  
  111.         return -1; //Error condition as we're expecting to find a match. (Assumes data set did not include negative numbers).
  112.  
  113.     }
  114. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement