🌟 Advent of Code (AoC) 2024 🌟

PermalÀnk
Medlem ★
●
Skrivet av Yoshman:

@GLaDER: var precis pÄ vÀg att göra en shameless copy av ditt 2023-startinlÀgg, sÄg detta nÀr jag gjorde refresh för att fÄ rÀtt rubrik!

Har gjort alla uppgifterna alla Är, sÄ tÀnker inte bryta den traditionen. Men lÀr tyvÀrr bli primÀrt kvÀllsjobb i Är, lite annat i vÀgen.

I Ă„r fĂ„r det bli Rust igen. Är ju sĂ„ mycket som hĂ€nder kring det sprĂ„ket, bl.a. rekommendationer frĂ„n US-gov, Microsoft, Google, m.fl. att alltid anvĂ€nda Rust över C och C++ om möjligt.

Skönt att fÄ jobba med nÄgot annat Àn det man primÀrt anvÀnder i jobbet, som senaste tiden Àr C#, Go och en del Python (uteslutande ihop med PyTorch).

Och kör man Rust (eller C eller C++) sÄ finns ju den roliga utmaningen att skriva sina lösningar sÄ alla svar berÀkningar pÄ under 1s pÄ en "normal dator". Sist jag körde Rust, 2021, rÀckte det med en RPi4 för att komma under 1s. Fast hÀnger i praktiken alltid pÄ vad de 1-2 "vÀrsta" fallen krÀver...

Aww alla uppgifter i alla Är...
Har du vunnit nÄgon av dem? = )

Visa signatur

42? Seven and a half million years and all you can come up with is 42?!
â–ș FD Define R2 | Win11Pro | R7-5800X | PA 120SE | ROG STRIX B550-F GAMING | CMN32GX4M2Z4600C18 | 1080 Ti | AX750 | Asus VG27WQ | HP Z27n |â–ș Realme GT Master |

PermalÀnk
●
Skrivet av bjoen:

DÄ skapar jag en ny för oss som inte Àr med i den gamla, eller om dÀr Àr mÄnga inaktiva i den gamla sÄ kan ju alla som gör den iÄr gÄ med hÀr ocksÄ!

Kod: 3412137-72abe3b6
@GLaDER kanske kan lÀgga in den i original-inlÀgget.

Vad roligt att det Àr AoC igen!

Jag gick med som "anonymous user #1176461", men kommer inte vara uppe i ottan och kÀmpa.

I Är ska jag köra C++ för att kÀnna pÄ det hÀr nya ranges som Àr en förenklad syntax för algoritmer och iteratorer och sÄnt.

Dag: 1
SprÄk: C++

#include <algorithm> // count, fold_left, sort #include <cmath> // std::abs #include <fstream> #include <functional> // std::plus #include <iostream> #include <ranges> // zip_transform #include <vector> int main(int argc, char* argv[]) { // Reading the input std::vector<int> left {}; std::vector<int> right {}; std::ifstream f(argv[1], std::ios::in); int first_num, second_num; while (f >> first_num && f >> second_num) { left.push_back(first_num); right.push_back(second_num); } std::ranges::sort(left); std::ranges::sort(right); // Part 1 auto distance = [](auto a, auto b) { return std::abs(a - b); }; auto part1 = std::ranges::fold_left( std::views::zip_transform(distance, right, left), 0, std::plus<>() ); // Part 2 auto similarity = [right](auto acc, auto b) { return std::ranges::count(right, b) * b + acc; }; auto part2 = std::ranges::fold_left(left, 0, similarity); std::cout << "Part 1: " << part1 << "\nPart 2: " << part2 << '\n'; return 0; }

Dold text
PermalÀnk
Medlem ★
●

TÀnker att man ska passa pÄ att prova nÄgot nytt, men vet inte om jag Àr jÀtteförtjust i just Go sÄhÀr direkt... Men nÄgot lÀr man sig iaf!

Dag: 1
SprÄk: Go
Lösning:

package main import ( "bufio" "fmt" "log" "os" "sort" "strconv" "strings" ) func readListsFromFile(filename string) ([]int, []int, error) { file, err := os.Open(filename) if err != nil { return nil, nil, fmt.Errorf("failed to open file: %w", err) } defer file.Close() scanner := bufio.NewScanner(file) leftValues := []int{} rightValues := []int{} for scanner.Scan() { columns := strings.Fields(scanner.Text()) if len(columns) != 2 { return nil, nil, fmt.Errorf("wrong number of columns in line: %s", scanner.Text()) } leftInt, err := strconv.Atoi(columns[0]) if err != nil { return nil, nil, fmt.Errorf("not an integer: %s", columns[0]) } rightInt, err := strconv.Atoi(columns[1]) if err != nil { return nil, nil, fmt.Errorf("not an integer: %s", columns[1]) } leftValues = append(leftValues, leftInt) rightValues = append(rightValues, rightInt) } if err := scanner.Err(); err != nil { return nil, nil, fmt.Errorf("error reading file: %w", err) } return leftValues, rightValues, nil } func calculateDistance(leftList []int, rightList []int) int { leftCopy := make([]int, len(leftList)) rightCopy := make([]int, len(rightList)) copy(leftCopy, leftList) copy(rightCopy, rightList) sort.Ints(leftCopy) sort.Ints(rightCopy) distance := 0 for i := 0; i < len(leftCopy); i++ { distance += abs(leftCopy[i] - rightCopy[i]) } return distance } func abs(x int) int { if x < 0 { return -x } return x } func calculateSimilarity(leftList []int, rightList []int) int { counts := map[int]int{} for _, v := range rightList { counts[v] += 1 } total := 0 for _, v := range leftList { total += v * counts[v] } return total } func main() { leftList, rightList, err := readListsFromFile("input.txt") if err != nil { log.Fatalf("Error: %s", err) } distance := calculateDistance(leftList, rightList) fmt.Printf("Part 1: %d\n", distance) similarity := calculateSimilarity(leftList, rightList) fmt.Printf("Part 2: %d\n", similarity) }

Dold text
Visa signatur

Desktop spel m.m.: Ryzen 9800X3D || MSI X870 Tomahawk Wifi || MSI Ventus 3x 5080 || Gskill FlareX 6000 64GB || Kingston KC3000 2TB || Samsung 970 EVO Plus 2TB || Samsung 960 Pro 1TB || Fractal Torrent || Asus PG42UQ 4K OLED
Arbetsstation: Ryzen 7945HX || Minisforum BD790i || Asus Proart 4070 Ti Super || Kingston Fury Impact 5600 65 GB || WD SN850 2TB || Samsung 990 Pro 2TB || Fractal Ridge
Proxmox server: Ryzen 5900X || Asrock Rack X570D4I-2T || Kingston 64GB ECC || WD Red SN700 1TB || Blandning av WD Red / Seagate Ironwolf för lagring || Fractal Node 304

PermalÀnk
Medlem ★
●
Skrivet av GLaDER:

