🌟 Advent of Code (AoC) 2020 🌟

PermalÀnk
Medlem ★
●
Skrivet av GLaDER:

Dag: 14
SprÄk: Go
Lösning: Main,

Glöm inte att kika in pÄ vÄr leaderboard: 115994-59705230

NÀr det stod att talen var 36 bitar borde jag lÄtit bli att vara lat och köra pÄ med vanliga int; men Del 1 gick ju toppenbra utan att ta till 64-bitars-tal sÄ.... Aja. Dagens svÄraste grej, för mig, var att fixa sÄ att "001X0XX1" expanderades pÄ rÀtt sÀtt. Det slutade med, tycker jag, en ganska snygg lösning dÀr jag tar ÄteranvÀnde mitt favoritsÀtt att traversera trÀd.

Dold text

Dag: 15
SprÄk: Go
Lösning: Main

Glöm inte att kika in pÄ vÄr leaderboard: 115994-59705230

Idag tyckte jag att jag var ganska snabb. Som sig bör fick jag direkt en tanke pÄ hur jag borde lösa uppgiften men sen gick tankeprocessen ungefÀr sÄhÀr:

  1. Började lÀsa beskrivningen

  2. Ah! AnvÀnd en map för associera ett nummer med nÀr det senast anropades.

  3. lÀste vidare i beskrivningen

  4. Oh.. jag behöver hÄlla koll pÄ fler anrop Àn senaste, hm. ska nog anvÀnda en slice istÀllet för en map dÄ...

  5. Kodar lite.

  6. Inser att jag behöver min map för att associera numret med listan av anrop. BÄde map och slice alltsÄ!

  7. Kodar lite till.

  8. Yes! Snabb och snygg lösning. Första stjÀrnan pÄ plats ~3000! Det Àr min bÀsta sedan Day 1.

Sen la jag tvÄ timmar -- tvÄ timmar -- pÄ att anvÀnda en slice med lÀngd tvÄ (och hela tiden bara ha exakt de tvÄ tal jag behöver tillgÀngliga) istÀllet för en slice med godtycklig lÀngd. Tror aldrig jag haft sÄ hÀr mÄnga off-by-one errors... StjÀrna tvÄ: Plats ~7000.

Dold text
Visa signatur

:(){ :|:& };:

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

PermalÀnk
●

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

Det hÀr var lite antiklimaktiskt Hade förvÀntat mig mer, men man ska vÀl inte klaga

PermalÀnk
Datavetare ★
●

Dag: 15
SprÄk: Swift
Lösning: Github

Enda "smarta" jag gjorde var att notera att talet aldrig kan bli fler Àn antal rundor och i de flesta fall Àr det betydligt lÀgre. SÄ bÀsta prestanda fÄr man genom att rakt upp och ned köra en array för historia dÀr talet Àr index och vÀrdet Àr senaste rundan det nÀmndes.

Även med "för lite" fysiskt RAM blir det snabbt med en array dĂ„ majoriteten av array:en behöver bara virtuellt minne, men dĂ„ den aldrig anvĂ€nds behöver det aldrig backas av fysiskt RAM.

Att gÄ frÄn Dictionary<Int, Int> -> Array<Int> gav ~x4 speedup

➜ day15 git:(main) ✗ swift run -c release 🌟 Part 1 : 981 ⌚ Elapsed : 0 ms 🌟 Part 2 : 164878 ⌚ Elapsed : 398 ms

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: 15
SprÄk: Golang
Lösning:

Ska skriva om den senare för anvÀnda en array istÀllet..
Del1: 71”s
Del2: 2,5s

package main import ( "bufio" "fmt" "os" "strconv" "strings" ) func getLast(numbers []int, stop int) int { lastIndexes := map[int]int{} numberLen := len(numbers) for i := 1; i < numberLen; i++ { lastIndexes[numbers[i-1]] = i } last := numbers[numberLen-1:][0] for i := numberLen; i < stop; i++ { new := 0 if lastIndex, ok := lastIndexes[last]; ok { new = i - lastIndex } lastIndexes[last] = i last = new } return last } func getPartOne(numbers []int) int { return getLast(numbers, 2020) } func getPartTwo(numbers []int) int { return getLast(numbers, 30000000) } func getNumbers(filename string) []int { file, _ := os.Open(filename) defer file.Close() scanner := bufio.NewScanner(file) numbers := []int{} for scanner.Scan() { row := scanner.Text() fields := strings.Split(row, ",") for _, field := range fields { val, _ := strconv.Atoi(field) numbers = append(numbers, val) } } return numbers } func main() { numbers := getNumbers("../input.txt") fmt.Println("PartOne", getPartOne(numbers)) fmt.Println("PartTwo", getPartTwo(numbers)) }

Dold text
PermalÀnk
Medlem ★
●
Skrivet av gibbon_:

SÄ nu kan du fÄ svaret inom en dag kanske?

Feta steps Àr absolut rÀtt riktning

Om du hittat T dÀr buss 3 avgÄr, behöver du titta pÄ T+1 eller T+2?

Om du hittat T dÀr buss 3 OCH 5 avgÄr, behöver du titta pÄ T+3?

ytterligare
om du vill ha ytterligare en nudge

Yes, jag tittade pÄ en Kotlin-lösning frÄn Reddit som anvÀnde sig utav Chinese remainder theorem. Satt och försökte förstÄ, men det gick bara inte. BestÀmmer mig för att detta helt enkelt Àr överkurs för mig.

Sen nÀr jag kollade pÄ uppgiftsbeskrivningen för dag 14 fattade jag ingenting. Speciellt detta stycke:

Skrivet av AOC:

This program starts by specifying a bitmask (mask = ....). The mask it specifies will overwrite two bits in every written value: the 2s bit is overwritten with 0, and the 64s bit is overwritten with 1.

Skulle nÄn kunna förklara för mig vad som skall göras?

ÄndĂ„ rĂ€tt nöjd med att det tog 13 dagar innan jag blev helt sĂ€nkt.

