🌟 Advent of Code (AoC) 2023 🌟

PermalÀnk
●

Dag 2
SprÄk: C

Jag ska försöka skriva lite mer lÀsbart istÀllet för att hÄlla ner storleken fast idag blev ÀndÄ kortare Àn igÄr.

Har mÀrkt att min syntaxfÀrgning ser fruktansvÀrd ut i forumets nattlÀge, men jag orkar inte pilla med att byta fÀrgschema.

#include <stdio.h> #include <string.h> #define LINELEN 256 #define SUBSTRLEN 6 #define MAX(a,b) ((a) > (b) ? (a) : (b)) #define MAXRED 12 #define MAXGREEN 13 #define MAXBLUE 14 int maxcubes(char* line, char* color); int main() { int part1 = 0; int part2 = 0; char line[LINELEN]; FILE* fptr = fopen("input", "r"); while (fgets(line, sizeof line, fptr) != NULL) { int game_id, red, green, blue; sscanf(line, "Game %i:", &game_id); red = maxcubes(line, "red"); green = maxcubes(line, "green"); blue = maxcubes(line, "blue"); if (red <= MAXRED && green <= MAXGREEN && blue <= MAXBLUE) part1 += game_id; part2 += red * green * blue; } fclose(fptr); printf("Part 1: %i\nPart 2: %i\n", part1, part2); } // Count the maximum number of cubes seen on a line, of a specific color. int maxcubes(char* line, char* color) { int most_seen = 0; char* sub = line; while (1) { sub = strstr(sub, color); // Search for 1st occurrence. if (sub == NULL) return most_seen; int seen = 0; if (sscanf(sub-SUBSTRLEN, "%*s %i", &seen) == 1) most_seen = MAX(most_seen, seen); ++sub; // Increment so that next strstr will find new match. } }

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

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

Som skrivet ovan: Detta var en klurig dag 1. Tycker att jag fick till en ganska fin lösning ÀndÄ, men gÄr sÀkert hitta Àn smartare sÀtt.

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

Idag gjorde jag bort mig Ä det grövsta.

Jag missade att man skulle ta hÀnsyn till flera grupper/rundor i varje spel och istÀllet trodde jag att blandningen av ; och , var för att luras...

Aja. NÀr jag vÀl lÀste ordentligt var det ju inte sÄ brokigt.

Dold text
Visa signatur

:(){ :|:& };:

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

PermalÀnk
Datavetare ★
●

Dag: 2
SprÄk: Python(PyTorch)

import torch def parse_color(color_desc): (count, color) = color_desc.split() counts = torch.zeros(3, dtype=torch.int32) counts[{'red': 0, 'green': 1, 'blue': 2}[color]] = int(count) return counts def parse_game(line): reveals_desc = line.split(': ')[1] reveals = [ torch.sum(torch.vstack([parse_color(color_desc) for color_desc in subset.split(', ')]), 0) for subset in reveals_desc.split('; ') ] return torch.max(torch.vstack(reveals), dim=0)[0] def sum_possible_game_ids(games): possible_game_ids = torch.all(games <= torch.tensor([12, 13, 14]), dim=1).nonzero() + 1 return torch.sum(possible_game_ids).item() def total_power(games): power_for_each_game = torch.prod(games, dim=1) return torch.sum(power_for_each_game).item() def solve(input): games = torch.vstack([parse_game(line) for line in input]) print(f'{sum_possible_game_ids(games)}') print(f'{total_power(games)}') if __name__ == '__main__': solve(open('input/day2.txt').readlines())

Hmm, inser att det var vÀldigt lÀnge sedan (~15 Är sedan) jag skrev lite större mÀngder Python och det mÀrktes...
Visa signatur

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

PermalÀnk
Medlem
●

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

Visa signatur

3700X | 32GB DDR4 3600 | 3070

PermalÀnk
Medlem
●
Skrivet av GLaDER:

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

Idag gjorde jag bort mig Ä det grövsta.

Jag missade att man skulle ta hÀnsyn till flera grupper/rundor i varje spel och istÀllet trodde jag att blandningen av ; och , var för att luras...

Aja. NÀr jag vÀl lÀste ordentligt var det ju inte sÄ brokigt.

Dold text

Haha jag gjorde exakt samma misstag först

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

Dag: 2
SprÄk: Unreal Blueprints
Lösning: UE Blueprints

Gjorde den först i Python, och sen Àven C++... sen hade jag trÄkigt och fick en dÄlig idé

Visa signatur

13600KF, RTX 4070 FE, B760I, 32GB DDR4, NR200P

PermalÀnk
●
Skrivet av Thomas:

Uppgifterna varierar i svÄrighetsgrad, och kan vara svÄra pÄ olika sÀtt -- den hÀr verkar ju de flesta överens om var ganska dryg, speciellt för att vara dag #1 som brukar vara enkel. Jag tycker ÀndÄ inte att du ska ge upp redan.

YAY! GE ALDRIG UPP MEN RESPEKTERA DINA GRÄNSER & DIN TID!

IgÄr blev jag lite tÄrögd (vÀtska i ögonen) pga. hur "Àgd" jag kÀnde mig inombords av Dag 1 Del 2, riktigt patetiskt faktiskt att jag ens kÀnde sÄ! Nu lyckades jag vid första försöket efter lite sökning om att matcha Àven överlappningar: (dvs., hitta bÄde "two" och "one" i "twone" och liknande fall).

Stort tack till finska engelsksprÄkiga: https://mtsknn.fi/blog/how-to-do-overlapping-matches-with-reg...

DAG 1 DEL 1 & DEL 2:

// FOR BOTH PARTS OF DAY 1 // day1Input = from https://adventofcode.com/2023/day/1/input as template literal const day1InputArr = day1Input.split("\n"); // DAY 1 PART 1 ONLY!!! let summarizedCollection = []; // Loop through each Line | FOR PART 1 day1InputArr.forEach((line) => { let extractDigits = line.match(/(\d)/g); // Only one digit per array element! if (extractDigits.length > 1) { summarizedCollection.push( parseInt( extractDigits[0].toString() + extractDigits[extractDigits.length - 1].toString() ) ); } // Insert duplication of the single integer (converted from string) otherwise else { summarizedCollection.push( parseInt(extractDigits[0].toString() + extractDigits[0].toString()) ); } }); const summarizedCollectionSum = summarizedCollection.reduce((a, b) => a + b, 0); console.log(summarizedCollectionSum); // Final answer! o7 (PART 1 ONLY!) const spelledN = [ "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", ]; // DAY 1 PART 2 ONLY!!! summarizedCollection = []; day1InputArr.forEach((line) => { let lineArray = Array.from( line.matchAll(/(?=([1-9]|one|two|three|four|five|six|seven|eight|nine))/g), (m) => m[1] ); lineArray = lineArray.map((e) => { if (spelledN.includes(e)) { return (spelledN.indexOf(e) + 1).toString(); } return e; }); if (lineArray.length > 1) { summarizedCollection.push( parseInt( lineArray[0].toString() + lineArray[lineArray.length - 1].toString() ) ); } else { summarizedCollection.push( parseInt(lineArray[0].toString() + lineArray[0].toString()) ); } }); const summarizedCollectionSum2 = summarizedCollection.reduce( (a, b) => a + b, 0 ); console.log(summarizedCollectionSum2);

Dold text

Lösningen för Dag 1 Del 2 blev dÄ:

// Matcha överlappande & lagra enbart array av matchningarna - inget annat, YAY! let lineArray = Array.from( line.matchAll(/(?=([1-9]|one|two|three|four|five|six|seven|eight|nine))/g), (m) => m[1] ); // ErsÀtt bokstavering med vanliga siffror, YAY! lineArray = lineArray.map((e) => { if (spelledN.includes(e)) { return (spelledN.indexOf(e) + 1).toString(); } return e; });

En sista "putsning" hade varit att push-funktionen i slutet som trycker in via parseInt kunde ha blivit sin egen funktion som nyttjas tvĂ„ gĂ„nger. Men men, gjort Ă€r gjort nu sĂ„! Nu blir det fira med köttbullar, ketschup, fullkornspasta, rostad lök & trocadero zero! đŸ„°