StÀllde klockan, pÄ 05:45, trots att jag sagt till mig sjÀlv att jag inte ska stressa med AoC i Är. Tror kroppen hÄller med, för jag lyckades somna om direkt efter att alarmet gick Skönt med en liten mjukstart, som vanligt.

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

NÄgon som hittade nÄgon esoterisk lösning?

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

Visa signatur

:(){ :|:& };:

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

PermalÀnk
Medlem
●

Dag: 2
Sprak: Golang (prover livet med Amerikansk tangentbort)

package main import ( "bufio" "cmp" "fmt" "os" "slices" "sort" "strconv" "strings" ) func getPartOne(rows [][]int) int { unsafeRoutes := 0 for _, row := range rows { if !isSafeRoute(row) { unsafeRoutes += 1 } } return len(rows) - unsafeRoutes } func abs(x int) int { if x < 0 { return -x } return x } func isSafeRoute(row []int) bool { ascending := sort.IntsAreSorted(row) descending := slices.IsSortedFunc(row, func(a, b int) int { return -1 * cmp.Compare(a, b) }) if !ascending && !descending { return false } for i := 0; i < len(row)-1; i++ { diff := abs(int(row[i]) - int(row[i+1])) if diff < 1 || diff > 3 { return false } } return true } func getPartTwo(rows [][]int) int { unsafeRoutes := 0 for _, row := range rows { if !isSafeRoute(row) { foundNewSafeRoute := false for i := 0; i < len(row); i++ { newRow := RemoveCopy(row, i) if isSafeRoute(newRow) { foundNewSafeRoute = true break } } if !foundNewSafeRoute { unsafeRoutes += 1 } } } return len(rows) - unsafeRoutes } func RemoveCopy(a []int, i int) []int { b := make([]int, len(a)-1) copy(b, a[:i]) copy(b[i:], a[i+1:]) return b } func getRows(filename string) [][]int { file, err := os.Open(filename) if err != nil { panic(err) } defer file.Close() scanner := bufio.NewScanner(file) var rows [][]int for scanner.Scan() { vals := strings.Split(scanner.Text(), " ") var row []int for _, val := range vals { intVal, _ := strconv.Atoi(val) row = append(row, intVal) } rows = append(rows, row) } return rows } func main() { fmt.Println("Part one:", getPartOne(getRows("../input.txt"))) fmt.Println("Part two:", getPartTwo(getRows("../input.txt"))) }

Dold text
PermalÀnk
Medlem
●
Skrivet av GLaDER:

NÄgon som hittade nÄgon esoterisk lösning?

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

NĂ€, bruteforce ftw

PermalÀnk
Medlem ★
●

Dag: 2
SprÄk: Python

from itertools import combinations def decreasing_safely(l): return all(l[i] > l[i+1] > l[i] - 4 for i in range(len(l) - 1)) def increasing_safely(l): return all(l[i] < l[i+1] < l[i] + 4 for i in range(len(l) - 1)) def remove_one_level(l, f): return any(f(c) for c in combinations(l, len(l) - 1)) reports = [[int(r) for r in l.split()] for l in open("input02.txt", "r").readlines()] print(sum([increasing_safely(r) or decreasing_safely(r) for r in reports]), sum([remove_one_level(r, increasing_safely) or remove_one_level(r, decreasing_safely) for r in reports]))

Dold text
PermalÀnk
Medlem
●

Dag: 2
SprÄk: Java
Lösning: GitHub

PermalÀnk
Medlem ★
●

Dag: 2
SprÄk: C#

Denna gillade jag inte alls

public class Puzzle_2024_2 : Puzzle { public override object PartOne(string data) { var parsed = data .Split(Environment.NewLine) .Select(line => line.Split(" ", StringSplitOptions.RemoveEmptyEntries)) .Select(l => l.Select(int.Parse).ToList()) .ToList(); return parsed.Count(record => AllAscending(record) || AllDescending(record)); } public override object PartTwo(string data) { var parsed = data .Split(Environment.NewLine) .Select(line => line.Split(" ", StringSplitOptions.RemoveEmptyEntries)) .Select(l => l.Select(int.Parse).ToList()) .ToList(); return parsed.Count(record => AllAscendingDampener(record) || AllDescendingDamper(record)); } private static bool AllAscending(List<int> record) { return record.Zip(record.Skip(1), (l, r) => l != r && Math.Abs(l - r) <= 3 && l < r).All(b => b); } private static bool AllAscendingDampener(List<int> record) { return AllDescending(record) || record.Select((t, i) => record.Where((_, j) => j != i).ToList()).Any(AllAscending); } private static bool AllDescending(List<int> record) { return record.Zip(record.Skip(1), (l, r) => l != r && Math.Abs(l - r) <= 3 && l > r).All(b => b); } private static bool AllDescendingDamper(List<int> record) { return AllDescending(record) || record.Select((t, i) => record.Where((_, j) => j != i).ToList()).Any(AllDescending); } }

Dold text
PermalÀnk
Hedersmedlem ★
●

Uppgift tvÄ skapade lite problem för tvÄ av rapporterna, men gick till slut...

Visa signatur

AnvÀnd gilla för att markera nyttiga inlÀgg!

PermalÀnk
Medlem ★
●

Dag: 2
SprÄk: F#

Bruteforce for the win! (för ovanlighetens skull!)

open System let input = System.IO.File.ReadAllLines "input.txt" |> Array.map (_.Split(" ", StringSplitOptions.RemoveEmptyEntries) >> Array.map int >> List.ofArray) |> List.ofArray let isLevelSafe = List.pairwise >> (fun lst -> ((List.forall (fun (a, b) -> a > b) lst || List.forall (fun (a, b) -> a < b) lst)) && List.forall (fun (a, b) -> abs (a - b) >= 1 && abs (a - b) <= 3) lst) let filterAndCount predicate = List.filter predicate >> List.length let part1 = filterAndCount isLevelSafe let part2 = filterAndCount (fun list -> List.mapi (fun i _ -> List.take i list @ List.skip (i + 1) list) list |> List.exists isLevelSafe) printfn $"Safe levels part 1: %i{input |> part1} part 2: %i{input |> part2}"

Dold text
Visa signatur

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

PermalÀnk
Medlem
●

Dag: 2
SprÄk: Java
Lösning: GitHub
Satt pÄ tok för lÀnge och försökte lösa den utan bruteforce.

... börjar nog med att testa det nÀsta gÄng

Visa signatur

Starka Äsikter om onödiga saker.

PermalÀnk
Medlem ★
●

Dag 2, C#

Inte helt nöjd med en del saker, men det fÄr vara.

var lines = File.ReadAllLines("input.txt").Select(x => x.Split(" ").Select(int.Parse)).ToList(); int sumpart1 = 0; int sumpart2 = 0; foreach (var line in lines) { if (is_safe(line)) { sumpart1++; sumpart2++; continue; } for (int i = 0; i < line.Count(); i++) { var list = line.ToList(); list.RemoveAt(i); if (is_safe(list)) { sumpart2++; break; } } } Console.WriteLine("Part 1: " + sumpart1); Console.WriteLine("Part 2: " + sumpart2); static bool is_safe(IEnumerable<int> line) { var tuples = line.Zip(line.Skip(1), (a, b) => Tuple.Create(a, b)); return tuples.All(pair => Math.Abs(pair.Item1 - pair.Item2) <= 3) && (tuples.All(pair => pair.Item1 < pair.Item2) || tuples.All(pair => pair.Item1 > pair.Item2) ); }

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 Endast del 1 Àn sÄ lÀnge!!!
PHP - Körs via "Code Runner" i VSCode Terminal

