Advent of Code 2023
Sie verwenden einen veralteten Browser (%browser%) mit Sicherheitsschwachstellen und können nicht alle Funktionen dieser Webseite nutzen.
Hier erfahren Sie, wie einfach Sie Ihren Browser aktualisieren können.
Hier erfahren Sie, wie einfach Sie Ihren Browser aktualisieren können.
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“ ()
-
Also hier für AoC nicht. Für die Projekte bei der Arbeit ja.
-
@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.
nogoodcodewars.com Rank: 4 kyuDieser Beitrag wurde bereits 1 mal editiert, zuletzt von „nogood“ ()
-
Part 1 C#-Quellcode
- private static void Part01()
- {
- var source = Source();
- var maps = ToMaps(source.Skip(1));
- var seeds = source[0][1].Split(" ",
- StringSplitOptions.RemoveEmptyEntries).Select(long.Parse);
- var result = long.MaxValue;
- foreach (var seed in seeds)
- {
- var value = seed;
- foreach (var map in maps)
- foreach (var (src, dest, cnt) in map)
- if (src <= value && value < src + cnt)
- { value = dest + value - src; break; }
- result = Math.Min(result, value);
- }
- Console.WriteLine($"{nameof(Part01)}: lowest location: {result}");
- }
Part 2 C#-Quellcode
- private static void Part02()
- {
- var src = SourceText();
- var idx = src[0].IndexOf(':') + 1;
- var seeds = src[0].Substring(idx).Split(" ",
- StringSplitOptions.RemoveEmptyEntries).Select(long.Parse)
- .Chunk(2);
- List<(long start, long to)> tmp;
- var result = new List<(long start, long to)>();
- var changed = new List<(long start, long to)>();
- seeds.ForEach(x => result.Add((x[0],x[1])));
- foreach (var line in src.Skip(1))
- {
- tmp = [];
- if (line == "" || line.Contains(':'))
- {
- foreach (var (start, to) in changed)
- result.Add((start, to));
- changed.Clear();
- continue;
- }
- var map = line.Split().Where(s=> !string.IsNullOrEmpty(s)).Select(long.Parse).ToList();
- foreach (var (start, to) in result)
- {
- var rstart = map[1];
- var rto = map[1] + map[2] - 1;
- var offset = map[0] - map[1];
- var sstart = start;
- var sto = start + to - 1;
- long crstart = 0, crto = 0;
- switch (true)
- {
- case var b when rstart < sstart && rto >= sstart & rto <= sto:
- crstart = sstart;
- crto = rto;
- changed.Add((crstart + offset, crto - crstart + 1));
- if (crto + 1 <= sto) tmp.Add((crto + 1, sto - (crto + 1) + 1));
- break;
- case var b when rstart >= sstart && rto <= sto:
- crstart = rstart;
- crto = rto;
- changed.Add((crstart + offset, crto - crstart + 1));
- if (crto + 1 <= sto) tmp.Add((crto + 1, sto - (crto + 1) + 1));
- if (crstart - 1 >= sstart) tmp.Add((sstart, crstart - 1 - sstart + 1));
- break;
- case var b when rstart >= sstart && rstart <= sto && rto > sto:
- crstart = rstart;
- crto = sto;
- changed.Add((crstart + offset, crto - crstart + 1));
- if (crstart - 1 >= sstart) tmp.Add((sstart, crstart - 1 - sstart + 1));
- break;
- case var b when rstart < sstart && rto > sto:
- crstart = sstart;
- crto = sto;
- changed.Add((crstart + offset, crto - crstart + 1));
- break;
- default:
- tmp.Add((sstart, sto - sstart + 1));
- break;
- }
- }
- result = tmp;
- }
- changed.ForEach(x => result.Add((x.start, x.to)));
- Console.WriteLine($"{nameof(Part02)}: {result.Min(x => x.start)}");
- }
Source C#-Quellcode
- private static string[][] Source()
- {
- var result = new List<string[]>();
- var src = SourceText().Where(line => line != "").ToArray();
- var first = src.First().Split(": ",StringSplitOptions.RemoveEmptyEntries);
- first[0] += ":";
- result.Add(first);
- for (var i = 1; i < src.Length; i++)
- {
- var tmp = new List<string>{src[i]};
- for (var j = ++i; j < src.Length; j++, i++)
- {
- if (src[j].Contains('-'))
- { i--;break; }
- else tmp.Add(src[j]);
- }
- result.Add([.. tmp]);
- }
- return [.. result];
- }
- private static string[] SourceText() =>
- [
- "seeds: 79 14 55 13",
- "",
- "seed-to-soil map:",
- "50 98 2",
- "52 50 48",
- "",
- "soil-to-fertilizer map:",
- "0 15 37",
- "37 52 2",
- "39 0 15",
- "",
- "fertilizer-to-water map:",
- "49 53 8",
- "0 11 42",
- "42 0 7",
- "57 7 4",
- "",
- "water-to-light map:",
- "88 18 7",
- "18 25 70",
- "",
- "light-to-temperature map:",
- "45 77 23",
- "81 45 19",
- "68 64 13",
- "",
- "temperature-to-humidity map:",
- "0 69 1",
- "1 0 69",
- "",
- "humidity-to-location map:",
- "60 56 37",
- "56 93 4",
- ];
Hier noch eine Rekursive Methode
Part 2 Rekursiv C#-Quellcode
- private static void Part02_Recursiv()
- {
- var src = Source();
- var maps = ToMaps(src.Skip(1));
- src[0] = [string.Join(" ", src[0])];
- (long from,long to)[] seeds = src[0][0].Split(" ").Skip(1).Select(long.Parse).Chunk(2)
- .Select(pair => (pair[0],pair[0] + pair[1] - 1) ).ToArray();
- static bool TryToComparer((long from, long to) this_, (long from, long to) other,
- out (long from, long to) compare)
- {
- compare = new(Math.Max(this_.from, other.from), Math.Min(this_.to, other.to));
- return compare.to >= compare.from;
- }
- static (long from, long to) FromCount(long start, long count) =>
- new(start, start + count - 1);
- static (long from, long to) Offset((long from, long to)this_, long distance) =>
- new(this_.from + distance,this_. to + distance);
- long lookup_bfs((long from, long to) range, int idx)
- {
- if (idx >= maps!.Length) return range.from;
- var compareleft = new List<(long from, long to)>();
- var compareright = new List<(long from, long to)>();
- foreach (var (src, dest, cnt) in maps[idx])
- {
- var tmp = FromCount(src, cnt);
- if (TryToComparer(range, tmp, out var compare))
- {
- compareleft.Add(compare);
- compareright.Add(Offset(compare, dest - src));
- }
- }
- var leftmin = compareleft.OrderBy(_ => _.from)
- .Prepend((range.from - 1, range.from - 1))
- .Append((range.to + 1, range.to + 1))
- .Pairwise((r1, r2) => (r1.Item2 + 1, r2.Item1 - 1))
- .Where(_ => _.Item2 >= _.Item1);
- return leftmin.Concat(compareright).Min(x => lookup_bfs(x, idx + 1));
- }
- var result = seeds!.Select(_ => lookup_bfs(_, 0)).Min();
- Console.WriteLine($"{nameof(Part02_Recursiv)}: {result}");
- }
- private static (long src, long dest, long cnt)[][] ToMaps(IEnumerable<string[]> src)
- {
- var result = new List<(long src, long dest, long cnt)[]>();
- foreach (var datas in src)
- {
- var tmp = new List<(long src, long dest, long cnt)>();
- foreach (var strset in datas.Skip(1))
- {
- if (strset == string.Empty) continue;
- var lset = strset.Split(' ', StringSplitOptions.RemoveEmptyEntries).Select(long.Parse).ToArray();
- tmp.Add((lset[1], lset[0], lset[2]));
- }
- result.Add([.. tmp]);
- }
- return [.. result];
- }
Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „exc-jdbi“ ()
-
Ich weiß nicht mal was tdd ist.^^
D5 Part 1 VB.NET-Quellcode
- Private maps As IEnumerable(Of IEnumerable(Of mapping))
- Sub Main()
- Dim input = IO.File.ReadAllText(FilePathOfData).Split(vbCrLf & vbCrLf)
- Dim seeds = input(0).Substring(7).Split(" "c).Select(Function(s) CLng(s))
- maps = input.Skip(1).Select(Function(s) s.Split(vbCrLf).Skip(1).Select(Function(l) New mapping(l.Split(" "c))))
- Dim result = seeds.Min(Function(s)
- Dim value = s
- For i = 0 To maps.Count - 1
- value = MapToMap(i, value)
- Next
- Return value
- End Function)
- Stop
- End Sub
- Private Function MapToMap(mapidx As Integer, input As Long) As Long
- Dim map = maps(mapidx).FirstOrDefault(Function(m) input >= m.src AndAlso input <= m.src + m.len)
- If map Is Nothing Then Return Long.MaxValue
- Return input - map.src + map.dest
- End Function
- Friend Class mapping
- Property dest As Long
- Property src As Long
- Property len As Long
- Sub New(from As String())
- _dest = CLng(from(0))
- _src = CLng(from(1))
- _len = CLng(from(2))
- End Sub
- 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 7malFirstOrDefault
so lange dauert
VB.NET-Quellcode
- Private maps As mapping()()
- Sub Main()
- Dim input = IO.File.ReadAllText(FilePathOfData).Split(vbCrLf & vbCrLf)
- Dim seeds = input(0).Substring(7).Split(" "c).Select(AddressOf Long.Parse)
- Dim rgx As New Regex("(?<start>\d+) (?<length>\d+)")
- Dim seedRanges = rgx.Matches(input(0)).Select(Function(m) New With {.start = CLng(m.Groups("start").Value), .length = CLng(m.Groups("length").Value)}).ToArray
- maps = input.Skip(1).Select(Function(s) s.Split(vbCrLf).Skip(1).Select(Function(l) New mapping(l.Split(" "c))).ToArray).ToArray
- Dim resultPart1 = seeds.Min(Function(s)
- Dim value = s
- For i = 0 To maps.Count - 1
- value = MapToMap(i, value)
- Next
- Return value
- End Function)
- Dim resultPart2 As Long
- Dim seed As Long
- Dim k As Integer = 6 'Gern auch höher, ggf. Anzahl der Stellen der max möglichen Location
- While k >= 0
- While Not seedRanges.Any(Function(r) seed >= r.start AndAlso seed < r.start + r.length)
- resultPart2 += 10 ^ k
- seed = resultPart2
- For i = maps.Length - 1 To 0 Step -1
- seed = MapToMapReverse(i, seed)
- Next
- End While
- resultPart2 -= 10 ^ k
- k -= 1
- seed = resultPart2
- End While
- resultPart2 += 1
- End Sub
- Private Function MapToMap(mapidx As Integer, input As Long) As Long
- Dim map = maps(mapidx).FirstOrDefault(Function(m) input >= m.src AndAlso input <= m.src + m.len)
- If map Is Nothing Then Return input
- Return input + map.dest - map.src
- End Function
- Private Function MapToMapReverse(mapidx As Integer, input As Long) As Long
- Dim map = maps(mapidx).FirstOrDefault(Function(m) input >= m.dest AndAlso input <= m.dest + m.len)
- If map Is Nothing Then Return input
- Return input + map.src - map.dest
- End Function
- Friend Class mapping
- Property dest As Long
- Property src As Long
- Property len As Long
- Sub New(from As String())
- _dest = CLng(from(0))
- _src = CLng(from(1))
- _len = CLng(from(2))
- End Sub
- End Class
Dieser Beitrag wurde bereits 19 mal editiert, zuletzt von „Haudruferzappeltnoch“ ()
-
@Haudruferzappeltnoch: Test Driven Development
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
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
Spoiler anzeigen VB.NET-Quellcode
- Friend Class FrmMain
- Private Async Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
- Dim Values = Await Threading.Tasks.Task.Run(Function() New ValueCalculatorForDay5().GetValuesFor("input2.txt"))
- MessageBox.Show(Values.Part1Value.ToString)
- MessageBox.Show(Values.Part2Value.ToString)
- End Sub
- End Class
- Friend Class ValueCalculatorForDay5
- Private ReadOnly TitleParameterTypePairs As New Dictionary(Of String, ParameterType) From {{"seed-to-soil map:", ParameterType.SeedToSoil},
- {"soil-to-fertilizer map:", ParameterType.SoilToFertilizer},
- {"fertilizer-to-water map:", ParameterType.FertilizerToWater},
- {"water-to-light map:", ParameterType.WaterToLight},
- {"light-to-temperature map:", ParameterType.LightToTemperature},
- {"temperature-to-humidity map:", ParameterType.TemperatureToHumidity},
- {"humidity-to-location map:", ParameterType.HumidityToLocation}}
- Private ReadOnly ParameterTables As New List(Of ParameterTable)
- Private MinimumLocationIDs As New List(Of Long)
- Private MinimumEnhancedLocationIDs As New List(Of Long)
- Function GetValuesFor(FilePath As String) As (Part1Value As Long, Part2Value As Long)
- InitializeIDLists()
- Dim RawDataLines = GetRawDataFrom(FilePath)
- ParseRawData(RawDataLines)
- Dim SeedData = GetSeedDataFrom(GetSeedValuesAsTexts(RawDataLines(0)))
- Threading.Tasks.Parallel.For(0, SeedData.Count - 1, Sub(x) ConvertSeedIDsToLocationIDs(SeedData(x), x))
- Return (MinimumLocationIDs.Min, MinimumEnhancedLocationIDs.Min)
- End Function
- Private Sub InitializeIDLists()
- For i = 1 To 10
- MinimumLocationIDs.Add(Long.MaxValue)
- MinimumEnhancedLocationIDs.Add(Long.MaxValue)
- Next
- End Sub
- Private Function GetSeedValuesAsTexts(RawDataLine As String) As IEnumerable(Of String)
- Return RawDataLine.Split({":"c, " "c}, StringSplitOptions.RemoveEmptyEntries).Skip(1)
- End Function
- Private Function GetSeedDataFrom(RawDataValues As IEnumerable(Of String)) As IEnumerable(Of (Value1 As Long, Value2 As Long))
- Dim List As New List(Of (Value1 As Long, Value2 As Long))
- For i = 0 To RawDataValues.Count - 1 Step 2
- List.Add((Long.Parse(RawDataValues(i)), Long.Parse(RawDataValues(i + 1))))
- Next
- Return List
- End Function
- Private Function GetRawDataFrom(FilePath As String) As IEnumerable(Of String)
- Return IO.File.ReadAllLines(FilePath)
- End Function
- Private Sub ParseRawData(RawDataLines As IEnumerable(Of String))
- ParseBlocks(GetDataBlocksFrom(RawDataLines.Skip(2)))
- End Sub
- Private Function GetDataBlocksFrom(RawDataLines As IEnumerable(Of String)) As IEnumerable(Of IEnumerable(Of String))
- Dim Blocks As New List(Of IEnumerable(Of String))
- Dim BlockData As New List(Of String)
- For Each RawDataLine In RawDataLines
- If Not String.IsNullOrEmpty(RawDataLine) Then
- BlockData.Add(RawDataLine)
- Else
- Blocks.Add(BlockData)
- BlockData = New List(Of String)
- End If
- Next
- Blocks.Add(BlockData)
- Return Blocks
- End Function
- Private Sub ParseBlocks(Blocks As IEnumerable(Of IEnumerable(Of String)))
- Blocks.ToList.ForEach(Sub(x) ParseBlock(x))
- End Sub
- Private Sub ParseBlock(BlockData As IEnumerable(Of String))
- Dim NewParameterTable As New ParameterTable With {.ParameterType = TitleParameterTypePairs.Single(Function(x) x.Key = BlockData(0)).Value}
- For Each BlockLine In BlockData.Skip(1)
- Dim RawData = BlockLine.Split
- Dim SourceStartValue = Long.Parse(RawData(1))
- Dim DestinationStartValue = Long.Parse(RawData(0))
- Dim Range = Integer.Parse(RawData(2))
- NewParameterTable.AdditionalMappings.Add(New AdditionalMapping(SourceStartValue, DestinationStartValue, Range))
- Next
- ParameterTables.Add(NewParameterTable)
- End Sub
- Private Sub ConvertSeedIDsToLocationIDs(Data As (Value1 As Long, Value2 As Long), Index As Integer)
- Call {Data.Value1, Data.Value2}.ToList.ForEach(Sub(x) MinimumLocationIDs(Index) = Math.Min(GetLocationIdFrom(x), MinimumLocationIDs(Index)))
- ConvertEnhancedSeedIdToLocationId(Data, Index)
- End Sub
- Private Function GetLocationIdFrom(SeedID As Long) As Long
- Dim CurrentID = SeedID
- For Each ParameterTable In ParameterTables
- CurrentID = GetNewIdFrom(ParameterTable, CurrentID)
- Next
- Return CurrentID
- End Function
- Private Sub ConvertEnhancedSeedIdToLocationId(Data As (Value1 As Long, Value2 As Long), Index As Integer)
- For i = Data.Value1 To Data.Value1 + Data.Value2 - 1
- MinimumEnhancedLocationIDs(Index) = Math.Min(GetLocationIdFrom(i), MinimumEnhancedLocationIDs(Index))
- Next
- End Sub
- Private Function GetNewIdFrom(ParameterTable As ParameterTable, ID As Long) As Long
- Dim FittingMapping = ParameterTable.AdditionalMappings.FirstOrDefault(Function(x) x.Contains(ID))
- If FittingMapping Is Nothing Then Return ID
- Return FittingMapping.GetConvertedValueOf(ID)
- End Function
- End Class
- Friend Class ParameterTable
- Property ParameterType As ParameterType
- Property AdditionalMappings As New List(Of AdditionalMapping)
- End Class
- Friend Class AdditionalMapping
- Property SourceStartValue As Long
- Property DestinationStartValue As Long
- Property Range As Integer
- Sub New(SourceStartValue As Long, DestinationStartValue As Long, Range As Integer)
- Me.SourceStartValue = SourceStartValue
- Me.DestinationStartValue = DestinationStartValue
- Me.Range = Range
- End Sub
- Function Contains(ID As Long) As Boolean
- Return ID >= SourceStartValue AndAlso ID <= SourceStartValue + Range - 1
- End Function
- Function GetConvertedValueOf(ID As Long) As Long
- Dim Offset = DestinationStartValue - SourceStartValue
- Return ID + Offset
- End Function
- End Class
- Friend Enum ParameterType
- SeedToSoil
- SoilToFertilizer
- FertilizerToWater
- WaterToLight
- LightToTemperature
- TemperatureToHumidity
- HumidityToLocation
- End Enum
@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 -
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
- using System.Text.RegularExpressions;
- namespace Tag05
- {
- internal class Program
- {
- static void Main(string[] args)
- {
- string[] inputFile = File.ReadAllLines("Input.txt");
- Garden gardenP1 = new Garden();
- gardenP1.Convert(inputFile);
- gardenP1.ProcessSeedsP1();
- Console.WriteLine($"Lowest Location P1: {gardenP1.seeds.Min(x => x.Location)}");
- Garden gardenP2 = new Garden();
- gardenP2.Convert(inputFile,true);
- Console.WriteLine($"Lowest Location P1: {gardenP2.ProcessSeedsP2()}");
- }
- }
- class Garden
- {
- public List<Seed> seeds = new List<Seed>();
- List<Map> maps = new List<Map>();
- Dictionary<long, long> SeedToSoil = new Dictionary<long, long>();
- Dictionary<long, long> SoilToFertilizer = new Dictionary<long, long>();
- Dictionary<long, long> FertilizerToWater = new Dictionary<long, long>();
- Dictionary<long, long> WaterToLight = new Dictionary<long, long>();
- Dictionary<long, long> LightToTemperature = new Dictionary<long, long>();
- Dictionary<long, long> TemperatureToHumidity = new Dictionary<long, long>();
- Dictionary<long, long> HumidityToLocation = new Dictionary<long, long>();
- public Garden()
- {
- maps.Add(new Map() { OrderNumber = 0, Name = "seed-to-soil", Mapping = SeedToSoil });
- maps.Add(new Map() { OrderNumber = 1, Name = "soil-to-fertilizer", Mapping = SoilToFertilizer });
- maps.Add(new Map() { OrderNumber = 2, Name = "fertilizer-to-water", Mapping = FertilizerToWater });
- maps.Add(new Map() { OrderNumber = 3, Name = "water-to-light", Mapping = WaterToLight });
- maps.Add(new Map() { OrderNumber = 4, Name = "light-to-temperature", Mapping = LightToTemperature });
- maps.Add(new Map() { OrderNumber = 5, Name = "temperature-to-humidity", Mapping = TemperatureToHumidity });
- maps.Add(new Map() { OrderNumber = 6, Name = "humidity-to-location", Mapping = HumidityToLocation });
- }
- public void Convert(string[] lines, bool part2 = false)
- {
- string processingType = "seeds";
- foreach (string line in lines)
- {
- if (String.IsNullOrEmpty(line)) continue;
- if (line.Contains("map:"))
- {
- processingType = line.Replace(" map:", "");
- continue;
- }
- if (processingType == "seeds")
- {
- if (line.StartsWith("seeds:"))
- {
- if (part2)
- {
- if(!File.Exists(Path.Combine(Environment.CurrentDirectory, "part2.txt")))
- {
- var matches = Regex.Matches(line.Replace("seeds:", ""), "(\\d+) (\\d+)");
- using StreamWriter sw = new StreamWriter(Path.Combine(Environment.CurrentDirectory, "part2.txt"));
- foreach (Match match in matches)
- {
- string[] numbers = match.Value.Split(' ');
- Int64 num1 = Int64.Parse(numbers[0]);
- Int64 num2 = Int64.Parse(numbers[1]);
- Console.WriteLine($"{num1} - {num1 + num2}");
- for (Int64 i = num1; i <= num1 + num2; i++)
- {
- sw.WriteLine(i.ToString());
- }
- }
- }
- }
- else
- {
- seeds.AddRange(line.Replace("seeds: ", "").Split(' ').Select(x => (new Seed() { SeedNumber = Int64.Parse(x) })).ToArray());
- }
- }
- continue;
- }
- Map currentMap = maps.FirstOrDefault(x => x.Name == processingType);
- if (currentMap != null)
- {
- string[] numbers = line.Split(' ');
- long destinationStart = Int64.Parse(numbers[0].ToString());
- long sourceStart = Int64.Parse(numbers[1].ToString());
- long length = Int64.Parse(numbers[2].ToString());
- Mapping mapping = new Mapping();
- mapping.SourceStart = sourceStart;
- mapping.DestinationStart = destinationStart;
- mapping.Length = length;
- currentMap.Mapping2.Add(mapping);
- }
- }
- }
- public void ProcessSeedsP1()
- {
- foreach (Map map in maps.OrderBy(x => x.OrderNumber))
- {
- foreach (Seed seed in seeds)
- {
- switch (map.Name)
- {
- case "seed-to-soil":
- seed.Soil = GetKeyFromDict(seed.SeedNumber, map.Mapping2);
- break;
- case "soil-to-fertilizer":
- seed.Fertilizer = GetKeyFromDict(seed.Soil, map.Mapping2);
- break;
- case "fertilizer-to-water":
- seed.Water = GetKeyFromDict(seed.Fertilizer, map.Mapping2);
- break;
- case "water-to-light":
- seed.Ligth = GetKeyFromDict(seed.Water, map.Mapping2);
- break;
- case "light-to-temperature":
- seed.Temperature = GetKeyFromDict(seed.Ligth, map.Mapping2);
- break;
- case "temperature-to-humidity":
- seed.Humidity = GetKeyFromDict(seed.Temperature, map.Mapping2);
- break;
- case "humidity-to-location":
- seed.Location = GetKeyFromDict(seed.Humidity, map.Mapping2);
- break;
- default:
- break;
- }
- }
- }
- }
- public Int64 ProcessSeedsP2()
- {
- Int64 smallesLocation = Int64.MaxValue;
- Parallel.ForEach(File.ReadLines(Path.Combine(Environment.CurrentDirectory, "part2.txt")), seedLine =>
- {
- Seed seed = new Seed() { SeedNumber = Int64.Parse(seedLine) };
- foreach (Map map in maps.OrderBy(x => x.OrderNumber))
- {
- switch (map.Name)
- {
- case "seed-to-soil":
- seed.Soil = GetKeyFromDict(seed.SeedNumber, map.Mapping2);
- break;
- case "soil-to-fertilizer":
- seed.Fertilizer = GetKeyFromDict(seed.Soil, map.Mapping2);
- break;
- case "fertilizer-to-water":
- seed.Water = GetKeyFromDict(seed.Fertilizer, map.Mapping2);
- break;
- case "water-to-light":
- seed.Ligth = GetKeyFromDict(seed.Water, map.Mapping2);
- break;
- case "light-to-temperature":
- seed.Temperature = GetKeyFromDict(seed.Ligth, map.Mapping2);
- break;
- case "temperature-to-humidity":
- seed.Humidity = GetKeyFromDict(seed.Temperature, map.Mapping2);
- break;
- case "humidity-to-location":
- seed.Location = GetKeyFromDict(seed.Humidity, map.Mapping2);
- if (seed.Location < smallesLocation)
- {
- smallesLocation = seed.Location;
- }
- break;
- default:
- break;
- }
- }
- });
- return smallesLocation;
- }
- private long GetKeyFromDict(long searchValue, HashSet<Mapping> dict)
- {
- Mapping mapping = dict.Where(x => searchValue >= x.SourceStart).Where(x => searchValue <= x.SourceStart + x.Length).FirstOrDefault();
- if (mapping == null) return searchValue;
- long length = searchValue - mapping.SourceStart;
- return mapping.DestinationStart + length;
- }
- }
- class Map
- {
- public int OrderNumber { get; set; }
- public string Name { get; set; }
- public Dictionary<long, long> Mapping { get; set; } = new Dictionary<long, long>();
- public HashSet<Mapping> Mapping2 { get; set; } = new HashSet<Mapping>();
- }
- class Mapping
- {
- public long SourceStart { get; set; }
- public long DestinationStart { get; set; }
- public long Length { get; set; }
- }
- class Seed
- {
- public long SeedNumber { get; set; }
- public long Soil { get; set; } = 0;
- public long Fertilizer { get; set; } = 0;
- public long Water { get; set; } = 0;
- public long Ligth { get; set; } = 0;
- public long Temperature { get; set; } = 0;
- public long Humidity { get; set; } = 0;
- public long Location { get; set; } = 0;
- }
- }
-
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 kamDieser 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
- Sub Main()
- Dim input = IO.File.ReadAllLines(FilePathOfData)
- Dim times = input(0).Substring(5).Split(" "c, StringSplitOptions.RemoveEmptyEntries).Select(Function(s) Integer.Parse(s))
- Dim distances = input(1).Substring(9).Split(" "c, StringSplitOptions.RemoveEmptyEntries).Select(Function(s) Integer.Parse(s))
- Dim result = times.Zip(distances, AddressOf FindIntSpaceBetweenZeroes).Aggregate(Function(x, y) x * y)
- End Sub
- Private Function FindIntSpaceBetweenZeroes(x As Long, y As Long) As Integer
- Return Math.Floor(x / 2 + Math.Sqrt(x ^ 2 / 4 - y)) - Math.Ceiling(x / 2 - Math.Sqrt(x ^ 2 / 4 - y)) + 1
- End Function
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
- Friend Class FrmMain
- Private Async Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
- Dim Values = Await Threading.Tasks.Task.Run(Function() New ValueCalculatorForDay6().GetValuesFor("input2.txt"))
- MessageBox.Show(Values.Part1Value.ToString)
- MessageBox.Show(Values.Part2Value.ToString)
- End Sub
- End Class
- Friend Class ValueCalculatorForDay6
- Private ReadOnly Races As New List(Of Race)
- Private ReadOnly AcceleratorButtonPressDurationsToWin As New List(Of IEnumerable(Of Long))
- Function GetValuesFor(FilePath As String) As (Part1Value As Long, Part2Value As Long)
- Dim RawDataLines = GetRawDataFrom(FilePath)
- ParseRawData(RawDataLines)
- RetrieveAcceleratorButtonPressDurationsToWinAllRaces()
- Return (GetProductOfAcceleratorButtonPressDurations, 0)
- End Function
- Private Function GetRawDataFrom(FilePath As String) As IEnumerable(Of String)
- Return IO.File.ReadAllLines(FilePath)
- End Function
- Private Sub ParseRawData(RawDataLines As IEnumerable(Of String))
- Dim Times = RawDataLines(0).Split({":"c, " "c}, StringSplitOptions.RemoveEmptyEntries).Skip(1).Select(Function(x) Long.Parse(x))
- Dim Records = RawDataLines(1).Split({":"c, " "c}, StringSplitOptions.RemoveEmptyEntries).Skip(1).Select(Function(x) Long.Parse(x))
- For i = 0 To Times.Count - 1
- Races.Add(New Race(Times(i), Records(i)))
- Next
- End Sub
- Private Sub RetrieveAcceleratorButtonPressDurationsToWinAllRaces()
- AcceleratorButtonPressDurationsToWin.AddRange(Races.Select(Function(x) x.GetAcceleratorButtonPressDurationToWin))
- End Sub
- Private Function GetProductOfAcceleratorButtonPressDurations() As Long
- Dim Result = 1
- For Each AcceleratorButtonPressDurationToWin In AcceleratorButtonPressDurationsToWin
- Result *= AcceleratorButtonPressDurationToWin.Count
- Next
- Return Result
- End Function
- End Class
- Friend Class Race
- Private ReadOnly DurationInMilliseconds As Long
- Private ReadOnly DistanceToBeat As Long
- Sub New(DurationInMilliseconds As Long, DistanceToBeat As Long)
- Me.DurationInMilliseconds = DurationInMilliseconds
- Me.DistanceToBeat = DistanceToBeat
- End Sub
- Function GetAcceleratorButtonPressDurationToWin() As IEnumerable(Of Long)
- Dim AcceleratorButtonPressDurationsToWin As New List(Of Long)
- For i = 0 To DurationInMilliseconds - 1
- Dim TimeToDrive = DurationInMilliseconds - i
- Dim ReachableDistance = TimeToDrive * i
- If ReachableDistance > DistanceToBeat Then AcceleratorButtonPressDurationsToWin.Add(i)
- Next
- Return AcceleratorButtonPressDurationsToWin
- End Function
- 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
- private static void Part01()
- {
- var src = Source().Select(s => s.Split(' ',
- StringSplitOptions.RemoveEmptyEntries).Skip(1).Select(int.Parse));
- var datas = src.First().Zip(src.Last(), (t, d) => (t, d));
- var result = new List<int>();
- foreach (var (time, distance) in datas)
- {
- var tmp = new List<int>();
- for (var i = 1; i < time; i++)
- if (i * (time - i) > distance)
- tmp.Add(i);
- if (tmp.Count > 0) result.Add(tmp.Count);
- }
- Console.WriteLine($"{nameof(Part01)}: {result.Aggregate(1, (a, b) => a * b)}");
- }
Part 2 C#-Quellcode
- private static void Part02()
- {
- var src = Source().Select(s => string.Join("", s.Split(' ',
- StringSplitOptions.RemoveEmptyEntries).Skip(1))).Select(long.Parse);
- var time = src.First();
- var distance = src.Last();
- var result = new List<long>();
- for (var i = 1; i < time; i++)
- if (i * (time - i) > distance)
- result.Add(i);
- Console.WriteLine($"{nameof(Part02)}: {result.Count}");
- }
Challenge C#-Quellcode
- private static void Day06Stress()
- {
- var src = SourceStress().Select(s => s.Split(' ',
- StringSplitOptions.RemoveEmptyEntries).Skip(1).Select(long.Parse));
- var datas = src.First().Zip(src.Last(), (t, d) => (t, d));
- Int128 result = 1;
- foreach (var (time, distance) in datas)
- {
- // -x^2 + time * x - distance > 0.
- var (x1, x2) = SolveEq(-1, time, -distance);
- var minx = (Int128)Math.Floor(x1) + 1;
- var maxx = (Int128)Math.Ceiling(x2) - 1;
- result *= maxx - minx + 1;
- }
- Console.WriteLine($"{nameof(Day06Stress)}_Part1: {result}");
- var newsrc = SourceStress().Select(s => string.Join("", s.Split(' ',
- StringSplitOptions.RemoveEmptyEntries).Skip(1))).Select(Int128.Parse);
- var t = newsrc.First();
- var d = newsrc.Last();
- {
- result = 0; ;
- // -x^2 + time * x - distance > 0.
- var (x1, x2) = SolveEq(-1, t, -d);
- var minx = (Int128)Math.Floor(x1) + 1;
- var maxx = (Int128)Math.Ceiling(x2) - 1;
- result = maxx - minx + 1;
- }
- Console.WriteLine($"{nameof(Day06Stress)}_Part2: {result}");
- }
- // solves ax^2 + bx + c = 0 (with two roots)
- private static (double, double) SolveEq(Int128 a, Int128 b, Int128 c)
- {
- var r = b * b - 4 * a * c;
- var d = Math.Sqrt((double)r);
- var x1 = (-(double)b - d) / (double)(2 * a);
- var x2 = (-(double)b + d) / (double)(2 * a);
- return (Math.Min(x1, x2), Math.Max(x1, x2));
- }
- private static string[] SourceStress() =>
- [
- "Time: 56 97 77 93 67 71 86 91",
- "Distance: 499 2210 1097 1440 603 753 1232 997",
- ];
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
- using FileStream fs = File.OpenRead(@"C:\Dev\dotnet\AdventOfCode\2023\Day3\input.txt");
- using StreamReader sr = new(fs);
- int y = 0;
- List<V> schema = new();
- List<S> symbols = new();
- while (!sr.EndOfStream)
- {
- var lineSpan = sr.ReadLine().AsSpan();
- bool parsingNumber = false;
- V? v = null;
- for (int x = 0; x < lineSpan.Length; ++x)
- {
- if ((lineSpan[x] >= 48) && (lineSpan[x] <= 57))
- {
- if (!parsingNumber) v = new(x, y);
- v!.Value.Add(lineSpan[x]);
- parsingNumber = true;
- continue;
- }
- else
- {
- if (parsingNumber)
- {
- v!.EndIndex = x - 1;
- schema.Add(v);
- parsingNumber = false;
- }
- if (lineSpan[x] == '.') continue;
- symbols.Add(new(x, y, lineSpan[x]));
- }
- }
- if (parsingNumber)
- {
- v!.EndIndex = lineSpan.Length - 1;
- schema.Add(v);
- }
- ++y;
- }
- int total = 0;
- #region Part1
- foreach (var v in schema)
- {
- if (HasAdjacentSymbol(v.StartIndex, v.EndIndex, v.Y))
- total += int.Parse(string.Join("", v.Value));
- }
- #endregion
- #region Part2
- foreach (var s in symbols)
- {
- if (s.v != '*') continue;
- total += CalculateGearRatio(s.x, s.y);
- }
- #endregion
- System.Console.WriteLine(total);
- bool HasAdjacentSymbol(int x1, int x2, int y)
- {
- foreach (var s in symbols)
- {
- if (Math.Abs(s.y - y) > 1) continue;
- for (int i = x1; i <= x2; ++i)
- {
- if (Math.Abs(i - s.x) <= 1) return true;
- }
- }
- return false;
- }
- int CalculateGearRatio(int x, int y)
- {
- int idx = 0;
- int[] gearValues = new int[2];
- foreach (var s in schema)
- {
- if (Math.Abs(s.Y - y) > 1) continue;
- for (int i = s.StartIndex; i <= s.EndIndex; ++i)
- {
- if (Math.Abs(i - x) <= 1)
- {
- if (idx > 1) return 0;
- gearValues[idx] = int.Parse(string.Join("", s.Value));
- ++idx;
- break;
- }
- }
- }
- return gearValues[0] * gearValues[1];
- }
- class V
- {
- public V(int x, int y)
- {
- StartIndex = x;
- Y = y;
- }
- public int StartIndex { get; set; }
- public int EndIndex { get; set; }
- public int Y { get; set; }
- public List<char> Value { get; set; } = new();
- }
- record struct S(int x, int y, char v);
Tag 4
Part 1
Spoiler anzeigen C#-Quellcode
- using FileStream fs = File.OpenRead(@"C:\Dev\dotnet\AdventOfCode\2023\Day4\input.txt");
- using StreamReader sr = new(fs);
- int total = 0;
- while (!sr.EndOfStream)
- {
- var lineSpan = sr.ReadLine().AsSpan();
- List<int> winningNumbers = new();
- List<int> cardsOnHand = new();
- // winning numbers
- for (int i = lineSpan.IndexOf(':') + 2; i < lineSpan.IndexOf('|') - 1; i += 3)
- {
- winningNumbers.Add(int.Parse(lineSpan[i..(i + 2)]));
- }
- int count = 0;
- for (int i = lineSpan.IndexOf('|') + 2; i < lineSpan.Length - 1; i += 3)
- {
- int c = int.Parse(lineSpan[i..(i + 2)]);
- if (winningNumbers.Contains(c))
- ++count;
- }
- if (count > 0)
- total += 1 << (count - 1);
- }
- System.Console.WriteLine(total);
Part 2
Spoiler anzeigen C#-Quellcode
- using FileStream fs = File.OpenRead(@"C:\Dev\dotnet\AdventOfCode\2023\Day4\input.txt");
- using StreamReader sr = new(fs);
- List<C> deckCounter = new();
- while (!sr.EndOfStream)
- {
- var lineSpan = sr.ReadLine().AsSpan();
- List<int> winningNumbers = new();
- List<int> cardsOnHand = new();
- for (int i = lineSpan.IndexOf(':') + 2; i < lineSpan.IndexOf('|') - 1; i += 3)
- {
- winningNumbers.Add(int.Parse(lineSpan[i..(i + 2)]));
- }
- int count = 0;
- for (int i = lineSpan.IndexOf('|') + 2; i < lineSpan.Length - 1; i += 3)
- {
- int c = int.Parse(lineSpan[i..(i + 2)]);
- if (winningNumbers.Contains(c))
- ++count;
- }
- deckCounter.Add(new(count, 1));
- }
- for (int i = 0; i < deckCounter.Count; ++i)
- {
- int copyCount = 0;
- do
- {
- ++copyCount;
- for (int j = 1; j <= deckCounter[i].Won; ++j)
- {
- deckCounter[i + j].Total++;
- deckCounter[i + j].Copy++;
- }
- }
- while (copyCount <= deckCounter[i].Copy);
- }
- System.Console.WriteLine(deckCounter.Sum(d => d.Total));
- class C
- {
- public int Won { get; set; }
- public int Copy { get; set; }
- public int Total { get; set; }
- public C(int won, int total)
- {
- Won = won;
- Total = total;
- }
- }
Tag 5
Part 1
Spoiler anzeigen C#-Quellcode
- using FileStream fs = File.OpenRead(@"C:\Dev\dotnet\AdventOfCode\2023\Day5\input.txt");
- using StreamReader sr = new(fs);
- List<long> seeds = new();
- Dictionary<string, List<long[]>> maps = new();
- List<string> types = new();
- string type = string.Empty;
- while (!sr.EndOfStream)
- {
- var lineSpan = sr.ReadLine().AsSpan();
- if (lineSpan.Length == 0) continue;
- int colonIndex = lineSpan.IndexOf(':');
- if (colonIndex > -1)
- {
- type = lineSpan[..colonIndex].ToString();
- if (type == "seeds")
- {
- ExtractSeeds(lineSpan[(colonIndex + 2)..]);
- }
- else
- types.Add(type);
- }
- else
- {
- SplitMap(type, lineSpan);
- }
- }
- long minLocation = 0;
- int typeIdx = 0;
- foreach (long seed in seeds)
- {
- typeIdx = 0;
- long currentLocation = GetLocation(seed);
- if ((currentLocation < minLocation) || (minLocation == 0))
- minLocation = currentLocation;
- }
- System.Console.WriteLine(minLocation);
- long GetLocation(long seed)
- {
- long searchValue = seed;
- while (typeIdx < types.Count)
- {
- searchValue = GetMapValue(types[typeIdx], searchValue);
- ++typeIdx;
- }
- return searchValue;
- }
- long GetMapValue(string type, long searchValue)
- {
- var v = maps[type];
- foreach (long[] x in v)
- {
- if (x[1] > searchValue || (x[1] + (x[2] - 1)) < searchValue)
- {
- continue;
- }
- return x[0] + searchValue - x[1];
- }
- return searchValue;
- }
- void ExtractSeeds(ReadOnlySpan<char> line)
- {
- Range[] ranges = new Range[line.Count(' ') + 1];
- if (line.Split(ranges, ' ') <= 0) return;
- foreach (Range r in ranges)
- {
- seeds.Add(long.Parse(line[r]));
- }
- }
- void SplitMap(string type, ReadOnlySpan<char> line)
- {
- Range[] ranges = new Range[3];
- line.Split(ranges, ' ');
- long[] values = new long[3];
- for (int i = 0; i < ranges.Length; ++i)
- {
- values[i] = long.Parse(line[ranges[i]]);
- }
- if (!maps.ContainsKey(type))
- maps.Add(type, new() { values });
- else
- maps[type].Add(values);
- }
Part 2
Spoiler anzeigen
Habe ich etwas parallelisiert - lief dann in 9m 51.208s - Vielleicht gehts noch schneller, oder hübscher. Kp.
C#-Quellcode
- using FileStream fs = File.OpenRead(@"C:\Dev\dotnet\AdventOfCode\2023\Day5\input.txt");
- using StreamReader sr = new(fs);
- List<long> seeds = new();
- Dictionary<string, List<long[]>> maps = new();
- List<string> types = new();
- string type = string.Empty;
- while (!sr.EndOfStream)
- {
- var lineSpan = sr.ReadLine().AsSpan();
- if (lineSpan.Length == 0) continue;
- int colonIndex = lineSpan.IndexOf(':');
- if (colonIndex > -1)
- {
- type = lineSpan[..colonIndex].ToString();
- if (type == "seeds")
- {
- ExtractSeeds(lineSpan[(colonIndex + 2)..]);
- }
- else
- types.Add(type);
- }
- else
- {
- SplitMap(type, lineSpan);
- }
- }
- long minLocation = 0;
- object o = new();
- for (int i = 0; i < seeds.Count - 1; i += 2)
- {
- long dest = seeds[i] + seeds[i + 1] - 1;
- Parallel.For(seeds[i], dest, new ParallelOptions { MaxDegreeOfParallelism = 10 }, j =>
- {
- long currentLocation = GetLocation(j);
- lock (o)
- {
- if ((currentLocation < minLocation) || (minLocation == 0))
- minLocation = currentLocation;
- }
- });
- }
- System.Console.WriteLine(minLocation);
- long GetLocation(long seed)
- {
- long searchValue = seed;
- int typeIdx = 0;
- while (typeIdx < types.Count)
- {
- searchValue = GetMapValue(types[typeIdx], searchValue);
- ++typeIdx;
- }
- return searchValue;
- }
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
- using System.Text.RegularExpressions;
- namespace Tag06
- {
- internal class Program
- {
- static void Main(string[] args)
- {
- string[] exampleFile = File.ReadAllLines("Example.txt");
- string[] inputFile = File.ReadAllLines("Input.txt");
- Console.WriteLine($"Example: {Calculate(exampleFile)}");
- Console.WriteLine($"Example2: {Calculate(exampleFile, true)}");
- Console.WriteLine($"Input Part 1: {Calculate(inputFile)}");
- Console.WriteLine($"Input Part 2: {Calculate(inputFile,true)}");
- }
- static long Calculate(string[] lines, bool p2 = false)
- {
- long sum = 1;
- long[] times = null;
- long[] distances = null;
- if (!p2)
- {
- times = Regex.Matches(lines[0].Split(':')[1], @"(\d)+").Select(x => long.Parse(x.Value)).ToArray();
- distances = Regex.Matches(lines[1].Split(':')[1], @"(\d)+").Select(x => long.Parse(x.Value)).ToArray();
- } else
- {
- times = Regex.Matches(lines[0].Split(':')[1].Replace(" ", ""), @"(\d)+").Select(x => long.Parse(x.Value)).ToArray();
- distances = Regex.Matches(lines[1].Split(':')[1].Replace(" ", ""), @"(\d)+").Select(x => long.Parse(x.Value)).ToArray();
- }
- for (long i = 0; i < times.Length; i++)
- {
- int totalWins = 0;
- long time = times[i];
- long distance = distances[i];
- for (long t = 1; t <= time; t++)
- {
- long traveled = t * (time - t);
- if( traveled > distance )
- {
- totalWins++;
- }
- }
- sum *= totalWins;
- }
- return sum;
- }
- }
- }
-
Und dann haben wir noch Tag 6
Spoiler anzeigen C#-Quellcode
- using System.Text.RegularExpressions;
- using FileStream fs = File.OpenRead(@"D:\Dev\net\AdventOfCode\2023\Day6\input.txt");
- using StreamReader sr = new(fs);
- int total = 1;
- const string pattern = "\\d+";
- Regex r = new(pattern, RegexOptions.Compiled);
- List<long> times = new();
- List<long> distances = new();
- int line = 0;
- while (!sr.EndOfStream)
- {
- var lineSpan = sr.ReadLine().AsSpan();
- var values = lineSpan[(lineSpan.IndexOf(':') + 1)..].TrimStart();
- if (r.IsMatch(lineSpan))
- {
- int len = 0;
- foreach (var m in r.EnumerateMatches(lineSpan))
- {
- len += m.Length;
- #region Part1
- int v = int.Parse(lineSpan[m.Index..(m.Index + m.Length)]);
- if (line == 0)
- times.Add(v);
- else
- distances.Add(v);
- #endregion
- }
- #region Part2
- long v = long.Parse(string.Create(len, values.ToString(), (s, value) =>
- {
- var p = value.AsSpan();
- int idx = 0;
- for (int i = 0; i < p.Length; ++i)
- {
- if (p[i] == ' ') continue;
- s[idx++] = p[i];
- }
- }));
- if (line == 0)
- times.Add(v);
- else
- distances.Add(v);
- #endregion
- }
- ++line;
- }
- for (int i = 0; i < times.Count; ++i)
- {
- int p = 0;
- for (int j = 1; j < times[i] - 1; j++)
- {
- if ((j * (times[i] - j)) > distances[i])
- p++;
- else if (p > 0)
- break;
- }
- total *= p;
- }
- 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“ ()
-
Ähnliche Themen
-
FinnSoft - - Off-Topic
-
8 Benutzer haben hier geschrieben
- VaporiZed (27)
- Haudruferzappeltnoch (26)
- xChRoNiKx (18)
- exc-jdbi (17)
- nogood (8)
- ISliceUrPanties (6)
- oobdoo (1)
- Elanda (1)