AnmÀl dig till Roborock Challenge!

🌟 Advent of Code (AoC) 2020 🌟

PermalÀnk
Medlem
●

Dag 10 Dyalog APL:

d←⍎¹⊃⎕nget'10.txt'1 ⎕PP←15 s←¯2-/(0,⊱,3+⊱/)d[⍋d] ⍝ sorterad diff {(+/1=⍔)×(+/3=⍔)}s ⍝ del1 ×/1 2 4 7[≱¹3(≠⊆⊱)s] ⍝ del2

Dold text

Gick tillbaka och gjorde dag 8 i Scala ocksÄ

object Day08: enum Op: case Acc(arg: Int) case Jmp(arg: Int) case Nop(arg: Int) import Op._ val parse: String => Op = case s"acc ${arg}" => Acc(arg.toInt) case s"jmp ${arg}" => Jmp(arg.toInt) case s"nop ${arg}" => Nop(arg.toInt) final case class State(ip: Int = 0, acc: Int = 0, seen: HashSet[Int] = HashSet.empty[Int]) val step: (Op, State) => State = case (Acc(arg), State(ip, acc, seen)) => State(ip + 1, acc + arg, seen + ip) case (Jmp(arg), State(ip, acc, seen)) => State(ip + arg, acc, seen + ip) case (Nop(arg), State(ip, acc, seen)) => State(ip + 1, acc, seen + ip) val program = Using.resource(Source.fromFile("8.txt"))(_.getLines().map(parse).toVector) @main def part1 = Iterator.iterate(State())(s => step(program(s.ip), s)) .collectFirst{ case s if s.seen.contains(s.ip) => s.acc } .foreach(println) @main def part2 = def maybeSwap(prog: Vector[Op], i: Int): Option[Vector[Op]] = prog(i) match case _: Acc => None case Jmp(arg) => Some(program.updated(i, Nop(arg))) case Nop(arg) => Some(program.updated(i, Jmp(arg))) program.indices .flatMap(maybeSwap(program, _)) .flatMap(prg => Iterator.iterate(State())(s => step(prg(s.ip), s)) .takeWhile(s => !s.seen.contains(s.ip)) .collectFirst { case s if s.ip >= program.size => s.acc } ).foreach(println)

Dold text
Uppdaterade dyalog koden till en nÄgot kortare sortering
PermalÀnk
Medlem ★
●
Skrivet av Yoshman:

RÀtt sÀker att jag hittat vilken serie den följer: Tribinacci. Skriver man ut den serien fÄr man

0,0,1,1,4,7,13,24,44

StÀmmer i alla fall för 4 och 5 ettor i rad, nÄgot bevis har jag dock inte men finns kanske nÄgon som orkar reda ut det?
SÄ Àndrade min lösning till att anvÀnda det i stÀllet för hÄrdkodade antal permutationer.

Intressant. Jag missade helt att diffen mellan tvÄ nummer alltid Àr 1 eller 3. Hur pass svÄr hade en lösning pÄ det hÀr spÄret varit om en diff kunde varit 2?

Kanske jag skulle ha tagit mer av en hint frÄn första delen nÀr de inte frÄgade om diffar pÄ 2..

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 ★
●

Det hÀr kan vara dagen som gör att jag slutar för i Är.

Jag har lagt 90 minuter pÄ att förstÄ hur Golang vill att jag ska hantera tvÄ "grids". Min initiala tanke (för del 1) var:

simulations := 0 for { simulations++ newSeatGrid := runSimulationOneStep(oldSeatGrid) if newSeatGrid == oldSeatGrid { return simulations } oldSeatGrid = newSeatGrid }

Men jag lyckas inte förstÄ hur jag ska kunna skicka in oldSeatGrid som argument och fÄ den att inte mutera. Jag har anvÀnt make och copy för att försöka sÀkerstÀlla att min newSeatGrid verkligen ska vara en ny, fristÄende, slice; men nu ger jag upp.

Dold text

@Flexbert, har du nÄgra tips? NÀr jag slutat jobbet idag kan jag postat en lÀnk till min ofÀrdiga kod, om du vill.

EDIT: Jag har löst Part 1 nu. Det tog seriöst 90 minuter innan jag hade tillslut hittade den hÀr reddit-kommentaren som mycket riktigt hade svar pÄ tal. Nu har dock arbetsdagen börjat, sÄ Part 2 fÄr vÀnta till i eftermiddag.

Visa signatur

:(){ :|:& };:

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

PermalÀnk
Medlem ★
●

Dag 11, awk.

part1$ <in awk -v p1=1 -f d11.awk part2$ <in awk -f d11.awk

d11.awk

{ split($1, v, ""); for (x in v) { c = x" "NR; cs[c] = m[c] = v[x] } mx = length(v) } END { d[-1]; d[0]; d[1]; for (x in d) { for (y in d) { dirs[x" "y] } } delete dirs[0" "0] do { delete u for (c in cs) { if (m[c] == ".") { continue } occupied = 0 for (dir in dirs) { split(dir, d); split(c, p) occupied += test(p[1] + d[1], p[2] + d[2], d[1], d[2]) } if (m[c] == "L" && occupied == 0) { u[c] = "#" } if (m[c] == "#" && occupied >= (p1 ? 4 : 5)) { u[c] = "L" } } for (x in u) { m[x] = u[x] } } while (length(u) > 0) for (x in m) { answer += m[x] == "#" } print answer } function test(x, y, dx, dy) { return m[x" "y] == "#" ? 1 : p1 || x <= 0 || y <= 0 || x > mx || y > NR || m[x" "y] == "L" ? 0 : test(x + dx, y + dy, dx, dy) }

Inte den snabbaste lösningen men det gick ann..

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
●

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

Roligt att man fick anvÀndning av sin lösning frÄn dag 3 idag

Dold text
PermalÀnk
Medlem ★
●

Dag 10. Del ett var ju inte sÄ svÄr. Egentligen inte del tvÄ heller tror jag, men osÀker pÄ om jag orkar/har tid skriva koden som krÀvs.
Men sen kollar man leaderboard och ser att de snabbaste klarade uppgiften pÄ under 5 minuter. Hur kan det ens vara möjligt..?
MÄste sitta pÄ fÀrdig kod (Typ Game of Life), som bara krÀvt mindre justeringar?

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