2.php - Only Part I so far!!!

<?php $data = "16 19 21 24 21 15 18 19 22 24 25 25 and_so_on_..."; // Source: https://adventofcode.com/2024/day/2/input // First we grab all data by splitting the data string by new lines $lines = explode("\n", $data); // Each line has a list of number separated by spaces. We will store how many of these // lines are considered "safe" by checking each numbers in each line and see if every // adjacent number are differient by at least 1 or at most 3. Any other difference // makes the entire line of numbers "unsafe". If it is "safe" we will increase "safeReports" // by 1. A crucial detail to consider is that the numbers could be increasing or decreasing // but each line is ONLY consireded safe is the numbers are only increasing or only decreasing // by at least 1 or at most 3. Otherwise it is considered unsafe and not added to "safeReports". $safeReports = 0; foreach ($lines as $line) { $numbers = explode(" ", $line); $safe = true; $length = count($numbers) - 1; // PlÄga inte looparna! // First loop will just check if there is a valid absolute difference (at least 1 or at most 3) // between each two adjacent numbers. If there is not, the line is considered unsafe and we break. for ($i = 0; $i < $length; $i++) { // First get absolute difference $diff = abs($numbers[$i] - $numbers[$i + 1]); if ($diff < 1 || $diff > 3) { $safe = false; break; } } // No need to continue current $line if the line is already considered unsafe if (!$safe) { continue; } // Second loop will check if all numbers are either increasing or either decreasing. If they // shift at any point between increasing and decreasing, the line is considered unsafe and we break. // What we'll do is first check two first numbers before the loop to know whether it should always // increase or always decrease. Then we loop through to make sure it is always increasing or decreasing. // Before we loop we first check if two first numbers are equal because that is a special case // that is not allowed since all numbers should be all increasing or all decreasing! if ($numbers[0] === $numbers[1]) { $safe = false; } // Now we check if the numbers are increasing or decreasing but only if the line is still considered safe. if ($safe) { $increasing = $numbers[0] < $numbers[1]; for ($i = 0; $i < $length; $i++) { if ($increasing && $numbers[$i] > $numbers[$i + 1]) { $safe = false; break; } else if (!$increasing && $numbers[$i] < $numbers[$i + 1]) { $safe = false; break; } } } // Finally we will only add to "safeReports" if the line is considered safe. if ($safe) { $safeReports++; } } echo "Safe reports: $safeReports\n"; ?>

Dold text

Trots lÄnga "kommentarsinstruktioner" sÄ var den inte smart. Det var just det dÀr intressanta specialfallet nÀr tvÄ första nummer Àr lika. Dessutom fattade den (gpt) inte kruxet med att kunna helt plötsligt hoppa frÄn ökande till minskade (eller sÄ Àr det jag som suger pÄ kommentarsinstruktioner xD) sÄ dÀr fick jag fixa lite manuellt. Nu lÀser jag Dag 2 Del 2 och tar sedan en paus och lÄter hjÀrnan vid TV:n fÄ lösa det med pseudokod!

Med andra ord har AOC 2024 verkligen gjort sitt yttersta för att göra det rÀtt sÄ svÄrt som möjligt för icke-kodare att enbart förlita sig pÄ LLM:er. Men Dag 2 Del 1 blev rÀtt vid första försöket trots pytteliten "hm?"-kÀnsla över om jag hade tolkat "level" korrekt. NÀr jag sjÀlv kollade sÄ ansÄg jag att jag hade fullföljt "Kravspecifikationen" rÀtt och det hade jag tydligen. Fick en trevlig guldstjÀrna för Dag 2 Del 1!

(Damn, jag ser nu redan att Dag 2 Del 2 Ă€r ett riktigt saftigt mittenfinger mot alla som anvĂ€nder LLM:er!😂)

Mvh,
WKF.

Visa signatur

(V)ulnerabilities
(I)n
(B)asically
(E)verything
Programming

PermalÀnk
Hedersmedlem ★
●
Skrivet av WebbkodsFrilansaren:

Trots lÄnga "kommentarsinstruktioner" sÄ var den inte smart. Det var just det dÀr intressanta specialfallet nÀr tvÄ första nummer Àr lika. Dessutom fattade den (gpt) inte kruxet med att kunna helt plötsligt hoppa frÄn ökande till minskade (eller sÄ Àr det jag som suger pÄ kommentarsinstruktioner xD) sÄ dÀr fick jag fixa lite manuellt. Nu lÀser jag Dag 2 Del 2 och tar sedan en paus och lÄter hjÀrnan vid TV:n fÄ lösa det med pseudokod!

Med andra ord har AOC 2024 verkligen gjort sitt yttersta för att göra det rÀtt sÄ svÄrt som möjligt för icke-kodare att enbart förlita sig pÄ LLM:er. Men Dag 2 Del 1 blev rÀtt vid första försöket trots pytteliten "hm?"-kÀnsla över om jag hade tolkat "level" korrekt. NÀr jag sjÀlv kollade sÄ ansÄg jag att jag hade fullföljt "Kravspecifikationen" rÀtt och det hade jag tydligen. Fick en trevlig guldstjÀrna för Dag 2 Del 1!

(Damn, jag ser nu redan att Dag 2 Del 2 Ă€r ett riktigt saftigt mittenfinger mot alla som anvĂ€nder LLM:er!😂)

Även om uppgifterna har varit lite kluriga sĂ„ Ă€r det inte sĂ„ svĂ„rt hittills. Jag funderar till och med pĂ„ att försöka lura min dotter att prova. Hon studerar till Civ Ing inom ett annat fĂ€lt Ă€n programmering men har gĂ„tt en Python kurs i höst. Jag tror att innehĂ„llet i den kursen rĂ€cker för att lösa allt hittills.

Visa signatur

AnvÀnd gilla för att markera nyttiga inlÀgg!

PermalÀnk
●

Dag: 2
SprÄk: C++

Min safe-funktion Àr tillkrÄnglad jÀmfört med andra ser jag och jag Àr vÀl inte helt nöjd med main heller, sÄ djupt indenterad och for-loopen hade jag gÀrna blivit av med.

