DEV Community

Cover image for Advent Of Code 2023: Day 1 - Trebuchet
Grant Riordan
Grant Riordan

Posted on

Advent Of Code 2023: Day 1 - Trebuchet

Day 1 - Trebuchet

link

Simply put, this challenge requires the developer to retrieve numbers from lines of text, and then add up all the numbers from each line to get a total.

Part 1 was fairly straightforward. Select all the digits from within the text. This can easily be done via the LINQ Select method, and passing it a method which checks whether the current character is a digit and, if so returns it.

Once we have this, it's just a case of selecting the first and last items in the array, as we always know there will be more than 1 digit based on the challenge instructions.

Part 2 however had me pulling my hair out for a little while, as this was sneakily more complicated. I began by simply pulling out the text and numeric values using a lookup. However, this did not work due to there being overlap between numbers (text version), e.g. 'eightwo' etc.

To resolve simply replace the matched numbers (in text) format with their digit counterpart, prefixed and suffixed with their text format. This removes any cross over / overlap of words. It's a bit of a hacky solution, but it is one that worked for me (and others it seems online too).


Solution: Available also at my Github link to Day 1

using System.Runtime.ExceptionServices;
using System.Text;
using System.Text.RegularExpressions;

string FILE_PATH = "./final_input.txt";

Dictionary<string, string> translations = new(){
      {"one", "one1one"},
      {"two", "two2two"},
      {"three", "three3three"},
      {"four", "four4four"},
      {"five", "five5five"},
      {"six", "six6six"},
      {"seven", "seven7seven"},
      {"eight", "eight8eight"},
      {"nine", "nine9nine"}
    };

string OnlyNumerics(string strInput)
{
  StringBuilder builder = new();
  foreach (char ch in strInput)
  {
    if (char.IsDigit(ch)) builder.Append(ch);
  }
  return builder.ToString();
}

string ReplaceNumbers(string original)
{
  foreach (var key in translations.Keys)
  {
    original = original.Replace(key, translations[key].ToString());
  }
  return original;
}

int GetFirstAndLast(string str)
{
  int first = int.Parse(str[0].ToString());
  int last = int.Parse(str[^1].ToString());

  return first * 10 + last; // this converts first digit to a 10th digit e.g 1 = 10, 2 = 20
}

int Challenge_1()
{
  string[] lines = File.ReadAllLines(FILE_PATH);
  return lines.Select(OnlyNumerics).Select(GetFirstAndLast).Sum();
}

int Challenge_2()
{
  string[] lines = File.ReadAllLines(FILE_PATH);
  string[] replaced = lines.Select(ReplaceNumbers).ToArray();
  return replaced.Select(OnlyNumerics).Select(GetFirstAndLast).Sum();
}

Console.WriteLine("Part 1:" + Challenge_1().ToString());
Console.WriteLine("Part 2:" + Challenge_2().ToString());

Enter fullscreen mode Exit fullscreen mode

Top comments (0)