Visa signatur

| Mobo: Gigabyte X570 GAMING X | CPU: AMD Ryzen 9 3900X + Dark Rock 4 | RAM: 32GB @ 3000MHz | GPU: Gigabyte RTX 3080 OC | PSU: Seasonic GX 850W | Chassi: NZXT S340 Elite Matte Black | M.2: Samsung 970 Evo 500GB & 1000GB | HDD: 4TB | Monitors: Acer Predator X34 GS & Acer XB270HU |

PermalÀnk
Medlem ★
●
Skrivet av Dave1080:

Skulle nÄn kunna förklara för mig vad som skall göras?

HÀr Àr exemplet med 11 lite mer utförligt:

Konvertera 11 till binÀrt (1011).
Skriv masken under. Fyll pÄ med nollor framför 1011 sÄ att de blir lika lÄnga.

value: 000000000000000000000000000000001011 (decimal 11) mask: XXXXXXXXXXXXXXXXXXXXXXXXXXXXX1XXXX0X result:

GÄ sedan frÄn höger till vÀnster, en siffra i taget.

Om mask-tecknet Àr X, ta siffran frÄn vÀrdet.
Om mask-tecknet Àr 0, ta 0.
Om mask-tecknet Àr 1, ta 1.

Mask-tecknet lÀngst till höger Àr X, sÄ dÄ tar vi 1:an lÀngst till höger i vÀrdet.

value: 000000000000000000000000000000001011 (decimal 11) mask: XXXXXXXXXXXXXXXXXXXXXXXXXXXXX1XXXX0X result: 1

NÀsta mask-tecken Àr 0. DÄ blir det alltid 0.

value: 000000000000000000000000000000001011 (decimal 11) mask: XXXXXXXXXXXXXXXXXXXXXXXXXXXXX1XXXX0X result: 01

Och sÄ vidare tills hela resultatet Àr ifyllt:

value: 000000000000000000000000000000001011 (decimal 11) mask: XXXXXXXXXXXXXXXXXXXXXXXXXXXXX1XXXX0X result: 000000000000000000000000000001001001

Det Ă€r alltsĂ„ sĂ„ som du “lĂ€gger ihop en mask och ett tal”. Sen Ă€r ju uppgiften lite mer Ă€n sĂ„, men detta kanske fĂ„r dig pĂ„ rĂ€tt spĂ„r?

PermalÀnk
Medlem ★
●
Skrivet av Dave1080:

Yes, jag tittade pÄ en Kotlin-lösning frÄn Reddit som anvÀnde sig utav Chinese remainder theorem. Satt och försökte förstÄ, men det gick bara inte. BestÀmmer mig för att detta helt enkelt Àr överkurs för mig.

Du behöver inte anvÀnda CRT för att lösa uppgiften Du har fÄtt nÄgra tips ovan om att loopa pÄ ett lite smartare sÀtt.

Skrivet av Dave1080:

Sen nÀr jag kollade pÄ uppgiftsbeskrivningen för dag 14 fattade jag ingenting. Speciellt detta stycke:

This program starts by specifying a bitmask (mask = ....). The mask it specifies will overwrite two bits in every written value: the 2s bit is overwritten with 0, and the 64s bit is overwritten with 1.

Skulle nÄn kunna förklara för mig vad som skall göras?

ÄndĂ„ rĂ€tt nöjd med att det tog 13 dagar innan jag blev helt sĂ€nkt.

Jag tycker att exemplet pÄ AoC hjÀlper mycket!

Om du fÄr följande som input:

mask = XXXXXXXXXXXXXXXXXXXXXXXXXXXXX1XXXX0X mem[8] = 11 mem[7] = 101 mem[8] = 0

ska vÀrdena 11, 101, och 0 modifieras av "masken" och det modifierade vÀrdet ska sedan skrivas till minnesadresserna 8, 7, och 8. (Ja, du kommer skriva över vÀrdet pÄ minnesadress 8.)

Sen fÄr man ett exempel pÄ hur sjÀlva maskningen ska gÄ till:

value: 000000000000000000000000000000001011 (decimal 11) mask: XXXXXXXXXXXXXXXXXXXXXXXXXXXXX1XXXX0X result: 000000000000000000000000000001001001 (decimal 73

Ovan har du talet 11 Ätergivet bÄde decimalt (bas 10) och pÄ binÀr form (bas 2). Om du kollar pÄ binÀrformen ser du att den Àr lika lÄng som masken. Du kan nu anvÀnda reglerna som Àr beskrivna av AoC för att fÄ fram ditt modifierade tal:

A 0 or 1 overwrites the corresponding bit in the value, while an X leaves the bit in the value unchanged.

NÀr jag skrev min kod löste jag det sÄhÀr:

mask = "" mem = dict() for row in input: if "mask" in row: mask = parseMask(row) else: addr, value = parseMemVal(row) mem[addr] = maskedValue(mask, value)

Kruxet Àr givetvis att skriva maskedValue(). SÀg till om du vill ha vidare guidning

Dold text
Typo.
Visa signatur

:(){ :|:& };:

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

PermalÀnk
Medlem
●
Skrivet av Yoshman:

Dag: 15
SprÄk: Swift
Lösning: Github

Enda "smarta" jag gjorde var att notera att talet aldrig kan bli fler Àn antal rundor och i de flesta fall Àr det betydligt lÀgre. SÄ bÀsta prestanda fÄr man genom att rakt upp och ned köra en array för historia dÀr talet Àr index och vÀrdet Àr senaste rundan det nÀmndes.

Även med "för lite" fysiskt RAM blir det snabbt med en array dĂ„ majoriteten av array:en behöver bara virtuellt minne, men dĂ„ den aldrig anvĂ€nds behöver det aldrig backas av fysiskt RAM.

Att gÄ frÄn Dictionary<Int, Int> -> Array<Int> gav ~x4 speedup

➜ day15 git:(main) ✗ swift run -c release 🌟 Part 1 : 981 ⌚ Elapsed : 0 ms 🌟 Part 2 : 164878 ⌚ Elapsed : 398 ms

Dold text

Om jag anvÀnder arrayer sÄ Àr jag nere pÄ:
Del1: 5”s
Del2: 750ms

Dold text
PermalÀnk
Datavetare ★
●
Skrivet av Flexbert:

Om jag anvÀnder arrayer sÄ Àr jag nere pÄ:
Del1: 5”s
Del2: 750ms

Dold text

Kan köra ditt ursprungliga program pÄ 1,7s (med min input, men det borde inte spela nÄgon roll). LÀrde mig att de fÄtt igÄng Go pÄ M1 Mac nu, endera vÀnta till nÀsta release av Go sÄ kommer det förpackat eller lÀs denna trÄd sÄ finns instruktioner för att bygga frÄn git. Det som Àr lite underförstÄtt Àr att man först mÄste ladda ner x86_64 versionen för MacOS, lÀgga den i PATH, sen kör man bootstrap scriptet och specificerar ARM64 som CPU och Darwin som OS.

$ file $(which go) /Volumes/Samsung_T5/go-darwin-arm64-bootstrap/bin/go: Mach-O 64-bit executable arm64

Du postade aldrig array-versionen va?

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
●
Skrivet av Yoshman:

Kan köra ditt ursprungliga program pÄ 1,7s (med min input, men det borde inte spela nÄgon roll). LÀrde mig att de fÄtt igÄng Go pÄ M1 Mac nu, endera vÀnta till nÀsta release av Go sÄ kommer det förpackat eller lÀs denna trÄd sÄ finns instruktioner för att bygga frÄn git. Det som Àr lite underförstÄtt Àr att man först mÄste ladda ner x86_64 versionen för MacOS, lÀgga den i PATH, sen kör man bootstrap scriptet och specificerar ARM64 som CPU och Darwin som OS.

$ file $(which go) /Volumes/Samsung_T5/go-darwin-arm64-bootstrap/bin/go: Mach-O 64-bit executable arm64

Du postade aldrig array-versionen va?

NÀ, hÀr har du den. Mitt bench-test Àr utan indatalÀsning.

main.go

package main import ( "bufio" "fmt" "os" "strconv" "strings" ) func getLast(numbers []int, stop int) int { lastIndexes := make([]int, stop) numberLen := len(numbers) for i := 1; i < numberLen; i++ { lastIndexes[numbers[i-1]] = i } last := numbers[numberLen-1:][0] for i := numberLen; i < stop; i++ { new := 0 if lastIndexes[last] != 0 { new = i - lastIndexes[last] } lastIndexes[last] = i last = new } return last } func getPartOne(numbers []int) int { return getLast(numbers, 2020) } func getPartTwo(numbers []int) int { return getLast(numbers, 30000000) } func getNumbers(filename string) []int { file, _ := os.Open(filename) defer file.Close() scanner := bufio.NewScanner(file) numbers := []int{} for scanner.Scan() { row := scanner.Text() fields := strings.Split(row, ",") for _, field := range fields { val, _ := strconv.Atoi(field) numbers = append(numbers, val) } } return numbers } func main() { numbers := getNumbers("../input.txt") fmt.Println("PartOne", getPartOne(numbers)) fmt.Println("PartTwo", getPartTwo(numbers)) }

main_test.go

package main import "testing" func BenchmarkPartOne(b *testing.B) { rows := getNumbers("../input.txt") for i := 0; i < b.N; i++ { getPartOne(rows) } } func BenchmarkPartTwo(b *testing.B) { rows := getNumbers("../input.txt") for i := 0; i < b.N; i++ { getPartTwo(rows) } }

go test --bench .

Dold text
PermalÀnk
Datavetare ★
●
Skrivet av Flexbert:

NÀ, hÀr har du den. Mitt bench-test Àr utan indatalÀsning.

main.go

package main import ( "bufio" "fmt" "os" "strconv" "strings" ) func getLast(numbers []int, stop int) int { lastIndexes := make([]int, stop) numberLen := len(numbers) for i := 1; i < numberLen; i++ { lastIndexes[numbers[i-1]] = i } last := numbers[numberLen-1:][0] for i := numberLen; i < stop; i++ { new := 0 if lastIndexes[last] != 0 { new = i - lastIndexes[last] } lastIndexes[last] = i last = new } return last } func getPartOne(numbers []int) int { return getLast(numbers, 2020) } func getPartTwo(numbers []int) int { return getLast(numbers, 30000000) } func getNumbers(filename string) []int { file, _ := os.Open(filename) defer file.Close() scanner := bufio.NewScanner(file) numbers := []int{} for scanner.Scan() { row := scanner.Text() fields := strings.Split(row, ",") for _, field := range fields { val, _ := strconv.Atoi(field) numbers = append(numbers, val) } } return numbers } func main() { numbers := getNumbers("../input.txt") fmt.Println("PartOne", getPartOne(numbers)) fmt.Println("PartTwo", getPartTwo(numbers)) }

main_test.go

package main import "testing" func BenchmarkPartOne(b *testing.B) { rows := getNumbers("../input.txt") for i := 0; i < b.N; i++ { getPartOne(rows) } } func BenchmarkPartTwo(b *testing.B) { rows := getNumbers("../input.txt") for i := 0; i < b.N; i++ { getPartTwo(rows) } }

go test --bench .

Dold text

$ go test --bench=. goos: darwin goarch: arm64 pkg: day15 BenchmarkPartOne-8 569848 2101 ns/op BenchmarkPartTwo-8 3 369253292 ns/op PASS ok day15 4.623s

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
●
Skrivet av Yoshman:

$ go test --bench=. goos: darwin goarch: arm64 pkg: day15 BenchmarkPartOne-8 569848 2101 ns/op BenchmarkPartTwo-8 3 369253292 ns/op PASS ok day15 4.623s

Snyggt, fÄr köpa mig en sÄdan. Den krossar ju min: Mbp 2017, 3,1 GHz Quad-Core Intel Core i7.

PermalÀnk
Medlem ★
●
Skrivet av lydell:

HÀr Àr exemplet med 11 lite mer utförligt:

Konvertera 11 till binÀrt (1011).
Skriv masken under. Fyll pÄ med nollor framför 1011 sÄ att de blir lika lÄnga.

value: 000000000000000000000000000000001011 (decimal 11) mask: XXXXXXXXXXXXXXXXXXXXXXXXXXXXX1XXXX0X result:

GÄ sedan frÄn höger till vÀnster, en siffra i taget.

Om mask-tecknet Àr X, ta siffran frÄn vÀrdet.
Om mask-tecknet Àr 0, ta 0.
Om mask-tecknet Àr 1, ta 1.

Mask-tecknet lÀngst till höger Àr X, sÄ dÄ tar vi 1:an lÀngst till höger i vÀrdet.

value: 000000000000000000000000000000001011 (decimal 11) mask: XXXXXXXXXXXXXXXXXXXXXXXXXXXXX1XXXX0X result: 1

NÀsta mask-tecken Àr 0. DÄ blir det alltid 0.

value: 000000000000000000000000000000001011 (decimal 11) mask: XXXXXXXXXXXXXXXXXXXXXXXXXXXXX1XXXX0X result: 01

Och sÄ vidare tills hela resultatet Àr ifyllt:

value: 000000000000000000000000000000001011 (decimal 11) mask: XXXXXXXXXXXXXXXXXXXXXXXXXXXXX1XXXX0X result: 000000000000000000000000000001001001

Det Ă€r alltsĂ„ sĂ„ som du “lĂ€gger ihop en mask och ett tal”. Sen Ă€r ju uppgiften lite mer Ă€n sĂ„, men detta kanske fĂ„r dig pĂ„ rĂ€tt spĂ„r?

Stort tack för en otroligt bra förklaring! Jag skrev ihop koder som kunde lösa exemplet i beskrivningen, men det blev fel nĂ€r jag skulle köra med den riktiga inputen. Tror det blev tokigt nĂ€r jag körde Long.toString(radix: 2) rakt av. Problemet Ă€r ju kombination av min okunskap om binĂ€ra tal och saknaden av debugmöjligheter. Det var lite som mission impossible sĂ„ jag letade upp en lösning pĂ„ reddit och hĂ€mtade inspiration dĂ€rifrĂ„n. Skrattade lite för mig sjĂ€lv, hade Ă€ndĂ„ inte klarat det sjĂ€lv. ÄndĂ„ nice att lĂ€ra mig operators som substringAfter och zip.

HÀr Àr lösningen för del 1 om ni Àr nyfikna. Del 2 kommer jag inte att röra.

Skrivet av GLaDER:

Du behöver inte anvÀnda CRT för att lösa uppgiften Du har fÄtt nÄgra tips ovan om att loopa pÄ ett lite smartare sÀtt.

Jag tycker att exemplet pÄ AoC hjÀlper mycket!

Om du fÄr följande som input:

mask = XXXXXXXXXXXXXXXXXXXXXXXXXXXXX1XXXX0X mem[8] = 11 mem[7] = 101 mem[8] = 0

ska vÀrdena 11, 101, och 0 modifieras av "masken" och det modifierade vÀrdet ska sedan skrivas till minnesadresserna 8, 7, och 8. (Ja, du kommer skriva över vÀrdet pÄ minnesadress 8.)

Sen fÄr man ett exempel pÄ hur sjÀlva maskningen ska gÄ till:

value: 000000000000000000000000000000001011 (decimal 11) mask: XXXXXXXXXXXXXXXXXXXXXXXXXXXXX1XXXX0X result: 000000000000000000000000000001001001 (decimal 73

Ovan har du talet 11 Ätergivet bÄde decimalt (bas 10) och pÄ binÀr form (bas 2). Om du kollar pÄ binÀrformen ser du att den Àr lika lÄng som masken. Du kan nu anvÀnda reglerna som Àr beskrivna av AoC för att fÄ fram ditt modifierade tal:

A 0 or 1 overwrites the corresponding bit in the value, while an X leaves the bit in the value unchanged.

NÀr jag skrev min kod löste jag det sÄhÀr:

mask = "" mem = dict() for row in input: if "mask" in row: mask = parseMask(row) else: addr, value = parseMemVal(row) mem[addr] = maskedValue(mask, value)

Kruxet Àr givetvis att skriva maskedValue(). SÀg till om du vill ha vidare guidning

Dold text

Tack till dig ocksÄ! Ja ok, in that case kommer jag att backa till dag 13 och försöka klura ut det.

Visa signatur

| Mobo: Gigabyte X570 GAMING X | CPU: AMD Ryzen 9 3900X + Dark Rock 4 | RAM: 32GB @ 3000MHz | GPU: Gigabyte RTX 3080 OC | PSU: Seasonic GX 850W | Chassi: NZXT S340 Elite Matte Black | M.2: Samsung 970 Evo 500GB & 1000GB | HDD: 4TB | Monitors: Acer Predator X34 GS & Acer XB270HU |

PermalÀnk
Medlem ★
●

Dag 16, Python. Nej, den hÀr lösning Àr jag inte sÀrskilt nöjd med. Den blev varken kort eller elegant, istÀllet blev den bÄde lÄng och imperativ

FilinlÀsningen var inte sÄ mycket man kunde göra nÄgot Ät.
Listan matches innehÄller kolumn och alla regler som en viss kolumn Àr giltig för.
Hitta den kolumn som bara matchar en regel, stoppa den i uniques, ta bort den regeln frÄn matches och leta igen.

import re from numpy import prod def readinput(): f = open("input") rules = [] while True: line = f.readline().strip() m = re.search(r'(.+): (\d+)\-(\d+) or (\d+)\-(\d+)', line) if not m: break rules.append((m[1], ((int(m[2]), int(m[3])), (int(m[4]), int(m[5]))))) f.readline() line = f.readline().strip() ticket = [int(i) for i in line.split(',')] f.readline() line = f.readline() others = [[int(i) for i in line.split(',')] for line in f.readlines()] return rules, ticket, others def valid(x): return any([lo <= x <= hi for r in rules for lo, hi in r[1]]) rules, ticket, others = readinput() v = [t for t in others if (all([valid(i) for i in t]))] matches = [(c, set([i for i,rule in enumerate(rules) if all([any([lo <= v <= hi for lo, hi in rule[1]]) for v in [t[c] for t in v]])])) for c in range(len(ticket))] uniques = [] while len(uniques) < len(matches): unique = [x for x in matches if len(x[1]) == 1][0] u = list(unique[1])[0] uniques.append((unique[0], u)) for m in matches: if u in m[1]: m[1].remove(u) print(sum([i for t in others for i in t if not(valid(i))]), prod([ticket[c] for c,r in uniques if rules[r][0].startswith('departure')]))

Dold text
Förenklade lite
PermalÀnk
Datavetare ★
●

Dag: 16
SprÄk: Swift
Lösning: Github

Inga konstigheter, listade bara alla rader som var giltiga för alla giltiga biljetter och körde sedan en djupet först sökning för att hitta en kombination dÀr alla fÀlt anvÀndes.

Edit: ok, en sak. Sorterade listan med möjligheter sÄ att man tittar pÄ fallen med minst antal möjligheter först, tar jag bort den sorteringen (som inte Àr nödvÀndig för korrekthet) tar det >1 minut att hitta svaret.

$ swift run -c release 🌟 Part 1 : 19060 ⌚ Elapsed : 0 ms 🌟 Part 2 : 953713095011 ⌚ Elapsed : 4 ms

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 ★
●
Skrivet av GLaDER:

Dag: 15
SprÄk: Go
Lösning: Main

Glöm inte att kika in pÄ vÄr leaderboard: 115994-59705230

Idag tyckte jag att jag var ganska snabb. Som sig bör fick jag direkt en tanke pÄ hur jag borde lösa uppgiften men sen gick tankeprocessen ungefÀr sÄhÀr:

  1. Började lÀsa beskrivningen

  2. Ah! AnvÀnd en map för associera ett nummer med nÀr det senast anropades.

  3. lÀste vidare i beskrivningen

  4. Oh.. jag behöver hÄlla koll pÄ fler anrop Àn senaste, hm. ska nog anvÀnda en slice istÀllet för en map dÄ...

  5. Kodar lite.

  6. Inser att jag behöver min map för att associera numret med listan av anrop. BÄde map och slice alltsÄ!

  7. Kodar lite till.

  8. Yes! Snabb och snygg lösning. Första stjÀrnan pÄ plats ~3000! Det Àr min bÀsta sedan Day 1.

Sen la jag tvÄ timmar -- tvÄ timmar -- pÄ att anvÀnda en slice med lÀngd tvÄ (och hela tiden bara ha exakt de tvÄ tal jag behöver tillgÀngliga) istÀllet för en slice med godtycklig lÀngd. Tror aldrig jag haft sÄ hÀr mÄnga off-by-one errors... StjÀrna tvÄ: Plats ~7000.

Dold text

Dag: 16
SprÄk: Go
Lösning: Main

Glöm inte att kika in pÄ vÄr leaderboard: 115994-59705230

Kod. Kod. Kod.

Idag blev det lÄngt. Jag löste Del 1 ganska smÀrtfritt, men jag lyckades verkligen inte hÄlla tungan i rÀtt mun nÀr jag skulle hantera olika sorters index och vÀrden. Det blev superviktigt att anvÀnda riktigt tydliga variabelnamn, för jag blandade konstant ihop "indexet i en ticket", "vÀrdet index" som jag höll reda pÄ, etc. Inte ens nu, nÀr allting fungera, Àr jag helt hundra pÄ vad som Àr vad.

Vad vÀrre Àr lade jag sÀkert en timme pÄ en lösning som var inversen till den jag tillslut fick rÀtt svar med.

KÀrnan i min fungerande lösning ser ni nedan.

for c, v := range constraints { lowList := util.MakeRange(v[0][0], v[0][1]) highList := util.MakeRange(v[1][0], v[1][1]) vRange := append(lowList, highList...) availIds := util.MakeRange(0, len(tickets[0])-1) for _, ticket := range tickets { for valueIdx, ticketValue := range ticket { if !util.IntInSlice(ticketValue, vRange) { availIds = util.RemoveIntByValue(valueIdx, availIds) } } } constraintToRange[c] = append(constraintToRange[c], availIds...) }

Grundpremissen Àr att jag har en lista: vRange, som innehÄller alla giltiga vÀrden för en viss constraint. För varje ticket skapar jag sedan en lista med alla möjliga index (availIds). DÀrefter kollar jag siffran pÄ varje position i ticket. Om siffran inte Äterfinns i vRange tar jag bort den frÄn availIds.

AoC inputen Àr gjord sÄ att minst en constraint bara kommer ha en siffra i availIds. SÄ i en annan del av koden loopar jag helt enkelt över alla constraints. Om det bara finns ett vÀrde i availIds Àr jag klar med det constraintet. DÄ tar jag bort det IDt frÄn alla andra constraints och vipps Àr det minst en constraint som bara har ett vÀrde igen.

Problemet med mitt initiala lösningsförslag var att jag gjorde tvÀrtom. Jag började med en tom lista och loopade igenom alla tickets. "Fungerar det hÀr indexet? Ja. LÀgg till." Förhoppningen var att ett index per constraint skulle vara "högst", men sÄ blev det inte... BlÀh.

Dold text
Visa signatur

:(){ :|:& };:

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

PermalÀnk
Medlem ★
●

Dag 16, ngl, börjar tappa tÄlamodet pÄ awk nu. Komplexiteten börjar bli för mycket för ett sÄ primitivt verktyg. Inte för att problemen i sig krÀver nÄgra finare features, men det gÄr Ät en viss "kognitiv belastning" Ät att mappa allt till strÀngar och hashmaps. Idag tappade jag förtroendet lite pÄ min lösning halvvÀgs genom, och dÄ sved det extra nÀr man knappt minns vad som Àr vad lÀngre. Tack för statiskt typade sprÄk, sÀger jag bara.

BEGIN { reading = "rules" } /your ticket/ { reading = "mine" } /nearby tickets/ { reading = "nearby" } reading == "rules" && length($0) { rules[++num_rules] = $0 split($(NF - 2), range, "-"); for (i = range[1]; i <= range[2]; i++) { accept[num_rules","i] } split($NF, range, "-"); for (i = range[1]; i <= range[2]; i++) { accept[num_rules","i] } } reading == "mine" && /[0-9,]+/ { split($0, mine, ",") } reading == "nearby" && /[0-9,]+/ { ticket_ok = 1 split($0, values, ",") for (f in values) { ok = 0 for (r = 1; r <= num_rules; r++) { ok = ok || r","values[f] in accept } if (!ok) { ticket_ok = 0 p1 += values[f] } } if (ticket_ok) { tickets[$0] } } END { for (n = 1; n <= num_rules; n++) { left[n] } while (length(left) > 0) { for (f = 1; f <= num_rules; f++) { cnt = 0 for (r = 1; r <= num_rules; r++) { if (!(r in left)) { continue } ok = 1 for (t in tickets) { split(t, values, ",") ok = ok && r","values[f] in accept } if (ok) { cnt++ rule = r } } if (cnt == 1) { field_map[f] = rule delete left[rule] } } } p2 = 1 for (f in field_map) { p2 *= rules[field_map[f]] ~ /^departure/ ? mine[f] : 1 } print p1 print p2 }

Var inte allt för nöjd med ovan, sÀrskilt att göra sÄ mycket jobb pÄ slutet nÀr man sÀkert sett tillrÀckligt tidigare i programmet.. Blev ~15ggr snabbare nÀr jag höll lite extra state för att minnas frÄn rad till rad vilka fÀlt som fortfarande Àr ok för diverse kolumner.

BEGIN { reading = "rules" } /your ticket/ { reading = "mine" } /nearby tickets/ { reading = "nearby" } reading == "rules" && length($0) { rules[++num_rules] = $0 split($(NF - 2), range, "-"); for (i = range[1]; i <= range[2]; i++) { accept[num_rules","i] } split($NF, range, "-"); for (i = range[1]; i <= range[2]; i++) { accept[num_rules","i] } } reading == "mine" && /[0-9,]+/ { split($0, mine, ",") } reading == "nearby" && /[0-9,]+/ { ticket_ok = 1 split($0, values, ",") for (f in values) { ok = 0 for (r = 1; r <= num_rules; r++) { ok = ok || r","values[f] in accept } if (!ok) { ticket_ok = 0 p1 += values[f] } } if (ticket_ok) { tickets[$0] for (f in values) { for (r = 1; r <= num_rules; r++) { map[f","r] = (!(f","r in map) || map[f","r]) && r","values[f] in accept } } } } END { p2 = 1 for (n = 1; n <= num_rules; n++) { left[n] } for (f = 1; length(left); f = (f % num_rules) + 1) { cnt = 0 for (r in left) { if (map[f","r]) { cnt++; rule = r } } if (cnt == 1) { p2 *= rules[rule] ~ /^departure/ ? mine[f] : 1; delete left[rule] } } print p1 print p2 }

Dold text

Jag tror med detta att jag fÄr ge upp mina hopp om att nÄ top 5 (anonymous user #122421), det lÀr bara bli vÀrre hÀrifrÄn. MÄrten, om du ser detta, vem du Àn Àr.. fan ta dig Min hemliga nemesis senaste veckan eller sÄ.. Med det sagt.. ta top 3 frÄn den dÀr andra anonyme! God speed

Visa signatur

"Some poor, phoneless fool is probably sitting next to a waterfall somewhere, totally unaware of how angry and scared he's supposed to be." - Duncan Trussell

PermalÀnk
●

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

Gjorde det nog mer invecklat Àn det hade behövt vara pÄ del 2...

PermalÀnk
Medlem ★
●
Skrivet av gibbon_:

Dag 16, ngl, börjar tappa tÄlamodet pÄ awk nu. Komplexiteten börjar bli för mycket för ett sÄ primitivt verktyg.

Du har gjort ett bra jobb. Jag Àr klart imponerad över att du lyckats lösa problemen in awk (och de andra kommandoradsverktygen).

PermalÀnk
Medlem ★
●
Skrivet av Ingetledigtnamn:

Du har gjort ett bra jobb. Jag Àr klart imponerad över att du lyckats lösa problemen in awk (och de andra kommandoradsverktygen).

Ja, jag Àr vÀldigt imponerad över er alla som kommit sÄ hÀr lÄngt pÄ ett frÀmmande sprÄk. Jag fixar det inte ens pÄ mitt favoritsprÄk. Jag Àr inte ute efter nÄn tröst, detta Àr bara hÀftigt tycker jag. Inspirerande.

Visa signatur

| Mobo: Gigabyte X570 GAMING X | CPU: AMD Ryzen 9 3900X + Dark Rock 4 | RAM: 32GB @ 3000MHz | GPU: Gigabyte RTX 3080 OC | PSU: Seasonic GX 850W | Chassi: NZXT S340 Elite Matte Black | M.2: Samsung 970 Evo 500GB & 1000GB | HDD: 4TB | Monitors: Acer Predator X34 GS & Acer XB270HU |

PermalÀnk
Medlem
●

Idag blir det ingen lösning frÄn mig, fick aldrig ordning pÄ sista delen.

PermalÀnk
Medlem ★
●

Dag: 15
SprÄk: Kotlin
Lösning: GitHub

Förlorade tyvÀrr vÀldigt mycket tid pÄ en bugg dÀr det var rÀtt svar för del 1 men aldrig för del 2. Trodde att det var för att Int inte kunde hantera sÄ stora siffror, men det visade sig senare att jag hade deklarerat listan och mapen som top-level variables..... sjukt onödigt. Sen var uppgiften lite ful och stökade till det med att börja med index 1.

Visa signatur

| Mobo: Gigabyte X570 GAMING X | CPU: AMD Ryzen 9 3900X + Dark Rock 4 | RAM: 32GB @ 3000MHz | GPU: Gigabyte RTX 3080 OC | PSU: Seasonic GX 850W | Chassi: NZXT S340 Elite Matte Black | M.2: Samsung 970 Evo 500GB & 1000GB | HDD: 4TB | Monitors: Acer Predator X34 GS & Acer XB270HU |

PermalÀnk
Medlem ★
●

Uppenbarligen nÄgot fundamentalt jag missar idag, för exemplet stÀmmer inte alls med hur jag lÀser reglerna för hur kartan ska uppdateras.

Before any cycles: z=0 .#. ..# ###

"If a cube is inactive but exactly 3 of its neighbors are active, the cube becomes active. Otherwise, the cube remains inactive."

After 1 cycle: z=0 #.# .## .#.

Övre vĂ€nster hörn, hur blev den aktiv?

Edit: Idiot.. De gjorde ju tom en edit i uppgifts-beskrivningen, de la till "(and the frame of view follows the active cells in each cycle)", och jag förstod fortfarande inte.. Givetvis menade de att övre raden Àr y=0 i exemplet och y=1 efter en cykel, för y=0 hade inga aktiva kuber kvar..

Vidare hade jag stavat fel pÄ en variabel, vilket sÄklart awk inte skrek pÄ och hanterade som 0 istÀllet.

Visa signatur

"Some poor, phoneless fool is probably sitting next to a waterfall somewhere, totally unaware of how angry and scared he's supposed to be." - Duncan Trussell

PermalÀnk
Medlem ★
●
Skrivet av gibbon_:

Uppenbarligen nÄgot fundamentalt jag missar idag, för exemplet stÀmmer inte alls med hur jag lÀser reglerna för hur kartan ska uppdateras.

Before any cycles: z=0 .#. ..# ###

"If a cube is inactive but exactly 3 of its neighbors are active, the cube becomes active. Otherwise, the cube remains inactive."

After 1 cycle: z=0 #.# .## .#.

Övre vĂ€nster hörn, hur blev den aktiv?

Edit: Idiot.. De gjorde ju tom en edit i uppgifts-beskrivningen, de la till "(and the frame of view follows the active cells in each cycle)", och jag förstod fortfarande inte.. Givetvis menade de att övre raden Àr y=0 i exemplet och y=1 efter en cykel, för y=0 hade inga aktiva kuber kvar..

Vidare hade jag stavat fel pÄ en variabel, vilket sÄklart awk inte skrek pÄ och hanterade som 0 istÀllet.

Ja gag satt en timme och klurade pÄ varför jag inte fÄr det som exemplet.
Exemplet Àr det fel pÄ.
Men följer du reglerna sÄ Àr det bara att lösa.

Är det fel med flit eller har nĂ„gon klantat sig?

PermalÀnk
Medlem ★
●
Skrivet av GLaDER:

Dag: 16
SprÄk: Go
Lösning: Main

Glöm inte att kika in pÄ vÄr leaderboard: 115994-59705230

Kod. Kod. Kod.

Idag blev det lÄngt. Jag löste Del 1 ganska smÀrtfritt, men jag lyckades verkligen inte hÄlla tungan i rÀtt mun nÀr jag skulle hantera olika sorters index och vÀrden. Det blev superviktigt att anvÀnda riktigt tydliga variabelnamn, för jag blandade konstant ihop "indexet i en ticket", "vÀrdet index" som jag höll reda pÄ, etc. Inte ens nu, nÀr allting fungera, Àr jag helt hundra pÄ vad som Àr vad.

Vad vÀrre Àr lade jag sÀkert en timme pÄ en lösning som var inversen till den jag tillslut fick rÀtt svar med.

KÀrnan i min fungerande lösning ser ni nedan.

for c, v := range constraints { lowList := util.MakeRange(v[0][0], v[0][1]) highList := util.MakeRange(v[1][0], v[1][1]) vRange := append(lowList, highList...) availIds := util.MakeRange(0, len(tickets[0])-1) for _, ticket := range tickets { for valueIdx, ticketValue := range ticket { if !util.IntInSlice(ticketValue, vRange) { availIds = util.RemoveIntByValue(valueIdx, availIds) } } } constraintToRange[c] = append(constraintToRange[c], availIds...) }

Grundpremissen Àr att jag har en lista: vRange, som innehÄller alla giltiga vÀrden för en viss constraint. För varje ticket skapar jag sedan en lista med alla möjliga index (availIds). DÀrefter kollar jag siffran pÄ varje position i ticket. Om siffran inte Äterfinns i vRange tar jag bort den frÄn availIds.

AoC inputen Àr gjord sÄ att minst en constraint bara kommer ha en siffra i availIds. SÄ i en annan del av koden loopar jag helt enkelt över alla constraints. Om det bara finns ett vÀrde i availIds Àr jag klar med det constraintet. DÄ tar jag bort det IDt frÄn alla andra constraints och vipps Àr det minst en constraint som bara har ett vÀrde igen.

Problemet med mitt initiala lösningsförslag var att jag gjorde tvÀrtom. Jag började med en tom lista och loopade igenom alla tickets. "Fungerar det hÀr indexet? Ja. LÀgg till." Förhoppningen var att ett index per constraint skulle vara "högst", men sÄ blev det inte... BlÀh.

Dold text

Dag: 17
SprÄk: Go
Lösning: Main, Paket för Block

Glöm inte att kika in pÄ vÄr leaderboard: 115994-59705230

Jag fick ta hjÀlp av Internet för att lösa Del 1, men min slutliga lösning Àr vÀldigt inspirerad av Dag 11. Stora skillnaden frÄn Dag 11 Àr:

  1. jag anvÀnder en []Cube för att hÄlla koll pÄ aktiva koordinater

  2. jag anvÀnder map[Cube]int under sjÀlva simuleringen för att mappa koordinater till aktiva grannar

Den hÀr lösningen Àr utökbar till godtyckligt mÄnga dimensioner, vilket gjorde steget mellan Del 1 och Del 2 trivial.

Dold text
Visa signatur

:(){ :|:& };:

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

PermalÀnk
Medlem ★
●

Dag 17, awk.

$ <in awk -v num_cycles=6 -f d17p2.awk

d17p2.awk

{ split($1, v, ""); for (x in v) { if (v[x] == "#") { map[x" "NR" "1" "1] } } max_x = length(v); max_y = NR } END { min_x = min_y = min_z = max_z = min_w = max_w = 1 d[-1]; d[0]; d[1] for (x in d) { for (y in d) { for (z in d) { for (w in d) { dirs[x" "y" "z" "w] } } } } delete dirs[0" "0" "0" "0] for (cycle = 0; cycles < num_cycles; cycles++) { delete add delete rem for (x = min_x - 1; x <= max_x + 1; x++) { for (y = min_y - 1; y <= max_y + 1; y++) { for (z = min_z - 1; z <= max_z + 1; z++) { for (w = min_w - 1; w <= max_w + 1; w++) { c = x" "y" "z" "w cnt = 0 for (dir in dirs) { split(dir, d) cnt += x + d[1]" "y + d[2]" "z + d[3]" "w + d[4] in map } if (c in map && cnt != 2 && cnt != 3) { rem[c] } if (!(c in map) && cnt == 3) { add[c] } } } } } for (c in rem) { delete map[c] } for (c in add) { map[c] split(c, v) min_x = v[1] < min_x ? v[1] : min_x; max_x = v[1] > max_x ? v[1] : max_x min_y = v[2] < min_y ? v[2] : min_y; max_y = v[2] > max_y ? v[2] : max_y min_z = v[3] < min_z ? v[3] : min_z; max_z = v[3] > max_z ? v[3] : max_z min_w = v[4] < min_w ? v[4] : min_w; max_w = v[4] > max_w ? v[4] : max_w } } print length(map) }

Dold text
Visa signatur

"Some poor, phoneless fool is probably sitting next to a waterfall somewhere, totally unaware of how angry and scared he's supposed to be." - Duncan Trussell

PermalÀnk
Datavetare ★
●

Dag: 17
SprÄk: Swift
Lösning: Github

TÀnkte först att x- och y-dimensionen var oÀndlig genom att dessa koordinater wrappade, men det hade man ju insett var fel om man noterade att bredd/höjd i exemplet ökade vid andra cykeln...

$ swift run -c release 🌟 Part 1 : 359 ⌚ Elapsed : 64 ms 🌟 Part 2 : 2228 ⌚ Elapsed : 675 ms

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
●

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

Jag fortsatte pÄ gÄrdagens spÄr och anvÀnde sets för att hÄlla reda pÄ vilka koordinater som var aktiva. Det förenklade framförallt nÀr jag skulle kolla vilka inaktiva grannar som eventuellt skulle bli aktiva nÀsta cykel, det var bara att lÀgga till alla grannar i ett sets medan jag ÀndÄ loopade igenom dom nÀr jag rÀknade antal grannar till de aktiva cellerna. Blev dock lite mycket repetition av koden dÄ jag hÄrdkodat en Vec3 typ till Part1 sÄ det blev en kopiering rakt av men byte till Vec4 dÄ.

Part 1: 313 Part 2: 2640 Part1 ............................... 8.304 ms ±0.313 x10 Part2 ............................. 302.407 ms ±4.558 x10

Dold text
PermalÀnk
Datavetare ★
●

Dag: 17
SprÄk: C++/OpenMP
Lösning: Github

Lunchkul, mest för att det gÄr. Maximal teoretisk speedup Àr antal unika x-dimensioner, varje kub för nÀsta generation kan ju berÀknas oberoende och hÄlla delmÀngden av nya aktiva kuber pÄ varje separat trÄd för att sedan köra en union av alla delmÀngder pÄ slutet.

AnvÀnder en annan dator i detta fall, MacOS/ARM64 saknar stöd för OpenMP Àn
Kör pÄ en 3900X

$ ./day17 Part 1 : 359 Took : 10ms Part 2 : 2228 Took : 28ms

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 17. NumPy. Inte supereffektiv, men ganska elegant.

Lösningarna blev ju ganska lika.

import numpy as np a = np.array([[1 if x == '#' else 0 for x in line.strip()] for line in open("input")])[np.newaxis,:,:] for i in range(6): a = np.pad(a, 1, mode='constant', constant_values=(0,0)) a2 = np.pad(a, 1, mode='constant', constant_values=(0,0)) xs, ys, zs = a.shape ns = np.array([[[np.sum(a2[x:x+3, y:y+3, z:z+3]) - a[x,y,z] for z in range(zs)] for y in range(ys)] for x in range(xs)]) n3 = np.where(ns == 3,1,0) n2 = np.where(ns == 2,1,0) a = a * (n2 + n3) + (1 - a) * n3 print(np.sum(a)) a = np.array([[1 if x == '#' else 0 for x in line.strip()] for line in open("input")])[np.newaxis,np.newaxis,:,:] for i in range(6): a = np.pad(a, 1, mode='constant', constant_values=(0,0)) a2 = np.pad(a, 1, mode='constant', constant_values=(0,0)) xs, ys, zs, ws = a.shape ns = np.array([[[[np.sum(a2[x:x+3, y:y+3, z:z+3, w:w+3]) - a[x,y,z,w] for w in range(ws)] for z in range(zs)] for y in range(ys)] for x in range(xs)]) n3 = np.where(ns == 3,1,0) n2 = np.where(ns == 2,1,0) a = a * (n2 + n3) + (1 - a) * n3 print(np.sum(a))

Dold text