#include <algorithm> #include <fstream> #include <iostream> #include <ranges> #include <vector> enum LevelGapType { UNSAFE, SAFE_ASCENDING, SAFE_DESCENDING }; bool safe(auto report) { auto classify_level_gap = [](auto a, auto b) { if (a-b < 0 && a-b >= -3) return SAFE_ASCENDING; if (a-b > 0 && a-b <= 3) return SAFE_DESCENDING; return UNSAFE; }; auto level_gaps = report | std::views::adjacent_transform<2>(classify_level_gap); auto equals_first_gap = [first {*level_gaps.begin()}] (auto x) { return x == first; }; return !equals_first_gap(UNSAFE) && std::ranges::all_of(level_gaps, equals_first_gap ); } int main(int argc, char* argv[]) { std::ifstream f(argv[1]); std::vector<int> report {}; int part1 { 0 }; int part2 { 0 }; int tmp {}; while (f >> tmp) { report.push_back(tmp); if (f.peek() == '\n') { if (safe(report)) { ++part1; ++part2; } else for (int i_drop=0; i_drop < report.size(); ++i_drop) { if (safe(report | std::views::enumerate | std::views::filter([i_drop](auto l) {return std::get<0>(l) != i_drop;} ) | std::views::values)) { ++part2; break; } } report.clear(); } } std::cout << "Part 1: " << part1 << "\nPart 2: " << part2 << '\n'; return 0; }

Dold text
PermalÀnk
Medlem
●
Skrivet av Wefod:

Dag 1
SprÄk: Python

def p1(): with open('input.txt', 'r') as file: lines = [line.strip().split() for line in file] l1 = sorted(int(line[0]) for line in lines) l2 = sorted(int(line[1]) for line in lines) res = sum(abs(id1 - id2) for id1, id2 in zip(l1, l2)) print(res) def p2(): with open('input.txt', 'r') as file: lines = [line.strip().split() for line in file] l1 = sorted(int(line[0]) for line in lines) l2 = {} for line in lines: key = int(line[1]) l2[key] = l2.get(key, 0) + key res = sum(l2.get(id, 0) for id in l1) print(res) p1() p2()

Dold text

Dag 2
SprÄk: Python

def p1(): with open('input.txt', 'r') as file: levels = [list(map(int, line.strip().split())) for line in file] ans = sum(is_valid_sequence(level) for level in levels) print(ans) def is_valid_sequence(level): if len(level) < 2: return False increasing = level[0] < level[1] for a, b in zip(level, level[1:]): if a == b: return False if increasing and (b - a < 1 or b - a > 3 or b <= a): return False if not increasing and (a - b < 1 or a - b > 3 or b >= a): return False return True def problem_dampener(level): if is_valid_sequence(level): return True for i in range(len(level)): test_level = level[:i] + level[i+1:] if is_valid_sequence(test_level): return True return False def p2(): with open('input.txt', 'r') as file: levels = [list(map(int, line.strip().split())) for line in file] ans = sum(problem_dampener(level) for level in levels) print(ans) p1() p2()

Dold text
PermalÀnk
Medlem ★
●

Dag 2 Del 1 + Del 2!
PHP - Körs via "Code Runner" i VSCode Terminal

2.php - Dag 2 Del 1 + Del 2

$data = "16 19 21 24 21 15 18 19 22 24 25 25 and_so_on_..."; // Source: https://adventofcode.com/2024/day/2/input // First we grab all data by splitting the data string by new lines $lines = explode("\n", $data); // Each line has a list of number separated by spaces. We will store how many of these // lines are considered "safe" by checking each numbers in each line and see if every // adjacent number are differient by at least 1 or at most 3. Any other difference // makes the entire line of numbers "unsafe". If it is "safe" we will increase "safeReports" // by 1. A crucial detail to consider is that the numbers could be increasing or decreasing // but each line is ONLY consireded safe is the numbers are only increasing or only decreasing // by at least 1 or at most 3. Otherwise it is considered unsafe and not added to "safeReports". $safeReports = 0; foreach ($lines as $line) { $numbers = explode(" ", $line); $safe = true; $length = count($numbers) - 1; // PlÄga inte looparna! // First loop will just check if there is a valid absolute difference (at least 1 or at most 3) // between each two adjacent numbers. If there is not, the line is considered unsafe and we break. if (!allNumbersValidAbsoluteDifferences($numbers)) { $safe = false; } // No need to continue current $line if the line is already considered unsafe if (!$safe) { continue; } // Second loop will check if all numbers are either increasing or either decreasing. If they // shift at any point between increasing and decreasing, the line is considered unsafe and we break. // What we'll do is first check two first numbers before the loop to know whether it should always // increase or always decrease. Then we loop through to make sure it is always increasing or decreasing. // Before we loop we first check if two first numbers are equal because that is a special case // that is not allowed since all numbers should be all increasing or all decreasing! if (!allNumbersOnlyIncreaseOrOnlyDecrease($numbers)) { $safe = false; } // Finally we will only add to "safeReports" if the line is considered safe. if ($safe) { $safeReports++; } } echo "Safe reports first time: $safeReports\n"; // Part 2 - reset safeReports $safeReports = 0; $unsureReports = []; // We will store the lines that are unsure if they are safe or not // We now loop through all lines again but this time we will store the lines that are unsure foreach ($lines as $line) { $numbers = explode(" ", $line); $safe = true; $length = count($numbers) - 1; // PlÄga inte looparna! // First loop will just check if there is a valid absolute difference (at least 1 or at most 3) // between each two adjacent numbers. If there is not, the line is considered unsafe and we break. if (!allNumbersValidAbsoluteDifferences($numbers)) { $safe = false; } if (!allNumbersOnlyIncreaseOrOnlyDecrease($numbers)) { $safe = false; } // Finally we will only add to "safeReports" if the line is considered safe. if ($safe) { $safeReports++; } else { $unsureReports[] = $line; // we will store the line since we will check it later } } // Now we will loop through all unsure reports and check if we can make them safe by removing one number // meaning we will need to bruteforce all possible combinations of removing one number from each line and // check if the line is safe. If it is, we will increase "safeReports" by 1. // A function that will return true if all numbers are valid by checking if the absolute difference // between each two adjacent numbers are at least 1 or at most 3. function allNumbersValidAbsoluteDifferences($numbers) { $length = count($numbers) - 1; for ($i = 0; $i < $length; $i++) { $diff = abs($numbers[$i] - $numbers[$i + 1]); if ($diff < 1 || $diff > 3) { return false; } } return true; } // A function that will return true if all numbers are either increasing or decreasing but not both. function allNumbersOnlyIncreaseOrOnlyDecrease($numbers) { $length = count($numbers) - 1; if ($numbers[0] === $numbers[1]) { return false; } $increasing = $numbers[0] < $numbers[1]; for ($i = 0; $i < $length; $i++) { if ($increasing && $numbers[$i] > $numbers[$i + 1]) { return false; } else if (!$increasing && $numbers[$i] < $numbers[$i + 1]) { return false; } } return true; } // The foreach that will loop through all unsure reports and check if we can make them safe by removing one number foreach ($unsureReports as $line) { $line = trim($line); $numbers = explode(" ", $line); $length = count($numbers); $safe = false; // By using the functions we created above, we can check if the line is safe after removing one number // meaning we will have to send all possible combinations of removing one number from the line ($numbers) and check // if the line is safe. If it is, we will increase "safeReports" by 1. for ($i = 0; $i < $length; $i++) { $newNumbers = $numbers; unset($newNumbers[$i]); $newNumbers = array_values($newNumbers); // Reindex the array if (allNumbersValidAbsoluteDifferences($newNumbers) && allNumbersOnlyIncreaseOrOnlyDecrease($newNumbers)) { $safe = true; break; } } // If safe after all checks in the beginning, we will add to safeReports if ($safe) { $safeReports++; } } echo "Safe reports second time: $safeReports\n";