Dag 10. Del ett var ju inte sÄ svÄr. Egentligen inte del tvÄ heller tror jag, men osÀker pÄ om jag orkar/har tid skriva koden som krÀvs.
Men sen kollar man leaderboard och ser att de snabbaste klarade uppgiften pÄ under 5 minuter. Hur kan det ens vara möjligt..?
MÄste sitta pÄ fÀrdig kod (Typ Game of Life), som bara krÀvt mindre justeringar?

Dold text

Menar du den globala leaderboarden? För jag tror inte vi kan se tiden pÄ vÄran privata? De som landar pÄ den globala Àr absolut freaks av nÄ slag, och/eller har en uppsjö av knep för att inte behöva lösa problemen pÄ egen hand eller frÄn scratch..

Villt skilda lösningar pÄ gÄrdagen men hÀr har du min oneliner igen som visar att det inte behöver bli sÀrskilt mycket kod

<in sort -n | awk '{ n[NR] = $1 } END { print f(0, 1) } function f(c, i) { return c in s ? s[c] : s[c] = n[i] - c <= 3 ? i == NR ? 1 : f(n[i], i + 1) + f(c, i + 1) : 0 }'

Dold text

Det tog mig pÄ tok för lÄng tid att komma fram till den dock. Och det trotts att jag ocksÄ trodde jag hade en lösning i Ätanke innan jag började fippla..

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_:

Menar du den globala leaderboarden? För jag tror inte vi kan se tiden pÄ vÄran privata? De som landar pÄ den globala Àr absolut freaks av nÄ slag, och/eller har en uppsjö av knep för att inte behöva lösa problemen pÄ egen hand eller frÄn scratch..

Jo, precis, pÄ den globala.

Funderade lite till pÄ del tvÄ för idag, och behövdes inte sÄ mycket extra kod.
Dag: 10
SprÄk: JavaScript

Var förvirrad en stund innan jag insÄg hur man kopierade 2d arrayer...

Ett "trick" Àr att "padda" datan med nÄgot annat tecken, för att slippa massa boundary checks. Finns mÄnga möjligheter att minska mÀngden kod, men har inte tid med det idag tyvÀrr. Detta Àr bara lösningen för del tvÄ, blev för mycket duplicerad kod/extrajobb att ha bÄda i samma körning pÄ ett snyggt sÀtt.

function calculate(list) { for (let i = 0; i < 1000; i++) { let newState = JSON.parse(JSON.stringify(list)) let height = list.length; let width = list[0].length; for (let y = 1; y < height - 1; y++) { for (let x = 1; x < width - 1; x++) { newState[y][x] = getNewState(list, x, y); } } if (JSON.stringify(list) === JSON.stringify(newState)) { console.log("Stable after " + i + " iterations"); console.log(countAllOccupied(newState) + " occupied seats"); break; } list = JSON.parse(JSON.stringify(newState)) } } function countAllOccupied(list) { let freeSeats = 0; for (let y = 0; y < list.length; y++) { for (let x = 0; x < list[y].length; x++) { if (list[y][x] === "#") { freeSeats++; } } } return freeSeats; } function see(list, x, y, dx, dy) { x = x + dx; y = y + dy; while (list[y][x] === ".") { x = x + dx; y = y + dy; } return list[y][x]; } function countSurroundingOccupied(list, x, y) { let occupied = 0; if (see(list, x, y, -1, -1) === "#") { occupied++; } if (see(list, x, y, -1, 0) === "#") { occupied++; } if (see(list, x, y, -1, 1) === "#") { occupied++; } if (see(list, x, y, 0, -1) === "#") { occupied++; } if (see(list, x, y, 0, 1) === "#") { occupied++; } if (see(list, x, y, 1, -1) === "#") { occupied++; } if (see(list, x, y, 1, 0) === "#") { occupied++; } if (see(list, x, y, 1, 1) === "#") { occupied++; } return occupied; } function getNewState(list, x, y) { if (list[y][x] === "L" && (see(list, x, y, -1, -1) != "#" && see(list, x, y, -1, 0) != "#" && see(list, x, y, -1, 1) != "#" && see(list, x, y, 0, -1) != "#" && see(list, x, y, 0, 1) != "#" && see(list, x, y, 1, -1) != "#" && see(list, x, y, 1, 0) != "#" && see(list, x, y, 1, 1) != "#")) { return "#"; } else if (list[y][x] === "#" && countSurroundingOccupied(list, x, y) >= 5) { return "L"; } else { return list[y][x]; } } function parseInput(text) { const list = text.split("\n"); for (let i = 0; i < list.length; i++) { list[i] = ("B" + list[i] + "B").split(""); } let emptyLine = new Array(list[0].length).fill("B"); list.unshift(emptyLine); list.push(emptyLine); calculate(list); } async function fetchInput() { var response = await fetch('input.txt'); var text = await response.text(); parseInput(text); } fetchInput();

Dold text
PermalÀnk
Datavetare ★
●

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

Denna Àr en kandidat för CUDA, fÄ se om jag orkar fixa en sÄdan ikvÀll

Började med en array + "padding" tricket, men tÀnkte sedan att det Àr enklare att bara ha tvÄ set: ett med positionen pÄ alla stolar samt ett med de stolar som Àr upptagna. Man Àr klar nÀr mÀngden upptagna stolar inte lÀngre Àndras.

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:

Det hÀr kan vara dagen som gör att jag slutar för i Är.

Jag har lagt 90 minuter pÄ att förstÄ hur Golang vill att jag ska hantera tvÄ "grids". Min initiala tanke (för del 1) var:

simulations := 0 for { simulations++ newSeatGrid := runSimulationOneStep(oldSeatGrid) if newSeatGrid == oldSeatGrid { return simulations } oldSeatGrid = newSeatGrid }

Men jag lyckas inte förstÄ hur jag ska kunna skicka in oldSeatGrid som argument och fÄ den att inte mutera. Jag har anvÀnt make och copy för att försöka sÀkerstÀlla att min newSeatGrid verkligen ska vara en ny, fristÄende, slice; men nu ger jag upp.

Dold text

@Flexbert, har du nÄgra tips? NÀr jag slutat jobbet idag kan jag postat en lÀnk till min ofÀrdiga kod, om du vill.