Senare ikvĂ€ll fĂ„r jag istĂ€llet "grĂ„ta" över Dag 2! 😂

Mvh,
WKL.

P.S. Bra lÀrdom av att anvÀnda sig av RegEx i "överlappningsfall" trots allt!

Visa signatur

<WKL:"En kodrad i taget!";/>

PermalÀnk
Medlem ★
●

Dag: 1
SprÄk: Java

Är pĂ„ del tvĂ„ och den sĂ€ger att det Ă€r fel totalsiffra av nĂ„gon anledning. Har manuellt granskat de första 50 raderna eller sĂ„ och allt ser ok ut. Kan nĂ„gon kolla?
https://codefile.io/f/zcTx6pGLS1

Visa signatur

Klicka pÄ citera nÀr du ska svara nÄgon!

PermalÀnk
Medlem ★
●

Dag: 2
SprÄk: C#

Inte vackert. Men trevligare Àn gÄrdagens. Som vanligt lÀser man fel ett par gÄnger..

Förövrigt tycker jag det Àr fult med folk som pÄpekar verbositet nÀr man sjÀlv hÄrdkodar alla edge-cases.

public override object A(string data) { return data .Split("\r\n") .Select((l, i) => new { index = i, vals = l[(l.IndexOf(':') + 1)..] .Split(";") .SelectMany(g => g.Split(",").Select(x => x.Trim())) }) .Where(g => g.vals.All(InRange)) .Sum(x => x.index + 1); } public override object B(string data) { return data .Split("\r\n") .Select(l => l[(l.IndexOf(':') + 1)..] .Split(";") .SelectMany(g => g.Split(",").Select(x => x.Trim()))) .Select(game => game.GroupBy(s => s.Split(' ')[1]) .Select(grp => grp .Select(val => int.Parse(val.Split(' ')[0])) .OrderByDescending(x => x) .Take(1) .First()) .Aggregate((x, y) => x * y) ) .Sum(); } private static bool InRange(string data) { int red = 12; int green = 13; int blue = 14; var parts = data.Split(' '); int val = int.Parse(parts[0]); string colour = parts[1]; if (colour == "red") return val <= red; if (colour == "green") return val <= green; if (colour == "blue") return val <= blue; return false; }

Dold text
PermalÀnk
Medlem
●
Skrivet av Treant:

Dag: 1
SprÄk: Java

Är pĂ„ del tvĂ„ och den sĂ€ger att det Ă€r fel totalsiffra av nĂ„gon anledning. Har manuellt granskat de första 50 raderna eller sĂ„ och allt ser ok ut. Kan nĂ„gon kolla?
https://codefile.io/f/zcTx6pGLS1

Kan inte java, sÄ har inte granskat din kod. Men det har nog med överlappen att göra som vi har diskuterat tidigare i trÄden, t.ex. "threeight". Om du kör sekventiell matchning sÄ kan "eight" missas om "three" redan har matchats. De Àr inte sÄ mÄnga fall sÄ det Àr nog bara pÄ nÄgon enstaka rad det fallerar.

Dold text
PermalÀnk
Hedersmedlem ★
●
Skrivet av Treant:

Dag: 1
SprÄk: Java

Är pĂ„ del tvĂ„ och den sĂ€ger att det Ă€r fel totalsiffra av nĂ„gon anledning. Har manuellt granskat de första 50 raderna eller sĂ„ och allt ser ok ut. Kan nĂ„gon kolla?
https://codefile.io/f/zcTx6pGLS1

Är inte sĂ„ hemma pĂ„ Java, men det verkar vara samma problem som mĂ„nga (inkl jag) i trĂ„den haft, kolla bakĂ„t lite dĂ€r.

Mindre spoiler, mer ett tips:

Testa sÄ att strÀngen "twone" ger "21". Fungerar inte det sÄ kommer svaren bli fel i ett fÄtal (kritiska) lÀgen.

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"
Mobil: Moto G200

PermalÀnk
Medlem
●

Dag: 2
SprÄk: Rust
Lösning: Github eller se nedan

Hej och hÄ. Vill gÀrna gilla Rust men det Àr inte sÄ lÀtt att komma igÄng med...

use regex::Regex; use std::fs::read_to_string; struct Counts { red: u8, green: u8, blue: u8, } fn read_lines(filename: &str) -> Vec<String> { let mut result = Vec::new(); for line in read_to_string(filename).unwrap().lines() { result.push(line.to_string()) } result } fn update_counts(color: &str, count: &u8, current: &mut Counts) -> () { if color == "red" { current.red = std::cmp::max(*count, current.red); } else if color == "green" { current.green = std::cmp::max(*count, current.green); } else if color == "blue" { current.blue = std::cmp::max(*count, current.blue); } else { panic!() } } fn reveal_is_possible(color: &str, count: &u8) -> bool { if color == "red" { return *count <= 12; } else if color == "green" { return *count <= 13; } else if color == "blue" { return *count <= 14; } else { panic!() } } fn solve(lines: &Vec<String>, re: Regex) -> (u32, u32) { let mut part1: u32 = 0; let mut part2: u32 = 0; for (game, line) in lines.iter().enumerate() { let mut game_possible: bool = true; let mut counts = Counts { red: 0, green: 0, blue: 0, }; let parts = line.split(";"); for part in parts { println!("{}", part); for caps in re.captures_iter(part) { let cap: String = caps[0].to_string(); println!("{}", cap); let subparts: Vec<&str> = cap.split(" ").collect(); let count: u8 = subparts[0].parse().unwrap(); let color: &str = subparts[1]; if !reveal_is_possible(color, &count) { game_possible = false; } update_counts(color, &count, &mut counts); } } if game_possible { part1 += (game + 1) as u32; } part2 += counts.red as u32 * counts.green as u32 * counts.blue as u32; } return (part1, part2); } fn main() { let lines = read_lines("input/day_02.txt"); let re = Regex::new(r"([0-9]+) (red|green|blue)").unwrap(); let (part1, part2) = solve(&lines, re); println!("**AoC-2023 day 2 part 1: {} **", part1); println!("**AoC-2023 day 2 part 1: {} **", part2); }

Dold text
PermalÀnk
Hedersmedlem ★
●

@gbroll Jag har inte rört mycket Rust pÄ lÀnge, men om jag inte minns fel sÄ kan du ersÀtta alla *count med count och lÄta kompilatorn lista ut resten. (Det Àr ju aldrig nÄgon risk, om det kompilerar sÄ Àr det korrekt.)

Sen Àr det ju ocksÄ vÀrt att fundera pÄ om det Àr nÄgon mening att skicka en ensam byte via referens istÀllet för att kopiera den, nÀr den ÀndÄ inte Àr mutable.

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"
Mobil: Moto G200

PermalÀnk
Medlem
●
Skrivet av Thomas:

@gbroll Jag har inte rört mycket Rust pÄ lÀnge, men om jag inte minns fel sÄ kan du ersÀtta alla *count med count och lÄta kompilatorn lista ut resten. (Det Àr ju aldrig nÄgon risk, om det kompilerar sÄ Àr det korrekt.)

Sen Àr det ju ocksÄ vÀrt att fundera pÄ om det Àr nÄgon mening att skicka en ensam byte via referens istÀllet för att kopiera den, nÀr den ÀndÄ inte Àr mutable.

Du menar att det finns förbÀttringspotential? Knappast
SkÀmt Äsido sÄ fÄr jag slÄss sÄ mkt mot kompilatorn att jag kÀnner mig rÀtt nöjd nÀr jag hittar nÄgot som faktiskt funkar. Kanske kan bli nÄgot snyggare i AoC-2024

PermalÀnk
Medlem ★
●

Dag 2
C#