Utan A4-kommentarer:

$data = "https://adventofcode.com/2024/day/2/input"; $lines = explode("\n", $data); $safeReports = 0; foreach ($lines as $line) { $numbers = explode(" ", $line); $safe = true; $length = count($numbers) - 1; if (!allNumbersValidAbsoluteDifferences($numbers)) { $safe = false; } if (!$safe) { continue; } if (!allNumbersOnlyIncreaseOrOnlyDecrease($numbers)) { $safe = false; } if ($safe) { $safeReports++; } } echo "Safe reports first time: $safeReports\n"; $safeReports = 0; $unsureReports = []; foreach ($lines as $line) { $numbers = explode(" ", $line); $safe = true; $length = count($numbers) - 1; if (!allNumbersValidAbsoluteDifferences($numbers)) { $safe = false; } if (!allNumbersOnlyIncreaseOrOnlyDecrease($numbers)) { $safe = false; } if ($safe) { $safeReports++; } else { $unsureReports[] = $line; } } function allNumbersValidAbsoluteDifferences($numbers) { $length = count($numbers) - 1; for ($i = 0; $i < $length; $i++) { $diff = abs($numbers[$i] - $numbers[$i + 1]); if ($diff < 1 || $diff > 3) { return false; } } return true; } function allNumbersOnlyIncreaseOrOnlyDecrease($numbers) { $length = count($numbers) - 1; if ($numbers[0] === $numbers[1]) { return false; } $increasing = $numbers[0] < $numbers[1]; for ($i = 0; $i < $length; $i++) { if ($increasing && $numbers[$i] > $numbers[$i + 1]) { return false; } else if (!$increasing && $numbers[$i] < $numbers[$i + 1]) { return false; } } return true; } foreach ($unsureReports as $line) { $line = trim($line); $numbers = explode(" ", $line); $length = count($numbers); $safe = false; for ($i = 0; $i < $length; $i++) { $newNumbers = $numbers; unset($newNumbers[$i]); $newNumbers = array_values($newNumbers); if (allNumbersValidAbsoluteDifferences($newNumbers) && allNumbersOnlyIncreaseOrOnlyDecrease($newNumbers)) { $safe = true; break; } } if ($safe) { $safeReports++; } } echo "Safe reports second time: $safeReports\n";

Dold text

Först kÀndes det omöjligt, sedan delade jag in det i mindre delar: tvÄ funktioner som gjorde saker som jag ej behövde kolla pÄ och jag provade ÄteranvÀnda dem för Dag 2 Del 1 sÄ att jag visste att de bara gjorde vad de skulle göra och det gjorde dem.

Sedan gjorde jag tre fel:
- Felsatt boolean som gjorde att den rÀknade med alla sÄ det blev för högt svar
- Felsatt lÀngd pÄ array-lÀngd som gjorde att den loopade igenom ett fÀrre element varje gÄng
- Avsaknad av omindexering av numerÀr array av nÀr ett element togs bort frÄn en array

Detta ledde dÄ till tvÄ felaktiga svar, ett för högt och ett för lÄgt. DÄ utbrast jag i tillfÀlligt skrik! Det tredje felet orsakade runtime error sÄ det inte blev nÄgot svar alls att skicka in. Jag kunde ha lagt till förberedande data till del 2 redan under del 1:s körning. Men men, icke-optimerad lathet!

(Att jag missat att en numrerad array mĂ„ste omindexeras efter unset() Ă€r pinsamt misstag frĂ„n min sida!🙈)

Än sĂ„ lĂ€nge Ă€r det bara endimensionella arrayer som behövs bearbetas...đŸ˜±đŸ„¶

Mvh,
WKF.

Visa signatur

(V)ulnerabilities
(I)n
(B)asically
(E)verything
Programming

PermalÀnk
Datavetare ★
●
Skrivet av xfade:

Aww alla uppgifter i alla Är...
Har du vunnit nÄgon av dem? = )

PĂ„ global leader-board menar du?
Knappast, man behöver vara toksnabb för det. Men har i alla fall varit med nÄgon gÄng pÄ den.

Tycker primÀrt att AoC Àr ett utmÀrkt sÀtt att kÀnna pÄ nya sprÄk alt. köra nÄgot "eget" tema. Har testat Rust, Go och Swift dÀr AoC rÀtt mycket varit första jag skrivit i dem.

Problemet Àr vÀl att AoC Àr en rÀtt "speciell" typ av programmering. Go Àr favorit-sprÄket just nu, för det jag "normalt" brukar jobba med. Go Àr inte nÄgon direkt perfekt match för det man stÀlls inför i AoC, styrkan dÀr Àr hantering av I/O samt hur trevligt det Àr om man kör pÄ alla möjliga plattformar.

I kategorin "eget tema" har jag sett att det finns en del som kör utmaningen: lösa alla 25 dagarna i sekvens pÄ under 1s. Kört den tvÄ Är tidigare, en i C++ och en i Rust. Kör samma i Är (med Rust). Spenderat <300”s sÄ hÀr lÄngt, men det brukar ju bara vara 1-2 dagar som i praktiken spelar roll

Edit: Blir ju 500 stjÀrnor efter detta Är

Klicka för mer information
Visa mer
Visa signatur

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

PermalÀnk
Datavetare ★
●

Dag: 2
SprÄk: Rust

use itertools::Itertools; use std::ops::RangeInclusive; use std::str::FromStr; use std::{fs, usize}; pub const INPUT_FILE: &str = "input.txt"; pub type Level = i32; pub struct Report(Vec<Level>); impl Report { fn new(report_str: &str) -> Report { let levels = report_str .split_ascii_whitespace() .map(i32::from_str) .map(Result::unwrap) .collect(); Report(levels) } fn is_valid(&self) -> bool { self.is_valid_with_ignored_index(usize::MAX) } fn is_valid_with_problem_dampener(&self) -> bool { for ignored_index in 0..self.0.len() { if self.is_valid_with_ignored_index(ignored_index) { return true; } } false } fn is_valid_with_ignored_index(&self, ignored_index: usize) -> bool { let valid_range = valid_delta_range(self.0.iter()); self.0 .iter() .enumerate() .filter_map(|(i, level)| { if i == ignored_index { None } else { Some(level) } }) .tuple_windows() .all(|(a, b)| valid_range.contains(&(b - a))) } } fn valid_delta_range<'a, I>(mut levels: I) -> RangeInclusive<Level> where I: Iterator<Item = &'a Level>, { let first = levels.next().unwrap(); let second = levels.next().unwrap(); if first < second { 1..=3 } else { -3..=-1 } } pub fn read_to_reports(path: &str) -> Vec<Report> { fs::read_to_string(path) .expect(&format!("File {} should be present", path)) .lines() .map(Report::new) .collect() } pub fn count_valid_reports(reports: &[Report]) -> usize { reports.iter().filter(|&report| report.is_valid()).count() } pub fn count_valid_reports_with_problem_dampener(reports: &[Report]) -> usize { reports .iter() .filter(|&report| report.is_valid_with_problem_dampener()) .count() } fn main() { let reports = read_to_reports(INPUT_FILE); println!("part 1: {}", count_valid_reports(&reports)); println!( "part 2: {}", count_valid_reports_with_problem_dampener(&reports) ); }