EDIT: Jag har löst Part 1 nu. Det tog seriöst 90 minuter innan jag hade tillslut hittade den hÀr reddit-kommentaren som mycket riktigt hade svar pÄ tal. Nu har dock arbetsdagen börjat, sÄ Part 2 fÄr vÀnta till i eftermiddag.

Stötte pÄ samma problem imorse. Nu vet jag knappt vad jag pratar om; men det Àr vÀl shallow copy som Àr default (vÀrdena har samma pekare) och i det hÀr fallet hade en deep copy (vÀrdena Àr helt skilda mellan listorna) hjÀlpt oss. Börjar du peta pÄ nÄgot vÀrde i en lista med shallow copy fÄr du dÀrför inte det resultatet du önskat. Det finns nog bibliotek för att göra deep-copys. Sen mindes jag @Ingetledigtnamn och hans kommenterar dÄ jag tidigare (Dag 8) höll pÄ att kopiera listor. Det Àr dyrt och ofta finns det ett bÀttre sÀtt. DÀrför hittade jag en lösning utan kopiering. Kan dela den senare, den Àr olÀslig..

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

Stötte pÄ samma problem imorse. Nu vet jag knappt vad jag pratar om; men det Àr vÀl shallow copy som Àr default (vÀrdena har samma pekare) och i det hÀr fallet hade en deep copy (vÀrdena Àr helt skilda mellan listorna) hjÀlpt oss. Börjar du peta pÄ nÄgot vÀrde i en lista med shallow copy fÄr du dÀrför inte det resultatet du önskat. Det finns nog bibliotek för att göra deep-copys. Sen mindes jag @Ingetledigtnamn och hans kommenterar dÄ jag tidigare (Dag 8) höll pÄ att kopiera listor. Det Àr dyrt och ofta finns det ett bÀttre sÀtt. DÀrför hittade jag en lösning utan kopiering. Kan dela den senare, den Àr olÀslig..

Dold text

Jag tar gÀrna en titt pÄ din lösning! FÄr se om jag bemödar mig med del 2 öht idag.

Visa signatur

:(){ :|:& };:

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

PermalÀnk
Datavetare ★
●

Dag: 11
SprÄk: C++/OpenMP

#include <algorithm> #include <boost/iostreams/device/mapped_file.hpp> #include <chrono> #include <cstring> #include <functional> #include <iostream> #include <string> #include <unordered_set> #include <vector> struct Pos { int x; int y; Pos(int _x, int _y) : x(_x), y(_y) { } bool operator==(const Pos &rhs) const { return x == rhs.x && y == rhs.y; } bool operator<(const Pos &rhs) const { return (x == rhs.x && y < rhs.y) || x < rhs.x; } Pos &operator+=(const Pos &rhs) { x += rhs.x; y += rhs.y; return *this; } }; namespace std { template<> struct hash<Pos> { size_t operator()(const Pos &pos) const { return hash<int>()(pos.x ^ (pos.y << 7)); } }; } struct SetReducer { SetReducer(std::unordered_set<Pos> s = {}) : set(s) {} SetReducer& operator+= (const SetReducer &rhs) { set.insert(rhs.set.begin(), rhs.set.end()); return *this; } std::unordered_set<Pos> set; }; #pragma omp declare reduction(SetReducerInsert: SetReducer: omp_out += omp_in) struct WaitingArea { std::vector<Pos> seats; std::unordered_set<Pos> occupied; int width; int height; bool isPart1; WaitingArea(const char *input, bool part1) : isPart1(part1) { int x = 0; int y = 0; char tile; width = std::strchr(input, '\n') - input; height = std::strlen(input) / (width + 1); while ((tile = *input++) != '\0') { switch (tile) { case '\n': x = 0; y++; break; case 'L': seats.push_back(Pos(x, y)); // fallthrough default: x++; break; } } std::sort(seats.begin(), seats.end()); } int countAdjacentOccupied(const Pos &pos) { int cnt = 0; for (int dy = -1; dy <= 1; dy++) { for (int dx = -1; dx <= 1; dx++) { if (!(dy == 0 && dx == 0) && occupied.count(Pos(pos.x + dx, pos.y + dy)) > 0) { cnt += 1; } } } return cnt; } bool isOccupiedVisible(const Pos &from, const Pos &dir) { Pos pos = from; pos += dir; while (pos.x >= 0 && pos.x < width && pos.y >= 0 && pos.y < height) { if (occupied.count(pos) > 0) { return true; } if (std::binary_search(seats.begin(), seats.end(), pos)) { return false; } pos += dir; } return false; } int countVisibleOccupied(const Pos &pos) { int cnt = 0; for (int dy = -1; dy <= 1; dy++) { for (int dx = -1; dx <= 1; dx++) { if (!(dy == 0 && dx == 0) && isOccupiedVisible(pos, Pos(dx, dy))) { cnt += 1; } } } return cnt; } bool nextGeneration() { SetReducer nextOccupied; #pragma omp parallel for reduction(SetReducerInsert:nextOccupied) for (int i = 0; i < seats.size(); i++) { const Pos& seat = seats[i]; if (isPart1) { int n = countAdjacentOccupied(seat); if (n == 0 || (n < 4 && occupied.count(seat) > 0)) { nextOccupied += SetReducer({seat}); } } else { int n = countVisibleOccupied(seat); if (n == 0 || (n < 5 && occupied.count(seat) > 0)) { nextOccupied += SetReducer({seat}); } } } if (occupied == nextOccupied.set) { return true; } occupied = nextOccupied.set; return false; } }; static void bench(std::function<void()> fn) { auto start = std::chrono::high_resolution_clock::now(); fn(); auto finish = std::chrono::high_resolution_clock::now(); auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(finish - start); std::cout << "Took " << duration.count() << " ms\n"; } int main() { boost::iostreams::mapped_file input("input.txt", boost::iostreams::mapped_file::readonly); WaitingArea wa1(input.const_data(), true); WaitingArea wa2(input.const_data(), false); bench([&]() { while (!wa1.nextGeneration()) { } std::cout << "Part 1 : " << wa1.occupied.size() << "\n"; }); bench([&]() { while (!wa2.nextGeneration()) { } std::cout << "Part 2 : " << wa2.occupied.size() << "\n"; }); }

