Advent of Code 2022

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

    Day 4, Part 1:

    Spoiler anzeigen

    C#-Quellcode

    1. namespace Four;
    2. public class Program
    3. {
    4. static void Main(string[] args)
    5. {
    6. string[] data = File.ReadAllLines("input.txt");
    7. int sum = 0;
    8. for (int i = 0; i < data.Length; i++)
    9. sum += CheckPair(data[i]);
    10. Console.WriteLine(sum);
    11. }
    12. static int CheckPair(string input)
    13. {
    14. var elements = input.Split(new string[] { "-", "," }, StringSplitOptions.RemoveEmptyEntries).Select(x => int.Parse(x)).ToList();
    15. var list1 = Enumerable.Range(elements[0], (elements[1] - elements[0]) + 1).ToList();
    16. var list2 = Enumerable.Range(elements[2], (elements[3] - elements[2]) + 1).ToList();
    17. var result = list1.Intersect(list2).Count();
    18. if (result == list1.Count || result == list2.Count)
    19. return 1;
    20. else
    21. return 0;
    22. }
    23. }



    Day 4, Part 2:

    Spoiler anzeigen

    C#-Quellcode

    1. namespace Four;
    2. public class Program
    3. {
    4. static void Main(string[] args)
    5. {
    6. string[] data = File.ReadAllLines("input.txt");
    7. int sum = 0;
    8. for (int i = 0; i < data.Length; i++)
    9. sum += CheckPair(data[i]);
    10. Console.WriteLine(sum);
    11. }
    12. static int CheckPair(string input)
    13. {
    14. var elements = input.Split(new string[] { "-", "," }, StringSplitOptions.RemoveEmptyEntries).Select(x => int.Parse(x)).ToList();
    15. var list1 = Enumerable.Range(elements[0], (elements[1] - elements[0]) + 1).ToList();
    16. var list2 = Enumerable.Range(elements[2], (elements[3] - elements[2]) + 1).ToList();
    17. var result = list1.Intersect(list2).Count();
    18. if (result > 0)
    19. return 1;
    20. else
    21. return 0;
    22. }
    23. }


    Im 2. Teil hat sich eigentlich nur das Return-Statement geändert.
    Die Unendlichkeit ist weit. Vor allem gegen Ende. ?(
    Manche Menschen sind gar nicht dumm. Sie haben nur Pech beim Denken. 8o

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

    Die erste Frage kenne ich.

    EDIT: Muss jetzt doch kurz Fragen, wie heisst die zweite Frage?

    Teil 1

    C#-Quellcode

    1. public static void Main()
    2. {
    3. static bool checkpair(IEnumerable<IEnumerable<int>> ints)
    4. {
    5. var item1 = ints.ElementAt(0);
    6. var item2 = ints.ElementAt(1);
    7. return (item1.ElementAt(0) <= item2.ElementAt(0) && item1.ElementAt(1) >= item2.ElementAt(1)) ||
    8. (item2.ElementAt(0) <= item1.ElementAt(0) && item2.ElementAt(1) >= item1.ElementAt(1));
    9. }
    10. var source = Sources();
    11. var result = 0;
    12. foreach (var src in source)
    13. {
    14. var ints = src.Split(",")
    15. .Select(str => str.Split("-")
    16. .Select(s => ((int)s[0]) - 48));
    17. var included = checkpair(ints);
    18. Console.WriteLine(included);
    19. result += included ? 1 : 0;
    20. }
    21. Console.WriteLine();
    22. Console.WriteLine($"Result = {result}");
    23. Console.WriteLine();
    24. Console.ReadLine();
    25. }

    Teil 2

    C#-Quellcode

    1. private static void Main()
    2. {
    3. //Muss eine Annahme treffen.
    4. //Die 2. Frage könnte lauten, wo gibt es Verbesserungspotential?
    5. static bool checkpair(IEnumerable<IEnumerable<int>> pairs)
    6. {
    7. var last = pairs.Last();
    8. var first = pairs.First();
    9. return !((first.First() < last.First() && first.Last() < last.First()) ||
    10. (last.First() < first.First() && last.Last() < first.First()));
    11. }
    12. var result = Sources().Select(str => checkpair(str.Split(",")
    13. .Select(str => str.Split("-")
    14. .Select(int.Parse)))).ToArray();
    15. Array.ForEach(result, Console.WriteLine);
    16. Console.WriteLine();
    17. Console.WriteLine(result.Where(b => b).Count());
    18. Console.WriteLine();
    19. Console.ReadLine();
    20. }

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

    Tag 04 Part 1 & 2: Da geht noch mehr mit LINQ aber hab jetzt nicht mehr soviel Zeit heute daher kurz runter getippt eventuell pack ich heute abend noch eine andere Lösung rein.
    Spoiler anzeigen

    C#-Quellcode

    1. string[] lines = File.ReadAllLines("Input.txt");
    2. int scoreP1 = 0;
    3. int scoreP2 = 0;
    4. foreach (string line in lines)
    5. {
    6. int[] elfNumbers = line.Split(',').SelectMany(e => e.Split('-')).Select(Int32.Parse).ToArray();
    7. int elf1Min = elfNumbers[0];
    8. int elf1Max = elfNumbers[1];
    9. int elf2Min = elfNumbers[2];
    10. int elf2Max = elfNumbers[3];
    11. if(elf1Min >= elf2Min && elf1Max <= elf2Max || elf2Min >= elf1Min && elf2Max <= elf1Max) scoreP1++;
    12. if (elf2Min <= elf1Min && elf2Max >= elf1Min || elf2Max >= elf1Max && elf2Max <= elf1Min)
    13. {
    14. scoreP2++;
    15. } else if (elf1Min <= elf2Min && elf1Max >= elf2Min || elf1Max >= elf2Max && elf1Max <= elf2Min)
    16. {
    17. scoreP2++;
    18. }
    19. }
    20. Console.WriteLine(scoreP1);
    21. Console.WriteLine(scoreP2);
    Grüße , xChRoNiKx

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

    Elanda schrieb:

    wäre das "thematisch" bitte möglich diesen Thread zu verschieben? Es ist ja eigentlich on-topic.

    "Off-Topic" ist dieses Thema zwar nicht, aber in meinen Augen haben wir auf VBP kein passendes Unterforum für solche Threads.
    Besucht auch mein anderes Forum:
    Das Amateurfilm-Forum

    Marcus Gräfe schrieb:

    "Off-Topic" ist dieses Thema zwar nicht, aber in meinen Augen haben wir auf VBP kein passendes Unterforum für solche Threads.

    Verstehe, danke!
    Einen Versuch war es Wert. :)

    Edit: Kann gerade keinen neuen Beitrag erstellen, deswegen editier ich meinen Versuch einfach in die bestehende Antwort. (ja moin)


    Heute wollte ich mal den kompliziertesten parsing-loop haben.
    AoC 2022 - Tag 4 (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. // A range of section ids
    12. struct Section
    13. {
    14. int startNr;
    15. int endNr;
    16. };
    17. // A pair of elves that define their sections
    18. struct ElfPair
    19. {
    20. //==============================================================================================================
    21. Section sectionElf1;
    22. Section sectionElf2;
    23. //==============================================================================================================
    24. [[nodiscard]]
    25. constexpr bool containsContained() const noexcept
    26. {
    27. return ((sectionElf1.startNr >= sectionElf2.startNr && sectionElf1.endNr <= sectionElf2.endNr)
    28. || (sectionElf2.startNr >= sectionElf1.startNr && sectionElf2.endNr <= sectionElf1.endNr));
    29. }
    30. [[nodiscard]]
    31. constexpr bool intersects() const noexcept
    32. {
    33. return ((sectionElf1.endNr >= sectionElf2.startNr && sectionElf2.endNr >= sectionElf1.endNr)
    34. || (sectionElf2.endNr >= sectionElf1.startNr && sectionElf1.endNr >= sectionElf2.endNr));
    35. }
    36. //==============================================================================================================
    37. [[nodiscard]]
    38. static ElfPair fromString(const std::string &input) noexcept
    39. {
    40. ElfPair pair;
    41. const std::array vars {
    42. &pair.sectionElf1.startNr,
    43. &pair.sectionElf1.endNr,
    44. &pair.sectionElf2.startNr,
    45. &pair.sectionElf2.endNr
    46. };
    47. auto var_it = vars.begin();
    48. for (auto it = input.begin(); it != input.end(); ++it)
    49. {
    50. std::array<char, 4> buffer { *it };
    51. auto buf_it = buffer.begin() + 1;
    52. for (; (std::next(it) != input.end() && *it >= '0' && *it <= '9'); ++it)
    53. {
    54. *buf_it++ = *std::next(it);
    55. }
    56. const int result = std::strtol(buffer.data(), nullptr, 10);
    57. *(*var_it++) = result;
    58. }
    59. return pair;
    60. }
    61. };
    62. }
    63. //======================================================================================================================
    64. // endregion Namespace
    65. //**********************************************************************************************************************
    66. // region Main
    67. //======================================================================================================================
    68. int main()
    69. {
    70. std::fstream input(INPUT_FILE);
    71. if (!input.is_open())
    72. {
    73. return 1;
    74. }
    75. std::string line;
    76. int contained_count = 0;
    77. int intersect_count = 0;
    78. while (std::getline(input, line))
    79. {
    80. const ::ElfPair pair = ::ElfPair::fromString(line);
    81. if (pair.containsContained())
    82. {
    83. (void) ++contained_count;
    84. }
    85. if (pair.intersects())
    86. {
    87. (void) ++intersect_count;
    88. }
    89. }
    90. std::cout << "In " << contained_count << " pairs there is a significant containment, reporter states.\n";
    91. std::cout << "At least " << intersect_count << " of the pairs intersect section-wise, not good dawg.\n";
    92. return 0;
    93. }
    94. //======================================================================================================================
    95. // endregion Main
    96. //**********************************************************************************************************************

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

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

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

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

    Part 1
    Spoiler anzeigen

    C#-Quellcode

    1. using StreamReader sr = new(File.OpenRead(@"input.txt"));
    2. int full = 0;
    3. while (!sr.EndOfStream)
    4. {
    5. string[] sections = sr.ReadLine()!.Split(',');
    6. (int min, int max) section1 = GetSection(sections[0].Split('-'));
    7. (int min, int max) section2 = GetSection(sections[1].Split('-'));
    8. if (((section1.min <= section2.min) && (section1.max >= section2.max)) ||
    9. ((section2.min <= section1.min) && (section2.max >= section1.max)))
    10. {
    11. full++;
    12. }
    13. };
    14. Console.WriteLine(full);
    15. (int, int) GetSection(string[] sections) => (int.Parse(sections[0]), int.Parse(sections[1]));


    Part 2
    Spoiler anzeigen

    C#-Quellcode

    1. using StreamReader sr = new(File.OpenRead(@"input.txt"));
    2. int overlap = 0;
    3. while (!sr.EndOfStream)
    4. {
    5. string[] sections = sr.ReadLine()!.Split(',');
    6. (int min, int max) section1 = GetSection(sections[0].Split('-'));
    7. (int min, int max) section2 = GetSection(sections[1].Split('-'));
    8. if (((section1.min <= section2.min) && (section1.max >= section2.max)) ||
    9. ((section2.min <= section1.min) && (section2.max >= section1.max)) ||
    10. ((section1.min >= section2.min) && (section1.min <= section2.max)) ||
    11. ((section2.min >= section1.min) && (section2.min <= section1.max)))
    12. {
    13. overlap++;
    14. }
    15. };
    16. Console.WriteLine(overlap);
    17. (int, int) GetSection(string[] sections) => (int.Parse(sections[0]), int.Parse(sections[1]));
    Tag 05 - Part 1 und 2
    Spoiler anzeigen

    C#-Quellcode

    1. string[] lines = File.ReadAllLines("Input.txt");
    2. int AnzahlKraehn = (int)Math.Ceiling(lines[0].Length / 4.0);
    3. List<char>[] Kraehne = new List<char>[AnzahlKraehn];
    4. void initialisieren()
    5. {
    6. for (var i = 0; i < AnzahlKraehn; i++)
    7. {
    8. Kraehne[i] = new List<char>();
    9. }
    10. int y = 0;
    11. for (; y < lines.Length && lines[y][1] != '1'; y++)
    12. {
    13. var line = lines[y];
    14. int Krahn = 0;
    15. foreach (var Kiste in line.Chunk(4).Select(x => x[1]))
    16. {
    17. if (Kiste != ' ')
    18. {
    19. Kraehne[Krahn].Add(Kiste);
    20. }
    21. Krahn++;
    22. }
    23. }
    24. }
    25. initialisieren();
    26. foreach (string line in lines)
    27. {
    28. if (!line.StartsWith("move")) continue;
    29. string[] tmp = line.Split(" ");
    30. int Anzahl = Int32.Parse(tmp[1]);
    31. int vonKrahn = Int32.Parse(tmp[3]) - 1;
    32. int nachKrahn = Int32.Parse(tmp[5]) - 1;
    33. for (var i = 0; i < Anzahl; i++)
    34. {
    35. Kraehne[nachKrahn].Insert(0, Kraehne[vonKrahn][i]);
    36. }
    37. Kraehne[vonKrahn].RemoveRange(0, Anzahl);
    38. }
    39. Console.WriteLine($"Part 1: {String.Join("", Kraehne.Select(x => x[0]))}");
    40. initialisieren();
    41. foreach (string line in lines)
    42. {
    43. if (!line.StartsWith("move")) continue;
    44. string[] tmp = line.Split(" ");
    45. int Anzahl = Int32.Parse(tmp[1]);
    46. int vonKrahn = Int32.Parse(tmp[3]) - 1;
    47. int nachKrahn = Int32.Parse(tmp[5]) - 1;
    48. Kraehne[nachKrahn].InsertRange(0 , Kraehne[vonKrahn].Take(Anzahl));
    49. Kraehne[vonKrahn].RemoveRange(0, Anzahl);
    50. }
    51. Console.WriteLine($"Part 2: {String.Join("", Kraehne.Select(x => x[0]))}");
    Grüße , xChRoNiKx

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

    Teil 1 und 2 C#

    Spoiler anzeigen

    C#-Quellcode

    1. using System.Text.RegularExpressions;
    2. var AllLines = File.ReadAllLines("CodeAdvent_5.txt");
    3. //the max Hight of the input stacks
    4. int stackHights = 8;
    5. var StackHorizontalLines = AllLines.Take(stackHights).ToList();
    6. var MoveLines = AllLines.Skip(stackHights+2).ToList();
    7. StackStorage ElvesStack = new(StackHorizontalLines);
    8. //Console.WriteLine($"Result: {ElvesStack.MoveStorage9000(MoveLines)}");
    9. Console.WriteLine($"Result: {ElvesStack.MoveStorage9001(MoveLines)}");
    10. class StackStorage
    11. {
    12. public StackStorage(List<string> stackHorizontalLines)
    13. {
    14. PopulateStorageStacks(stackHorizontalLines);
    15. }
    16. public List<List<char>> VerticalStorageStacks { get; set; } = new();
    17. private void PopulateStorageStacks(List<string> stackHorizontalLines)
    18. {
    19. for (int i = 0; i < stackHorizontalLines[0].Count() / 4; i++)
    20. {//[G] [G] [C] [J] [P] [P] [Z] [R] [H] CharCount/4 => NrOfStacks
    21. VerticalStorageStacks.Add(new List<char>());
    22. }
    23. var nrOfSpacesInHorizontalLine = stackHorizontalLines[0].Count();
    24. foreach (var horizontalLine in stackHorizontalLines)
    25. {//TODO firstLine of Example ends not at 33+ because no whitespaces in .txt => edit input.txt to same LineLength
    26. var counter = 0;
    27. for (int i = 1; i < nrOfSpacesInHorizontalLine; i+=4)
    28. {//index1=X +4=Y ... => [X]_[Y][X]_[Z]...
    29. VerticalStorageStacks[counter].Add(horizontalLine[i]);
    30. foreach (var item in VerticalStorageStacks[counter])
    31. {
    32. var res = item;
    33. }
    34. counter++;
    35. }
    36. }
    37. foreach (var s in VerticalStorageStacks)
    38. {//delete all the Whitespaces from Lists
    39. foreach (var c in s.ToList())
    40. {//https://stackoverflow.com/questions/604831/collection-was-modified-enumeration-operation-may-not-execute
    41. if (string.IsNullOrWhiteSpace(c.ToString()))
    42. s.Remove(c);
    43. }
    44. }
    45. }
    46. public string MoveStorage9000(List<string> moveLines)
    47. {
    48. foreach (var line in moveLines)
    49. {
    50. var matches = Regex.Matches(line, @"\d+");
    51. var intQuantity = int.Parse(matches[0].Value);
    52. var indexFromStack = int.Parse(matches[1].Value)-1;
    53. var indexToStack = int.Parse(matches[2].Value)-1;
    54. for (int i = 0; i < intQuantity; i++)
    55. {
    56. VerticalStorageStacks[indexToStack].Insert(0, VerticalStorageStacks[indexFromStack][i]);
    57. }
    58. VerticalStorageStacks[indexFromStack].RemoveRange(0, intQuantity);
    59. }
    60. string result = "";
    61. foreach (var item in VerticalStorageStacks)
    62. {
    63. result += item.First().ToString();
    64. }
    65. return result;
    66. }
    67. public string MoveStorage9001(List<string> moveLines)
    68. {
    69. foreach (var line in moveLines)
    70. {
    71. var matches = Regex.Matches(line, @"\d+");
    72. var intQuantity = int.Parse(matches[0].Value);
    73. var indexFromStack = int.Parse(matches[1].Value)-1; //Stackindexs starts at 0 => -1
    74. var indexToStack = int.Parse(matches[2].Value)-1;
    75. VerticalStorageStacks[indexToStack].InsertRange(0, VerticalStorageStacks[indexFromStack].Take(intQuantity));
    76. VerticalStorageStacks[indexFromStack].RemoveRange(0, intQuantity);
    77. //PrintStack();
    78. }
    79. string result = "";
    80. foreach (var item in VerticalStorageStacks)
    81. {
    82. result += item.First().ToString();
    83. }
    84. return result;
    85. }
    86. public void PrintStack()
    87. {
    88. foreach (var s in VerticalStorageStacks)
    89. {
    90. foreach (var item in s)
    91. {
    92. Console.Write(item);
    93. }
    94. Console.WriteLine();
    95. }
    96. }
    97. }
    codewars.com Rank: 4 kyu
    Part 1
    Spoiler anzeigen

    C#-Quellcode

    1. using System.Text.RegularExpressions;
    2. using StreamReader sr = new(File.OpenRead("input.txt"));
    3. Regex crateRegex = new(@"\[([A-Z])\]", RegexOptions.Compiled);
    4. Regex movingRegex = new(@"[0-9]+", RegexOptions.Compiled);
    5. Queue<string>[] queues = new Queue<string>[9] { new(), new(), new(), new(), new(), new(), new(), new(), new() };
    6. Stack<string>[] stacks = new Stack<string>[9];
    7. bool headerRead = false;
    8. while (!sr.EndOfStream)
    9. {
    10. var line = sr.ReadLine();
    11. if (!headerRead)
    12. {
    13. if (crateRegex.IsMatch(line!))
    14. {
    15. foreach (Match match in crateRegex.Matches(line!))
    16. {
    17. queues[match.Index / 4].Enqueue(match.Groups[1].Value);
    18. }
    19. continue;
    20. }
    21. headerRead = string.IsNullOrEmpty(line);
    22. for (int i = 0; i < stacks.Length; ++i)
    23. {
    24. stacks[i] = new Stack<string>(queues[i].Reverse());
    25. }
    26. }
    27. else
    28. {
    29. var matches = movingRegex.Matches(line!);
    30. (int from, int to) x = (int.Parse(matches[1].Value), int.Parse(matches[2].Value));
    31. for (int i = 0; i < int.Parse(matches[0].Value); ++i)
    32. {
    33. stacks[x.to - 1].Push(stacks[x.from - 1].Pop());
    34. }
    35. }
    36. }
    37. for (int i = 0; i < queues.Length; ++i)
    38. {
    39. Console.Write(stacks[i].Pop());
    40. }


    Part 2
    Spoiler anzeigen

    C#-Quellcode

    1. using System.Text.RegularExpressions;
    2. using StreamReader sr = new(File.OpenRead("input.txt"));
    3. Regex crateRegex = new(@"\[([A-Z])\]", RegexOptions.Compiled);
    4. Regex movingRegex = new(@"[0-9]+", RegexOptions.Compiled);
    5. Queue<string>[] queues = new Queue<string>[9] { new(), new(), new(), new(), new(), new(), new(), new(), new() };
    6. Stack<string> movingStack = new();
    7. Stack<string>[] stacks = new Stack<string>[9];
    8. bool headerRead = false;
    9. while (!sr.EndOfStream)
    10. {
    11. var line = sr.ReadLine();
    12. if (!headerRead)
    13. {
    14. if (crateRegex.IsMatch(line!))
    15. {
    16. foreach (Match match in crateRegex.Matches(line!))
    17. {
    18. queues[match.Index / 4].Enqueue(match.Groups[1].Value);
    19. }
    20. continue;
    21. }
    22. headerRead = string.IsNullOrEmpty(line);
    23. for (int i = 0; i < stacks.Length; ++i)
    24. {
    25. stacks[i] = new Stack<string>(queues[i].Reverse());
    26. }
    27. }
    28. else
    29. {
    30. movingStack.Clear();
    31. var matches = movingRegex.Matches(line!);
    32. (int from, int to) x = (int.Parse(matches[1].Value), int.Parse(matches[2].Value));
    33. for (int i = 0; i < int.Parse(matches[0].Value); ++i)
    34. {
    35. movingStack.Push(stacks[x.from - 1].Pop());
    36. }
    37. while (movingStack.Count > 0)
    38. {
    39. stacks[x.to - 1].Push(movingStack.Pop());
    40. }
    41. }
    42. }
    43. for (int i = 0; i < queues.Length; ++i)
    44. {
    45. Console.Write(stacks[i].Pop());
    46. }

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

    Ich bin nun endlich auch fertig geworden.

    AoC 2022 - Tag 5
    Heute nur auf GitHub, da der code um die 500 Zeilen hat, ich denke das wäre verständlicherweise etwas zu lang.
    github.com/ElandaOfficial/adve…/master/src/day5/main.cpp
    ----------------------------------------------------------------------------------------------------------------------

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

    ----------------------------------------------------------------------------------------------------------------------
    Tag 6

    Teil 1 und 2 C#
    Gestern hab ich noch gedacht, dass wär der Letzte Tage den ich mache, zu viel Aufwand ... .
    Heute im Vergleich zu Gestern 10 Min, und fertig :)
    Spoiler anzeigen

    C#-Quellcode

    1. var Input = File.ReadAllText("CodeAdvent_6.txt");
    2. var IndexLength= Input.Length;
    3. var markerLength = 14;
    4. for (int i = 0; i < IndexLength; i++)
    5. {
    6. char[] segment = new char[markerLength];
    7. if (i + markerLength <= IndexLength)
    8. {
    9. var counter = 0;
    10. for (int j = 0; j < markerLength; j++)
    11. {
    12. segment[j] = Input[i + counter];
    13. counter++;
    14. }
    15. var res = segment.Distinct().ToArray();
    16. if (res.Length == markerLength)
    17. {
    18. Console.WriteLine(i + markerLength);
    19. return;
    20. }
    21. }
    22. }
    codewars.com Rank: 4 kyu
    Wird ja immer leichter anstatt schwerer :(

    Spoiler anzeigen

    C#-Quellcode

    1. namespace Six;
    2. public class Program
    3. {
    4. static void Main(string[] args)
    5. {
    6. string data = File.ReadAllText("input.txt");
    7. List<char> buffer = new();
    8. int result = 0;
    9. int length = 14; //or 4 for the firstPart
    10. for (int i = 0; i < data.Length; i++)
    11. {
    12. buffer.Add(data[i]);
    13. if (buffer.Count == length)
    14. {
    15. int test = buffer.Distinct().Count();
    16. if (test != length)
    17. buffer.RemoveAt(0);
    18. else
    19. {
    20. result = i + 1;
    21. break;
    22. }
    23. }
    24. }
    25. Console.WriteLine(result);
    26. }
    27. }

    Die Unendlichkeit ist weit. Vor allem gegen Ende. ?(
    Manche Menschen sind gar nicht dumm. Sie haben nur Pech beim Denken. 8o
    Tag 06 hier ist die Linq Lösung:
    Spoiler anzeigen

    C#-Quellcode

    1. string[] lines = File.ReadAllLines("Input.txt");
    2. int getZeichenAnzahl(int zeichenGroesse)
    3. {
    4. return lines.Select(s =>
    5. Enumerable.Range(0, s.Length - (zeichenGroesse + 1))
    6. .Select(i => (i + zeichenGroesse, s.Substring(i, zeichenGroesse)))
    7. .First(x => x.Item2.Distinct().Count() == zeichenGroesse)
    8. .Item1)
    9. .First();
    10. }
    11. Console.WriteLine($"Part1: {getZeichenAnzahl(4)}");
    12. Console.WriteLine($"Part2: {getZeichenAnzahl(14)}");
    Grüße , xChRoNiKx

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

    xChRoNiKx schrieb:

    Tag 06 hier ist die Linq Lösung:


    EDIT:
    Doch noch ein paar Fragen @xChRoNiKx
    Untersucht lines.Select(s => ... jede Zeile für sich gesehen nach dem Unique-Zeichen?

    Ich hatte die Aufgabe so gelesen, dass der String komplett zusammen gehört ohne Zeilenumbruch = auf 'Null'.

    Oder verstehe ich LINQ immer noch so schlecht, dass doch der ganze Text auf einmal durchsucht wird.

    Wie Debuged man so ein LINQ-Konstrukt. Wie kann ich das Teil für Teil zusammen setzen. Könnte man das auf einzelne LINQ Schritte aufteilen. Pro Zeile eine 'Sortierung' oder geht das nur als Ganzes?
    codewars.com Rank: 4 kyu

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

    Part 1 + 2
    Spoiler anzeigen

    C#-Quellcode

    1. using StreamReader sr = new(File.OpenRead("input.txt"));
    2. int markerPos = 0;
    3. while (!sr.EndOfStream)
    4. {
    5. var dataStreamSpan = sr.ReadLine()!.AsSpan();
    6. for (int i = 0; i < dataStreamSpan.Length; ++i)
    7. {
    8. bool doubletFound = false;
    9. var streamPart = dataStreamSpan[i..(i + 4)];
    10. int j = 0;
    11. while (!doubletFound && (j < streamPart.Length - 1))
    12. {
    13. for (int k = j + 1; k < streamPart.Length; ++k)
    14. {
    15. if (streamPart[j].Equals(streamPart[k]))
    16. {
    17. doubletFound = true;
    18. break;
    19. }
    20. }
    21. ++j;
    22. }
    23. if (!doubletFound)
    24. {
    25. markerPos = i + 4;
    26. break;
    27. }
    28. }
    29. }
    30. Console.WriteLine(markerPos);


    Naja.. :whistling:
    Ich konnte heute leider nicht zu meinem PC daher musste ich es am Smartphone machen, deshalb entschuldigt bitte diese Unordnung.

    AoC 2022 - Tag 6
    Spoiler anzeigen

    C-Quellcode

    1. #include <array>
    2. #include <iostream>
    3. #include <unordered_set>
    4. #include <string_view>
    5. constexpr std::string_view input = "vldvlvvhwhttcsttpntnvvqpqpddmlddwhwcwnwmwfwppdrrhllcwwgwhwvhwhshchshtsstzstztgtlggcwwtptrppfpggwpwmppnfpfnfznffmvfmvffgfwwwgrrqgglrgrqqlslhhgjgwwdswsbwwqswqwnqwqpqttqstqtjqqctcbtcbttcptpbbsmmhggwmggjllcpcvcrrphpjjwzwgzgtzggscggwdgghlhnhddlclrcchllrlbbnlbbgpbgghvggpbgpgssbszzjbbcpbpttwztwwgngnqqgllcvlvlzvzwwzssbppjwwvswwbjwbjwwwsjsdjsszmssfvsvcscqssnbnzbzzhsszttfvvdllzjzsjjzzvzsvzzdvvcpphfhzhrzrnnwffnrrhwrhrnrhnrrgfgmmzwmzmhzzsrzrgggnfntnpnqqdhhmrmrrqdqwqsqmssmllmvmgglttdmdffwzzhszhzphzphplpvpzvvsvcvgvqgqpgqqrmqmqssdbdcdpphddvppfggwrgrdgrggtvggrttmpmvmnmwnmmlcccwssfjftfbbgqbbnlldzlddzbbvmmvbmvvbsszggmnggqsqvssdlddqbbtfbttlhhlssplphlhzzcmmdcmmlqlqmmtddztzctzzlglwlzwwsmsddbrrzqqpdpjdpjjzhjjjzttvvwcvcdvvwqvvwqqgpgjgwgvgmmdjjmbbttmffwgwgppspzzvddjnjppmsscjczcqcczlzjzbbzmzllsshrrdtdttjdtdnnwbwttzptztrzzgfgfqfjjlwjjbfbsbmmhphqqjlqjjjshsvvrzrffvnfftrrpzzrdrbbcqbqjqccphhwfwgfwgwgwzzhggddctcsttjgjppghppfhhlnhhhwfwrfrggtjjgjbgbjbrrssjvvlcvvdzvdzzjhhgpprnpnpggfmfgfzfrzzsjjwhhrmmmvppgfffdsfddwlddmccjfcjjrwwsmwsstlsszbbjssjtsjjmpjpqqzffhphfffrzffnbnvnzvnvsvjjbljlflglrlvvghhcrhccnhccdbcdclcbbgffhwhnwwrwbbngnwwlpwlwsllsffzvzbzhbhppvdvfdvffvsvlslcslsqqszqzrrqbrrpjjvgjggbvvpbblnlvnnvrrprbpbvbccrjsdfrnqvhgfrwtvqjfzflnqqgbwlvfwwmrgnsltsqjfcctdwhqrstpvllhfrbnvnhvvgfvhbsgppslqnhmwdnrjnpfmrppppqpmrmcvtndrgwngrblpvrgnbhgtflthdjdtqhwcfzbdwsjshhnglprfcjfdwffmhbvhshbzsgdsbdwpcjfhrccqmjslqjjrwnbtqftqlvgnpmmzlfnmjzvrfslmmvhqwzjqbwsqfcnlmgdwlcbrlqlfwzhcfjsnncnnjqltfccmllhnjczqssjnjmhqbhqzdplbvfdpmdjmgthvqgjzqqschzgtmpdzmvvhlrwjpbqfplcqdbjfjfcrzdclctldvvqphtnvmgzvwprhzmbsbgfjlhvbtcmnccrgrpjlcjqqfcgjhtwvfstrtzszgcprmcngbhbdvjbfvgqdlhzgtzcjqnjmdtmwzchcfhzhgwprgrzbfwbhstfbprhnbzhsglmwhcjbppnshmzlnzsmbhcrmvpdgftfrwjfnmdvtrrqwjmzlbdjppsnvmlstsnrjwslqtqfmfcspzgrqhshhvclvqdfpbmzvsnthmcrzdmzqcjnnmbwbdlbfmcrzjjsrjbwchlvljplqdbjfchbslcvbjvvzfgdzmmnrgqwftppgpfwhfvdqqsrphrqmdtzjghlldfpgnczzjhqhfjvgqmcpzqssfqsfblcvqfttznpmvczprcptgcfwwlwsmqvfrjzcwbhppsjghmltqtcqljmpjzddncbslqdvgzhdvfpdpgpzljrfnjwdtnbdjwzjvmhqvnrdrjmhcfsbjcwtflljwjvtjbsbhzbghnzwtwpwzzwnfhwszsghggqthcbtwjrhdphbdslzmwhpmtjfbnpzspfqrvvtsjpvjmbtwrsqvfzzphllbvmvczsphdtblgdczjsqqthgscdqpvnmbpblspbcmpgjjtjtdrwhrqcgbrvlcsrwzwnjlgbfjbfgwpqpvnnmmgbdrhrwsptmddvtgbjhgzcphzmscjrqlnngpsnmjhvtmnhmqmcwdpjpbjsntcgppqrjndfsfhrhcvgcmrfrrsvnddwjsndlwffrgqnldqnvtgfvdrwtrlcqhltmbvdndzpdqndqrbtzqwbmbtzzsqftjftcnbrtsgvdrmnqlbbmhwmzpngltcslwdnpzpvstpdtfdcqvlwtbppsjvpdbspzlwnfvgcslzvmrpgplbnrvwpfwnrhcncdzptrjsqvghrczmrfwfntqlvlccwtbwqdcngzlqqvvnvfttqmcbqfqndhlsmbvcnstjcbpffmsptdnqbntnhhdctgdbnvwzgwznsgpvmslpmlcffsdtfnlcmbdgbntcslrlhfmrpddmjjttbtcrgbmfsbbwphtmlrdrgffdlnrwndhttjrplstwfwlpnljlcjphdvdvslwvnstqlrsgwdltlqwzdgsltzjqsgwqpbzgvqbdmvqtdgsnhttqprttzrnmddzdnqsgmnhfrmmfnrmltgjqpmgmdzdwpnzdsgstmwlgstmtjtqlhngmpwdqscrjmpmndddppsgthtbmznndswpsftcfltmhbbglnlmlszsssrlgbzcqpngvtgttlblsthmrltgctpgpjmhqqbldfgcrmclsmjhnjspzgwpmwncjgwrgdjmfgrpndztfdssmjhfmstgbjjzvmrpbmfzljpffwgvszwvtclfdnnbswzpjgthcbzpcbmgfvhfwnfthjdmnzdptqflzldnvnmfqnbggsrzjjssdntqhsjltjlfvjhncbrfbhllmqdpdnlbjptdcrqqghvvfvzzvtbvnjhshptcmgcnlmmpgdggdsfnpfsgrbcnfvrvfcqdfdfbgfvqcspvnrrljsgdtsbbcvcqnlwmrfgjhbdnjqgpggnpqtqgwspgljbrsggnmbmdbctwsdzqjmzrcwqgsvnhlpnlnqgfvgdfpgwsbqpqjcjpwwbrtzqhhgswggwnhmzwtvrqcrgbsrjspmczctgprgcwjtnzghvzqgnpmfqdswnzfzdbpdnpcgmwdrpmjtzhhwcnrrpfvqsgbrzngmwdgvjnmcftcjpcmdvcwjgfgvjrblsdnbsgfmjnvvvfwpfhztbgfddlcljzmwrwglnrfbnphlpvvcbfnwpsmsnhshzwrpnljzstmglrwdcctqlbwvqtfpjjdqzgncwgsnhczhvnvnzzmsjhfvgpdrhsmgnrfjcrzblzncdlffjrcqrqqdnjhgwgdgjlgbtphzgrjvmgnqrvdgmtgvpdbzqcvsfctrntjsnfcwnzpslzsvmtjhtcvcdsbqflbmtvclssrvcwjwcbspjgqhznzpttlbsnrpdrnqsddlcvjdrnqcgjhjfdclhwscdpbsjzcmrhgfwdnqbzqjsdqwbqdfcrztzfvclvbnhqstjztqdmsvlfqzmllphgrnwjqpdlrdnsbdltrggvlmdpfdwrdwnsdnscfcjzmrwqpsjwzrqcqcfndlvtfftbhdcbgcgtrfqrqnvwgbpstrtzgpjcjswfcwgvfnwlpprthntmlqbchjcwnqgppchgtvrzjbdzptfqqbmchmpqlnnfvpghjnmshpcjgsprbjpqnpwwddnswnfjvbzwszplhnhgzmzdqncmqrqtbqhdwbtrbrljpcwbdhjzvcqpdgvbtczlhwwzfmgvffnbcglpdqjdsnhhtnvvmtnhlbqcfqjfcgmcnqstzbgmqcfsgrzncwcfrlpsctpspvvdzwtbrhqzhfcwvwqvtzrmfjgpmlsdjmlgwhcldqlhsjvprvnmzcsldzfpzhmzdbqbpwnrsffswbjcwjgblnlcwzqlmcgfstqggdbsqpcpqcgfvn";
    6. int main()
    7. {
    8. static constexpr auto func_get_unique = [](int length) -> int
    9. {
    10. const int offset = (length - 1);
    11. for (auto it = (input.begin() + offset); it != input.end(); ++it)
    12. {
    13. const std::unordered_set<char> sequence((it - offset), (it + 1));
    14. if (sequence.size() == length)
    15. {
    16. return std::distance(input.begin(), it) + 1;
    17. }
    18. }
    19. return -1;
    20. };
    21. std::cout << "Pscket index is: " << func_get_unique(4) << '\n';
    22. std::cout << "Message index is: " << func_get_unique(14) << '\n';
    23. return 0;
    24. }

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

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

    ----------------------------------------------------------------------------------------------------------------------
    Teilweise Verkünstelt, teilweise doch ein klein wenig Elegant. Hier meine Lösungen für Tag 3-6:
    Tag 3:
    Spoiler anzeigen

    C#-Quellcode

    1. ​public static class AoC_D3
    2. {
    3. public static int PriorityScorePt1 { get; set; } = 0;
    4. public static int PriorityScorePt2 { get; set; } = 0;
    5. public static void ReadInputAndCalculateContents()
    6. {
    7. using StreamReader streamReader = new StreamReader("AoC_3_input.txt");
    8. Backpack[] packs = new Backpack[3];
    9. int i = 0;
    10. do
    11. {
    12. string contents = streamReader.ReadLine();
    13. if (string.IsNullOrWhiteSpace(contents))
    14. {
    15. continue;
    16. }
    17. Backpack current = Backpack.CreateBackpack(contents);
    18. PriorityScorePt1 += (int)current.SharedContent;
    19. packs[i] = current;
    20. if (i == 2)
    21. {
    22. char sharedContent = packs[0].AllContents.Intersect(packs[1].AllContents).Intersect(packs[2].AllContents).ToList()[0];
    23. Enum.TryParse(sharedContent.ToString(), out LetterValues SharedValue);
    24. PriorityScorePt2 += (int)SharedValue;
    25. i = 0;
    26. continue;
    27. }
    28. i++;
    29. } while (!streamReader.EndOfStream);
    30. }
    31. }
    32. class Backpack
    33. {
    34. public string AllContents { get; set; }
    35. public string LeftCompartment { get; set; }
    36. public string RightCompartment { get; set; }
    37. public LetterValues SharedContent { get; set; }
    38. public static Backpack CreateBackpack(string contents)
    39. {
    40. Backpack backpack = new() { AllContents = contents };
    41. int halfContents = contents.Length / 2;
    42. backpack.LeftCompartment = contents.Substring(0, halfContents);
    43. backpack.RightCompartment = contents.Substring(halfContents, halfContents);
    44. char both = backpack.LeftCompartment.Intersect(backpack.RightCompartment).ToList()[0];
    45. Enum.TryParse(both.ToString(), out LetterValues SharedValue);
    46. backpack.SharedContent = SharedValue;
    47. return backpack;
    48. }
    49. }
    50. enum LetterValues
    51. {
    52. a = 1, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z,
    53. A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z,
    54. }


    Tag 4:
    Spoiler anzeigen

    C#-Quellcode

    1. public static class AoC_D4
    2. {
    3. public static int FullyContainedAssignments { get; set; } = 0;
    4. public static int OverlappingAssignments { get; set; } = 0;
    5. public static void ReadInputAndCalculate()
    6. {
    7. using StreamReader streamReader = new StreamReader("AoC_4_input.txt");
    8. do
    9. {
    10. string line = streamReader.ReadLine();
    11. if (string.IsNullOrWhiteSpace(line))
    12. continue;
    13. CleaningSections sections = new CleaningSections(line);
    14. int[] remaindersFirst = sections.FirstSections.Except(sections.SecondSections).ToArray();
    15. int[] remainderssecond = sections.SecondSections.Except(sections.FirstSections).ToArray();
    16. if (remaindersFirst.Length == 0 || remainderssecond.Length == 0)
    17. FullyContainedAssignments++;
    18. bool overlap = sections.FirstSections.Intersect(sections.SecondSections).Any();
    19. if (overlap)
    20. OverlappingAssignments++;
    21. } while (!streamReader.EndOfStream);
    22. }
    23. }
    24. public class CleaningSections
    25. {
    26. public int[] FirstSections { get; set; }
    27. public int[] SecondSections { get; set; }
    28. public CleaningSections(string line)
    29. {
    30. string[] ranges = line.Split(',');
    31. CalculateRange(ranges[0], out int start, out int length);
    32. FirstSections = Enumerable.Range(start, length).ToArray();
    33. CalculateRange(ranges[1], out start, out length);
    34. SecondSections = Enumerable.Range(start, length).ToArray();
    35. }
    36. public void CalculateRange(string range, out int start, out int length)
    37. {
    38. string[] sections = range.Split('-');
    39. start = int.Parse(sections[0]);
    40. int end = int.Parse(sections[1]);
    41. length = (end - start) + 1;
    42. }
    43. }​


    Tag 5:
    Spoiler anzeigen

    C#-Quellcode

    1. ​public static class AoC_D5
    2. {
    3. public static string CargoStackMessagePt1 { get; private set; } = string.Empty;
    4. public static string CargoStackMessagePt2 { get; private set; } = string.Empty;
    5. private static Stack<string>[] CargoStacksPt1 = new Stack<string>[9];
    6. private static Stack<string>[] CargoStacksPt2 = new Stack<string>[9];
    7. static AoC_D5()
    8. {
    9. for (int i = 0; i < CargoStacksPt1.Length; i++)
    10. {
    11. CargoStacksPt1[i] = new Stack<string>();
    12. CargoStacksPt2[i] = new Stack<string>();
    13. }
    14. }
    15. public static void ReadInputAndCalculate()
    16. {
    17. using StreamReader streamReader = new StreamReader("AoC_5_input.txt");
    18. Stack<string> initStack = new Stack<string>();
    19. for (int row = 0; row < 8; row++)
    20. {
    21. string line = streamReader.ReadLine();
    22. initStack.Push(line);
    23. }
    24. //Setup Stack 1 and 2 identically.
    25. while (initStack.TryPop(out string initLine))
    26. {
    27. for (int i = 0; i < 9; i++)
    28. {
    29. CargoStacksPt1[i].Push(initLine[4 * i + 1].ToString());
    30. CargoStacksPt2[i].Push(initLine[4 * i + 1].ToString());
    31. }
    32. }
    33. //No need to check both cargostacks, they're identical anyway.
    34. for (int stack = 0; stack < CargoStacksPt1.Length; stack++)
    35. {
    36. while (string.IsNullOrWhiteSpace(CargoStacksPt1[stack].Peek()))
    37. {
    38. CargoStacksPt1[stack].Pop();
    39. CargoStacksPt2[stack].Pop();
    40. }
    41. }
    42. //Read over the next 2 lines that are irrelevant/empty.
    43. _ = streamReader.ReadLine();
    44. _ = streamReader.ReadLine();
    45. do
    46. {
    47. string line = streamReader.ReadLine();
    48. string[] lineParts = line.Split(' ');
    49. int amount = int.Parse(lineParts[1]);
    50. int from = int.Parse(lineParts[3]) - 1;
    51. int to = int.Parse(lineParts[5]) - 1;
    52. CalculateMovementsForPt1(amount, from, to);
    53. CalculateMovementsForPt2(amount, from, to);
    54. } while (!streamReader.EndOfStream);
    55. for (int stack = 0; stack < CargoStacksPt1.Length; stack++)
    56. {
    57. CargoStackMessagePt1 += CargoStacksPt1[stack].Peek();
    58. CargoStackMessagePt2 += CargoStacksPt2[stack].Peek();
    59. }
    60. }
    61. public static void CalculateMovementsForPt1(int amount, int from, int to)
    62. {
    63. //CrateMover 9000 moves one crate at a time.
    64. for (int toDo = 0; toDo < amount; toDo++)
    65. {
    66. string item = CargoStacksPt1[from].Pop();
    67. CargoStacksPt1[to].Push(item);
    68. }
    69. }
    70. public static void CalculateMovementsForPt2(int amount, int from, int to)
    71. {
    72. //Since CrateMover 9001 can lift multiple crates at once, the counterstack represents the grabbing device of the crane.
    73. Stack<string> counterStack = new Stack<string>();
    74. for (int toDo = 0; toDo < amount; toDo++)
    75. {
    76. string crate = CargoStacksPt2[from].Pop();
    77. counterStack.Push(crate);
    78. }
    79. while (counterStack.TryPop(out string crate))
    80. {
    81. CargoStacksPt2[to].Push(crate);
    82. }
    83. }
    84. }


    Tag 6:
    Spoiler anzeigen

    C#-Quellcode

    1. public static class AoC_D6
    2. {
    3. public static int MarkerPt1 { get; set; }
    4. public static int MarkerPt2 { get; set; }
    5. public static void ReadInputAndCalculate()
    6. {
    7. using StreamReader streamReader = new StreamReader("AoC_6_input.txt");
    8. string input = streamReader.ReadToEnd();
    9. MarkerPt1 = CalculateMarker(input, 4);
    10. MarkerPt2 = CalculateMarker(input, 14);
    11. }
    12. private static int CalculateMarker(string input, int markerLength)
    13. {
    14. bool markerFound = false;
    15. for (int inputPosition = 0; inputPosition < input.Length - markerLength; inputPosition++)
    16. {
    17. char[] buffer = input.Substring(inputPosition, markerLength).ToCharArray();
    18. HashSet<char> found = new HashSet<char>();
    19. for (int bufferPosition = 0; bufferPosition < buffer.Length; bufferPosition++)
    20. {
    21. markerFound = found.Add(buffer[bufferPosition]);
    22. if (!markerFound)
    23. {
    24. break;
    25. }
    26. }
    27. if (markerFound)
    28. {
    29. return inputPosition + markerLength;
    30. }
    31. }
    32. return 0;
    33. }
    34. }​
    Hier meine Lösung für Tag 7.
    Wäre ich nicht über die Aufgabenstellung von Pt1 gestolpert, wäre das eigentlich recht fix erledigt gewesen. Mehr dazu in den Kommentaren des Codes (will ja nix verraten ;) )
    Spoiler anzeigen

    C#-Quellcode

    1. public static class AoC_D7
    2. {
    3. public static int TotalFolderSizePt1 { get; private set; }
    4. public static int TotalFolderSizePt2 { get; private set; }
    5. public static Folder Root { get; private set; } = new Folder("/", null);
    6. public static void ReadInputAndCalculate()
    7. {
    8. using StreamReader streamReader = new StreamReader("AoC_7_input.txt");
    9. Folder current = null;
    10. do
    11. {
    12. string line = streamReader.ReadLine();
    13. string[] parts = line.Split(' ', StringSplitOptions.RemoveEmptyEntries);
    14. if (parts[0] == "$")
    15. if (parts[1] == "cd")
    16. current = parts[2] switch
    17. {
    18. "/" => Root,
    19. ".." => current.Parent,
    20. _ => current = current.Folders[parts[2]],
    21. };
    22. else
    23. continue;
    24. else if (parts[0] == "dir")
    25. current.AddFolder(new Folder(parts[1], current));
    26. else
    27. current.AddFile(new File(parts[1], int.Parse(parts[0]), current));
    28. } while (!streamReader.EndOfStream);
    29. TotalFolderSizePt1 = Root.GetFoldersBelowSize(100000).Sum(x => x.TotalSize);
    30. CalculdatePt2();
    31. }
    32. private static void CalculdatePt2()
    33. {
    34. int requiredSpace = 30000000;
    35. int totalSpace = 70000000;
    36. int usedSpace = Root.TotalSize;
    37. int freeSpace = totalSpace - usedSpace;
    38. int neededSpace = requiredSpace - freeSpace;
    39. List<Folder> allFolders = Root.GetFoldersBelowSize(int.MaxValue).ToList();
    40. Folder deleteFolder = allFolders.OrderBy(x => x.TotalSize).Where(x => x.TotalSize >= neededSpace).First();
    41. TotalFolderSizePt2 = deleteFolder.TotalSize;
    42. }
    43. }
    44. public class Folder
    45. {
    46. public string Name { get; set; }
    47. public int TotalSize { get; private set; }
    48. public List<File> Files { get; } = new List<File>();
    49. public Dictionary<string, Folder> Folders { get; } = new Dictionary<string, Folder>();
    50. public Folder Parent { get; }
    51. private List<Action> SizeChangedSubscribers { get; } = new List<Action>();
    52. public Folder(string name, Folder parent)
    53. {
    54. Name = name;
    55. Parent = parent;
    56. }
    57. public void AddFile(File newFile)
    58. {
    59. Files.Add(newFile);
    60. TotalSize += newFile.Size;
    61. SizeChanged();
    62. }
    63. public void AddFolder(Folder newFolder)
    64. {
    65. Folders[newFolder.Name] = newFolder;
    66. TotalSize += newFolder.TotalSize;
    67. newFolder.SubscribeSizeChanged(RecalculateTotalSize);
    68. SizeChanged();
    69. }
    70. public void SubscribeSizeChanged(Action callback)
    71. => SizeChangedSubscribers.Add(callback);
    72. protected void SizeChanged()
    73. {
    74. foreach (var item in SizeChangedSubscribers)
    75. item();
    76. }
    77. private void RecalculateTotalSize()
    78. {
    79. TotalSize = 0;
    80. foreach (var item in Files)
    81. TotalSize += item.Size;
    82. foreach (var item in Folders)
    83. TotalSize += item.Value.TotalSize;
    84. SizeChanged();
    85. }
    86. public List<Folder> GetFoldersBelowSize(int size)
    87. {
    88. List<Folder> result = new List<Folder>();
    89. foreach (var item in Folders)
    90. {
    91. if (item.Value.TotalSize <= size)
    92. result.Add(item.Value);
    93. result.AddRange(item.Value.GetFoldersBelowSize(size));
    94. }
    95. return result;
    96. //This was the code that made me go validate the result by hand going through the input,
    97. //printing out my file/folder tree into the console, checking all the folders and their sizes
    98. //with notepad and calculator open, until I realized that the objective was to get the
    99. //size of ALL folders, not just the topmost ones even if its just stacked empty folders
    100. //with only the bottom most one having a file in it.
    101. //
    102. //LESSON: Reading is important!
    103. //
    104. /*foreach (var item in Folders)
    105. *{
    106. * if (item.Value.TotalSize <= size)
    107. * result.Add(item.Value);
    108. * else
    109. * result.AddRange(item.Value.GetFoldersBelowSize(size));
    110. *}
    111. *return result;
    112. */
    113. }
    114. /// <summary>
    115. /// Prints a nice file/folder structure into the console/Debug/whatever. <br />
    116. /// Why? because I was grasping at straws for why my code returned the wrong total size.<br />
    117. /// See comments in <see cref="GetFoldersBelowSize"/> for more info.
    118. /// </summary>
    119. /// <returns></returns>
    120. public override string ToString()
    121. {
    122. string result = string.Empty;
    123. if (Parent == null)
    124. {
    125. result += $"- {Name} (dir, TotalSize={TotalSize})\r\n";
    126. }
    127. else
    128. {
    129. Folder current = Parent;
    130. int offset = 0;
    131. do
    132. {
    133. offset++;
    134. current = current.Parent;
    135. } while (current != null);
    136. result += $"{"".PadLeft(offset * 2)}- {Name} (dir, TotalSize={TotalSize})\r\n";
    137. }
    138. foreach (var item in Files)
    139. {
    140. result += item.ToString();
    141. }
    142. foreach (var item in Folders)
    143. {
    144. result += item.Value.ToString();
    145. }
    146. return result;
    147. }
    148. }
    149. public class File
    150. {
    151. public string Name { get; set; }
    152. public int Size { get; set; }
    153. public Folder Parent { get; set; }
    154. public File(string name, int size, Folder parent)
    155. {
    156. Name = name;
    157. Size = size;
    158. Parent = parent;
    159. }
    160. public override string ToString()
    161. {
    162. Folder current = Parent;
    163. int offset = 0;
    164. do
    165. {
    166. offset++;
    167. current = current.Parent;
    168. } while (current != null);
    169. return $"{"".PadLeft(offset * 2)}- {Name} (file, size={Size})\r\n";
    170. }
    171. }