using var sr = new StreamReader("input.txt"); int pt1score = 0; int pt2score = 0; (int red, int green, int blue) goal = (12, 13, 14); while (!sr.EndOfStream) { string[] line = sr.ReadLine()!.Split(':'); int gameno = int.Parse(line[0].Split(' ')[1]); bool enough_cubes = true; var pulls = line[1].Split(';'); (int red, int green, int blue) least = (0, 0, 0); foreach (var pull in pulls) { var cubes = pull.Split(','); foreach (var c in cubes) { var split = c.Trim().Split(' '); int no = int.Parse(split[0]); if (split[1] == "red") { if (no > goal.red) enough_cubes = false; least.red = int.Max(no, least.red); } else if (split[1] == "green") { if (no > goal.green) enough_cubes = false; least.green = int.Max(no, least.green); } else if (split[1] == "blue") { if (no > goal.blue) enough_cubes = false; least.blue = int.Max(no, least.blue); } } } if (enough_cubes) pt1score += gameno; pt2score += least.red * least.green * least.blue; } Console.WriteLine("Part 1 " + pt1score); Console.WriteLine("Part 2 " + pt2score);

Dold text
Visa signatur

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

PermalÀnk
Medlem
●

Dag: 2
SprÄk: C#

Ganska nöjd jag fick rÀtt svar pÄ del 2 pÄ första försöket

using System.Text.RegularExpressions; namespace AOC2023.Puzzles; internal partial class Puzzle2 : Puzzle<int> { [GeneratedRegex(@Game (\d+):)] private static partial Regex GameRegex(); private record struct Game(int Id, IReadOnlyCollection<Set> Sets); private record struct Set(IDictionary<string, int> Cubes); private readonly IDictionary<string, int> AvailableCubes = new Dictionary<string, int> { ["red"] = 12, ["green"] = 13, ["blue"] = 14 }; protected override void Solve(string[] lines) { var games = lines.Select(line => { var gameId = int.Parse(GameRegex().Match(line).Groups[1].Value); var sets = line.Substring(line.IndexOf(": ") + 2).Split("; ") .Select(set => new Set(set.Split(", ") .Select(cubeStr => cubeStr.Split(" ")) .ToDictionary(x => x[1], x => int.Parse(x[0])))) .ToList(); return new Game(gameId, sets); }); One = games .Where(x => x.Sets.All(set => !AvailableCubes.Any(c => set.Cubes.TryGetValue(c.Key, out var amount) && amount > c.Value))) .Sum(x => x.Id); Two = games .Select(game => game.Sets .SelectMany(x => x.Cubes) .GroupBy(x => x.Key, x => x.Value, (_, vals) => vals.Max()) .Aggregate((val, acc) => val * acc)) .Sum(); } }

Dold text
PermalÀnk
●

Dag: 1
SprÄk: JavaScript

input .split('\n') .map((line) => { const digits = line .replace(/one/g, 'one1one') .replace(/two/g, 'two2two') .replace(/three/g, 'three3three') .replace(/four/g, 'four4four') .replace(/five/g, 'five5five') .replace(/six/g, 'six6six') .replace(/seven/g, 'seven7seven') .replace(/eight/g, 'eight8eight') .replace(/nine/g, 'nine9nine') .split('') .filter((char) => char.match(/\d/)) return Number(digits[0] + digits[digits.length - 1]); }) .reduce((a,b) => a+b)

Dold text

Dag: 2
SprÄk: TypeScript / JavaScript

function getFirstAnswer(input: string, totalCubes: Record<Color, number>) { return input .split('\n') .map((game, index) => { const gameIsPossible = game .split(';') .every((sets) => { return sets.split(',') .every((set) => { const {color, cubes } = getCubes(set); return cubes <= totalCubes[color]; }); }) return gameIsPossible ? index + 1 : 0; }) .reduce(add); } function getSecondAnswer(input: string) { return input .split('\n') .map((game) => { const minimumCubes = game .split(';') .reduce((highestCubeCount, sets) => { sets.split(',') .forEach((set) => { const {color, cubes } = getCubes(set); if (typeof highestCubeCount[color] === 'undefined' || highestCubeCount[color] < cubes) { highestCubeCount[color] = cubes; } }); return highestCubeCount; }, {} as Record<Color, number>) return Object.values(minimumCubes).reduce(multiply) }) .reduce(add); } function add(a: number,b: number) { return a + b; } function multiply(a: number,b: number) { return a * b; } function getCubes(set: string) { const {color, cubes } = /(?<cubes>\d*) (?<color>blue|green|red)/.exec(set)?.groups as unknown as {color: Color, cubes: string}; return { color, cubes: Number(cubes) } } type Color = 'blue' | 'green' | 'red';

Dold text
Visa signatur

Är det verkligen det hĂ€r du borde lĂ€sa just nu?

PermalÀnk
Medlem ★
●
Skrivet av WebbkodsLĂ€rlingen:

<Uppladdad bildlÀnk>
YAY! GE ALDRIG UPP MEN RESPEKTERA DINA GRÄNSER & DIN TID!

IgÄr blev jag lite tÄrögd (vÀtska i ögonen) pga. hur "Àgd" jag kÀnde mig inombords av Dag 1 Del 2, riktigt patetiskt faktiskt att jag ens kÀnde sÄ! Nu lyckades jag vid första försöket efter lite sökning om att matcha Àven överlappningar: (dvs., hitta bÄde "two" och "one" i "twone" och liknande fall).

Stort tack till finska engelsksprÄkiga: https://mtsknn.fi/blog/how-to-do-overlapping-matches-with-reg...

DAG 1 DEL 1 & DEL 2:

// FOR BOTH PARTS OF DAY 1 // day1Input = from https://adventofcode.com/2023/day/1/input as template literal const day1InputArr = day1Input.split("\n"); // DAY 1 PART 1 ONLY!!! let summarizedCollection = []; // Loop through each Line | FOR PART 1 day1InputArr.forEach((line) => { let extractDigits = line.match(/(\d)/g); // Only one digit per array element! if (extractDigits.length > 1) { summarizedCollection.push( parseInt( extractDigits[0].toString() + extractDigits[extractDigits.length - 1].toString() ) ); } // Insert duplication of the single integer (converted from string) otherwise else { summarizedCollection.push( parseInt(extractDigits[0].toString() + extractDigits[0].toString()) ); } }); const summarizedCollectionSum = summarizedCollection.reduce((a, b) => a + b, 0); console.log(summarizedCollectionSum); // Final answer! o7 (PART 1 ONLY!) const spelledN = [ "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", ]; // DAY 1 PART 2 ONLY!!! summarizedCollection = []; day1InputArr.forEach((line) => { let lineArray = Array.from( line.matchAll(/(?=([1-9]|one|two|three|four|five|six|seven|eight|nine))/g), (m) => m[1] ); lineArray = lineArray.map((e) => { if (spelledN.includes(e)) { return (spelledN.indexOf(e) + 1).toString(); } return e; }); if (lineArray.length > 1) { summarizedCollection.push( parseInt( lineArray[0].toString() + lineArray[lineArray.length - 1].toString() ) ); } else { summarizedCollection.push( parseInt(lineArray[0].toString() + lineArray[0].toString()) ); } }); const summarizedCollectionSum2 = summarizedCollection.reduce( (a, b) => a + b, 0 ); console.log(summarizedCollectionSum2);

Dold text

Lösningen för Dag 1 Del 2 blev dÄ:

// Matcha överlappande & lagra enbart array av matchningarna - inget annat, YAY! let lineArray = Array.from( line.matchAll(/(?=([1-9]|one|two|three|four|five|six|seven|eight|nine))/g), (m) => m[1] ); // ErsÀtt bokstavering med vanliga siffror, YAY! lineArray = lineArray.map((e) => { if (spelledN.includes(e)) { return (spelledN.indexOf(e) + 1).toString(); } return e; });

En sista "putsning" hade varit att push-funktionen i slutet som trycker in via parseInt kunde ha blivit sin egen funktion som nyttjas tvĂ„ gĂ„nger. Men men, gjort Ă€r gjort nu sĂ„! Nu blir det fira med köttbullar, ketschup, fullkornspasta, rostad lök & trocadero zero! đŸ„°

Senare ikvĂ€ll fĂ„r jag istĂ€llet "grĂ„ta" över Dag 2! 😂

Mvh,
WKL.

P.S. Bra lÀrdom av att anvÀnda sig av RegEx i "överlappningsfall" trots allt!

Nog för att du Àr en dag sen, men [ spoiler ] - taggar Àr bra grejer, dels för att de tar mindre plats i trÄden men ocksÄ för att inte sabba för andra. Det gÀller koden och förklaringen innan som pratar om lösningen

