🌟 Advent of Code (AoC) 2020 🌟

PermalÀnk
Medlem ★
●
Skrivet av Ingetledigtnamn:

Jag försökte med rad 7 och tryckte in den i firefox, men fick 404. TÀnkte att man kanske mÄste ha access till sidan eller nÄt, men din direktlÀnk pekar faktiskt till ett annat stÀlle Àn rad 7 hÀnvisar.

Att man kunde klicka pÄ funktionerna visste jag inte. Tackar för den lektionen.

Huh. SpÀnnande, oklart varför... Men bra att du hittade ÀndÄ! Fina funktioner.

Visa signatur

:(){ :|:& };:

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

PermalÀnk
Medlem
●

Dag 8 Scala. Uuugh. Satt över 4 timmar idag. TÀnkte "bra, nu kan jag ta en promenad och fÄ lite sol kanske för att rensa huvudet och bli lite gladare". Tittar ut, det Àr "molnig vinterdag under pandemiÄret 2020 regisserad av Ingmar Bergman".

object Emulator extends App { sealed trait Errors case class InfiniteRecursion(line: Int) extends Errors case class OobAttempt(line: Int) extends Errors sealed trait Ops case class Nop(steps: Int) extends Ops case class Jmp(steps: Int) extends Ops case class Acc(value: Int) extends Ops def apply(program: List[String]) = new Emulator(program) def decode(str: String):Ops = (str.take(3), str.drop(4).toInt) match { case ("nop", amount) => Nop(amount) case ("acc", amount) => Acc(amount) case ("jmp", step) => Jmp(step) case _ => throw new IllegalArgumentException(s"Unknown op $str") } class Emulator(val program: List[String]) { def step(seen: Set[Int], acc:Int, pos:Int, fixed: Boolean = false):Either[Errors, Int] = { if (seen.contains(pos)) return Left(InfiniteRecursion(pos)) if (pos < 0 || pos > program.size-1) return Left(OobAttempt(pos)) val op = decode(program(pos)) val newValue = op match { case Acc(value) => acc + value case _=> acc } //Horray, the program terminated and we have an answer if (pos==program.size-1) return Right(newValue) val newPos = op match { case Jmp(steps) => pos + steps case _ => pos + 1 } val newSeen = seen + pos def result = step(newSeen, newValue, newPos, fixed) (fixed, result, op) match { case (_, Right(answer), _) => result //we have an answer, return it case (true, Left(err), _) => result //Already tried fixing once, not allowed more attempts. case (false, Left(err), Nop(x)) => step(newSeen, acc, pos + x, true) //Change to Jmp case (false, Left(err), Jmp(_)) => step(newSeen, acc, pos+1, true) //Change to Nop case (false, Left(err), _) => result //Accs are never wrong, nothing to do here. } } def run(): Either[Errors, Int] = { step(Set[Int](), 0, 0) } } }

Blev vÀl acceptabel tillslut, men "step" Àr för lÄng, den gör return pÄ 8 olika stÀllen, och Àr svÄr att testa pÄ nÄgot utom full programinput. KÀnns inte som det blev sÄ funktionellt denna gÄng.

Dold text
BĂ€ttre pattern matching
PermalÀnk
Medlem ★
●

Dag 8, Python andra försöket. Stop-hacket var bara för fult.

from functools import partial instructions = [l.split() for l in open('input', 'r')] def acc(pc, accumulator, offset): return pc + 1, accumulator + offset def jmp(pc, accumulator, offset): return pc + offset, accumulator def nop(pc, accumulator, offset): return pc + 1, accumulator def swap(instructions, i): s = instructions[i][0] swaps = { 'jmp':'nop', 'nop':'jmp'} if s in swaps: instructions[i][0] = swaps[s] pc, accumulator = run(instructions, set([len(instructions)])) instructions[i][0] = s if pc == len(instructions): return accumulator return 0 def run(instructions, executed = set()): pc, accumulator = 0, 0 while pc not in executed: executed.add(pc) i = instructions[pc] pc, accumulator = eval(i[0])(pc, accumulator, int(i[1])) return pc, accumulator print(run(instructions)[1], sum(map(partial(swap, instructions), range(len(instructions)))))

Dold text
PermalÀnk
Medlem ★
●

Fastna lite pÄ dag 4 pga. CRLF/LF diff mellan testinputen och den riktiga. Blev inget gjort i helgen heller sÄ börjar redan hamna efter

Dag: 4
SprÄk: Powershell
Lösning: Github

$InputData = Get-Content "input.txt" -Raw $Fields = @('byr','iyr','eyr','hgt','hcl','ecl','pid') function Test-Passports { param ( [string]$Data, [Array]$RequiredFields ) $Result = @() $Passports = $Data -Split "`n`n" # Validate passwords for ($i = 0; $i -lt $Passports.Count; $i++) { $Entries = $Passports[$i].Split("`n").Split(" ") $PassportResults = @(); $HasFields = -not (($RequiredFields | % {$Entries.Split(":") -contains $_}) -contains $false) if ($HasFields) { foreach ($Entry in $Entries) { $PassportResults += Test-PassportField $Entry.Trim() } } Else { $PassportResults += $false } $Result += -not ($PassportResults -contains $false) } return $Result } function Test-PassportField { param ( [string]$PassportField ) $Field, $Data = $PassportField.Split(":") switch ($Field) { # byr (Birth Year) - four digits; at least 1920 and at most 2002. "byr" { $Data -match "^(19[2-9][0-9]|200[0-2])$" } # iyr (Issue Year) - four digits; at least 2010 and at most 2020. "iyr" { $Data -match "^20(1[0-9]|20)$" } # eyr (Expiration Year) - four digits; at least 2020 and at most 2030. "eyr" { $Data -match "^20(2[0-9]|30)$" } # hgt (Height) - a number followed by either cm or in: # If cm, the number must be at least 150 and at most 193. # If in, the number must be at least 59 and at most 76. "hgt" { $hgt = $Data.Substring(0,$Data.Length-2) $unit = $Data.Substring($Data.Length-2,2) switch ($unit) { "cm" { $hgt -ge 150 -AND $hgt -le 193 } "in" { $hgt -ge 59 -AND $hgt -le 76 } Default {$false} } } # hcl (Hair Color) - a # followed by exactly six characters 0-9 or a-f. "hcl" { $Data -match "^#[0-9a-f]{6}$" } # ecl (Eye Color) - exactly one of: amb blu brn gry grn hzl oth. "ecl" { $Data -match "^(amb|blu|brn|gry|grn|hzl|oth)$" } # pid (Passport ID) - a nine-digit number, including leading zeroes. "pid" { $Data -match "^\d{9}$" } # cid (Country ID) - ignored, missing or not. "cid" { $true } Default {$false} } } $ValidatedPassports = Test-Passports -Data $InputData -RequiredFields $Fields ($ValidatedPassports -eq $true).Count

Dold text

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

$InputData = Get-Content "input.txt" function Get-SeatID { param ( [String]$Seat ) $Row = [convert]::ToInt32($Seat.Substring(0,7).Replace("F",0).Replace("B",1),2) $Colum = [convert]::ToInt32($Seat.Substring(7,3).Replace("L",0).Replace("R",1),2) return $Row * 8 + $Colum; } $Seats = $InputData | % {Get-SeatID $_} $Max = ($Seats | Measure-Object -Maximum).Maximum $AllSeats = $Seats[0]..$Max $MySeat = $AllSeats | ? {-not ($Seats -contains $_)} Write-Host "Highest Seat ID: $Max" Write-Host "My Seat ID: $MySeat"

Dold text
Visa signatur

StationÀra | Define 7 Compact | RM750x White | X570S AERO G | Ryzen 5 5600x | NH-D15 Chromax | Flare X 4x8GB 3200MHz | RTX 4070 Super | MP600 1TB | 980 1TB | A2000 1TB | 970 EVO 500GB | 850 EVO 500GB |
Acer X34A + 2x Dell U2719D | Wave 1 | Arctis Nova Pro Wireless |
Laptop | Macbook Air M1 2020 | 16GB | 256GB |
3dkatten.se

PermalÀnk
Medlem ★
●

Dag 7 var ordentligt bökig, försökte lösa A först med rekursion för att hitta alla vÀskor men gick bet. InsÄg efter en stund att det kunde tolkas som ett grafproblem sÄ efter att ha meckat med en BFS en stund fick jag till det! B var mycket enklare dÄ jag redan var inne i rekursionstÀnket. Tyckte framförallt att dag 7 hade onödigt jobbig input, och det lilla introduktionsexemplet till uppgiften var inte tillrÀckligt komplext för att visa hur den riktiga inputen kan se ut.

Dag 8 var mindre bökig, men jag misstolkade uppgiften helt och hÄllet först, trodde acc skulle öka de "iterativa hoppen" i listan med motsvarande mÀngd först. B-uppgiften klurade jag pÄ ett litet tag innan jag till slut löste det genom att för varje "nop" eller "jmp" Àndra den till motsatsen i en duplicerad array och skicka in den nya arrayen i min funktion för A-uppgiften tills dess att den nÄdde slutet av listan

PermalÀnk
Medlem ★
●

Skam den som ger sig...

Dag: 6
SprÄk: Powershell
Lösning: Github

$InputData = Get-Content "$PSScriptRoot\input.txt" -Delimiter "`r`n`r`n" function Measure-Answares { param ( [array]$Answares, [switch]$PartTwo=$false ) if (-not $PartTwo) { ($Answares | % {$_.Replace("`r`n", "").ToCharArray() | Sort-Object | Get-Unique}).Count } Else { foreach ($Set in $Answares) { $Rows = ($Set | Measure-Object -Word).Words $SetAns = $Set | % {$_.Replace("`r`n", "").ToCharArray() | Group-Object} $AllYes += (($SetAns | % {$_.Count -eq $Rows}) -eq $true).Count } $AllYes } } Write-Host "Part #1: " -NoNewline Measure-Answares -Answares $InputData Write-Host "Part #2: " -NoNewline Measure-Answares -Answares $InputData -PartTwo

Dold text
Visa signatur

StationÀra | Define 7 Compact | RM750x White | X570S AERO G | Ryzen 5 5600x | NH-D15 Chromax | Flare X 4x8GB 3200MHz | RTX 4070 Super | MP600 1TB | 980 1TB | A2000 1TB | 970 EVO 500GB | 850 EVO 500GB |
Acer X34A + 2x Dell U2719D | Wave 1 | Arctis Nova Pro Wireless |
Laptop | Macbook Air M1 2020 | 16GB | 256GB |
3dkatten.se

PermalÀnk
Hedersmedlem ★
●

Dag: 8
SprÄk: Powershell
Lösning: Github

Denna var lite smÄklurig, sÀrskilt eftersom...

... pusslet verkar vilja att man löser nÄgot som Àr datalogiskt omöjligt att lösa i det generella fallet, nÀmligen stopproblemet.

Som tur var sÄ finns det en lösning för detta speciella fall, och det Àr att:

.. anvÀnda en bredd-först-sökning.

I det hÀr fallet genom att skapa alla möjliga modifierade program, och sedan köra dem ett steg i taget. NÀr ett av programmet stoppat sÄ behöver man inte köra resten av programmen till slutet.

superspoiler för del 2
ledtrÄd för del 2
Milda spoilers om del 2

För det hÀr problemet sÄ kÀndes det vÀldigt naturligt att nyttja klasser i Powershell, nÄgot som jag sÀllan faktiskt anvÀnder i detta sprÄk.

PermalÀnk
Medlem
●

Dag: 8
SprÄk: Golang
Lösning(uppdaterad):

Part1: 78ÎŒs, utan fillĂ€sning.
Part2: 4,1ms, utan fillÀsning.

BenchmarkPartOne-8 15312 78767 ns/op BenchmarkPartTwo-8 289 4101560 ns/op

Nu gÄr det nog inte fortare om jag inte hittar pÄ en annan algoritm.

package main import ( "bufio" "fmt" "os" "strconv" "strings" ) type Instruction struct { Operation string Value int } func getInstructions(rows []string) []Instruction { instructions := []Instruction{} for _, row := range rows { fields := strings.Fields(row) operation := fields[0] value, _ := strconv.Atoi(fields[1]) instructions = append(instructions, Instruction{Operation: operation, Value: value}) } return instructions } func execute(instructions []Instruction) (bool, int) { globalAccelator := 0 visited := map[int]bool{} reachedEnd := true for i := 0; i < len(instructions); { if _, ok := visited[i]; ok { reachedEnd = false break } visited[i] = false if instructions[i].Operation == "nop" { i++ } else if instructions[i].Operation == "acc" { globalAccelator += instructions[i].Value i++ } else if instructions[i].Operation == "jmp" { i += instructions[i].Value } } return reachedEnd, globalAccelator } func getPartOne(instructions []Instruction) int { _, acc := execute(instructions) return acc } func getPartTwo(instructions []Instruction) int { copyInstructions := make([]Instruction, len(instructions)) swaps := map[string]string{"jmp": "nop", "nop": "jmp"} for i := range instructions { if swapVal, ok := swaps[instructions[i].Operation]; ok { copy(copyInstructions, instructions) copyInstructions[i].Operation = swapVal if reachedEnd, acc := execute(copyInstructions); reachedEnd { return acc } } } return 0 } 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(getInstructions(rows))) fmt.Println("PartTwo", getPartTwo(getInstructions(rows))) }

Dold text
PermalÀnk
Medlem ★
●

Dag: 8
SprÄk: VB.Net

Imports System.IO Module Program Sub Main(args As String()) Dim instructionSet = File.ReadAllLines("input.txt") Dim partOne As Integer = 0 Dim partTwo As Integer = 0 IsInfiniteLoop(instructionSet, partOne) Dim correctFound As Boolean = False Dim index As Integer = 0 While Not correctFound And index < instructionSet.Length Dim instructionSetToTest(instructionSet.Length - 1) As String For i = 0 To instructionSet.Length - 1 instructionSetToTest(i) = instructionSet(i).Clone() Next Dim instruction = instructionSetToTest(index).Split(" "c) If instruction(0) = "jmp" Then instructionSetToTest(index) = "nop " & instruction(1) ElseIf instruction(0) = "nop" Then instructionSetToTest(index) = "jmp " & instruction(1) End If If Not IsInfiniteLoop(instructionSetToTest, partTwo) Then correctFound = True index += 1 End While Console.WriteLine("Part 1: " & partOne) Console.WriteLine("Part 2: " & partTwo) End Sub Function IsInfiniteLoop(instructionSet As String(), ByRef acc As Integer) As Boolean Dim hasBeenRun(instructionSet.Length - 1) As Boolean Dim infiniteLoopFound As Boolean = False Dim internalAcc As Integer = 0 Dim index As Integer = 0 While Not infiniteLoopFound And index < instructionSet.Length hasBeenRun(index) = True Dim instruction = instructionSet(index).Split(" "c) Dim code = instruction(0) Dim increment = instruction(1) If code = "acc" Then If increment(0) = "+"c Then internalAcc += Integer.Parse(increment.Substring(1)) If increment(0) = "-"c Then internalAcc -= Integer.Parse(increment.Substring(1)) index += 1 End If If code = "jmp" Then If increment(0) = "+"c Then index += Integer.Parse(increment.Substring(1)) If increment(0) = "-"c Then index -= Integer.Parse(increment.Substring(1)) End If If code = "nop" Then index += 1 End If If index < instructionSet.Length AndAlso hasBeenRun(index) Then infiniteLoopFound = True End While acc = internalAcc Return infiniteLoopFound End Function End Module

Dold text
PermalÀnk
Medlem ★
●

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

VÀldigt kul uppgifter idag, har alltid gillat att skriva whileloopar dÀr jag manipulerar iteratorn. PÄminner om smÄspelet Human Resource Machine som Àr baserat pÄ assemblerkod.

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

Nu gÄr det nog inte fortare om jag inte hittar pÄ en annan algoritm.

Du kan börja med att ta bort kopieringen. Byt jmp/nop kör execute och byt tillbaka. Det borde mÀrkas ordentligt i körtid.

Gissningsvis skulle det gÄ fortare att ha en array istÀllet för en map till visited. Den mÄste nollas (om inte Golang noll-initerar den Ät dig, men Àven om Golang gör det kommer du fÄr betala för den körtiden), men Ä andra sida slipper du all minneshantering nÀr du stoppar in nya element och uppslagningen Àr bara en pekaraddition istÀllet för hash/trÀdtraversering.

NÀr det Àr fixat kommer vi till finliret. Vilken operation Àr vanligast i ditt indata? Testa pÄ den först och sedan den nÀst vanligaste och ha tredje fallet i en else-gren sÄ slipper du en test. NÀr vi ÀndÄ pratar om tester sÄ behöver du inte testa hela strÀngen. Du kan fuska och bara testa pÄ första tecknet, det rÀcker. Och testar vi bara pÄ första tecknet i strÀngen skulle jag byta ut swaps mot en tabell-uppslagning.

PermalÀnk
Datavetare ★
●

Dag: 8
SprÄk: CUDA

#include <chrono> #include <cstdint> #include <fstream> #include <functional> #include <iostream> #include <string> #include <vector> #define OP_ACC 0 #define OP_JMP 1 #define OP_NOP 2 typedef struct { uint32_t bits[256]; } executed_t; __device__ bool mark_executed(executed_t *exec, unsigned pc) { unsigned a = pc >> 5; unsigned b = 1 << (pc & 31); bool c = !!(exec->bits[a] & b); exec->bits[a] |= b; return c; } __global__ void day8_kernel(executed_t *execs, int *res, uint8_t *ops, int *args, int prog_len) { int idx = blockIdx.x * blockDim.x + threadIdx.x; executed_t *exec = execs + idx; uint8_t new_op = ops[idx] ^ (OP_JMP + OP_NOP); int pc = 0; int acc = 0; if (idx < prog_len) { while (!mark_executed(exec, pc)) { uint8_t op = (idx == pc) ? new_op : ops[pc]; switch (op) { case OP_JMP: pc += args[pc]; break; case OP_NOP: pc += 1; break; default: acc += args[pc]; pc += 1; } if (pc == prog_len) { res[idx] = acc; break; } } } } static void * gpu_buf(void *host_ptr, size_t buf_len) { void *gpu_ptr; cudaMallocManaged(&gpu_ptr, buf_len); if (host_ptr == nullptr) { memset(gpu_ptr, 0, buf_len); } else { memcpy(gpu_ptr, host_ptr, buf_len); } return gpu_ptr; } static void day6(const std::vector<uint8_t> &ops, const std::vector<int> &args) { uint8_t *gpu_ops = (uint8_t *)gpu_buf((void *)ops.data(), ops.size() * sizeof(uint8_t)); int *gpu_args = (int *)gpu_buf((void *)args.data(), args.size() * sizeof(int)); executed_t *gpu_exec = (executed_t *)gpu_buf(nullptr, ops.size() * sizeof(executed_t)); int *gpu_res = (int*)gpu_buf(nullptr, ops.size() * sizeof(int)); int prog_len = ops.size(); day8_kernel<<<prog_len, 1>>>(gpu_exec, gpu_res, gpu_ops, gpu_args, prog_len); cudaDeviceSynchronize(); for (int i = 0; i < prog_len; i++) { if (gpu_res[i]) { std::cout << "Part 2 : " << gpu_res[i] << '\n'; } } cudaFree(gpu_ops); cudaFree(gpu_args); cudaFree(gpu_exec); cudaFree(gpu_res); } static int measure(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); auto sec = duration.count(); return sec; } int main(int argc, char *argv[]) { std::ifstream fin("input.txt"); std::string line; std::vector<uint8_t> ops; std::vector<int> args; while (std::getline(fin, line)) { if (line.rfind("acc") == 0) { ops.push_back(OP_ACC); } else if (line.rfind("jmp") == 0) { ops.push_back(OP_JMP); } else { ops.push_back(OP_NOP); } args.push_back(std::atoi(line.c_str() + 4)); } std::cout << "Took " << measure([&]() { day6(ops, args); }) << "ms\n"; } // Local Variables: // mode: c++ // compile-command: "cd build; make" // End:

Lösning

Del 2 i CUDA, varje möjlig förÀndring körs pÄ en egen "GPU-kÀrna" parallellt. PrestandamÀssig helt meningslös idé i detta fall, berÀkningen Àr alldeles för liten. Men blev inte sÄ fasligt mycket kod ÀndÄ!

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

Ska bli skönt att kolla andras lösningar nu, för jag satt hela tiden och funderade pÄ vad för grundlÀggade grej jag missade denna gÄng.

Brute-force rakt igenom.

Edit; Gjorde lite optimeringar som Dictionary och Enum, kom under 0.6ms. (exkluderar "File.ReadAllLines")

Parse: 0,1358ms Part1: 0,0114ms Part3: 0,4267ms

void Main()
{
var file = File.ReadAllLines("day-08.txt");

var parsed = Parse(file, out var parse_ms);
var part1 = Part1(parsed, out var part1_ms);
var part2 = Part2(parsed, out var part2_ms);

new { part1, part2, }.Dump();
new { Parsed = $"{parse_ms:0.000}ms", Part1 = $"{part1_ms:0.000}ms", Part2 = $"{part2_ms:0.000}ms", }.Dump();
}

enum Command { Accumulator, Jump, NoOperation };

Dictionary<int, (Command, int)> Parse(string[] lines, out double ms)
{
var stopwatch = Stopwatch.StartNew();
var parsed = new Dictionary<int, (Command, int)>();

for (int i = 0; i < lines.Length; i++)
{
var line = lines[i];
var split = line.Split(' ');
var command = split[0];
var argument = int.Parse(split[1]);
var command_parsed =
command == "acc" ? Command.Accumulator :
command == "jmp" ? Command.Jump :
command == "nop" ? Command.NoOperation :
throw new NotImplementedException($"Invalid Command: '{command}'");
parsed.Add(i, (command_parsed, argument));
}

ms = stopwatch.Elapsed.TotalMilliseconds;
return parsed;
}

int Part1(Dictionary<int, (Command Command, int Argument)> instructions, out double ms)
{
var stopwatch = Stopwatch.StartNew();
var index = 0;
var accumulator = 0;
var executed_instructions = new HashSet<int>();

while (executed_instructions.Add(index))
{
var instruction = instructions[index];

if (instruction.Command == Command.Accumulator)
{
accumulator += instruction.Argument;
index++;
}
else if (instruction.Command == Command.Jump)
{
index += instruction.Argument;
}
else if (instruction.Command == Command.NoOperation)
{
index++;
}
}

ms = stopwatch.Elapsed.TotalMilliseconds;
return accumulator;
}

int Part2(Dictionary<int, (Command Command, int Argument)> instructions, out double ms)
{
var stopwatch = Stopwatch.StartNew();
var index = 0;
var accumulator = 0;
var swapped_instruction = false;
var executed_instructions = new HashSet<int>();
var attempted_nops = new HashSet<int>();
var attempted_jmps = new HashSet<int>();

while (true)
{
var instruction = instructions[index];

if (!swapped_instruction &&
instruction.Command == Command.NoOperation &&
attempted_nops.Add(index))
{
swapped_instruction = true;
instruction.Command = Command.Jump;
}
else if (!swapped_instruction &&
instruction.Command == Command.Jump &&
attempted_jmps.Add(index))
{
swapped_instruction = true;
instruction.Command = Command.NoOperation;
}

if (instruction.Command == Command.Accumulator)
{
accumulator += instruction.Argument;
index++;
}
else if (instruction.Command == Command.Jump)
{
index += instruction.Argument;
}
else if (instruction.Command == Command.NoOperation)
{
index++;
}

if (index == instructions.Count) // last instruction => exit
{
break;
}
else if (!executed_instructions.Add(index)) // infinite loop => retry
{
index = 0;
accumulator = 0;
swapped_instruction = false;
executed_instructions.Clear();
}
}

ms = stopwatch.Elapsed.TotalMilliseconds;
return accumulator;
}

Dag: 8 // SprÄk: c#
PermalÀnk
Medlem ★
●
Skrivet av GLaDER:

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

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

Idag gick det precis som jag vill! Min initiala idé fungerade och jag fick lÀra mig lite nya grejer om sprÄket jag anvÀnder. Idag lÄg klurigheten i att slices skickas runt "by reference" som default, och att jag dÀrför behövde skapa en ny kopia för varje variant av programmet.

Jag hoppas fler pussel gÄr ut pÄ att hjÀlpa vÄr stolsgranne, och om historisk data Àr en indikation för framtida problem borde det vara just sÄ.

Dold text

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

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

Jag Àlskar frÄgor likt dagens! Del 1 var enkel och Del 2 var orimlig att klara med brute force.

Mitt första försök pÄ Del 2 var att generera alla möjliga kombinationer av index för min input, och sedan addera ihop dem, ett, i taget. Att först generera alla kombinationer och sedan börja rÀkna gjorde att programmet gjorde slut pÄ RAM redan i fjÀrde loopen. Att generera varje kombination "on the fly" fungerade, rent minnesmÀssigt, men efter ~5 minuter tÀnkte jag att det mÄste finnas ett bÀttre sÀtt.

Min slutliga lösning jobbar bara med index och rör sig sĂ„ sakteligen genom listan av möjliga inputs. Jag tror fortfarande att rad 44 och 45 Ă€r lite onödiga (det borde vara mer effektivt att hĂ„lla candidateSum utanför loopen och sen addera/subtrahera allt eftersom), men lösningen kör pĂ„ ~200ÎŒs, sĂ„ det fĂ„r duga.

EDIT:
En sak slog mig precis. Har jag bara tur som hade mitt contagious set pÄ rad? Exemplet pÄ hemsidan har ju ocksÄ det, men jag kan inte lÀsa mig fram till att sÄ alltid Àr fallet, i beskrivningen.

EDIT2:
Det Àr inte contagious, utan contiguous........ jag Àr inte lÀskunnig. Sorry. DÄ var ju mitt första försök (generera alla kombinationer) bara jÀttedumt.

Dold text
Visa signatur

:(){ :|:& };:

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

PermalÀnk
Medlem
●

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

PartOne: 147ÎŒs, utan fillĂ€sning
PartTwo: 16ÎŒs, utan fillĂ€sning

BenchmarkPartOne-8 6796 147318 ns/op BenchmarkPartTwo-8 72369 15967 ns/op

package main import ( "bufio" "fmt" "os" "sort" "strconv" ) func getNumbers(rows []string) []int { numbers := []int{} for _, row := range rows { value, _ := strconv.Atoi(row) numbers = append(numbers, value) } return numbers } func getPartOne(numbers []int, preambleSize int) int { preamble := numbers[:preambleSize] numbers = numbers[preambleSize:] for len(numbers) > 0 { found := false for j := 0; j < len(preamble); j++ { for k := j + 1; k < len(preamble); k++ { if numbers[0] == preamble[j]+preamble[k] { found = true } } } if !found { return numbers[0] } preamble = append(preamble[1:], numbers[:1]...) numbers = numbers[1:] } return 0 } func getPartTwo(numbers []int, invalid int) int { candidates := []int{} sum := int64(0) for i := 0; i < len(numbers); i++ { candidates = append(candidates, numbers[i]) sum += int64(numbers[i]) for sum > int64(invalid) { sum -= int64(candidates[:1][0]) candidates = candidates[1:] } if sum == int64(invalid) { sort.Ints(candidates) return candidates[0] + candidates[len(candidates)-1] } } return 0 } 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") numbers := getNumbers(rows) partOne := getPartOne(numbers, 25) fmt.Println("PartOne", partOne) fmt.Println("PartTwo", getPartTwo(numbers, partOne)) }

Dold text
PermalÀnk
Medlem
●
Skrivet av Ingetledigtnamn:

Du kan börja med att ta bort kopieringen. Byt jmp/nop kör execute och byt tillbaka. Det borde mÀrkas ordentligt i körtid.

Gissningsvis skulle det gÄ fortare att ha en array istÀllet för en map till visited. Den mÄste nollas (om inte Golang noll-initerar den Ät dig, men Àven om Golang gör det kommer du fÄr betala för den körtiden), men Ä andra sida slipper du all minneshantering nÀr du stoppar in nya element och uppslagningen Àr bara en pekaraddition istÀllet för hash/trÀdtraversering.

NÀr det Àr fixat kommer vi till finliret. Vilken operation Àr vanligast i ditt indata? Testa pÄ den först och sedan den nÀst vanligaste och ha tredje fallet i en else-gren sÄ slipper du en test. NÀr vi ÀndÄ pratar om tester sÄ behöver du inte testa hela strÀngen. Du kan fuska och bara testa pÄ första tecknet, det rÀcker. Och testar vi bara pÄ första tecknet i strÀngen skulle jag byta ut swaps mot en tabell-uppslagning.

Tack för bra förslag, man snöar lÀtt in sig i sin egna lilla vÀrld. Ska pröva nÀr tid ges.

PermalÀnk
Medlem
●
Skrivet av GLaDER:

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

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

Jag Àlskar frÄgor likt dagens! Del 1 var enkel och Del 2 var orimlig att klara med brute force.

Mitt första försök pÄ Del 2 var att generera alla möjliga kombinationer av index för min input, och sedan addera ihop dem, ett, i taget. Att först generera alla kombinationer och sedan börja rÀkna gjorde att programmet gjorde slut pÄ RAM redan i fjÀrde loopen. Att generera varje kombination "on the fly" fungerade, rent minnesmÀssigt, men efter ~5 minuter tÀnkte jag att det mÄste finnas ett bÀttre sÀtt.

Min slutliga lösning jobbar bara med index och rör sig sĂ„ sakteligen genom listan av möjliga inputs. Jag tror fortfarande att rad 44 och 45 Ă€r lite onödiga (det borde vara mer effektivt att hĂ„lla candidateSum utanför loopen och sen addera/subtrahera allt eftersom), men lösningen kör pĂ„ ~200ÎŒs, sĂ„ det fĂ„r duga.

EDIT:
En sak slog mig precis. Har jag bara tur som hade mitt contagious set pÄ rad? Exemplet pÄ hemsidan har ju ocksÄ det, men jag kan inte lÀsa mig fram till att sÄ alltid Àr fallet, i beskrivningen.

Dold text

VĂ€nta nu, har inte alla samma indata och resultat? Det hade jag totalt missat.

PermalÀnk
Medlem ★
●
Skrivet av Flexbert:

VĂ€nta nu, har inte alla samma indata och resultat? Det hade jag totalt missat.

Nope Det finns ett (okÀnt) antal för-genererade inputs. Exemplet Àr alltid samma, för alla, men inputen du fÄr frÄn input-lÀnken Àr unik.

Om du klickar pÄ lÀnken jag skickade, vad fÄr du dÄ?

Min input börjar:
1742
1763
1238
1424
1736
1903
1580
1847
1860

Visa signatur

:(){ :|:& };:

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

PermalÀnk
Medlem
●

Dag: 8
SprÄk: Powershell
Lösning: Github

@pv2b sÄ hÀr tÀnker du kring classer

Visa signatur

Vad vore vÀrlden utan silvertejp?

PermalÀnk
Medlem ★
●

Dag 9.
SprÄk: Java
GÄr sÀkert att optimera pÄ mÄnga sÀtt men gjorde det enkelt för mig. Fick sÄ stora tal i B-uppgiften att det blev intOverflow och fick alltsÄ göra om alltihop till Longs istÀllet

private static final int nrSize = 25; private static ArrayList<Integer> nrList = new ArrayList<Integer>(nrSize); private static HashSet<Integer> validNumbers = new HashSet<Integer>(); public static int uppgiftA(ArrayList<String> a1) { for (String row : a1) { int number = Integer.parseInt(row); if (nrList.size() != nrSize) { nrList.add(number); continue; } validNumbers.clear(); for (int i = 0; i < nrList.size() - 1; i++) { for (int j = 1; j < nrList.size(); j++) { validNumbers.add(nrList.get(i) + nrList.get(j)); } } if (validNumbers.contains(number)) { nrList.remove(0); nrList.add(number); } else { return (number); // break; } } System.err.println("! No badNo found (Uppgift A)"); return 0; } public static void uppgiftB(ArrayList<String> a1, int i0) { int c = 0; long badNo = i0; for (String row : a1) { long number = Long.parseLong(row); int c2 = c + 1; long total = number; long smallest = number; long largest = number; while (total <= badNo) { if (c2 > a1.size()) { break; } long i1 = Long.parseLong(a1.get(c2)); if (smallest > i1) { smallest = i1; } else if (largest < i1) { largest = i1; } total += i1; if (total == badNo) { System.out.println("Contigiuos numbers found! " + smallest + " + " + largest + " = " + (smallest+largest)); break; } c2++; } c++; } } public static void main(String[] args) throws Exception { String inputFile = "... /AdventOfCode2020/src/day9/input.txt"; ArrayList<String> a1 = new ArrayList<String>(MyFileReader.read(inputFile)); // uppgiftA(a1); // nrList.clear(); validNumbers.clear(); uppgiftB(a1, uppgiftA(a1)); }

Dold text
PermalÀnk
Medlem ★
●

Dag 9

Körde först en dubbel-loop pÄ första frÄgan, men efter att andra frÄgan innebar DP gick jag tillbaka och fulade mig lite pÄ första innan jag blev eh, "nöjd"

part1$ <in awk '{ n[NR] = $1; for (i = NR - 25; i < NR; i++) { x = n[NR] + n[i]; a[x] = NR; b[x] = i } } NR > 25 && !($1 in a); $1 in a && NR - a[$1] > 25 && NR - b[$1] > 25' part2$ <in awk -v bad=1639024365 '{ n[NR] = $1 } END { for (o = 0; o <= NR; o++) { for (i = 1; i + o <= NR; i++) { v[i, o] = v[i, (o - 1)] + n[i + o] if (v[i, o] == bad && o > 0) { for (k = i; k <= i + o; k++) { print n[k] } exit } } } }' | sort -n | awk '{ n[NR] = $1 } END { print n[1] + n[NR] }'

Edit: Derp, DP var sÄklart inte nödvÀndigt idag.. Fan, jag var sÄ glad över att jag trodde jag hade anvÀndning av det för första gÄngen sen algo-kursen för 11 Är sen.

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

Dag: 9
SprÄk: Javascript

KÀnns som att Àven dagens uppgift var betydligt mycket enklare Àn nÄgra av de tidigare. Finns en hel del optimeringar att göra misstÀnker jag, men gÄr sÄ snabbt Àven med brute force att det inte riktigt kÀnns lönt. Ser ut som att Àven summan av de största talen borde fÄ plats i en long long int i C, sÄ verkar inte vara det som Àr tÀnkt som utmaningen heller.

function calculatePartOne(list, preambleLength) { for (let i = preambleLength; i < list.length; i++) { let match = false; for (let j = i - preambleLength; j < i; j++) { for (let k = i - preambleLength; k < i; k++) { if (j != k) { let res = (list[j] + list[k]); if (res === list[i]) { match = true; } } } } if (match == false) { console.log("Part 1: " + list[i]); return list[i]; } } } function calculatePartTwo(list, invalidNumber) { for (let i = 0; i < list.length; i++) { let res = 0; let j = i; match = false; let addedNumbers = []; while (res < invalidNumber) { res =+ list[j]; addedNumbers.push(list[j]) j++; if (res == invalidNumber) { match = true; break; } } if (match == true) { console.log("Part 2: " + (Math.min(...addedNumbers) + Math.max(...addedNumbers))); return; } } if (match == false) { console.log("No match"); } } async function fetchInput() { var response = await fetch('input.txt'); var text = await response.text(); var list = text.split("\n").map(function (x) { return parseInt(x, 10); }); let answerFromPartOne = calculatePartOne(list, 25); calculatePartTwo(list, answerFromPartOne); } fetchInput();

Dold text
PermalÀnk
Medlem ★
●

Day 9, kompakt-Python. Det gick fint med en brute force-lösning

from itertools import combinations input = [int(line) for line in open("input", "r")] def valid(input, i): return input[i] in map(sum, combinations(input[i-25:i], 2)) invalid = [input[i] for i in range(26, len(input)) if not valid(input, i)][0] print(invalid, *[min(l) + max(l) for l in [input[i:j] for i in range(len(input)) for j in range(i + 2, len(input))] if sum(l) == invalid])

Dold text
PermalÀnk
●

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

Trevligt problem idag, inte sÄ mycket parsing som det varit dom tidigare dagarna

PermalÀnk
Medlem
●

Inte lika snabb som Go, inte lika snygg som Python, men jag löste det i alla fall. Dag 9, Scala.

object Xmas extends App { def apply(l: List[BigInt]) = new Xmas(l) //Uppgift 1 def findNonValid(in: List[BigInt], preambleSize: Int):Option[BigInt] = { val candidates = in.drop(preambleSize) candidates.foldLeft(Xmas(in.take(preambleSize))) { (acc, elem) => acc.add(elem) }.nonvalids.headOption } //Uppgift 2 def find(list: List[BigInt], wanted: BigInt): Option[BigInt] = { for { x <- 0 to list.size y <- x to list.size if (y - x > 1) slice = list.slice(x,y) if (slice.sum == wanted) } return Some(slice.min + slice.max) None } class Xmas(val preamble: List[BigInt]) { import scala.collection.mutable val nonvalids = new mutable.Queue[BigInt]() val source = new mutable.Queue().addAll(preamble) def valids = (for { x <- source; y <- source; if x!=y } yield (x + y)).distinct def add(x: BigInt): Xmas = { if (source.contains(x) || !valids.contains(x)) nonvalids.addOne(x) else source.addOne(x).dequeue() this } } }

Uppgift 2 försökte jag först skapa alla permutations rekursivt med immutables och sen köra fold, out of memory inte sĂ„ ovĂ€ntat. Sen försökte jag en rekursiv med head/tail pekare, avbröt den efter 5 minuter (kan ha funnits en bugg). Denna lösning kör pĂ„ lite under en sekund vilket Ă€ndĂ„ Ă€r rĂ€tt kasst jĂ€mfört med Flexberts 16ÎŒs, ska fundera hur jag kan optimera bĂ„de snygghet och hastighet. Efter att jag hunnit igenom nĂ€sta ML kapitel i boken.

Edit: Kunde ju inte slÀppa det hÀr. Nytt försök pÄ tvÄan:

def find(list: List[BigInt], wanted: BigInt): Option[BigInt] = { for { x <- 1 to list.size slice <- list.sliding(x) if (slice.sum == wanted) } return Some(slice.min + slice.max) None }

Nu körde den pÄ 8 mllisecs. Ett par orders of magnitude snabbare Àn tidigare. Forfarande 3 orders of magnitude lÄngsammare Àn Go, men det fÄr duga för icke-kompilerad, icke-jittad kod som körs i en REPL.

Dold text
PermalÀnk
Datavetare ★
●

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

Dagens problem skulle konceptuellt passa rÀtt bra för GPGPU, bara rÀkna startindex parallellt pÄ olika GPU-cores. Men givet att en rÀtt brute-force lösning i Swift tar nÄgra millisekunder (edit: att lÀsa in filen tar 3-4 ms, att lösa problemet tar <1ms pÄ en 3900X) Àr det ingen riktig poÀng...

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
●

Jag hade helt glömt bort AoC i Är. Gick tillbaka och löste nÄgra av de kortare problemen ocksÄ.

Dag 9 Scala:

@main def day09 = val input = Using.resource(Source.fromFile("9.txt"))(_.getLines().flatMap(_.toIntOption).toList) val part1 = input.sliding(25).zip(input.drop(25)).collectFirst { case (preamble, n) if !preamble.combinations(2).map(_.sum).contains(n) => n }.get.tap(println) (2 to input.size).view .flatMap(input.sliding) .collectFirst { case xs if xs.sum == part1 => xs.min + xs.max} .get.pipe(println)

Dold text

Dag 1 Scala & Dyalog APL:

scala: @main def day01 = val input = Using.resource(Source.fromFile("1.txt"))(_.getLines().flatMap(_.toIntOption).toList) input.combinations(2).collectFirst { case xs if xs.sum == 2020 => xs.product }.foreach(println) input.combinations(3).collectFirst { case xs if xs.sum == 2020 => xs.product }.foreach(println) dyalog: d←⍎¹⊃⎕nget'1.txt'1 ×/d[⊃⍾2020=∘.+⍹d] ×/d[⊃⍾2020=∘.+⍣2⍹d]

Dold text

Dag 2 Scala:

@main def day01 = val input = Using.resource(Source.fromFile("1.txt"))(_.getLines().toList) input.count { case s"${lo}-${hi} ${ltr}: ${pwd}" => val count = pwd.count(_ == ltr.head) lo.toInt <= count && count <= hi.toInt }.pipe(println) input.count { case s"${lo}-${hi} ${ltr}: ${pwd}" => pwd.charAt(lo.toInt - 1) == ltr.head ^ pwd.charAt(hi.toInt - 1) == ltr.head }.pipe(println)

Dold text

Dag 5 Scala & Dyalog APL:

scala: @main def day05 = val input = Using.resource(Source.fromFile("5.txt")) (_.getLines().map(str => Integer.valueOf(str.replaceAll("B|R", "1").replaceAll("F|L", "0"), 2)).toList) input.max.pipe(println) input.sorted.sliding(2).collectFirst { case List(a, b) if b - a != 1 => a + 1}.foreach(println) dyalog: d←{2⊄⍔∊'BR'}¹⊃⎕NGET'5.txt'1 ⌈/d 1+sâŒ·âšâžÂŻ2=2-/s←d[⍋d]

Dold text

Dag 6 Scala & Dyalog APL:

scala: @main def day06 = val input = Using.resource(Source.fromFile("6.txt"))(_.mkString.split("\n\n").map(_.split('\n'))) input.map(_.reduce(_ ++ _).distinct.size).sum.pipe(println) input.map(_.reduce(_ intersect _).size).sum.pipe(println) dyalog: d←{⍔⊆⍚(⊂'')â‰ąÂšâ”}⊃⎕NGET'6.txt' 1 +/{≱⊃âˆȘ/⍔}šd +/{â‰ąâŠƒâˆ©/⍔}šd

Dold text
PermalÀnk
Medlem
●
Skrivet av jclr:

Jag hade helt glömt bort AoC i Är. Gick tillbaka och löste nÄgra av de kortare problemen ocksÄ.

Kul med nÄgon annan som kör Scala ocksÄ! Se dÀr, dag 9 uppgift 1 gick att lösa funktionellt ocksÄ, misstÀnkte det men gav upp.

PermalÀnk
Medlem
●

Dag: 9
SprÄk: Powershell
Lösning: Github

Tycker sjÀlv att jag fick till en bra lösning som blev snabbare Àn vad jag trodde

Visa signatur

Vad vore vÀrlden utan silvertejp?

PermalÀnk
Medlem ★
●

Edit; Lite break och continue gjorde Part2 snabb.

void Main() {
var lines = File.ReadAllLines("day-09.txt");
var parse = Parse(lines);
var part1 = Part1(parse);
var part2 = Part2(parse, part1);
}

long[] Parse(string[] lines) {
var parsed = new long[lines.Length];
for (int i = 0; i < lines.Length; i++) { parsed[i] = long.Parse(lines[i]); }
return parsed;
}

const int preamble = 25;

long Part1(long[] numbers) {
for (int i = preamble; i < numbers.Length; i++) {
var number = numbers[i];
var contains = false;
for (int j = i - preamble; j < i; j++) {
if (contains) { break; }
for (int k = i - preamble; k < i; k++) {
if (numbers[j] + numbers[k] == number) { contains = true; break; }
}
}
if (!contains) { return number; }
}
return -1L;
}

long Part2(long[] numbers, long part1) {
for (int i = numbers.Length - 1; 0 <= i; i--) {
var number1 = numbers[i];
var sum = number1;
if (sum > part1) { continue; }
var range = new List<long> { number1 };
for (int j = i - 1; 0 <= j; j--) {
var number2 = numbers[j];
sum += number2;
if (sum > part1) { break; }
range.Add(number2);
if (sum == part1) { return range.Min() + range.Max(); }
}
}
return -1L;
}

Dag: 9 // SprÄk: c#