Dold text
Visa signatur

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

PermalÀnk
Medlem
●

Dag: 2
SprÄk: Scala

val data = Using.resource(Source.fromFile("2.txt"))(_.getLines.map(_.split(" ").map(_.toInt)).toArray) def isSafe(row: Array[Int]) = val diff = row.view.zip(row.view.tail).map(_ - _) diff.forall(x => 1 <= x && x <= 3) || diff.forall(x => -3 <= x && x <= -1) // del 1 data.count(isSafe) // del 2 data.count(row => row.indices.exists(i => isSafe(row.patch(i, Nil, 1))))

Dold text
PermalÀnk
Medlem ★
●

Dag: 2
SprÄk: Go
Lösning:

package main import ( "bufio" "fmt" "log" "os" "strconv" "strings" ) func readValuesFromFile(filename string) ([][]int, error) { file, err := os.Open(filename) if err != nil { return nil, fmt.Errorf("failed to open file: %w", err) } defer file.Close() scanner := bufio.NewScanner(file) values := [][]int{} for scanner.Scan() { columns := strings.Fields(scanner.Text()) line := []int{} for _, v := range columns { intVal, err := strconv.Atoi(v) if err != nil { return nil, fmt.Errorf("not an integer: %s", v) } line = append(line, intVal) } values = append(values, line) } if err := scanner.Err(); err != nil { return nil, fmt.Errorf("error reading file: %w", err) } return values, nil } func isValidReport(report []int) (bool, error) { if len(report) < 2 { return false, fmt.Errorf("too few levels in report %d", len(report)) } increasing := report[0] < report[1] for i := 0; i < len(report)-1; i++ { var supposedlyHigher, supposedlyLower int if increasing { supposedlyHigher = report[i+1] supposedlyLower = report[i] } else { supposedlyHigher = report[i] supposedlyLower = report[i+1] } if supposedlyHigher <= supposedlyLower { return false, nil } if supposedlyHigher-supposedlyLower > 3 { return false, nil } } return true, nil } func isValidReportWithDampening(report []int) (bool, error) { for i := 0; i < len(report); i++ { reportCopy := make([]int, len(report)) copy(reportCopy, report) candidateDampenedReport := append(reportCopy[:i], reportCopy[i+1:]...) valid, err := isValidReport(candidateDampenedReport) if err != nil { return false, fmt.Errorf("validation of dampened report failed: %w", err) } if valid { return true, nil } } return false, nil } func calculateSafeReports(reports [][]int, validationFunc func(report []int) (bool, error)) (int, error) { validReports := 0 for _, report := range reports { valid, err := validationFunc(report) if err != nil { return 0, fmt.Errorf("failed to check report validity: %w", err) } if valid { validReports++ } } return validReports, nil } func main() { reports, err := readValuesFromFile("input.txt") if err != nil { log.Fatalf("Error reading data: %s", err) } safeReports, err := calculateSafeReports(reports, isValidReport) if err != nil { log.Fatalf("Error calculating part 1: %s", err) } fmt.Printf("Part 1: %d\n", safeReports) safeReports2, err := calculateSafeReports(reports, isValidReportWithDampening) if err != nil { log.Fatalf("Error calculating part 2: %s", err) } fmt.Printf("Part 2: %d\n", safeReports2) }

Dold text
Visa signatur

Desktop spel m.m.: Ryzen 9800X3D || MSI X870 Tomahawk Wifi || MSI Ventus 3x 5080 || Gskill FlareX 6000 64GB || Kingston KC3000 2TB || Samsung 970 EVO Plus 2TB || Samsung 960 Pro 1TB || Fractal Torrent || Asus PG42UQ 4K OLED
Arbetsstation: Ryzen 7945HX || Minisforum BD790i || Asus Proart 4070 Ti Super || Kingston Fury Impact 5600 65 GB || WD SN850 2TB || Samsung 990 Pro 2TB || Fractal Ridge
Proxmox server: Ryzen 5900X || Asrock Rack X570D4I-2T || Kingston 64GB ECC || WD Red SN700 1TB || Blandning av WD Red / Seagate Ironwolf för lagring || Fractal Node 304

PermalÀnk
Medlem ★
●
Skrivet av GLaDER:

NÄgon som hittade nÄgon esoterisk lösning?

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

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

Lite reguljÀra uttryck pÄ en tisdagsmorgon Àr ju inte fel. Fick lÀra mig om re.finditer idag.

Dold text
Visa signatur

:(){ :|:& };:

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

PermalÀnk
Medlem ★
●

Dag 3 Del 1 Endast !!!
PHP - Körs via "Code Runner" i VSCode Terminal

3.php Endast Del 1

$data = "soLongStringThatVSCodeTokenizerStartedCrying"; // Source: https://adventofcode.com/2024/day/3/input // We will extract all mul(\d+,\d+) from the $data variable using regex // After that we will multiply each \d+ after the , \d+ before the , and sum all the results // Extract all mul(\d+,\d+) from the $data variable preg_match_all('/mul\((\d+),(\d+)\)/', $data, $matches); // Initialize the $result variable $result = 0; // Loop through all the matches foreach ($matches[1] as $key => $value) { // Multiply the values and add the result to the $result variable $result += $value * $matches[2][$key]; } echo "Part 1 result: $result\n";

3.php Endast Del 1 - Kommentarsfri

preg_match_all('/mul\((\d+),(\d+)\)/', $data, $matches); $result = 0; foreach ($matches[1] as $key => $value) { $result += $value * $matches[2][$key]; } echo "Part 1 result: $result\n";

Dold text

Jag pÄbörjar Dag 3 Del 2 nu och ser om jag gÄr in i vÀggen direkt. För första delen kÀndes alldeles för lÀtt för att vara en Regex-utmaning.

Jag pratar om vad som kanske ger lösningsledtrÄdar genom att prata om fjolÄrets liknande kodutmaning:

Jag minns nÀr lookahead-regex behövdes i en kodutmaning förra Äret. DÄ grÀtskrek jag en hel del!

Dold text

Mvh,
WKF.

Visa signatur

(V)ulnerabilities
(I)n
(B)asically
(E)verything
Programming

PermalÀnk
Medlem ★
●

Dag: 3
SprÄk: Python