PermalÀnk
Medlem
●

Hakar pÄ och tar det som en chans att fÄ repetera lite Python, skoj!

Dag: 1
SprÄk: Python 3

import re digits = [int(digit[0] + digit[-1]) for digit in [re.findall(r'\d', line) for line in open('inputs/day01.txt')]] print('part 1:', sum(digits)) regex = r'(?=(\d|one|two|three|four|five|six|seven|eight|nine))' digits = { 'one': '1', 'two': '2', 'three': '3', 'four': '4', 'five': '5', 'six': '6', 'seven': '7', 'eight': '8', 'nine': '9', } digits = [int(digits.get(digit[0], digit[0]) + digits.get(digit[-1], digit[-1])) for digit in [re.findall(regex, line) for line in open('inputs/day01.txt')]] print('part 2:', sum(digits))

Dag 1

Dag: 2
SprÄk: Python 3

import re def possibleGame(game): nr = int(re.match(r'Game (\d*)', game).group(1)) return nr if max([int(cubes) for cubes in re.findall(r'(\d*) red', game)]) <= 12 and \ max([int(cubes) for cubes in re.findall(r'(\d*) green', game)]) <= 13 and \ max([int(cubes) for cubes in re.findall(r'(\d*) blue', game)]) <= 14 \ else 0 def possibleCubeAmount(game): return max([int(cubes) for cubes in re.findall(r'(\d*) red', game)]) * \ max([int(cubes) for cubes in re.findall(r'(\d*) green', game)]) * \ max([int(cubes) for cubes in re.findall(r'(\d*) blue', game)]) print('part1:', sum([possibleGame(line) for line in open('inputs/day02.txt')])) print('part2:', sum([possibleCubeAmount(line) for line in open('inputs/day02.txt')]))

Dag 2

Mycket regex sÄ hÀr lÄngt

Dold text
PermalÀnk
Medlem
●

Dag: 1 (del 1)
SprÄk: Python 3.10

import pathlib import typing def solve(path: pathlib.Path) -> int: with open(path) as file: entries = [line.rstrip() for line in file] calibrations: list[int] = list() for entry in entries: first: typing.Optional[str] = None last: typing.Optional[str] = None for character in entry: if not first and character.isdigit(): first = character last = character continue if character.isdigit(): last = character calibrations.append(int(first + last)) return sum(calibrations) if __name__ == "__main__": print(f"Result: {solve(...)}")

Dold text

Dag: 1 (del 2)
SprÄk: Python 3.10

import pathlib import typing WORD_TO_NUMBERS = { "one": 1, "two": 2, "three": 3, "four": 4, "five": 5, "six": 6, "seven": 7, "eight": 8, "nine": 9, } def solve(path: pathlib.Path) -> int: with open(path) as file: entries = [line.rstrip() for line in file] calibrations: list[int] = list() for entry in entries: first: typing.Optional[str] = None first_index: typing.Optional[int] = None last: typing.Optional[str] = None last_index: typing.Optional[int] = None for number, index in [ (number, entry.find(word)) for word, number in WORD_TO_NUMBERS.items() ]: if index == -1: continue if first: if index < first_index: first = str(number) first_index = index else: continue else: first = str(number) first_index = index for word, number, index in [ (word, number, entry.rfind(word)) for word, number in WORD_TO_NUMBERS.items() ]: if index == -1: continue if last: if index > last_index: last = str(number) last_index = index else: continue else: last = str(number) last_index = index for index, character in enumerate(entry): if not first and character.isdigit(): first = character first_index = index if not last and character.isdigit(): last = character last_index = index if character.isdigit(): if index < first_index: first = character first_index = index if index > last_index: last = character last_index = index calibrations.append(int(first + last)) return sum(calibrations) if __name__ == "__main__": print(f"Result: {solve(...)}")

Dold text

Dag: 2 (del 1)
SprÄk: Python 3.10

import dataclasses import pathlib import enum import re class Cube(str, enum.Enum): RED = "red" GREEN = "green" BLUE = "blue" @dataclasses.dataclass class HypotheticalBag: red_cubes: int green_cubes: int blue_cubes: int @dataclasses.dataclass(frozen=True) class RuleSet: max_red_cubes: int max_green_cubes: int max_blue_cubes: int @dataclasses.dataclass class Game: id: int bag: HypotheticalBag rule_set: RuleSet = dataclasses.field( default=RuleSet( max_blue_cubes=14, max_green_cubes=13, max_red_cubes=12 ) ) def is_possible(self) -> bool: ok = True ok &= self.bag.blue_cubes <= self.rule_set.max_blue_cubes ok &= self.bag.green_cubes <= self.rule_set.max_green_cubes ok &= self.bag.red_cubes <= self.rule_set.max_red_cubes return ok def extract_game(line: str) -> Game: x, rest = line.split(":") pattern = r'\s*(\d+)' game_id, *_ = re.findall(pattern, x) game_id = int(game_id) return Game(game_id, HypotheticalBag(0, 0, 0)) def extract_max_rgb(line: str) -> tuple[int, int, int]: _, rest = line.split(":") pattern = r'(\d+)\s*([a-zA-Z]+)' r_max, g_max, b_max = 0, 0, 0 for match in re.findall(pattern, rest): amount, color = match amount = int(amount) cube = Cube(color) if cube is Cube.RED: r_max = amount if amount > r_max else r_max continue if cube is Cube.GREEN: g_max = amount if amount > g_max else g_max continue if cube is Cube.BLUE: b_max = amount if amount > b_max else b_max continue return r_max, g_max, b_max def create_games(path: pathlib.Path) -> list[Game]: games: list[Game] = list() with open(path) as file: for line in file: line = line.rstrip() game = extract_game(line) max_r, max_g, max_b = extract_max_rgb(line) game.bag.red_cubes = max_r game.bag.green_cubes = max_g game.bag.blue_cubes = max_b games.append(game) return games def solve(path: pathlib.Path) -> int: games = create_games(path) return sum((game.id for game in games if game.is_possible())) if __name__ == "__main__": print(f"Result: {solve(...)}")

Dold text

Dag: 2 (del 2)
SprÄk: Python 3.10

import dataclasses import pathlib import enum import re class Cube(str, enum.Enum): RED = "red" GREEN = "green" BLUE = "blue" @dataclasses.dataclass class HypotheticalBag: red_cubes: int green_cubes: int blue_cubes: int @property def power(self) -> int: return self.red_cubes * self.green_cubes * self.blue_cubes @dataclasses.dataclass(frozen=True) class RuleSet: max_red_cubes: int max_green_cubes: int max_blue_cubes: int @dataclasses.dataclass class Game: id: int bag: HypotheticalBag rule_set: RuleSet = dataclasses.field( default=RuleSet( max_blue_cubes=14, max_green_cubes=13, max_red_cubes=12 ) ) def is_possible(self) -> bool: ok = True ok &= self.bag.blue_cubes <= self.rule_set.max_blue_cubes ok &= self.bag.green_cubes <= self.rule_set.max_green_cubes ok &= self.bag.red_cubes <= self.rule_set.max_red_cubes return ok def extract_game(line: str) -> Game: x, rest = line.split(":") pattern = r'\s*(\d+)' game_id, *_ = re.findall(pattern, x) game_id = int(game_id) return Game(game_id, HypotheticalBag(0, 0, 0)) def extract_max_rgb(line: str) -> tuple[int, int, int]: _, rest = line.split(":") pattern = r'(\d+)\s*([a-zA-Z]+)' r_max, g_max, b_max = 0, 0, 0 for match in re.findall(pattern, rest): amount, color = match amount = int(amount) cube = Cube(color) if cube is Cube.RED: r_max = amount if amount > r_max else r_max continue if cube is Cube.GREEN: g_max = amount if amount > g_max else g_max continue if cube is Cube.BLUE: b_max = amount if amount > b_max else b_max continue return r_max, g_max, b_max def create_games(path: pathlib.Path) -> list[Game]: games: list[Game] = list() with open(path) as file: for line in file: line = line.rstrip() game = extract_game(line) max_r, max_g, max_b = extract_max_rgb(line) game.bag.red_cubes = max_r game.bag.green_cubes = max_g game.bag.blue_cubes = max_b games.append(game) return games def solve(path: pathlib.Path) -> int: games = create_games(path) return sum((game.bag.power for game in games)) if __name__ == "__main__": print(f"Result: {solve(...)}")

