🌟 Advent of Code (AoC) 2023 🌟

PermalÀnk
●

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

Den hÀr kÀndes ganska svÄr, körde en naiv metod först men var tvungen att optimera min lösning...

Först tÀnkte jag bara skapa en dictionary för varje map, med det var ju sjukt mÄnga tal sÄ RAM-minnet tog slut. DÄ gick jag istÀllet över till att spara intervallen istÀllet och loopa över dom.
PÄ del 2 försökte jag inte ens att gÄ frÄn seed till location utan valde att gÄ frÄn location till seed och kolla om det existerar. Den hÀr lösningen tog "bara" 3 minuter att köra.

Dold text
PermalÀnk
Medlem ★
●

Dag: 3
SprÄk: Python

Nöjd med hur pass kompakt del 2 blev. Del 1 gÄr att snygga till med ett par loopar till, men det orkar jag inte

Del tvÄ gÄr dessutom egentligen att minska ner ytterligare. Min input har t.ex. aldrig fler Àn tvÄ tal bredvid ett kugghjul.

import re def not_empty(str): return not str == "." and not str.isdigit() def find_number(pos_x, pos_y, str): start = end = pos_x while str[start].isdigit(): start-=1 while str[end].isdigit(): end+=1 return int(str[start+1:end]),start+1,end,y with open('input.txt') as file: lines=file.read().splitlines() schematic = [] schematic.append("."*(len(lines[0])+2)) for line in lines: schematic.append("." + line + ".") schematic.append("."*(len(lines[0])+2)) #Part 1 sum = 0 for y, line in enumerate(schematic): for m in re.finditer("\d+", line): isolated = True if not_empty(schematic[y-1][m.start()-1]) or not_empty(schematic[y][m.start()-1]) or not_empty(schematic[y+1][m.start()-1]): isolated = False for x in range(m.start(), m.end()): if not_empty(schematic[y-1][x]) or not_empty(schematic[y+1][x]): isolated = False if not_empty(schematic[y-1][m.end()]) or not_empty(schematic[y][m.end()]) or not_empty(schematic[y+1][m.end()]): isolated = False if not isolated: sum+=int(m.group(0)) print("Part one:", sum) #Part 2 gear_sum = 0 for y, line in enumerate(schematic): for m in re.finditer("\*", line): numbers = [] for i in range(-1,2): for j in range(-1,2): if schematic[y+i][m.start()+j].isdigit(): numbers.append(find_number(m.start()+j,y+i, schematic[y+i])) unique_numbers = list(set(numbers)) if(len(unique_numbers) == 2): gear_sum+=unique_numbers[0][0]*unique_numbers[1][0] print("Part two:", gear_sum)

Dold text
PermalÀnk
Medlem ★
●

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

Kul dag, började ocksÄ med en naiv lösning som jag antog skulle faila pÄ del 2 men var inte ens nÀra att klara del 1.

Gjorde samma sak som @huggeMugg och försökte först stoppa in alla mappningar i en BTreeMap sÄ uppdaterade till nuvarande Vec<(Range<usize>, usize)> som Àr en lista av tuples med en range för src och start pÄ dst. Listan Àr sorterad sÄ jag kan anvÀnda binary search för att hitta rÀtt tuple.

Blev lite rÀdd för Del 2 nÀr den tuggat pÄ lÀnge utan resultat men kom pÄ att jag kompilerat i debug mode. Efter release mode ser runtime ut sÄhÀr:

Part 1 took 0.043083ms
Part 2 took 41178.652ms

Fortfarande inte en tid att va stolt över kanske men inget jag orkar försöka optimera

Dold text

@huggeMugg Noterade att din input ligger i ditt repo, det finns visserligen inget superofficellt sagt om enstaka inputs men generellt Àr det att rekomendera att gitignora input filerna https://www.reddit.com/r/adventofcode/wiki/faqs/copyright/inp...

PermalÀnk
TangentbordskonnĂ€ssör ★
●

Ligger hopplöst efter, men tuggar pÄ i egen takt.

Dag: 2
SprÄk: Erlang

GitHub

-module(day2). -export([part1/1, part2/1]). part1(File) -> Games = get_formatted_game_data(File), get_valid_games(Games). part2(File) -> Games = get_formatted_game_data(File), get_power_of_games(Games). -spec get_formatted_game_data(File :: binary()) -> [{integer(), [[{}]]}]. get_formatted_game_data(File) -> {ok, FileContent} = file:read_file(File), Lines = binary:split(FileContent, <<"\n">>, [global]), {Games, _} = lists:foldl( fun(X, {Accu, Count}) -> ColorsAndValues = separate_colors(remove_game_text(X)), case is_list(ColorsAndValues) of true -> {[{Count, ColorsAndValues} | Accu], Count + 1}; _ -> Accu end end, {[], 1}, Lines ), Games. get_power_of_games(Games) -> Result = lists:foldl( fun({_GameNr, GameSets}, SumOfGames) -> {GreenInt, BlueInt, RedInt} = lists:foldl( fun(Y, {CurrentGreenInt, CurrentBlueInt, CurrentRedInt}) -> {get_highest_int(CurrentGreenInt, get_int(<<"green">>, Y)), get_highest_int(CurrentBlueInt, get_int(<<"blue">>, Y)), get_highest_int(CurrentRedInt, get_int(<<"red">>, Y))} end, {1, 1, 1}, GameSets), GameResult = GreenInt * BlueInt * RedInt, SumOfGames + GameResult end, 0, Games), Result. get_valid_games(Games) -> MaxBlue = 14, MaxGreen = 13, MaxRed = 12, ValidGames = lists:foldl( fun({GameNr, List}, TotalNrOfValidGames) -> OkList = lists:filter( fun(Y) -> GreenInt = get_int(<<"green">>, Y), BlueInt = get_int(<<"blue">>, Y), RedInt = get_int(<<"red">>, Y), BlueOk = BlueInt < MaxBlue orelse BlueInt == MaxBlue, GreenOk = GreenInt < MaxGreen orelse GreenInt == MaxGreen, RedOk = RedInt < MaxRed orelse RedInt == MaxRed, case {BlueOk, GreenOk, RedOk} of {true, true, true} -> true; _ -> false end end, List), case length(List) == length(OkList) of true -> TotalNrOfValidGames + GameNr; false -> TotalNrOfValidGames end end, 0, Games), ValidGames. -spec get_int(Color :: binary(), Data :: map()) -> integer(). get_int(Color, Data) -> case lists:keyfind(Color, 1, Data) of false -> 0; {_, GreenValue0} -> list_to_integer(GreenValue0) end. -spec get_highest_int(Current :: integer(), New :: integer()) -> integer(). get_highest_int(Current, New) -> CurrentIsHigher = Current > New, case CurrentIsHigher of true -> Current; false -> New end. remove_game_text(Game) -> {Position, _Length} = binary:match(Game, <<":">>), SpaceAndColonRemovedPosition = Position +2, GameStringLength = byte_size(Game) - SpaceAndColonRemovedPosition, Extracted = binary:part(Game, SpaceAndColonRemovedPosition, GameStringLength), Extracted. separate_colors(Game) -> GameSplits = binary:split(Game, <<";">>, [global]), ColorValues = lists:foldl( fun(X, Acc) -> Colors = binary:split(X, <<",">>, [global]), ColorValues = lists:foldl( fun(Color, Acc1) -> [extract_color_and_value(Color) | Acc1] end, [], Colors), [ColorValues | Acc] end, [], GameSplits), ColorValues. extract_color_and_value(Input) -> Colors = [<<"green">>, <<"blue">>, <<"red">>], lists:foldl( fun(Color, Acc) -> case string:find(Input, Color) of nomatch -> Acc; _ -> {Color, get_digits(Input)} end end, [], Colors). get_digits(Input) -> InputString = binary_to_list(Input), lists:filtermap( fun(Char) -> lists:member(Char, "0123456789") end, InputString).

