Advent of Code 2022

Es gibt 85 Antworten in diesem Thema. Der letzte Beitrag () ist von Elanda.

    Heute war es immer noch einfach, aber schon kniffliger. Dieses Puzzle hab ich in C++ gelöst.
    Spoiler anzeigen

    C-Quellcode

    1. #include <iostream>
    2. #include <fstream>
    3. #include <string>
    4. using namespace std;
    5. enum class Shapes
    6. {
    7. Rock = 1,
    8. Paper = 2,
    9. Scissors = 3,
    10. };
    11. class GameItem
    12. {
    13. public:
    14. Shapes Shape;
    15. GameItem(Shapes shape) : Shape(shape) {}
    16. GameItem(char input)
    17. {
    18. switch (input)
    19. {
    20. case 'A':
    21. case 'X':
    22. Shape = Shapes::Rock;
    23. break;
    24. case 'B':
    25. case 'Y':
    26. Shape = Shapes::Paper;
    27. break;
    28. case 'C':
    29. case 'Z':
    30. Shape = Shapes::Scissors;
    31. break;
    32. default:
    33. throw ("Illegal char");
    34. }
    35. }
    36. bool DefeatsShape(GameItem target)
    37. {
    38. switch (Shape)
    39. {
    40. case Shapes::Rock:
    41. return target.Shape == Shapes::Scissors;
    42. case Shapes::Paper:
    43. return target.Shape == Shapes::Rock;
    44. case Shapes::Scissors:
    45. return target.Shape == Shapes::Paper;
    46. default:
    47. return false;
    48. }
    49. }
    50. };
    51. int GetPoints(GameItem myItem, GameItem opponentItem)
    52. {
    53. if (myItem.Shape == opponentItem.Shape)
    54. {
    55. return (int)myItem.Shape + 3;
    56. }
    57. if (myItem.DefeatsShape(opponentItem))
    58. {
    59. return (int)myItem.Shape + 6;
    60. }
    61. return (int)myItem.Shape;
    62. }
    63. void ChangeShapeForForcedEnd(GameItem* myItem, GameItem opponentItem)
    64. {
    65. switch (myItem->Shape)
    66. {
    67. case Shapes::Paper://draw
    68. myItem->Shape = opponentItem.Shape;
    69. break;
    70. case Shapes::Rock: //lose
    71. switch (opponentItem.Shape)
    72. {
    73. case Shapes::Rock:
    74. myItem->Shape = Shapes::Scissors;
    75. break;
    76. case Shapes::Paper:
    77. myItem->Shape = Shapes::Rock;
    78. break;
    79. case Shapes::Scissors:
    80. myItem->Shape = Shapes::Paper;
    81. break;
    82. }
    83. break;
    84. case Shapes::Scissors://win
    85. switch (opponentItem.Shape)
    86. {
    87. case Shapes::Rock:
    88. myItem->Shape = Shapes::Paper;
    89. break;
    90. case Shapes::Paper:
    91. myItem->Shape = Shapes::Scissors;
    92. break;
    93. case Shapes::Scissors:
    94. myItem->Shape = Shapes::Rock;
    95. break;
    96. }
    97. break;
    98. }
    99. }
    100. int main()
    101. {
    102. std::ifstream inputFile("input.txt");
    103. if (!inputFile.is_open())
    104. {
    105. cout << "Can't open the file";
    106. return -1;
    107. }
    108. int myPointsPuzzle1 = 0;
    109. int myPointsPuzzle2 = 0;
    110. for (string line; getline(inputFile, line);)
    111. {
    112. GameItem opponentItem(line[0]);
    113. GameItem myItem(line[2]);
    114. myPointsPuzzle1 += GetPoints(myItem, opponentItem);
    115. ChangeShapeForForcedEnd(&myItem, opponentItem);
    116. myPointsPuzzle2 += GetPoints(myItem, opponentItem);
    117. }
    118. cout << myPointsPuzzle1 << endl << myPointsPuzzle2;
    119. return 0;
    120. }

    @BitBrösel da hatten wir ähnliche Gedanken:
    Spoiler anzeigen

    C#-Quellcode

    1. public static class StrategyConverter
    2. {
    3. public static int StrategyGuideScorePt1 { get; private set; }
    4. public static int StrategyGuideScorePt2 { get; private set; }
    5. public static void ReadDataAndCalculateOutcome()
    6. {
    7. using StreamReader sr = new("AoC_2 Data.txt");
    8. do
    9. {
    10. string line = sr.ReadLine();
    11. string[] strats = line.Split(' ');
    12. Game current = CalculateGameFromLinePt1(strats);
    13. StrategyGuideScorePt1 += (int)current.Me + (int)current.Outcome;
    14. current = CalculateGameFromLinePt2(strats);
    15. StrategyGuideScorePt2 += (int)current.Me + (int)current.Outcome;
    16. } while (!sr.EndOfStream);
    17. }
    18. private static Game CalculateGameFromLinePt1(string[] line)
    19. {
    20. Game current = new()
    21. {
    22. Oppopnent = line[0] switch
    23. {
    24. "A" => Handsign.Rock,
    25. "B" => Handsign.Paper,
    26. "C" => Handsign.Scissors,
    27. },
    28. Me = line[1] switch
    29. {
    30. "X" => Handsign.Rock,
    31. "Y" => Handsign.Paper,
    32. "Z" => Handsign.Scissors,
    33. }
    34. };
    35. current.Outcome = current.Oppopnent switch
    36. {
    37. Handsign.Rock => current.Me switch
    38. {
    39. Handsign.Rock => Result.Draw,
    40. Handsign.Paper => Result.Win,
    41. Handsign.Scissors => Result.Loss
    42. },
    43. Handsign.Paper => current.Me switch
    44. {
    45. Handsign.Rock => Result.Loss,
    46. Handsign.Paper => Result.Draw,
    47. Handsign.Scissors => Result.Win
    48. },
    49. Handsign.Scissors => current.Me switch
    50. {
    51. Handsign.Rock => Result.Win,
    52. Handsign.Paper => Result.Loss,
    53. Handsign.Scissors => Result.Draw
    54. }
    55. };
    56. return current;
    57. }
    58. private static Game CalculateGameFromLinePt2(string[] line)
    59. {
    60. Game current = new()
    61. {
    62. Oppopnent = line[0] switch
    63. {
    64. "A" => Handsign.Rock,
    65. "B" => Handsign.Paper,
    66. "C" => Handsign.Scissors,
    67. },
    68. Outcome = line[1] switch
    69. {
    70. "X" => Result.Loss,
    71. "Y" => Result.Draw,
    72. "Z" => Result.Win,
    73. }
    74. };
    75. current.Me = current.Oppopnent switch
    76. {
    77. Handsign.Rock => current.Outcome switch
    78. {
    79. Result.Draw => Handsign.Rock,
    80. Result.Win => Handsign.Paper,
    81. Result.Loss => Handsign.Scissors
    82. },
    83. Handsign.Paper => current.Outcome switch
    84. {
    85. Result.Draw => Handsign.Paper,
    86. Result.Win => Handsign.Scissors,
    87. Result.Loss => Handsign.Rock
    88. },
    89. Handsign.Scissors => current.Outcome switch
    90. {
    91. Result.Draw => Handsign.Scissors,
    92. Result.Win => Handsign.Rock,
    93. Result.Loss => Handsign.Paper
    94. }
    95. };
    96. return current;
    97. }
    98. }
    99. public class Game
    100. {
    101. public Handsign Oppopnent { get; set; }
    102. public Handsign Me { get; set; }
    103. public Result Outcome { get; set; }
    104. }
    105. public enum Handsign
    106. {
    107. Rock = 1,
    108. Paper,
    109. Scissors
    110. }
    111. public enum Result
    112. {
    113. Loss = 0,
    114. Draw = 3,
    115. Win = 6
    116. }

    C#-Quellcode

    1. static void Main(string[] args)
    2. {
    3. StrategyConverter.ReadDataAndCalculateOutcome();
    4. Console.WriteLine("Solution Day_2_P1:" + StrategyConverter.StrategyGuideScorePt1);
    5. Console.WriteLine("Solution Day_2_P2:" + StrategyConverter.StrategyGuideScorePt2);
    6. Console.ReadKey();
    7. }


    Edit: Auf den zweiten Blick ists doch ein wenig anders^^

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „EaranMaleasi“ ()

    Wobei mir dein Code irgendwie besser gefällt. Aber ich hab da noch eine Anmerkung zu deinem Code, den Schritt mit dem splitten kannst du einsparen.

    C#-Quellcode

    1. string s = "A B";
    2. char a = s[0];
    3. char b = s[2];


    PS: Doch ein unsinniger Gedanke, besser 1 Parameter für die Funktion beibehalten, immer besser als 2;

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „BitBrösel“ ()

    Stimmt schon, ich könnte einfach die ganze Zeilen unverändert in die Funktion geben und dann line[0] und line[2] benutzen. Jedoch macht das Split in meinen Augen eher klar, was hier passiert im Kontext mit dem restlichen Code. (Wenn ich jetzt noch die Funktionen und deren Argumente ein wenig umbenennen würde wäre es sogar Konsistent)
    Ich habe das einfach kurz runter geschrieben. Mich auch nicht ganz an die geforderten Angaben gehalten.

    Freundliche Grüsse

    exc-jdbi

    Spoiler anzeigen

    C#-Quellcode

    1. namespace AdventCalendar2022;
    2. using static RandomHolder;
    3. internal class Day02
    4. {
    5. public static void Start()
    6. {
    7. ProblemFormulation();
    8. RandomTest();
    9. }
    10. public static void RandomTest()
    11. {
    12. var count = 3;
    13. var games = new Game[count];
    14. var elements = ((Elements[])Elements.GetValues(typeof(Elements)));
    15. for (var i = 0; i < games.Length; i++)
    16. {
    17. var a = new Participant(elements[Rand.Next(elements.Length)]);
    18. var b = new Participant(elements[Rand.Next(elements.Length)]);
    19. games[i] = new Game(a, b);
    20. games[i].Score();
    21. games[i].PrintOut();
    22. }
    23. Console.WriteLine($"Result A = {games.Sum(x => x.A.Result)}; Result B = {games.Sum(x => x.B.Result)}");
    24. Console.WriteLine();
    25. Console.ReadLine();
    26. }
    27. public static void ProblemFormulation()
    28. {
    29. var games = new Game[3];
    30. var a = new Participant(Elements.Rock);
    31. var b = new Participant(Elements.Paper);
    32. games[0] = new Game(a, b);
    33. a = new Participant(Elements.Paper);
    34. b = new Participant(Elements.Rock);
    35. games[1] = new Game(a, b);
    36. a = new Participant(Elements.Scissors);
    37. b = new Participant(Elements.Scissors);
    38. games[2] = new Game(a, b);
    39. games[0].Score();
    40. games[1].Score();
    41. games[2].Score();
    42. games[0].PrintOut();
    43. games[1].PrintOut();
    44. games[2].PrintOut();
    45. Console.WriteLine($"Result A = {games.Sum(x=>x.A.Result)}; Result B = {games.Sum(x => x.B.Result)}");
    46. Console.WriteLine();
    47. Console.WriteLine();
    48. Console.ReadLine();
    49. }
    50. }
    51. internal enum Elements
    52. {
    53. Rock = 1,
    54. Paper = 2,
    55. Scissors = 3,
    56. }
    57. internal enum Assessment
    58. {
    59. Lost = 0,
    60. Drawn = 3,
    61. Win = 6,
    62. }
    63. internal class Game
    64. {
    65. public Participant A { get; private set; }
    66. public Participant B { get; private set; }
    67. public Game(Participant first, Participant seconde)
    68. {
    69. this.A = first;
    70. this.B = seconde;
    71. }
    72. public void Score()
    73. {
    74. if (A.Elements == B.Elements)
    75. {
    76. A.Assessment = B.Assessment = Assessment.Drawn;
    77. }
    78. else if (A.Elements == Elements.Rock && B.Elements == Elements.Paper)
    79. {
    80. A.Assessment = Assessment.Lost;
    81. B.Assessment = Assessment.Win;
    82. }
    83. else if (A.Elements == Elements.Rock && B.Elements == Elements.Scissors)
    84. {
    85. A.Assessment = Assessment.Win;
    86. B.Assessment = Assessment.Lost;
    87. }
    88. else if (A.Elements == Elements.Paper && B.Elements == Elements.Rock)
    89. {
    90. A.Assessment = Assessment.Win;
    91. B.Assessment = Assessment.Lost;
    92. }
    93. else if (A.Elements == Elements.Paper && B.Elements == Elements.Scissors)
    94. {
    95. A.Assessment = Assessment.Lost;
    96. B.Assessment = Assessment.Win;
    97. }
    98. else if (A.Elements == Elements.Scissors && B.Elements == Elements.Rock)
    99. {
    100. A.Assessment = Assessment.Lost;
    101. B.Assessment = Assessment.Win;
    102. }
    103. else if (A.Elements == Elements.Scissors && B.Elements == Elements.Paper)
    104. {
    105. A.Assessment = Assessment.Win;
    106. B.Assessment = Assessment.Lost;
    107. }
    108. A.Score();
    109. B.Score();
    110. }
    111. public void PrintOut()
    112. {
    113. if (A.Elements == B.Elements)
    114. {
    115. Console.WriteLine($"A: {A.Elements}; B: {B.Elements}");
    116. Console.Write($"A: Drawn: result = {A.Result}; ");
    117. Console.WriteLine($"B: Drawn: result = {B.Result}");
    118. Console.WriteLine();
    119. return;
    120. }
    121. Console.WriteLine($"A: {A.Elements}; B: {B.Elements}");
    122. var win = A.Assessment == Assessment.Win ? "A" : "B";
    123. var winassessment = A.Assessment == Assessment.Win ? A.Assessment : B.Assessment;
    124. var winresult = A.Assessment == Assessment.Win ? A.Result : B.Result;
    125. var lost = A.Assessment == Assessment.Win ? "B" : "A";
    126. var lostassessment = A.Assessment == Assessment.Win ?B.Assessment : A.Assessment;
    127. var lostresult = A.Assessment == Assessment.Win ? B.Result : A.Result;
    128. Console.WriteLine($"{win}: {winassessment}: result = {winresult}; {lost}: {lostassessment}: result = {lostresult}");
    129. Console.WriteLine();
    130. }
    131. }
    132. internal class Participant
    133. {
    134. public int Result = -1;
    135. public Elements Elements;
    136. public Assessment Assessment;
    137. public Participant(Elements element) { Elements = element; }
    138. public void Score()
    139. {
    140. Result = (int)Elements + (int)Assessment;
    141. }
    142. }
    143. internal class RandomHolder
    144. {
    145. public static Random Rand = new();
    146. public static int Next(int max)
    147. {
    148. return Next(0, max);
    149. }
    150. public static int Next(int min, int max)
    151. {
    152. return Rand.Next(min, max);
    153. }
    154. }

    Ich will mal versuchen, so weit wie möglich nur mit Expression Statements und LINQ Query Syntax zu kommen (keine Seiteneffekte/keinen imperativen Code mit Ausnahme der Ausgabe oder Assertions).

    Ich hab den Tipp gesehen, den ganzen Code mit einem Unit Test Projekt umzusetzen, damit man pro Tag einfach per VS Test Explorer den aktuellen Tag laufen lassen kann, ohne sich groß um verschiedene Projekte oder main Methoden kümmern zu müssen. Den Tipp fand ich gut - ich hab direkt mal umgestellt.

    Spoiler anzeigen

    C#-Quellcode

    1. namespace AdventOfCode2022;
    2. public sealed class Day02
    3. {
    4. private readonly ITestOutputHelper _output;
    5. public Day02(ITestOutputHelper log) => _output = log;
    6. [Theory]
    7. [InlineData("A Y\r\nB X\r\nC Z")]
    8. public void SolvePt1(string input) =>
    9. _output.WriteLine(
    10. from @in in new[] { input }
    11. let rounds =
    12. from round in input.Split("\r\n", StringSplitOptions.RemoveEmptyEntries)
    13. let other = MoveFromChar(round[0])
    14. let me = MoveFromChar(round[2])
    15. select new Round(other, me)
    16. select GetScore(rounds)
    17. );
    18. [Theory]
    19. [InlineData("A Y\r\nB X\r\nC Z")]
    20. public void SolvePt2(string input) =>
    21. _output.WriteLine(
    22. from @in in new[] { input }
    23. let rounds =
    24. from round in input.Split("\r\n", StringSplitOptions.RemoveEmptyEntries)
    25. let requiredResult = round[2] switch
    26. {
    27. 'X' => Winner.Other,
    28. 'Y' => Winner.Draw,
    29. 'Z' => Winner.Me,
    30. _ => throw new Exception(),
    31. }
    32. let other = MoveFromChar(round[0])
    33. let me = (other, requiredResult) switch
    34. {
    35. (Move.Rock, Winner.Other) => Move.Scissor,
    36. (Move.Rock, Winner.Draw) => Move.Rock,
    37. (Move.Rock, Winner.Me) => Move.Paper,
    38. (Move.Paper, Winner.Other) => Move.Rock,
    39. (Move.Paper, Winner.Draw) => Move.Paper,
    40. (Move.Paper, Winner.Me) => Move.Scissor,
    41. (Move.Scissor, Winner.Other) => Move.Paper,
    42. (Move.Scissor, Winner.Draw) => Move.Scissor,
    43. (Move.Scissor, Winner.Me) => Move.Rock,
    44. _ => throw new Exception(),
    45. }
    46. select new Round(other, me)
    47. select GetScore(rounds)
    48. );
    49. private static int GetScore(IEnumerable<Round> rounds) =>
    50. (from round in rounds
    51. let winner = round switch
    52. {
    53. { Other: Move.Rock, Me: Move.Rock } => Winner.Draw,
    54. { Other: Move.Rock, Me: Move.Paper } => Winner.Me,
    55. { Other: Move.Rock, Me: Move.Scissor } => Winner.Other,
    56. { Other: Move.Paper, Me: Move.Rock } => Winner.Other,
    57. { Other: Move.Paper, Me: Move.Paper } => Winner.Draw,
    58. { Other: Move.Paper, Me: Move.Scissor } => Winner.Me,
    59. { Other: Move.Scissor, Me: Move.Rock } => Winner.Me,
    60. { Other: Move.Scissor, Me: Move.Paper } => Winner.Other,
    61. { Other: Move.Scissor, Me: Move.Scissor } => Winner.Draw,
    62. _ => throw new Exception(),
    63. }
    64. let moveScore = (int)round.Me
    65. let resultScore = (int)winner
    66. let score = moveScore + resultScore
    67. select score).Sum();
    68. private static Move MoveFromChar(char c) =>
    69. c switch
    70. {
    71. 'X' => Move.Rock,
    72. 'Y' => Move.Paper,
    73. 'Z' => Move.Scissor,
    74. 'A' => Move.Rock,
    75. 'B' => Move.Paper,
    76. 'C' => Move.Scissor,
    77. _ => throw new Exception(),
    78. };
    79. private enum Winner
    80. {
    81. Other = 0,
    82. Draw = 3,
    83. Me = 6,
    84. }
    85. private enum Move
    86. {
    87. Rock = 1,
    88. Paper = 2,
    89. Scissor = 3,
    90. }
    91. private sealed record Round(Move Other, Move Me);
    92. }

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

    Part 1 straight forward runtergeschrieben:
    Spoiler anzeigen

    C#-Quellcode

    1. using FileStream fs = File.OpenRead("input.txt");
    2. using StreamReader sr = new StreamReader(fs);
    3. int score = 0;
    4. while (!sr.EndOfStream)
    5. {
    6. var line = sr.ReadLine()!.AsSpan();
    7. score += line[2] switch
    8. {
    9. 'X' => 1,
    10. 'Y' => 2,
    11. 'Z' => 3,
    12. _ => 0
    13. };
    14. if (RoundDraw(line[0], line[2]))
    15. {
    16. score += 3;
    17. }
    18. else if(RoundWon(line[0], line[2]))
    19. {
    20. score += 6;
    21. }
    22. }
    23. Console.WriteLine(score);
    24. sr.Close();
    25. fs.Close();
    26. bool RoundDraw(char a, char b) => (a == 'A' && b == 'X') || (a == 'B' && b == 'Y') || (a == 'C' && b == 'Z');
    27. bool RoundWon(char a, char b) => (a == 'C' && b == 'X') || (a == 'A' && b == 'Y') || (a == 'B' && b == 'Z');


    Ebenso Part 2
    Spoiler anzeigen

    C#-Quellcode

    1. using FileStream fs = File.OpenRead("input.txt");
    2. using StreamReader sr = new StreamReader(fs);
    3. int score = 0;
    4. while (!sr.EndOfStream)
    5. {
    6. var line = sr.ReadLine()!.AsSpan();
    7. score += line[2] switch
    8. {
    9. 'X' => Loose(line[0]),
    10. 'Y' => Draw(line[0]) + 3,
    11. 'Z' => Win(line[0]) + 6,
    12. _ => 0
    13. };
    14. }
    15. Console.WriteLine(score);
    16. sr.Close();
    17. fs.Close();
    18. int Loose(char a) => a switch
    19. {
    20. 'A' => 3,
    21. 'B' => 1,
    22. 'C' => 2,
    23. _ => 0
    24. };
    25. int Draw(char a) => a switch
    26. {
    27. 'A' => 1,
    28. 'B' => 2,
    29. 'C' => 3,
    30. _ => 0
    31. };
    32. int Win(char a) => a switch
    33. {
    34. 'A' => 2,
    35. 'B' => 3,
    36. 'C' => 1,
    37. _ => 0
    38. };


    Nichts besonderes, kann man bestimmt noch eindampfen :)
    Moin,

    mein 2. Tag - erster Versuch PT1 und PT2: (jetzt gehts ans kürzen)

    Spoiler anzeigen

    C#-Quellcode

    1. string[] games = File.ReadAllLines("Input.txt");
    2. int scorePt1 = 0;
    3. int scorePt2 = 0;
    4. foreach (string game in games)
    5. {
    6. scorePt1 += game[0] switch
    7. {
    8. 'A' => game[2] switch
    9. {
    10. 'X' => 1 + 3,
    11. 'Y' => 2 + 6,
    12. 'Z' => 3 + 0
    13. },
    14. 'B' => game[2] switch
    15. {
    16. 'X' => 1 + 0,
    17. 'Y' => 2 + 3,
    18. 'Z' => 3 + 6
    19. },
    20. 'C' => game[2] switch
    21. {
    22. 'X' => 1 + 6,
    23. 'Y' => 2 + 0,
    24. 'Z' => 3 + 3
    25. }
    26. };
    27. scorePt2 += game[0] switch
    28. {
    29. 'A' => game[2] switch
    30. {
    31. 'X' => 3 + 0,
    32. 'Y' => 1 + 3,
    33. 'Z' => 2 + 6
    34. },
    35. 'B' => game[2] switch
    36. {
    37. 'X' => 1 + 0,
    38. 'Y' => 2 + 3,
    39. 'Z' => 3 + 6
    40. },
    41. 'C' => game[2] switch
    42. {
    43. 'X' => 2 + 0,
    44. 'Y' => 3 + 3,
    45. 'Z' => 1 + 6
    46. }
    47. };
    48. }
    49. Console.WriteLine($"Total Day02-PT1: {scorePt1}");
    50. Console.WriteLine($"Total Day02-PT2: {scorePt2}");
    Grüße , xChRoNiKx

    Nützliche Links:
    Visual Studio Empfohlene Einstellungen | Try-Catch heißes Eisen
    Habs dann schlussendlich auch hinbekommen.
    Ohne jegliche explizite branching-statements. (ich musste mir ja unbedingt so ein doofes Handicap geben)

    Naja egal, AoC 2022 - Tag 2 (GitHub)
    Spoiler anzeigen

    C-Quellcode

    1. #include <array>
    2. #include <fstream>
    3. #include <iostream>
    4. #include <string>
    5. //**********************************************************************************************************************
    6. // region Namespace
    7. //======================================================================================================================
    8. namespace
    9. {
    10. //==================================================================================================================
    11. /** The character index of the opponents figure. */
    12. constexpr int offsetOpponent = 0;
    13. /** The character index of my figure. */
    14. constexpr int offsetMe = 2;
    15. //==================================================================================================================
    16. struct Round
    17. {
    18. //==============================================================================================================
    19. char opponent;
    20. char me;
    21. //==============================================================================================================
    22. [[nodiscard]]
    23. static Round fromInput(const std::string &input) noexcept
    24. {
    25. // This only works because we know that every line of input is consistent
    26. // Otherwise we would probably do this either by tokenisation or regexing
    27. return { static_cast<char>(input[offsetOpponent] - 'A' + 1), static_cast<char>(input[offsetMe] - 'X' + 1) };
    28. }
    29. };
    30. //==================================================================================================================
    31. // Today I learned, the modulo '%' operator is not actually doing "modulo" but "remainder" instead (this seems to be the case for every language)
    32. // So I had to search for a real modulo implementation on the webs: https://stackoverflow.com/a/12277233/13170332
    33. [[nodiscard]]
    34. constexpr long modulo(long a, long b) noexcept
    35. {
    36. return (a % b + b) % b;
    37. }
    38. //==================================================================================================================
    39. constexpr std::array<int(*)(int), 3> strategies {
    40. // lose
    41. [](int figure) -> int
    42. {
    43. return modulo((figure - 2), 3) + 1;
    44. },
    45. // draw
    46. [](int figure) -> int
    47. {
    48. return figure;
    49. },
    50. // win
    51. [](int figure) -> int
    52. {
    53. return ((figure % 3) + 1);
    54. }
    55. };
    56. //==================================================================================================================
    57. [[nodiscard]]
    58. constexpr int calculateResult(int figureOpponent, int figureMe) noexcept
    59. {
    60. const int factor = ::modulo(((figureOpponent % 3) - figureMe), 3) + 1;
    61. return 3 * (factor % 3);
    62. }
    63. }
    64. //======================================================================================================================
    65. // endregion Namespace
    66. //**********************************************************************************************************************
    67. // region Main
    68. //======================================================================================================================
    69. int main()
    70. {
    71. std::fstream file(INPUT_FILE);
    72. std::string input;
    73. int opponent_points = 0;
    74. int my_points = 0;
    75. int opponent_actual_points = 0;
    76. int my_actual_points = 0;
    77. while (std::getline(file, input))
    78. {
    79. const ::Round round = ::Round::fromInput(input);
    80. // The drama of guessing what a column means
    81. const int result = ::calculateResult(round.opponent, round.me);
    82. opponent_points += (round.opponent + result);
    83. my_points += (round.me + (6 - result));
    84. // The drama of then actually hearing what it really is about
    85. const int needed_fig = strategies[round.me - 1](round.opponent);
    86. // Would probably be better to cache all possible results inside a lookup table and make a lookup instead
    87. // of calculating it everytime again, but... idrc
    88. const int result_2 = ::calculateResult(round.opponent, needed_fig);
    89. opponent_actual_points += (round.opponent + result_2);
    90. my_actual_points += (needed_fig + (6 - result_2));
    91. }
    92. std::cout << "I have won with " << my_points << " points, hooray! (opponent has: " << opponent_points << ")\n";
    93. std::cout << "For real though, actually I won with " << my_actual_points
    94. << " points, hooray! (opponent has: " << opponent_actual_points << ')';
    95. return 0;
    96. }
    97. //======================================================================================================================
    98. // endregion Main
    99. //**********************************************************************************************************************

    ----------------------------------------------------------------------------------------------------------------------

    Hier könnte meine Signatur stehen, aber die ist mir abfußen gekommen.

    ----------------------------------------------------------------------------------------------------------------------

    Hab es jetzt erst gesehen und konnte nicht widerstehen || Tag 1 und Tag 2

    Tag 1

    Teil 1 C#
    Spoiler anzeigen

    C#-Quellcode

    1. List<int> ElvesCals= new List<int>();
    2. var CalCount = 0;
    3. foreach (var line in File.ReadAllLines("CodeAdvent_1.txt").ToList())
    4. {
    5. if (string.IsNullOrWhiteSpace(line))
    6. {
    7. ElvesCals.Add(CalCount);
    8. CalCount = 0;
    9. }
    10. else
    11. {
    12. CalCount += int.Parse(line);
    13. }
    14. }
    15. Console.WriteLine($"{ElvesCals.Max()}");


    Noch nicht schön da ​if (string.IsNullOrWhiteSpace(line)) noch darauf angewiesen ist, dass in der Textdatei am Ende noch eine Leerzeile angefügt werden muss. Da der letzte 'Block' sonst nicht gezählt wird.

    Teil 2 C#
    Spoiler anzeigen

    C#-Quellcode

    1. List<int> ElvesCals= new List<int>();
    2. var CalCount = 0;
    3. foreach (var line in File.ReadAllLines("CodeAdvent_1.txt").ToList())
    4. {
    5. if (string.IsNullOrWhiteSpace(line))
    6. {
    7. ElvesCals.Add(CalCount);
    8. CalCount = 0;
    9. }
    10. else
    11. {
    12. CalCount += int.Parse(line);
    13. }
    14. }
    15. for (int i = 0; i < 3; i++)
    16. {
    17. CalCount += ElvesCals.Max();
    18. _= ElvesCals.Remove(ElvesCals.Max());
    19. }
    20. Console.WriteLine($"{CalCount}");​


    Tag 2

    Teil 1 C#
    Spoiler anzeigen

    C#-Quellcode

    1. var Player2FinalScore = 0;
    2. foreach (var line in File.ReadAllLines("CodeAdvent_2.txt").ToList())
    3. {
    4. Player2FinalScore += CalcPlayer2Score(ConvertInput(line.Substring(0, 1)), ConvertInput(line.Substring(2, 1)));
    5. }
    6. Console.WriteLine($"MyScore: {Player2FinalScore}");
    7. Console.ReadLine();
    8. int ConvertInput(string input)
    9. {
    10. return input switch
    11. {
    12. "A" or "X" => 1,
    13. "B" or "Y" => 2,
    14. "C" or "Z" => 3,
    15. _ => 0,
    16. };
    17. }
    18. int CalcPlayer2Score(int player1Move, int player2Move)
    19. {
    20. var player2Score = player2Move;
    21. if (player1Move == player2Move)
    22. return player2Score + 3;
    23. if (player1Move - player2Move == -1 || player1Move - player2Move == 2)
    24. return player2Score + 6;
    25. return player2Score;
    26. }


    Teil 2 C#
    Etwas messy da ich Teil eins weiterverwendet habe.
    Spoiler anzeigen

    C#-Quellcode

    1. var Player2FinalScore = 0;
    2. foreach (var line in File.ReadAllLines("CodeAdvent_2.txt").ToList())
    3. {
    4. Player2FinalScore += CalcPlayer2Score(ConvertInput(line.Substring(0, 1)), ConvertInput(line.Substring(2, 1)));
    5. }
    6. Console.WriteLine($"MyScore: {Player2FinalScore}");
    7. Console.ReadLine();
    8. int ConvertInput(string input)
    9. {
    10. return input switch
    11. {
    12. "A" or "X" => 1,
    13. "B" or "Y" => 2,
    14. "C" or "Z" => 3,
    15. _ => 0,
    16. };
    17. }
    18. int CalcPlayer2Score(int player1Move, int player2Move)
    19. {
    20. if (player2Move == 1)
    21. {//X = 1 => Lose
    22. return player1Move switch
    23. {
    24. 1 => 3,
    25. 2 => 1,
    26. 3 => 2,
    27. _ => 0
    28. };
    29. }
    30. if (player2Move == 2)
    31. {//Y = 2 => Draw
    32. return player1Move switch
    33. {
    34. 1 => 1 + 3,
    35. 2 => 2 + 3,
    36. 3 => 3 + 3,
    37. _ => 0
    38. };
    39. }
    40. if (player2Move == 3)
    41. {//Z = 3 => Win
    42. return player1Move switch
    43. {
    44. 1 => 2 + 6,
    45. 2 => 3 + 6,
    46. 3 => 1 + 6,
    47. _ => 0
    48. };
    49. }
    50. return 0;
    51. }
    codewars.com Rank: 4 kyu

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

    Die Erste ist funktional, und die zweite eine kleine LINQ-Variante.

    Nachtrag: LINQ-Variante

    Freundliche Grüsse

    exc-jdbi


    Spoiler anzeigen

    C#-Quellcode

    1. using System.Text;
    2. namespace AdventCalendar2022;
    3. using static RandomHolder;
    4. internal class Day03
    5. {
    6. private const string Chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
    7. public static void Start()
    8. {
    9. Test01();
    10. RandomTest();
    11. }
    12. private static void RandomTest()
    13. {
    14. var src = RngSource(6);
    15. var commonsign = new StringBuilder();
    16. foreach (var str in src)
    17. commonsign.Append(CommonSign(str));
    18. var priority = CalcPriority(commonsign.ToString());
    19. Console.WriteLine($"Common Sign = {commonsign}; priority = {priority}");
    20. Console.WriteLine();
    21. Console.ReadLine();
    22. }
    23. private static void Test01()
    24. {
    25. var src = Source();
    26. var commonsign = new StringBuilder();
    27. foreach (var str in src)
    28. commonsign.Append(CommonSign(str));
    29. var priority = CalcPriority(commonsign.ToString());
    30. Console.WriteLine($"Common Sign = {commonsign}; priority = {priority}");
    31. Console.WriteLine();
    32. Console.ReadLine();
    33. }
    34. private static int CalcPriority(string source)
    35. {
    36. var result = 0;
    37. foreach (var c in source)
    38. result += Chars.IndexOf(c) + 1;
    39. return result;
    40. }
    41. private static char CommonSign(string source)
    42. {
    43. var split = HalfString(source);
    44. foreach (var c in split[0])
    45. if (split[1].Contains(c))
    46. return c;
    47. return char.MinValue;
    48. }
    49. private static string[] HalfString(string source)
    50. {
    51. var half = source.Length / 2;
    52. var str1 = source[..half]; //Substring(0, half);
    53. var str2 = source[half..]; //Substring(half);
    54. return new string[] { str1, str2 };
    55. }
    56. private static string[] RngSource(int knapsackcount, int min = 16, int max = 32)
    57. {
    58. var chars = Enumerable.Range(0, knapsackcount).Select(x => RngChars(Rand.Next(min, max))).ToArray();
    59. char ch;
    60. for (var i = 0; i < chars.Length; i++)
    61. {
    62. var halflength = chars[i].Length / 2;
    63. ch = chars[i][Rand.Next(halflength)];
    64. chars[i][halflength + Rand.Next(halflength)] = ch;
    65. }
    66. return ToStrings(chars);
    67. }
    68. private static string[] ToStrings(char[][] source)
    69. {
    70. var result = new string[source.Length];
    71. for (var i = 0; i < result.Length; i++)
    72. result[i] = string.Join(string.Empty, source[i]);
    73. return result;
    74. }
    75. private static char[] RngChars(int size)
    76. {
    77. if ((size & 1 )== 1) size += 1;
    78. return Chars.OrderBy(x => Rand.Next()).Take(size).ToArray();
    79. }
    80. private static string[] Source()
    81. {
    82. return new string[]
    83. {
    84. "vJrwpWtwJgWrhcsFMMfFFhFp",
    85. "jqHRNqRjqzjGDLGLrsFMfFZSrLrFZsSL",
    86. "PmmdzqPrVvPwwTWBwg",
    87. "wMqvLMZHhHMvwLHjbvcjnnSBnvTQFn",
    88. "ttgJtRGJQctTZtZT",
    89. "CrZsJsPPZsGzwwsLwLmpwMDw"
    90. };
    91. }
    92. }


    Spoiler anzeigen

    C#-Quellcode

    1. private static void Start()
    2. {
    3. var src = Source();
    4. var data = src.Select(str =>
    5. {
    6. var c = str[..(str.Length / 2)].Where(ch => str[(str.Length / 2)..].Contains(ch)).First();
    7. var idx = (c > 96) ? c - 96 : c - 38;
    8. return (c, idx);
    9. });
    10. var priority = data.Sum(itm => itm.idx);
    11. var commonsign = string.Join(string.Empty, data.Select(d => d.c).ToArray());
    12. PrintOut(src, commonsign, priority);
    13. Console.ReadLine();
    14. }
    15. private static void PrintOut(string[] source, string commonsign, int priority)
    16. {
    17. Array.ForEach(source, str => Console.WriteLine(str));
    18. Console.WriteLine();
    19. Console.WriteLine($"Common Sign = {commonsign}; priority = {priority}");
    20. Console.WriteLine();
    21. Console.WriteLine();
    22. }
    23. private static string[] Source()
    24. {
    25. return new string[]
    26. {
    27. "vJrwpWtwJgWrhcsFMMfFFhFp",
    28. "jqHRNqRjqzjGDLGLrsFMfFZSrLrFZsSL",
    29. "PmmdzqPrVvPwwTWBwg",
    30. "wMqvLMZHhHMvwLHjbvcjnnSBnvTQFn",
    31. "ttgJtRGJQctTZtZT",
    32. "CrZsJsPPZsGzwwsLwLmpwMDw"
    33. };
    34. }

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

    Tag 3

    Heute musste ich schon deutlich mehr Zeit ins Debugging und Aufgabenstellung lesen/verstehen stecken.

    Teil 1 C#
    Spoiler anzeigen

    C#-Quellcode

    1. var Lines = File.ReadAllLines("CodeAdvent_3.txt");
    2. var Sum = 0;
    3. foreach (var line in Lines)
    4. {
    5. var firstHalf = line.Substring(0, line.Length/2).ToCharArray().Distinct();
    6. var secondHalf = line.Substring((line.Length/2), line.Length/2).ToCharArray().Distinct();
    7. var res = firstHalf.Where(x => secondHalf.Contains(x)).First();
    8. var myint = (int)res;
    9. if (myint <= 90)
    10. myint -= 38;
    11. if (myint >= 97)
    12. myint -= 96;
    13. Sum += myint;
    14. }
    15. Console.WriteLine(Sum);


    Teil 2 C#
    Spoiler anzeigen

    C#-Quellcode

    1. var Lines = File.ReadAllLines("CodeAdvent_3.txt");
    2. var Sum = 0;
    3. for (int i = 0; i < Lines.Length; i+=3)
    4. {
    5. var elf1 = Lines[i+0].ToCharArray().Distinct();
    6. var elf2 = Lines[i+1].ToCharArray().Distinct();
    7. var elf3 = Lines[i+2].ToCharArray().Distinct();
    8. var elf1Andelf2Same = elf1.Where(x => elf2.Contains(x));
    9. var elfBadge = elf1Andelf2Same.Where(x => elf3.Contains(x)).First();
    10. var myInt = (int)elfBadge;
    11. if (myInt <= 90)
    12. myInt -= 38;
    13. if (myInt >= 97)
    14. myInt -= 96;
    15. Sum += myInt;
    16. }
    17. Console.WriteLine(Sum);


    Es riecht nach LINQ One-Liner ...
    codewars.com Rank: 4 kyu

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

    nogood schrieb:

    Es riecht nach LINQ One-Liner ...

    Ja so in der Art.

    Tag 03 Part 1 und 2:
    Spoiler anzeigen

    Wenn man sich die ASCI Tabelle anschaut: yorktown.cbe.wwu.edu/sandvig/shared/asciicodes.aspx
    Fällt einem sicher schnell auf das die Buchstaben a bis z die Zahlen 97 - 122 sind und A bis Z 65 - 90.
    Um also die Prio zu bekommen brauchen wir bei Buchstaben die einen Zahlenwert größer 96 haben immer nur MINUS 96 rechnen Beispiel: h = 104 - 96 = 8.

    Für den ersten Part machen wir die Zeile zu nem CharArray -> holen uns per Chunk genau die hälfte und haben damit 2 "chunks".
    Danach prüfen wir einfach welche Chars vom ersten Chunk sind auch im 2. Chunk vorhanden (Intersect) und holen uns davon den ersten ( es gibt immer nur einen ).
    Das summieren wir per Sum mit der Funktion score.

    Für den 2. Part holen wir uns uns immer 3 Zeilen nutzen Aggregate um mit Intersect für jede Zeile alle Buchstaben / Item types zu bekommen die in allen vorhanden sind.
    Ich kann Aggregate ganz schlecht selbst erklären dafür gibt es das: Aggregate im Prinzip führt Aggregate diese Funktion jetzt immer mit den Werten des Ergebnisses vom vorherigen Aufruf aus.
    Im Example auf der Seite haben wir ja folgende Lines:

    vJrwpWtwJgWrhcsFMMfFFhFp
    jqHRNqRjqzjGDLGLrsFMfFZSrLrFZsSL
    PmmdzqPrVvPwwTWBwg

    Jetzt prüft Aggregate erstmal welche gleichen Zeichen es gibt von der 1. und der 2. Zeile die übrig gebliebenen Zeichen ( hier jetzt "rsFMf" ) pack ich mit ToArray in ein char array.
    Nun nimmt Aggregate das CharArray vom ersten Aufruf "rsFMf" und vergleich das mit der 3. Zeile "PmmdzqPrVvPwwTWBwg". Jetzt bleib nur noch "r" übrig das geht in ein CharArray.
    Da hier dann nur noch eins möglich sein kann nehme ich mit First das erste und habe damit mein Ergebnis. Diesen Char pack ich wieder in die Score Funktion und habe damit das Ergebnis.

    Ich bin echt schlecht im erklären hoffe aber das dies etwas Licht ins dunkle bringt.

    C#-Quellcode

    1. string[] lines = File.ReadAllLines("Input.txt");
    2. int score(char c)
    3. {
    4. return (c > 96) ? c - 96 : c - 38;
    5. }
    6. Console.WriteLine(lines
    7. .Select(e => e.ToCharArray().Chunk(e.Length / 2))
    8. .Select(r => r.First().Intersect(r.Last()).First())
    9. .Sum(score));
    10. Console.WriteLine(lines
    11. .Select(e => e.ToCharArray()).Chunk(3)
    12. .Select(e => e.Aggregate((r, t) => r.Intersect(t).ToArray()).First())
    13. .Sum(score));
    Grüße , xChRoNiKx

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

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

    Part 1
    Spoiler anzeigen

    C#-Quellcode

    1. using var sr = new StreamReader(File.OpenRead("input.txt"));
    2. Stack<char> containing = new();
    3. while (!sr.EndOfStream)
    4. {
    5. var line = sr.ReadLine()!.AsSpan();
    6. var s = (line.Length / 2);
    7. var f = line[..s];
    8. var l = line[s..];
    9. for (int i = 0; i < f.Length; ++i)
    10. {
    11. if (l.Contains(f[i]))
    12. {
    13. containing.Push(f[i]);
    14. break;
    15. }
    16. }
    17. }
    18. int prio = 0;
    19. while (containing.Count > 0)
    20. {
    21. char c = containing.Pop();
    22. prio += c switch
    23. {
    24. >= (char)97 => (c - 97) + 1,
    25. >= (char)65 => (c - 65) + 27,
    26. _ => 0
    27. };
    28. }
    29. sr.Close();
    30. Console.WriteLine(prio);


    Und Part 2
    Spoiler anzeigen

    C#-Quellcode

    1. using var sr = new StreamReader(File.OpenRead(@"D:\Dev\net\AdventOfCode22\Day3\input.txt"));
    2. Stack<char> containing = new();
    3. Stack<string> group = new();
    4. while (!sr.EndOfStream)
    5. {
    6. group.Push(sr.ReadLine());
    7. if (group.Count == 3)
    8. {
    9. ReadOnlySpan<char> g1 = group.Pop().AsSpan();
    10. ReadOnlySpan<char> g2 = group.Pop().AsSpan();
    11. ReadOnlySpan<char> g3 = group.Pop().AsSpan();
    12. for (int i = 0; i < g3.Length; ++i)
    13. {
    14. if (g1.Contains(g3[i]) && g2.Contains(g3[i]))
    15. {
    16. containing.Push(g3[i]);
    17. break;
    18. }
    19. }
    20. }
    21. }
    22. int prio = 0;
    23. while (containing.Count > 0)
    24. {
    25. char c = containing.Pop();
    26. prio += c switch
    27. {
    28. >= (char)97 => (c - 97) + 1,
    29. >= (char)65 => (c - 65) + 27,
    30. _ => 0
    31. };
    32. }
    33. sr.Close();
    34. Console.WriteLine(prio);


    Edit: Ich habe mal Part 1 von diesem Tag in AL umgesetzt. :whistling:
    Spoiler anzeigen

    Quellcode

    1. codeunit 50100 Day3
    2. {
    3. trigger OnRun()
    4. var
    5. ServerFileName: Text;
    6. WindowTitleTxt: Label 'Choose Input File';
    7. begin
    8. // Dateien können nur auf dem Service-Tier verarbeitet werden
    9. ServerFileName := FileManagement.UploadFile(WindowTitleTxt, '');
    10. Message(
    11. Format(
    12. CalculatePriorityInRucksack(ServerFileName)));
    13. // Aufräumen
    14. FileManagement.DeleteServerFile(ServerFileName);
    15. end;
    16. var
    17. FileManagement: Codeunit "File Management";
    18. local procedure CalculatePriorityInRucksack(ServerFileName: Text): Integer
    19. var
    20. StreamReader: Codeunit DotNet_StreamReader;
    21. Encoding: Codeunit DotNet_Encoding;
    22. InputFile: File;
    23. FileInStream: InStream;
    24. Line: Text;
    25. Items: List of [Char];
    26. Priority: Integer;
    27. begin
    28. Priority := 0;
    29. if not InputFile.Open(ServerFileName) then
    30. exit;
    31. InputFile.CreateInStream(FileInStream);
    32. Encoding.UTF8();
    33. StreamReader.StreamReader(FileInStream, Encoding);
    34. while not StreamReader.EndOfStream() do begin
    35. Items.Add(CollectContainingItems(StreamReader.ReadLine()));
    36. end;
    37. Priority := CalculatePriority(Items);
    38. StreamReader.Close();
    39. StreamReader.Dispose();
    40. exit(Priority);
    41. end;
    42. local procedure CollectContainingItems(Line: Text) Item: Char
    43. var
    44. i: Integer;
    45. j: Integer;
    46. Len: Integer;
    47. FirstHalf: Text;
    48. SecondHalf: Text;
    49. begin
    50. Len := StrLen(Line) / 2;
    51. FirstHalf := CopyStr(Line, 1, Len);
    52. SecondHalf := CopyStr(Line, Len + 1);
    53. for i := 1 to StrLen(FirstHalf) do
    54. for j := 1 to StrLen(SecondHalf) do
    55. if FirstHalf[i] = SecondHalf[j] then
    56. exit(FirstHalf[i]);
    57. end;
    58. local procedure CalculatePriority(Items: List of [Char]) Priority: Integer
    59. var
    60. c: Char;
    61. begin
    62. Priority := 0;
    63. foreach c in Items do
    64. case true of
    65. c >= 97:
    66. Priority += (c - 97) + 1;
    67. c >= 65:
    68. Priority += (c - 65) + 27;
    69. end;
    70. end;
    71. }

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

    Heute mal wieder komplett übertrieben aber gut... mein Handicap heute war "nur C++ Templates" (es geht bestimmt auch kürzer, aber ich nehme immer das erste das funktioniert für AoC)

    AoC 2022 - Tag 3 (GitHub)
    Spoiler anzeigen

    C-Quellcode

    1. #include <algorithm>
    2. #include <array>
    3. #include <iostream>
    4. #include <string_view>
    5. //**********************************************************************************************************************
    6. // region Namespace
    7. //======================================================================================================================
    8. namespace
    9. {
    10. //==================================================================================================================
    11. // We include the input as an array
    12. constexpr std::array input {
    13. #include "input.txt"
    14. };
    15. constexpr std::size_t maxCompartmentSize = []()
    16. {
    17. std::size_t max = 0;
    18. for (const char *rucksack : input)
    19. {
    20. const std::string_view entry { rucksack };
    21. const std::size_t csize = (entry.length() / 2);
    22. if (csize > max)
    23. {
    24. max = csize;
    25. }
    26. }
    27. return max;
    28. }();
    29. constexpr std::size_t priorityOffsetLower = ('a' - 1);
    30. constexpr std::size_t priorityOffsetUpper = ('A' - 27);
    31. //==================================================================================================================
    32. using UniqueArray = std::array<char, maxCompartmentSize>;
    33. //==================================================================================================================
    34. [[nodiscard]]
    35. constexpr auto filterCompartmentDuplicates(std::string_view data)
    36. {
    37. UniqueArray buffer {};
    38. int index = 0;
    39. for (const char c : data)
    40. {
    41. auto it = buffer.begin();
    42. for (; *it != 0; ++it)
    43. {
    44. if (*it == c)
    45. {
    46. break;
    47. }
    48. }
    49. if (*it == 0)
    50. {
    51. buffer[index++] = c;
    52. }
    53. }
    54. return buffer;
    55. }
    56. //==================================================================================================================
    57. template<const auto &AllInputs, std::size_t Index>
    58. struct Group
    59. {
    60. //==============================================================================================================
    61. using NextGroup = std::conditional_t<((Index + 3) == AllInputs.size()), void, Group<AllInputs, Index + 3>>;
    62. //==============================================================================================================
    63. static constexpr std::array<std::string_view, 3> group {
    64. AllInputs[Index],
    65. AllInputs[Index + 1],
    66. AllInputs[Index + 2]
    67. };
    68. };
    69. template<const auto &AllInputs, std::size_t Index>
    70. struct Entry
    71. {
    72. static constexpr std::string_view value = AllInputs[Index];
    73. };
    74. template<class Input, std::size_t Offset, std::size_t Length>
    75. struct Compartment
    76. {
    77. static constexpr std::string_view inventory = std::string_view(Input::value).substr(Offset, Length);
    78. };
    79. template<class Input>
    80. struct Rucksack
    81. {
    82. //==============================================================================================================
    83. static constexpr std::string_view input { Input::value };
    84. static constexpr std::size_t inventoryOffset = (input.size() / 2);
    85. //==============================================================================================================
    86. using Compartment1 = Compartment<Input, 0, inventoryOffset>;
    87. using Compartment2 = Compartment<Input, inventoryOffset, (input.length() - inventoryOffset)>;
    88. //==============================================================================================================
    89. [[nodiscard]]
    90. static constexpr std::size_t calculatePriorities() noexcept
    91. {
    92. std::size_t priorities = 0;
    93. const UniqueArray filtered = filterCompartmentDuplicates(Compartment1::inventory);
    94. for (auto it = filtered.begin(); *it != 0; ++it)
    95. {
    96. const char c = *it;
    97. for (const char c2 : Compartment2::inventory)
    98. {
    99. if (c == c2)
    100. {
    101. // Upper
    102. if (c <= 'Z')
    103. {
    104. priorities += (c - priorityOffsetUpper);
    105. }
    106. // Lower
    107. else
    108. {
    109. priorities += (c - priorityOffsetLower);
    110. }
    111. break;
    112. }
    113. }
    114. }
    115. return priorities;
    116. }
    117. };
    118. template<std::size_t Size, std::size_t Offset, class Sequence = std::make_index_sequence<Size>>
    119. struct make_index_sequence_off;
    120. template<std::size_t Size, std::size_t ...Indices, std::size_t Offset>
    121. struct make_index_sequence_off<Size, Offset, std::index_sequence<Indices...>>
    122. {
    123. using type = std::index_sequence<Indices + Offset...>;
    124. };
    125. template<std::size_t Size, std::size_t Offset>
    126. using make_index_sequence_off_t = typename make_index_sequence_off<Size, Offset>::type;
    127. // A simple placeholder with a list of index sequences, we can unpack this one to make use of them individually
    128. template<class ...IndexSequences>
    129. struct ISeqArray {};
    130. // We want to split up our indices into several std::index_sequence types
    131. template<std::size_t Size, std::size_t LastSize, class ...Sequences>
    132. struct IndexSequenceSplitter
    133. : IndexSequenceSplitter<Size,
    134. LastSize + std::min<std::size_t>(Size - LastSize, 50),
    135. Sequences...,
    136. make_index_sequence_off_t<std::min<std::size_t>(Size - LastSize, 50), LastSize>>
    137. {};
    138. template<std::size_t Size, class ...Sequences>
    139. struct IndexSequenceSplitter<Size, Size, Sequences...>
    140. {
    141. using type = ISeqArray<Sequences...>;
    142. };
    143. // We want to split up our fold expressions to max 50 calculations, because there is a limit to them (which we are exceeding)
    144. template<const auto &AllInputs, std::size_t Result, class ...IndexSequences>
    145. struct FoldExpressionSplitter;
    146. template<const auto &AllInputs, std::size_t Result, class ...OtherSequences, std::size_t ...CurrentIndices>
    147. struct FoldExpressionSplitter<AllInputs, Result, std::index_sequence<CurrentIndices...>, OtherSequences...>
    148. : FoldExpressionSplitter<AllInputs,
    149. Result + (Rucksack<Entry<AllInputs, CurrentIndices>>::calculatePriorities() + ...),
    150. OtherSequences...>
    151. {};
    152. template<const auto &AllInputs, std::size_t Result, std::size_t ...CurrentIndices>
    153. struct FoldExpressionSplitter<AllInputs, Result, std::index_sequence<CurrentIndices...>>
    154. {
    155. static constexpr std::size_t value
    156. = (Result + (Rucksack<Entry<AllInputs, CurrentIndices>>::calculatePriorities() + ...));
    157. };
    158. // A tiny wrapper
    159. template<const auto &AllInputs, class IndexSequenceArray>
    160. struct PriorityEvaluator;
    161. template<const auto &AllInputs, class ...IndexSequences>
    162. struct PriorityEvaluator<AllInputs, ISeqArray<IndexSequences...>>
    163. {
    164. static constexpr int priorities = FoldExpressionSplitter<AllInputs, 0, IndexSequences...>::value;
    165. };
    166. // Evaluates all badge's priorities
    167. template<class Group>
    168. struct BadgeEvaluator
    169. {
    170. private:
    171. using Next = typename Group::NextGroup;
    172. //==============================================================================================================
    173. static constexpr std::size_t evaluateGroup()
    174. {
    175. for (const char c : Group::group[0])
    176. {
    177. for (const char c2 : Group::group[1])
    178. {
    179. if (c == c2)
    180. {
    181. for (const char c3 : Group::group[2])
    182. {
    183. if (c2 == c3)
    184. {
    185. // Upper
    186. if (c <= 'Z')
    187. {
    188. return (c - priorityOffsetUpper);
    189. }
    190. // Lower
    191. else
    192. {
    193. return (c - priorityOffsetLower);
    194. }
    195. break;
    196. }
    197. }
    198. }
    199. }
    200. }
    201. return 0;
    202. }
    203. static constexpr std::size_t getNext()
    204. {
    205. if constexpr (std::is_same_v<Next, void>)
    206. {
    207. return 0;
    208. }
    209. else
    210. {
    211. return BadgeEvaluator<Next>::priorities;
    212. }
    213. }
    214. public:
    215. static constexpr std::size_t priorities = evaluateGroup() + getNext();
    216. };
    217. }
    218. //======================================================================================================================
    219. // endregion Namespace
    220. //**********************************************************************************************************************
    221. // region Main
    222. //======================================================================================================================
    223. int main()
    224. {
    225. using IndexList = ::IndexSequenceSplitter<::input.size(), 0>::type;
    226. std::cout << "All duplicates priorities is: " << ::PriorityEvaluator<::input, IndexList>::priorities << '\n';
    227. std::cout << "All badge's priorities is: " << ::BadgeEvaluator<::Group<::input, 0>>::priorities << '\n';
    228. return 0;
    229. }
    230. //======================================================================================================================
    231. // endregion Main
    232. //**********************************************************************************************************************



    Edit: Wollte nur noch erwähnen, an die C++ devs die das hier lesen, bitte nehmt euch kein Beispiel an diesem Code.
    Dieser ist inkonsequent sowohl mit den Typen als auch den Entitäten, nicht geordnet und da ist viel unnötiger Clutter den es eigentlich nicht bräuchte.
    Ich wollte es, mit meinem Handicap, nur so schnell zum laufen bringen wie möglich.
    ----------------------------------------------------------------------------------------------------------------------

    Hier könnte meine Signatur stehen, aber die ist mir abfußen gekommen.

    ----------------------------------------------------------------------------------------------------------------------

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

    nogood schrieb:

    Könntest Du noch ein, zwei Sätze zu Deiner Lösung schreiben. DANKE


    Hab ich oben mal hinzu editiert im Spoiler ich hoffe ist verständlich... Bin echt schlecht im Erklären mancher dinge. Zum Post
    Grüße , xChRoNiKx

    Nützliche Links:
    Visual Studio Empfohlene Einstellungen | Try-Catch heißes Eisen
    @nogood Jetzt wo du es erwähnst, villeicht hätte ich den Thread in "Weitere Sprachen und sprachübergreifende Themen" erstellen sollen, so off-topic is das ganze ja nun auch wieder nicht.

    @Marcus Gräfe, wäre das "thematisch" bitte möglich diesen Thread zu verschieben? Es ist ja eigentlich on-topic. (Dieses Wort hab ich auch noch nie verwendet)
    ----------------------------------------------------------------------------------------------------------------------

    Hier könnte meine Signatur stehen, aber die ist mir abfußen gekommen.

    ----------------------------------------------------------------------------------------------------------------------

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

    Tag 4

    Teil1 & Teil2 C#
    Spoiler anzeigen

    C#-Quellcode

    1. using System.Text.RegularExpressions;
    2. //--Main
    3. List<Match> SectionLimits = new();
    4. List<ElfTeam> ElvesTeams = new();
    5. var Lines = File.ReadAllLines("CodeAdvent_4.txt");
    6. foreach (var line in Lines)
    7. {
    8. SectionLimits = Regex.Matches(line, @"\d+").ToList();
    9. ElvesTeams.Add(new ElfTeam(int.Parse(SectionLimits[0].Value), int.Parse(SectionLimits[1].Value), int.Parse(SectionLimits[2].Value), int.Parse(SectionLimits[3].Value)));
    10. }
    11. Console.WriteLine($"Is Overlapping: {ElvesTeams.Where(x => x.IsOverlapping).ToList().Count}");
    12. Console.WriteLine($"Is FullyOverlapping: {ElvesTeams.Where(x => x.IsFullyOverlapping).ToList().Count}");
    13. //--Class
    14. class ElfTeam
    15. {
    16. public ElfTeam(int elf1Low, int elf1High, int elf2Low, int elf2High)
    17. {
    18. Elf1Low = elf1Low;
    19. Elf1High = elf1High;
    20. Elf2Low = elf2Low;
    21. Elf2High = elf2High;
    22. SetIsOverlapping();
    23. SetIsFullyOverlapping();
    24. }
    25. public int Elf1Low { get; set; } = 0;
    26. public int Elf1High { get; set; } = 0;
    27. public int Elf2Low { get; set; } = 0;
    28. public int Elf2High { get; set; } = 0;
    29. public bool IsOverlapping { get; set; } = false;
    30. public bool IsFullyOverlapping { get; set; } = false;
    31. private void SetIsOverlapping()
    32. {
    33. if (Elf1Low <= Elf2Low && Elf1High >= Elf2Low || Elf1High >= Elf2High && Elf1High <= Elf2Low)
    34. IsOverlapping = true;
    35. if (Elf2Low <= Elf1Low && Elf2High >= Elf1Low || Elf2High >= Elf1High && Elf2High <= Elf1Low)
    36. IsOverlapping = true;
    37. }
    38. private void SetIsFullyOverlapping()
    39. {
    40. if (Elf1Low <= Elf2Low && Elf1High >= Elf2High)
    41. IsFullyOverlapping = true;
    42. if (Elf2Low <= Elf1Low && Elf2High >= Elf1High)
    43. IsFullyOverlapping = true;
    44. }
    45. }
    codewars.com Rank: 4 kyu

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