Dold text
PermalÀnk
Medlem
●

Dag: 2
SprÄk: JavaScript

Lösning - uppgift 1:

import fs from 'fs'; export default function calculatePossibleGames() { const targetCounts = { red: 12, green: 13, blue: 14, }; const possibleGames = []; const lines = fs.readFileSync('./src/02/input/02.txt', 'utf-8').trim().split('\n'); lines.forEach((line) => { const game = line.match(/Game (\d+): (.+)/); const gameID = parseInt(game[1], 10); const gameSubsets = game[2].split(';'); let gameIsPossible = true; gameSubsets.forEach((subset) => { const counts = subset.split(',').map((count) => count.trim().split(' ')); return counts.some(([amount, color]) => { const targetCount = targetCounts[color]; if (!targetCount || parseInt(amount, 10) > targetCount) { gameIsPossible = false; return true; } return false; }); }); if (gameIsPossible) { possibleGames.push(gameID); } }); console.log('Sum: ', possibleGames.reduce((sum, gameID) => sum + gameID)); }

Dold text

Lösning - uppgift 2:

import fs from 'fs'; export default function calculateMinimumSetOfCubes() { const lines = fs.readFileSync('./src/02/input/02.txt', 'utf-8').trim().split('\n'); const powerPerGame = []; lines.forEach((line) => { const game = line.match(/Game (\d+): (.+)/); const gameSubsets = game[2].split(';'); const minAmounts = { red: 0, green: 0, blue: 0, }; gameSubsets.forEach((subset) => { const counts = subset.split(',').map((count) => count.trim().split(' ')); counts.forEach(([amount, color]) => { if (amount > minAmounts[color]) { minAmounts[color] = parseInt(amount, 10); } }); }); powerPerGame.push(minAmounts.red * minAmounts.green * minAmounts.blue); }); console.log('Total sum of powers: ', powerPerGame.reduce((sum, value) => sum + value)); }

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

Dag 2

SprÄk: Matlab

Lite enklare uppgift idag.

fid=fopen('day2.txt'); while ~feof(fid) line = fgetl(fid); id = double(string(extractBetween(line, "Game ", ":"))); Game(id).id = id; sets = split(extractAfter(line, ":"), ";"); for k = 1:length(sets) pat = digitsPattern() + " red"; Game(id).set(k).red=sum(double(string(extract(extract(sets(k),... pat), digitsPattern())))); pat = digitsPattern() + " green"; Game(id).set(k).green=sum(double(string(extract(extract(sets(k),... pat), digitsPattern())))); pat = digitsPattern() + " blue"; Game(id).set(k).blue=sum(double(string(extract(extract(sets(k),... pat), digitsPattern())))); end end [Score1 Score2] = deal(0); for k=[Game.id] Score1 = Score1 + k * ((max([Game(k).set.blue]) <= 14) & ... (max([Game(k).set.green]) <= 13) & (max([Game(k).set.red]) <= 12)); Score2 = Score2 + max([Game(k).set.red])*max([Game(k).set.blue]) * ... max([Game(k).set.green]); end disp(['Task 1: ', num2str(Score1)]) disp(['Task 2: ', num2str(Score2)])

Dold text
PermalÀnk
●

Efter lite smÄkrÄngel med att returnera rÀtt vÀrden efter korrekt genomförd ternary operator sÄ gick det vÀgen med Dag 2 Del 1!
Dag 2 Del 1 (vanilla JavaScript)

/* Advent of Code 2023 - Day 2 | By WebbKodsLĂ€rlingen 2023-12-02 Part 1 */ /* GLOBAL FUNCTIONS: Probably useful for every Daily Challenge ahead! */ // RETURN ALL DIGITS OR NULL using RegEx function extractOnlyDigits(string, returnAs = "") { // Return as joined if (returnAs === "joined") { return parseInt(string.match(/\d+/g).join("")); } // Return default (array) return parseInt(string.match(/\d+/g)); } // RETURN ALL ALPHABETICAL LETTERS OR NULL using RegEx function extractOnlyLetters(string, returnAs = "") { // Return as joined string with if (returnAs === "joined") { return string.match(/\w+/g).join(""); } // Return default (array) return string.match(/\w+/g); } // All Input from Day 2 | https://adventofcode.com/2023/day/2/input // All lines there, so not included fully here if copy&pasted to online place! // Just make sure it starts with `Game 1: 4 blue, 4 red, 16 green; 14 green, 5 red; 1 blue, 3 red, 5 green // and last line ends with Game 100: 3 blue, 3 red, 6 green; 7 red, 2 green, 16 blue; 14 green, 9 red, 9 blue; 8 red, 10 green, 9 blue; 6 blue, 11 red`; const day2Input = `Game 1: 4 blue, 4 red, 16 green; 14 green, 5 red; 1 blue, 3 red, 5 green... Game 100: 3 blue, 3 red, 6 green; 7 red, 2 green, 16 blue; 14 green, 9 red, 9 blue; 8 red, 10 green, 9 blue; 6 blue, 11 red`; // Games split by newline (\n) const gameLines = day2Input.split("\n"); // Targets to check against const targetRed = 12; const targetGreen = 13; const targetBlue = 14; // Total sum of all id:s of valid games let finalSum = 0; // Declare boolean for game with rounds possible or not let gamePossible = true; // FUNCTIONS FOR THIS DAILY CHALLENGE // return the gameID integer value if all rounds possible ELSE or 0 if any round failed! function evaluateGame(gameArr) { // Grab game ID as an integer let gameID = extractOnlyDigits(gameArr.split(": ")[0], "joined"); // Grab the rounds from game ID and separate each round in one array let rounds = gameArr.split(": ")[1].split("; "); gamePossible = true; // Loop through each round. Only one round must return false // in order for entire game to be considered not possible! rounds.forEach((round) => evaluateRounds(round)); // After looping through all rounds, if game is possible we return the // gameID value to add or return 0 to add nothing to the final sum! console.log(gamePossible); return gamePossible ? gameID : 0; } // return true if all rounds were possible, else false! function evaluateRounds(roundsArr) { let colorsArrInRound = roundsArr.split(","); // forEach color (part of the round), if it exists AND // its value is higher than its targetColor int value // then we consider the game to be false. colorsArrInRound.forEach((color) => { if (color.includes("blue") && extractOnlyDigits(color) > targetBlue) { gamePossible = false; } else if (color.includes("red") && extractOnlyDigits(color) > targetRed) { gamePossible = false; } else if ( color.includes("green") && extractOnlyDigits(color) > targetGreen ) { gamePossible = false; } }); } // LOOP THROUGH ALL 100 GAMES NOW! And add either its gameID or 0 to "finalSum" gameLines.forEach((game) => (finalSum += evaluateGame(game))); // Console log total finalSum (sum of all gameID whose all rounds were possible!) console.log("Total sum: ", finalSum);

Dold text

Jag har tvÄ "globala funktioner" (och fler lÀr vÀl lÀggas till) som jag tror kommer att komma till nytta för alla kommande dagliga kodutmaningar:

/* GLOBAL FUNCTIONS: Probably useful for every Daily Challenge ahead! */ // RETURN ALL DIGITS OR NULL using RegEx function extractOnlyDigits(string, returnAs = "") { // Return as joined if (returnAs === "joined") { return parseInt(string.match(/\d+/g).join("")); } // Return default (array) return parseInt(string.match(/\d+/g)); } // RETURN ALL ALPHABETICAL LETTERS OR NULL using RegEx function extractOnlyLetters(string, returnAs = "") { // Return as joined string with if (returnAs === "joined") { return string.match(/\w+/g).join(""); } // Return default (array) return string.match(/\w+/g); }

Dold text

Nu blir det dags för Dag 2 Del 2 och kanske "grÄtögdhet"!

Mvh,
WKL.

Visa signatur

