Today's challenge screamed Regex when I first saw it, mainly because whenever I see "extract parts of this string", Regex is my goto;
Basic Concept and Requirements
So we need to find all the mul(number1, number2) and multiply these together, but ignore all other characters.
So we need to find a mechanism to find all the valid mul() function declarations.
To do this, we can leverage the power of Regex, using the following pattern
mul([0-9]{1,3},[0-9]{1,3})"
Which will match on mul( any number between 0-9 , a number of 1 > 3 times closing bracket.
Once we've got the mul() matches, we can utilise regex again to pull out the numbers, parsing these and adding to the total.
Quite a simple and straightforward solution.
void Part1() { const string regex = @"mul\([0-9]{1,3},[0-9]{1,3}\)"; var matches = Regex.Matches(input, regex); var total = 0; foreach (Match match in matches) { var numbers = GetNumbers(match); total += numbers[0] * numbers[1]; } } int[] GetNumbers(Match match) { var numbers = Regex.Matches(match.Value, "\d{1,3}"); var a = int.Parse(numbers[0].Value); var b = int.Parse(numbers[1].Value); return [a, b]; }
This added slightly more complicated instructions, adding the caveat that do() and don't() phrases will enable or disable the mil() functions.
The best way to handle this, seemed easy, update the Regex pattern to account for do() dont() or mul(number, number
The Regex will now look for any of these phrases, by using the | oprator.
We can then loop through these and using a switch statemnt decide if we're looking at a do, dont or mil() match, and update the enabled flag accordingly.
It's then a simple check of whether its a mul() and isEnabled is True, before multiplying and adding to the total.
Full Code for both solutions below
using System.Text.RegularExpressions; var input = File.ReadAllText("./input1.txt"); // var input = @"xmul(2,4)&mul[3,7]!^don't()_mul(5,5)+mul(32,64](mul(11,8)undo()?mul(8,5))"; Part1(); Part2(); return; void Part1() { const string regex = @"mul\([0-9]{1,3},[0-9]{1,3}\)"; var matches = Regex.Matches(input, regex); var total = 0; foreach (Match match in matches) { var numbers = GetNumbers(match); total += numbers[0] * numbers[1]; } Console.WriteLine("Total: " + total); } void Part2() { const string regex = @"do\(\)|don't\(\)|mul\([0-9]{1,3},[0-9]{1,3}\)"; var matches = Regex.Matches(input, regex); // At the start, mul instructions are enabled var isEnabled = true; var total = 0; // loop over the matches (e.g do(), dont() or mul(x, y) foreach (Match match in matches) { switch (match.Value) { case "do()": isEnabled = true; break; case "don't()": isEnabled = false; break; default: { if (match.Value.StartsWith("mul") && isEnabled) { var numbers = GetNumbers(match); total += numbers[0] * numbers[1]; } break; } } } Console.WriteLine("Total: " + total); } int[] GetNumbers(Match match) { var numbers = Regex.Matches(match.Value, "\d{1,3}"); var a = int.Parse(numbers[0].Value); var b = int.Parse(numbers[1].Value); return [a, b]; }
If you're new to my series, i'll re-iterate, I'm using AoC '24 to help learn and improve my existing Python skills - so all solutions will include both C# and Python attempts.
We can use the similar concepts but leverage Pythons language and functions:
import re # Read input from file with open("./input1.txt", "r") as file: input_text = file.read() # Part 1 def part1(): regex = r"mul\(\d{1,3},\d{1,3}\)" matches = re.findall(regex, input_text) total = 0 for match in matches: a, b = get_numbers(match) total += a * b print(f"Total: {total}") # Part 2 def part2(): regex = r"do\(\)|don't\(\)|mul\(\d{1,3},\d{1,3}\)" matches = re.findall(regex, input_text) is_enabled = True # At the start, mul instructions are enabled total = 0 for match in matches: if match == "do()": is_enabled = True elif match == "don't()": is_enabled = False elif match.startswith("mul") and is_enabled: a, b = get_numbers(match) total += a * b print(f"Total: {total}") # Helper function to extract numbers from a match def get_numbers(match): numbers = re.findall(r"\d{1,3}", match) return int(numbers[0]), int(numbers[1]) # Execute parts part1() part2()
As always you can follow me on twitter or view the whole repo for more solutions on Github.
The above is the detailed content of AoC - Day Mull it Over (C# and Python). For more information, please follow other related articles on the PHP Chinese website!