Dold text
PermalÀnk
●
Skrivet av Pie-or-paj:

@huggeMugg Noterade att din input ligger i ditt repo, det finns visserligen inget superofficellt sagt om enstaka inputs men generellt Àr det att rekomendera att gitignora input filerna https://www.reddit.com/r/adventofcode/wiki/faqs/copyright/inp...

Jo jag Àr medveten om att dom hade den regeln förut, men jag har för mig att dom tog bort den (eller sa att den inte var sÄ viktig) typ förra Äret. Men det kan ju sÄklart ha Àndrats iom alla LLM, dom vill kanske inte att dom ska trÀnas pÄ dom ocksÄ. Jag ska fixa gitignoren, tack

PermalÀnk
Medlem ★
●

Dag: 5
SprÄk: Matlab
Körtid: 0.06 s (vid en körning, 10 repeterade körningar ger 0.04 s i medeltal)

fid=fopen('day5.txt'); line = fgetl(fid); seed=double(string(split(extractAfter(line, "seeds: "), " "))); seedRange=[seed(1:2:end), seed(1:2:end)+seed(2:2:end)-1]; while ~feof(fid) line = fgetl(fid); switch line case "seed-to-soil map:" seedToSoil = map(fid); case "soil-to-fertilizer map:" soilToFertilizer = map(fid); case "fertilizer-to-water map:" fertilizerToWater = map(fid); case "water-to-light map:" waterToLight = map(fid); case "light-to-temperature map:" lightToTemp = map(fid); case "temperature-to-humidity map:" tempToHumidity = map(fid); case "humidity-to-location map:" humidityToLocation = map(fid); end end fclose(fid); Score1 = min(mapFind(humidityToLocation, ... mapFind(tempToHumidity, ... mapFind(lightToTemp, ... mapFind(waterToLight, ... mapFind(fertilizerToWater, ... mapFind(soilToFertilizer, ... mapFind(seedToSoil, seed)))))))); Score2 = min(min(mapFindRange(humidityToLocation, ... mapFindRange(tempToHumidity, ... mapFindRange(lightToTemp, ... mapFindRange(waterToLight, ... mapFindRange(fertilizerToWater, ... mapFindRange(soilToFertilizer, ... mapFindRange(seedToSoil, seedRange))))))))); disp(['Task 1: ', num2str(Score1)]) disp(['Task 2: ', num2str(Score2)]) function y = map(fid) y=[]; line = fgetl(fid); while ~isempty(line) && ~feof(fid) y = [y; double(string(split(line, " ")))']; line = fgetl(fid); end end function y = mapFind(map, x) y = []; for k = reshape(x, 1, []) row=find(map(:, 2)<=k & map(:, 2)+map(:, 3)>k); if isempty(row) y = [y k]; else y = [y map(row, 1) + k - map(row, 2)]; end end end function y = mapFindRange(map, x) y = []; for k = 1:length(map(:, 1)) for l = 1:length(x(:, 1)) if ~isnan(x(l, :)) if x(l,2) >= map(k, 2) && x(l,1) < map(k, 2) + map(k, 3) y = [y; [max(x(l, 1), map(k, 2)) min(map(k, 2) + ... map(k, 3)- 1, x(l, 2))] - diff([map(k, 1) ... map(k, 2)])]; end if x(l,1) < map(k, 2) x = [x; [x(l,1) min(map(k, 2) -1, x(l,2)) ]]; end if x(l,2) >= map(k, 2) + map(k, 3) x = [x; [max(map(k, 2) + map(k, 3), x(l,1)) x(l,2)]]; end x(l, :) = [NaN, NaN]; end end end y = [y; [x(x(:, 1)>=0, 1) x(x(:, 2)>=0, 2)]]; end

Dold text
Lade till körtid
PermalÀnk
Medlem ★
●

Dag 5

Lite besviken pÄ att det gick hur bra som helst att bruteforcea del 2 idag.
Jag hade 10 st par (antar att det var standard) och jag körde 10st workerthreads sÄ jag kunde exekvera dem parallellt (nodejs). Tog 15 min för det största att bli klart (ungefÀr 750 miljoner frö i det intervallet) och dÄ satt jag i daily ÀndÄ. InsÄg att det eventuellt skulle ta en jÀkla tid men hade inte tid att skriva en elegant lösning innan vÄr daily sÄ den fick tugga istÀllet.

10 gÄnger mer data hade fortfarande funkat
100 gÄnger mer... ok nu börjar det bli drygt

Dold text
Visa signatur

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

PermalÀnk
●

Dag: 5
SprÄk: C

Jag gillar nÀr det mÄste optimeras lite!

#include <limits.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAXLINE 256 #define MAXSEEDS 20 #define NMAPS 7 #define NFIELDS 3 #define NRULES 64 #define DEST 0 #define SRC 1 #define RANGE 2 #define EMPTY -1 #define FORWARD 0 #define BACKWARD 1 #define MIN(a,b) ((a) < (b) ? (a) : (b)) void readproblemfile(long int seeds[MAXSEEDS], long int maps[NMAPS][NRULES][NFIELDS]); void readlist(char* str, long int* list); long int lookup(long int val, long int map[NRULES][NFIELDS], int dir); int isseed(long int s, long int seeds[MAXSEEDS]); long int part1(long int seeds[MAXSEEDS], long int maps[NMAPS][NRULES][NFIELDS]); long int part2(long int seeds[MAXSEEDS], long int maps[NMAPS][NRULES][NFIELDS]); int main() { long int seeds[MAXSEEDS]; memset(seeds, 0xFF, sizeof seeds); // Set all to EMPTY. long int maps[NMAPS][NRULES][NFIELDS]; memset(maps, 0xFF, sizeof maps); // Set all to EMPTY. readproblemfile(seeds, maps); printf("Part 1: %li\nPart 2: %li\n", part1(seeds, maps), part2(seeds, maps)); } // For part 1, just check the location of each seed. long int part1(long int seeds[MAXSEEDS], long int maps[NMAPS][NRULES][NFIELDS]) { long int result = LONG_MAX; for (int i=0; i<MAXSEEDS && seeds[i] != EMPTY; ++i) { long int loc = seeds[i]; for (int m = 0; m < NMAPS; ++m) loc = lookup(loc, maps[m], FORWARD); result = MIN(loc, result); } return result; } // For part 2, it is faster to search backwards (location to // seed) instead of forwards (seed to location). // Also, start with a step size about the size of the smallest // seed range and use a logarithmic search pattern. long int part2(long int seeds[MAXSEEDS], long int maps[NMAPS][NRULES][NFIELDS]) { long int seed, location = 0; int stepsign = 1, stepsize = INT_MAX; for (int i=1; i<MAXSEEDS && seeds[i] != EMPTY; i+=2) stepsize = MIN(stepsize, seeds[i]); while (1) { location += stepsign * stepsize; seed = location; for (int m = NMAPS-1; m >= 0; --m) seed = lookup(seed, maps[m], BACKWARD); if (stepsign != (isseed(seed, seeds) ? -1 : 1)) { if (stepsize == 1) return stepsign == 1 ? location : location + 1; stepsize /= 2; stepsign *= -1; } } } // Read the problem data from file. void readproblemfile(long int seeds[MAXSEEDS], long int maps[NMAPS][NRULES][NFIELDS]) { char line[MAXLINE]; FILE* fptr = fopen("input", "r"); // First read list of seeds. if (fgets(line, sizeof line, fptr) != NULL) readlist(line + 7, seeds); // "+7" skips prefix "Seeds: ". // Then read all the various maps. int i_map = -1, i_rule = 0; while (fgets(line, sizeof line, fptr) != NULL) { long int dst, src, range; if (strstr(line, "map:") != NULL) { ++i_map; i_rule = 0; } else if (sscanf(line, "%li %li %li", &dst, &src, &range) == 3) { maps[i_map][i_rule][DEST] = dst; maps[i_map][i_rule][SRC] = src; maps[i_map][i_rule][RANGE] = range; ++i_rule; } } } // Convert string to list of numbers. void readlist(char* str, long int* list) { int i = 0, num_read; while (1) { if (sscanf(str, "%li %n", &list[i++], &num_read) != 1) break; str += num_read; } } // Look up a value in a map. direction dir can be // 0 or FORWARD: find destination from source. // 1 or BACKWARD: find source from destination. long int lookup(long int val, long int map[NRULES][NFIELDS], int dir) { for (int i = 0; i < NRULES && map[i][0] != EMPTY; ++i) { if (val >= map[i][SRC-dir] && val < map[i][SRC-dir] + map[i][RANGE]) { val += map[i][dir-DEST] - map[i][SRC-dir]; break; } } return val; } // Return 1 if s is a seed according to rules of part 2. int isseed(long int s, long int seeds[MAXSEEDS]) { for (int i=0; i+1<MAXSEEDS; i+=2) if (seeds[i] != EMPTY && s >= seeds[i] && s < seeds[i] + seeds[i+1]) return 1; return 0; }

Dold text
PermalÀnk
●
Skrivet av Iskra:

Dag: 5
SprÄk: Matlab
Körtid: 0.06 s (vid en körning, 10 repeterade körningar ger 0.04 s i medeltal)

Jag hÀnger inte med i svÀngarna dÀr i mapFindRange, men bra tider!

PermalÀnk
Medlem ★
●
Skrivet av Gubbjekeln:

Jag hÀnger inte med i svÀngarna dÀr i mapFindRange, men bra tider!

Tackar! Inte sÄ bra funktionsnamn kanske. Jag tÀnker mig att fröna hanteras som ett omfÄng ("range") och att tillÀmpningen av reglerna för hur de ska placeras Àr en "mappning". Logiskt sett borde funktionen kanske heta rangeMap() istÀllet. findMap() Àr tillÀmpningen av reglerna i uppgift 1, och map() Àr funktionen för att lÀsa in reglerna frÄn textfilen.

Hastigheten beror pÄ att jag inte hanterar varje datapunkt utan bara behöver början och slutet pÄ varje omfÄng.

PermalÀnk
Medlem ★
●
Skrivet av Iskra:

Tackar! Inte sÄ bra funktionsnamn kanske. Jag tÀnker mig att fröna hanteras som ett omfÄng ("range") och att tillÀmpningen av reglerna för hur de ska placeras Àr en "mappning". Logiskt sett borde funktionen kanske heta rangeMap() istÀllet. findMap() Àr tillÀmpningen av reglerna i uppgift 1, och map() Àr funktionen för att lÀsa in reglerna frÄn textfilen.

Hastigheten beror pÄ att jag inte hanterar varje datapunkt utan bara behöver början och slutet pÄ varje omfÄng.

Jag har ocksÄ stirrat pÄ mapFindRange ett tag och försökt att komma pÄ hemligheten

Var pÄ vÀg att skriva en frÄga för jag fortfarande inte förstod trots den beskrivningen men till slut trillade polletten ner nÀr jag formulerade mig. Smart!

PermalÀnk
Medlem ★
●

Dag: 5
SprÄk: Python

Det blev ganska normal Python den hÀr gÄngen. Namngivna funktioner och variabler för tydlighetens skull

import re numbers = re.compile(r'\d+') blobs = open("input05.txt").read().split('\n\n') seeds = list(map(int, numbers.findall(blobs[0]))) tables = [[ns for line in blob.split('\n') if (ns := list(map(int, numbers.findall(line))))] for blob in blobs[1:]] def pointinrange(p, r): return r[0] <= p < r[0] + r[1] def rangeinrange(r1, r2): return pointinrange(r1[0], r2) and pointinrange(r1[0] + r1[1] - 1, r2) def lookuprange(r, table): rs, rl = r for d,s,l in table: r2 = (s,l) if rangeinrange(r, r2): return [(rs + (d - s), rl)] elif rangeinrange(r2, r): # split into three ret = [] if outside := s - rs: ret.extend(lookuprange((rs, outside), table)) ret.append((d, l)) if outside := rl - l - (s - rs): ret.extend(lookuprange((s + l, outside), table)) return ret elif pointinrange(rs, r2): end = s + l inside = end - rs outside = rl - inside return [(rs + (d - s), inside)] + lookuprange((end, outside), table) elif pointinrange(rs + rl - 1, r2): outside = s - rs return lookuprange((rs, outside), table) + [(d, rl - outside)] return [r] def lookupranges(ranges, tables): for t in tables: newkeys = [] for r in ranges: newkeys.extend(lookuprange(r, t)) ranges = newkeys return ranges print(min([min(lookupranges([(s,1)], tables)) for s in seeds])[0], min([min(lookupranges([p], tables)) for p in zip(seeds[0::2], seeds[1::2])])[0])

Dold text
PermalÀnk
●

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

Det Àr vÀldigt inkonsekvent svÄrighetsgrad kÀnner jag. Idag var busenkel jÀmfört med gÄrdagen. Jag hade en kÀnsla av att dom kommer slÀnga nÄgon curveball pÄ del 2 nÀr jag gjorde del 1 men det var egentligen bara att anvÀnda samma kod dÀr med.

Det enda som var lite klurigt var nog parsingen, att man hade mycket whitespace mellan siffrorna. Paradoxalt nog var del 2 enklare Àn del 1 eftersom det bara var att göra en replace(" ", "") istÀllet för att plocka ut flera siffror. FÄr se om jag lyckats jinxa morgondagen nu xD

Dold text
PermalÀnk
Medlem ★
●

Dag: 6
SprÄk: Python (One-liner)

Dagens uppgift var inte sÀrskilt svÄr. Jag trodde jag skulle behöva intervallhalvera för att hitta punkterna dÀr man började och slutade vinna, men det var inga som helst probelm att brute-force:a ens i Python.

import re from math import prod print([f(lambda t: [x for i in range(t[0]) if (x := i * (t[0] - i)) > t[1]]) for f in [lambda f: prod(map(len, map(f, zip(*[list(map(int, re.findall(r"\d+", line))) for line in open("input06.txt").readlines()])))), lambda f: len(f(tuple(map(int, ["".join(re.findall(r"\d+", line)) for line in open("input06.txt").readlines()]))))]])

Dold text
PermalÀnk
Medlem ★
●

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

>Det Àr vÀldigt inkonsekvent svÄrighetsgrad kÀnner jag. Idag var busenkel jÀmfört med gÄrdagen. Jag hade en kÀnsla av att dom
>kommer slÀnga nÄgon curveball pÄ del 2 nÀr jag gjorde del 1 men det var egentligen bara att anvÀnda samma kod dÀr med.

Ja problemet hade nog fungerat bÀttre om inputen bara hade fler "race" sÄ att den naiva lösningen inte fungerat rakt av. Men fortfarande tidigt, efter dag 10 brukar det komma problem som omöjligt löses med brute force.

Parsningen stĂ€llde till det lite iom. strukturen i min template. Önskade att jag kunnat göra nĂ„got Ă„t inputen i del 2 innan den gemensamma parse funktionen körde men men, blev lite fulkod dĂ€r idag.

Dold text
PermalÀnk
Medlem ★
●

Dag: 6
SprÄk: Matlab
Körtid: 0.02 s - 0.06 s (max/min av 10 körningar)

LĂ€ttaste uppgiften hittills.

fid=fopen('day6.txt'); %%Task 1 timeLimit=double(string(extract(fgetl(fid), digitsPattern())))'; recordDistance=double(string(extract(fgetl(fid), digitsPattern())))'; Score1 = []; for k = 1:length(timeLimit) Score1 = [Score1 winPressTimeNo(timeLimit(k), recordDistance(k))]; end Score1 = prod(Score1); %% Task 2 timeLimit = double(strrep(join(string(timeLimit)),' ','')); recordDistance = double(strrep(join(string(recordDistance)),' ','')); Score2 = winPressTimeNo(timeLimit, recordDistance); disp(['Task 1: ', num2str(Score1)]) disp(['Task 2: ', num2str(Score2)]) function n = winPressTimeNo(a, b) % Computes the max and min press time using the pq formula minPressTime = ceil((a/2-sqrt(a^2/2^2-b))); maxPressTime = floor((a/2+sqrt(a^2/2^2-b))); c = ((a-minPressTime) * minPressTime > b) + ... ((a-maxPressTime) * maxPressTime > b); n = (maxPressTime - minPressTime + c - 1); end

Dold text
PermalÀnk
Medlem
●

Dag: 6
SprÄk: TypeScript

Dessa uppgifter var oerhört enkla jÀmfört med gÄrdagens (som jag för övrigt fortfarande inte löst 2an pÄ )

Uppgift 1

import fs from 'fs' const BOAT_SPEED = 1 const FILE_PATH = './src/resources/06.txt' interface Race { time: number distanceToBeat: number } export default function sumOfRaceWins (): void { const lines = fs.readFileSync(FILE_PATH, 'utf-8').trim().split('\n') const allRaces: Race[] = getAllRaces(lines) const amountOfPossibleWins: number[] = [] allRaces.forEach((race) => { amountOfPossibleWins.push(findWinCombinations(race)) }) console.log( 'Sum of total win possibilities', amountOfPossibleWins.reduce((sum, next) => sum * next) ) } function findWinCombinations (raceToBeat: Race): number { const { distanceToBeat, time } = raceToBeat let winCount = 0 for (let i = 1; i < time; i++) { const boatCurrentSpeed = i * BOAT_SPEED const totalDistanceTraveled = (time - i) * boatCurrentSpeed if (totalDistanceTraveled > distanceToBeat) winCount++ } return winCount } function getAllRaces (lines: string[]): Race[] { const races: Race[] = [] const numRegeex: RegExp = /\d+/g const timesMatches = lines[0].match(numRegeex) // times const distanceMatches = lines[1].match(numRegeex) // distance if (timesMatches !== null && distanceMatches !== null) { for (let i = 0; i < timesMatches.length; i++) { races.push({ time: parseInt(timesMatches[i]), distanceToBeat: parseInt(distanceMatches[i]) }) } } return races }

Dold text

Uppgift 2
Det enda som Àndrades i denna Àr hur jag lÀser ut tiden och distancen pÄ racet, annars exakt likadant som uppgift 1.

import fs from 'fs' const BOAT_SPEED = 1 const FILE_PATH = './src/resources/06.txt' interface Race { time: number distanceToBeat: number } export default function sumOfRaceWins2 (): void { const lines = fs.readFileSync(FILE_PATH, 'utf-8').trim().split('\n') const allRaces: Race[] = getAllRaces(lines) const amountOfPossibleWins: number[] = [] allRaces.forEach((race) => { amountOfPossibleWins.push(findWinCombinations(race)) }) console.log( 'Sum of total win possibilities', amountOfPossibleWins.reduce((sum, next) => sum * next) ) } function findWinCombinations (raceToBeat: Race): number { const { distanceToBeat, time } = raceToBeat let winCount = 0 for (let i = 1; i < time; i++) { const boatCurrentSpeed = i * BOAT_SPEED const totalDistanceTraveled = (time - i) * boatCurrentSpeed if (totalDistanceTraveled > distanceToBeat) winCount++ } return winCount } function getAllRaces (lines: string[]): Race[] { const races: Race[] = [] const numRegeex: RegExp = /\d+/g const timesMatches = lines[0].match(numRegeex) // times const distanceMatches = lines[1].match(numRegeex) // distance if (timesMatches !== null && distanceMatches !== null) { let raceTime: string = '' let distance: string = '' for (let i = 0; i < timesMatches.length; i++) { raceTime += timesMatches[i] distance += distanceMatches[i] } races.push({ time: parseInt(raceTime), distanceToBeat: parseInt(distance) }) } return races }

Dold text
Visa signatur

Ryzen 7 7800X3D | Nvidia Geforce RTX 4070 Ti 12gb | Corsair Vengeance DDR5 6000MHz RGB CL30 2x16GB | EVGA Supernova G2 750W | ASUS ROG Strix B650E-F Gaming | Be Quiet! Dark Rock Pro 5
Citera för svar!

PermalÀnk
Medlem ★
●

Skönt med en lite lugnare dag, kod kommer nÀr jag gjort en snyggare parsing.

PermalÀnk
Hedersmedlem ★
●

Dag: 6
SprÄk: Python

Blev orolig att del tvÄ skulle bli mycket bökigare, men brute force gick ju pÄ ett par sekunder Àven i Python, sÄ jag hÄller med om att den var lÀttast hittills.

import re from dataclasses import dataclass @dataclass class Race: length: int record: int def ways_to_win_race(race): ways_to_win = 0 for hold_time in range(1, race.length): speed = hold_time # mm/s length = speed * (race.length - hold_time) if length > race.record: ways_to_win += 1 return ways_to_win if __name__=='__main__': lines = open('data/day6.txt').read().splitlines() NUMBER_REGEX = re.compile(r'\d+') times = NUMBER_REGEX.findall(lines[0]) records = NUMBER_REGEX.findall(lines[1]) races = list(map(lambda x: Race(*map(int, x)), zip(times, records))) part_2_race = Race(int("".join(times)), int("".join(records))) prod = 1 for race in races: prod *= ways_to_win_race(race) print(f"Part 1: {prod}") print(f"Part 2: {ways_to_win_race(part_2_race)}")

Dold text

Har inte heller kört klart dag 5 del 2 Ànnu. Del 1 gick smidigt, men jag har en idé till del 2 som jag inte riktigt lyckas utveckla vidare i huvudet.

Visa signatur

Asus ROG STRIX B550-F / Ryzen 5800X3D / 48 GB 3200 MHz CL14 / Asus TUF 3080 OC / WD SN850 1 TB, Kingston NV1 2 TB + NAS / Corsair RM650x V3 / Acer XB271HU (1440p165) / LG C1 55"
NAS: 6700K/16GB/Debian+ZFS | Backup (offsite): 9600K/16GB/Debian+ZFS

PermalÀnk
Medlem ★
●

Dag: 6
SprÄk: F#

open System type Race = { record: int64; time: int64 } let readFile = System.IO.File.ReadAllLines("input.txt") |> Seq.map ( (fun c -> c.Split(' ', StringSplitOptions.TrimEntries ||| StringSplitOptions.RemoveEmptyEntries)) >> Seq.toList ) |> Seq.toList |> List.transpose |> List.skip 1 //Remove "header" let calculateDistances maxTime = [ 1L .. maxTime ] |> List.map (fun x -> (maxTime - x) * x) let parseRace (c: string list) = { record = int64 c.[1] time = int64 c.[0] } let CountAlternatives = parseRace >> fun race -> ((calculateDistances race.time) |> List.filter (fun x -> x > race.record) |> List.length) let task1 = List.map (CountAlternatives) let task2 = List.transpose >> List.map (String.concat "") >> CountAlternatives printfn $"Task 1: %i{readFile |> task1}" printfn $"Task 2: %i{readFile |> task2}"

Dold text

Dagens var lÀtt. Har som sÄ mÄnga fler i den hÀr gruppen kvar dag 5 del 2, jag har en idé pÄ hur jag ska göra den, men inte kommit sÄ lÄngt som att faktiskt programmera den.

Visa signatur

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

PermalÀnk
Medlem
●

Lite sen pÄ bollen men bÀttre sent Àn aldrig.

Dag: 1
SprÄk: Python

Del 1

https://www.online-python.com/EuRkTaMpzL

import re input_data = open('data.txt', 'r') # https://adventofcode.com/2023/day/1/input total = 0 for line in input_data: first = re.search(r'\d', line).group() last = re.findall(r'\d', line)[-1] if first and last: total += int(f"{first}{last}") print(total)

Dold text

Del 2
...

PermalÀnk
Datavetare ★
●

Dag: 6
SprÄk: Python

Även om det fungerade bra att brute-force:a Ă€ven med Python, sĂ„ gick du Ă€ven att lösa den 2:a-gradsekvation som "acceleration X i Y tidsenheter, följt av konstant hastighet i Z sekunder" ger.

Litet "hack" för att fixa till olikheten att man ska slÄ tidigare rekord, inte bara matcha det.

import functools import math def parse_boat_document(input): def parse_line(line): return [int(part) for part in line.split() if part[0].isdigit()] return list(zip(parse_line(input[0]), parse_line(input[1]))) def solve_quadratic_equation(b, c): d = math.sqrt(b**2 - 4*c) return ((-b - d) / 2, (-b + d) / 2) def possible_wins(raceDuration, record): roots = solve_quadratic_equation(-raceDuration, record + 0.1) first_win = math.ceil(roots[0]) last_win = math.floor(roots[1]) return last_win - first_win + 1 def margin(races): return functools.reduce(lambda partialMargin, race: partialMargin * possible_wins(*race), races, 1) def make_single_race(races): concatNumbers = lambda i: int(functools.reduce(lambda s, nPair: s+str(nPair[i]), races, '')) return (concatNumbers(0), concatNumbers(1)) def solve(input): races = parse_boat_document(input) print(margin(races)) print(margin([make_single_race(races)])) if __name__ == '__main__': solve(open('input/day6.txt').readlines())

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: 6
SprÄk: C

Jag skulle vilja hitta nÄn annan som kör C för att fÄ lite idéer. Jag kanske fÄr söka lite pÄ github eller reddit.

Körde andragradaren Àven om det inte behövdes. Lite synd att del 2 inte var jobbigare.

#include <math.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAXLINE 128 #define MAXRACES 4 // Data structure to hold problem details. typedef struct Race { long int time; long int distance; } Race; // Function declarations. int part1(Race*); int part2(Race*); int ways_to_win(Race r); Race* parseInput(); void readlist(char* str, int* list); long int concat(long int a, long int b); int main() { Race* races = parseInput(); printf("Part 1: %i\nPart 2: %i\n", part1(races), part2(races)); free(races); } int part1(Race* races) { int result = 1; for (int i = 0; i < MAXRACES && races[i].time > 0; ++i) result *= ways_to_win(races[i]); return result; } int part2(Race* races) { Race r = { .time = 0, .distance = 0 }; for (int i = 0; i < MAXRACES && races[i].time > 0; ++i) { r.time = concat(r.time, races[i].time); r.distance = concat(r.distance, races[i].distance); } return ways_to_win(r); } // Return the number of ways to win a race. // Solved as a quadratic equation. int ways_to_win(Race r) { double t = r.time; double d = r.distance; double tmp = sqrt(t*t/4 - d); return ceil(t/2+tmp) - floor(t/2-tmp) - 1; } // Read problem from input file. Race* parseInput() { Race* races = calloc(MAXRACES, sizeof (Race)); char line[MAXLINE]; FILE* fptr = fopen("input", "r"); if (fgets(line, sizeof line, fptr) != NULL) { int* tmp = calloc(MAXRACES, sizeof (int)); readlist(line + 10, tmp); for (int i = 0; i < MAXRACES; ++i) races[i].time = tmp[i]; } if (fgets(line, sizeof line, fptr) != NULL) { int* tmp = calloc(MAXRACES, sizeof (int)); readlist(line + 10, tmp); for (int i = 0; i < MAXRACES; ++i) races[i].distance = tmp[i]; } return races; } // Read list of numbers from string: "1 2 3" -> {1, 2, 3} void readlist(char* str, int* list) { int i = 0, num_read; while (1) { if (sscanf(str, "%i %n", &list[i++], &num_read) != 1) break; str += num_read; } } // Concatenate two numbers, so that concat(12, 34) == 1234. long int concat(long int a, long int b) { return a * pow(10, ceil( log10( b ))) + b; }

Dold text
PermalÀnk
Medlem
●

Dag 5 (Del 1 & 2)
SprÄk: Java
GitHub

Hade idéer för del 2, det borde ha funkat, men det tog för mycket tid att implementera.
Det blev brute force istÀllet. Den tiden som det tog rÀknas vÀl inte om man virkar medans datorn jobbar eller hur.

Dag: 6 (Del 1 & 2)
SprÄk: Java
GitHub

Dag 6 var vÀldigt enkelt i jÀmförelse med dag 5 del 2. Jo, kunde ha gjort det effektivare osv men.. if it works, it works.
Trodde först att del 2 skulle ha samma problem som med dag 5 del 2, men det funkade.

PermalÀnk
Datavetare ★
●
Skrivet av Gubbjekeln:

Dag: 6
SprÄk: C

Jag skulle vilja hitta nÄn annan som kör C för att fÄ lite idéer. Jag kanske fÄr söka lite pÄ github eller reddit.

Körde andragradaren Àven om det inte behövdes. Lite synd att del 2 inte var jobbigare.

#include <math.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAXLINE 128 #define MAXRACES 4 // Data structure to hold problem details. typedef struct Race { long int time; long int distance; } Race; // Function declarations. int part1(Race*); int part2(Race*); int ways_to_win(Race r); Race* parseInput(); void readlist(char* str, int* list); long int concat(long int a, long int b); int main() { Race* races = parseInput(); printf("Part 1: %i\nPart 2: %i\n", part1(races), part2(races)); free(races); } int part1(Race* races) { int result = 1; for (int i = 0; i < MAXRACES && races[i].time > 0; ++i) result *= ways_to_win(races[i]); return result; } int part2(Race* races) { Race r = { .time = 0, .distance = 0 }; for (int i = 0; i < MAXRACES && races[i].time > 0; ++i) { r.time = concat(r.time, races[i].time); r.distance = concat(r.distance, races[i].distance); } return ways_to_win(r); } // Return the number of ways to win a race. // Solved as a quadratic equation. int ways_to_win(Race r) { double t = r.time; double d = r.distance; double tmp = sqrt(t*t/4 - d); return ceil(t/2+tmp) - floor(t/2-tmp) - 1; } // Read problem from input file. Race* parseInput() { Race* races = calloc(MAXRACES, sizeof (Race)); char line[MAXLINE]; FILE* fptr = fopen("input", "r"); if (fgets(line, sizeof line, fptr) != NULL) { int* tmp = calloc(MAXRACES, sizeof (int)); readlist(line + 10, tmp); for (int i = 0; i < MAXRACES; ++i) races[i].time = tmp[i]; } if (fgets(line, sizeof line, fptr) != NULL) { int* tmp = calloc(MAXRACES, sizeof (int)); readlist(line + 10, tmp); for (int i = 0; i < MAXRACES; ++i) races[i].distance = tmp[i]; } return races; } // Read list of numbers from string: "1 2 3" -> {1, 2, 3} void readlist(char* str, int* list) { int i = 0, num_read; while (1) { if (sscanf(str, "%i %n", &list[i++], &num_read) != 1) break; str += num_read; } } // Concatenate two numbers, so that concat(12, 34) == 1234. long int concat(long int a, long int b) { return a * pow(10, ceil( log10( b ))) + b; }

Dold text

Inte C, men Go (d.v.s. low-level, inte lika low-level som C). Brute-force tar 14ms... Warning: hack för att testa prestanda, hÄrdkodad för min input.

➜ day6 time ./day6 36872656 ./day6 0.04s user 0.01s system 344% cpu 0.014 total

-----------

package main import ( "fmt" "runtime" ) type Race struct { Duration uint64 RecordDistance uint64 } func distance(accelerationTime, totalTime uint64) uint64 { return accelerationTime * (totalTime - accelerationTime) } func (race Race) isWin(accelerationTime uint64) bool { return distance(accelerationTime, race.Duration) > race.RecordDistance } func (race Race) numWins(from, cnt uint64) int { wins := 0 for accelerationTime := from; accelerationTime < from+cnt; accelerationTime++ { if race.isWin(uint64(accelerationTime)) { wins++ } } return wins } func totalWins(race Race) int { winsCh := make(chan int) numCpus := runtime.NumCPU() batchSz := race.Duration / uint64(numCpus+1) remAcceleration := race.Duration for i := 0; i < numCpus; i++ { start := batchSz * uint64(i) go func() { winsCh <- race.numWins(start, batchSz) }() remAcceleration -= batchSz } go func() { winsCh <- race.numWins(batchSz*uint64(numCpus), remAcceleration) }() totalWins := 0 for i := 0; i < numCpus+1; i++ { totalWins += <-winsCh } return totalWins } func main() { race := Race{ Duration: 62_73_75_65, RecordDistance: 644_1023_1240_1023, } fmt.Println(totalWins(race)) }

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

Inte C, men Go (d.v.s. low-level, inte lika low-level som C). Brute-force tar 14ms... Warning: hack för att testa prestanda, hÄrdkodad för min input.

Snyggt! Men jag sitter i WSL sÄ jag hara bara en cpu tillgÀnglig.

Gör du problemen i flera sprÄk?

PermalÀnk
Hedersmedlem ★
●

Skam den som ger sig.

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

Har undvikit GitHub för att jag inte vet hur lÀnge jag orkar köra, men det blir ju sÄ drygt att lÀsa kod pÄ SweClockers.

Denna tog pinsamt mycket arbete och tÀnkande, men det gick till slut. PÄ den ljusa sidan sÄ lyckades jag första gÄngen jag skickade in ett svar.
Ganska nöjd med den i slutÀndan, men det tog en del refactoring.

Dold text
Visa signatur

Asus ROG STRIX B550-F / Ryzen 5800X3D / 48 GB 3200 MHz CL14 / Asus TUF 3080 OC / WD SN850 1 TB, Kingston NV1 2 TB + NAS / Corsair RM650x V3 / Acer XB271HU (1440p165) / LG C1 55"
NAS: 6700K/16GB/Debian+ZFS | Backup (offsite): 9600K/16GB/Debian+ZFS

PermalÀnk
Medlem
●

Dag: 7
SprÄk: TypeScript
Lösning: GitHub

Uppgift 1

import fs from 'fs' import { groupBy } from '../helpers/array_helpers' const FILE_PATH = './src/resources/07.txt' type Card = string const CardStrength = { '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9, 'T': 10, 'J': 11, 'Q': 12, 'K': 13, 'A': 14 } const handType = [ 'FIVE_OF_KIND', 'FOUR_OF_KIND', 'FULL_HOUSE', 'THREE_OF_KIND', 'TWO_PAIR', 'ONE_PAIR', 'HIGH_CARD' ] as const type HandType = typeof handType[number] interface Hand { cards: Card[] bid: number type?: HandType rank?: number } export default function totalWinnings (): void { const lines = fs.readFileSync(FILE_PATH, 'utf-8').trim().split('\n') let hands: Hand[] = buildHandsArray(lines) hands = determineHandsRank(hands) let total = 0 hands.forEach((hand) => { total += hand.bid * (hand.rank ?? 0) }) console.log('Total winnings: ', total) } function buildHandsArray (lines: string[]): Hand[] { const returnHands: Hand[] = [] const numRegex: RegExp = /\d+/g lines.forEach((line) => { const hand = line.substring(0, 5) const bid = line.substring(5).match(numRegex) const cards: Card[] = [] for (const card of hand) { cards.push(card) } if (bid !== null) { const hand: Hand = { cards, bid: parseInt(bid[0]) } returnHands.push({ ...hand, type: getHandType(hand) }) } }) return returnHands } function getHandType (hand: Hand): HandType { const groupedCards = groupBy(hand.cards, (card) => card) const amountOfSimilarCards: number[] = [] groupedCards.forEach((group) => { amountOfSimilarCards.push(group.length) }) if (amountOfSimilarCards.includes(5)) { return 'FIVE_OF_KIND' } if (amountOfSimilarCards.includes(4)) { return 'FOUR_OF_KIND' } if (amountOfSimilarCards.includes(3) && amountOfSimilarCards.includes(2)) { return 'FULL_HOUSE' } if (amountOfSimilarCards.includes(3)) { return 'THREE_OF_KIND' } if (amountOfSimilarCards.filter((el) => el === 2).length === 2) { return 'TWO_PAIR' } if (amountOfSimilarCards.includes(2)) { return 'ONE_PAIR' } return 'HIGH_CARD' } function determineHandsRank (hands: Hand[]): Hand[] { const returnHands: Hand[] = [] const handsGroupedByType = groupBy(hands, (hand) => hand.type) let rank = hands.length handType.forEach((type) => { new Map([...handsGroupedByType].filter(([k, v]) => k === type)).forEach((hands) => { const sortedHands = hands.sort(sortCards) sortedHands.forEach((hand) => { returnHands.push({ ...hand, rank }) rank-- }) }) }) return returnHands } const sortCards = (cardA, cardB): number => { for (let i = 0; i < 5; i++) { const valueA = CardStrength[cardA.cards[i]] const valueB = CardStrength[cardB.cards[i]] if (valueA < valueB) { return 1 } else if (valueA > valueB) { return -1 } } return 0 }

Dold text

Uppgift 2

import fs from 'fs' import { groupBy } from '../helpers/array_helpers' const FILE_PATH = './src/resources/07.txt' type Card = string const CardStrength = { 'J': 1, '1': 2, '2': 3, '3': 4, '4': 5, '5': 6, '6': 7, '7': 8, '8': 9, '9': 10, 'T': 11, 'Q': 12, 'K': 13, 'A': 14 } const JOKER_CARD = 'J' const handType = [ 'FIVE_OF_KIND', 'FOUR_OF_KIND', 'FULL_HOUSE', 'THREE_OF_KIND', 'TWO_PAIR', 'ONE_PAIR', 'HIGH_CARD' ] as const type HandType = typeof handType[number] interface Hand { cards: Card[] bid: number type?: HandType rank?: number } export default function totalWinningsWithJoker (): void { const lines = fs.readFileSync(FILE_PATH, 'utf-8').trim().split('\n') const hands: Hand[] = buildHandsArray(lines) const totalWinnings: number = hands.reduce<number>((acc, currentHand) => { return acc + currentHand.bid * (currentHand.rank ?? 0) }, 0) console.log(`Total winnings with joker: ${totalWinnings}`) } function buildHandsArray (lines: string[]): Hand[] { const returnHands: Hand[] = [] const numRegex: RegExp = /\d+/g lines.forEach((line) => { const hand = line.substring(0, 5) const bid = line.substring(5).match(numRegex) const cards: Card[] = [] for (const card of hand) { cards.push(card) } if (bid !== null) { const hand: Hand = { cards, bid: parseInt(bid[0]) } returnHands.push({ ...hand, type: getHandType(hand) }) } }) return determineHandsRank(returnHands) } function countRepeatsWithJoker (input: string): Array<Map<string, number>> { const possibilities: Array<Map<string, number>> = [] // Iterate over each character in the input for (let i = 0; i < input.length; i++) { const char = input[i] // Create a map to store counts for this iteration const counts = new Map<string, number>() // Count occurrences, considering "J" as a wildcard for (let j = 0; j < input.length; j++) { const currentChar = input[j] === JOKER_CARD ? char : input[j] counts.set(currentChar, (counts.get(currentChar) ?? 0) + 1) } // Add the counts map to the possibilities array possibilities.push(counts) } return possibilities } function getHandType (hand: Hand): HandType { let handString = '' hand.cards.forEach((card) => { handString += card }) const mappedPossibleSolutions = countRepeatsWithJoker(handString) let previousType: HandType = 'HIGH_CARD' // Convert each Map entry to an array for easy iteration mappedPossibleSolutions.map(map => Array.from(map.values())).every((currentHandPossibility, index) => { if (previousType === 'FIVE_OF_KIND') return false const currentType: HandType = decideHand(currentHandPossibility) if (handType.indexOf(currentType) < handType.indexOf(previousType)) { previousType = currentType } return true }) return previousType } function decideHand (arrayOfHighestDuplicates: number[]): HandType { if (arrayOfHighestDuplicates.includes(5)) { return 'FIVE_OF_KIND' } if (arrayOfHighestDuplicates.includes(4)) { return 'FOUR_OF_KIND' } if (arrayOfHighestDuplicates.includes(3) && arrayOfHighestDuplicates.includes(2)) { return 'FULL_HOUSE' } if (arrayOfHighestDuplicates.includes(3)) { return 'THREE_OF_KIND' } if (arrayOfHighestDuplicates.filter((el) => el === 2).length === 2) { return 'TWO_PAIR' } if (arrayOfHighestDuplicates.includes(2)) { return 'ONE_PAIR' } return 'HIGH_CARD' } function determineHandsRank (hands: Hand[]): Hand[] { const returnHands: Hand[] = [] const handsGroupedByType = groupBy(hands, (hand) => hand.type) let rank = hands.length handType.forEach((type) => { new Map([...handsGroupedByType].filter(([k, v]) => k === type)).forEach((hands) => { const sortedHands = hands.sort(sortCards) sortedHands.forEach((hand) => { returnHands.push({ ...hand, rank }) rank-- }) }) }) return returnHands } const sortCards = (cardA, cardB): number => { for (let i = 0; i < 5; i++) { const valueA = CardStrength[cardA.cards[i]] const valueB = CardStrength[cardB.cards[i]] if (valueA < valueB) { return 1 } else if (valueA > valueB) { return -1 } } return 0 }

Dold text
Lagt till lösning för uppgift 2
Visa signatur

Ryzen 7 7800X3D | Nvidia Geforce RTX 4070 Ti 12gb | Corsair Vengeance DDR5 6000MHz RGB CL30 2x16GB | EVGA Supernova G2 750W | ASUS ROG Strix B650E-F Gaming | Be Quiet! Dark Rock Pro 5
Citera för svar!

PermalÀnk
Hedersmedlem ★
●

Dag: 7
SprÄk: Python
Lösning: GitHub

Ganska nöjd med denna. Skulle vilja stÀda upp logiken kring rad 40-43 (som tar hÀnsyn till lÀget i del 2 dÀr J Àr vanligaste kortet). Brukar skapa egna (data)klasser just för att slippa fulheter som [0][1] och liknande i koden, men orkar inte nu.

Edit: Tog tag i det lite senare och putsade till det lite, nÀr jag insÄg att det jag gjorde för ett specialfall gick att applicera som standard istÀllet.

Visa signatur

Asus ROG STRIX B550-F / Ryzen 5800X3D / 48 GB 3200 MHz CL14 / Asus TUF 3080 OC / WD SN850 1 TB, Kingston NV1 2 TB + NAS / Corsair RM650x V3 / Acer XB271HU (1440p165) / LG C1 55"
NAS: 6700K/16GB/Debian+ZFS | Backup (offsite): 9600K/16GB/Debian+ZFS

PermalÀnk
Medlem ★
●

Dag: 7
SprÄk: Python

Ganska elegant i dag.

from collections import Counter hands = list(map(lambda l: (l[0], Counter(l[0]), int(l[1])), [line.strip().split() for line in open("input07.txt").readlines()])) def part1(e): return ("".join(map(str, sorted(e[1].values(), reverse=True))), tuple(map(lambda card: "23456789TJQKA".index(card), e[0]))) def part2(e): js = e[1].pop('J', 0) if l := sorted(e[1].values(), reverse=True): l[0] += js else: l = [5] return ("".join(map(str, l)), tuple(map(lambda card: "J23456789TQKA".index(card), e[0]))) print([sum(map(lambda h: (h[0] + 1) * h[1][2], enumerate(sorted(hands, key = sorter)))) for sorter in [part1, part2]])

Dold text