<WKL:"En kodrad i taget!";/>

PermalÀnk
●

Äntligen lyckades "fĂ€rskingen" med vanilla JS att klara Dag 2 Del 2 pĂ„ redan första försöket (=nĂ€r du klickar pĂ„ "Submit" med ditt slutgiltiga framberĂ€knade vĂ€rde frĂ„n din kod)! SjĂ€lvfallet Ă€r jag redo pĂ„ att de redan kanske de kommande dagarna sĂ„ kommer jag att gĂ„ in i vĂ€ggen.

Jag tjuvkikade pĂ„ de sista koddagarna frĂ„n tidigare Ă„r (2022) och dĂ€r det ju nĂ€stan ut som om man ska skriva nĂ„gon assembler-liknande kod genom att ens kod simulerar nĂ„got lĂ„gnivĂ„sprĂ„k-aktigt? đŸ€” Hursomhelst roligt sĂ„ lĂ€nge det varar!

DAG 2 DEL 2 (vanilla JavaScript)

// DAY 2 PART 2 ONLY !!! let finalSum2 = 0; // Total sum // Default value & starting values const ZERO = 0; let maxBlueCubes = 0; let maxRedCubes = 0; let maxGreenCubes = 0; // FUNCTIONS FOR THIS PART 2 function evaluateGameAgain(gameArr) { // Set default starting values! maxBlueCubes = ZERO; maxGreenCubes = ZERO; maxRedCubes = ZERO; // Grab all rounds from "Game :", replace all ; with , and turn into array let allRounds = gameArr.split(": ")[1].replaceAll("; ", ", ").split(", "); // Loop through and add the highest value for each of the colors! allRounds.forEach((color) => { // We only add to the max<Color>Cubes variables when value is higher than them! if (color.includes("blue") && extractOnlyDigits(color) > maxBlueCubes) { maxBlueCubes = extractOnlyDigits(color); } else if ( color.includes("red") && extractOnlyDigits(color) > maxRedCubes ) { maxRedCubes = extractOnlyDigits(color); } else if ( color.includes("green") && extractOnlyDigits(color) > maxGreenCubes ) { maxGreenCubes = extractOnlyDigits(color); } }); // Return the final multiplied cubes whose value are the maximum of all rounds in the game return maxBlueCubes * maxGreenCubes * maxRedCubes; } gameLines.forEach((game) => (finalSum2 += evaluateGameAgain(game))); console.log("Total sum (Day 2 Part 2): ", finalSum2);

Dold text

Det blev möjligt för mig att ÄteranvÀnda mina "globala funktioner" vilket Àr nice!

/* GLOBAL FUNCTIONS: Probably useful for every Daily Challenge ahead! */ // RETURN ALL DIGITS OR NULL using RegEx function extractOnlyDigits(string, returnAs = "") { // Return as joined if (returnAs === "joined") { return parseInt(string.match(/\d+/g).join("")); } // Return default (array) return parseInt(string.match(/\d+/g)); } // RETURN ALL ALPHABETICAL LETTERS OR NULL using RegEx function extractOnlyLetters(string, returnAs = "") { // Return as joined string with if (returnAs === "joined") { return string.match(/\w+/g).join(""); } // Return default (array) return string.match(/\w+/g); }

Dold text

Det jag gör Àr att först ta en del av "input" och prova att se om algoritmlösningen fungerar pÄ en del för dÄ Àr tanken att om jag sedan delar in hela input in i en array sÄ kommer varje element att hanteras likadant (det Àr iaf förhoppningen med testandet för att sÀkerstÀlla halvt sÄ "pure function"-beteende ).

Mvh,
WKL.

Visa signatur

<WKL:"En kodrad i taget!";/>

PermalÀnk
Medlem ★
●
Skrivet av GLaDER:

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

Idag gjorde jag bort mig Ä det grövsta.

Jag missade att man skulle ta hÀnsyn till flera grupper/rundor i varje spel och istÀllet trodde jag att blandningen av ; och , var för att luras...

Aja. NÀr jag vÀl lÀste ordentligt var det ju inte sÄ brokigt.

Dold text

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

Parsningstung dag idag, men ganska kul uppgift. Tyckte jag hade ganska bra flyt i lösandet idag men kan hÀnda att jag skrev en lite "för generell lösning" och mÀngden kod Àr dÀrefter.

Mastodont-spoiler nedan. Beskriver med pseudokod hur jag löste uppgiften.

Jag parsade omedelbart schemat som en associativ lista (dictionary | map | hash table) dÀr varje koordinat pekade ut en symbol (siffran eller tecknet) om den fanns. Det gjorde att jag slapp alla problem med "att gÄ utanför schemat" nÀr jag skulle kolla grannar och Àr en taktik jag anvÀnt lÀnge i AoC-sammanhang.

Sen kom första frÄgetecknet: Hur hÄller jag koll pÄ att tvÄ (eller flera) siffror tillhör samma nummer?

Det löste jag genom att Àndra schema-parsningen frÄn:

{ (0, 0): 4, (1, 0): 6, (2, 0): 7, (5, 0): 1, ... }

till

{ (0, 0): 467, (1, 0): 467, (2, 0): 467, (5, 0): 114, ... }

Men dÄ kom frÄgetecken nummer tvÄ: Hur sÀkerstÀller jag att jag inte anvÀnder samma nummer flera gÄnger? Jag visste inte om numren skulle vara unika, sÄ jag ville inte chansa pÄ att det gick att kolla: Har jag anvÀnt det hÀr numret förut?

Lösningen hÀr blev en till lista dÀr jag associerade varje koordinat till ett index.

{ (0, 0): 1, (1, 0): 1, (2, 0): 1, (5, 0): 2, ... }

DÄ kunde jag sedan lösa uppgift 1 genom att:

för alla koordinater i schemat: för alla grannar till koordinaten: om grannen finns i schemat: om grannen inte Àr associerad till ett nummer: om koordinatens index inte har anvÀnts tidigare: addera koordinatens associerade nummer lÀgg till koordinatens index i listan över anvÀnda index

och uppgift tvÄ genom att:

för alla koordinater i schemat: om koordinatens associerade vÀrde Àr en "*" för alla grannar till *-koordinaten: lÀgg till (grann-koordinat, vÀrde, index) i en lista om *-koordinaten har fler Àn en granne: ta bort eventuella dublett-index frÄn listan multiplicera grann-vÀrdena och addera till slutsumman

Dold text
Visa signatur

:(){ :|:& };:

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

PermalÀnk
●

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

Den hÀr kÀndes svÄrare nÀr jag satt och lÀste beskrivningen Àn vad det i slutÀndan blev.

Jag fick i slutÀndan en vÀldigt snarlik lösning som @GlaDER dÀr jag sparade hela den parse:ade siffran pÄ alla del-siffrors koordinater. Och jag gav varje siffra ett unikt id för att hÄlla ordning pÄ vilka jag redan tagit med eller inte. För att undvika dupliceringar anvÀnde jag mig av mina favoritdatatstrukturer i AoC: sets. DÄ slipper man tÀnka sÄ mycket pÄ duplicerad data dÄ den ÀndÄ bara kan spara ett exemplar. Allt man behöver göra Àr att skapa en key som Àr unik och i det hÀr fallet var id:t unikt.

Dold text
PermalÀnk
Medlem ★
●

Skriver ikapp eftersom jag inte postat innan

Kör Rust i Är igen, hade lite tankar om OCaml eller Zig för att lÀra mig dem men Rust Àr det sprÄk jag tycker Àr kul att jobba i sÄ fick bli det ÀndÄ. För att fÄ in lite lÀrande anvÀndare jag nom för att parsa istÀllet. Har visserligen anvÀnt den tidigare men varje gÄng smÀlter min hjÀrna innan jag börjar fÄ ihop kod som fungerar, nu inne pÄ tredje dagen gÄr det lite smidigare. Förhoppningsvis kan nom till slut börja flöda lika smidigt som regex och ersÀtta det som standardvalet nÀr bÄgot behöver parseas eftersom det Àr sÄ mycket trevligare att debugga eller komma tillbaka till.

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

Del 2 tog lĂ€ngre tid att fatta Ă€n dag 1 nĂ„gonsin gjort tror jag 😅

