🌟 Advent of Code (AoC) 2022 🌟

PermalÀnk
●

Dag: 4
SprÄk: Haskell

Kom igÄng sent idag, men det blev gjort ÀndÄ.

Jag fick inte till nÄn snygg parsning av inputstrÀngen. Det kommer sÀkert att Äterkomma, sÄ fÄr försök hitta ett bra sÀtt att göra det.

-- The program expects the input on stdin, ie -- $ ./solve < input main = interact solve solve :: String -> String solve input = "Problem 1: " ++ show p1 ++ "\n" ++ "Problem 2: " ++ show p2 ++ "\n" where p1 = length (filter fullOverlap intervals) p2 = length (filter partialOverlap intervals) intervals = map getIntervals (lines input) fullOverlap :: (Int, Int, Int, Int) -> Bool fullOverlap (a, b, c, d) | (a <= c && b >= d) || (a >= c && b <= d) = True | otherwise = False partialOverlap :: (Int, Int, Int, Int) -> Bool partialOverlap (a, b, c, d) | (b < c) || (a > d) = False | otherwise = True getIntervals :: String -> (Int, Int, Int, Int) getIntervals s = (a, b, c, d) where (a, b) = parseInterval (takeWhile (/=',') s) (c, d) = parseInterval (tail (dropWhile (/=',') s)) parseInterval = (\s -> ( read (takeWhile (/='-') s), read (tail (dropWhile (/='-') s))))

(Jag anvÀnder highlight som finns i apt för syntaxfÀrgning.)

Dold text
PermalÀnk
Medlem
●

Dag: 4
SprÄk: Dyalog APL

a b←1 0 1 0⊂↑⍎¹¹'\d+'⎕S'&'¹⊃⎕NGET'4.txt' 1 +/0≄×/a-b ⍝ del1 +/0≄×/a-⌜b ⍝ del2

APL interpreteras frÄn höger till vÀnster.

'\d+'⎕S'&'¹⊃⎕NGET'4.txt'1

LĂ€ser in filen, regex plockar ut siffrorna

↑⍎¹¹'\d+'⎕S'&'¹⊃⎕NGET'4.txt'1

⍎š Tolkar om sifforna frĂ„n text till nummer, resultatet Ă€r en array fylld med fyra elements arrayer
↑ Gör om arrayen till en 1000x4 matris

1 0 1 0⊂↑⍎¹¹'\d+'⎕S'&'¹⊃⎕NGET'4.txt' 1

X ⊂ Y "Partitioned Enclose" delar upp arrayen Y enligt X.
Resultatet Àr en array innehÄllande tvÄ 1000x2 matriser. En matris per range.

a b←1 0 1 0⊂↑⍎¹¹'\d+'⎕S'&'¹⊃⎕NGET'4.txt' 1

Tilldelar variabeln a första matrisen och b den andra.

a-b

matris a - matris b vilket Àr samma sak som (range A start - range B start) (range A end - range B end)

×/a-b

Radvis reduce med multiplikation = (range A start - range B start) * (range A end - range B end)
Resultatet Àr en 1000 elements vektor. Reduce minskar arrayens/matrisens rank (dimensioner) med 1

0≄×/a-b

JÀmför alla element i vektorn med 0. Alla element som Àr negativa eller 0 sÀtts till 1

+/0≄×/a-b

+/ plus reduce Summerar vektorn vilket ger svaret

+/0≄×/a-⌜b

Samma som del1 men ⌜b byter plats pĂ„ kolumnerna i matris b. (range A start - range B end) * (range A end - range B start)

Dold text

Skrev Àven en vektoriserad version i Scala men gissningsvis genererar JIT-kompilatorn hyffsat bra kod ÀndÄ. Inte hunnit jÀmföra Ànnu.

Tog inte med fil io eller parsning. (as/bs = range a start/end, cs/ds = range b start/end)
BerÀknar del1 och del2 samtidigt. SIMD bitar / 16 element Ät gÄngen.
Programmet Àr lÄngsamt pÄ den vÀldigt korta input man fÄr frÄn AoC.

def day4(as: Array[Short], bs: Array[Short], cs: Array[Short], ds: Array[Short]): (Int, Int) = val spec = ShortVector.SPECIES_PREFERRED val sz = as.length var i = 0 var acc1v = ShortVector.zero(spec) var acc2v = ShortVector.zero(spec) while i < spec.loopBound(sz) do val av = ShortVector.fromArray(spec, as, i) val bv = ShortVector.fromArray(spec, bs, i) val cv = ShortVector.fromArray(spec, cs, i) val dv = ShortVector.fromArray(spec, ds, i) acc1v = acc1v.add(av.sub(bv).mul(bv.sub(dv)).compare(LE, 0).toVector.abs()) acc2v = acc2v.add(av.sub(dv).mul(bv.sub(cv)).compare(LE, 0).toVector.abs()) i += spec.length() var acc1s = 0 var acc2s = 0 while i < sz do if (as(i) - cs(i)) * (bs(i) - ds(i)) <= 0 then acc1s += 1 if (as(i) - ds(i)) * (bs(i) - cs(i)) <= 0 then acc2s += 1 i += 1 (acc1v.reduceLanes(ADD) + acc1s, acc2v.reduceLanes(ADD) + acc2s)

Dold text
Fel dag och kortare lösning.
PermalÀnk
Medlem
●

Dag:1 del1
SprÄk: Go
Lösning:

package main import ( "fmt" "os" "strconv" "strings" ) func main() { var elf []int input, _ := os.ReadFile("../input.txt") inputString := string(input) inputArray := strings.Split(inputString, "\n\n") for i := 1; i <= len(inputArray); i++ { var elfCal int calories := strings.Split(inputArray[i-1], "\n") for j := 0; j < len(calories); j++ { calInt, _ := strconv.Atoi(calories[j]) elfCal += calInt } elf = append(elf, elfCal) elfCal = 0 } maxElf := 0 for i := 0; i < len(elf); i++ { if elf[i] > maxElf { maxElf = elf[i] } } fmt.Println(maxElf) }

Dold text

Dag:1 del2
SprÄk: Go
Lösning:

package main import ( "fmt" "os" "strconv" "strings" ) func main() { var elf []int input, _ := os.ReadFile("../input.txt") inputString := string(input) inputArray := strings.Split(inputString, "\n\n") for i := 1; i <= len(inputArray); i++ { var elfCal int calories := strings.Split(inputArray[i-1], "\n") for j := 0; j < len(calories); j++ { calInt, _ := strconv.Atoi(calories[j]) elfCal += calInt } elf = append(elf, elfCal) elfCal = 0 } maxElf := 0 secondElf := 0 thirdElf := 0 for i := 0; i < len(elf); i++ { if elf[i] > maxElf { maxElf = elf[i] } } for i := 0; i < len(elf); i++ { if elf[i] > secondElf && elf[i] < maxElf { secondElf = elf[i] } } for i := 0; i < len(elf); i++ { if elf[i] > thirdElf && elf[i] < secondElf { thirdElf = elf[i] } } topThree := maxElf + secondElf + thirdElf fmt.Println(topThree) }

Dold text
Visa signatur

Citera sÄ hittar jag tillbaks och kan ge svar.

PermalÀnk
Medlem
●

Dag:2 del1
SprÄk: Go
Lösning:

package main import ( "fmt" "os" "strings" ) func main() { input, _ := os.ReadFile("../input.txt") inputString := string(input) rounds := strings.Split(inputString, "\n") var score int for i := 0; i < len(rounds); i++ { oponent := rounds[i][0] mine := rounds[i][2] switch mine { //I throw rock case 'X': score += 1 //I throw paper case 'Y': score += 2 //I throw scissors case 'Z': score += 3 } switch oponent { //They throw Rock case 'A': if mine == 'X' { score += 3 } if mine == 'Y' { score += 6 } if mine == 'Z' { score += 0 } //They throw Paper case 'B': if mine == 'X' { score += 0 } if mine == 'Y' { score += 3 } if mine == 'Z' { score += 6 } //They throw Scissors case 'C': if mine == 'X' { score += 6 } if mine == 'Y' { score += 0 } if mine == 'Z' { score += 3 } } } fmt.Println(score) }

Dold text

Dag:2 del2
SprÄk: Go
Lösning:

package main import ( "fmt" "os" "strings" ) func main() { input, _ := os.ReadFile("../input.txt") inputString := string(input) rounds := strings.Split(inputString, "\n") var score int for i := 0; i < len(rounds); i++ { oponent := rounds[i][0] mine := rounds[i][2] switch mine { //I throw rock case 'X': score += 0 //I throw paper case 'Y': score += 3 //I throw scissors case 'Z': score += 6 } switch oponent { //They throw Rock case 'A': if mine == 'X' { score += 3 } if mine == 'Y' { score += 1 } if mine == 'Z' { score += 2 } //They throw Paper case 'B': if mine == 'X' { score += 1 } if mine == 'Y' { score += 2 } if mine == 'Z' { score += 3 } //They throw Scissors case 'C': if mine == 'X' { score += 2 } if mine == 'Y' { score += 3 } if mine == 'Z' { score += 1 } } } fmt.Println(score) }

Dold text
Visa signatur

Citera sÄ hittar jag tillbaks och kan ge svar.

PermalÀnk
Medlem
●

Dag:3 del1
SprÄk: Go
Lösning:

package main import ( "fmt" "os" "strings" ) func main() { var backpacks []string var priority int //take input from file and make it a string input, _ := os.ReadFile("../input.txt") inputString := string(input) //split input into each elfs calories backpacks = strings.Split(inputString, "\n") for i := 0; i < len(backpacks); i++ { var prio int comp1 := backpacks[i][0 : len(backpacks[i])/2] comp2 := backpacks[i][len(backpacks[i])/2:] for _, ch := range comp1 { if strings.Contains(comp2, string(ch)) { if ch > 97 { prio = int(ch) prio -= 96 } else { prio = int(ch) prio -= 38 } } } priority += prio } fmt.Println(priority) }

Dold text

Dag:3 del2
SprÄk: Go
Lösning:

package main import ( "fmt" "os" "strings" ) func main() { var backpacks []string var priority int iterations := 0 compare := 1 //take input from file and make it a string input, _ := os.ReadFile("../input.txt") inputString := string(input) //split input into each elfs calories backpacks = strings.Split(inputString, "\n") for i := 0; i < len(backpacks); i += 3 { var prio int for _, ch := range backpacks[i] { if string(ch) == "g" { } if strings.Contains(backpacks[i+1], string(ch)) { if strings.Contains(backpacks[i+2], string(ch)) { if ch > 97 { prio = int(ch) prio -= 96 } else { prio = int(ch) prio -= 38 } break } } } priority += prio compare++ if compare >= 3 { compare = 1 } iterations++ } fmt.Println(priority) }

Dold text
Visa signatur

Citera sÄ hittar jag tillbaks och kan ge svar.

PermalÀnk
Medlem
●

Dag:4 del1
SprÄk: Go
Lösning:

package main import ( "fmt" "os" "strconv" "strings" ) func main() { counter := 0 //take input from file and make it a string input, _ := os.ReadFile("../input.txt") inputString := string(input) pairs := strings.Split(inputString, "\n") for i := 0; i < len(pairs); i++ { elfs := strings.Split(pairs[i], ",") elfOneStart, _ := strconv.Atoi(strings.Split(elfs[0], "-")[0]) elfOneEnd, _ := strconv.Atoi(strings.Split(elfs[0], "-")[1]) elfTwoStart, _ := strconv.Atoi(strings.Split(elfs[1], "-")[0]) elfTwoEnd, _ := strconv.Atoi(strings.Split(elfs[1], "-")[1]) if (elfOneStart <= elfTwoStart && elfOneEnd >= elfTwoEnd) || (elfTwoStart <= elfOneStart && elfTwoEnd >= elfOneEnd) { counter++ } } fmt.Println(counter) }

Dold text

Dag:4 del2
SprÄk: Go
Lösning:

package main import ( "fmt" "os" "strconv" "strings" ) func main() { counter := 0 //take input from file and make it a string input, _ := os.ReadFile("../input.txt") inputString := string(input) pairs := strings.Split(inputString, "\n") for i := 0; i < len(pairs); i++ { elfOneStart, _ := strconv.Atoi(strings.Split(strings.Split(pairs[i], ",")[0], "-")[0]) elfOneEnd, _ := strconv.Atoi(strings.Split(strings.Split(pairs[i], ",")[0], "-")[1]) elfTwoStart, _ := strconv.Atoi(strings.Split(strings.Split(pairs[i], ",")[1], "-")[0]) elfTwoEnd, _ := strconv.Atoi(strings.Split(strings.Split(pairs[i], ",")[1], "-")[1]) if (elfOneStart <= elfTwoStart && elfOneEnd >= elfTwoStart) || (elfTwoStart <= elfOneStart && elfTwoEnd >= elfOneStart) { counter++ } } fmt.Println(counter) }

Dold text
Visa signatur

Citera sÄ hittar jag tillbaks och kan ge svar.

PermalÀnk
Medlem ★
●

Aj! Dagens problem var ett rejÀlt hopp upp i svÄrighetsgrad. Blev sÄ pass mycket fulkod att jag inte ens vÄgar posta hÀr innan jag gÄtt igenom ordentligt och snyggat upp.

using AoCUtils; Console.WriteLine("Mickur's Advent of Code 2022 - Day 5!"); // Setup var input = File.ReadAllLines("input.txt"); var stackParseComplete = false; var instructionsBegin = 0; var stacks1 = new List<List<char>>(); var stacks2 = new List<List<char>>(); // Parsing... for (var i = 0; i < input.Length; i++) { if (stackParseComplete) { instructionsBegin = i + 1; break; } for (var j = 0; j < input[i].Length; j++) { var valueIndex = j * 4 + 1; // If valueIndex is out of range, continue. if (valueIndex >= input[i].Length) continue; // If valueIndex contains an integer, we are done. if (char.IsDigit(input[i][valueIndex])) { stackParseComplete = true; break; } // If we are in the first loop, create a stack to work with if (i == 0) { stacks1.Add(new List<char>()); stacks2.Add(new List<char>()); } // Push value to stacks if (input[i][valueIndex] != ' ') { stacks1[j].Add(input[i][valueIndex]); stacks2[j].Add(input[i][valueIndex]); } } } for (var i = 0; i < stacks1.Count; i++) { stacks1[i].Reverse(); stacks2[i].Reverse(); } // Actual instructions for (var i = instructionsBegin; i < input.Length; i++) { var split = input[i].Split(' '); var move = Parsing.FastIntParse(split[1]); var from = Parsing.FastIntParse(split[3]); var to = Parsing.FastIntParse(split[5]); // Part One for (var j = 0; j < move; j++) { var lastIndex = stacks1[from - 1].Count - 1; var temp = stacks1[from - 1][lastIndex]; stacks1[from - 1].RemoveAt(lastIndex); stacks1[to - 1].Add(temp); } // Part Two for (var j = move; j > 0; j--) { var currIndex = stacks2[from - 1].Count - j; var temp = stacks2[from - 1][currIndex]; stacks2[from - 1].RemoveAt(currIndex); stacks2[to - 1].Add(temp); } } // Part One: ... var answer = ""; foreach (var stack in stacks1) answer += stack[^1]; Console.WriteLine(answer); // Part Two: ... answer = ""; foreach (var stack in stacks2) answer += stack[^1]; Console.WriteLine(answer);

Dold text

Edit: FÄr nog duga sÄ...

Visa signatur

CPU: 7950X 5GHz@1.1v | RAM: 32GB 6000MHz CL36 | GPU: KFAÂČ 3090 SG w/ AlphaCool Eisblock Aurora
Ljudkort: Modius + Magnius | Lurar: GoldPlanar GL2000 / Sennheiser HD 650 / Philips Fidelio X3 / Supreme CD-99

PermalÀnk
Medlem ★
●
Skrivet av GLaDER:

Dag: 4
SprÄk: Python 3
Lösning: GitHub

Ugh. Det hÀr var inte min morgon. FrÄn att ha varit nÀstan Top 1 000 igÄr till en bit över 8 000 idag

Snurrade bort mig totalt pÄ bÄda delarna. I del 1 försökte jag lÀnge implementera min egna issubset-metod innan jag kom pÄ att det var just konceptet sub set jag letade efter.

I del 2 gick jag bort mig pÄ att jag började leta efter överlappet för samtliga tilldelningar, samt hur stort det totala överlappet var. Det var inte förrÀn jag lÀste igenom tredje gÄngen som jag förstod att det bara var huruvida det existerade ett överlapp för varje par som var intressant. Tyckte vÀl att över 85 000 var lite stort...

Dold text

Dag: 5
SprÄk: Python 3
Lösning: GitHub

Mitt hjÀrta blöder.

Jag har ett script som lÀser in datan frÄn AoC och sparar i en fil <dag>.input. Av nÄgon outgrundlig anledning fungerade inte scriptet för att lÀsa dagens input, men det tog lÄÄÄng tid att förstÄ varför. "Problemet" var att min parsningsfunktion fortfarande returnerade en helt rimlig parsning (och eftersom jag gjorde copy-paste pÄ test-input sÄ fick jag rÀtt pÄ test-input).

Det tog nog 20 minuter för mig att lösa uppgiften; sen tog det vÀldigt lÄng tid att fatta varför jag fick fel svar.

Dold text
Visa signatur

:(){ :|:& };:

đŸŠđŸ»â€â™‚ïž   đŸšŽđŸ»â€â™‚ïž   đŸƒđŸ»â€â™‚ïž   ☕

PermalÀnk
Datavetare ★
●

Dag: 5
SprÄk: Go

package main import ( "fmt" "strconv" "strings" ) type crateStack []byte type crateStorage []crateStack type crateMoves struct { cnt int from int to int } func (cStack *crateStack) push(crate byte) { *cStack = append(*cStack, crate) } func (cStack *crateStack) pop() byte { newLen := len(*cStack) - 1 crate := (*cStack)[newLen] *cStack = (*cStack)[:newLen] return crate } func parseCrateStorage(input []string, stackDesc string) crateStorage { stackDescVec := strings.Fields(stackDesc) numStacks, err := strconv.Atoi(stackDescVec[len(stackDescVec)-1]) if err != nil { panic("Failed to figure out number of stacks") } cs := make(crateStorage, numStacks) for row := len(input) - 1; row >= 0; row-- { line := input[row] for stack := 0; stack < numStacks; stack++ { crate := line[1+stack*4] if crate != ' ' { cs[stack].push(crate) } } } return cs } func parseCrateMoves(input []string) []crateMoves { cm := []crateMoves{} for _, row := range input { moves := crateMoves{} if _, err := fmt.Sscanf(row, "move %d from %d to %d", &moves.cnt, &moves.from, &moves.to); err != nil { panic("Failed to parse move") } cm = append(cm, moves) } return cm } func parseCrates(input []string) (crateStorage, []crateMoves) { for i, row := range input { if row == "" { return parseCrateStorage(input[:i-1], input[i-1]), parseCrateMoves(input[i+1:]) } } panic("Invalid input") } func copyCrateStorage(cs crateStorage) crateStorage { copy := append(crateStorage{}, cs...) for i := range copy { copy[i] = append(crateStack{}, copy[i]...) } return copy } func createMsg(crates crateStorage) string { msg := []byte{} for _, crate := range crates { msg = append(msg, crate.pop()) } return string(msg) } func moveCrates9000(crates crateStorage, moveInstr []crateMoves) string { for _, moves := range moveInstr { for cnt := 0; cnt < moves.cnt; cnt++ { crates[moves.to-1].push(crates[moves.from-1].pop()) } } return createMsg(crates) } func moveCrates9001(crates crateStorage, moveInstr []crateMoves) string { stack := crateStack{} for _, moves := range moveInstr { for cnt := 0; cnt < moves.cnt; cnt++ { stack.push(crates[moves.from-1].pop()) } for len(stack) > 0 { crates[moves.to-1].push(stack.pop()) } } return createMsg(crates) } func day5(input []string) { storage, moves := parseCrates(input) fmt.Println(moveCrates9000(copyCrateStorage(storage), moves)) fmt.Println(moveCrates9001(storage, moves)) } func init() { Solutions[5] = day5 }

Dold text

HÀlften av koden Àr parsning...

Del 2 löstest pÄ enkla sÀttet, inte det effektivare. LÀgg paketen i ett mellanlager, dÄ blir den omvÀnd ordning i mellanlagret och rÀtt ordning i efterföljande steg -> samma algoritm som i del 1 fungerar Àven dÀr

Dold text
Visa signatur

Care About Your Craft: Why spend your life developing software unless you care about doing it well? - The Pragmatic Programmer

PermalÀnk
Medlem ★
●

Dag: 5
SprÄk: js

Funderade pÄ att skriva en parser för startdatan men det skulle ta lÀngre tid Àn att bara skriva in det i ett par arrayer sÄ jag betade pÄ att jag inte skulle behöva Àndra nÄgot dÀr.

Gjorde samma sak med instruktionerna, ersatte 'move ', ' from ' och ' to ' sÄ jag fick en array i form av [2,4,6] (move 2 from 4 to 6) nÀr jag la in dem.
Sedan var det bara att iterera över instruktionerna.

const startData= { 1: ['N','R','G','P'], 2: ['J','T','B','L','F','G','D','C'], 3: ['M','S','V'], 4: ['L','S','R','C','Z','P'], 5: ['P','S','L','V','C','W','D','Q'], 6: ['C','T','N','W','D','M','S'], 7: ['H','D','G','W','P'], 8: ['Z','L','P','H','S','C','M','V'], 9: ['R','P','F','L','W','G','Z'] }; const instructions = [[2,4,6], etc. ] instructions.forEach(instruction => { for(let i = instruction[0]; i>0; i--){ startData[instruction[2]].push(startData[instruction[1]].pop()); } }); Object.values(startData).forEach(stack => console.log(stack.pop()));

Edit: jag inser nu att jag kunde kört splice + reverse + concat hÀr för att slippa forloopen

Del 2
Ändrade iterationen till att köra concat/ splice istĂ€llet för push/pop:

instructions.forEach(instruction => { startData[instruction[2]] = startData[instruction[2]].concat(startData[instruction[1]].splice((-1*instruction[0]),instruction[0])); });

Dold text
copy paste fel (haha t.o.m. utanför editor)
Visa signatur

Att föresprÄka Mac pÄ Swec Àr som att föresprÄka hybridbilar pÄ en raggartrÀff i Mora.

PermalÀnk
Datavetare ★
●
Skrivet av Flexbert:

Borde inte din M1 vara överlÀgsen min MBP2017, 15"?

Inte nödvÀndigtvis. Testade pÄ en i7-8559U (Intel NUC, men tror det Àr en CPU Àven Apple anvÀnt i MBP) och den Àr ibland snabbare om man enbart sjÀlva berÀkningen i lÀgen dÀr berÀkningen Àr trivial/vÀldigt enkel.

NÀr nÄgot Àr enkelt och samtidigt inte innehÄller massiv mÀngd parallellism pÄ instruktionsnivÄ slÄr högre frekvens "bredare" design.

I samma problem, mÀter man istÀllet hela flödet, d.v.s. inklusive parsing, Àr M1 vÀsentligt mycket snabbare Àn i7-8559U. Ser samma sak med dagens problem, sjÀlva berÀkningen Àr vÀldigt serialiserad och Àr snabbare pÄ i7-8559U (som klockar 4,5 GHz) medan hela flödet Àr klart snabbare pÄ M1

Sen finns Go-specifika orsaker: i de senaste versionerna har man gjort förÀndringar som pÄverkat prestanda rÀtt ordentligt. Vissa av dessa förÀndringar Àr CPU-arkitekturspecifika dÀr x86_64 fick vissa optimeringar versionen innan de kom till ARM64. Det handlar om upp mot 20 % prestandaökningar!

Visa signatur

Care About Your Craft: Why spend your life developing software unless you care about doing it well? - The Pragmatic Programmer

PermalÀnk
●

Dag: 5
SprÄk: Nim
Lösning: Github

Blev sÄ glad nÀr jag insÄg att man sjÀlvklart kunde representera en stack av lÄdor med datatypen stack xD. Idag var den svÄraste parsingen för i Är hittils. Men gick hyffsat smidigt om Àn kanske inte optimal prestanda.

include prelude, strscans, algorithm proc crateNumber(indent: int): int = indent div 4 proc readInput*(input: string): tuple[stack: seq[seq[char]], instructions: seq[tuple[start, to, amount: int]]] = result.stack = newSeq[seq[char]](9) for line in input.splitLines: if '[' in line: # crate for i, c in line: if c == '[': let crate = crateNumber(i) result.stack[crate].add line[i+1] elif line.startsWith("move"): # move var instr: tuple[start, to, amount: int] assert scanf(line, "move $i from $i to $i", instr.amount, instr.start, instr.to) # zero-index adjust instr.start -= 1 instr.to -= 1 result.instructions.add instr # reverse stacks for i in 0 .. result.stack.high: result.stack[i].reverse() proc part1(input: string) = var (stack, instructions) = readInput(input) for (start, to, amount) in instructions: for i in 0 ..< amount: stack[to].add stack[start].pop() var answer: seq[char] for s in stack: answer.add s[^1] echo "Part 1: ", answer.join("") proc part2(input: string) = var (stack, instructions) = readInput(input) for (start, to, amount) in instructions: let movedCrates = stack[start][^amount .. ^1] stack[start].setLen(stack[start].len - amount) stack[to].add movedCrates var answer: seq[char] for s in stack: answer.add s[^1] echo "Part 2: ", answer.join("") when isMainModule: let input = readFile("input.txt") part1(input) part2(input)

Dold text
PermalÀnk
Medlem ★
●

Dag: 5
SprÄk: C#

SpÀnnande problem. Tog en stund att komma pÄ en "bra" strategi för parsing

public sealed class SupplyStacks : Puzzle<string> { public override string A(string data) { var sections = data .Split("\r\n\r\n"); var stacks = ExtractStacks(sections); foreach (var line in sections[1].Split("\r\n")) { var instructions = line.Split(" "); var amount = int.Parse(instructions[1]); for (int i = 0; i < amount; i++) { stacks[int.Parse(instructions[5]) - 1].Push(stacks[int.Parse(instructions[3]) - 1].Pop()); } } return PeekStacks(stacks); } public override string B(string data) { var sections = data .Split("\r\n\r\n"); var stacks = ExtractStacks(sections); foreach (var line in sections[1].Split("\r\n")) { var instructions = line.Split(" "); var amount = int.Parse(instructions[1]); Stack<char> crates = new Stack<char>(); for (int i = 0; i < amount; i++) { crates.Push(stacks[int.Parse(instructions[3]) - 1].Pop()); } while (crates.Count != 0) { stacks[int.Parse(instructions[5]) - 1].Push(crates.Pop()); } } return PeekStacks(stacks); } private static List<Stack<char>> ExtractStacks(IReadOnlyList<string> sections) { var stackSection = sections[0].Split("\r\n"); List<Stack<char>> stacks = new List<Stack<char>>(); for (int i = 0; i <= stackSection[^1].Length / 4; i++) { stacks.Add(new Stack<char>()); } for (int i = stackSection.Length - 2; i >= 0; i--) { var chunks = stackSection[i].Chunk(4).Select(c => new string(c[..3])).ToArray(); for (int j = 0; j < chunks.Length; j++) { if (chunks[j] != " ") { stacks[j].Push(chunks[j][1]); } } } return stacks; } private static string PeekStacks(IEnumerable<Stack<char>> stacks) { return string.Join(null, stacks .Select(s => s.Peek())); } }

Dold text
StÀdning
PermalÀnk
Medlem
●

Dag: 5
SprÄk: Python3

Blev ingen supersnygg lösning men den funkar.
MÀrktes direkt att det var lite svÄrare idag. Satan vad man klÀttrade i rank.

with open('Day5/data.txt') as file: data = file.readlines() stack = data[0:8] moves = data[10:] stack_list = [""] * len(max(stack, key=len)) for line in stack: line_clean = line.strip() for n, letter in enumerate(line_clean): if 'A' <= letter <= 'Z': stack_list[n] = stack_list[n] + letter while '' in stack_list: stack_list.remove('') stack_list2 = stack_list.copy() # For second half of puzzle moves_list = [] for text_moves in moves: moves_list.append([int(s) for s in text_moves.split() if s.isdigit()]) def rearrange_crate(stack_remove, stack_add, n_moves): for move in range(n_moves): stack_add = stack_remove[0] + stack_add stack_remove = stack_remove[1:] return stack_remove, stack_add def print_answer(stacks): answer = '' for stack in stacks: answer = answer + stack[0] print(answer) for move in moves_list: new_stacks = rearrange_crate(stack_list[move[1] - 1], stack_list[move[2] - 1], move[0]) stack_list[move[1] - 1] = new_stacks[0] stack_list[move[2] - 1] = new_stacks[1] print_answer(stack_list) # Print first answer def rearrange_crate_9001(stack_remove, stack_add, n_moves): stack_add = stack_remove[0:n_moves] + stack_add stack_remove = stack_remove[n_moves:] return stack_remove, stack_add for move in moves_list: new_stacks = rearrange_crate_9001(stack_list2[move[1] - 1], stack_list2[move[2] - 1], move[0]) stack_list2[move[1] - 1] = new_stacks[0] stack_list2[move[2] - 1] = new_stacks[1] print_answer(stack_list2) # Print second answer

Dold text
PermalÀnk
Medlem ★
●

Dag: 5
SprÄk: Python

import re def read_creates(f): crates = ["" for _ in range(9)] while l := f.readline().strip('\n'): crates = [crates[i] + c for i, c in enumerate(l[1::4])] return [""] + [c[:-1][::-1].strip() for c in crates] def read_moves(f): return [map(int, re.findall(r'\d+', l)) for l in f.readlines()] def do_moves(crates, moves, reverse): for n, f, t in moves: crates[t] = crates[t] + crates[f][-n:][::reverse] crates[f] = crates[f][:-n] return crates def day05(reverse): with open("input05", "r") as f: crates = do_moves(read_creates(f), read_moves(f), reverse) return("".join([c[-1] for c in crates[1:]])) print([day05(r) for r in [-1, 1]])

Dold text
PermalÀnk
Medlem ★
●

Dag: 5
SprÄk: F# som fÄr en att grÄta

Inte skitsnyggt, men det fungerar

open System open System.IO open System.Text.RegularExpressions type instruction = {howMany: int; fromWhere: int; toWhere: int;} let parse = let data = File.ReadAllLines "input.txt" let folder (m:Map<int, char list>) c = m.Add (((c |> Seq.head |> int)-int('0')), c |> Seq.tail |> Seq.filter (fun c -> c <> ' ') |> Seq.rev |> Seq.toList) let map = data |> Seq.takeWhile (fun c -> c.Trim() <> "") |> Seq.transpose |> Seq.map Seq.rev |> Seq.filter (Seq.head >> (fun c -> c <> ' ')) |> Seq.fold folder Map.empty let parseInstruction row = let matches = Regex.Match(row, "move ([0-9]+) from ([0-9]+) to ([0-9])+") {howMany = matches.Groups[1].Value |> int; fromWhere = matches.Groups[2].Value |> int; toWhere = matches.Groups[3].Value |> int } let instructions = data |> Seq.skipWhile (fun c-> c.Trim() <> "") |> Seq.skip 1 |> Seq.map parseInstruction (map, instructions) let move listAction (map:Map<int, char list>) instruction = let toStack = map |> Map.find instruction.toWhere let fromStack = map |> Map.find instruction.fromWhere let taken, rest = fromStack |> List.splitAt instruction.howMany map |> Map.add instruction.fromWhere rest |> Map.add instruction.toWhere ((taken |> listAction) @ toStack) let map, instructions = parse let task task' = instructions |> Seq.fold (move task') map |> Map.map (fun _ -> List.head) |> Map.toList |> List.sortBy fst |> List.map snd |> List.toArray |> String; printfn "Task 1: %s" (task List.rev) printfn "Task 2: %s" (task (List.skip 0))

Dold text
Visa signatur

Jag Àr en optimist; det Àr aldrig sÄ dÄligt sÄ att det inte kan bli sÀmre.

PermalÀnk
Medlem
●

Dag: 5
SprÄk: Java
Lösning: ...

uph.

public class DayFive { public static void main(String[] args) { List<String> crates = new ArrayList<>(); List<String> instructions = new ArrayList<>(); try { File file = new File("C:\\AoC 22\\inputDay5.txt"); FileReader filereader = new FileReader(file); BufferedReader bufferedreader = new BufferedReader(filereader); String line; while((line = bufferedreader.readLine()) != null) { if(line.contains("move")) instructions.add(line); else crates.add(line); } filereader.close(); } catch(IOException e) { e.printStackTrace(); } List<Stack<Character>> stackList = new ArrayList<>(); Stack<Character> one = new Stack<>(); Stack<Character> two = new Stack<>(); Stack<Character> three = new Stack<>(); Stack<Character> four = new Stack<>(); Stack<Character> five = new Stack<>(); Stack<Character> six = new Stack<>(); Stack<Character> seven = new Stack<>(); Stack<Character> eight = new Stack<>(); Stack<Character> nine = new Stack<>(); stackList.add(one); stackList.add(two); stackList.add(three); stackList.add(four); stackList.add(five); stackList.add(six); stackList.add(seven); stackList.add(eight); stackList.add(nine); for(int i = crates.size()-1; i >= 0; i--) { String temp = crates.get(i); for(int j = 0; j <= temp.length()-1; j++) { if(Character.isAlphabetic(temp.charAt(j)) && !Character.isDigit(temp.charAt(j))) { if(j == 1) one.push(temp.charAt(j)); else if(j == 5) two.push(temp.charAt(j)); else if(j == 9) three.push(temp.charAt(j)); else if(j == 13) four.push(temp.charAt(j)); else if(j == 17) five.push(temp.charAt(j)); else if(j == 21) six.push(temp.charAt(j)); else if(j == 25) seven.push(temp.charAt(j)); else if(j == 29) eight.push(temp.charAt(j)); else if(j == 33) nine.push(temp.charAt(j)); } } } List<String> instructionsclean = new ArrayList<>(); for(int i = 0; i < instructions.size(); i++) { String temp = instructions.get(i); temp = temp.replace("move ", ""); temp = temp.replace("from ", ""); temp = temp.replace("to ", ""); instructionsclean.add(temp); } for(int i = 0; i < instructionsclean.size(); i++) { String temp = instructionsclean.get(i); int move = Integer.parseInt(temp.substring(0, temp.indexOf(' '))); int from = Integer.parseInt(temp.substring(temp.indexOf(' ')+1, temp.indexOf(' ')+2)); int to = Integer.parseInt(temp.substring(temp.indexOf(' ')+3, temp.length())); for(int m = 1; m <= move; m++) { char chara = stackList.get(from-1).pop(); stackList.get(to-1).push(chara); } } System.out.println("part one: " + stackList.get(0).peek() + " " + stackList.get(1).peek() + " " + stackList.get(2).peek() + " " + stackList.get(3).peek() + " " + stackList.get(4).peek() + " " + stackList.get(5).peek() + " " + stackList.get(6).peek() + " " + stackList.get(7).peek() + " " + stackList.get(8).peek()); /* * resetting stacks */ stackList.get(0).removeAllElements(); stackList.get(1).removeAllElements(); stackList.get(2).removeAllElements(); stackList.get(3).removeAllElements(); stackList.get(4).removeAllElements(); stackList.get(5).removeAllElements(); stackList.get(6).removeAllElements(); stackList.get(7).removeAllElements(); stackList.get(8).removeAllElements(); for(int i = crates.size()-1; i >= 0; i--) { String temp = crates.get(i); for(int j = 0; j <= temp.length()-1; j++) { if(Character.isAlphabetic(temp.charAt(j)) && !Character.isDigit(temp.charAt(j))) { if(j == 1) one.push(temp.charAt(j)); else if(j == 5) two.push(temp.charAt(j)); else if(j == 9) three.push(temp.charAt(j)); else if(j == 13) four.push(temp.charAt(j)); else if(j == 17) five.push(temp.charAt(j)); else if(j == 21) six.push(temp.charAt(j)); else if(j == 25) seven.push(temp.charAt(j)); else if(j == 29) eight.push(temp.charAt(j)); else if(j == 33) nine.push(temp.charAt(j)); } } } for(int i = 0; i < instructionsclean.size(); i++) { String temp = instructionsclean.get(i); int move = Integer.parseInt(temp.substring(0, temp.indexOf(' '))); int from = Integer.parseInt(temp.substring(temp.indexOf(' ')+1, temp.indexOf(' ')+2)); int to = Integer.parseInt(temp.substring(temp.indexOf(' ')+3, temp.length())); List<Character> tempList = new ArrayList<>(); for(int m = 1; m <= move; m++) { char chara = stackList.get(from-1).remove(stackList.get(from-1).size()-1); tempList.add(chara); } for(int k = tempList.size()-1; k >= 0; k--) stackList.get(to-1).push(tempList.get(k)); tempList.clear(); } System.out.println("part two: " + stackList.get(0).peek() + " " + stackList.get(1).peek() + " " + stackList.get(2).peek() + " " + stackList.get(3).peek() + " " + stackList.get(4).peek() + " " + stackList.get(5).peek() + " " + stackList.get(6).peek() + " " + stackList.get(7).peek() + " " + stackList.get(8).peek()); }

Dold text
PermalÀnk
Medlem ★
●

Dag 5
SprÄk C#

Nu börjar man kÀnna igen den, textparsningsmisÀren. NÄja, jag Àr vÀl ÀndÄ hyfsat nöjd med hur det blev till slut (iaf nu efter att jag gÄtt över den igen nu ikvÀll)

Kod:

using var sr = new StreamReader("input.txt"); bool is_orders = false; Stack<string> the_stack = new(); List<Stack<string>> stacks_pt1 = new(); List<Stack<string>> stacks_pt2 = new(); while (!sr.EndOfStream) { var line = sr.ReadLine()!; if (string.IsNullOrEmpty(line)) { is_orders = true; int num = int.Parse(the_stack.Pop()[^2..]); for (int i = 0; i < num; i++) { stacks_pt1.Add(new()); stacks_pt2.Add(new()); } while (the_stack.Any()) { stackify(the_stack.Pop()); } continue; } if (!is_orders) { the_stack.Push(line); } else { operate_crane(line); } } Console.Write("Part 1: "); printresult(stacks_pt1); Console.Write("Part 2: "); printresult(stacks_pt2); void operate_crane(string order) { var splat = order.Split(' '); int crates = int.Parse(splat.ElementAt(1)); int from = int.Parse(splat.ElementAt(3)) -1; int to = int.Parse(splat.ElementAt(5)) -1; Stack<string> tempstack = new(); for (int i = 0; i < crates; i++) { stacks_pt1.ElementAt(to).Push(stacks_pt1.ElementAt(from).Pop()); tempstack.Push(stacks_pt2.ElementAt(from).Pop()); } while (tempstack.Any()) { stacks_pt2.ElementAt(to).Push(tempstack.Pop()); } } void stackify(string line) { int last_stack_line_position = line.Length; int linepos = 1; int stacklistelement = 0; while (linepos <= last_stack_line_position) { if (line[linepos] != ' ') { stacks_pt1.ElementAt(stacklistelement).Push($"{line[linepos]}"); stacks_pt2.ElementAt(stacklistelement).Push($"{line[linepos]}"); } linepos += 4; stacklistelement++; } } void printresult(List<Stack<string>> stacks) { foreach (var row in stacks) { Console.Write(row.Peek()); } Console.WriteLine(); }

Dold text
Visa signatur

The power of GNU compiles you!
"Often statistics are used as a drunken man uses lampposts -- for support rather than illumination."

PermalÀnk
Medlem
●
Skrivet av Yoshman:

Inte nödvÀndigtvis. Testade pÄ en i7-8559U (Intel NUC, men tror det Àr en CPU Àven Apple anvÀnt i MBP) och den Àr ibland snabbare om man enbart sjÀlva berÀkningen i lÀgen dÀr berÀkningen Àr trivial/vÀldigt enkel.

NÀr nÄgot Àr enkelt och samtidigt inte innehÄller massiv mÀngd parallellism pÄ instruktionsnivÄ slÄr högre frekvens "bredare" design.

I samma problem, mÀter man istÀllet hela flödet, d.v.s. inklusive parsing, Àr M1 vÀsentligt mycket snabbare Àn i7-8559U. Ser samma sak med dagens problem, sjÀlva berÀkningen Àr vÀldigt serialiserad och Àr snabbare pÄ i7-8559U (som klockar 4,5 GHz) medan hela flödet Àr klart snabbare pÄ M1

Sen finns Go-specifika orsaker: i de senaste versionerna har man gjort förÀndringar som pÄverkat prestanda rÀtt ordentligt. Vissa av dessa förÀndringar Àr CPU-arkitekturspecifika dÀr x86_64 fick vissa optimeringar versionen innan de kom till ARM64. Det handlar om upp mot 20 % prestandaökningar!

Tack för ett informativt svar!

PermalÀnk
Medlem
●

Dag: 5
SprÄk: Go

Parsningen tog en stund att knÀcka idag. Och sÄ rÄkade jag lösa del 2 först, sÄ jag kÀnde igen svaren nÀr jag kom dit :p. Benchtestet nedan innehÄller en kopiering av crates "objektet".

go test -bench=. ./...
goos: darwin
goarch: amd64
pkg: aoc2022/05/a
cpu: Intel(R) Core(TM) i7-7920HQ CPU @ 3.10GHz
BenchmarkPartOne-8 153040 6949 ns/op
BenchmarkPartTwo-8 218338 5360 ns/op
PASS
ok aoc2022/05/a 2.607s

package main import ( "bufio" "fmt" "os" "strings" ) type Instruction struct { Count int From int To int } func getResult(crateStacks [][]rune) string { result := "" for _, stack := range crateStacks { result += string(stack[len(stack)-1:]) } return result } func reverse(r []rune) { for i, j := 0, len(r)-1; i < j; i, j = i+1, j-1 { r[i], r[j] = r[j], r[i] } } func moveCrates(crateStacks [][]rune, instructions []Instruction, preservePickOneByOneOrder bool) { for _, inst := range instructions { fromStack := crateStacks[inst.From] stackIndex := len(fromStack) - inst.Count lastCrates := fromStack[stackIndex:] // get last crateStacks[inst.From] = fromStack[:stackIndex] // remove last if preservePickOneByOneOrder { reverse(lastCrates) } crateStacks[inst.To] = append(crateStacks[inst.To], lastCrates...) } } func getPartOne(crateStacks [][]rune, instructions []Instruction) string { moveCrates(crateStacks, instructions, true) result := getResult(crateStacks) return result } func getPartTwo(crateStacks [][]rune, instructions []Instruction) string { moveCrates(crateStacks, instructions, false) result := getResult(crateStacks) return result } func getRows(filename string) ([][]rune, []Instruction) { file, err := os.Open(filename) if err != nil { panic(err) } defer file.Close() scanner := bufio.NewScanner(file) crateStacks := make([][]rune, 0) instructions := make([]Instruction, 0) for scanner.Scan() { row := scanner.Text() if strings.Contains(row, "[") { for i := 1; i < len(row); i += 4 { j := (i - 1) / 4 if j+1 > len(crateStacks) { crateStacks = append(crateStacks, make([]rune, 0)) } if string(row[i]) != " " { crateStacks[j] = append(crateStacks[j], int32(row[i])) } } } else if strings.Contains(row, "move") { var inst Instruction fmt.Sscanf(row, "move %d from %d to %d", &inst.Count, &inst.From, &inst.To) inst.From -= 1 inst.To -= 1 instructions = append(instructions, inst) } } // Reverse the crateStack for _, crateStack := range crateStacks { reverse(crateStack) } return crateStacks, instructions } func main() { fmt.Println("Part one:", getPartOne(getRows("../input.txt"))) fmt.Println("Part two:", getPartTwo(getRows("../input.txt"))) }

Dold text
PermalÀnk
Medlem ★
●

Dag 5 i Kotlin, nu börjar det bli fult pÄ ögat.

data class Crate(val crateMarking: Char) data class CrateStack(val stack: ArrayDeque<Crate>) data class MoveInstruction(val numberToMove: Int, val target: Int, val destination: Int) fun run() { val input = File("src/input/day5.txt").readText() val inputParts = input.split("\r\n\r\n") val crates = inputParts[0] val instructions = inputParts[1] val rowsFromBottom = crates.split("\n").reversed() val numberOfStacks = rowsFromBottom.first().trim().last().digitToInt() val part1Lambda = {moves: Int, targetStack: CrateStack, destinationStack: CrateStack -> for (i in 1..moves) { destinationStack.stack.addFirst(targetStack.stack.removeFirst()) } } val part2Lambda = {moves: Int, targetStack: CrateStack, destinationStack: CrateStack -> val tempCrateStack = ArrayDeque<Crate>() for (i in 1..moves) { val topCrate = targetStack.stack.removeFirst() tempCrateStack.add(topCrate) } repeat(tempCrateStack.size) { destinationStack.stack.addFirst(tempCrateStack.removeLast()) } } println(solver(part1Lambda, instructions, getCrates(rowsFromBottom, numberOfStacks))) println(solver(part2Lambda, instructions, getCrates(rowsFromBottom, numberOfStacks))) } private fun getCrates(rowsFromBottom: List<String>, numberOfStacks: Int): List<CrateStack> { val stacks = IntRange(1, numberOfStacks).map { CrateStack(ArrayDeque()) } rowsFromBottom.drop(1).forEach { row -> for ((currentStack, i) in (1..row.length step 4).withIndex()) { val crateMarking = row[i] if (crateMarking.isLetter()) { val crate = Crate(crateMarking) stacks[currentStack].stack.addFirst(crate) } } } return stacks } private fun solver(lambda: (Int,CrateStack, CrateStack) -> Unit, moveInstructions: String, stacks:List<CrateStack>): String { buildMoveCrateInstruction(moveInstructions).forEach { instruction -> val targetStack = stacks[instruction.target - 1] val destinationStack = stacks[instruction.destination - 1] lambda(instruction.numberToMove, targetStack, destinationStack) } return stacks.map { it.stack.first().crateMarking }.toString() } private fun buildMoveCrateInstruction(moveInstructions: String): List<MoveInstruction> { val instructionParts = moveInstructions.split("\r\n").map { it.split(" ") } return instructionParts.map { MoveInstruction(it[1].toInt(), it[3].toInt(), it.last().toInt()) } }

Dold text
PermalÀnk
Medlem ★
●

Dag: 5
SprÄk: Kotlin

Blev inte sÄ snyggt, och hade svÄrt att göra denna uppgift utan att mutera en massa, men det fungerar.

// Parse the instruction strings and create instruction objects val instructionList = instructions.lines() .map { Regex("([0-9]+)").findAll(it).map { it.value }.toList() } .map { Instruction(it[0].toInt(), it[1].toInt(), it[2].toInt()) } println("Part 1: ${part1Day5(stack, instructionList)} Part 2:${part2Day5(stack, instructionList)}") } data class Instruction(val number: Int, val from: Int, val to: Int) // Create a list of "stack" lists corresponding to the given initial crate positions. fun crateSetup(stack: String) = stack.lines().reversed().flatMap { it.withIndex().toList() } .groupBy(keySelector = { it.index }, valueTransform = {it.value}) .map { it.value.filter { it.isLetter() } }.filter { it.isNotEmpty() }.map { it.toMutableList() } // Order a copy of the crate stacks, mutate according to the instructions. Return the top element char in each stack fun part1Day5(stack: String, instructionList: List<Instruction>): String { val stackList = crateSetup(stack) for (instruction in instructionList) { for (i in 0 until instruction.number) { stackList[instruction.to - 1].add(stackList[instruction.from - 1].removeLast()) } } return stackList.map { it.last() }.joinToString("") } fun part2Day5(stack: String, instructionList: List<Instruction>): String { val stackList = crateSetup(stack) for (instruction in instructionList) { val position = stackList[instruction.from - 1].size - instruction.number for (i in 0 until instruction.number) { stackList[instruction.to - 1].add(stackList[instruction.from - 1].removeAt(position)) } } return stackList.map { it.last() }.joinToString("") }

Dold text
Visa signatur

i5-7600k . GTX 1080 . 16 GB

PermalÀnk
Medlem
●

Dag: 5
SprÄk: Scala
SÄg att jag skrev fel dag i förra inlÀgget. Det hÀr Àr dag 5 pÄ riktigt.
Dagens uppgift kÀndes lite trÄkig sÄ nöjde mig med att bara plocka fram rÀtt svar utan att snygga till koden.

val input = Using.resource(Source.fromFile("""5.txt"""))(_.getLines().toVector) val (crates, moves) = input.span(_ != "") val crates2 = crates.map(str => (1 to str.length by 4).map(str)).transpose.map(_.dropWhile(_ == ' ').init) moves.foldLeft(crates2) { (state, move) => move match case s"move $amount from $from to $to" => val (fst, snd) = state(from.toInt - 1).splitAt(amount.toInt) state.updated(from.toInt - 1, snd).updated(to.toInt - 1, fst.reverse ++ state(to.toInt - 1)) case _ => state }.map(_.head).mkString moves.foldLeft(crates2) { (state, move) => move match case s"move $amount from $from to $to" => val (fst, snd) = state(from.toInt - 1).splitAt(amount.toInt) state.updated(from.toInt - 1, snd).updated(to.toInt - 1, fst ++ state(to.toInt - 1)) case _ => state }.map(_.head).mkString

Skiljer bara en .reverse mellan del1 och del2.

Dold text
PermalÀnk
●

Dag: 5
SprÄk: Haskell

Inte sÄ nöjd idag, det hÀr Àr kanske pÄ grÀnsen till vad jag klarar av.

Idag blev parsningen Ànnu fulare Àn igÄr. Usch, kolla funktionen readMoves.

-- The program expects the input on stdin, ie -- $ ./solve < input import Data.Char (isDigit, isUpper) main = interact solve solve :: String -> String solve input = "Problem 1: " ++ show (map head finalCratesPt1) ++ "\n" ++ "Problem 2: " ++ show (map head finalCratesPt2) ++ "\n" where finalCratesPt1 = foldr doMovePt1 crates moves finalCratesPt2 = foldr doMovePt2 crates moves crates = filter (not.null) (map (filter isUpper) (transpose cratesInput)) moves = reverse (map readMove (filter (not.null) movesInput)) (cratesInput, movesInput) = break null (lines input) -- Some types for readability. data Move = Move {num::Int, from::Int, to::Int} deriving (Show) type Crates = [String] type Stack = String transpose :: [[a]] -> [[a]] transpose ([]:_) = [] transpose x = (map head x) : transpose (map tail x) -- Parse the strings from the problem input. readMove :: String -> Move readMove s = Move a b c where a = read (takeWhile isDigit (dropWhile (not.isDigit) s)) b = read (takeWhile isDigit (dropWhile (not.isDigit) (dropWhile isDigit (dropWhile (not.isDigit) s)))) c = read (takeWhile isDigit (dropWhile (not.isDigit) (dropWhile isDigit (dropWhile (not.isDigit) (dropWhile isDigit (dropWhile (not.isDigit) s)))))) -- Remove a number of crates from a specific target stack. popStack :: Move -> Crates -> (Crates, Stack) popStack move crates = (before ++ [remaining] ++ after, removed) where (before, target:after) = splitAt ((from move)-1) crates (removed, remaining) = splitAt (num move) target -- Place a number of crates on a specific target stack. pushStack :: Move -> Stack -> Crates -> Crates pushStack move moved crates = before ++ [moved ++ target] ++ after where (before, target:after) = splitAt ((to move)-1) crates -- Perform a move while reversing the crates, for part 1. doMovePt1 :: Move -> Crates -> Crates doMovePt1 move crates = pushStack move (reverse moved) crates_ where (crates_, moved) = popStack move crates -- Perform a move, without reversing the crates, for part 2. doMovePt2 :: Move -> Crates -> Crates doMovePt2 move crates = pushStack move moved crates_ where (crates_, moved) = popStack move crates

(Jag anvÀnder highlight som finns i apt för syntaxfÀrgning.)

Dold text
PermalÀnk
Medlem ★
●

Dag: 5
SprÄk: VB.Net

edit: Snyggade till koden lite

Imports System.IO Module Program Sub Main(args As String()) Dim input = File.ReadAllLines("input.txt") Dim stacks = resetStacks(input) Dim instructionStart = Array.FindIndex(input, Function(line) line.Contains("move")) For i = instructionStart To input.Length - 1 Step 1 Dim instruction = input(i).Split(" ") For j = 1 To Integer.Parse(instruction(1)) Step 1 stacks(Integer.Parse(instruction(5)) - 1).Push(stacks(Integer.Parse(instruction(3)) - 1).Pop()) Next Next Dim part1 As String = "" For Each stack In stacks part1 = part1 & stack.Peek Next stacks = resetStacks(input) Dim crane As New Stack(Of Char) For i = instructionStart To input.Length - 1 Step 1 Dim instruction = input(i).Split(" ") For j = 1 To Integer.Parse(instruction(1)) Step 1 crane.Push(stacks(Integer.Parse(instruction(3)) - 1).Pop()) Next For j = 1 To Integer.Parse(instruction(1)) Step 1 stacks(Integer.Parse(instruction(5)) - 1).Push(crane.Pop()) Next Next Dim part2 As String = "" For Each stack In stacks part2 = part2 & stack.Peek Next Console.WriteLine(part1) Console.WriteLine(part2) End Sub Function resetStacks(input As String()) As List(Of Stack(Of Char)) Dim stacks As New List(Of Stack(Of Char)) Dim stacksEnd = Array.FindIndex(input, Function(line) (Not line.Contains("["))) For i = 0 To ((input(0).Length - 3) / 4) Step 1 stacks.Add(New Stack(Of Char)) Next For i = stacksEnd - 1 To 0 Step -1 If Not String.IsNullOrWhiteSpace(input(i)(1)) Then stacks(0).Push(input(i)(1)) End If For j = 1 To stacks.Count - 1 Step 1 If Not String.IsNullOrWhiteSpace(input(i)(1 + (j * 4))) Then stacks(j).Push(input(i)(1 + (j * 4))) End If Next Next Return stacks End Function End Module

Dold text
PermalÀnk
Medlem
●

Dag: 5
SprÄk: Go
Lösning:

package main import ( "fmt" "os" "strconv" "strings" ) func getMoves(input string) (int, []string) { var crateRows int //Count on which row there's a double linebreak for i, ch := range input { if ch == '\n' && input[i+1] != '\n' { crateRows++ } if ch == '\n' && input[i+1] == '\n' { break } } //Return number of rows and the moves moves := strings.Split(input, "\n")[crateRows+2:] return crateRows, moves } // Function to get the letters from each "crate" func splitToStacks(input string, crateRows int) [][]string { rows := strings.Split(input, "\n")[0:crateRows] crateRow := strings.Split(input, "\n")[crateRows] numCrates, _ := strconv.Atoi(string(crateRow[len(crateRow)-2])) stacks := make([][]string, numCrates+1) for i := len(rows) - 1; i >= 0; i-- { k := 1 for j := 1; j < len(rows[0])-1; j += 4 { if string(rows[i][j]) != " " { stacks[k] = append(stacks[k], string(rows[i][j])) } k++ } } return stacks } func splitMoves(moves []string) [][]int { toret := make([][]int, len(moves)) for i := 0; i < len(moves); i++ { //Split each move into numbers move := strings.Split(moves[i], " ") tempNum, _ := strconv.Atoi(move[1]) tempFrom, _ := strconv.Atoi(move[3]) tempTo, _ := strconv.Atoi(move[5]) //Save the numbers to an array toret[i] = append(toret[i], tempNum) toret[i] = append(toret[i], tempFrom) toret[i] = append(toret[i], tempTo) } return toret } func MakeMoves1(stacks [][]string, moves [][]int) [][]string { for i := 0; i < len(moves); i++ { num := moves[i][0] from := moves[i][1] to := moves[i][2] //Move the correct number of letters from the "from" stack to the "to" stack for j := 0; j < num; j++ { stacks[to] = append(stacks[to], stacks[from][len(stacks[from])-1]) stacks[from] = stacks[from][:len(stacks[from])-1] } } return stacks } func MakeMoves2(stacks [][]string, moves [][]int) [][]string { for i := 0; i < len(moves); i++ { num := moves[i][0] from := moves[i][1] to := moves[i][2] //Move letters from the "from" stack to the "to" stack in batches on "num" stacks[to] = append(stacks[to], stacks[from][len(stacks[from])-num:]...) stacks[from] = stacks[from][:len(stacks[from])-num] } return stacks } func printLast(stacks [][]string) { for i := 1; i < len(stacks); i++ { fmt.Print(stacks[i][len(stacks[i])-1]) } } func main() { input, _ := os.ReadFile("input.txt") inputString := string(input) //Find separator between crates and moves crateRows, tempmoves := getMoves(inputString) //Get the crate letters into an array per collumn stacks := splitToStacks(inputString, crateRows) //Split moverows into pure numbers moves := splitMoves(tempmoves) //Create stack for first method stacks1 := MakeMoves1(stacks, moves) //Need to recreate stacks because MakeMoves1 changes the original stacks = splitToStacks(inputString, crateRows) //Create stack for second method stacks2 := MakeMoves2(stacks, moves) //Print last element of each stack printLast(stacks1) fmt.Println() printLast(stacks2) }

Dold text
Visa signatur

Citera sÄ hittar jag tillbaks och kan ge svar.

PermalÀnk
Medlem ★
●

Dag 5
SprÄk: Node (js)

Tycker det Àr lite halvtradigt nÀr dom meckar till parsingen, det Àr inte riktigt dÀr jag tycker om att lÀgga tid pÄ dessa.

import { data, testData } from "../input/day5.js"; function getData(rawData) { let instructions; let input; [input, instructions] = data.split('\n\n'); input = input.split('\n'); const matris = []; for (const line of input) { if (line.substring(0, 3) === ' 1 ') { break; } for (let i = 1; i <= line.length; i+=4) { if (line[i] === ' ') continue; else { const n = Math.round(i / 4); while (matris.length <= n) { matris.push([]); } matris[n].push(line[i]) } } } for (let i = 0; i < matris.length; i++) { matris[i] = matris[i].reverse(); } instructions = instructions .split('\n').map(row => row .split(' ') .filter(n => n .match(/[0-9]+/g)) .map(n => parseInt(n))); return { matris, instructions } } function getVisibleCrates(matris) { let str = ''; for (let i = 0; i < matris.length; i++) { str += matris[i].at(-1); } return str; } const solutionA = () => { const { matris, instructions } = getData(data); for (const instruction of instructions) { const [amount, from, to] = instruction; for (let i = 0; i < amount; i++) { matris[to - 1].push(...matris[from - 1].pop()); } } console.log(getVisibleCrates(matris)); } const solutionB = () => { const { matris, instructions } = getData(data); for (const instruction of instructions) { const [amount, from, to] = instruction; matris[to - 1].push(...matris[from - 1].splice(-amount)); } console.log(getVisibleCrates(matris)); } export { solutionA, solutionB };

Dold text
PermalÀnk
Medlem ★
●

Dag: 5
SprÄk: C++

Blev ingen vidare tjusig lösning idag, parsningen stÀllde till det lite. Hade ocksÄ en size_t som datatyp i en for loop som subtraherade ner till 0:

for (size_t j = rowIndex - 1; j >= 0; j--)

vilket resulterar i en underflow vilket var lite störigt att felsöka innan jag insÄg mitt misstag

#include "../AoCHelper/AoCHelper.h" #include <vector> #include <stack> void puzzle_one(std::vector<std::string> &input) { bool parseStacks{true}; std::vector<std::stack<char>> stacks{}; for (size_t i = 0; i <= 9; i++) { stacks.push_back(std::stack<char>()); // 0 will be unused } for (size_t rowIndex = 0; rowIndex < input.size(); rowIndex++) { std::string row = input[rowIndex]; if (parseStacks) { if (row.find(" 1 2 3 ") == std::string::npos) { continue; } parseStacks = false; for (size_t i = 1; (i + 1) < row.size(); i += 4) { for (int j = rowIndex - 1; j >= 0; j--) { if (input[j][i] != ' ') { stacks[(i / 4) + 1].push(input[j][i]); } } } } else { if (row.find("move") == std::string::npos) { continue; } auto splitRow = (myLib::split(row, ' ')); int amount = std::stoi(splitRow[1]); int from = std::stoi(splitRow[3]); int to = std::stoi(splitRow[5]); for (int i = 0; i < amount; i++) { stacks[to].push(stacks[from].top()); stacks[from].pop(); } } } std::string answer{}; for (size_t i = 1; i <= 9; i++) { if (!stacks[i].empty()) { answer.push_back(stacks[i].top()); } } std::cout << "Puzzle one: " << answer << std::endl; } void puzzle_two(std::vector<std::string> &input) { bool parseStacks{true}; std::vector<std::stack<char>> stacks{}; for (size_t i = 0; i <= 9; i++) { stacks.push_back(std::stack<char>()); // 0 will be unused } for (size_t rowIndex = 0; rowIndex < input.size(); rowIndex++) { std::string row = input[rowIndex]; if (parseStacks) { if (row.find(" 1 2 3 ") == std::string::npos) { continue; } parseStacks = false; for (size_t i = 1; (i + 1) < row.size(); i += 4) { for (int j = rowIndex - 1; j >= 0; j--) { if (input[j][i] != ' ') { stacks[(i / 4) + 1].push(input[j][i]); } } } } else { if (row.find("move") == std::string::npos) { continue; } const auto splitRow = (myLib::split(row, ' ')); const int amount = std::stoi(splitRow[1]); const int from = std::stoi(splitRow[3]); const int to = std::stoi(splitRow[5]); std::stack<char> tempStack{}; for (int i = 0; i < amount; i++) { tempStack.push(stacks[from].top()); stacks[from].pop(); } for (int i = 0; i < amount; i++) { stacks[to].push(tempStack.top()); tempStack.pop(); } } } std::string answer{}; for (size_t i = 1; i <= 9; i++) { if (!stacks[i].empty()) { answer.push_back(stacks[i].top()); } } std::cout << "Puzzle two: " << answer << std::endl; } int main() { std::vector<std::string> exampleInput{ " [D] ", "[N] [C] ", "[Z] [M] [P]", " 1 2 3 ", "", "move 1 from 2 to 1", "move 3 from 1 to 3", "move 2 from 2 to 1", "move 1 from 1 to 2" }; AoCHelper a1{"2022", "5"}; std::vector<std::string> result = a1.get_input(); puzzle_one(result); puzzle_two(result); }

Dold text
PermalÀnk
Medlem
●

Dag: 5
SprÄk: C#

using AOC.Helpers.Extensions; using System.Text.RegularExpressions; namespace AOC2022.Puzzles; internal partial class Puzzle5 : Puzzle<string> { [GeneratedRegex(@move (\d+) from (\d+) to (\d+))] private static partial Regex InstructionRegex(); [GeneratedRegex(@\[(.)\])] private static partial Regex CrateRegex(); protected override void Solve(string[] lines) { One = SetupAndMoveCrates(lines, false); Two = SetupAndMoveCrates(lines, true); } private static string SetupAndMoveCrates(string[] lines, bool moveAsGroup) { var idx = lines.ToList().FindIndex(string.IsNullOrWhiteSpace); var crateLines = lines[..idx]; var instructions = lines[(idx + 1)..]; var stacks = Enumerable.Range(0, crateLines.Last().Last(char.IsDigit) - '0') .Select((x, stackIdx) => new Stack<char>(crateLines.Reverse().Skip(1) .Select(crateLine => crateLine .Chunk(4) .Skip(stackIdx) .Select(crateStr => CrateRegex().Match(string.Concat(crateStr)) .Groups.Values.Last().Value.FirstOrDefault()) .FirstOrDefault()) .Where(x => x > 0))) .ToArray(); MoveCrates(instructions, stacks, moveAsGroup); return string.Concat(stacks.Select(x => x.Peek())); } private static void MoveCrates(IEnumerable<string> instructions, Stack<char>[] stacks, bool moveAsGroup) { foreach (var instruction in instructions) { var values = InstructionRegex().Match(instruction).Groups.Values .Skip(1).Select(x => int.Parse(x.Value)).ToList(); var (amount, from, to) = (values[0], values[1], values[2]); var crates = Enumerable.Range(0, amount).Select(_ => stacks[from - 1].Pop()); if (moveAsGroup) crates = crates.Reverse(); stacks[to - 1].PushRange(crates); } } }

Dold text
PermalÀnk
Medlem
●

Dag: 5
SprÄk: C

#include <errno.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #define ARRAY_LEN(x) (sizeof(x) / sizeof((x)[0])) #define MAX_CRATES 128 #define MAX_PILES 9 struct pile { char c[MAX_CRATES]; int n; }; struct pile p[MAX_PILES]; struct pile p2[MAX_PILES]; void parsePiles(char *line, ssize_t len) { int idx = 0, chr = 0; while(++chr < len) { if (line[chr] == ' ') { idx++; chr += 3; continue; } memmove(p[idx].c+1, p[idx].c, p[idx].n); p[idx].c[0] = line[chr]; p[idx].n++; idx++; chr+=3; } } void doMoves(char *line) { int n, from, to; if (sscanf(line, "move %d from %d to %d\n", &n, &from, &to) != 3) exit(EXIT_FAILURE); from--; to--; // Part 1 for (int i=0; i<n; i++) p[to].c[p[to].n++] = p[from].c[--p[from].n]; // Part 2 p2[from].n -= n; memcpy(&p2[to].c[p2[to].n], &p2[from].c[p2[from].n], n); p2[to].n += n; } int main(void) { char *line = NULL; size_t len = 0; ssize_t nread; FILE *fp = fopen("d5_input.txt", "r"); if (!fp) { perror("Failed to open file"); exit(EXIT_FAILURE); } while ((nread = getline(&line, &len, fp)) != -1) { if (!strcmp(line, "\n")) break; if (strncmp(line, " ", 3) && strncmp(line, "[", 1)) continue; parsePiles(line, nread); } memcpy(p2, p, sizeof(p)); while ((nread = getline(&line, &len, fp)) != -1) doMoves(line); printf("Answer string for part 1: "); for (int i=0; i<ARRAY_LEN(p); i++) putchar(p[i].c[p[i].n-1]); putchar('\n'); printf("Answer string for part 2: "); for (int i=0; i<ARRAY_LEN(p2); i++) putchar(p2[i].c[p2[i].n-1]); putchar('\n'); free(line); fclose(fp); exit(EXIT_SUCCESS); }

Dold text
sscanf