Advent of Code 2023

Es gibt 103 Antworten in diesem Thema. Der letzte Beitrag () ist von nogood.

    Advent of Code 2023

    ... es ist schon wieder ein Jahr vorbei.

    @Elanda wo ist der AoC Thread für 2023?

    Der Coder Adventskalender ist aufgehangen morgen gehts los. Falls Ihr Lust hab jeden Tag ein klein wenig zu Coden ... meldet euch beim adventofcode an.
    Jeden Tag ein ein zweiteiliges Codepuzzel.

    Letztes Jahr musste ich um Tag 10 die Segel streichen.

    Ich erinnere noch, dass es spannend war die vielen Lösungswege zu sehen. Falls Ihr Lust habt mit zu machen, postet doch Euren Code hier im Thread.

    Als Beispiel besucht den Thread von @Elanda vom letzten Jahr.

    Hyperlink-Formatfehler korrigiert ~VaporiZed
    codewars.com Rank: 4 kyu

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „VaporiZed“ ()

    Hey,

    ja ich bin auch wieder dabei. Ich hab tatsächlich letztes Jahr alle Tage gemacht aber glaub ich irgendwann aufgehört zu posten.
    Eventuell schaff ich es ja dieses Jahr alle Lösungen zu posten.

    Allen die mitmachen viel Spaß dabei !
    Grüße , xChRoNiKx

    Nützliche Links:
    Visual Studio Empfohlene Einstellungen | Try-Catch heißes Eisen
    Part 1

    C#-Quellcode

    1. private static void Part01()
    2. {
    3. // LINQ-Version
    4. //var result = Source().Select(line =>
    5. // line.Where(s => int.TryParse(s.ToString(), out _)))
    6. // .Select(line => line.First().ToString() + line.Last().ToString())
    7. // .Sum(int.Parse);
    8. var src = Source();
    9. var result = new List<int>();
    10. string snumber = string.Empty;
    11. foreach (var tmp in src)
    12. {
    13. snumber = string.Empty;
    14. var calibrations = tmp.ToArray();
    15. foreach (var value in calibrations)
    16. if (int.TryParse($"{value}", out var number))
    17. {
    18. snumber += number.ToString();
    19. break;
    20. }
    21. Array.Reverse(calibrations);
    22. foreach (var value in calibrations)
    23. if (int.TryParse($"{value}", out var number))
    24. {
    25. snumber += number.ToString();
    26. break;
    27. }
    28. result.Add(int.Parse(snumber));
    29. }
    30. Console.WriteLine($"{nameof(Part01)}: {result.Sum()}");

    Source

    C#-Quellcode

    1. private static string[] Source() =>
    2. [
    3. "1abc2",
    4. "pqr3stu8vwx",
    5. "a1b2c3d4e5f",
    6. "treb7uchet",
    7. ];


    Part 2

    C#-Quellcode

    1. ​private static void Part02()
    2. {
    3. var result = new List<int>();
    4. var numbers = new []
    5. {
    6. "one", "two", "three", "four",
    7. "five", "six", "seven", "eight", "nine"
    8. };
    9. foreach (var tmp in Source2())
    10. {
    11. var idx = -1;
    12. var str = string.Empty;
    13. var calibrations = tmp;
    14. var snumber = string.Empty;
    15. foreach (var value in calibrations)
    16. {
    17. idx++;
    18. str = value switch
    19. {
    20. var chr when chr is >= '0' and <= '9' => (chr - '0').ToString(),
    21. 'o' when idx + numbers[0].Length <= calibrations.Length && calibrations[idx..(idx + numbers[0].Length)] == numbers[0] => 1.ToString(),
    22. 't' when idx + numbers[1].Length <= calibrations.Length && calibrations[idx..(idx + numbers[1].Length)] == numbers[1] => 2.ToString(),
    23. 't' when idx + numbers[2].Length <= calibrations.Length && calibrations[idx..(idx + numbers[2].Length)] == numbers[2] => 3.ToString(),
    24. 'f' when idx + numbers[3].Length <= calibrations.Length && calibrations[idx..(idx + numbers[3].Length)] == numbers[3] => 4.ToString(),
    25. 'f' when idx + numbers[4].Length <= calibrations.Length && calibrations[idx..(idx + numbers[4].Length)] == numbers[4] => 5.ToString(),
    26. 's' when idx + numbers[5].Length <= calibrations.Length && calibrations[idx..(idx + numbers[5].Length)] == numbers[5] => 6.ToString(),
    27. 's' when idx + numbers[6].Length <= calibrations.Length && calibrations[idx..(idx + numbers[6].Length)] == numbers[6] => 7.ToString(),
    28. 'e' when idx + numbers[7].Length <= calibrations.Length && calibrations[idx..(idx + numbers[7].Length)] == numbers[7] => 8.ToString(),
    29. 'n' when idx + numbers[8].Length <= calibrations.Length && calibrations[idx..(idx + numbers[8].Length)] == numbers[8] => 9.ToString(),
    30. _ => str,
    31. };
    32. if (snumber == string.Empty)
    33. snumber += str;
    34. }
    35. snumber += str;
    36. result.Add(int.Parse(snumber));
    37. }
    38. Console.WriteLine($"{nameof(Part02)}: {result.Sum()}");
    39. }

    Source

    C#-Quellcode

    1. private static string[] Source2() =>
    2. [
    3. "two1nine",
    4. "eightwothree",
    5. "abcone2threexyz",
    6. "xtwone3four",
    7. "4nineeightseven2",
    8. "zoneight234",
    9. "7pqrstsixteen",
    10. ];​

    Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von „exc-jdbi“ () aus folgendem Grund: Part 2 hinzugesetzt

    Hab noch nie teilgenommen, daher kenn ich die Codeanforderungen/Rahmenbedingungen nicht.
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Private Sub CalculateSumOfCalibratingValuesFrom(RawText As String)
    2. Dim SumOfCalibratingValues = GetSumOfCalibratingValues(GetCalibratingValuesFrom(RawText))
    3. End Sub
    4. Private Function GetSumOfCalibratingValues(CalibratingValues As IEnumerable(Of Integer)) As Integer
    5. Return CalibratingValues.Sum
    6. End Function
    7. Private Function GetCalibratingValuesFrom(RawText As String) As IEnumerable(Of Integer)
    8. Dim DocumentLines = RawText.Split({Environment.NewLine}, StringSplitOptions.None)
    9. Return DocumentLines.Select(Function(x) GetCalibratingValueIn(x))
    10. End Function
    11. Private Function GetCalibratingValueIn(DocumentLine As String) As Integer
    12. Dim PositionOfFirstDigit = DocumentLine.IndexOfAny("0123456789".ToArray)
    13. Dim PositionOfLastDigit = DocumentLine.LastIndexOfAny("0123456789".ToArray)
    14. Return Integer.Parse($"{DocumentLine(PositionOfFirstDigit)}{DocumentLine(PositionOfLastDigit)}")
    15. End Function
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    @VaporiZed
    Es gibt keine Anforderungen. Jeder macht es so wie er es für richtig hält.
    Ich nutze das oft um mal auch Dinge zu nutzen die ich nicht jeden Tag nutze.

    Part 1 und 2:
    Spoiler anzeigen

    geht sicher kürzer und besser mit LINQ aber ich nutze LINQ oft und wollte hier mal direkt ohne LINQ arbeiten.
    Dictionarys benutze ich fast nie sowie den StringBuilder.

    C#-Quellcode

    1. using System.Text;
    2. using System.Text.RegularExpressions;
    3. namespace Tag01
    4. {
    5. internal class Program
    6. {
    7. public static List<string> digits = new List<string>() { "1", "2", "3", "4", "5", "6", "7", "8", "9", "one", "two", "three", "four", "five", "six", "seven" , "eight", "nine" };
    8. static void Main(string[] args)
    9. {
    10. string[] exampleFile = File.ReadAllLines("Example.txt");
    11. string[] exampleFile2 = File.ReadAllLines("Example2.txt");
    12. string[] inputFile = File.ReadAllLines("Input.txt");
    13. Console.WriteLine($"Example: {Calculate(exampleFile)}");
    14. Console.WriteLine($"Example2: {Calculate(exampleFile2, true)}");
    15. Console.WriteLine($"Input Part 1: {Calculate(inputFile)}");
    16. Console.WriteLine($"Input Part 2: {Calculate(inputFile, true)}");
    17. }
    18. static int Calculate(string[] lines, bool p2 = false) {
    19. int sum = 0;
    20. foreach (string line in lines)
    21. {
    22. string cleaned = line;
    23. if (p2)
    24. {
    25. cleaned = ReplaceTextDigitsToDigits(cleaned);
    26. }
    27. cleaned = Regex.Replace(cleaned, "[^0-9]", "");
    28. StringBuilder sb = new StringBuilder();
    29. if (cleaned.Length > 0)
    30. {
    31. sb.Append(cleaned[0].ToString());
    32. sb.Append(cleaned[cleaned.Length - 1].ToString());
    33. int finalNumber = Int32.Parse(sb.ToString());
    34. sum += finalNumber;
    35. }
    36. }
    37. return sum;
    38. }
    39. static string ReplaceTextDigitsToDigits(string line)
    40. {
    41. Dictionary<int, string> dic = new Dictionary<int, string>();
    42. foreach (string digit in digits)
    43. {
    44. int index = line.IndexOf(digit);
    45. while(index != -1)
    46. {
    47. dic.Add(index, digit);
    48. index = line.IndexOf(digit, index + 1);
    49. }
    50. }
    51. StringBuilder sb = new StringBuilder();
    52. foreach (var d in dic.OrderBy(x => x.Key))
    53. {
    54. sb.Append(d.Value.ToString());
    55. sb.Replace("one", "1");
    56. sb.Replace("two", "2");
    57. sb.Replace("three", "3");
    58. sb.Replace("four", "4");
    59. sb.Replace("five", "5");
    60. sb.Replace("six", "6");
    61. sb.Replace("seven", "7");
    62. sb.Replace("eight", "8");
    63. sb.Replace("nine", "9");
    64. }
    65. return sb.ToString();
    66. }
    67. }
    68. }
    Grüße , xChRoNiKx

    Nützliche Links:
    Visual Studio Empfohlene Einstellungen | Try-Catch heißes Eisen
    Oh, Teil 2 gibt es ja auch noch. Muss mal schauen, ob ich mich dort anmelde, um den Zugang zur Aufgabe zu bekommen.

    ##########

    03.12.: Teil 2
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Private Replacements As IEnumerable(Of (Word As String, DigitCharacter As Char)) = {("one", "1"c), ("two", "2"c), ("three", "3"c), ("four", "4"c), ("five", "5"c), ("six", "6"c), ("seven", "7"c), ("eight", "8"c), ("nine", "9"c)}
    2. Private Sub ShowSumOfCalibratingValuesFrom(RawText As String)
    3. MessageBox.Show(GetSumOfCalibratingValues(GetCalibratingValuesFrom(RawText)).ToString)
    4. End Sub
    5. Private Function GetSumOfCalibratingValues(CalibratingValues As IEnumerable(Of Integer)) As Integer
    6. Return CalibratingValues.Sum
    7. End Function
    8. Private Function GetCalibratingValuesFrom(RawText As String) As IEnumerable(Of Integer)
    9. Dim DocumentLines = RawText.Split({Environment.NewLine}, StringSplitOptions.None)
    10. Return DocumentLines.Select(Function(x) GetCalibratingValueIn(x))
    11. End Function
    12. Private Function GetCalibratingValueIn(DocumentLine As String) As Integer
    13. Dim FirstDigitCharacter = GetFirstDigitCharacterIn(DocumentLine)
    14. Dim LastDigitCharacter = GetLastDigitCharacterIn(DocumentLine)
    15. Return Integer.Parse($"{FirstDigitCharacter}{LastDigitCharacter}")
    16. End Function
    17. Private Function GetFirstDigitCharacterIn(DocumentLine As String) As Char
    18. Dim IndexOfFirstDigitCharacter = Integer.MaxValue
    19. Dim FirstDigitCharacter As Char
    20. For Each Replacement In Replacements
    21. Dim IndexOfFirstDigitAsWord = DocumentLine.IndexOf(Replacement.Word)
    22. Dim IndexOfFirstDigitAsCharacter = DocumentLine.IndexOf(Replacement.DigitCharacter)
    23. Dim LowestMatchIndex = If(IndexOfFirstDigitAsWord > -1 AndAlso IndexOfFirstDigitAsCharacter > -1, Math.Min(IndexOfFirstDigitAsWord, IndexOfFirstDigitAsCharacter), Math.Max(IndexOfFirstDigitAsWord, IndexOfFirstDigitAsCharacter))
    24. If LowestMatchIndex > -1 AndAlso (LowestMatchIndex < IndexOfFirstDigitCharacter) Then IndexOfFirstDigitCharacter = LowestMatchIndex : FirstDigitCharacter = Replacement.DigitCharacter
    25. Next
    26. If FirstDigitCharacter = Microsoft.VisualBasic.vbNullChar Then Stop
    27. Return FirstDigitCharacter
    28. End Function
    29. Private Function GetLastDigitCharacterIn(DocumentLine As String) As Char
    30. Dim IndexOfLastDigitCharacter = -1
    31. Dim LastDigitCharacter As Char
    32. For Each Replacement In Replacements
    33. Dim IndexOfLastDigitAsWord = DocumentLine.LastIndexOf(Replacement.Word)
    34. Dim IndexOfLastDigitAsCharacter = DocumentLine.LastIndexOf(Replacement.DigitCharacter)
    35. Dim HighestMatchIndex = Math.Max(IndexOfLastDigitAsWord, IndexOfLastDigitAsCharacter)
    36. If HighestMatchIndex > -1 AndAlso HighestMatchIndex > IndexOfLastDigitCharacter Then IndexOfLastDigitCharacter = HighestMatchIndex : LastDigitCharacter = Replacement.DigitCharacter
    37. Next
    38. If LastDigitCharacter = Microsoft.VisualBasic.vbNullChar Then Stop
    39. Return LastDigitCharacter
    40. End Function

    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „VaporiZed“ ()

    Part 1
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Dim input = IO.File.ReadAllLines(FilePathOfDataPart1)
    2. Dim resultPart1 = input.Sum(Function(line) 10 * Integer.Parse(line.First(Function(c) Char.IsDigit(c))) + Integer.Parse(line.Last(Function(c) Char.IsDigit(c))))


    Part 2 hab ich wohl nicht verstanden, ist dieselbe Lösung, nachdem die Zahlen umgewandelt worden sind. Aber scheinbar falsch
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Dim SuperDigits As New Dictionary(Of String, String) From {
    2. {"twone", "21"},
    3. {"eightwo", "82"},
    4. {"oneight", "18"},
    5. {"one", "1"},
    6. {"two", "2"},
    7. {"three", "3"},
    8. {"four", "4"},
    9. {"five", "5"},
    10. {"six", "6"},
    11. {"seven", "7"},
    12. {"eight", "8"},
    13. {"nine", "9"}}
    14. Dim input = IO.File.ReadAllLines(FilePathOfDataPart1)
    15. For i = 0 To input.Length - 1
    16. For Each d In SuperDigits
    17. input(i) = input(i).Replace(d.Key, d.Value)
    18. Next
    19. Next
    20. Dim result = input.Sum(Function(line) 10 * Integer.Parse(line.First(Function(c) Char.IsDigit(c))) + Integer.Parse(line.Last(Function(c) Char.IsDigit(c))))

    Dieser Beitrag wurde bereits 13 mal editiert, zuletzt von „Haudruferzappeltnoch“ ()

    Hi hi,
    ich bin auch wieder dabei, so lange ich mir Zeit für die Aufgaben nehmen kann :)

    Tag 1
    Spoiler anzeigen

    C#-Quellcode

    1. ​using FileStream fs = File.OpenRead(@"C:\Dev\dotnet\AdventOfCode\2023\Day1\input.txt");
    2. using StreamReader sr = new(fs);
    3. int total = 0;
    4. string[] numberWords = ["one", "two", "three", "four", "five", "six", "seven", "eight", "nine"];
    5. while (!sr.EndOfStream)
    6. {
    7. ReadOnlySpan<char> lineSpan = sr.ReadLine().AsSpan();
    8. char[] numbers = Array.Empty<char>();
    9. #region Part1
    10. for (int i = 0; i < lineSpan.Length; ++i)
    11. {
    12. if ((lineSpan[i] >= 48) && (lineSpan[i] <= 57))
    13. {
    14. numbers[0] = lineSpan[i];
    15. break;
    16. }
    17. }
    18. for (int i = lineSpan.Length - 1; i >= 0; --i)
    19. {
    20. if ((lineSpan[i] >= 48) && (lineSpan[i] <= 57))
    21. {
    22. numbers[1] = lineSpan[i];
    23. break;
    24. }
    25. }
    26. #endregion
    27. #region Part2
    28. Dictionary<int, char> numberBuffer = new();
    29. for (int i = 0; i < lineSpan.Length; ++i)
    30. {
    31. if ((lineSpan[i] >= 48) && (lineSpan[i] <= 57))
    32. {
    33. numberBuffer.Add(i, lineSpan[i]);
    34. }
    35. }
    36. foreach (var word in numberWords)
    37. {
    38. for (int i = 0; i <= lineSpan.Length - word.Length; ++i)
    39. {
    40. ReadOnlySpan<char> current = lineSpan[i..(i + word.Length)];
    41. if (current.ToString() == word)
    42. {
    43. char number = current switch
    44. {
    45. "one" => '1',
    46. "two" => '2',
    47. "three" => '3',
    48. "four" => '4',
    49. "five" => '5',
    50. "six" => '6',
    51. "seven" => '7',
    52. "eight" => '8',
    53. "nine" => '9',
    54. _ => '0'
    55. };
    56. numberBuffer.Add(i, number);
    57. }
    58. }
    59. }
    60. int minIndex = numberBuffer.Min(e => e.Key);
    61. int maxIndex = numberBuffer.Max(e => e.Key);
    62. numbers = [GetNumberCharFromStringIndex(numberBuffer, minIndex), GetNumberCharFromStringIndex(numberBuffer, maxIndex)];
    63. #endregion
    64. total += int.Parse(numbers);
    65. }
    66. Console.WriteLine(total);
    67. char GetNumberCharFromStringIndex(Dictionary<int, char> numberBuffer, int index) => (from no in numberBuffer
    68. where no.Key == index
    69. select no.Value).First();

    Tag1
    Junge für Tag eins hatte ich etwas leichteres erwartet. Oder meine Erinnerung täuscht mich vom letzten Jahr.
    Tag1 Part 1 u. 2 C# (Dauer ca. 3 Std. (Part1 15 Min)). Erst hatte ich eine sexy Lösung, jedoch mit falschem Ergebnis. Match die WordNummern und füge die Int-Zahl davor in den String ein. Leider erkennt er dann z.B. nicht mehr "eightwothree" -> eigh2two3three. Da 'two' den Match mit eight kaputt macht.

    Spoiler anzeigen

    C#-Quellcode

    1. using System.Text.RegularExpressions;
    2. var Part1 = false;
    3. if (Part1)
    4. {
    5. //Part1
    6. var input = File.ReadAllLines("AoC_D1.txt");
    7. var sum = 0;
    8. foreach (var line in input)
    9. {
    10. var firstDigit = Regex.Matches(line, @"[0-9]");
    11. sum += Int32.Parse(firstDigit.First().Value + firstDigit.Last().Value);
    12. }
    13. Console.WriteLine(sum);
    14. }
    15. else
    16. {
    17. //Part2
    18. var input = File.ReadAllLines("AoC_D1.txt").ToList();
    19. var sum = 0;
    20. string[] wordNrs = ["zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"];
    21. Dictionary<int, string> posIndex_Nr = new();
    22. foreach (var line in input)
    23. {
    24. posIndex_Nr.Clear();
    25. for (int i = 0; i < wordNrs.Length; i++)
    26. {//iterate over all 'zero', 'one', ... words in each Line if Match is found add to Dictionary the IndexPosition of the Match (Position of first Letter of Match)
    27. //e.g. two1nine -> Add("0","2")
    28. var wordNrMatches = Regex.Matches(line, wordNrs[i]);
    29. foreach (Match nrMatch in wordNrMatches.Cast<Match>())
    30. {
    31. posIndex_Nr.Add(nrMatch.Index, i.ToString());
    32. }
    33. }
    34. var digits = Regex.Matches(line, @"[0-9]");
    35. foreach (Match nrMatch in digits.Cast<Match>())
    36. {//match all regular digits and also add the position of the match
    37. //e.g. two1nine -> Add("3","1")
    38. posIndex_Nr.Add(nrMatch.Index, nrMatch.Value);
    39. }
    40. //sort Dictionary by Key Posion Int -> then first & last
    41. var PositionSortedDictionary = posIndex_Nr.OrderBy(x => x.Key);
    42. var first = PositionSortedDictionary.First().Value;
    43. var last = PositionSortedDictionary.Last().Value;
    44. sum += Int32.Parse(first + last);
    45. }
    46. Console.WriteLine(sum);
    47. }
    codewars.com Rank: 4 kyu

    Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von „nogood“ ()

    Moin moin,
    hier ist Tag02 einmal komplett:

    Da nogood auch gepostet hat wielange er gebraucht hat mach ich das mal ab jetzt auch.
    Beides zusammen ca. 14 Minuten wenn ich vom Projekterstelldatum ausgehe.

    Spoiler anzeigen

    C#-Quellcode

    1. using System.Collections.Concurrent;
    2. namespace Tag02
    3. {
    4. internal class Program
    5. {
    6. public static Dictionary<string, int> bag = new Dictionary<string, int>
    7. {
    8. { "red", 12 },
    9. { "green", 13 },
    10. { "blue", 14 }
    11. };
    12. static void Main(string[] args)
    13. {
    14. string[] exampleFile = File.ReadAllLines("Example.txt");
    15. string[] inputFile = File.ReadAllLines("Input.txt");
    16. Console.WriteLine($"Example: {CalculateP1(exampleFile)}");
    17. Console.WriteLine($"Example2: {CalculateP2(exampleFile)}");
    18. Console.WriteLine($"Input Part 1: {CalculateP1(inputFile)}");
    19. Console.WriteLine($"Input Part 2: {CalculateP2(inputFile)}");
    20. }
    21. static int CalculateP1(string[] lines)
    22. {
    23. int sum = 0;
    24. foreach (var line in lines)
    25. {
    26. bool gamePlayable = true;
    27. string[] gameLine = line.Split(':');
    28. int gameNumber = Int32.Parse(gameLine[0].Replace("Game ", ""));
    29. string[] gameSets = gameLine[1].Split(";");
    30. foreach (var gameSet in gameSets)
    31. {
    32. if (!gamePlayable) continue;
    33. string[] cubes = gameSet.Split(',');
    34. foreach (var cube in cubes)
    35. {
    36. if (!gamePlayable) continue;
    37. string[] splitted = cube.Trim().Split(' ');
    38. int cubeCount = Int32.Parse(splitted[0]);
    39. string cubeColor = splitted[1];
    40. if (bag.ContainsKey(cubeColor))
    41. {
    42. int bagColorCount = bag[cubeColor];
    43. if(cubeCount > bagColorCount)
    44. {
    45. gamePlayable = false;
    46. }
    47. }
    48. }
    49. }
    50. if (gamePlayable) sum += gameNumber;
    51. }
    52. return sum;
    53. }
    54. static int CalculateP2(string[] lines)
    55. {
    56. int sum = 0;
    57. foreach (var line in lines)
    58. {
    59. Dictionary<string, int> highestCubes = new Dictionary<string, int>();
    60. int gamePower = 1;
    61. string[] gameLine = line.Split(':');
    62. int gameNumber = Int32.Parse(gameLine[0].Replace("Game ", ""));
    63. string[] gameSets = gameLine[1].Split(";");
    64. foreach (var gameSet in gameSets)
    65. {
    66. string[] cubes = gameSet.Split(',');
    67. foreach (var cube in cubes)
    68. {
    69. string[] splitted = cube.Trim().Split(' ');
    70. int cubeCount = Int32.Parse(splitted[0]);
    71. string cubeColor = splitted[1].Trim();
    72. if (highestCubes.ContainsKey(cubeColor))
    73. {
    74. int bagColorCount = highestCubes[cubeColor];
    75. if (cubeCount > bagColorCount)
    76. {
    77. highestCubes[cubeColor] = cubeCount;
    78. }
    79. } else
    80. {
    81. highestCubes[cubeColor] = cubeCount;
    82. }
    83. }
    84. }
    85. foreach (var cube in highestCubes)
    86. {
    87. gamePower *= cube.Value;
    88. }
    89. sum += gamePower;
    90. }
    91. return sum;
    92. }
    93. }
    94. }


    Wer nur Part 1 / Part 2 sehen will:

    Part01:
    Spoiler anzeigen

    lines ist immer ReadAllLines(inputFile)

    C#-Quellcode

    1. static int CalculateP1(string[] lines)
    2. {
    3. int sum = 0;
    4. foreach (var line in lines)
    5. {
    6. bool gamePlayable = true;
    7. string[] gameLine = line.Split(':');
    8. int gameNumber = Int32.Parse(gameLine[0].Replace("Game ", ""));
    9. string[] gameSets = gameLine[1].Split(";");
    10. foreach (var gameSet in gameSets)
    11. {
    12. if (!gamePlayable) continue;
    13. string[] cubes = gameSet.Split(',');
    14. foreach (var cube in cubes)
    15. {
    16. if (!gamePlayable) continue;
    17. string[] splitted = cube.Trim().Split(' ');
    18. int cubeCount = Int32.Parse(splitted[0]);
    19. string cubeColor = splitted[1];
    20. if (bag.ContainsKey(cubeColor))
    21. {
    22. int bagColorCount = bag[cubeColor];
    23. if(cubeCount > bagColorCount)
    24. {
    25. gamePlayable = false;
    26. }
    27. }
    28. }
    29. }
    30. if (gamePlayable) sum += gameNumber;
    31. }
    32. return sum;
    33. }


    Part02:
    Spoiler anzeigen

    lines ist immer ReadAllLines(inputFile)

    C#-Quellcode

    1. static int CalculateP2(string[] lines)
    2. {
    3. int sum = 0;
    4. foreach (var line in lines)
    5. {
    6. Dictionary<string, int> highestCubes = new Dictionary<string, int>();
    7. int gamePower = 1;
    8. string[] gameLine = line.Split(':');
    9. int gameNumber = Int32.Parse(gameLine[0].Replace("Game ", ""));
    10. string[] gameSets = gameLine[1].Split(";");
    11. foreach (var gameSet in gameSets)
    12. {
    13. string[] cubes = gameSet.Split(',');
    14. foreach (var cube in cubes)
    15. {
    16. string[] splitted = cube.Trim().Split(' ');
    17. int cubeCount = Int32.Parse(splitted[0]);
    18. string cubeColor = splitted[1].Trim();
    19. if (highestCubes.ContainsKey(cubeColor))
    20. {
    21. int bagColorCount = highestCubes[cubeColor];
    22. if (cubeCount > bagColorCount)
    23. {
    24. highestCubes[cubeColor] = cubeCount;
    25. }
    26. } else
    27. {
    28. highestCubes[cubeColor] = cubeCount;
    29. }
    30. }
    31. }
    32. foreach (var cube in highestCubes)
    33. {
    34. gamePower *= cube.Value;
    35. }
    36. sum += gamePower;
    37. }
    38. return sum;
    39. }
    Grüße , xChRoNiKx

    Nützliche Links:
    Visual Studio Empfohlene Einstellungen | Try-Catch heißes Eisen
    Part 1

    C#-Quellcode

    1. private static void Part01()
    2. {
    3. var comparison = new[]
    4. {
    5. ("blue", 14), ("red", 12), ("green", 13)
    6. }.ToDictionary();
    7. var result = new List<int>();
    8. var src = Source();
    9. for (var i = 0; i < src.Length; i++)
    10. {
    11. var flag = true;
    12. for (var j = 1; j < src[i].Length; j++)
    13. for (var k = 1; k < src[i][j].Length; k += 2)
    14. if (comparison[src[i][j][k]] < int.Parse(src[i][j][k - 1]))
    15. { flag = false; break; };
    16. if (flag) result.Add(i + 1);
    17. }
    18. Console.WriteLine($"{nameof(Part01)}: {result.Sum()}");
    19. }

    Part 2

    C#-Quellcode

    1. private static void Part01()
    2. {
    3. var src = Source();
    4. var comparison = new[]
    5. {
    6. ("blue", 0), ("red", 0), ("green", 0)
    7. }.ToDictionary();
    8. var result = new List<int>();
    9. for (var i = 0; i < src.Length; i++)
    10. {
    11. var comp = comparison.ToDictionary(entry => entry.Key, entry => entry.Value);
    12. for (var j = 1; j < src[i].Length; j++)
    13. for (var k = 1; k < src[i][j].Length; k += 2)
    14. if (comp[src[i][j][k]] < int.Parse(src[i][j][k - 1]))
    15. comp[src[i][j][k]] = int.Parse(src[i][j][k - 1]);
    16. result.Add(comp.Values.Aggregate(1, (a, b) => a * b));
    17. }
    18. Console.WriteLine($"{nameof(Part02)}: {result.Sum()}");
    19. }

    Source

    C#-Quellcode

    1. private static string[][][] Source()
    2. {
    3. return SourceText().Select(line =>
    4. line.Split(":;".ToCharArray(), StringSplitOptions.RemoveEmptyEntries))
    5. .Select(game => game.Select(line => line.Split(
    6. " ,".ToCharArray(), StringSplitOptions.RemoveEmptyEntries)).ToArray()).ToArray();
    7. }
    8. private static string[] SourceText() =>
    9. [
    10. "Game 1: 3 blue, 4 red; 1 red, 2 green, 6 blue; 2 green",
    11. "Game 2: 1 blue, 2 green; 3 green, 4 blue, 1 red; 1 green, 1 blue",
    12. "Game 3: 8 green, 6 blue, 20 red; 5 blue, 4 red, 13 green; 5 green, 1 red",
    13. "Game 4: 1 green, 3 red, 6 blue; 3 green, 6 red; 3 green, 15 blue, 14 red",
    14. "Game 5: 6 red, 1 blue, 3 green; 2 blue, 1 red, 2 green",
    15. ];

    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „exc-jdbi“ ()

    D2 Part 1

    VB.NET-Quellcode

    1. Dim input = File.ReadAllLines(FilePathOfDataPart1)
    2. Dim rgx As New Regex("[:;](?: (?:(?<green>\d+) green|(?<red>\d+) red|(?<blue>\d+) blue),?){1,3}")
    3. Dim result As Integer
    4. For i = 0 To input.Length - 1
    5. Dim draws = rgx.Matches(input(i)).Cast(Of Match)
    6. If draws.All(AddressOf IsPossible) Then result += i + 1
    7. Next
    8. Private Function IsPossible(m As Match) As Boolean
    9. Dim red = If(m.Groups("red").Value = String.Empty, 0, CInt(m.Groups("red").Value))
    10. Dim green = If(m.Groups("green").Value = String.Empty, 0, CInt(m.Groups("green").Value))
    11. Dim blue = If(m.Groups("blue").Value = String.Empty, 0, CInt(m.Groups("blue").Value))
    12. Return red <= 12 AndAlso green <= 13 AndAlso blue <= 14
    13. End Function

    D2 Part 2

    VB.NET-Quellcode

    1. Dim input = File.ReadAllLines(FilePathOfDataPart2)
    2. Dim rgx As New Regex("[:;](?: (?:(?<green>\d+) green|(?<red>\d+) red|(?<blue>\d+) blue),?){1,3}")
    3. Dim colors = {"red", "green", "blue"}
    4. Dim result As Integer
    5. For i = 0 To input.Length - 1
    6. Dim draws = rgx.Matches(input(i)).Cast(Of Match)
    7. result += colors.Select(Function(c) draws.Max(Function(m) Cnt(m, c))).Aggregate(Function(x, y) x * y)
    8. Next
    9. Private Function Cnt(m As Match, color As String) As Integer
    10. Dim c = m.Groups(color).Value
    11. Return If(c = String.Empty, 0, CInt(c))
    12. End Function

    Man kann die Summe auch mit LinQ machen, aber das sah mir zu unübersichtlich aus, weil die einzelnen Elemente dann schon Formeln sind. Und bei Part 1 noch schlimmer, wegen if

    Dieser Beitrag wurde bereits 7 mal editiert, zuletzt von „Haudruferzappeltnoch“ ()

    Einfach mal alles zusammengeklatscht. :S
    Spoiler anzeigen

    C#-Quellcode

    1. ​const string inputFile = @"D:\Dev\net\AdventOfCode\2023\Day2\input.txt";
    2. using FileStream fs = File.OpenRead(inputFile);
    3. using StreamReader sr = new(fs);
    4. const int allowedRed = 12;
    5. const int allowedGreen = 13;
    6. const int allowedBlue = 14;
    7. int total = 0;
    8. while (!sr.EndOfStream)
    9. {
    10. var lineSpan = sr.ReadLine().AsSpan();
    11. int delimiterIndex = lineSpan.IndexOf(':');
    12. #region Part1
    13. int gameId = int.Parse(lineSpan[5..delimiterIndex]);
    14. total += IsPossibileGame(lineSpan[(delimiterIndex + 2)..]) ? gameId : 0;
    15. #endregion
    16. #region Part2
    17. total += getHighestCubes(lineSpan[(delimiterIndex + 2)..]);
    18. #endregion
    19. }
    20. System.Console.WriteLine(total);
    21. #region Part1
    22. bool IsPossibileGame(ReadOnlySpan<char> gameSet)
    23. {
    24. Range[] roundRanges = new Range[gameSet.Count(';') + 1];
    25. gameSet.Split(roundRanges, ';');
    26. foreach (Range round in roundRanges)
    27. {
    28. Range[] commas = new Range[gameSet[round].Count(',') + 1];
    29. var currentRound = gameSet[round];
    30. currentRound.Split(commas, ',', StringSplitOptions.TrimEntries);
    31. foreach (Range commaRange in commas)
    32. {
    33. Range[] whiteSpaces = new Range[2];
    34. var currentGame = currentRound[commaRange];
    35. if (currentGame.Split(whiteSpaces, ' ', StringSplitOptions.TrimEntries) > 0)
    36. {
    37. if (!CheckIfPossible(whiteSpaces, currentGame))
    38. {
    39. return false;
    40. }
    41. }
    42. }
    43. }
    44. return true;
    45. }
    46. static bool CheckIfPossible(Range[] whiteSpaces, ReadOnlySpan<char> currentGame)
    47. {
    48. int c = int.Parse(currentGame[whiteSpaces[0]]);
    49. bool isPossible = currentGame[whiteSpaces[1]] switch
    50. {
    51. "blue" => c <= allowedBlue,
    52. "green" => c <= allowedGreen,
    53. "red" => c <= allowedRed,
    54. _ => false
    55. };
    56. return isPossible;
    57. }
    58. #endregion
    59. #region Part2
    60. int getHighestCubes(ReadOnlySpan<char> gameSet)
    61. {
    62. int power = 1;
    63. Dictionary<string, int> highestCubes = new()
    64. {
    65. { "red", 0 },
    66. { "green", 0 },
    67. { "blue", 0 }
    68. };
    69. Range[] roundRanges = new Range[gameSet.Count(';') + 1];
    70. gameSet.Split(roundRanges, ';');
    71. foreach (Range round in roundRanges)
    72. {
    73. Range[] commas = new Range[gameSet[round].Count(',') + 1];
    74. var currentRound = gameSet[round];
    75. currentRound.Split(commas, ',', StringSplitOptions.TrimEntries);
    76. foreach (Range commaRange in commas)
    77. {
    78. Range[] whiteSpaces = new Range[2];
    79. var currentGame = currentRound[commaRange];
    80. if (currentGame.Split(whiteSpaces, ' ', StringSplitOptions.TrimEntries) > 0)
    81. {
    82. int c = int.Parse(currentGame[whiteSpaces[0]]);
    83. string currentKey = currentGame[whiteSpaces[1]].ToString();
    84. if (highestCubes[currentKey] < c)
    85. {
    86. highestCubes[currentKey] = c;
    87. }
    88. }
    89. }
    90. }
    91. foreach (string key in highestCubes.Keys)
    92. {
    93. power *= highestCubes[key];
    94. }
    95. return power;
    96. }
    97. #endregion

    Tag 2
    Heute war es Schön. Es ging eher in Richtung Fleissaufgabe. Zeit heute für Part 1 ca. 60 Min. und Part 2, noch 15 Min. hinterher.

    C# Part1 und 2
    Spoiler anzeigen

    C#-Quellcode

    1. #region Setup Input
    2. using System.Text.RegularExpressions;
    3. var input = File.ReadAllLines("AoC_D02.txt");
    4. List<Game> Games = []; //.Net8 new ini
    5. foreach (var line in input)
    6. {
    7. //split "Game 1: 3 blue, 4 red; 1 red, 2 green, 6 blue; 2 green" ----> 4 Parts: 'Game1' // '3 blue, 4 red' // ...
    8. var OneGameLineSplited = line.Split(':', ';');
    9. var GameId = Int32.Parse(Regex.Match(OneGameLineSplited[0], @"\d+").Value);
    10. List<Set> Sets = [];
    11. for (int i = 1; i < OneGameLineSplited.Length; i++)
    12. {//lookbehind: gets digits followed by 'blue'
    13. var blue = Regex.Match(OneGameLineSplited[i], @"\d+ (?=blue)").Value;
    14. var green = Regex.Match(OneGameLineSplited[i], @"\d+ (?=green)").Value;
    15. var red = Regex.Match(OneGameLineSplited[i], @"\d+ (?=red)").Value;
    16. Sets.Add(new Set(blue != string.Empty ? Int32.Parse(blue) : 0, green != string.Empty ? Int32.Parse(green) : 0, red != string.Empty ? Int32.Parse(red) : 0));
    17. }
    18. Games.Add(new Game(GameId, Sets));
    19. }
    20. #endregion Setup Input
    21. #region Part1 GamesIsPossible
    22. bool GameIsPossible(Set maxSet, Game game)
    23. {
    24. foreach (var oneGameSet in game.Sets)
    25. {
    26. if (oneGameSet.Blue > maxSet.Blue || oneGameSet.Green > maxSet.Green || oneGameSet.Red > maxSet.Red)
    27. {
    28. return false;
    29. }
    30. }
    31. return true;
    32. }
    33. #endregion Part1 GamesIsPossible
    34. #region Part2 Powers
    35. int GamePower(Game game)
    36. {
    37. var blue = game.Sets.Max(x => x.Blue);
    38. var green = game.Sets.Max(x => x.Green);
    39. var red = game.Sets.Max(x => x.Red);
    40. blue = blue == 0 ? 1 : blue;
    41. green = green == 0 ? 1 : green;
    42. red = red == 0 ? 1 : red;
    43. return blue * green * red;
    44. }
    45. #endregion Part2 Powers
    46. #region MAIN Game
    47. Set MaxSet = new(14, 13, 12);
    48. var sum = 0;
    49. var sum2 = 0;
    50. foreach (var game in Games)
    51. {
    52. if (GameIsPossible(MaxSet, game))
    53. {
    54. sum += game.Id;
    55. }
    56. sum2 += GamePower(game);
    57. }
    58. Console.WriteLine($"Part1: {sum}\nPart2: {sum2}");
    59. #endregion MAIN Game
    60. //--------------CLASSES
    61. class Game(int id, List<Set> sets)
    62. {// .Net8 Primär Konstruktor
    63. public int Id { get; set; } = id;
    64. public List<Set> Sets { get; set; } = sets;
    65. }
    66. class Set(int blue, int green, int red)
    67. {// .Net8 Primär Konstruktor
    68. public int Blue { get; set; } = blue;
    69. public int Green { get; set; } = green;
    70. public int Red { get; set; } = red;
    71. }
    codewars.com Rank: 4 kyu
    Tag 3


    Gedanke
    Spoiler anzeigen
    Finde alle Nummern. Startindex/Endindex der Nummer +/-1 und schauen ob da ein 'Symbol' ist. Gleiches mit der Zeile da drüber/drunter. Selbe Indizes


    Part 1 C# ca. 60 Min.
    Spoiler anzeigen

    C#-Quellcode

    1. using System.Text.RegularExpressions;
    2. var input = File.ReadAllLines("aoc.txt").ToList();
    3. #region EdgeCase FirstLine LastLine
    4. //Input from e.g. 345 to ->
    5. //.....
    6. //.345.
    7. //.....
    8. input.Insert(0, new string('.', input[0].Length));
    9. input.Insert(input.Count, new string('.', input[0].Length));
    10. string[] inputArray = new string[input.Count];
    11. for (int i = 0; i < input.Count; i++)
    12. {
    13. inputArray[i] = "." + input[i] + ".";
    14. }
    15. #endregion
    16. var sum = 0;
    17. for (int i = 1; i < inputArray.Length - 1; i++)
    18. {
    19. var nrsMatchedInLine = Regex.Matches(inputArray[i], @"\d+");
    20. if (nrsMatchedInLine.Count > 0)
    21. {
    22. foreach (Match nrMatch in nrsMatchedInLine)
    23. {
    24. if (CheckForSymbol(inputArray[i - 1], inputArray[i], inputArray[i + 1], nrMatch))
    25. {
    26. sum += Int32.Parse(nrMatch.Value);
    27. }
    28. }
    29. }
    30. }
    31. bool CheckForSymbol(string lineT, string lineM, string lineB, Match nrMatch)
    32. {
    33. var startIndex = nrMatch.Index - 1;
    34. var endIndex = nrMatch.Length + 2;
    35. #region DEBUG
    36. var r_1 = lineT.Substring(startIndex, endIndex);
    37. var r1 = Regex.Match(lineT.Substring(startIndex, endIndex), @"[^\.\d]").Success;
    38. var r_2 = lineM.Substring(startIndex, endIndex);
    39. var r2 = Regex.Match(lineM.Substring(startIndex, endIndex), @"[^\.\d]").Success;
    40. var r_3 = lineB.Substring(startIndex, endIndex);
    41. var r3 = Regex.Match(lineB.Substring(startIndex, endIndex), @"[^\.\d]").Success;
    42. #endregion DEBUG
    43. //matches everything BUT 'digits' and '.'
    44. if (Regex.Match(lineT.Substring(startIndex, endIndex), @"[^\.\d]").Success | Regex.Match(lineM.Substring(startIndex, endIndex), @"[^\.\d]").Success | Regex.Match(lineB.Substring(startIndex, endIndex), @"[^\.\d]").Success)
    45. {
    46. return true;
    47. }
    48. return false;
    49. }
    50. Console.WriteLine(sum);


    Gedanke
    Spoiler anzeigen
    ​Finde alle Nummern, die einen * haben. Speichere die Nummer und die Position des * in einem Dictionary <int, Point>. Im Fall, dass zwei Nummern den selben Point teilen -> Gear.


    Part 2 (kommt noch)
    codewars.com Rank: 4 kyu

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „nogood“ ()

    D3 Part 1

    VB.NET-Quellcode

    1. Private input = File.ReadAllText(FilePathOfDataPart1)
    2. input = input.Replace(vbCrLf, String.Empty) ' width ist 140
    3. Dim i, result As Integer
    4. While i < input.Length
    5. Dim numberRange = GetNumberRange(i)
    6. If Not GetSymbolRange(numberRange).All(Function(x) input(x) = "." OrElse Char.IsDigit(input(x))) Then result += Calc(numberRange)
    7. i += Math.Max(1, numberRange.Count)
    8. End While
    9. Private Function GetNumberRange(idx As Integer) As Integer()
    10. If Not Char.IsDigit(input(idx)) Then Return Array.Empty(Of Integer)
    11. Dim lst As New List(Of Integer) From {idx}
    12. If Char.IsDigit(input(idx + 1)) Then
    13. lst.Add(idx + 1)
    14. If Char.IsDigit(input(idx + 2)) Then lst.Add(idx + 2)
    15. End If
    16. Return lst.ToArray
    17. End Function
    18. Private Function GetSymbolRange(number As IEnumerable(Of Integer)) As Integer()
    19. If number.Count = 0 Then Return Array.Empty(Of Integer)
    20. Dim lst As New List(Of Integer)
    21. For i = number.First - 1 To number.Last + 1
    22. lst.AddRange({i - 140, i, i + 140})
    23. Next
    24. Return lst.Distinct.Where(Function(n) n >= 0 AndAlso n < input.Length).ToArray
    25. End Function
    26. Private Function Calc(number As IEnumerable(Of Integer)) As Integer
    27. Dim m = number.Count - 1
    28. Dim ret As Integer
    29. For i = 0 To m
    30. ret += 10 ^ (m - i) * Integer.Parse(input(number.First + i))
    31. Next
    32. Return ret
    33. End Function

    Part 2 fehlt mir die Idee wie der Part 1 Code das mit abdecken kann. Daher hab ich das nicht gemacht. Auf n neuen Ansatz hatte ich noch keine Lust, aber vielleicht später

    So mit einem neuen Ansatz läuft beides, ist sogar kürzer und leichter geworden als der erste Ansatz.
    Ansatz2 Part2

    VB.NET-Quellcode

    1. Private input As String = File.ReadAllText(FilePathOfData)
    2. Sub Main()
    3. input = input.Replace(vbCrLf, "."c) 'width ist nun 141
    4. 'input = String.Join("*"c, input.Split({"+"c, "-"c, "#"c, "$"c, "%"c, "&"c, "/"c, "="c, "@"c}, StringSplitOptions.RemoveEmptyEntries))
    5. Dim idx As Integer
    6. Dim result As Integer
    7. While FindNext(idx)
    8. result += GetNumbers(idx).Aggregate(Function(x, y) x * y)
    9. End While
    10. End Sub
    11. Private Function FindNext(ByRef idx As Integer) As Boolean
    12. idx = input.IndexOf("*"c, idx + 1)
    13. Return idx > -1
    14. End Function
    15. Private Function GetNumbers(idx As Integer) As Integer()
    16. Dim lst As New List(Of Integer)
    17. For Each n In {-142, -141, -140, -1, 1, 140, 141, 142}
    18. If Char.IsDigit(input(idx + n)) Then lst.Add(GetNumber(idx + n, n))
    19. Next
    20. Dim cutlst = lst.Distinct.ToList
    21. If cutlst.Count < 2 Then cutlst.Add(0)
    22. Return cutlst.ToArray
    23. End Function
    24. Private Function GetNumber(idx As Integer, line0 As Integer) As Integer
    25. Dim last = If(line0 = -1, idx - line0, input.IndexOf("."c, idx))
    26. Dim first = If(line0 = 1, idx, input.LastIndexOf("."c, idx) + 1)
    27. Return Integer.Parse(input.Substring(first, last - first))
    28. End Function

    Ansatz2 Part1
    Auskommentierte Zeile aktivieren und im Aggregat * auf + ändern

    Dieser Beitrag wurde bereits 7 mal editiert, zuletzt von „Haudruferzappeltnoch“ ()

    Platzhalter für Tag 2 und 3 - ich hinke nach.
    @Haudruferzappeltnoch: Ich weiß nicht, ob Dein Tag 1, Teil 2 überhaupt funktioniert, aber Option Strict On ist er nicht. Dictionary(Of String, Char), aber die Zweitwerte sind Strings. Und "21" wird nie ein Char.

    ##########

    Tag 2 Teil 1

    VB.NET-Quellcode

    1. Friend Class FrmMain
    2. Private ExistingCubes As CubeSet
    3. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    4. CalculateValueForDay2()
    5. End Sub
    6. Private Sub CalculateValueForDay2()
    7. SetExistingCubes(12, 13, 14)
    8. Dim GameData = CollectDataFrom("input.txt")
    9. Dim FittingGames = GetFittingGamesFrom(GameData)
    10. ShowFinalGameSetIdSumFrom(FittingGames)
    11. End Sub
    12. Private Sub SetExistingCubes(CountOfRedCubes As Integer, CountOfGreenCubes As Integer, CountOfBlueCubes As Integer)
    13. ExistingCubes = New CubeSet(CountOfRedCubes, CountOfGreenCubes, CountOfBlueCubes)
    14. End Sub
    15. Private Function CollectDataFrom(FilePath As String) As IEnumerable(Of GameData)
    16. Dim ListOfGameData As New List(Of GameData)
    17. For Each RawDataLine In IO.File.ReadAllLines(FilePath)
    18. Dim MainData = RawDataLine.Split(":"c)
    19. Dim GameID = Integer.Parse(MainData(0).Substring("Game ".Length))
    20. Dim CubeSets = GetCubeSetsFrom(MainData(1).Trim)
    21. Dim NextGameData As New GameData(GameID, CubeSets)
    22. ListOfGameData.Add(NextGameData)
    23. Next
    24. Return ListOfGameData
    25. End Function
    26. Private Function GetCubeSetsFrom(RawData As String) As IEnumerable(Of CubeSet)
    27. Dim CubeSets As New List(Of CubeSet)
    28. For Each CubeSetRawData In RawData.Split(";"c)
    29. Dim CubeData = CubeSetRawData.Split(","c)
    30. Dim NewCubeSet As New CubeSet(0, 0, 0)
    31. For Each SingleCubeData In CubeData
    32. Dim SingleCubeSetRawData = SingleCubeData.Trim.Split
    33. Dim CubeCount = Integer.Parse(SingleCubeSetRawData(0))
    34. Dim CubeColorAsText = SingleCubeSetRawData(1)
    35. Select Case CubeColorAsText
    36. Case "red" : NewCubeSet.CountOfRedCubes = CubeCount
    37. Case "green" : NewCubeSet.CountOfGreenCubes = CubeCount
    38. Case "blue" : NewCubeSet.CountOfBlueCubes = CubeCount
    39. End Select
    40. Next
    41. CubeSets.Add(NewCubeSet)
    42. Next
    43. Return CubeSets
    44. End Function
    45. Private Function GetFittingGamesFrom(GameData As IEnumerable(Of GameData)) As IEnumerable(Of GameData)
    46. Return GameData.Where(Function(x) AllCubeSetsFit(x))
    47. End Function
    48. Private Function AllCubeSetsFit(SingleGameData As GameData) As Boolean
    49. Return SingleGameData.CubeSets.All(Function(x) SingleCubeSetFitsToExistingCubes(x))
    50. End Function
    51. Private Function SingleCubeSetFitsToExistingCubes(CubeSet As CubeSet) As Boolean
    52. If CubeSet.CountOfRedCubes > ExistingCubes.CountOfRedCubes Then Return False
    53. If CubeSet.CountOfGreenCubes > ExistingCubes.CountOfGreenCubes Then Return False
    54. If CubeSet.CountOfBlueCubes > ExistingCubes.CountOfBlueCubes Then Return False
    55. Return True
    56. End Function
    57. Private Sub ShowFinalGameSetIdSumFrom(FittingGames As IEnumerable(Of GameData))
    58. MessageBox.Show(FittingGames.Sum(Function(x) x.ID).ToString)
    59. End Sub
    60. End Class
    61. Friend Class GameData
    62. Property ID As Integer
    63. Property CubeSets As New List(Of CubeSet)
    64. Sub New(ID As Integer, CubeSets As IEnumerable(Of CubeSet))
    65. Me.ID = ID
    66. Me.CubeSets.AddRange(CubeSets)
    67. End Sub
    68. End Class
    69. Friend Class CubeSet
    70. Property CountOfRedCubes As Integer
    71. Property CountOfGreenCubes As Integer
    72. Property CountOfBlueCubes As Integer
    73. Sub New(CountOfRedCubes As Integer, CountOfGreenCubes As Integer, CountOfBlueCubes As Integer)
    74. Me.CountOfRedCubes = CountOfRedCubes
    75. Me.CountOfGreenCubes = CountOfGreenCubes
    76. Me.CountOfBlueCubes = CountOfBlueCubes
    77. End Sub
    78. End Class



    Tag 2 Teil 2

    VB.NET-Quellcode

    1. Friend Class FrmMain
    2. Private ExistingCubes As CubeSet
    3. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    4. CalculateValueForDay2()
    5. End Sub
    6. Private Sub CalculateValueForDay2()
    7. SetExistingCubes(12, 13, 14)
    8. Dim GameData = CollectDataFrom("input.txt")
    9. Dim FittingGames = GetFittingGamesFrom(GameData)
    10. ShowFinalGameSetIdSumFrom(FittingGames)
    11. Dim MinimumCubeCounts = GetMinimumCubeCountFor(GameData)
    12. ShowFinalValueFrom(MinimumCubeCounts)
    13. End Sub
    14. Private Sub SetExistingCubes(CountOfRedCubes As Integer, CountOfGreenCubes As Integer, CountOfBlueCubes As Integer)
    15. ExistingCubes = New CubeSet(CountOfRedCubes, CountOfGreenCubes, CountOfBlueCubes)
    16. End Sub
    17. Private Function CollectDataFrom(FilePath As String) As IEnumerable(Of GameData)
    18. Dim ListOfGameData As New List(Of GameData)
    19. For Each RawDataLine In IO.File.ReadAllLines(FilePath)
    20. Dim MainData = RawDataLine.Split(":"c)
    21. Dim GameID = Integer.Parse(MainData(0).Substring("Game ".Length))
    22. Dim CubeSets = GetCubeSetsFrom(MainData(1).Trim)
    23. Dim NextGameData As New GameData(GameID, CubeSets)
    24. ListOfGameData.Add(NextGameData)
    25. Next
    26. Return ListOfGameData
    27. End Function
    28. Private Function GetCubeSetsFrom(RawData As String) As IEnumerable(Of CubeSet)
    29. Dim CubeSets As New List(Of CubeSet)
    30. For Each CubeSetRawData In RawData.Split(";"c)
    31. Dim CubeData = CubeSetRawData.Split(","c)
    32. Dim NewCubeSet As New CubeSet(0, 0, 0)
    33. For Each SingleCubeData In CubeData
    34. Dim SingleCubeSetRawData = SingleCubeData.Trim.Split
    35. Dim CubeCount = Integer.Parse(SingleCubeSetRawData(0))
    36. Dim CubeColorAsText = SingleCubeSetRawData(1)
    37. Select Case CubeColorAsText
    38. Case "red" : NewCubeSet.CountOfRedCubes = CubeCount
    39. Case "green" : NewCubeSet.CountOfGreenCubes = CubeCount
    40. Case "blue" : NewCubeSet.CountOfBlueCubes = CubeCount
    41. End Select
    42. Next
    43. CubeSets.Add(NewCubeSet)
    44. Next
    45. Return CubeSets
    46. End Function
    47. Private Function GetFittingGamesFrom(GameData As IEnumerable(Of GameData)) As IEnumerable(Of GameData)
    48. Return GameData.Where(Function(x) AllCubeSetsFit(x))
    49. End Function
    50. Private Function AllCubeSetsFit(SingleGameData As GameData) As Boolean
    51. Return SingleGameData.CubeSets.All(Function(x) SingleCubeSetFitsToExistingCubes(x))
    52. End Function
    53. Private Function SingleCubeSetFitsToExistingCubes(CubeSet As CubeSet) As Boolean
    54. If CubeSet.CountOfRedCubes > ExistingCubes.CountOfRedCubes Then Return False
    55. If CubeSet.CountOfGreenCubes > ExistingCubes.CountOfGreenCubes Then Return False
    56. If CubeSet.CountOfBlueCubes > ExistingCubes.CountOfBlueCubes Then Return False
    57. Return True
    58. End Function
    59. Private Sub ShowFinalGameSetIdSumFrom(FittingGames As IEnumerable(Of GameData))
    60. MessageBox.Show(FittingGames.Sum(Function(x) x.ID).ToString)
    61. End Sub
    62. Private Function GetMinimumCubeCountFor(Games As IEnumerable(Of GameData)) As IEnumerable(Of CubeSet)
    63. Return Games.Select(Function(x) GetMinimumCubeCountFor(x))
    64. End Function
    65. Private Function GetMinimumCubeCountFor(GameData As GameData) As CubeSet
    66. Dim MaximumCountOfRedCubes As Integer
    67. Dim MaximumCountOfGreenCubes As Integer
    68. Dim MaximumCountOfBlueCubes As Integer
    69. For Each CubeSet In GameData.CubeSets
    70. MaximumCountOfRedCubes = Math.Max(MaximumCountOfRedCubes, CubeSet.CountOfRedCubes)
    71. MaximumCountOfGreenCubes = Math.Max(MaximumCountOfGreenCubes, CubeSet.CountOfGreenCubes)
    72. MaximumCountOfBlueCubes = Math.Max(MaximumCountOfBlueCubes, CubeSet.CountOfBlueCubes)
    73. Next
    74. Return New CubeSet(MaximumCountOfRedCubes, MaximumCountOfGreenCubes, MaximumCountOfBlueCubes)
    75. End Function
    76. Private Sub ShowFinalValueFrom(MinimumCubeCounts As IEnumerable(Of CubeSet))
    77. MessageBox.Show(MinimumCubeCounts.Sum(Function(x) x.CountOfRedCubes * x.CountOfGreenCubes * x.CountOfBlueCubes).ToString)
    78. End Sub
    79. End Class
    80. Friend Class GameData
    81. Property ID As Integer
    82. Property CubeSets As New List(Of CubeSet)
    83. Sub New(ID As Integer, CubeSets As IEnumerable(Of CubeSet))
    84. Me.ID = ID
    85. Me.CubeSets.AddRange(CubeSets)
    86. End Sub
    87. End Class
    88. Friend Class CubeSet
    89. Property CountOfRedCubes As Integer
    90. Property CountOfGreenCubes As Integer
    91. Property CountOfBlueCubes As Integer
    92. Sub New(CountOfRedCubes As Integer, CountOfGreenCubes As Integer, CountOfBlueCubes As Integer)
    93. Me.CountOfRedCubes = CountOfRedCubes
    94. Me.CountOfGreenCubes = CountOfGreenCubes
    95. Me.CountOfBlueCubes = CountOfBlueCubes
    96. End Sub
    97. End Class


    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „VaporiZed“ ()

    Part 1

    C#-Quellcode

    1. private static void Part01()
    2. {
    3. var src = Source();
    4. var symbols = AllSymbols();
    5. var l = symbols.Length;
    6. var numbers = ToNumbers(src);
    7. var result = new List<int>();
    8. for (var i = 0; i < numbers.Count; i++)
    9. if (LegalNumber(src, symbols, numbers[i].Numbers, numbers[i].XY))
    10. result.Add(numbers[i].Numbers);
    11. Console.WriteLine($"{nameof(Part01)}: {result.Sum()}");
    12. }
    13. private static bool LegalNumber(string[] grid, string symbols, int number, (int x, int y) xy)
    14. {
    15. var nb = Neighbor();
    16. int r = xy.y, c = xy.x;
    17. var nlength = $"{number}".Length;
    18. for (var x = 0; x < nlength; x++)
    19. {
    20. for (var i = 0; i < nb.Length; i++)
    21. {
    22. if (nb[i].X + x + c >= 0 && nb[i].X + x + c < grid[r].Length &&
    23. nb[i].Y + r >= 0 && nb[i].Y + r < grid.Length)
    24. {
    25. if (grid[r + nb[i].Y][x + nb[i].X + c] == '.') continue;
    26. if (symbols.Contains(grid[r + nb[i].Y][x + nb[i].X + c]))
    27. return true;
    28. }
    29. }
    30. }
    31. return false;
    32. }

    Part 2

    C#-Quellcode

    1. private static void Part02()
    2. {
    3. var src = Source();
    4. var symbols = AllSymbols();
    5. var l = symbols.Length;
    6. var numbers = ToNumbers(src);
    7. var resultlist = new List<((int x, int y) xy, int number)>();
    8. for (var i = 0; i < numbers.Count; i++)
    9. {
    10. var xyn = SymbolXY(src, '*', numbers[i].Numbers, numbers[i].XY);
    11. if (xyn != ((-1, -1), -1))
    12. resultlist.Add(xyn);
    13. }
    14. var result = new List<int>();
    15. var res = resultlist.OrderBy(x => x.xy).ToArray();
    16. for (var i = 1; i < res.Length; i++)
    17. {
    18. var (xy, number) = res[i];
    19. if (res[i - 1].xy == xy)
    20. {
    21. var t = new List<int> { res[i - 1].number, res[i].number };
    22. for (var j = i + 1; j < res.Length; j++)
    23. if (res[j].xy != xy) break;
    24. else t.Add(res[j].number);
    25. result.Add(t.Aggregate(1, (a, b) => a * b));
    26. }
    27. }
    28. Console.WriteLine($"{nameof(Part02)}: {result.Sum()}");
    29. }
    30. private static ((int x, int y) xy, int number) SymbolXY(string[] grid, char symbols, int number, (int x, int y) xy)
    31. {
    32. var nb = Neighbor();
    33. int r = xy.y, c = xy.x;
    34. var nlength = $"{number}".Length;
    35. for (var x = 0; x < nlength; x++)
    36. {
    37. for (var i = 0; i < nb.Length; i++)
    38. {
    39. if (nb[i].X + x + c >= 0 && nb[i].X + x + c < grid[r].Length &&
    40. nb[i].Y + r >= 0 && nb[i].Y + r < grid.Length)
    41. {
    42. if (grid[r + nb[i].Y][x + nb[i].X + c] == '.') continue;
    43. if (symbols == grid[r + nb[i].Y][x + nb[i].X + c])
    44. return ((x + nb[i].X + c, r + nb[i].Y), number);
    45. }
    46. }
    47. }
    48. return ((-1, -1), -1);
    49. }

    Methodes

    C#-Quellcode

    1. private static List<(int Numbers, (int X, int Y) XY)> ToNumbers(string[] grid)
    2. {
    3. var result = new List<(int num, (int x, int y))>();
    4. for (var r = 0; r < grid.Length; r++)
    5. {
    6. var snumber = string.Empty;
    7. for (var c = 0; c < grid[r].Length; c++)
    8. {
    9. while (int.TryParse(grid[r][c].ToString(), out _))
    10. {
    11. snumber += grid[r][c++];
    12. if (c == grid[r].Length) break;
    13. }
    14. if (snumber.Length > 0)
    15. {
    16. result.Add((int.Parse(snumber), (c - snumber.Length, r)));
    17. snumber = string.Empty;
    18. }
    19. }
    20. }
    21. return result;
    22. }
    23. private static (int X, int Y)[] Neighbor() =>
    24. new[]
    25. {
    26. (-1, -1) ,(0, -1) ,(1, -1) ,
    27. (-1, 0) , (1, 0) ,
    28. (-1, 1) ,(0, 1) ,( 1, 1) ,
    29. };
    30. private static string AllSymbols()
    31. {
    32. var src = Source();
    33. var result = new StringBuilder();
    34. var sbl = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.";
    35. foreach (var lines in src)
    36. foreach (var chr in lines)
    37. if (!sbl.Contains(chr))
    38. result.Append(chr);
    39. return string.Join("", result.ToString().ToHashSet().ToArray());
    40. }

    Source

    C#-Quellcode

    1. private static string[] Source() =>
    2. [
    3. "467..114..",
    4. "...*......",
    5. "..35..633.",
    6. "......#...",
    7. "617*......",
    8. ".....+.58.",
    9. "..592.....",
    10. "......755.",
    11. "...$.*....",
    12. ".664.598..",
    13. ];