SjÀlvklart var de de överlappande "siffrorna" som jag inte tÀnkt pÄ...
Första submit av del 2 blev dÀrmed "too low"

Dold text

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

Trevlig uppgift, gick smidigt och kÀnns helt klart bÀttre Àn dag 1 som ett tidigt problem.

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

Parse-delen blev helt klart over-engineered, men som tack för det tog del 2 bara nÄgon minut. NÀstan lite besviken att del 2 inte var svÄrare men det Àr ju fortfarande vÀldigt tidigt och helt klart mitt fel att bli carried away i parsningen

TvÄ missar pÄ del 1, hade först inte tÀnkt pÄ deduplicering vilket resulterade i en "too high" och sen en naiv deduplicering med siffran som nyckel som blev "too low" eftersom samma siffra Äterkommer i den riktiga inputen men inte i exemplet. Till slut sparade jag alla koordinater och deduplicerar med dem.

Dold text
PermalÀnk
Medlem ★
●

Dag: 1
SprÄk: C#
Kommentar: Not great, not terrible

var day1Res = FileReader.ReadLines("Day1.txt") .Select(x => { var first = x.ToCharArray().First(possibleNum => char.IsNumber(possibleNum)); var last = x.ToCharArray().Last(possibleNum => char.IsNumber(possibleNum)); return char.GetNumericValue(first) * 10 + char.GetNumericValue(last); }).Sum(); Console.WriteLine(day1Res); var day1Res2 = FileReader.ReadLines("Day1.txt") .Select(x => { var firstIndex = int.MaxValue; var firstValue = 0; var secondIndex = int.MinValue; var secondValue = 0; foreach (var item in numToInt) { var indexOfFirstKey = x.IndexOf(item.Key); if (indexOfFirstKey >= 0 && indexOfFirstKey < firstIndex) { firstIndex = indexOfFirstKey; firstValue = item.Value; } var indexOfSecondKey = x.LastIndexOf(item.Key); if (indexOfSecondKey >= 0 && indexOfSecondKey > secondIndex) { secondIndex = indexOfSecondKey; secondValue = item.Value; } } return firstValue*10 + secondValue; }).Sum(); Console.WriteLine(day1Res2); }

Dold text

Dag: 2
SprÄk: C#
Kommentar: Nöjd med denna