Lösning

C++ variant med custom OpenMP reducer. Parallellismen hÀr ligger i att alla celler för nÀsta generation kan berÀknas oberoende av varandra, sÄ passar egentligen GPU bÀttre Àn multi-core CPU. En sekventiell C++ lösning kan m.h.a. OpenMP realtivt lÀtt konverteras till nÄgot som i alla fall löser varje rad parallellt, lite förÀndringar frÄn min Swift lösning krÀvs.

OpenMP "parallell for" mÄste ha C-style arrayer att jobba med, sÄ gÄr inte att anvÀnda std::unordered_set<Pos>, att anvÀnda en std::vektor<Pos> fungerar bra förutsatt att man sorterar den sÄ det gÄr att binÀrsöka i den.

Sedan har man problemet att alla trÄdar kommer fylla i nya generationen, för att inte behöva Àndra allt för mycket frÄn Swift-lösningen defininerar jag en custom OpenMP reducer. Alla CPU-trÄdar fÄr sin eget lokala set som de adderar till, OpenMP syntetiserar sedan kod för att slÄ ihop alla delresultat nÀr man lÀmnar den parallella sektionen.

Inte *super-wow* prestandavinst, men man fÄr i alla fall 2-4 gÄnger högre prestanda förutsatt att man har 4C/8T eller mer (pÄ min 3900X med 12C/24T börjar prestanda minska ingen om man anvÀnder allt för mÄnga CPU-trÄdar).

Part 1 : 2481 Took 53 ms Part 2 : 2227 Took 97 ms

Edit: kanske posta körtider ocksÄ
Visa signatur

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

PermalÀnk
●
Skrivet av GLaDER:

Jag tar gÀrna en titt pÄ din lösning! FÄr se om jag bemödar mig med del 2 öht idag.

Det slog mig nyss hur jag ocksÄ kunde Àndra min kod sÄ att jag inte behövde göra nÄgra kopieringar. Den gÄr istÀllet ut pÄ att jag kör tvÄ "passes" över griden och i det första passet gÄr jag igenom varje punkt i griden och bokför i en lista vilka rutor som ska Àndras. Och sen gör jag ett andra pass över griden dÀr jag utför dessa Àndringar. Knepet dÄ för att veta om den grid jag fÄr Àr samma som den innan Àr att min bokföringslista Àr tom, alltsÄ inga Àndringar att göra. Hoppas du kan fÄ ut nÄgot av det hÀr iaf

Dold text
PermalÀnk
Medlem
●

Dag: 11
SprÄk: Golang
Lösning:

Part1: 86ms
Part2: 62ms.

BenchmarkPartOne-8 13 85881343 ns/op
BenchmarkPartTwo-8 18 62739727 ns/op

Börjar gÄ trögt och det Àr nog inte datorns fel..

