Advent of Code 2023

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

    Wer macht die Codes hier für AoC eigentlich mit TDD? Wäre m.E. ganz sinnvoll. Aber leider mach ich es nicht - weder hier noch bei anderen Projekten. ||
    Aber als Einzelentwickler ist leider auch keiner da, der mir diesbezüglich in den Ar…beitscode redet - leider.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

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

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

    @exc-jdbi Falls es Dich noch interessiert. Die Summe für Teil 2 aus deiner Post für meinen Input ... (ist falsch; ne war mein Fehler) ist RICHTIG!!!

    @VaporiZed TDD! Ich leider nicht. Da nur Hobby Coder + Einzelkämpfer. Obwohl ich denke, dass TDD ein Schritt wäre, der mich weiter bringt. Es fehlt an der Motivation.

    nogood
    codewars.com Rank: 4 kyu

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

    Part 1

    C#-Quellcode

    1. private static void Part01()
    2. {
    3. var source = Source();
    4. var maps = ToMaps(source.Skip(1));
    5. var seeds = source[0][1].Split(" ",
    6. StringSplitOptions.RemoveEmptyEntries).Select(long.Parse);
    7. var result = long.MaxValue;
    8. foreach (var seed in seeds)
    9. {
    10. var value = seed;
    11. foreach (var map in maps)
    12. foreach (var (src, dest, cnt) in map)
    13. if (src <= value && value < src + cnt)
    14. { value = dest + value - src; break; }
    15. result = Math.Min(result, value);
    16. }
    17. Console.WriteLine($"{nameof(Part01)}: lowest location: {result}");
    18. }

    Part 2

    C#-Quellcode

    1. private static void Part02()
    2. {
    3. var src = SourceText();
    4. var idx = src[0].IndexOf(':') + 1;
    5. var seeds = src[0].Substring(idx).Split(" ",
    6. StringSplitOptions.RemoveEmptyEntries).Select(long.Parse)
    7. .Chunk(2);
    8. List<(long start, long to)> tmp;
    9. var result = new List<(long start, long to)>();
    10. var changed = new List<(long start, long to)>();
    11. seeds.ForEach(x => result.Add((x[0],x[1])));
    12. foreach (var line in src.Skip(1))
    13. {
    14. tmp = [];
    15. if (line == "" || line.Contains(':'))
    16. {
    17. foreach (var (start, to) in changed)
    18. result.Add((start, to));
    19. changed.Clear();
    20. continue;
    21. }
    22. var map = line.Split().Where(s=> !string.IsNullOrEmpty(s)).Select(long.Parse).ToList();
    23. foreach (var (start, to) in result)
    24. {
    25. var rstart = map[1];
    26. var rto = map[1] + map[2] - 1;
    27. var offset = map[0] - map[1];
    28. var sstart = start;
    29. var sto = start + to - 1;
    30. long crstart = 0, crto = 0;
    31. switch (true)
    32. {
    33. case var b when rstart < sstart && rto >= sstart & rto <= sto:
    34. crstart = sstart;
    35. crto = rto;
    36. changed.Add((crstart + offset, crto - crstart + 1));
    37. if (crto + 1 <= sto) tmp.Add((crto + 1, sto - (crto + 1) + 1));
    38. break;
    39. case var b when rstart >= sstart && rto <= sto:
    40. crstart = rstart;
    41. crto = rto;
    42. changed.Add((crstart + offset, crto - crstart + 1));
    43. if (crto + 1 <= sto) tmp.Add((crto + 1, sto - (crto + 1) + 1));
    44. if (crstart - 1 >= sstart) tmp.Add((sstart, crstart - 1 - sstart + 1));
    45. break;
    46. case var b when rstart >= sstart && rstart <= sto && rto > sto:
    47. crstart = rstart;
    48. crto = sto;
    49. changed.Add((crstart + offset, crto - crstart + 1));
    50. if (crstart - 1 >= sstart) tmp.Add((sstart, crstart - 1 - sstart + 1));
    51. break;
    52. case var b when rstart < sstart && rto > sto:
    53. crstart = sstart;
    54. crto = sto;
    55. changed.Add((crstart + offset, crto - crstart + 1));
    56. break;
    57. default:
    58. tmp.Add((sstart, sto - sstart + 1));
    59. break;
    60. }
    61. }
    62. result = tmp;
    63. }
    64. changed.ForEach(x => result.Add((x.start, x.to)));
    65. Console.WriteLine($"{nameof(Part02)}: {result.Min(x => x.start)}");
    66. }

    Source

    C#-Quellcode

    1. private static string[][] Source()
    2. {
    3. var result = new List<string[]>();
    4. var src = SourceText().Where(line => line != "").ToArray();
    5. var first = src.First().Split(": ",StringSplitOptions.RemoveEmptyEntries);
    6. first[0] += ":";
    7. result.Add(first);
    8. for (var i = 1; i < src.Length; i++)
    9. {
    10. var tmp = new List<string>{src[i]};
    11. for (var j = ++i; j < src.Length; j++, i++)
    12. {
    13. if (src[j].Contains('-'))
    14. { i--;break; }
    15. else tmp.Add(src[j]);
    16. }
    17. result.Add([.. tmp]);
    18. }
    19. return [.. result];
    20. }
    21. private static string[] SourceText() =>
    22. [
    23. "seeds: 79 14 55 13",
    24. "",
    25. "seed-to-soil map:",
    26. "50 98 2",
    27. "52 50 48",
    28. "",
    29. "soil-to-fertilizer map:",
    30. "0 15 37",
    31. "37 52 2",
    32. "39 0 15",
    33. "",
    34. "fertilizer-to-water map:",
    35. "49 53 8",
    36. "0 11 42",
    37. "42 0 7",
    38. "57 7 4",
    39. "",
    40. "water-to-light map:",
    41. "88 18 7",
    42. "18 25 70",
    43. "",
    44. "light-to-temperature map:",
    45. "45 77 23",
    46. "81 45 19",
    47. "68 64 13",
    48. "",
    49. "temperature-to-humidity map:",
    50. "0 69 1",
    51. "1 0 69",
    52. "",
    53. "humidity-to-location map:",
    54. "60 56 37",
    55. "56 93 4",
    56. ];


    Hier noch eine Rekursive Methode
    Part 2 Rekursiv

    C#-Quellcode

    1. private static void Part02_Recursiv()
    2. {
    3. var src = Source();
    4. var maps = ToMaps(src.Skip(1));
    5. src[0] = [string.Join(" ", src[0])];
    6. (long from,long to)[] seeds = src[0][0].Split(" ").Skip(1).Select(long.Parse).Chunk(2)
    7. .Select(pair => (pair[0],pair[0] + pair[1] - 1) ).ToArray();
    8. static bool TryToComparer((long from, long to) this_, (long from, long to) other,
    9. out (long from, long to) compare)
    10. {
    11. compare = new(Math.Max(this_.from, other.from), Math.Min(this_.to, other.to));
    12. return compare.to >= compare.from;
    13. }
    14. static (long from, long to) FromCount(long start, long count) =>
    15. new(start, start + count - 1);
    16. static (long from, long to) Offset((long from, long to)this_, long distance) =>
    17. new(this_.from + distance,this_. to + distance);
    18. long lookup_bfs((long from, long to) range, int idx)
    19. {
    20. if (idx >= maps!.Length) return range.from;
    21. var compareleft = new List<(long from, long to)>();
    22. var compareright = new List<(long from, long to)>();
    23. foreach (var (src, dest, cnt) in maps[idx])
    24. {
    25. var tmp = FromCount(src, cnt);
    26. if (TryToComparer(range, tmp, out var compare))
    27. {
    28. compareleft.Add(compare);
    29. compareright.Add(Offset(compare, dest - src));
    30. }
    31. }
    32. var leftmin = compareleft.OrderBy(_ => _.from)
    33. .Prepend((range.from - 1, range.from - 1))
    34. .Append((range.to + 1, range.to + 1))
    35. .Pairwise((r1, r2) => (r1.Item2 + 1, r2.Item1 - 1))
    36. .Where(_ => _.Item2 >= _.Item1);
    37. return leftmin.Concat(compareright).Min(x => lookup_bfs(x, idx + 1));
    38. }
    39. var result = seeds!.Select(_ => lookup_bfs(_, 0)).Min();
    40. Console.WriteLine($"{nameof(Part02_Recursiv)}: {result}");
    41. }
    42. private static (long src, long dest, long cnt)[][] ToMaps(IEnumerable<string[]> src)
    43. {
    44. var result = new List<(long src, long dest, long cnt)[]>();
    45. foreach (var datas in src)
    46. {
    47. var tmp = new List<(long src, long dest, long cnt)>();
    48. foreach (var strset in datas.Skip(1))
    49. {
    50. if (strset == string.Empty) continue;
    51. var lset = strset.Split(' ', StringSplitOptions.RemoveEmptyEntries).Select(long.Parse).ToArray();
    52. tmp.Add((lset[1], lset[0], lset[2]));
    53. }
    54. result.Add([.. tmp]);
    55. }
    56. return [.. result];
    57. }

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

    Ich weiß nicht mal was tdd ist.^^
    D5 Part 1

    VB.NET-Quellcode

    1. Private maps As IEnumerable(Of IEnumerable(Of mapping))
    2. Sub Main()
    3. Dim input = IO.File.ReadAllText(FilePathOfData).Split(vbCrLf & vbCrLf)
    4. Dim seeds = input(0).Substring(7).Split(" "c).Select(Function(s) CLng(s))
    5. maps = input.Skip(1).Select(Function(s) s.Split(vbCrLf).Skip(1).Select(Function(l) New mapping(l.Split(" "c))))
    6. Dim result = seeds.Min(Function(s)
    7. Dim value = s
    8. For i = 0 To maps.Count - 1
    9. value = MapToMap(i, value)
    10. Next
    11. Return value
    12. End Function)
    13. Stop
    14. End Sub
    15. Private Function MapToMap(mapidx As Integer, input As Long) As Long
    16. Dim map = maps(mapidx).FirstOrDefault(Function(m) input >= m.src AndAlso input <= m.src + m.len)
    17. If map Is Nothing Then Return Long.MaxValue
    18. Return input - map.src + map.dest
    19. End Function
    20. Friend Class mapping
    21. Property dest As Long
    22. Property src As Long
    23. Property len As Long
    24. Sub New(from As String())
    25. _dest = CLng(from(0))
    26. _src = CLng(from(1))
    27. _len = CLng(from(2))
    28. End Sub
    29. End Class


    Nach Post 47 eingefügt: @VaporiZed
    Mein Part 2 Algo dauert definitiv Stunden^^ Ist quasi derselbe wie i Part 1. Wenn ich alles lade, sind das einige GB
    Ich habe versucht mich ranzutasten (das geht zügig), aber je nachdem wie eng die Pfade durch die Maps sein können, ist es reine Glückssache, wenn man den richtigen Wert damit findet. Hab zwar einen der Faktor 5 kleiner ist als Part 1 aber nicht der richtige xD
    Das wird aber nicht der richtige Weg sein. Da muss man schon kräftig knobeln

    Vielleicht kann einer von den anderen die AoC schon kennen was dazu sagen, ob manche Lösungen tatsächlich mehr als 1 Sekunde Codelaufzeit sein können?

    ---Edit---
    Habe den Trick gefunden. Alle Maps sind bijektiv, das heißt man kann rückwärts durchlaufen. Also alle Locations von 0 aufwärts prüfen, statt alle Seeds.
    Denn die minimale Location kennt man erst nachdem man die meisten Seeds geprüft hat, aber die erste Location, die einen Seed findet ist automatisch die minimale Location. (Witzig mit diesem Ansatz wäre Part 1 ungleich langsamer, da die Ergebnis-Location erwartungsgemäß massiv höher ausfällt als die Anzahl der Seeds)
    Nun trotz dessen ist mein Code echt langsam, aber man kann sich innerhalb weniger Minuten zum Ergebnis tasten (und da werden nur n paar MB geladen)

    ---Edit2---
    Beendet nun sofort:
    D5 Part 2 und Part 1 in einem
    Um 28Mio liegt das Ergebnis rum. Die Sache ist mein Debugger sagt mir ein Loop dauert < 1ms, aber ich schaffe in Wahrheit nur 50.000 loops pro Sekunde. Werde das heute nicht genauer auswerten. Irgendwo stimmt da noch was nicht, das kann doch nicht sein, dass 7mal FirstOrDefault so lange dauert ?(

    VB.NET-Quellcode

    1. Private maps As mapping()()
    2. Sub Main()
    3. Dim input = IO.File.ReadAllText(FilePathOfData).Split(vbCrLf & vbCrLf)
    4. Dim seeds = input(0).Substring(7).Split(" "c).Select(AddressOf Long.Parse)
    5. Dim rgx As New Regex("(?<start>\d+) (?<length>\d+)")
    6. Dim seedRanges = rgx.Matches(input(0)).Select(Function(m) New With {.start = CLng(m.Groups("start").Value), .length = CLng(m.Groups("length").Value)}).ToArray
    7. maps = input.Skip(1).Select(Function(s) s.Split(vbCrLf).Skip(1).Select(Function(l) New mapping(l.Split(" "c))).ToArray).ToArray
    8. Dim resultPart1 = seeds.Min(Function(s)
    9. Dim value = s
    10. For i = 0 To maps.Count - 1
    11. value = MapToMap(i, value)
    12. Next
    13. Return value
    14. End Function)
    15. Dim resultPart2 As Long
    16. Dim seed As Long
    17. Dim k As Integer = 6 'Gern auch höher, ggf. Anzahl der Stellen der max möglichen Location
    18. While k >= 0
    19. While Not seedRanges.Any(Function(r) seed >= r.start AndAlso seed < r.start + r.length)
    20. resultPart2 += 10 ^ k
    21. seed = resultPart2
    22. For i = maps.Length - 1 To 0 Step -1
    23. seed = MapToMapReverse(i, seed)
    24. Next
    25. End While
    26. resultPart2 -= 10 ^ k
    27. k -= 1
    28. seed = resultPart2
    29. End While
    30. resultPart2 += 1
    31. End Sub
    32. Private Function MapToMap(mapidx As Integer, input As Long) As Long
    33. Dim map = maps(mapidx).FirstOrDefault(Function(m) input >= m.src AndAlso input <= m.src + m.len)
    34. If map Is Nothing Then Return input
    35. Return input + map.dest - map.src
    36. End Function
    37. Private Function MapToMapReverse(mapidx As Integer, input As Long) As Long
    38. Dim map = maps(mapidx).FirstOrDefault(Function(m) input >= m.dest AndAlso input <= m.dest + m.len)
    39. If map Is Nothing Then Return input
    40. Return input + map.src - map.dest
    41. End Function
    42. Friend Class mapping
    43. Property dest As Long
    44. Property src As Long
    45. Property len As Long
    46. Sub New(from As String())
    47. _dest = CLng(from(0))
    48. _src = CLng(from(1))
    49. _len = CLng(from(2))
    50. End Sub
    51. End Class


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

    @Haudruferzappeltnoch: Test Driven Development :D

    Ich krieg nen Vogel bei Part2. Entweder hab ich nen totalen Denkfehler oder meiner Code ist super ineffizient. Da sollen Abermilliarden von IDs getestet werden?!? Mein Algo scheint zwar zu funktionieren, aber das Durcharbeiten würde Stunden dauern. Ok, vielleicht nicht, aber der erste von 10 Blöcken dauert schon 100 Sekunden :S
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

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

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

    Finally got it. Ich dachte schon, dass nach 20 Minuten Rechenzeit der falsche Wert rauskommt :S
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Friend Class FrmMain
    2. Private Async Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    3. Dim Values = Await Threading.Tasks.Task.Run(Function() New ValueCalculatorForDay5().GetValuesFor("input2.txt"))
    4. MessageBox.Show(Values.Part1Value.ToString)
    5. MessageBox.Show(Values.Part2Value.ToString)
    6. End Sub
    7. End Class
    8. Friend Class ValueCalculatorForDay5
    9. Private ReadOnly TitleParameterTypePairs As New Dictionary(Of String, ParameterType) From {{"seed-to-soil map:", ParameterType.SeedToSoil},
    10. {"soil-to-fertilizer map:", ParameterType.SoilToFertilizer},
    11. {"fertilizer-to-water map:", ParameterType.FertilizerToWater},
    12. {"water-to-light map:", ParameterType.WaterToLight},
    13. {"light-to-temperature map:", ParameterType.LightToTemperature},
    14. {"temperature-to-humidity map:", ParameterType.TemperatureToHumidity},
    15. {"humidity-to-location map:", ParameterType.HumidityToLocation}}
    16. Private ReadOnly ParameterTables As New List(Of ParameterTable)
    17. Private MinimumLocationIDs As New List(Of Long)
    18. Private MinimumEnhancedLocationIDs As New List(Of Long)
    19. Function GetValuesFor(FilePath As String) As (Part1Value As Long, Part2Value As Long)
    20. InitializeIDLists()
    21. Dim RawDataLines = GetRawDataFrom(FilePath)
    22. ParseRawData(RawDataLines)
    23. Dim SeedData = GetSeedDataFrom(GetSeedValuesAsTexts(RawDataLines(0)))
    24. Threading.Tasks.Parallel.For(0, SeedData.Count - 1, Sub(x) ConvertSeedIDsToLocationIDs(SeedData(x), x))
    25. Return (MinimumLocationIDs.Min, MinimumEnhancedLocationIDs.Min)
    26. End Function
    27. Private Sub InitializeIDLists()
    28. For i = 1 To 10
    29. MinimumLocationIDs.Add(Long.MaxValue)
    30. MinimumEnhancedLocationIDs.Add(Long.MaxValue)
    31. Next
    32. End Sub
    33. Private Function GetSeedValuesAsTexts(RawDataLine As String) As IEnumerable(Of String)
    34. Return RawDataLine.Split({":"c, " "c}, StringSplitOptions.RemoveEmptyEntries).Skip(1)
    35. End Function
    36. Private Function GetSeedDataFrom(RawDataValues As IEnumerable(Of String)) As IEnumerable(Of (Value1 As Long, Value2 As Long))
    37. Dim List As New List(Of (Value1 As Long, Value2 As Long))
    38. For i = 0 To RawDataValues.Count - 1 Step 2
    39. List.Add((Long.Parse(RawDataValues(i)), Long.Parse(RawDataValues(i + 1))))
    40. Next
    41. Return List
    42. End Function
    43. Private Function GetRawDataFrom(FilePath As String) As IEnumerable(Of String)
    44. Return IO.File.ReadAllLines(FilePath)
    45. End Function
    46. Private Sub ParseRawData(RawDataLines As IEnumerable(Of String))
    47. ParseBlocks(GetDataBlocksFrom(RawDataLines.Skip(2)))
    48. End Sub
    49. Private Function GetDataBlocksFrom(RawDataLines As IEnumerable(Of String)) As IEnumerable(Of IEnumerable(Of String))
    50. Dim Blocks As New List(Of IEnumerable(Of String))
    51. Dim BlockData As New List(Of String)
    52. For Each RawDataLine In RawDataLines
    53. If Not String.IsNullOrEmpty(RawDataLine) Then
    54. BlockData.Add(RawDataLine)
    55. Else
    56. Blocks.Add(BlockData)
    57. BlockData = New List(Of String)
    58. End If
    59. Next
    60. Blocks.Add(BlockData)
    61. Return Blocks
    62. End Function
    63. Private Sub ParseBlocks(Blocks As IEnumerable(Of IEnumerable(Of String)))
    64. Blocks.ToList.ForEach(Sub(x) ParseBlock(x))
    65. End Sub
    66. Private Sub ParseBlock(BlockData As IEnumerable(Of String))
    67. Dim NewParameterTable As New ParameterTable With {.ParameterType = TitleParameterTypePairs.Single(Function(x) x.Key = BlockData(0)).Value}
    68. For Each BlockLine In BlockData.Skip(1)
    69. Dim RawData = BlockLine.Split
    70. Dim SourceStartValue = Long.Parse(RawData(1))
    71. Dim DestinationStartValue = Long.Parse(RawData(0))
    72. Dim Range = Integer.Parse(RawData(2))
    73. NewParameterTable.AdditionalMappings.Add(New AdditionalMapping(SourceStartValue, DestinationStartValue, Range))
    74. Next
    75. ParameterTables.Add(NewParameterTable)
    76. End Sub
    77. Private Sub ConvertSeedIDsToLocationIDs(Data As (Value1 As Long, Value2 As Long), Index As Integer)
    78. Call {Data.Value1, Data.Value2}.ToList.ForEach(Sub(x) MinimumLocationIDs(Index) = Math.Min(GetLocationIdFrom(x), MinimumLocationIDs(Index)))
    79. ConvertEnhancedSeedIdToLocationId(Data, Index)
    80. End Sub
    81. Private Function GetLocationIdFrom(SeedID As Long) As Long
    82. Dim CurrentID = SeedID
    83. For Each ParameterTable In ParameterTables
    84. CurrentID = GetNewIdFrom(ParameterTable, CurrentID)
    85. Next
    86. Return CurrentID
    87. End Function
    88. Private Sub ConvertEnhancedSeedIdToLocationId(Data As (Value1 As Long, Value2 As Long), Index As Integer)
    89. For i = Data.Value1 To Data.Value1 + Data.Value2 - 1
    90. MinimumEnhancedLocationIDs(Index) = Math.Min(GetLocationIdFrom(i), MinimumEnhancedLocationIDs(Index))
    91. Next
    92. End Sub
    93. Private Function GetNewIdFrom(ParameterTable As ParameterTable, ID As Long) As Long
    94. Dim FittingMapping = ParameterTable.AdditionalMappings.FirstOrDefault(Function(x) x.Contains(ID))
    95. If FittingMapping Is Nothing Then Return ID
    96. Return FittingMapping.GetConvertedValueOf(ID)
    97. End Function
    98. End Class
    99. Friend Class ParameterTable
    100. Property ParameterType As ParameterType
    101. Property AdditionalMappings As New List(Of AdditionalMapping)
    102. End Class
    103. Friend Class AdditionalMapping
    104. Property SourceStartValue As Long
    105. Property DestinationStartValue As Long
    106. Property Range As Integer
    107. Sub New(SourceStartValue As Long, DestinationStartValue As Long, Range As Integer)
    108. Me.SourceStartValue = SourceStartValue
    109. Me.DestinationStartValue = DestinationStartValue
    110. Me.Range = Range
    111. End Sub
    112. Function Contains(ID As Long) As Boolean
    113. Return ID >= SourceStartValue AndAlso ID <= SourceStartValue + Range - 1
    114. End Function
    115. Function GetConvertedValueOf(ID As Long) As Long
    116. Dim Offset = DestinationStartValue - SourceStartValue
    117. Return ID + Offset
    118. End Function
    119. End Class
    120. Friend Enum ParameterType
    121. SeedToSoil
    122. SoilToFertilizer
    123. FertilizerToWater
    124. WaterToLight
    125. LightToTemperature
    126. TemperatureToHumidity
    127. HumidityToLocation
    128. End Enum
    Aber die Parallelverarbeitung brachte nix. Da fehlt mir wohl noch Übung.
    @Haudruferzappeltnoch: Ich hatte auch zuerst versucht, alle Seeds in den RAM zu donnern, aber das gab auch GB-Mengen, was verweigert wurde. Daher hab ich es nun paarweise gemacht.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

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

    Haudruferzappeltnoch schrieb:

    Vielleicht kann einer von den anderen die AoC schon kennen was dazu sagen, ob manche Lösungen tatsächlich mehr als 1 Sekunde Codelaufzeit sein können?

    Ja das kann sein. Gerade bei einem Tag wie heute.
    Ich habe jetzt meinen Code fertig und hab mal gestartet. Mal schauen ob ich weniger als 20 Minuten Rechenzeit brauche.
    Weiß aber nicht ob mein Code da so performant ist. Sobald fertig und das Ergebnis stimmt poste ich mal den Code.
    @VaporiZed ich machs jetzt auch "nach und nach" mein PC mochte nicht mehr nachdem die 64GB Ram voll waren :D
    Grüße , xChRoNiKx

    Nützliche Links:
    Visual Studio Empfohlene Einstellungen | Try-Catch heißes Eisen
    Uff ok. Ich musste nochmal umschreiben weil nach 50+ Minuten nichts fertig war.
    Hier jetzt aber P1 und P2 sorry nur full source diesmal:
    EDIT// Ich seh grad hab noch garnicht full aufgeräumt... mach ich mal die tage.
    Spoiler anzeigen

    Ich habe natürlich auch erst alles in den RAM geladen war keine gute Idee...
    Nun schreibe ich alle Seeds erst in eine TXT (Achtung die ist bei mir 30GB groß) und gehe dann parallel per ReadLines die zeilen durch um für P2 die lowest location zu berechnen.
    Der Vorgang hat ca. 40 Minuten gedauert.
    Für performantere Lösungen bin ich gerne zu haben :)

    C#-Quellcode

    1. using System.Text.RegularExpressions;
    2. namespace Tag05
    3. {
    4. internal class Program
    5. {
    6. static void Main(string[] args)
    7. {
    8. string[] inputFile = File.ReadAllLines("Input.txt");
    9. Garden gardenP1 = new Garden();
    10. gardenP1.Convert(inputFile);
    11. gardenP1.ProcessSeedsP1();
    12. Console.WriteLine($"Lowest Location P1: {gardenP1.seeds.Min(x => x.Location)}");
    13. Garden gardenP2 = new Garden();
    14. gardenP2.Convert(inputFile,true);
    15. Console.WriteLine($"Lowest Location P1: {gardenP2.ProcessSeedsP2()}");
    16. }
    17. }
    18. class Garden
    19. {
    20. public List<Seed> seeds = new List<Seed>();
    21. List<Map> maps = new List<Map>();
    22. Dictionary<long, long> SeedToSoil = new Dictionary<long, long>();
    23. Dictionary<long, long> SoilToFertilizer = new Dictionary<long, long>();
    24. Dictionary<long, long> FertilizerToWater = new Dictionary<long, long>();
    25. Dictionary<long, long> WaterToLight = new Dictionary<long, long>();
    26. Dictionary<long, long> LightToTemperature = new Dictionary<long, long>();
    27. Dictionary<long, long> TemperatureToHumidity = new Dictionary<long, long>();
    28. Dictionary<long, long> HumidityToLocation = new Dictionary<long, long>();
    29. public Garden()
    30. {
    31. maps.Add(new Map() { OrderNumber = 0, Name = "seed-to-soil", Mapping = SeedToSoil });
    32. maps.Add(new Map() { OrderNumber = 1, Name = "soil-to-fertilizer", Mapping = SoilToFertilizer });
    33. maps.Add(new Map() { OrderNumber = 2, Name = "fertilizer-to-water", Mapping = FertilizerToWater });
    34. maps.Add(new Map() { OrderNumber = 3, Name = "water-to-light", Mapping = WaterToLight });
    35. maps.Add(new Map() { OrderNumber = 4, Name = "light-to-temperature", Mapping = LightToTemperature });
    36. maps.Add(new Map() { OrderNumber = 5, Name = "temperature-to-humidity", Mapping = TemperatureToHumidity });
    37. maps.Add(new Map() { OrderNumber = 6, Name = "humidity-to-location", Mapping = HumidityToLocation });
    38. }
    39. public void Convert(string[] lines, bool part2 = false)
    40. {
    41. string processingType = "seeds";
    42. foreach (string line in lines)
    43. {
    44. if (String.IsNullOrEmpty(line)) continue;
    45. if (line.Contains("map:"))
    46. {
    47. processingType = line.Replace(" map:", "");
    48. continue;
    49. }
    50. if (processingType == "seeds")
    51. {
    52. if (line.StartsWith("seeds:"))
    53. {
    54. if (part2)
    55. {
    56. if(!File.Exists(Path.Combine(Environment.CurrentDirectory, "part2.txt")))
    57. {
    58. var matches = Regex.Matches(line.Replace("seeds:", ""), "(\\d+) (\\d+)");
    59. using StreamWriter sw = new StreamWriter(Path.Combine(Environment.CurrentDirectory, "part2.txt"));
    60. foreach (Match match in matches)
    61. {
    62. string[] numbers = match.Value.Split(' ');
    63. Int64 num1 = Int64.Parse(numbers[0]);
    64. Int64 num2 = Int64.Parse(numbers[1]);
    65. Console.WriteLine($"{num1} - {num1 + num2}");
    66. for (Int64 i = num1; i <= num1 + num2; i++)
    67. {
    68. sw.WriteLine(i.ToString());
    69. }
    70. }
    71. }
    72. }
    73. else
    74. {
    75. seeds.AddRange(line.Replace("seeds: ", "").Split(' ').Select(x => (new Seed() { SeedNumber = Int64.Parse(x) })).ToArray());
    76. }
    77. }
    78. continue;
    79. }
    80. Map currentMap = maps.FirstOrDefault(x => x.Name == processingType);
    81. if (currentMap != null)
    82. {
    83. string[] numbers = line.Split(' ');
    84. long destinationStart = Int64.Parse(numbers[0].ToString());
    85. long sourceStart = Int64.Parse(numbers[1].ToString());
    86. long length = Int64.Parse(numbers[2].ToString());
    87. Mapping mapping = new Mapping();
    88. mapping.SourceStart = sourceStart;
    89. mapping.DestinationStart = destinationStart;
    90. mapping.Length = length;
    91. currentMap.Mapping2.Add(mapping);
    92. }
    93. }
    94. }
    95. public void ProcessSeedsP1()
    96. {
    97. foreach (Map map in maps.OrderBy(x => x.OrderNumber))
    98. {
    99. foreach (Seed seed in seeds)
    100. {
    101. switch (map.Name)
    102. {
    103. case "seed-to-soil":
    104. seed.Soil = GetKeyFromDict(seed.SeedNumber, map.Mapping2);
    105. break;
    106. case "soil-to-fertilizer":
    107. seed.Fertilizer = GetKeyFromDict(seed.Soil, map.Mapping2);
    108. break;
    109. case "fertilizer-to-water":
    110. seed.Water = GetKeyFromDict(seed.Fertilizer, map.Mapping2);
    111. break;
    112. case "water-to-light":
    113. seed.Ligth = GetKeyFromDict(seed.Water, map.Mapping2);
    114. break;
    115. case "light-to-temperature":
    116. seed.Temperature = GetKeyFromDict(seed.Ligth, map.Mapping2);
    117. break;
    118. case "temperature-to-humidity":
    119. seed.Humidity = GetKeyFromDict(seed.Temperature, map.Mapping2);
    120. break;
    121. case "humidity-to-location":
    122. seed.Location = GetKeyFromDict(seed.Humidity, map.Mapping2);
    123. break;
    124. default:
    125. break;
    126. }
    127. }
    128. }
    129. }
    130. public Int64 ProcessSeedsP2()
    131. {
    132. Int64 smallesLocation = Int64.MaxValue;
    133. Parallel.ForEach(File.ReadLines(Path.Combine(Environment.CurrentDirectory, "part2.txt")), seedLine =>
    134. {
    135. Seed seed = new Seed() { SeedNumber = Int64.Parse(seedLine) };
    136. foreach (Map map in maps.OrderBy(x => x.OrderNumber))
    137. {
    138. switch (map.Name)
    139. {
    140. case "seed-to-soil":
    141. seed.Soil = GetKeyFromDict(seed.SeedNumber, map.Mapping2);
    142. break;
    143. case "soil-to-fertilizer":
    144. seed.Fertilizer = GetKeyFromDict(seed.Soil, map.Mapping2);
    145. break;
    146. case "fertilizer-to-water":
    147. seed.Water = GetKeyFromDict(seed.Fertilizer, map.Mapping2);
    148. break;
    149. case "water-to-light":
    150. seed.Ligth = GetKeyFromDict(seed.Water, map.Mapping2);
    151. break;
    152. case "light-to-temperature":
    153. seed.Temperature = GetKeyFromDict(seed.Ligth, map.Mapping2);
    154. break;
    155. case "temperature-to-humidity":
    156. seed.Humidity = GetKeyFromDict(seed.Temperature, map.Mapping2);
    157. break;
    158. case "humidity-to-location":
    159. seed.Location = GetKeyFromDict(seed.Humidity, map.Mapping2);
    160. if (seed.Location < smallesLocation)
    161. {
    162. smallesLocation = seed.Location;
    163. }
    164. break;
    165. default:
    166. break;
    167. }
    168. }
    169. });
    170. return smallesLocation;
    171. }
    172. private long GetKeyFromDict(long searchValue, HashSet<Mapping> dict)
    173. {
    174. Mapping mapping = dict.Where(x => searchValue >= x.SourceStart).Where(x => searchValue <= x.SourceStart + x.Length).FirstOrDefault();
    175. if (mapping == null) return searchValue;
    176. long length = searchValue - mapping.SourceStart;
    177. return mapping.DestinationStart + length;
    178. }
    179. }
    180. class Map
    181. {
    182. public int OrderNumber { get; set; }
    183. public string Name { get; set; }
    184. public Dictionary<long, long> Mapping { get; set; } = new Dictionary<long, long>();
    185. public HashSet<Mapping> Mapping2 { get; set; } = new HashSet<Mapping>();
    186. }
    187. class Mapping
    188. {
    189. public long SourceStart { get; set; }
    190. public long DestinationStart { get; set; }
    191. public long Length { get; set; }
    192. }
    193. class Seed
    194. {
    195. public long SeedNumber { get; set; }
    196. public long Soil { get; set; } = 0;
    197. public long Fertilizer { get; set; } = 0;
    198. public long Water { get; set; } = 0;
    199. public long Ligth { get; set; } = 0;
    200. public long Temperature { get; set; } = 0;
    201. public long Humidity { get; set; } = 0;
    202. public long Location { get; set; } = 0;
    203. }
    204. }
    Grüße , xChRoNiKx

    Nützliche Links:
    Visual Studio Empfohlene Einstellungen | Try-Catch heißes Eisen
    Wie lange hat der Durchgang gedauert?
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Ich kann als Mod sehen, dass der Edit kurz nach meiner Frage kam ;)
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Heute nur Mathe
    D6 Part 1

    VB.NET-Quellcode

    1. Sub Main()
    2. Dim input = IO.File.ReadAllLines(FilePathOfData)
    3. Dim times = input(0).Substring(5).Split(" "c, StringSplitOptions.RemoveEmptyEntries).Select(Function(s) Integer.Parse(s))
    4. Dim distances = input(1).Substring(9).Split(" "c, StringSplitOptions.RemoveEmptyEntries).Select(Function(s) Integer.Parse(s))
    5. Dim result = times.Zip(distances, AddressOf FindIntSpaceBetweenZeroes).Aggregate(Function(x, y) x * y)
    6. End Sub
    7. Private Function FindIntSpaceBetweenZeroes(x As Long, y As Long) As Integer
    8. Return Math.Floor(x / 2 + Math.Sqrt(x ^ 2 / 4 - y)) - Math.Ceiling(x / 2 - Math.Sqrt(x ^ 2 / 4 - y)) + 1
    9. End Function

    D6 Part 2

    VB.NET-Quellcode

    1. Sub Main()
    2. Dim input = IO.File.ReadAllLines(FilePathOfData)
    3. Dim t = CLng(input(0).Substring(5).Replace(" "c, String.Empty))
    4. Dim s = CLng(input(1).Substring(9).Replace(" "c, String.Empty))
    5. Dim result = FindIntSpaceBetweenZeroes(t, s)
    6. End Sub

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

    Der Tag war einfach. Das ist beides mit einem Schlag erledigt.
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Friend Class FrmMain
    2. Private Async Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    3. Dim Values = Await Threading.Tasks.Task.Run(Function() New ValueCalculatorForDay6().GetValuesFor("input2.txt"))
    4. MessageBox.Show(Values.Part1Value.ToString)
    5. MessageBox.Show(Values.Part2Value.ToString)
    6. End Sub
    7. End Class
    8. Friend Class ValueCalculatorForDay6
    9. Private ReadOnly Races As New List(Of Race)
    10. Private ReadOnly AcceleratorButtonPressDurationsToWin As New List(Of IEnumerable(Of Long))
    11. Function GetValuesFor(FilePath As String) As (Part1Value As Long, Part2Value As Long)
    12. Dim RawDataLines = GetRawDataFrom(FilePath)
    13. ParseRawData(RawDataLines)
    14. RetrieveAcceleratorButtonPressDurationsToWinAllRaces()
    15. Return (GetProductOfAcceleratorButtonPressDurations, 0)
    16. End Function
    17. Private Function GetRawDataFrom(FilePath As String) As IEnumerable(Of String)
    18. Return IO.File.ReadAllLines(FilePath)
    19. End Function
    20. Private Sub ParseRawData(RawDataLines As IEnumerable(Of String))
    21. Dim Times = RawDataLines(0).Split({":"c, " "c}, StringSplitOptions.RemoveEmptyEntries).Skip(1).Select(Function(x) Long.Parse(x))
    22. Dim Records = RawDataLines(1).Split({":"c, " "c}, StringSplitOptions.RemoveEmptyEntries).Skip(1).Select(Function(x) Long.Parse(x))
    23. For i = 0 To Times.Count - 1
    24. Races.Add(New Race(Times(i), Records(i)))
    25. Next
    26. End Sub
    27. Private Sub RetrieveAcceleratorButtonPressDurationsToWinAllRaces()
    28. AcceleratorButtonPressDurationsToWin.AddRange(Races.Select(Function(x) x.GetAcceleratorButtonPressDurationToWin))
    29. End Sub
    30. Private Function GetProductOfAcceleratorButtonPressDurations() As Long
    31. Dim Result = 1
    32. For Each AcceleratorButtonPressDurationToWin In AcceleratorButtonPressDurationsToWin
    33. Result *= AcceleratorButtonPressDurationToWin.Count
    34. Next
    35. Return Result
    36. End Function
    37. End Class
    38. Friend Class Race
    39. Private ReadOnly DurationInMilliseconds As Long
    40. Private ReadOnly DistanceToBeat As Long
    41. Sub New(DurationInMilliseconds As Long, DistanceToBeat As Long)
    42. Me.DurationInMilliseconds = DurationInMilliseconds
    43. Me.DistanceToBeat = DistanceToBeat
    44. End Sub
    45. Function GetAcceleratorButtonPressDurationToWin() As IEnumerable(Of Long)
    46. Dim AcceleratorButtonPressDurationsToWin As New List(Of Long)
    47. For i = 0 To DurationInMilliseconds - 1
    48. Dim TimeToDrive = DurationInMilliseconds - i
    49. Dim ReachableDistance = TimeToDrive * i
    50. If ReachableDistance > DistanceToBeat Then AcceleratorButtonPressDurationsToWin.Add(i)
    51. Next
    52. Return AcceleratorButtonPressDurationsToWin
    53. End Function
    54. End Class

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

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

    C#-Quellcode

    1. private static void Part01()
    2. {
    3. var src = Source().Select(s => s.Split(' ',
    4. StringSplitOptions.RemoveEmptyEntries).Skip(1).Select(int.Parse));
    5. var datas = src.First().Zip(src.Last(), (t, d) => (t, d));
    6. var result = new List<int>();
    7. foreach (var (time, distance) in datas)
    8. {
    9. var tmp = new List<int>();
    10. for (var i = 1; i < time; i++)
    11. if (i * (time - i) > distance)
    12. tmp.Add(i);
    13. if (tmp.Count > 0) result.Add(tmp.Count);
    14. }
    15. Console.WriteLine($"{nameof(Part01)}: {result.Aggregate(1, (a, b) => a * b)}");
    16. }

    Part 2

    C#-Quellcode

    1. private static void Part02()
    2. {
    3. var src = Source().Select(s => string.Join("", s.Split(' ',
    4. StringSplitOptions.RemoveEmptyEntries).Skip(1))).Select(long.Parse);
    5. var time = src.First();
    6. var distance = src.Last();
    7. var result = new List<long>();
    8. for (var i = 1; i < time; i++)
    9. if (i * (time - i) > distance)
    10. result.Add(i);
    11. Console.WriteLine($"{nameof(Part02)}: {result.Count}");
    12. }

    Source

    C#-Quellcode

    1. private static string[] Source() =>
    2. [
    3. "Time: 7 15 30",
    4. "Distance: 9 40 200",
    5. ];
    6. private static string[] Source2() =>
    7. [
    8. "Time: 71530",
    9. "Distance: 940200",
    10. ];


    Challenge

    C#-Quellcode

    1. private static void Day06Stress()
    2. {
    3. var src = SourceStress().Select(s => s.Split(' ',
    4. StringSplitOptions.RemoveEmptyEntries).Skip(1).Select(long.Parse));
    5. var datas = src.First().Zip(src.Last(), (t, d) => (t, d));
    6. Int128 result = 1;
    7. foreach (var (time, distance) in datas)
    8. {
    9. // -x^2 + time * x - distance > 0.
    10. var (x1, x2) = SolveEq(-1, time, -distance);
    11. var minx = (Int128)Math.Floor(x1) + 1;
    12. var maxx = (Int128)Math.Ceiling(x2) - 1;
    13. result *= maxx - minx + 1;
    14. }
    15. Console.WriteLine($"{nameof(Day06Stress)}_Part1: {result}");
    16. var newsrc = SourceStress().Select(s => string.Join("", s.Split(' ',
    17. StringSplitOptions.RemoveEmptyEntries).Skip(1))).Select(Int128.Parse);
    18. var t = newsrc.First();
    19. var d = newsrc.Last();
    20. {
    21. result = 0; ;
    22. // -x^2 + time * x - distance > 0.
    23. var (x1, x2) = SolveEq(-1, t, -d);
    24. var minx = (Int128)Math.Floor(x1) + 1;
    25. var maxx = (Int128)Math.Ceiling(x2) - 1;
    26. result = maxx - minx + 1;
    27. }
    28. Console.WriteLine($"{nameof(Day06Stress)}_Part2: {result}");
    29. }
    30. // solves ax^2 + bx + c = 0 (with two roots)
    31. private static (double, double) SolveEq(Int128 a, Int128 b, Int128 c)
    32. {
    33. var r = b * b - 4 * a * c;
    34. var d = Math.Sqrt((double)r);
    35. var x1 = (-(double)b - d) / (double)(2 * a);
    36. var x2 = (-(double)b + d) / (double)(2 * a);
    37. return (Math.Min(x1, x2), Math.Max(x1, x2));
    38. }
    39. private static string[] SourceStress() =>
    40. [
    41. "Time: 56 97 77 93 67 71 86 91",
    42. "Distance: 499 2210 1097 1440 603 753 1232 997",
    43. ];

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

    War leider die letzten Tage krank, habe jetzt mal bis Tag 5 alles nachgeholt.^^
    Tag 3
    Spoiler anzeigen

    C#-Quellcode

    1. using FileStream fs = File.OpenRead(@"C:\Dev\dotnet\AdventOfCode\2023\Day3\input.txt");
    2. using StreamReader sr = new(fs);
    3. int y = 0;
    4. List<V> schema = new();
    5. List<S> symbols = new();
    6. while (!sr.EndOfStream)
    7. {
    8. var lineSpan = sr.ReadLine().AsSpan();
    9. bool parsingNumber = false;
    10. V? v = null;
    11. for (int x = 0; x < lineSpan.Length; ++x)
    12. {
    13. if ((lineSpan[x] >= 48) && (lineSpan[x] <= 57))
    14. {
    15. if (!parsingNumber) v = new(x, y);
    16. v!.Value.Add(lineSpan[x]);
    17. parsingNumber = true;
    18. continue;
    19. }
    20. else
    21. {
    22. if (parsingNumber)
    23. {
    24. v!.EndIndex = x - 1;
    25. schema.Add(v);
    26. parsingNumber = false;
    27. }
    28. if (lineSpan[x] == '.') continue;
    29. symbols.Add(new(x, y, lineSpan[x]));
    30. }
    31. }
    32. if (parsingNumber)
    33. {
    34. v!.EndIndex = lineSpan.Length - 1;
    35. schema.Add(v);
    36. }
    37. ++y;
    38. }
    39. int total = 0;
    40. #region Part1
    41. foreach (var v in schema)
    42. {
    43. if (HasAdjacentSymbol(v.StartIndex, v.EndIndex, v.Y))
    44. total += int.Parse(string.Join("", v.Value));
    45. }
    46. #endregion
    47. #region Part2
    48. foreach (var s in symbols)
    49. {
    50. if (s.v != '*') continue;
    51. total += CalculateGearRatio(s.x, s.y);
    52. }
    53. #endregion
    54. System.Console.WriteLine(total);
    55. bool HasAdjacentSymbol(int x1, int x2, int y)
    56. {
    57. foreach (var s in symbols)
    58. {
    59. if (Math.Abs(s.y - y) > 1) continue;
    60. for (int i = x1; i <= x2; ++i)
    61. {
    62. if (Math.Abs(i - s.x) <= 1) return true;
    63. }
    64. }
    65. return false;
    66. }
    67. int CalculateGearRatio(int x, int y)
    68. {
    69. int idx = 0;
    70. int[] gearValues = new int[2];
    71. foreach (var s in schema)
    72. {
    73. if (Math.Abs(s.Y - y) > 1) continue;
    74. for (int i = s.StartIndex; i <= s.EndIndex; ++i)
    75. {
    76. if (Math.Abs(i - x) <= 1)
    77. {
    78. if (idx > 1) return 0;
    79. gearValues[idx] = int.Parse(string.Join("", s.Value));
    80. ++idx;
    81. break;
    82. }
    83. }
    84. }
    85. return gearValues[0] * gearValues[1];
    86. }
    87. class V
    88. {
    89. public V(int x, int y)
    90. {
    91. StartIndex = x;
    92. Y = y;
    93. }
    94. public int StartIndex { get; set; }
    95. public int EndIndex { get; set; }
    96. public int Y { get; set; }
    97. public List<char> Value { get; set; } = new();
    98. }
    99. record struct S(int x, int y, char v);


    Tag 4
    Part 1
    Spoiler anzeigen

    C#-Quellcode

    1. using FileStream fs = File.OpenRead(@"C:\Dev\dotnet\AdventOfCode\2023\Day4\input.txt");
    2. using StreamReader sr = new(fs);
    3. int total = 0;
    4. while (!sr.EndOfStream)
    5. {
    6. var lineSpan = sr.ReadLine().AsSpan();
    7. List<int> winningNumbers = new();
    8. List<int> cardsOnHand = new();
    9. // winning numbers
    10. for (int i = lineSpan.IndexOf(':') + 2; i < lineSpan.IndexOf('|') - 1; i += 3)
    11. {
    12. winningNumbers.Add(int.Parse(lineSpan[i..(i + 2)]));
    13. }
    14. int count = 0;
    15. for (int i = lineSpan.IndexOf('|') + 2; i < lineSpan.Length - 1; i += 3)
    16. {
    17. int c = int.Parse(lineSpan[i..(i + 2)]);
    18. if (winningNumbers.Contains(c))
    19. ++count;
    20. }
    21. if (count > 0)
    22. total += 1 << (count - 1);
    23. }
    24. System.Console.WriteLine(total);


    Part 2
    Spoiler anzeigen

    C#-Quellcode

    1. using FileStream fs = File.OpenRead(@"C:\Dev\dotnet\AdventOfCode\2023\Day4\input.txt");
    2. using StreamReader sr = new(fs);
    3. List<C> deckCounter = new();
    4. while (!sr.EndOfStream)
    5. {
    6. var lineSpan = sr.ReadLine().AsSpan();
    7. List<int> winningNumbers = new();
    8. List<int> cardsOnHand = new();
    9. for (int i = lineSpan.IndexOf(':') + 2; i < lineSpan.IndexOf('|') - 1; i += 3)
    10. {
    11. winningNumbers.Add(int.Parse(lineSpan[i..(i + 2)]));
    12. }
    13. int count = 0;
    14. for (int i = lineSpan.IndexOf('|') + 2; i < lineSpan.Length - 1; i += 3)
    15. {
    16. int c = int.Parse(lineSpan[i..(i + 2)]);
    17. if (winningNumbers.Contains(c))
    18. ++count;
    19. }
    20. deckCounter.Add(new(count, 1));
    21. }
    22. for (int i = 0; i < deckCounter.Count; ++i)
    23. {
    24. int copyCount = 0;
    25. do
    26. {
    27. ++copyCount;
    28. for (int j = 1; j <= deckCounter[i].Won; ++j)
    29. {
    30. deckCounter[i + j].Total++;
    31. deckCounter[i + j].Copy++;
    32. }
    33. }
    34. while (copyCount <= deckCounter[i].Copy);
    35. }
    36. System.Console.WriteLine(deckCounter.Sum(d => d.Total));
    37. class C
    38. {
    39. public int Won { get; set; }
    40. public int Copy { get; set; }
    41. public int Total { get; set; }
    42. public C(int won, int total)
    43. {
    44. Won = won;
    45. Total = total;
    46. }
    47. }


    Tag 5
    Part 1
    Spoiler anzeigen

    C#-Quellcode

    1. using FileStream fs = File.OpenRead(@"C:\Dev\dotnet\AdventOfCode\2023\Day5\input.txt");
    2. using StreamReader sr = new(fs);
    3. List<long> seeds = new();
    4. Dictionary<string, List<long[]>> maps = new();
    5. List<string> types = new();
    6. string type = string.Empty;
    7. while (!sr.EndOfStream)
    8. {
    9. var lineSpan = sr.ReadLine().AsSpan();
    10. if (lineSpan.Length == 0) continue;
    11. int colonIndex = lineSpan.IndexOf(':');
    12. if (colonIndex > -1)
    13. {
    14. type = lineSpan[..colonIndex].ToString();
    15. if (type == "seeds")
    16. {
    17. ExtractSeeds(lineSpan[(colonIndex + 2)..]);
    18. }
    19. else
    20. types.Add(type);
    21. }
    22. else
    23. {
    24. SplitMap(type, lineSpan);
    25. }
    26. }
    27. long minLocation = 0;
    28. int typeIdx = 0;
    29. foreach (long seed in seeds)
    30. {
    31. typeIdx = 0;
    32. long currentLocation = GetLocation(seed);
    33. if ((currentLocation < minLocation) || (minLocation == 0))
    34. minLocation = currentLocation;
    35. }
    36. System.Console.WriteLine(minLocation);
    37. long GetLocation(long seed)
    38. {
    39. long searchValue = seed;
    40. while (typeIdx < types.Count)
    41. {
    42. searchValue = GetMapValue(types[typeIdx], searchValue);
    43. ++typeIdx;
    44. }
    45. return searchValue;
    46. }
    47. long GetMapValue(string type, long searchValue)
    48. {
    49. var v = maps[type];
    50. foreach (long[] x in v)
    51. {
    52. if (x[1] > searchValue || (x[1] + (x[2] - 1)) < searchValue)
    53. {
    54. continue;
    55. }
    56. return x[0] + searchValue - x[1];
    57. }
    58. return searchValue;
    59. }
    60. void ExtractSeeds(ReadOnlySpan<char> line)
    61. {
    62. Range[] ranges = new Range[line.Count(' ') + 1];
    63. if (line.Split(ranges, ' ') <= 0) return;
    64. foreach (Range r in ranges)
    65. {
    66. seeds.Add(long.Parse(line[r]));
    67. }
    68. }
    69. void SplitMap(string type, ReadOnlySpan<char> line)
    70. {
    71. Range[] ranges = new Range[3];
    72. line.Split(ranges, ' ');
    73. long[] values = new long[3];
    74. for (int i = 0; i < ranges.Length; ++i)
    75. {
    76. values[i] = long.Parse(line[ranges[i]]);
    77. }
    78. if (!maps.ContainsKey(type))
    79. maps.Add(type, new() { values });
    80. else
    81. maps[type].Add(values);
    82. }


    Part 2
    Spoiler anzeigen

    Habe ich etwas parallelisiert - lief dann in 9m 51.208s - Vielleicht gehts noch schneller, oder hübscher. Kp.

    C#-Quellcode

    1. using FileStream fs = File.OpenRead(@"C:\Dev\dotnet\AdventOfCode\2023\Day5\input.txt");
    2. using StreamReader sr = new(fs);
    3. List<long> seeds = new();
    4. Dictionary<string, List<long[]>> maps = new();
    5. List<string> types = new();
    6. string type = string.Empty;
    7. while (!sr.EndOfStream)
    8. {
    9. var lineSpan = sr.ReadLine().AsSpan();
    10. if (lineSpan.Length == 0) continue;
    11. int colonIndex = lineSpan.IndexOf(':');
    12. if (colonIndex > -1)
    13. {
    14. type = lineSpan[..colonIndex].ToString();
    15. if (type == "seeds")
    16. {
    17. ExtractSeeds(lineSpan[(colonIndex + 2)..]);
    18. }
    19. else
    20. types.Add(type);
    21. }
    22. else
    23. {
    24. SplitMap(type, lineSpan);
    25. }
    26. }
    27. long minLocation = 0;
    28. object o = new();
    29. for (int i = 0; i < seeds.Count - 1; i += 2)
    30. {
    31. long dest = seeds[i] + seeds[i + 1] - 1;
    32. Parallel.For(seeds[i], dest, new ParallelOptions { MaxDegreeOfParallelism = 10 }, j =>
    33. {
    34. long currentLocation = GetLocation(j);
    35. lock (o)
    36. {
    37. if ((currentLocation < minLocation) || (minLocation == 0))
    38. minLocation = currentLocation;
    39. }
    40. });
    41. }
    42. System.Console.WriteLine(minLocation);
    43. long GetLocation(long seed)
    44. {
    45. long searchValue = seed;
    46. int typeIdx = 0;
    47. while (typeIdx < types.Count)
    48. {
    49. searchValue = GetMapValue(types[typeIdx], searchValue);
    50. ++typeIdx;
    51. }
    52. return searchValue;
    53. }

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

    VaporiZed schrieb:

    Der Tag war einfach


    Ja sehe ich auch so:

    Tag06
    Beides in einem:
    Spoiler anzeigen

    C#-Quellcode

    1. ​using System.Text.RegularExpressions;
    2. namespace Tag06
    3. {
    4. internal class Program
    5. {
    6. static void Main(string[] args)
    7. {
    8. string[] exampleFile = File.ReadAllLines("Example.txt");
    9. string[] inputFile = File.ReadAllLines("Input.txt");
    10. Console.WriteLine($"Example: {Calculate(exampleFile)}");
    11. Console.WriteLine($"Example2: {Calculate(exampleFile, true)}");
    12. Console.WriteLine($"Input Part 1: {Calculate(inputFile)}");
    13. Console.WriteLine($"Input Part 2: {Calculate(inputFile,true)}");
    14. }
    15. static long Calculate(string[] lines, bool p2 = false)
    16. {
    17. long sum = 1;
    18. long[] times = null;
    19. long[] distances = null;
    20. if (!p2)
    21. {
    22. times = Regex.Matches(lines[0].Split(':')[1], @"(\d)+").Select(x => long.Parse(x.Value)).ToArray();
    23. distances = Regex.Matches(lines[1].Split(':')[1], @"(\d)+").Select(x => long.Parse(x.Value)).ToArray();
    24. } else
    25. {
    26. times = Regex.Matches(lines[0].Split(':')[1].Replace(" ", ""), @"(\d)+").Select(x => long.Parse(x.Value)).ToArray();
    27. distances = Regex.Matches(lines[1].Split(':')[1].Replace(" ", ""), @"(\d)+").Select(x => long.Parse(x.Value)).ToArray();
    28. }
    29. for (long i = 0; i < times.Length; i++)
    30. {
    31. int totalWins = 0;
    32. long time = times[i];
    33. long distance = distances[i];
    34. for (long t = 1; t <= time; t++)
    35. {
    36. long traveled = t * (time - t);
    37. if( traveled > distance )
    38. {
    39. totalWins++;
    40. }
    41. }
    42. sum *= totalWins;
    43. }
    44. return sum;
    45. }
    46. }
    47. }
    Grüße , xChRoNiKx

    Nützliche Links:
    Visual Studio Empfohlene Einstellungen | Try-Catch heißes Eisen
    Und dann haben wir noch Tag 6

    Spoiler anzeigen

    C#-Quellcode

    1. ​using System.Text.RegularExpressions;
    2. using FileStream fs = File.OpenRead(@"D:\Dev\net\AdventOfCode\2023\Day6\input.txt");
    3. using StreamReader sr = new(fs);
    4. int total = 1;
    5. const string pattern = "\\d+";
    6. Regex r = new(pattern, RegexOptions.Compiled);
    7. List<long> times = new();
    8. List<long> distances = new();
    9. int line = 0;
    10. while (!sr.EndOfStream)
    11. {
    12. var lineSpan = sr.ReadLine().AsSpan();
    13. var values = lineSpan[(lineSpan.IndexOf(':') + 1)..].TrimStart();
    14. if (r.IsMatch(lineSpan))
    15. {
    16. int len = 0;
    17. foreach (var m in r.EnumerateMatches(lineSpan))
    18. {
    19. len += m.Length;
    20. #region Part1
    21. int v = int.Parse(lineSpan[m.Index..(m.Index + m.Length)]);
    22. if (line == 0)
    23. times.Add(v);
    24. else
    25. distances.Add(v);
    26. #endregion
    27. }
    28. #region Part2
    29. long v = long.Parse(string.Create(len, values.ToString(), (s, value) =>
    30. {
    31. var p = value.AsSpan();
    32. int idx = 0;
    33. for (int i = 0; i < p.Length; ++i)
    34. {
    35. if (p[i] == ' ') continue;
    36. s[idx++] = p[i];
    37. }
    38. }));
    39. if (line == 0)
    40. times.Add(v);
    41. else
    42. distances.Add(v);
    43. #endregion
    44. }
    45. ++line;
    46. }
    47. for (int i = 0; i < times.Count; ++i)
    48. {
    49. int p = 0;
    50. for (int j = 1; j < times[i] - 1; j++)
    51. {
    52. if ((j * (times[i] - j)) > distances[i])
    53. p++;
    54. else if (p > 0)
    55. break;
    56. }
    57. total *= p;
    58. }
    59. System.Console.WriteLine(total);
    Wer sich interessiert, habe Tag 5 Part 2 nun angeschaut: Es war das typische "LINQ wird erst ausgeführt, wenns gebraucht wird". Habe also .ToArray vorgeklatscht, wo ging und dadurch erstmal Faktor 7-8 rausgekriegt.
    Das läuft sauber in etwas über 1 Minute.
    Dann habe ich aber die Suche des Minimums manipuliert, im Prinzip das händische Herantasten simuliert. Das liefert das Ergebnis sofort (~50 ms), aber dadurch eine eher unschöne Lösung.

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