import re def process_instructions(instructions, always_enabled): s, enabled = 0, True for line in instructions: for i in line[0]: match i[:2]: case 'do': enabled = i == 'do()' case 'mu': if enabled or always_enabled: numbers = re.findall(r'\d+', i) s += int(numbers[0]) * int(numbers[1]) return s instructions = [[re.findall(r"mul\(\d{1,3},\d{1,3}\)|do\(\)|don't\(\)", l)] for l in open("input03.txt", "r").readlines()] print(process_instructions(instructions, True), process_instructions(instructions, False))

Dold text
PermalÀnk
Medlem ★
●

Dag: 3
SprÄk: C#

Skönt med en snabb idag

public partial class Puzzle_2024_3 : Puzzle { public override object PartOne(string data) { return MulRegex() .Matches(data) .Select(m => m.Value[4..^1] .Split(',') .Select(int.Parse) .Aggregate((x, y) => x * y)) .Sum(); } public override object PartTwo(string data) { int sum = 0; var matches = DoMulRegex().Matches(data); bool enable = true; foreach (Match match in matches) { Console.WriteLine(match.Value); if (match.Value == "do()") enable = true; else if (match.Value == "don't()") enable = false; else if (enable) sum += match.Value[4..^1].Split(',').Select(int.Parse).Aggregate((x, y) => x * y); } return sum; } [GeneratedRegex(@mul\(\d+,\d+\), RegexOptions.Compiled)] private static partial Regex MulRegex(); [GeneratedRegex(@(do\(\))|(don't\(\))|(mul\(\d+,\d+\)), RegexOptions.Compiled)] private static partial Regex DoMulRegex(); }

Dold text
PermalÀnk
Medlem ★
●

Dag 3, C#

using System.Text.RegularExpressions; var lines = File.ReadAllLines("input.txt"); (int sumpart1, int sumpart2) = (0, 0); var pattern = @(do\(\))|(mul\(\d+,\d+\))|(don't\(\)); bool is_active = true; foreach (var line in lines) { var matches = Regex.Matches(line, pattern).Cast<Match>().Select(m => m.Value); foreach(var match in matches) { switch (match) { case "don't()": is_active = false; break; case "do()": is_active = true; break; default: sumpart1 += mult(match); if (is_active) sumpart2 += mult(match); break; } } } Console.WriteLine("Part 1: " + sumpart1); Console.WriteLine("Part 2: " + sumpart2); int mult(string input) { input = input.Remove(0, 4); input = input.Remove(input.Length - 1, 1); var a = input.Split(",").Select(int.Parse).ToArray(); return a[0] * a[1]; }

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
●

Regex in the morning makes me cry.

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

PermalÀnk
Medlem
●

Dag: 3
Sprak: Golang

Jag undviker regexp i de lengste

package main import ( "bufio" "fmt" "os" "strconv" "strings" ) type Instruction struct { Operation string A int B int Enabled bool } func solve(rows []string, ignoreDoDont bool) int { var instructions []Instruction mulPrefix := "mul(" enabled := true for _, row := range rows { for i := range row { if strings.HasPrefix(row[i:], "don't()") { enabled = false } else if strings.HasPrefix(row[i:], "do()") { enabled = true } else if strings.HasPrefix(row[i:], mulPrefix) { beginIndex := i + len(mulPrefix) endOfA := strings.Index(row[beginIndex:], ",") if endOfA == -1 { continue } aVal := row[beginIndex : beginIndex+endOfA] a, err := strconv.Atoi(aVal) if err != nil { continue } endOfB := strings.Index(row[beginIndex+endOfA:], ")") if endOfB == -1 { continue } bVal := row[beginIndex+endOfA+1 : beginIndex+endOfA+endOfB] b, err := strconv.Atoi(bVal) if err != nil { continue } instructions = append(instructions, Instruction{Operation: "mul", A: a, B: b, Enabled: enabled}) } } } result := 0 for _, instruction := range instructions { if instruction.Operation == "mul" && (instruction.Enabled || ignoreDoDont) { result += instruction.A * instruction.B } } return result } func getPartOne(rows []string) int { return solve(rows, true) } func getPartTwo(rows []string) int { return solve(rows, false) } func getRows(filename string) []string { file, err := os.Open(filename) if err != nil { panic(err) } defer file.Close() scanner := bufio.NewScanner(file) var rows []string for scanner.Scan() { rows = append(rows, scanner.Text()) } return rows } func main() { fmt.Println("Part one:", getPartOne(getRows("../input.txt"))) fmt.Println("Part two:", getPartTwo(getRows("../input.txt"))) }

Dold text
PermalÀnk
Medlem ★
●

Dag 3 Del 1+2
PHP - Körs via "Code Runner" i VSCode Terminal

3.php - Dag 3 Del 1+2 (med kommentarer)

$data = "^+'*>,,why()mul(229,919)&-#^~mul(187,600)_Inte_ Php_VĂ€nlig_Tackvare_Alla$_Tecken_Som_Parseas_i_PHP $_Source: https://adventofcode.com/2024/day/3/input"; // We will extract all mul(\d+,\d+) from the $data variable using regex // After that we will multiply each \d+ after the , \d+ before the , and sum all the results // Extract all mul(\d+,\d+) from the $data variable preg_match_all('/mul\((\d+),(\d+)\)/', $data, $matches); // Initialize the $result variable $result = 0; // Loop through all the matches foreach ($matches[1] as $key => $value) { // Multiply the values and add the result to the $result variable $result += $value * $matches[2][$key]; } echo "Part 1 result: $result\n"; // For Part 2 we will create a simple tokenizer that will start "reading" the $data variable // and keeping track of its position in the string, the current state (valid or invalid) // by knowing whether it has seen a "do()" or "don't()". // "do()" means we will parse and multiply the values inside of mul(\d+,\d+) // whereas "don't()" means we will ignore the values inside of mul(\d+,\d+) // until we stumble upon a "do()" again. // Reset the $result variable and initialize others $result = 0; $currentState = "do()"; $currentToken = ""; // This will store the current token we are parsing which will be "do()", "don't()" or a mul(\d+,\d+) $currentNumber1 = ""; // This and variable below will store the values inside of mul(\d+,\d+) $currentNumber2 = ""; // After that they would be multiplied and added to the $result variable, then reset to 0 // Initialize the $position variable $position = 0; // Use a while loop to tokenize the input string $i = 0; while ($i < strlen($data)) { echo "Current $i: " . $data[$i] . "| Current token: $currentToken" . "\n"; // Check if current character is a "m" when state is do and token is empty // This means we are trying to build a "mul(\d+,\d+)" token string if ($currentState == "do()" && $currentToken == "" && $data[$i] == "m") { // We now check if the next 3 characters are "mul(" and if so we add them to the token if ($data[$i] == "m" && $data[$i + 1] == "u" && $data[$i + 2] == "l" && $data[$i + 3] == "(") { $currentToken = "mul("; $i += 3; } } // Check if current token is "mul(" which means next up is "\d+,\d+" elseif ($currentState == "do()" && $currentToken == "mul(" && is_numeric($data[$i])) { // We then loop through the string until we HOPEFULLY find a "," which means we have found the first number $validNumbers = true; // This boolean will be used to determine if the current mul(\d+,\d+) is valid or not while (is_numeric($data[$i])) { $currentNumber1 .= $data[$i]; echo "Current $i: " . $data[$i] . "| Current token: $currentToken | Current 1st Number: $currentNumber1" . "\n"; $i++; } // When a comma after first number was not found, we will consider the current mul(\d+,\d+) as invalid if ($data[$i] != ",") { $validNumbers = false; echo "Invalid split after (no comma) $currentNumber1. NOT added to the current result: $result\n"; $currentToken = ""; $currentNumber1 = ""; $currentNumber2 = ""; continue; } $i++; // to skip the valid "," // Then we loop again until we HOPEFULLY find ")" which means we have found the second number while (is_numeric($data[$i])) { $currentNumber2 .= $data[$i]; echo "Current $i: " . $data[$i] . "| Current token: $currentToken | Current 2nd Number: $currentNumber2" . "\n"; $i++; } // Check if the non-numeric character after the second number is a ")" which means we have found a valid mul(\d+,\d+) if ($data[$i] != ")") { $validNumbers = false; echo "Invalid split after (no closing parenthesis) $currentNumber2. NOT added to the current result: $result\n"; $currentToken = ""; $currentNumber1 = ""; $currentNumber2 = ""; continue; } // and we can change the $currentToken to "" and reset the $currentNumber1 and $currentNumber2. // Now, we also multiply and increment the $result variable $currentToken = ""; $result += intval($currentNumber1) * intval($currentNumber2); echo "Numbers: $currentNumber1 and $currentNumber2 multiplied and added to current result: $result\n"; $currentNumber1 = ""; $currentNumber2 = ""; } // Check if current token "d" meaning we will check for "do()" or "don't()" to change the current token. elseif ($currentToken == "" && $data[$i] == "d") { // Now check if after "d" o() follows which means we have found a "do()" if ($data[$i + 1] == "o" && $data[$i + 2] == "(" && $data[$i + 3] == ")") { $currentState = "do()"; $currentToken = ""; $i += 3; echo "Do() found\n"; } // Else check if after "d" on't() follows which means we have found a "don't()" elseif ($data[$i + 1] == "o" && $data[$i + 2] == "n" && $data[$i + 3] == "'" && $data[$i + 4] == "t" && $data[$i + 5] == "(" && $data[$i + 6] == ")") { $currentState = "don't()"; $currentToken = ""; $i += 6; echo "Don't() found\n"; } } $i++; } echo "Part 2 result: $result\n";

3.php - Dag 3 Del 1+2 (utan kommentarer)

<?php $data = "^+'*>,,why()mul(229,919)&-#^~mul(187,600)_Inte_ Php_VĂ€nlig_Tackvare_Alla$_Tecken_Som_Parseas_i_PHP $_Source: https://adventofcode.com/2024/day/3/input"; preg_match_all('/mul\((\d+),(\d+)\)/', $data, $matches); $result = 0; foreach ($matches[1] as $key => $value) { $result += $value * $matches[2][$key]; } echo "Part 1 result: $result\n"; $result = 0; $currentState = "do()"; $currentToken = ""; $currentNumber1 = ""; $currentNumber2 = ""; $position = 0; $i = 0; while ($i < strlen($data)) { echo "Current $i: " . $data[$i] . "| Current token: $currentToken" . "\n"; if ($currentState == "do()" && $currentToken == "" && $data[$i] == "m") { if ($data[$i] == "m" && $data[$i + 1] == "u" && $data[$i + 2] == "l" && $data[$i + 3] == "(") { $currentToken = "mul("; $i += 3; } } elseif ($currentState == "do()" && $currentToken == "mul(" && is_numeric($data[$i])) { $validNumbers = true; while (is_numeric($data[$i])) { $currentNumber1 .= $data[$i]; echo "Current $i: " . $data[$i] . "| Current token: $currentToken | Current 1st Number: $currentNumber1" . "\n"; $i++; } if ($data[$i] != ",") { $validNumbers = false; echo "Invalid split after (no comma) $currentNumber1. NOT added to the current result: $result\n"; $currentToken = ""; $currentNumber1 = ""; $currentNumber2 = ""; continue; } $i++; while (is_numeric($data[$i])) { $currentNumber2 .= $data[$i]; echo "Current $i: " . $data[$i] . "| Current token: $currentToken | Current 2nd Number: $currentNumber2" . "\n"; $i++; } if ($data[$i] != ")") { $validNumbers = false; echo "Invalid split after (no closing parenthesis) $currentNumber2. NOT added to the current result: $result\n"; $currentToken = ""; $currentNumber1 = ""; $currentNumber2 = ""; continue; } $currentToken = ""; $result += intval($currentNumber1) * intval($currentNumber2); echo "Numbers: $currentNumber1 and $currentNumber2 multiplied and added to current result: $result\n"; $currentNumber1 = ""; $currentNumber2 = ""; } elseif ($currentToken == "" && $data[$i] == "d") { if ($data[$i + 1] == "o" && $data[$i + 2] == "(" && $data[$i + 3] == ")") { $currentState = "do()"; $currentToken = ""; $i += 3; echo "Do() found\n"; } elseif ($data[$i + 1] == "o" && $data[$i + 2] == "n" && $data[$i + 3] == "'" && $data[$i + 4] == "t" && $data[$i + 5] == "(" && $data[$i + 6] == ")") { $currentState = "don't()"; $currentToken = ""; $i += 6; echo "Don't() found\n"; } } $i++; } echo "Part 2 result: $result\n";

Dold text

Japp: en jÀdrans supersimpel tokenizer för jag hade inte förmÄgan att fÄ till en simpel Regex för Dag 3 Del 2 sÄ dÄ tÀnkte jag prova pÄ en mycket supersimpel tokenizer för att prova pÄ det.

HÀr kan jag rapportera att LLM:en jag anvÀnder (chatGPT-gratis) Àr sÄ "hm?" att den klarade inte ens av att skriva vissa elseif-satser korrekt. Exempelvis glömde den bort den viktiga apostrofen i en elseif-sats.

I princip blev det att skriva mycket smÄ saker i taget. Och jag fick ÀndÄ ett par fel för att jag inte hade hanterat ett par specialfall. I slutÀndan fungerade det dock som jag ville. Tog cirka 2,5 timmar bara del 2.

Intressant mini-inblick i skapandet av en "tokenizer" dÄ det verkar bestÄ av att tugga igenom en stor loop med sedan mindre sÄdana inuti beroende pÄ "tillstÄndet" i den stora huvudloopen.

(Alla $ inuti all data var ju ocksÄ trevligt för just PHP! Enkelfnuttar fanns redan inuti all data sÄ att köra med enkelfnuttar hade ej löst det. Jag fÄr nog anvÀnda <<<'TEXT' och TEXT; hÀdanefter!)

Mvh,
WKF.

Visa signatur

(V)ulnerabilities
(I)n
(B)asically
(E)verything
Programming