package main import ( "bufio" "fmt" "os" ) type Position struct { Y int X int Value string } func getPartOne(rows []string) int { return countSeats(rows, 4, 1) } func getPartTwo(rows []string) int { return countSeats(rows, 5, len(rows)+len(rows[0])) // too lazy to count diagonal, it should be the longest possible depth } func countSeats(rows []string, maxAdjecent int, depth int) int { layout := getLayout(rows) changeLog := []Position{} count := 0 i := 0 for ; i == 0 || len(changeLog) > 0; i++ { count = 0 for _, change := range changeLog { layout[change.Y][change.X] = change.Value } changeLog = []Position{} for y, line := range layout { for x, col := range line { if col == "L" { adjecentCount := findAdjacentOccupied(layout, y, x, depth) if adjecentCount == 0 { changeLog = append(changeLog, Position{Y: y, X: x, Value: "#"}) } } else if col == "#" { count++ adjecentCount := findAdjacentOccupied(layout, y, x, depth) if adjecentCount >= maxAdjecent { changeLog = append(changeLog, Position{Y: y, X: x, Value: "L"}) } } } } //fmt.Println(i) //for _, row := range layout { // fmt.Println(row) //} } //fmt.Printf("Done after %v iterations\n", i) return count } func findAdjacentOccupied(layout [][]string, y int, x int, depth int) int { count := 0 for i := -1; i < 2; i++ { for j := -1; j < 2; j++ { if i == 0 && j == 0 { continue // stay, is not valid } count += checkSeats(layout, y, x, i, j, depth) } } return count } func checkSeats(layout [][]string, y int, x int, moveY int, moveX int, depth int) int { position := Position{Y: y, X: x} count := 0 height := len(layout) width := len(layout[0]) for i := 0; i < depth; i++ { position.X += moveX position.Y += moveY if !isInbound(height, width, position.Y, position.X) { break } if layout[position.Y][position.X] == "#" { count++ break } if layout[position.Y][position.X] == "L" { break } } return count } func isInbound(height int, width int, y int, x int) bool { return y >= 0 && x >= 0 && y < height && x < width } func getLayout(rows []string) [][]string { layout := [][]string{} for i, row := range rows { layout = append(layout, []string{}) for _, col := range row { layout[i] = append(layout[i], string(col)) } } return layout } func getRows(filename string) []string { file, _ := os.Open(filename) defer file.Close() scanner := bufio.NewScanner(file) var rows []string for scanner.Scan() { rows = append(rows, scanner.Text()) } return rows } func main() { rows := getRows("../input.txt") fmt.Println("PartOne", getPartOne(rows)) fmt.Println("PartTwo", getPartTwo(rows)) }

Dold text
Spelling of adjacent
PermalÀnk
Medlem ★
●
Skrivet av GLaDER:

Dag: 10
SprÄk: Go
Lösning: GitHub

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

Idag var det svÄrt med del 2. OmgÄende tÀnkte jag att jag skulle anvÀnda memoization, men det var lÀngesedan jag sysslade med Dynamic Programming. Jag hade för mÄnga bollar i luften och tog inte en sak i taget. Tillslut fick jag ta nÄgra djupa andetag och tillsammans med Internet lyckades jag fÄ ihop en bra lösning.

Dold text

Dag: 11
SprÄk: Go
Lösning: Main, Grid Util

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

SÄ, som jag skrev i mitt morgoninlÀgg var jag mÄttligt irriterad i morse. Jag var vÀldigt sÀker pÄ att min algoritm fungerade, men jag fick inte Golang att fatta att jag ville ha en ny grid i varje loop... Jag har tidigare anvÀnt make och copy för att ta kopior av slices, men jag fick det inte att fungera den hÀr gÄngen -- förrÀn jag hittade reddit-kommentaren; bless him.

Sagt och gjort. NÀsta problem var att hitta ett effektivt sÀtt att traversera diagonalt i en matris. Jag skrev asmycket kod för att lösa problemet, men skÀmdes sÄ mycket över vad jag hade framför mig att jag inte bemödade mig slutföra det spÄret. IstÀllet hittade jag en toppenlösning pÄ nÀtet som jag stal rakt av. Kruxet var att ha alla riktningar (typ som egenvektorer?) och sen multiplicera med en skalÀr för att bestÀmma hur lÄngt man ska titta. (DÄ passade jag Àven pÄ att skriva om lösningen för del 1, sÄ den anvÀnde samma teknik.)

@huggeMugg nÀmnde en lösning dÀr man slipper kopiera i sitt inlÀgg, men nÀr jag lÀste det inlÀgget hade jag löst kopieringsbiten sedan lÀnge och hade inga prestandaproblem i sikte.

First answer retrieved in: 146.727914ms Second answer retrieved in: 135.172917ms

Dold text
Visa signatur

:(){ :|:& };:

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

PermalÀnk
Medlem
●
Skrivet av GLaDER:

Dag: 11
SprÄk: Go
Lösning: Main, Grid Util

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

SÄ, som jag skrev i mitt morgoninlÀgg var jag mÄttligt irriterad i morse. Jag var vÀldigt sÀker pÄ att min algoritm fungerade, men jag fick inte Golang att fatta att jag ville ha en ny grid i varje loop... Jag har tidigare anvÀnt make och copy för att ta kopior av slices, men jag fick det inte att fungera den hÀr gÄngen -- förrÀn jag hittade reddit-kommentaren; bless him.

Sagt och gjort. NÀsta problem var att hitta ett effektivt sÀtt att traversera diagonalt i en matris. Jag skrev asmycket kod för att lösa problemet, men skÀmdes sÄ mycket över vad jag hade framför mig att jag inte bemödade mig slutföra det spÄret. IstÀllet hittade jag en toppenlösning pÄ nÀtet som jag stal rakt av. Kruxet var att ha alla riktningar (typ som egenvektorer?) och sen multiplicera med en skalÀr för att bestÀmma hur lÄngt man ska titta. (DÄ passade jag Àven pÄ att skriva om lösningen för del 1, sÄ den anvÀnde samma teknik.)

@huggeMugg nÀmnde en lösning dÀr man slipper kopiera i sitt inlÀgg, men nÀr jag lÀste det inlÀgget hade jag löst kopieringsbiten sedan lÀnge och hade inga prestandaproblem i sikte.

First answer retrieved in: 146.727914ms Second answer retrieved in: 135.172917ms

Dold text

Bra att du inte har kastat in handduken!

PermalÀnk
Medlem ★
●
Skrivet av Flexbert:

Bra att du inte har kastat in handduken!

Ă€n...

Men Tack! Bra jobbat du ocksÄ

Visa signatur

:(){ :|:& };:

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

PermalÀnk
Medlem ★
●

Dag 11, Python, eller snarare NumPy. Först uppgiften gick bra i "bara" numpy, till den andra behövdes en extra funktion.

import numpy as np from functools import reduce input = [list(map(ord, list(i.strip()))) for i in open("input","r")] sx, sy = len(input), len(input[0]) def pad(a, f = np.zeros): res = f((sx+2, sy+2), dtype = np.int8) res[1:1+sx,1:1+sy] = a return res is_seat = pad(np.where(np.array(input) == ord('L'), 1, 0), np.ones) directions = ((-1,-1), (-1, 0), (-1, 1), ( 0,-1), ( 0, 1), ( 1,-1), ( 1, 0), ( 1, 1)) def neighbors1(a): return reduce(np.add, [a[1+x:1+x+sx,1+y:1+y+sy] for x,y in directions]) def neighbors2(a): def los(a, pos, dir): while True: pos = tuple(np.add(pos, dir)) if is_seat[pos]: return a[pos] return np.array([[sum([los(a, (x,y), dir) for dir in directions]) for y in range(1,1+sy)] for x in range(1,1+sx)]) def round(a, neighbors, crowded): ns = neighbors(a) birth = pad(np.where(ns == 0, 1, 0)) not_death = pad(np.where(ns < crowded, 1, 0)) return np.where(a * not_death + birth, 1, 0) * is_seat def run(neighbors, crowded): a = np.zeros((sx+2, sy+2), dtype = np.int8) while True: b = a a = round(a, neighbors, crowded) if np.array_equal(a, b): return np.sum(a) print(run(neighbors1, 4), run(neighbors2, 5))

Dold text
PermalÀnk
Medlem ★
●

Jag tror att jag lÄtsas att denna dag aldrig hÀnde. Del 1 var enkelt, men jag kan inte ens förstÄ problemet för del 2, blir bara hÄrigare för varje gÄng jag försöker förstÄ problemet, sÄ jag ger upp och tar mig an nÀsta dag imorgon (vilket blir dag 11), jag mÄste ju ocksÄ njuta av min helg.

Dag: 10, endast del 1
SprÄk: Kotlin
Lösning: GitHub

PermalÀnk
Medlem
●

Dag: 11
SprÄk: Rust
Lösning: lÀnk

Ber om ursÀkt för eventuell kaos kod, har inte hunnit gÄ igenom sÄ noga

Skrivet av Yoshman:

Dag: 11
SprÄk: C++/OpenMP

#include <algorithm> #include <boost/iostreams/device/mapped_file.hpp> #include <chrono> #include <cstring> #include <functional> #include <iostream> #include <string> #include <unordered_set> #include <vector> struct Pos { int x; int y; Pos(int _x, int _y) : x(_x), y(_y) { } bool operator==(const Pos &rhs) const { return x == rhs.x && y == rhs.y; } bool operator<(const Pos &rhs) const { return (x == rhs.x && y < rhs.y) || x < rhs.x; } Pos &operator+=(const Pos &rhs) { x += rhs.x; y += rhs.y; return *this; } }; namespace std { template<> struct hash<Pos> { size_t operator()(const Pos &pos) const { return hash<int>()(pos.x ^ (pos.y << 7)); } }; } struct SetReducer { SetReducer(std::unordered_set<Pos> s = {}) : set(s) {} SetReducer& operator+= (const SetReducer &rhs) { set.insert(rhs.set.begin(), rhs.set.end()); return *this; } std::unordered_set<Pos> set; }; #pragma omp declare reduction(SetReducerInsert: SetReducer: omp_out += omp_in) struct WaitingArea { std::vector<Pos> seats; std::unordered_set<Pos> occupied; int width; int height; bool isPart1; WaitingArea(const char *input, bool part1) : isPart1(part1) { int x = 0; int y = 0; char tile; width = std::strchr(input, '\n') - input; height = std::strlen(input) / (width + 1); while ((tile = *input++) != '\0') { switch (tile) { case '\n': x = 0; y++; break; case 'L': seats.push_back(Pos(x, y)); // fallthrough default: x++; break; } } std::sort(seats.begin(), seats.end()); } int countAdjacentOccupied(const Pos &pos) { int cnt = 0; for (int dy = -1; dy <= 1; dy++) { for (int dx = -1; dx <= 1; dx++) { if (!(dy == 0 && dx == 0) && occupied.count(Pos(pos.x + dx, pos.y + dy)) > 0) { cnt += 1; } } } return cnt; } bool isOccupiedVisible(const Pos &from, const Pos &dir) { Pos pos = from; pos += dir; while (pos.x >= 0 && pos.x < width && pos.y >= 0 && pos.y < height) { if (occupied.count(pos) > 0) { return true; } if (std::binary_search(seats.begin(), seats.end(), pos)) { return false; } pos += dir; } return false; } int countVisibleOccupied(const Pos &pos) { int cnt = 0; for (int dy = -1; dy <= 1; dy++) { for (int dx = -1; dx <= 1; dx++) { if (!(dy == 0 && dx == 0) && isOccupiedVisible(pos, Pos(dx, dy))) { cnt += 1; } } } return cnt; } bool nextGeneration() { SetReducer nextOccupied; #pragma omp parallel for reduction(SetReducerInsert:nextOccupied) for (int i = 0; i < seats.size(); i++) { const Pos& seat = seats[i]; if (isPart1) { int n = countAdjacentOccupied(seat); if (n == 0 || (n < 4 && occupied.count(seat) > 0)) { nextOccupied += SetReducer({seat}); } } else { int n = countVisibleOccupied(seat); if (n == 0 || (n < 5 && occupied.count(seat) > 0)) { nextOccupied += SetReducer({seat}); } } } if (occupied == nextOccupied.set) { return true; } occupied = nextOccupied.set; return false; } }; static void bench(std::function<void()> fn) { auto start = std::chrono::high_resolution_clock::now(); fn(); auto finish = std::chrono::high_resolution_clock::now(); auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(finish - start); std::cout << "Took " << duration.count() << " ms\n"; } int main() { boost::iostreams::mapped_file input("input.txt", boost::iostreams::mapped_file::readonly); WaitingArea wa1(input.const_data(), true); WaitingArea wa2(input.const_data(), false); bench([&]() { while (!wa1.nextGeneration()) { } std::cout << "Part 1 : " << wa1.occupied.size() << "\n"; }); bench([&]() { while (!wa2.nextGeneration()) { } std::cout << "Part 2 : " << wa2.occupied.size() << "\n"; }); }

Lösning

C++ variant med custom OpenMP reducer. Parallellismen hÀr ligger i att alla celler för nÀsta generation kan berÀknas oberoende av varandra, sÄ passar egentligen GPU bÀttre Àn multi-core CPU. En sekventiell C++ lösning kan m.h.a. OpenMP realtivt lÀtt konverteras till nÄgot som i alla fall löser varje rad parallellt, lite förÀndringar frÄn min Swift lösning krÀvs.

OpenMP "parallell for" mÄste ha C-style arrayer att jobba med, sÄ gÄr inte att anvÀnda std::unordered_set<Pos>, att anvÀnda en std::vektor<Pos> fungerar bra förutsatt att man sorterar den sÄ det gÄr att binÀrsöka i den.

Sedan har man problemet att alla trÄdar kommer fylla i nya generationen, för att inte behöva Àndra allt för mycket frÄn Swift-lösningen defininerar jag en custom OpenMP reducer. Alla CPU-trÄdar fÄr sin eget lokala set som de adderar till, OpenMP syntetiserar sedan kod för att slÄ ihop alla delresultat nÀr man lÀmnar den parallella sektionen.

Inte *super-wow* prestandavinst, men man fÄr i alla fall 2-4 gÄnger högre prestanda förutsatt att man har 4C/8T eller mer (pÄ min 3900X med 12C/24T börjar prestanda minska ingen om man anvÀnder allt för mÄnga CPU-trÄdar).

Part 1 : 2481 Took 53 ms Part 2 : 2227 Took 97 ms

Edit: kanske posta körtider ocksÄ

Har inte hunnit kolla pÄ sÄ mÄnga andras lösningar Àn. Men jag tÀnkte mig...

...uppsÀttningen stolar/golv-platser som en 2D lista med alla tiles. Fick följande tider för min lösning (entrÄdig, ej medvetet optimerad för prestanda)

Part1: 2222 took 25ms Part2: 2032 took 50ms

..en annan lösning
PermalÀnk
Medlem ★
●

$ <in sed -E 's/^(.)/\1 /' | awk 'BEGIN { dx = 1; wx = 10; wy = 1 } /E/ { p1x += $2; wx += $2 } /W/ { p1x -= $2; wx -= $2 } /N/ { p1y += $2; wy += $2 } /S/ { p1y -= $2; wy -= $2 } /F/ { p1x += dx * $2; p1y += dy * $2; p2x += wx * $2; p2y += wy * $2 } /R/ || /L/ { turn = mod($1 ~ /R/ ? $2 : -$2, 360) for (i = turn; i > 0; i -= 90) { px = dx; dx = dy; dy = -px } for (i = turn; i > 0; i -= 90) { px = wx; wx = wy; wy = -px } } END { print (p1x < 0 ? -p1x : p1x) + (p1y < 0 ? -p1y : p1y) } END { print (p2x < 0 ? -p2x : p2x) + (p2y < 0 ? -p2y : p2y) } function mod(n, m) { return n % m + (n < 0 ? m : 0) }'

Dag 12, precis nÀr jag gett upp pÄ att awk skulle vara ett rimligt sprÄk för kommande problem.. Àr det inte lite vackert ÀndÄ?
radbrytningar
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 GLaDER:

Dag: 11
SprÄk: Go
Lösning: Main, Grid Util

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

SÄ, som jag skrev i mitt morgoninlÀgg var jag mÄttligt irriterad i morse. Jag var vÀldigt sÀker pÄ att min algoritm fungerade, men jag fick inte Golang att fatta att jag ville ha en ny grid i varje loop... Jag har tidigare anvÀnt make och copy för att ta kopior av slices, men jag fick det inte att fungera den hÀr gÄngen -- förrÀn jag hittade reddit-kommentaren; bless him.

Sagt och gjort. NÀsta problem var att hitta ett effektivt sÀtt att traversera diagonalt i en matris. Jag skrev asmycket kod för att lösa problemet, men skÀmdes sÄ mycket över vad jag hade framför mig att jag inte bemödade mig slutföra det spÄret. IstÀllet hittade jag en toppenlösning pÄ nÀtet som jag stal rakt av. Kruxet var att ha alla riktningar (typ som egenvektorer?) och sen multiplicera med en skalÀr för att bestÀmma hur lÄngt man ska titta. (DÄ passade jag Àven pÄ att skriva om lösningen för del 1, sÄ den anvÀnde samma teknik.)

@huggeMugg nÀmnde en lösning dÀr man slipper kopiera i sitt inlÀgg, men nÀr jag lÀste det inlÀgget hade jag löst kopieringsbiten sedan lÀnge och hade inga prestandaproblem i sikte.

First answer retrieved in: 146.727914ms Second answer retrieved in: 135.172917ms

Dold text

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

First answer retrieved in: 31.28”s Second answer retrieved in: 26.55”s

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

Dagens lÀrdomar:

  1. I go sÄ Àr inte % som jag förvÀntade mig. (Exempel).

  2. Exemplet för part 2 svÀngde bara höger, sÄ jag fick rÀtt pÄ testet trots att min kod var fel. (BÄda brancherna i min if/else-if-sats hade rotDir == "R".) SÄ gÄr det nÀr man försöker vara duktig och tÀcka alla baser, istÀllet för att bara köra if/else.

  3. Jag har svÄrt att hitta balansen mellan "snabbast möjliga fulhack" och "lÀra mig Golang ordentligt". Det gör att mina lösningar blir mellanmjölk. Varken snabba eller Go-iska.

Dold text
Visa signatur

:(){ :|:& };:

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

PermalÀnk
●

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

Trevligt med lösningar som bara tog 4 mikrosekunder idag för ovanlighetens skull

PermalÀnk
Medlem ★
●

Dag 12, Python. Ganska prydlig lösning om jag fÄr sÀga det sjÀlv. Inte en enda list comprehension

Komplexa tal hÄller koordinatberÀkningarna enkla.

rdirs = [complex(1,0),complex(0, 1),complex(-1,0),complex(0,-1)] ldirs = [complex(1,0),complex(0,-1),complex(-1,0),complex(0, 1)] def eswn(dir, p, sp, wp, d, x): offset = rdirs['ESWN'.find(d)] * x return (dir, p + offset, sp, wp + offset) def f(dir, p, sp, wp, d, x): return dir, p + rdirs[dir] * x, sp + wp * x, wp def r(dir, p, sp, wp, d, x): return (dir + x // 90) % 4, p, sp, wp * rdirs[x // 90] def l(dir, p, sp, wp, d, x): return (dir - x // 90) % 4, p, sp, wp * ldirs[x // 90] func = {'E' : eswn, 'S' : eswn, 'W' : eswn, 'N' : eswn, 'R' : r, 'L' : l, 'F' : f} dir, p, sp, wp = 0, complex(0,0), complex(0,0), complex(10,-1) for line in open('input', 'r'): dir, p, sp, wp = func[line[0]](dir, p, sp, wp, line[0], int(line[1:])) print(int(abs(p.real) + abs(p.imag)), int(abs(sp.real) + abs(sp.imag)))

Dold text
Stavfel
PermalÀnk
Datavetare ★
●

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

Swift har, likt t.ex. Rust, möjlighet att associera ett vÀrde till enums. Passade pÄ att anvÀnda det i denna lösning.

Visa signatur

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

PermalÀnk
Datavetare ★
●
Skrivet av usbalbin:

...uppsÀttningen stolar/golv-platser som en 2D lista med alla tiles. Fick följande tider för min lösning (entrÄdig, ej medvetet optimerad för prestanda)

Part1: 2222 took 25ms Part2: 2032 took 50ms

Hash-tabeller Àr ofta mumma för en algoritms komplexitet, men det Àr absolut öken för moderna CPUer dÄ en bra hash-funktion kommer per definition stÀlla till det för CPU-logiken som försöker gissa nÀsta minnesaccess.

Ju snabbare och "bredare" CPU man har, ju mer tjÀnar man i praktiken pÄ att vÀlja algoritmer med förutsÀgbar minnesaccess, d.v.s. i praktiken: vanlig array/vector Àr nÀstan alltid vÀsentligt snabbare om man kan avvara tillrÀckligt med minne.

I C++ fallet ovan började jag med cp day11.swift day11.cpp, tyckte lösningen var lite vÀl seg i Swift och gjorde ett provskott pÄ hur logiskt samma lösning fungerade i C++. Var bara runt dubbelt sÄ snabbt i C++, sÄ Swift Àr helt OK. FrÄn den punkten funderade jag pÄ hur man kunde lyfta in OpenMP...

Gjorde en annan Àndring igÄr, bytte ut occupied mÀngden mot en std::vector<bool> i stÀllet (C++ har specialisering för bool, sÄ blir en bit-array). Enbart den Àndringen resulterade i ungefÀr den enkeltrÄdprestanda din Rust lösning har. D.v.s. bara frÄn att gÄ frÄn std::unordered_set<> (vÀldigt elak mot moderna high-end CPUer sett till minnesaccess) till std::vector<bool> (dÀr man indexerar direkt med (x + 1) + (width + 2) * (y + 1), d.v.s. hela rutnÀtet med en ram dÀr inget Àr taget) nÀstan tiodubblade enkeltrÄdprestanda.

Är Ă€nnu mer lurigt om man vill göra saker effektiva över flera kĂ€rnor. De mer komplexa/effektiva algoritmerna passar ofta dĂ„ligt att sprida över flera kĂ€rnor, sĂ„ man fĂ„r prova sig fram om en enklare algoritm kan kompenseras av att man kan slĂ€nga fler kĂ€rnor pĂ„ problemet. Ofta Ă€r det bĂ€st att optimera för enkeltrĂ„dfallet och bara anvĂ€nda flera kĂ€rnor om man har flera samtida oberoende problem att lösa, ofta men lĂ„ngt ifrĂ„n alltid

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 ★
●

Blev inspirerad av @Ingetledigtnamn.

Glömde bort hur komplexa tal kunde hjÀlpa med rotation i 2D. DessvÀrre har inte awk stöd för komplexa tal, sÄ fick skapa mina egna. Vackert blev det inte, men kul att se vilka dumheter man kan hitta pÄ med vÀldigt simpla verktyg..

part1$ <in sed -E 's/^(.)/\1 /' | awk -f d12.awk -v p1=1 -v dx=1 part2$ <in sed -E 's/^(.)/\1 /' | awk -f d12.awk -v dx=10 -v dy=1

d12.awk

BEGIN { R = "real"; I = "imag" wp = complex_make(dx, dy) lookup[dirs[0] = "E"] = complex_make(1, 0) lookup[dirs[1] = "S"] = complex_make(0, -1) lookup[dirs[2] = "W"] = complex_make(-1, 0) lookup[dirs[3] = "N"] = complex_make(0, 1) } /[EWNS]/ { res = complex_add(p1 ? pos : wp, complex_mult(complex_make($2, 0), lookup[$1])) } /[EWNS]/ && p1 { pos = res } /[EWNS]/ && !p1 { wp = res } /F/ { pos = complex_add(pos, complex_mult(wp, complex_make($2, 0))) } /R|L/ { wp = complex_mult(wp, lookup[dirs[mod(($1 ~ /R/ ? $2 : -$2) / 90, 4)]]) } END { complex_split(pos, r); print (r[R] < 0 ? -r[R] : r[R]) + (r[I] < 0 ? -r[I] : r[I]) } function mod(n, m) { return n % m + (n < 0 ? m : 0) } function complex_add(a, b) { complex_split(a, a_) complex_split(b, b_) return complex_make(a_[R] + b_[R], a_[I] + b_[I]) } function complex_mult(a, b) { complex_split(a, a_) complex_split(b, b_) return complex_make(a_[R] * b_[R] - a_[I] * b_[I], a_[R] * b_[I] + a_[I] * b_[R]) } function complex_split(a, r) { split(a, v, ",") r[R] = v[1] r[I] = v[2] } function complex_make(r, i) { return r","i }

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
Medlem ★
●

Jag har fuskat lite genom att inte ta hÀnsyn till om adjacent seats faktiskt finns utan istÀllet fÄngar alla icke-existerande-seat-krascher i try/catch. Hade inte gjort sÄ i produktion.

Dock har jag ingen aning om hur jag kan skapa en lista av relevanta coordinates för del 2? Jag förstÄr att jag vill kolla alla seats i alla Ätta hÄll, men vet inte hur jag kan skapa en sÄdan lista enkelt. Tips pÄ algoritm?

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

Sen kan jag tycka att det kÀnns som att det Àr bara folk som faktiskt löser skriver hÀr. Kom igen, det finns vÀl mycket fler som ocksÄ har det kÀmpigt?!

EDIT: Jag kom pÄ en lösning under min dagliga promenad och jag tÀnkte skitsamma. VÀldigt ful och hemsk lösning men jag har en helg att tÀnka pÄ.

PermalÀnk
Medlem ★
●
Skrivet av Dave1080:

Dock har jag ingen aning om hur jag kan skapa en lista av relevanta coordinates för del 2? Jag förstÄr att jag vill kolla alla seats i alla Ätta hÄll, men vet inte hur jag kan skapa en sÄdan lista enkelt. Tips pÄ algoritm?

Varför vill du ha en lista? Du har ju en 2D tabell att leta i. Det Àr bara att gÄ i en riktning i taget tills du hittar ett sÀte. Tomt eller inte.

PermalÀnk
Medlem
●
Skrivet av Dave1080:

Jag har fuskat lite genom att inte ta hÀnsyn till om adjacent seats faktiskt finns utan istÀllet fÄngar alla icke-existerande-seat-krascher i try/catch. Hade inte gjort sÄ i produktion.

Dock har jag ingen aning om hur jag kan skapa en lista av relevanta coordinates för del 2? Jag förstÄr att jag vill kolla alla seats i alla Ätta hÄll, men vet inte hur jag kan skapa en sÄdan lista enkelt. Tips pÄ algoritm?

Dag: 11, endast del 1
SprÄk: Kotlin
Lösning: GitHub

Sen kan jag tycka att det kÀnns som att det Àr bara folk som faktiskt löser skriver hÀr. Kom igen, det finns vÀl mycket fler som ocksÄ har det kÀmpigt?!

Det Àr fler som har det kÀmpigt

Första gÄngen jag provar AOC med sprÄket Rust. Har inte gjort sÄ mycket med Rust mer Àn lÀst och hÀngt med för att det Àr ett intressant sprÄk.

Jobbar som utvecklare och efter 8 timmar direkt sÀtta sig ner med AOC har haft sina pÄfrestningar. Min hjÀrna mÄste fÄ slappna av efter jobbet. Kommer nog sitta i mÄn av tid och lösa pusslen nÀr man Àr sugen.

Visa signatur

AMD Ryzen 3700X, Gigabyte Elite X570, 32GB Ballistix Sport, NH-D15S, SAPPHIRE NITRO+ RX 7900 XTX, Corsair AX760, LG OLED C2 42"