public static void Run() { var games = FileReader.ReadLines("Day2.txt") .Select(GameMaker) .ToList(); var day1Res = games.Where(x => x.Possible).Select(x => x.Id).Sum(); Console.WriteLine(day1Res); var day2Res = games.Select(x => x.Blue * x.Red * x.Green).Sum(); Console.WriteLine(day2Res); } private static Game GameMaker(string input) { var idAndCubesSeparation = input.Split(":", StringSplitOptions.RemoveEmptyEntries); string id = idAndCubesSeparation[0].Split(" ")[1]; var game = new Game(int.Parse(id)); var gameSections = idAndCubesSeparation[1].Split(";", StringSplitOptions.RemoveEmptyEntries); foreach (var section in gameSections) { var sectionColorParts = section.Split(",", StringSplitOptions.RemoveEmptyEntries); foreach (var colorPart in sectionColorParts) { var numCubesAndColor = colorPart.Split(" ", StringSplitOptions.RemoveEmptyEntries); var num = int.Parse(numCubesAndColor[0]); var color = numCubesAndColor[1]; //if Possible has been set to false, it will stay false, otherwise do the value check game = (color) switch { "blue" => game with { Possible = !game.Possible ? game.Possible : num <= Game.BLUE_LIMIT, Blue = int.Max(game.Blue, num) }, "red" => game with { Possible = !game.Possible ? game.Possible : num <= Game.RED_LIMIT, Red = int.Max(game.Red, num) }, "green" => game with { Possible = !game.Possible ? game.Possible : num <= Game.GREEN_LIMIT, Green = int.Max(game.Green, num) }, _ => game }; } } return game; } private record Game(int Id, int Blue = 0, int Red = 0, int Green = 0, bool Possible = true) { internal const int BLUE_LIMIT = 14; internal const int RED_LIMIT = 12; internal const int GREEN_LIMIT = 13; }

Dold text

Dag: 3
SprÄk: C#
Kommentar: Fy fan jag borde sluta koda och bli jordgubbsförsÀljare var kÀnslan jag fick

public static void Run() { var lines = FileReader.ReadLines("Day3.txt"); var lineDetails = lines .Select((line, index) => { List<Gear> gears = []; List<LineNumber> lineNumbers = []; string currNumber = ""; for (int i = 0; i < line.Length; i++) { var currChar = line[i]; if (currChar == '*') { gears.Add(new Gear(i, [])); } if (!char.IsNumber(currChar)) { if (currNumber != "") { lineNumbers.Add(new LineNumber(int.Parse(currNumber), i - currNumber.Length, i)); currNumber = ""; } } else { currNumber += currChar; } } if (currNumber != "") { lineNumbers.Add(new LineNumber(int.Parse(currNumber), line.Length - currNumber.Length, line.Length)); } return new LineDetails(line, index, index == 0, index == lines.Length - 1, lineNumbers, gears); }) .ToList(); lineDetails.ForEach(ld => ld.Numbers.ForEach(ln => ln.CheckSurrounding(ld, lineDetails))); var part1Res = lineDetails.SelectMany(ld => { return ld.Numbers.Where(ldn => ldn.SymbolSurrounded); }).Sum(x => x.Number); var part2Res = lineDetails .SelectMany(ld => ld.Gears) .Where(x => x.Numbers.Count == 2) .Select(x => x.Numbers.Aggregate((a, b) => a * b)) .Sum(); Console.WriteLine(part1Res); Console.WriteLine(part2Res); } internal record LineDetails(string Line, int Index, bool IsTop, bool IsBottom, List<LineNumber> Numbers, List<Gear> Gears); internal class LineNumber() { public int Number { get; init; } public int StartIndex { get; init; } public int EndIndex { get; init; } public bool SymbolSurrounded { get; set; } readonly Func<char, bool> _isSymbol = (char c) => (!char.IsNumber(c) && c != '.'); readonly Func<char, bool> _isGear = (char c) => (c == '*'); public LineNumber(int number, int startIndex, int endIndex, bool symbolSurrounded = false) : this() { Number = number; StartIndex = startIndex; EndIndex = endIndex; SymbolSurrounded = symbolSurrounded; } public void CheckSurrounding(LineDetails ld, List<LineDetails> allLines) { bool addedTopAlready = false; bool addedBottomAlready = false; for (int i = StartIndex; i < EndIndex; i++) { if (!ld.IsTop) { var lineDescriptionAbove = allLines[ld.Index - 1]; var upperleftIndex = i > 0 ? i - 1 : -1; var upperRightIndex = i < ld.Line.Length - 1 ? i + 1 : -1; if (upperleftIndex > 0) { if (_isGear(lineDescriptionAbove.Line[upperleftIndex]) && !addedTopAlready) { lineDescriptionAbove.Gears.First(x => x.Index == upperleftIndex).Numbers.Add(Number); addedTopAlready = true; } if (!SymbolSurrounded && _isSymbol(lineDescriptionAbove.Line[upperleftIndex])) this.SymbolSurrounded = true; } if (_isGear(lineDescriptionAbove.Line[i]) && !addedTopAlready) { lineDescriptionAbove.Gears.First(x => x.Index == i).Numbers.Add(Number); addedTopAlready = true; } if (!SymbolSurrounded && _isSymbol(lineDescriptionAbove.Line[i])) this.SymbolSurrounded = true; if (upperRightIndex > 0) { if (_isGear(lineDescriptionAbove.Line[upperRightIndex]) && !addedTopAlready) { lineDescriptionAbove.Gears.First(x => x.Index == upperRightIndex).Numbers.Add(Number); addedTopAlready = true; } if (!SymbolSurrounded && _isSymbol(lineDescriptionAbove.Line[upperRightIndex])) this.SymbolSurrounded = true; } } if (!ld.IsBottom) { var lineDescriptionBelow = allLines[ld.Index + 1]; var lowerleftIndex = i > 0 ? i - 1 : -1; var lowerRightIndex = i < ld.Line.Length - 1 ? i + 1 : -1; if (lowerleftIndex > 0) { if (_isGear(lineDescriptionBelow.Line[lowerleftIndex]) && !addedBottomAlready) { lineDescriptionBelow.Gears.First(x => x.Index == lowerleftIndex).Numbers.Add(Number); addedBottomAlready = true; } if (!SymbolSurrounded && _isSymbol(lineDescriptionBelow.Line[lowerleftIndex])) this.SymbolSurrounded = true; } if (_isGear(lineDescriptionBelow.Line[i]) && !addedBottomAlready) { lineDescriptionBelow.Gears.First(x => x.Index == i).Numbers.Add(Number); addedBottomAlready = true; } if (!SymbolSurrounded && _isSymbol(lineDescriptionBelow.Line[i])) this.SymbolSurrounded = true; if (lowerRightIndex > 0) { if (_isGear(lineDescriptionBelow.Line[lowerRightIndex]) && !addedBottomAlready) { lineDescriptionBelow.Gears.First(x => x.Index == lowerRightIndex).Numbers.Add(Number); addedBottomAlready = true; } if (!SymbolSurrounded && _isSymbol(lineDescriptionBelow.Line[lowerRightIndex])) this.SymbolSurrounded = true; } } if (i > 0) { if (_isGear(ld.Line[i - 1])) ld.Gears.First(x => x.Index == i - 1).Numbers.Add(Number); if (!SymbolSurrounded && _isSymbol(ld.Line[i-1])) this.SymbolSurrounded = true; } if (i < ld.Line.Length - 1) { if (_isGear(ld.Line[i + 1])) ld.Gears.First(x => x.Index == i+1).Numbers.Add(Number); if (!SymbolSurrounded && _isSymbol(ld.Line[i + 1])) this.SymbolSurrounded = true; } } } } internal record Gear(int Index, List<int> Numbers);

Dold text
PermalÀnk
●

Dag 3
SprÄk C

Idag var jobbig tycker jag, jag satt lÀnge men dÄ slapp jag gÄ ut i solen i alla fall.

Jag experimenterade lite med fÀrgschemat igÄr ÀndÄ och fick till ett som jag tycker ser hyfsat ut i forumets bÄda lÀgen.

Jag fick in del 2 utan alltför stora förÀndringar, men hade jag vetat vad den innebar hade jag kanske gjort pÄ annat sÀtt frÄn början.

#include <stdio.h> #include <stdlib.h> #define BUFFERSIZE 160 #define MAXGEARS 512 // Global variable to keep track of gears. struct gear { unsigned long id; int num1; int num2; } gears[MAXGEARS]; // Function declarations. int sumparts(char* prev, char* cur, char* next); int symbol(char* line, int num, int pos); void foundgear(char* line, int num, int pos); int countgears(); unsigned long hash(unsigned char *str); int main() { int part1 = 0; for (int i=0; i<MAXGEARS; ++i) { gears[i].id = 0; gears[i].num1 = 0; gears[i].num2 = 0; } char* prevline = calloc(BUFFERSIZE, sizeof(char)); char* curline = calloc(BUFFERSIZE, sizeof(char)); char* nextline = calloc(BUFFERSIZE, sizeof(char)); FILE* fptr = fopen("input", "r"); fgets(curline, BUFFERSIZE, fptr); while (fgets(nextline, BUFFERSIZE, fptr) != NULL) { part1 += sumparts(prevline, curline, nextline); // Rotate line buffers. char* tmp = prevline; prevline = curline; curline = nextline; nextline = tmp; } fclose(fptr); // After all lines are read, the last line has only // been tested as "next", not as "current". Set // nextline to empty and run one last time. for (int i=0; i<BUFFERSIZE; ++i) nextline[i] = '\0'; part1 += sumparts(prevline, curline, nextline); printf("Part 1: %i\nPart 2: %i\n", part1, countgears()); } // Takes three lines. Looks for numbers on the middle line (cur) // and then looks for adjacent symbols using the other lines. // Returns sum of numbers with adjacent symbols. // Sneakily, the register of gears will be built in the calls // to symbol(). int sumparts(char* prev, char* cur, char* next) { int result = 0; for (int i=0; cur[i] != '\0'; ++i) { if (cur[i] >= '0' && cur[i] <= '9') { // Read the entire number. int start = i; int num = cur[i] - '0'; while (cur[i+1] >= '0' && cur[i+1] <= '9') { ++i; num = 10 * num + cur[i] - '0'; } // Look for adjacent symbols. int adjacent = symbol(cur, num, start-1) + symbol(cur, num, i+1); for (int j=start-1; j<=i+1; ++j) { adjacent += symbol(prev, num, j); adjacent += symbol(next, num, j); } if (adjacent) result += num; ++i; } } return result; } // Return 1 if the character on the specified position in the line // counts as a symbol. Additionally, if the symbol is a gear, // register that gear along with the number it is adjacent to. int symbol(char* line, int num, int pos) { switch (line[pos]) { case '.': case '\n': case '\0': case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': return 0; case '*': foundgear(line, num, pos); default: return 1; } } // When a gear is found next to a number, register that gear and number. // When the entire file has been read, gear ratios can be calculated // from this register. // A gear is identified by a hash created by the line where it was // found, but altered to mark the gear position as well. void foundgear(char* line, int num, int pos) { line[pos] = 'G'; unsigned long h = hash(line); line[pos] = '*'; int i; for (i=0; gears[i].id != 0 && gears[i].id != h && i < MAXGEARS; ++i) ; gears[i].id = h; if (gears[i].num1 == 0) gears[i].num1 = num; else gears[i].num2 = num; } int countgears() { int result = 0; for (int i=0; i<MAXGEARS && gears[i].id != 0; ++i) if (gears[i].num1 && gears[i].num2) result += gears[i].num1 * gears[i].num2; return result; } // Hash function djb2 by Dan Bernstein, // from http://www.cse.yorku.ca/~oz/hash.html unsigned long hash(unsigned char *str) { unsigned long hash = 5381; int c; while (c = *str++) hash = ((hash << 5) + hash) + c; /* hash * 33 + c */ return hash; }

Dold text
PermalÀnk
Medlem ★
●

Dag: 3
SprÄk: Python (Ingen one-liner, men Numpy kan en hel del trix)

import numpy as np from functools import reduce from math import prod # Read file, add extra '.'s around it so we don't need to worry about indexing outside the array a = np.pad(np.array([list(line.strip()) for line in open("input03.txt").readlines()]), 1, constant_values='.') # Find the symbols and mark the elements around them adjacent = reduce(np.logical_and, [a != c for c in '.0123456789']) adjacent |= np.roll(adjacent, -1, axis = 0) | np.roll(adjacent, 1, axis = 0) adjacent |= np.roll(adjacent, -1, axis = 1) | np.roll(adjacent, 1, axis = 1) # Find the coords for each digit, gives a collect of x coordinates and collection of y coordinates digit_coords = np.where(np.char.isdigit(a)) # Find where a sequence of digits ends split_after = np.logical_or(np.diff(digit_coords[0]) != 0, np.diff(digit_coords[1]) != 1) # Convert slpit_after into indexes split_points = np.where(split_after == True) # Split the digit coordinates into chunks of sequential digits number_coords = np.split(np.array(digit_coords), split_points[0] + 1, axis = 1) # Set each cell to the value of the digit sequence it is a part of ratios = np.zeros(a.shape, dtype=np.int_) for nc in number_coords: ratios[tuple(nc)] = int("".join(a[tuple(nc)])) # If any of digits are adjacent to a symbol, include it in the sum print(sum([int("".join(a[tuple(nc)])) for nc in number_coords if np.any(adjacent[tuple(nc)])]), # Find all the numbers next to a '*'. If more than 1, include the product of the numbers in the sum sum([prod(s) for g in zip(*np.where(a == '*')) if len(s:= set([x for x in ratios[(g[0] + np.array([-1, -1, -1, 0, 0, 1, 1, 1]), g[1] + np.array([-1, 0, 1, -1, 1, -1, 0, 1]))] if x])) > 1]))

Dold text