🌟 Advent of Code (AoC) 2022 🌟

PermalÀnk
Medlem
●

Dag: 7
SprÄk: Go

Idag gÄr det sakta, men sÄnn fick det bli.

pkg: aoc2022/07/a BenchmarkPartOne-8 3448 296894 ns/op BenchmarkPartTwo-8 3934 307687 ns/op

package main import ( "bufio" "fmt" "os" "sort" "strings" ) type Instruction struct { Cmd string Files []FileDesc Folders []string } type FileDesc struct { Name string Size int } func getSizePerFolderAndFolderChildRelation(rows []Instruction) (map[string]int, map[string][]string) { localSizePerFolder := make(map[string]int, 0) folderChild := make(map[string][]string, 0) currentFolderStack := make([]string, 0) for _, row := range rows { size := 0 if strings.HasPrefix(row.Cmd, "cd ") { if row.Cmd == "cd .." { currentFolderStack = currentFolderStack[:len(currentFolderStack)-1] continue } else { currentFolderStack = append(currentFolderStack, strings.Replace(row.Cmd, "cd ", "", 1)) } } currentFolder := "" for _, f := range currentFolderStack { if f == "/" { currentFolder += "/" } else { currentFolder += f + "/" } } for _, file := range row.Files { size += file.Size } localSizePerFolder[currentFolder] = size for _, folder := range row.Folders { folderChild[currentFolder] = append(folderChild[currentFolder], currentFolder+folder+"/") } } return localSizePerFolder, folderChild } func findActualFolderSize(name string, localSizePerFolder map[string]int, folderChild map[string][]string) int { size := 0 if val, ok := localSizePerFolder[name]; ok { size += val } if _, ok := folderChild[name]; !ok { return size } for _, sub := range folderChild[name] { size += findActualFolderSize(sub, localSizePerFolder, folderChild) } return size } func getPartOne(rows []Instruction) int { localSizePerFolder, folderChild := getSizePerFolderAndFolderChildRelation(rows) sum := 0 for folder := range localSizePerFolder { s := findActualFolderSize(folder, localSizePerFolder, folderChild) if s <= 100000 { sum += s } } return sum } func getPartTwo(rows []Instruction) int { localSizePerFolder, folderChild := getSizePerFolderAndFolderChildRelation(rows) total := 70000000 wanted := 30000000 actual := findActualFolderSize("/", localSizePerFolder, folderChild) res := make([]int, 0) for folder := range localSizePerFolder { s := findActualFolderSize(folder, localSizePerFolder, folderChild) if total-actual+s > wanted { res = append(res, s) } } sort.Ints(res) return res[0] } func getRows(filename string) []Instruction { file, err := os.Open(filename) if err != nil { panic(err) } defer file.Close() scanner := bufio.NewScanner(file) instructions := make([]Instruction, 0) i := -1 for scanner.Scan() { row := scanner.Text() if strings.Contains(row, "$") { var inst Instruction inst.Cmd = strings.Replace(row, "$ ", "", 1) instructions = append(instructions, inst) i++ } else { if strings.Contains(row, "dir") { var folder string fmt.Sscanf(row, "dir %s", &folder) instructions[i].Folders = append(instructions[i].Folders, folder) } else { var fileDesc FileDesc fmt.Sscanf(row, "%d %s", &fileDesc.Size, &fileDesc.Name) instructions[i].Files = append(instructions[i].Files, fileDesc) } } } return instructions } 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 Mickur:

Den Àr ju brutalt hemsk just nu för att jag försöker hitta felet, men go ahead...

Console.WriteLine("Mickur's Advent of Code 2022 - Day 7!"); // Setup var input = File.ReadAllLines("input.txt"); var seenDirectories = new List<string>(); var seenFiles = new Dictionary<string, int>(); var currentLocation = ""; var directories = new Dictionary<string, int>(); foreach (var line in input) { // Ignore these lines if (line == "$ ls") continue; if (line.StartsWith("dir ")) continue; var output = line.Split(' '); // Commands... if (output[0] == "$") { // Change Location if (output[1] == "cd") { if (output[2].StartsWith('/')) { currentLocation = output[2]; continue; } if (output[2] == "..") { var temp = currentLocation.Split('/'); if (temp.Length <= 2) { currentLocation = "/"; continue; } currentLocation = ""; for (var i = 1; i < temp.Length - 1; i++) { currentLocation += $"/{temp[i]}"; } continue; } if(currentLocation == "/") currentLocation += $"{output[2]}"; else currentLocation += $"/{output[2]}"; } } // Output else { var dirName = currentLocation == "/" ? "/" : $"{currentLocation}/"; var fileName = currentLocation == "/" ? $"/{output[1]}" : $"{currentLocation}/{output[1]}"; if(!seenDirectories.Contains(dirName)) seenDirectories.Add(dirName); if (seenFiles.Keys.Contains(fileName)) continue; if (int.TryParse(output[0], out var result)) { if (directories.ContainsKey(dirName)) { directories[dirName] += result; seenFiles.Add(fileName, result); } else { directories[dirName] = result; seenFiles.Add(fileName, result); } } } } var directoriesTotals = new Dictionary<string, int>(); foreach (var directory in seenDirectories) { directoriesTotals[directory] = 0; // Fill it! foreach (var file in seenFiles) { if (file.Key.StartsWith(directory)) { directoriesTotals[directory] += file.Value; } } } long answer = 0; foreach (var dir in directoriesTotals) { if (dir.Value <= 100000) answer += dir.Value; } Console.WriteLine(answer);

Dold text

Edit: Ingen som kan hitta felet?

else { var dirName = currentLocation == "/" ? "/" : $"{currentLocation}/"; var fileName = currentLocation == "/" ? $"/{output[1]}" : $"{currentLocation}/{output[1]}"; if(!seenDirectories.Contains(dirName)) seenDirectories.Add(dirName); if (seenFiles.Keys.Contains(fileName)) continue; if (int.TryParse(output[0], out var result)) { if (directories.ContainsKey(dirName)) { directories[dirName] += result; seenFiles.Add(fileName, result); } else { directories[dirName] = result; seenFiles.Add(fileName, result); } } }

Dold text

Jag tror du har ditt problem i det hÀr blocket.
Om du har en fil i mappen /c/d/e sÄ ska mappstorleken ökas för samtliga av / /c /c/d/ /c/d/e
Min lösning för att bygga min dictionary var att jag höll mappar i en array istÀllet, och itererade över de kombinationer jag behöver spara ner i dictionaryn:

for (let i = 0; i < currFolders.length; i++) { // / a e const folderName = currFolders.slice(0, i+1).join(''); if (!hash[folderName]) hash[folderName] = num; else hash[folderName] += num; }

Dold text
PermalÀnk
Medlem ★
●

SvÄrt att felsöka nÀr test-input ger korrekt svar men ens egna ger fel ... speciellt med dagens problem som man gÀrna inte sitter och kör igenom med penna och papper

Visa signatur

Corsair Obsidian 250D | i5 7600K | Gigabyte Z270N WiFi | Samsung 960 EVO 250GB | Fractal Design Integra M 650W | Corsair Hydro H90 |Kingston 8GB 2133M DDR4 CL14 | Asus GeForce GTX 970 4GB STRIX DC2 OC MAX |

PermalÀnk
Medlem ★
●

Dag 7
SprÄk: C#

KÀnns som en vÀnda jÀrnvÀgsalgoritm skulle kunna fixa dagens problem utan större problem, men jag lyxade till det lite istÀllet idag

Dold text

Kod:

Program.cs

using Day7; using var sr = new StreamReader("input.txt"); var root = new ElfDir() { Name = "/", Files = new(), Subdirs = new() }; var cd = root; sr.ReadLine(); while (!sr.EndOfStream) { var line = sr.ReadLine()!.Split(); switch (line[0]) { case "$": if (line[1] == "cd") { if (line[2] == "..") { cd = cd.Parent!; } else { cd = cd!.Subdirs.Find(cd => cd.Name == line[2]); } } break; case "dir": cd!.Subdirs.Add(new() { Name = line[1], Parent = cd, Subdirs = new() }); break; default: cd!.Files += int.Parse(line[0]); break; } } int pt1 = root.AllSubdirs.Where(x => x.Size < 100000).Sum(d => d.Size); int pt2_goal = 30000000 - (70000000 - root.Size); var pt2 = root.AllSubdirs.Where(x => x.Size > pt2_goal).OrderBy(x => x.Size).First().Size; Console.WriteLine("Part 1: " + pt1); Console.WriteLine("Part 2: " + pt2);

ElfDir.css:

namespace Day7 { internal class ElfDir { public ElfDir? Parent { get; set; } public string Name { get; set; } = string.Empty; public List<ElfDir> Subdirs { get; set; } = new(); public int Files { get; set; } = new(); public int Size => Subdirs.Sum(x => x.Size) + Files; public (string, int) Info => (Name, Size); public List<ElfDir> AllSubdirs { get { List<ElfDir> retval = new(); retval.AddRange(Subdirs); foreach (var item in Subdirs) { retval.AddRange(item.AllSubdirs); } return retval; } } } }

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

SvÄrt att felsöka nÀr test-input ger korrekt svar men ens egna ger fel ... speciellt med dagens problem som man gÀrna inte sitter och kör igenom med penna och papper

Jag hade samma problem och kom fram till att kataloger kan heta samma sak men finnas pÄ olika stÀllen i strukturen. Kanske ett tips för din lösning, eller inte.

PermalÀnk
Medlem ★
●

Dag: 7
SprÄk: C#

Dagens blev en riktig styggelse. Men det fungerar! Man hade kunnat stÀda bort ganska mycket överflödigt som inte anvÀnds egentligen, men det kÀnns bÀttre att ha kvar, t.ex filnamn.

public sealed class Directories : Puzzle<int> { public override int A(string data) { Directory dir = BuildStructure(data); return CalculateTotal(dir, 100000); } public override int B(string data) { const int updateSize = 30000000; Directory dir = BuildStructure(data); var freeSpace = 70000000 - dir.GetDirectorySize(); var requiredSize = updateSize - freeSpace; return FindSmallestDirectory(dir, requiredSize); } private Directory BuildStructure(string input) { var root = new Directory("/", null); Directory current = root; foreach (var line in input.Split("\r\n").Skip(1)) { if (line[0] == '$') { if (line[2..4] != "cd") continue; current = line[5..6] switch { "." => current.Parent!, "/" => root, _ => current.Directories.First(d => d.Name == line.Split(" ")[2]) }; } else if (line[..3] == "dir") { current.Directories.Add(new Directory(line.Split(" ")[1], current)); } else { var parts = line.Split(" "); current.Files.Add(new File(parts[1], int.Parse(parts[0]))); } } return root; } private int CalculateTotal(Directory root, int maxSize) { var dirs = new Stack<Directory>(); dirs.Push(root); int sum = 0; while (dirs.Count > 0) { Directory d = dirs.Pop(); sum += d.GetDirectorySize(maxSize); foreach (Directory subDir in d.Directories) { dirs.Push(subDir); } } return sum; } private int FindSmallestDirectory(Directory root, int requestedSpace) { var directories = new Stack<Directory>(); var candidates = new List<int>(); directories.Push(root); while (directories.Count > 0) { Directory d = directories.Pop(); var size = d.GetDirectorySize(); if (size >= requestedSpace) { candidates.Add(size); } foreach (Directory subDir in d.Directories) { directories.Push(subDir); } } return candidates.MinBy(d => d); } private struct File { public string Name; public int Size; public File(string name, int size) { Name = name; Size = size; } } private sealed class Directory { public readonly string Name; public readonly Directory? Parent; public readonly List<Directory> Directories = new(); public readonly List<File> Files = new(); public Directory(string name, Directory? parent) { Name = name; Parent = parent; } public int GetDirectorySize(int? limit = null) { int sums = 0; Stack<Directory> dirs = new Stack<Directory>(); dirs.Push(this); while (dirs.Count > 0) { var d = dirs.Pop(); sums += d.Files.Sum(f => f.Size); foreach (Directory dir in d.Directories) { dirs.Push(dir); } } if (limit == null || sums <= limit) return sums; return 0; } } }

Dold text
PermalÀnk
Medlem ★
●

Dag 7
SprÄk: Python

Idag har jag lÀrt mig att Python inte Àr sÄ bra pÄ rekursivitet. Men det gick till slut.

Dold text

class Directory: def __init__(self, name, parent=None): self.name = name self.parent = parent self.size = 0 self.subdirectories = [] def calculate_size(self, total_size): calculated_size = self.size for sub in self.subdirectories: result = sub.calculate_size(total_size) calculated_size += result[0] total_size = result[1] if calculated_size <= 100000: total_size += calculated_size return calculated_size, total_size def find_smallest_to_delete(self, space_req, smallest): calculated_size = self.size for sub in self.subdirectories: result = sub.find_smallest_to_delete(space_req, smallest) calculated_size += result[0] smallest = result[1] if space_req <= calculated_size < smallest: smallest = calculated_size return calculated_size, smallest def day7(): input_list = open("data\\day7.txt").read().split("\n") root = Directory("root") active = root for line in input_list: if line == "$ cd /": active = root elif line == "$ cd ..": active = active.parent elif line.startswith("$ cd "): for sub in active.subdirectories: if sub.name == line[5:]: active = sub break elif line[0].isdigit(): active.size += int(line[:line.index(" ")]) elif line.startswith("dir"): active.subdirectories.append(Directory(line[4:], active)) result = root.calculate_size(0) space_req = 30000000 - (70000000 - result[0]) result2 = root.find_smallest_to_delete(space_req, result[0]) print(result[1]) print(result2[1])

Dold text
Visa signatur

He who hasn't hacked assembly language as a youth has no heart. He who does so as an adult has no brain.
~John Moore

PermalÀnk
Medlem ★
●

Dag: 7
SprÄk: js

Var mest parsningen i början som tog tid att skriva. TÀnkte det skulle vara enklare att lÀgga en parent-referens i varje dir istÀllet för att behöva hÄlla koll pÄ var i strukturen man var och det funkade bra.
Eftersom jag hade alla stolekarna i en separat array var det bara att sortera den och hitta första som var större Àn vad jag behövde. Tog nÄgon minut att fÄ rÀtt pÄ needsToFind men nÀr det vÀrdet vÀl var satt sÄ spottade den ut rÀtt svar direkt.

import {readFileSync} from 'fs'; const root = { childDirs:{}, files:{}}; let currentDir = root; const dirSizes = []; function processCommand(line){ if(line[1] === 'cd') { // we ignore ls if (line[2]=== ".."){ currentDir = currentDir.parent; } else { currentDir = currentDir.childDirs[line[2]]; } } } function parseInput(){ allLines.shift(); //easier to assume currentDir starts as root allLines.forEach(line => { if(line[0] === "$"){ // anything starting with $ is a command processCommand(line); } else if(Number.isNaN(Number(line[0]))){ // if it's not a number and it's not a line starting with $ then it's a dir currentDir.childDirs[line[1]] = { childDirs:{}, files:{}, parent: currentDir }; } else { // only files left in the format SIZE NAME currentDir.files[line[1]] = Number(line[0]); } }); } function calculateSizes(myCurrentDir){ myCurrentDir.size = Object.values(myCurrentDir.childDirs).reduce( (acc, childDir) => acc + calculateSizes(childDir), 0 ); myCurrentDir.size += Object.values(myCurrentDir.files).reduce( (acc, currentFile) => acc + currentFile, 0 ); dirSizes.push(myCurrentDir.size); return myCurrentDir.size; } const allLines = readFileSync("07data","utf8").split("\n").map(line => line.split(" ")); parseInput(); calculateSizes(root); console.log("Part 1:", dirSizes.filter( (size) => size <= 100000 ).reduce((acc,cur) => acc + cur)); const needsToFind = -70000000 + 30000000 + root.size; console.log("Part 2:",dirSizes .sort( (a,b) => a-b ) .find( (dirsize) => dirsize > needsToFind ));

Dold text
Visa signatur

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

PermalÀnk
Medlem ★
●
Skrivet av RÄdström:

Jag hade samma problem och kom fram till att kataloger kan heta samma sak men finnas pÄ olika stÀllen i strukturen. Kanske ett tips för din lösning, eller inte.

Jag var rÀdd att de skulle inkludera flera "cd /" sÄ jag sökte nervöst i inputen och insÄg att de var "snÀlla"

Visa signatur

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

PermalÀnk
Medlem ★
●
Skrivet av Mickur:

FÄr korrekt svar pÄ testdata, men vÀgrar ge mig rÀtt pÄ sjÀlva input. Jag blir galen.

Edit: Kan pÄ riktigt inte hitta vad som blir galet, snart ger jag upp

Är du sĂ€ker pĂ„ att du letar efter rĂ€tt vĂ€rde? Jag hade lite "otur" nĂ€r jag först skrev koden sĂ„ jag letade efter

70.000.000 minus nuvarande storlek pÄ / (hint: det Àr INTE rÀtt sÀtt )

Dold text

Edit: Om du postar din input kan jag testköra den och skriva ut storleken pÄ / (stÀmmer den sÄ vet du ju att berÀkning av storlek Àr reko, och annars vet du vilken del av koden som behöver lite kÀrlek)

Visa signatur

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

PermalÀnk
Medlem ★
●

Dag: 7
SprÄk: C#
Kvalité: KÀpprÀtt Ät helvete... Efter att ha försovit mig, sett problemet och slitit av det lilla hÄr jag hade kvar sÄ fÄr det hÀr duga. Jag var ju rÀtt nÀra frÄn start, men nÀra skjuter ingen hare... Efter att ha finslipat och snyggat till lite sÄ blev det sÄhÀr.

Console.WriteLine("Mickur's Advent of Code 2022 - Day 7!"); // Setup var input = File.ReadAllLines("input.txt"); var rootDir = new CustomDirectory("root"); var currentDir = rootDir; foreach (var line in input) { // Ignore these lines if (line == "$ ls") continue; if (line.StartsWith("dir ")) continue; // Changing directory if (line.StartsWith("$ cd ")) { var output = line.Split(' '); switch (output[2]) { case "/": currentDir = rootDir; continue; case "..": currentDir = currentDir.parent; continue; default: // Check if it already exists if (currentDir.subdirs.Exists(x => x.name == output[2])) currentDir = currentDir.subdirs.First(x => x.name == output[2]); else { var newDir = new CustomDirectory($"{output[2]}", currentDir); currentDir.subdirs.Add(newDir); currentDir = newDir; } continue; } } // Output else { var output = line.Split(' '); if (long.TryParse(output[0], out var result)) { currentDir.files.Add(output[1], result);; } } } var answerA = rootDir.GetTotalBelow(100000); var rootSize = rootDir.GetTotalFileSize(); var needToFree = -70000000 + 30000000 + rootSize; var answerB = rootDir.FindDirectoriesAbove(needToFree).Min(); Console.WriteLine(answerA); Console.WriteLine(answerB); class CustomDirectory { public string name; public Dictionary<string, long> files = new (); public CustomDirectory parent; public List<CustomDirectory> subdirs = new(); public CustomDirectory(string name, CustomDirectory parent = null) { this.name = name; this.parent = parent; } public long GetTotalFileSize() { long value = 0; foreach (var subDir in subdirs) { value += subDir.GetTotalFileSize(); } foreach (var file in files) { value += file.Value; } return value; } public long GetTotalBelow(long max) { long value = 0; long dirSize = 0; // Keep value from subdirs foreach (var subDir in subdirs) { value += subDir.GetTotalBelow(max); } // Add to value if we have a total below max foreach (var subDir in subdirs) { dirSize += subDir.GetTotalFileSize(); } foreach (var file in files) { dirSize += file.Value; } if (dirSize <= max) value += dirSize; return value; } public List<long> FindDirectoriesAbove(long minSize) { long dirSize = 0; var sizes = new List<long>(); // Keep sizes from subdirs foreach (var subDir in subdirs) { sizes.AddRange(subDir.FindDirectoriesAbove(minSize)); } // Add to sizes if we have a total above min foreach (var subDir in subdirs) { dirSize += subDir.GetTotalFileSize(); } foreach (var file in files) { dirSize += file.Value; } if (dirSize >= minSize) sizes.Add(dirSize); return sizes; } }

Dold text

Edit: Jag satt ju dessutom alldeles för lÀnge och skrev om koden om och om igen för att jag inte fick mitt resultat att stÀmma överens med texten till del 2... Bara för att till slut inse att det som stod i texten gÀllde för exemplet, och inte min egen input... *faceplant*

Visa signatur

CPU: 7950X 5GHz@1.1v | RAM: 32GB 6000MHz CL36 | GPU: KFAÂČ 3090 SG w/ AlphaCool Eisblock Aurora
Ljudkort: Modius + Magnius | Lurar: GoldPlanar GL2000 / Sennheiser HD 650 / Philips Fidelio X3 / Supreme CD-99

PermalÀnk
Medlem ★
●

Dag: 5
SprÄk: Rust

Hade inte riktigt tid med parsningen, sÄ fuskade och skapade startlÀget "manuellt".

Dold text

fn main() { let input = include_str!("./input.txt"); let v0 = vec![]; let v1 = vec!['L', 'N', 'W', 'T', 'D']; let v2 = vec!['C', 'P', 'H']; let v3 = vec!['W', 'P', 'H', 'N', 'D', 'G', 'M', 'J']; let v4 = vec!['C', 'W', 'S', 'N', 'T', 'Q', 'L']; let v5 = vec!['P', 'H', 'C', 'N']; let v6 = vec!['T', 'H', 'N', 'D', 'M', 'W', 'Q', 'B']; let v7 = vec!['M', 'B', 'R', 'J', 'G', 'S', 'L']; let v8 = vec!['Z', 'N', 'W', 'G', 'V', 'B', 'R', 'T']; let v9 = vec!['W', 'G', 'D', 'N', 'P', 'L']; let mut v = vec![v0, v1, v2, v3, v4, v5, v6, v7, v8, v9]; let crane_model = "9001"; for line in input.lines() { let split: Vec<&str> = line.split(" ").collect(); let amount = split[1].parse::<usize>().unwrap(); let from = split[3].parse::<usize>().unwrap(); let to = split[5].parse::<usize>().unwrap(); if crane_model.eq("9000") { for _i in 0..amount { let current_crate = v[from].pop().unwrap(); v[to].push(current_crate); } } else if crane_model.eq("9001") { let mut temp_v = vec![]; for _i in 0..amount { let current_crate = v[from].pop().unwrap(); temp_v.push(current_crate); } v[to].append(&mut temp_v.into_iter().rev().collect()); } } println!("{:?}", v[1]); println!("{:?}", v[2]); println!("{:?}", v[3]); println!("{:?}", v[4]); println!("{:?}", v[5]); println!("{:?}", v[6]); println!("{:?}", v[7]); println!("{:?}", v[8]); println!("{:?}", v[9]); print!("Solution 2: "); print!("{}", v[1].last().unwrap()); print!("{}", v[2].last().unwrap()); print!("{}", v[3].last().unwrap()); print!("{}", v[4].last().unwrap()); print!("{}", v[5].last().unwrap()); print!("{}", v[6].last().unwrap()); print!("{}", v[7].last().unwrap()); print!("{}", v[8].last().unwrap()); print!("{}", v[9].last().unwrap()); println!(""); }

Dold text

Dag: 6
SprÄk: Rust

fn find_marker(input: &str, len: usize) -> usize { let mut found; for i in 13..input.len() { found = true; for j in 0..len { for k in j..len { if j != k { if input.chars().nth(i - j).unwrap() == input.chars().nth(i-k).unwrap() { found = false; } } } } if found { return i + 1; } } return 0; } fn main() { let input = include_str!("./input.txt"); println!("Start-of-packet marker: {}", find_marker(input, 4)); println!("Start-of-message marker: {}", find_marker(input, 14)); }

Dold text

Dag: 7
SprÄk: Rust

Dold text

Första uppgiften dÀr jag Ängrar mitt val av sprÄk. Började med att försöka implementera ett trÀd, men att göra det med alla Rust's tankar om minnessÀkerhet övergick min förmÄga. SÄ fick bli en enklare och fulare lösning, men den fungerar för ÀndamÄlet...

use std::collections::HashMap; fn main() { let input = include_str!("./input.txt"); let mut filesystem = HashMap::new(); filesystem.insert("".to_string(), 0); let mut current_path = vec![""]; for line in input.lines() { let command: Vec<&str> = line.split(" ").collect(); if command[0].eq("$") { if command[1].eq("cd") && command[2].eq("/") { current_path = vec![""]; } else if command[1].eq("cd") && command[2].eq("..") { current_path.pop(); } else if command[1].eq("cd") { current_path.push(command[2]); filesystem.insert(current_path.join("/"), if filesystem.contains_key(&current_path.join("/")) { filesystem[&current_path.join("/")] } else {0}); } } else if command[0].eq("dir") { /* ignore */ } else { let mut temp_current_path = current_path.clone(); for _i in 0..temp_current_path.len() { *filesystem.get_mut(&temp_current_path.join("/")).unwrap() += command[0].parse::<u32>().unwrap(); temp_current_path.pop(); } } } let mut size_for_part_1: u32 = 0; let mut folder_size = vec![]; for (_dir, size) in &filesystem { folder_size.push(*size); if *size <= 100000 { size_for_part_1 += size; } } println!("Sum for part 1: {}", size_for_part_1); let free_space = 70000000 - filesystem[""]; let minimum_to_delete = 30000000 - free_space; folder_size.sort(); for i in 0..folder_size.len() { if folder_size[i] >= minimum_to_delete { println!("Delete folder with size: {}", folder_size[i]); break; } } }

Dold text
PermalÀnk
Medlem
●

Dag: 7
SprÄk: Scala
Fulkod. Fick fel resultat ett antal gÄnger eftersom jag inte kan rÀkna nollor och var dum nog att inte klippa/klistra.

val input = Using.resource(Source.fromFile("""7.txt"""))(_.getLines().toList) val sizes = input .foldLeft((List.empty[String], Map.empty[List[String], Int])) { case ((p, s), s"$$ cd ..") => (p.tail, s) case ((p, s), s"$$ cd $dir") => (dir :: p, s) case ((p, s), s"$sz $_") if sz.toIntOption.nonEmpty => val s2 = p.tails.foldLeft(s)((m, p) => m.updatedWith(p) { case None => Some(sz.toInt) case Some(v) => Some(v + sz.toInt) }) (p, s2) case ((p, s), _) => (p, s) } ._2 // del1 sizes.collect { case (_, size) if size <= 100_000 => size }.sum // del2 sizes.collect { case (_, size) if size >= 30_000_000 - (70_000_000 - sizes(List("/"))) => size }.min

Dold text
PermalÀnk
Medlem ★
●

Dag: 7
SprÄk: C++

Det blev en nÄgot överarbetad lösning, skapade ett trÀd av det hela med rekursiva funktioner för att traversera trÀdet. Hade problem med att testdatan gav mig korrekt svar men fick fel svar i den faktiska datan vilket alltid Àr oerhört frustrerande. Efter att ha utökat testdatan med egen data sÄ lyckades jag finna felet till slut i alla fall men jag föredrar verkligen nÀr testdatan Àr mer komplett, vilket den oftast brukar vara.

#include "../AoCHelper/AoCHelper.h" #include <vector> struct Directory { std::string name; Directory *parent; std::vector<Directory> subDirectories; std::vector<std::pair<std::string, size_t>> files; size_t total_size{0}; }; std::vector<Directory> findAllDirectoriesWithSizeLargerThan(std::vector<Directory> &directories, size_t size) { std::vector<Directory> directoriesWithSizeLargerThan; for (Directory directory : directories) { if (directory.total_size > size) { directoriesWithSizeLargerThan.push_back(directory); } std::vector<Directory> subDirectoriesWithSizeLargerThan = findAllDirectoriesWithSizeLargerThan(directory.subDirectories, size); directoriesWithSizeLargerThan.insert(directoriesWithSizeLargerThan.end(), subDirectoriesWithSizeLargerThan.begin(), subDirectoriesWithSizeLargerThan.end()); } return directoriesWithSizeLargerThan; } size_t findAllDirectoriesWithSizeLessThan(std::vector<Directory> &directories, size_t size) { size_t total{0}; for (Directory directory : directories) { if (directory.total_size <= size) { total += directory.total_size; } total += findAllDirectoriesWithSizeLessThan(directory.subDirectories, size); } return total; } size_t getDirectorySize(Directory &directory) { size_t size{0}; for (std::pair<std::string, size_t> file : directory.files) { size += file.second; } for (Directory subDirectory : directory.subDirectories) { size += getDirectorySize(subDirectory); } return size; } void updateAllTotalSizes(Directory &directory) { directory.total_size = getDirectorySize(directory); for (Directory &subDirectory : directory.subDirectories) { updateAllTotalSizes(subDirectory); } } void puzzle(std::vector<std::string> input) { size_t answer{}; Directory root{"/", nullptr, {}, {}, 0}; Directory *currentDirectory = &root; for (int i = 0; i < input.size(); i++) { std::string row = input[i]; if (row == "$ cd /") { currentDirectory = &root; } else if (row == "$ cd ..") { currentDirectory = currentDirectory->parent; } else if (row.substr(0, 4) == "$ cd") { std::string directoryName = myLib::split(row, ' ')[2]; if (std::any_of(currentDirectory->subDirectories.begin(), currentDirectory->subDirectories.end(), [directoryName](Directory directory) { return directory.name == directoryName; })) { for (Directory &directory : currentDirectory->subDirectories) { if (directory.name == directoryName) { currentDirectory = &directory; } } } else { Directory newDirectory{directoryName, currentDirectory, {}, {}, 0}; currentDirectory->subDirectories.push_back(newDirectory); currentDirectory = &newDirectory; } } else if (row == "$ ls") { size_t j = i + 1; while (input[j].substr(0, 1) != "$") { if (input[j].substr(0, 4) == "dir ") { std::string subDirectoryName = myLib::split(input[j], ' ')[1]; if (std::none_of(currentDirectory->subDirectories.begin(), currentDirectory->subDirectories.end(), [subDirectoryName](Directory directory) { return directory.name == subDirectoryName; })) { Directory newDirectory{subDirectoryName, currentDirectory, {}, {}, 0}; currentDirectory->subDirectories.push_back(newDirectory); } } else { std::string fileName = myLib::split(input[j], ' ')[1]; size_t fileSize = std::stoi(myLib::split(input[j], ' ')[0]); currentDirectory->files.push_back(std::make_pair(fileName, fileSize)); } if (j == input.size() - 1) { break; } j++; } } } updateAllTotalSizes(root); answer = findAllDirectoriesWithSizeLessThan(root.subDirectories, 100000); std::cout << "Puzzle one: " << answer << std::endl; int freeSpace = 70000000 - root.total_size; int neededSpace = 30000000; int spaceToBeFreed = neededSpace - freeSpace; std::vector<Directory> directoriesWithSizeLargerThan = findAllDirectoriesWithSizeLargerThan(root.subDirectories, spaceToBeFreed); std::sort(directoriesWithSizeLargerThan.begin(), directoriesWithSizeLargerThan.end(), [](Directory a, Directory b) { return a.total_size < b.total_size; }); int answerTwo = directoriesWithSizeLargerThan[0].total_size; std::cout << "Puzzle two: " << answerTwo << std::endl; } int main() { std::vector<std::string> exampleInput{ "$ cd /", "$ ls", "dir a", "14848514 b.txt", "8504156 c.dat", "dir d", "dir g", "$ cd a", "$ ls", "dir e", "29116 f", "2557 g", "62596 h.lst", "$ cd e", "$ ls", "584 i", "$ cd ..", "$ cd ..", "$ cd d", "$ ls", "4060174 j", "8033020 d.log", "5626152 d.ext", "7214296 k", "dir a", // had to add extra example data to find a bug in my program "$ cd a", "$ ls", "10203 abc", "$ cd /", "$ cd g", "$ ls", "2000 b.txt", "1000 c.dat", "dir k" "$ cd k", "$ ls", "5000 b.txt"}; AoCHelper a1{"2022", "7"}; std::vector<std::string> result = a1.get_input(); puzzle(result); }

Dold text
PermalÀnk
Medlem ★
●
Citat:

Edit: Jag satt ju dessutom alldeles för lÀnge och skrev om koden om och om igen för att jag inte fick mitt resultat att stÀmma överens med texten till del 2... Bara för att till slut inse att det som stod i texten gÀllde för exemplet, och inte min egen input... *faceplant*

Jag gjorde samma! Sen satt jag och gjorde om utrÀkningen flera gÄnger, men egentligen hade jag bara lÀst in pÄ fel sÀtt. Fun times!

PermalÀnk
●

Dag 7
C#

Slog knut pÄ mig sjÀlv denna uppgift och gjorde det helt klart svÄrare för mig Àn vad det borde varit. Helt vÀrdelös och bloatad kod med en fulfix för att rensa upp sÄ inte vissa directories dubbelrÀknades. Var visst nÄgot fel i hur jag kollade upp vilka underdirectories som tillhörde rotkatalogen men gick att fixa efter att ha slitit mitt obefintliga hÄr ett tag för att hitta felet. Men det funkade till slut, puh! Blir ju extra pinsamt nÀr man ser hur enkelt och lite kod andra har skrivit för denna uppgift.

public class Dir { public int dirNo; public int pDir; public string dir = ""; public List<int> upDir = new List<int>(); public List<Fil> files=new List<Fil>(); public void Print() { for(int i=0; i<files.Count();i++) { Console.WriteLine(files[i].name+" "+files[i].size); } } } public class Fil { public int size; public string name = ""; } public static void Day7() { String[] data = File.ReadAllLines("Day7.txt"); List<Dir> struktur = new List<Dir>(); Dir M = new Dir(); int currentDir = 0; int[] allSizes = new int[10000]; int counter = 0; struktur.Add(M); struktur[0].dir = "/"; struktur[0].pDir = 0; struktur[0].dirNo = 0; for (int i = 0; i < data.Length; i++) { String[] instructions = data[i].Split(' '); for(int j = 0; j < instructions.Length; j++) { if(instructions[j] == "cd") { for(int k = 0; k < struktur.Count(); k++) { if (instructions[j + 1]=="..") { currentDir = struktur[currentDir].pDir; break; } else if(struktur[currentDir].dir + instructions[j + 1]+"/" == struktur[k].dir) { currentDir = struktur[k].dirNo; break; } } } if(instructions[j] == "dir") { struktur[currentDir].upDir.Add(struktur.Count()); M = new Dir(); M.dir = struktur[currentDir].dir + instructions[j+1]+"/"; M.pDir = currentDir; M.dirNo=struktur.Count(); struktur.Add(M); } int a; if (int.TryParse(instructions[j],out a) == true) { Fil F = new Fil(); F.size = int.Parse(instructions[j]); F.name = instructions[j+1]; struktur[currentDir].files.Add(F); } } } int result = 0; for(int i= struktur.Count()-1; i>-1;i--) { struktur[struktur[i].pDir].upDir.AddRange(struktur[struktur[i].dirNo].upDir); } struktur[0].upDir.Sort(); for(int i=0; i< struktur[0].upDir.Count();i++) { if (struktur[0].upDir[i] == struktur[0].upDir[i]) { struktur[0].upDir.RemoveAt(i); } } for (int i = 0; i<struktur.Count(); i++) { int max = 0; for (int k = 0; k < struktur[i].files.Count(); k++) { max = max + struktur[i].files[k].size; } for (int j = 0; j < struktur[i].upDir.Count(); j++) { for(int k = 0; k < struktur[struktur[i].upDir[j]].files.Count(); k++) { max = max+ struktur[struktur[i].upDir[j]].files[k].size; } } allSizes[counter] = max; counter++; if (max < 100001) result = result + max; } int maxx = 0; for (int i = 0; i < allSizes.Length; i++) { if (allSizes[i] > maxx) maxx = allSizes[i]; if (allSizes[i] == 0) break; } double result2= 70000000; for (int i = 0; i<allSizes.Length; i++) { if (allSizes[i]> 30000000-(70000000 - maxx) && allSizes[i]<result2) result2=allSizes[i]; if (allSizes[i] == 0) break; } Console.WriteLine(); Console.WriteLine("Day7"); Console.WriteLine("Step1 result "+result+ " Step2 result " + result2); }

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

Jag gjorde samma! Sen satt jag och gjorde om utrÀkningen flera gÄnger, men egentligen hade jag bara lÀst in pÄ fel sÀtt. Fun times!

Jag har haft roligare!!!

Att vakna, kolla pÄ klockan och se att den Àr 06:30 och flyga upp till datorn Àr vÀl inte helt optimalt för programmering, hehe. Borde ha lyssnat pÄ magkÀnslan och kört pÄ rekursion redan frÄn början, men det Àr bra lÀrotillfÀlle detta. Lite synd bara att det Àr sÄ konstiga uppgifter som Àr snudd pÄ helt whack.

Visa signatur

CPU: 7950X 5GHz@1.1v | RAM: 32GB 6000MHz CL36 | GPU: KFAÂČ 3090 SG w/ AlphaCool Eisblock Aurora
Ljudkort: Modius + Magnius | Lurar: GoldPlanar GL2000 / Sennheiser HD 650 / Philips Fidelio X3 / Supreme CD-99

PermalÀnk
Medlem
●

Dag: 7
SprÄk: C

#include <errno.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> #include <string.h> struct file { unsigned int size; char *name; struct file *prev; }; struct dir { char *name; struct file *files; struct dir *dirs; struct dir *parent; struct dir *prev; }; struct state { struct dir *root; struct dir *cwd; FILE *fp; char *line; size_t len; }; struct cmd { char *cmdstr; int n; void (*doCmd)(struct state *s, char *arg); }; struct dir *getDir(struct dir *from, char *name) { for (struct dir *d = from->dirs; d; d=d->prev) { if (!strcmp(d->name, name)) return d; } return NULL; } void doCD(struct state *s, char *arg) { struct dir *d; if (!strcmp(arg, "/")) { s->cwd = s->root; return; } else if (!strcmp(arg, "..")) { s->cwd = s->cwd->parent; return; } d = getDir(s->cwd, arg); if (d) { s->cwd = d; return; } printf("cd: Invalid argument\n"); return; } void addDir(struct dir *dir, char *arg) { struct dir *new = getDir(dir, arg); if (new) return; new = calloc(1, sizeof(struct dir)); if (!new) exit(EXIT_FAILURE); new->name = strdup(arg); if (!new->name) exit(EXIT_FAILURE); new->prev = dir->dirs; new->parent = dir; dir->dirs = new; return; } int parseInt(const char *str) { char *endptr; int ret; errno = 0; ret = strtol(str, &endptr, 10); if (errno != 0) { perror("Failed to parse string"); exit(EXIT_FAILURE); } if (endptr == str) { fprintf(stderr, "No digits were found\n"); exit(EXIT_FAILURE); } return ret; } struct file *getFile(struct dir *d, char *name) { for (struct file *f=d->files; f; f=f->prev) { if (!strcmp(f->name, name)) return f; } return NULL; } void addFile(struct dir *d, char *arg) { char *name = strrchr(arg, ' ') + 1; struct file *f = getFile(d, name); if (f) return; f = calloc(1, sizeof(struct file)); if (!f) exit(EXIT_FAILURE); f->name = strdup(name); if (!f) exit(EXIT_FAILURE); f->size = parseInt(arg); f->prev = d->files; d->files = f; return; } void parseLS(struct state *s, char *arg) { ssize_t nread; (void) arg; while ((nread = getline(&s->line, &s->len, s->fp)) != -1) { s->line[nread-1] = '\0'; if (s->line[0] == '$') { fseek(s->fp, -nread, SEEK_CUR); return; } else if (!strncmp("dir ", s->line, 4)) { // dir addDir(s->cwd, s->line+4); } else { // file addFile(s->cwd, s->line); } } return; } struct cmd cmds[] = { { .cmdstr = "$ cd ", .n = sizeof("$ cd ")-1, .doCmd = &doCD }, { .cmdstr = "$ ls", .n = sizeof("$ ls")-1, .doCmd = &parseLS }, { 0 } }; void parseCMD(struct state *s, char *line) { for (struct cmd *c = cmds; c->cmdstr; c++) { if (!strncmp(line, c->cmdstr, c->n)) { c->doCmd(s, &line[c->n]); return; } } printf("Unknown command: %s\n", line); return; } void printFiles(struct dir *dir, int nindent) { for (struct file *f = dir->files; f; f=f->prev) printf("%*s- %s (file, size=%d)\n", nindent * 2, "", f->name, f->size); } void printDir(struct dir *dir, int nindent) { printf("%*s- %s (dir)\n", nindent * 2, "", dir->name); for (struct dir *d = dir->dirs; d; d=d->prev) printDir(d, nindent+1); printFiles(dir, nindent+1); } unsigned int getFileSize(struct dir *dir) { int ret = 0; for (struct file *f = dir->files; f; f=f->prev) ret += f->size; return ret; } unsigned int getDirSize(struct dir *dir) { unsigned int ret = 0; for (struct dir *d = dir->dirs; d; d=d->prev) ret += getDirSize(d); ret += getFileSize(dir); return ret; } unsigned int getDirsBelow(struct dir *dir, unsigned int threshold) { unsigned int ret = 0; for (struct dir *d = dir->dirs; d; d=d->prev) { unsigned int dsiz = getDirSize(d); if (dsiz <= threshold) ret += dsiz; ret += getDirsBelow(d, threshold); } return ret; } unsigned int getDirAbove(struct dir *dir, unsigned int threshold) { unsigned int retsize = getDirSize(dir); for (struct dir *d = dir->dirs; d; d=d->prev) { unsigned int dsiz = getDirAbove(d, threshold); if (dsiz > threshold && dsiz < retsize) retsize = dsiz; } return retsize; } void freeFiles(struct dir *dir) { for (struct file *f = dir->files; f;) { struct file *tmp = f->prev; free(f->name); f->name = NULL; free(f); f = tmp; } } void freeDir(struct dir *dir) { for (struct dir *d = dir->dirs; d; d=d->prev) freeDir(d); freeFiles(dir); free(dir->name); free(dir); } int main(void) { struct state state = { 0 }; ssize_t nread; state.line = NULL; unsigned int space_total = 70000000; unsigned int space_needed = 30000000; unsigned int need_to_free; state.root = calloc(1, sizeof(struct dir)); if (!state.root) exit(EXIT_FAILURE); state.root->parent = state.root; state.root->name = strdup("/"); state.cwd = state.root; state.fp = fopen("d7_input.txt", "r"); if (!state.fp) { perror("Failed to open file"); exit(EXIT_FAILURE); } while ((nread = getline(&state.line, &state.len, state.fp)) != -1) { state.line[nread-1] = '\0'; parseCMD(&state, state.line); } free(state.line); fclose(state.fp); printDir(state.root, 0); need_to_free = space_needed - (space_total - getDirSize(state.root)); printf("total size: %u\n", getDirSize(state.root)); printf("need to free: %u\n", need_to_free); printf("total special size (part 1): %u\n", getDirsBelow(state.root, 100000)); printf("delete size (part 2): %u\n", getDirAbove(state.root, need_to_free)); freeDir(state.root); exit(EXIT_SUCCESS); }

Dold text
PermalÀnk
Medlem ★
●

Dag: 7
SprÄk: Kotlin

Idag Ă€r man kanske inte sĂ„ nöjd. Satt en bra stund och klurade pĂ„ en lösning innan jag insĂ„g att samma mapp-namn naturligtvis kunde förekomma flera gĂ„nger. UpptĂ€ckte att min "dir till dir" graf gick i cirklar đŸ„č

Löste det ganska bruteforce.

Löper igenom alla rader och bygger pÄ och tar bort frÄn "sökvÀgen" under tiden. Sparar ner alla fil- och mapp-strÀngar pÄ deras sökvÀg i en map. Hittar sedan storleken pÄ varje mapp pÄ ett rekursivt och ineffektivt sÀtt och sparar i en map. val structureMap = mutableMapOf<List<String>, MutableList<String>>() val path = mutableListOf<String>() for (line in input.lines().map { it.trim() }) { if (line.subSequence(0, 4) == "$ cd") { val secondPart = line.substring(5) if(secondPart == "..") path.removeLast() else path.add(secondPart) } else if (!line.contains("\$ ls")) { structureMap.getOrPut(path.toList()) { mutableListOf() }.add(line) } } val sizeMap = structureMap.keys.associateWith { sizeSubstructure(it, structureMap) } println(sizeMap.filter { it.value < 100000 }.values.sum()) // Part 1 val minDelete = sizeMap.values.max() - (70000000 - 30000000) println(sizeMap.filter { it.value > minDelete }.values.minOf { it }) // Part 2 } fun sizeSubstructure(path: List<String>, structure: Map<List<String>, List<String>>): Int = structure[path]!!.sumOf { if(it.contains("dir")) sizeSubstructure(path + listOf(it.split(" ")[1]), structure) else it.split(" ")[0].toInt() }

Dold text

Edit: Skrev om efter att sett en liten del av en annans kommentar.

UtelÀmnade namn och sÄdant denna gÄngen. TÀnkte pÄ det nÀr jag gjorde första delen, men trodde man skulle behöva dem för del 2.

val dirStack = mutableListOf<Int>() val finishedDirs = mutableListOf<Int>() for (line in input.lines()) { if (line.substring(0, 4) == "$ cd") if (line.contains("..")) finishedDirs.add(dirStack.removeLast()) else dirStack.add(0) dirStack.replaceAll { it + (line.split(" ").first().toIntOrNull()?: 0) } } finishedDirs.addAll(dirStack) println(finishedDirs.filter { it < 100000 }.sum()) // Part 1 println(finishedDirs.filter { it > finishedDirs.max() - 40000000 }.min()) // Part 2

Dold text
Visa signatur

i5-7600k . GTX 1080 . 16 GB

PermalÀnk
Medlem ★
●

Dag: 7 (version 2)
SprÄk: Python

Man kan strunta helt i alla namnen. Det enda intressanta Àr att addera alla storlekar. Stoppa dem i en stack, pusha 0 nÀr man gör cd till nytt directory. Vid "cd ..", poppa av den ackumulerade storleken och addera till förÀldern i stacken. Spara den poppade storleken i listan av alla storlekar.

KrÀvs dock att man stÀdar stacken pÄ slutet eftersom de inte avslutar input med att gÄ upp till "/" igen.

En traversering och allt Àr klart. Inga strÀngar att brÄka med.

import itertools def read_sizes(current_size = [], all_sizes = []): for l in open("input07").readlines(): match l.strip().split(): case ['$', 'cd', d]: if d == "..": s = current_size.pop() all_sizes.append(s) current_size[-1] += s else: current_size.append(0) case ['$', 'ls']: pass case ['dir', d]: pass case [size, _]: current_size[-1] += int(size) return all_sizes + list(itertools.accumulate(current_size[::-1])) sizes = read_sizes() print(sum([s for s in sizes if s < 100000]), min([s for s in sizes if 70000000 - max(sizes) + s >= 30000000]))

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

Dag: 7
SprÄk: Go

Idag gÄr det sakta, men sÄnn fick det bli.

pkg: aoc2022/07/a BenchmarkPartOne-8 3448 296894 ns/op BenchmarkPartTwo-8 3934 307687 ns/op

package main import ( "bufio" "fmt" "os" "sort" "strings" ) type Instruction struct { Cmd string Files []FileDesc Folders []string } type FileDesc struct { Name string Size int } func getSizePerFolderAndFolderChildRelation(rows []Instruction) (map[string]int, map[string][]string) { localSizePerFolder := make(map[string]int, 0) folderChild := make(map[string][]string, 0) currentFolderStack := make([]string, 0) for _, row := range rows { size := 0 if strings.HasPrefix(row.Cmd, "cd ") { if row.Cmd == "cd .." { currentFolderStack = currentFolderStack[:len(currentFolderStack)-1] continue } else { currentFolderStack = append(currentFolderStack, strings.Replace(row.Cmd, "cd ", "", 1)) } } currentFolder := "" for _, f := range currentFolderStack { if f == "/" { currentFolder += "/" } else { currentFolder += f + "/" } } for _, file := range row.Files { size += file.Size } localSizePerFolder[currentFolder] = size for _, folder := range row.Folders { folderChild[currentFolder] = append(folderChild[currentFolder], currentFolder+folder+"/") } } return localSizePerFolder, folderChild } func findActualFolderSize(name string, localSizePerFolder map[string]int, folderChild map[string][]string) int { size := 0 if val, ok := localSizePerFolder[name]; ok { size += val } if _, ok := folderChild[name]; !ok { return size } for _, sub := range folderChild[name] { size += findActualFolderSize(sub, localSizePerFolder, folderChild) } return size } func getPartOne(rows []Instruction) int { localSizePerFolder, folderChild := getSizePerFolderAndFolderChildRelation(rows) sum := 0 for folder := range localSizePerFolder { s := findActualFolderSize(folder, localSizePerFolder, folderChild) if s <= 100000 { sum += s } } return sum } func getPartTwo(rows []Instruction) int { localSizePerFolder, folderChild := getSizePerFolderAndFolderChildRelation(rows) total := 70000000 wanted := 30000000 actual := findActualFolderSize("/", localSizePerFolder, folderChild) res := make([]int, 0) for folder := range localSizePerFolder { s := findActualFolderSize(folder, localSizePerFolder, folderChild) if total-actual+s > wanted { res = append(res, s) } } sort.Ints(res) return res[0] } func getRows(filename string) []Instruction { file, err := os.Open(filename) if err != nil { panic(err) } defer file.Close() scanner := bufio.NewScanner(file) instructions := make([]Instruction, 0) i := -1 for scanner.Scan() { row := scanner.Text() if strings.Contains(row, "$") { var inst Instruction inst.Cmd = strings.Replace(row, "$ ", "", 1) instructions = append(instructions, inst) i++ } else { if strings.Contains(row, "dir") { var folder string fmt.Sscanf(row, "dir %s", &folder) instructions[i].Folders = append(instructions[i].Folders, folder) } else { var fileDesc FileDesc fmt.Sscanf(row, "%d %s", &fileDesc.Size, &fileDesc.Name) instructions[i].Files = append(instructions[i].Files, fileDesc) } } } return instructions } func main() { fmt.Println("Part one:", getPartOne(getRows("../input.txt"))) fmt.Println("Part two:", getPartTwo(getRows("../input.txt"))) }

Dold text

FrÄga: vad Àr det som Àr med i benchmark-mÀtningen?

Har dessa dÀr parseInput(7) lÀser in min test-input för dag 7

func BenchmarkDay7_parsing(b *testing.B) { input := parseInput(7) for n := 0; n < b.N; n++ { parseFilesystem(input) } } func BenchmarkDay7_part1(b *testing.B) { fs := parseFilesystem(parseInput(7)) for n := 0; n < b.N; n++ { fs.sumSizeWithLimit(100000) } } func BenchmarkDay7_part2(b *testing.B) { fs := parseFilesystem(parseInput(7)) for n := 0; n < b.N; n++ { fs.bestFitForCap(70000000, 30000000) } }

FÄr dessa resultat pÄ en M1:a

$ go test -bench Day7 . goos: darwin goarch: arm64 pkg: aoc2022 BenchmarkDay7_parsing-8 3466 329109 ns/op BenchmarkDay7_part1-8 218112 5434 ns/op BenchmarkDay7_part2-8 220860 5375 ns/op PASS ok aoc2022 3.766s

Dold text
Visa signatur

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

PermalÀnk
Medlem
●
Skrivet av Yoshman:

FrÄga: vad Àr det som Àr med i benchmark-mÀtningen?

Har dessa dÀr parseInput(7) lÀser in min test-input för dag 7

func BenchmarkDay7_parsing(b *testing.B) { input := parseInput(7) for n := 0; n < b.N; n++ { parseFilesystem(input) } } func BenchmarkDay7_part1(b *testing.B) { fs := parseFilesystem(parseInput(7)) for n := 0; n < b.N; n++ { fs.sumSizeWithLimit(100000) } } func BenchmarkDay7_part2(b *testing.B) { fs := parseFilesystem(parseInput(7)) for n := 0; n < b.N; n++ { fs.bestFitForCap(70000000, 30000000) } }

FÄr dessa resultat pÄ en M1:a

$ go test -bench Day7 . goos: darwin goarch: arm64 pkg: aoc2022 BenchmarkDay7_parsing-8 3466 329109 ns/op BenchmarkDay7_part1-8 218112 5434 ns/op BenchmarkDay7_part2-8 220860 5375 ns/op PASS ok aoc2022 3.766s

Dold text

Bara berÀkningen, vill inte nöta pÄ min ssd i onödan.

PermalÀnk
Medlem ★
●

Dag: 7
SprÄk: Elixir
Lösning: Github

Visa signatur

AMD Ryzen 7 1700X 3.8 GHz 20MB | ASUS PRIME X370-PRO | MSI GeForce GTX 1080 Gaming X 8GB | G.Skill 16GB DDR4 3200 MHz CL14 Flare X | Corsair RM650x 650W

PermalÀnk
Medlem
●

Dag: 7
SprÄk: C#

Skoj uppgift med lite rekursion och traversering

namespace AOC2022.Puzzles; internal partial class Puzzle7 : Puzzle<int> { interface INode { Directory? Parent { get; } string Filename { get; } int Size { get; } } record Directory(string Filename, Directory? Parent) : INode { public List<INode> Children { get; } = new List<INode>(); public int Size => Children.Sum(c => c.Size); } record File(string Filename, int Size, Directory? Parent): INode; protected override void Solve(string[] lines) { var rootDir = lines.Skip(1).Aggregate( new Directory("/", null), (currentDir, line) => { if (line[0] != '$') { currentDir.Children.Add(ParseNode(line, currentDir)); return currentDir; } if (line.StartsWith("$ cd")) { var dirTarget = line.Split(' ').Last(); return dirTarget switch { ".." => currentDir.Parent!, _ => currentDir.Children.OfType<Directory>().First(x => x.Filename == dirTarget) }; } return currentDir; }, GetRoot); One = GetDirectories(rootDir).Where(dir => dir.Size <= 100000).Sum(c => c.Size); Two = GetDirectories(rootDir).Where(dir => dir.Size > (rootDir.Size - 40000000)) .OrderBy(x => x.Size).First().Size; } private static INode ParseNode(string filename, Directory parent) { var split = filename.Split(' '); return filename.StartsWith("dir") ? new Directory(split[1], parent) : new File(split[1], int.Parse(split[0]), parent); } private static IEnumerable<Directory> GetDirectories(Directory dir) => dir.Children .OfType<Directory>().SelectMany(GetDirectories).Append(dir); private static Directory GetRoot(INode node) => node.Parent != null ? GetRoot(node.Parent) : (Directory) node; }

Dold text
PermalÀnk
●

Dag: 7
SprÄk: Haskell

Ojojoj. Jag har hÄllit pÄ hela dan, av och till. Vid nÄgot tillfÀlle var adventofcode.com nere, senare togs stackoverflow ner för underhÄll! Det gick vÀgen till slut, men snyggt blev det inte.

Löste det genom att skapa en lista som matchade full sökvÀg med filstorlekar och sen söka i den listan. NÄgra problem jag stötte pÄ var att tomma kataloger inte kom med (jag hade bara filer i listan först) och att jag antog att alla kataloger hade namn pÄ bara en bokstav.

-- The program expects the input on stdin, ie -- $ ./solve < input import Data.List (isPrefixOf, nub, sortBy) main = interact solve solve :: String -> String solve input = "Problem 1: " ++ show p1 ++ "\n" ++ "Problem 2: " ++ show p2 ++ "\n" where p2 = snd (head (sortBy (\(_,a) (_,b) -> compare a b) bigEnoughToDelete)) bigEnoughToDelete = filter (\d -> snd d>=neededSpace) allSizes neededSpace = 30000000 - 70000000 + snd (head (filter (\d -> fst d == "/") allSizes)) p1 = sum (filter (<=100000) (map snd allSizes)) allSizes = map (\d -> (d, calcSize fullPathFiles d)) allDirs allDirs = "/" : nub (map fst (filter (\x -> snd x==0) fullPathFiles)) fullPathFiles = listFullPath [] (lines input) -- Calculate total size of a directory. calcSize :: [(String, Int)] -> String -> Int calcSize x path = sum (map snd (filter (\s -> path `isPrefixOf` (fst s)) x)) -- Create a list of (fullpath, size). listFullPath :: String -> [String] -> [(String, Int)] listFullPath cwd (l:ls) = case words l of ("$":"cd":"/":[]) -> listFullPath "/" ls ("$":"cd":"..":[]) -> listFullPath (dropWhile (/='/') (tail cwd)) ls ("$":"cd":dir:[]) -> listFullPath ("/" ++ reverse dir ++ cwd) ls ("$":"ls":[]) -> listFullPath cwd ls ("dir":dir:[]) -> (reverse cwd ++ dir, 0):listFullPath cwd ls (size:file:[]) -> (reverse cwd ++ file, read size):listFullPath cwd ls otherwise -> listFullPath cwd ls listFullPath _ [] = []

(Jag anvÀnder highlight som finns i apt för syntaxfÀrgning.)

Dold text
PermalÀnk
Datavetare ★
●

Dag: 7
SprÄk: Python3

SÄ fÄr ge mig pÄ en variant jag ocksÄ...

import itertools st = [] dir_sizes = [] for cmd in itertools.chain(open('day7.txt').readlines(), itertools.cycle(['$ cd ..'])): p = cmd.strip().split() if p[0] == '$' and p[1] == 'cd': if p[2] == '..': top = st.pop() dir_sizes.append(top) if len(st) == 0: break st[-1] = st[-1] + top else: st.append(0) elif p[0].isnumeric(): st[-1] = st[-1] + int(p[0]) print(sum(filter(lambda sz: sz <= 100000, dir_sizes))) additional_space = 30000000 - (70000000 - dir_sizes[-1]) print(min(filter(lambda sz: sz >= additional_space, dir_sizes)))

Verkar populÀrt med stack-lösningen
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: 8
SprÄk: C#
Kommentar: Idag satte jag krokben för mig sjÀlv genom att anvÀnda >= istÀllet för <=. Jag behöver vakna till tror jag

Hemsk kod med mycket förbÀttringspotential, helt klart.

Console.WriteLine("Mickur's Advent of Code 2022 - Day 8!"); var input = File.ReadAllLines("input.txt"); var treeGrid = new List<List<int>>(); var counter = 0; long bestBAnswer = 0; foreach (var line in input) { var currRow = new List<int>(); for (var i = 0; i < line.Length; i++) { currRow.Add(line[i]); } treeGrid.Add(currRow); } var height = treeGrid.Count - 1; var width = treeGrid[0].Count - 1; for (var currY = 0; currY < treeGrid.Count; currY++) { for (var currX = 0; currX < treeGrid[currY].Count; currX++) { var canBeSeenFromTop = true; var canBeSeenFromRight = true; var canBeSeenFromBottom = true; var canBeSeenFromLeft = true; // Check up and down var currValue = treeGrid[currY][currX]; // A: Check top for (var top = 0; top < currY; top++) { var checkValue = treeGrid[top][currX]; if (checkValue >= currValue) { canBeSeenFromTop = false; break; } } // A: Check right for (var right = width; right > currX; right--) { var checkValue = treeGrid[currY][right]; if (checkValue >= currValue) { canBeSeenFromRight = false; break; } } // A: Check bottom for (var bottom = height; bottom > currY; bottom--) { var checkValue = treeGrid[bottom][currX]; if (checkValue >= currValue) { canBeSeenFromBottom = false; break; } } // A: Check left for (var left = 0; left < currX; left++) { var checkValue = treeGrid[currY][left]; if (checkValue >= currValue) { canBeSeenFromLeft = false; break; } } if (canBeSeenFromTop || canBeSeenFromRight || canBeSeenFromBottom || canBeSeenFromLeft) counter++; // B: Check top var tempY = currY - 1; var topSight = 0; while (tempY >= 0) { if (currValue <= treeGrid[tempY][currX]) { topSight++; break; } if (currValue > treeGrid[tempY][currX]) topSight++; else break; tempY--; } // B: Check bottom tempY = currY + 1; var bottomSight = 0; while (tempY <= height) { if (currValue <= treeGrid[tempY][currX]) { bottomSight++; break; } if (currValue > treeGrid[tempY][currX]) bottomSight++; else break; tempY++; } // B: Check left var tempX = currX - 1; var leftSight = 0; while (tempX >= 0) { if (currValue <= treeGrid[currY][tempX]) { leftSight++; break; } if (currValue > treeGrid[currY][tempX]) leftSight++; else break; tempX--; } // B: Check right tempX = currX + 1; var rightSight = 0; while (tempX <= width) { if (currValue <= treeGrid[currY][tempX]) { rightSight++; break; } if (currValue > treeGrid[currY][tempX]) rightSight++; else break; tempX++; } long bValue = topSight * rightSight * bottomSight * leftSight; if (bValue > bestBAnswer) bestBAnswer = bValue; } } Console.WriteLine(counter); Console.WriteLine(bestBAnswer);

Dold text
Visa signatur

CPU: 7950X 5GHz@1.1v | RAM: 32GB 6000MHz CL36 | GPU: KFAÂČ 3090 SG w/ AlphaCool Eisblock Aurora
Ljudkort: Modius + Magnius | Lurar: GoldPlanar GL2000 / Sennheiser HD 650 / Philips Fidelio X3 / Supreme CD-99

PermalÀnk
●

Dag 8
C#
Riktigt kul uppgift dÀr första delen gick rÀtt sÄ enkelt Àven om det tog lÄng tid att skriva och blev mÄnga rader. Andra delen fick jag sitta lÀnge och fundera pÄ hur loopen egentligen skulle se ut det blev ett par ÄtervÀndsgrÀnder men lösningen blev hyfsat kompakt till slut. SÀkert rÀtt kass kod men svaren blev ju rÀtt sÄ jag Àr nöjd!! Imponerad över de som skapar dessa uppgifter, pÄhittiga och skoj. Extra kul att visualisera skogen idag med lite utskrifter för att se om lösningen sÄg rimlig ut.

del 1

String[] data = File.ReadAllLines("Day8.txt"); int step1 = 0; bool[,] check = new bool[99, 99]; int[,] checkValue=new int[99,99]; //populate visible/invisible trees and tree height for (int i = 0; i < check.GetLength(0); i++) { for(int j = 0; j < check.GetLength(1); j++) { if (i == 0 || j == 0 || i == check.GetLength(0) - 1 || j == check.GetLength(1) - 1) check[i, j] = true; else check[i, j] = false; checkValue[i, j] = int.Parse(data[i][j].ToString()); } } //check left to right for (int i=1; i < check.GetLength(0)-1; i++) { for( int j = 1; j < check.GetLength(1)-1; j++) { if (checkValue[i,j]> checkValue[i,j-1]) { check[i, j] = true; } if(checkValue[i, j] < checkValue[i, j - 1]) { checkValue[i, j] = checkValue[i, j - 1]; } } } //repopulate tree heights for (int i = 0; i < check.GetLength(0); i++) { for (int j = 0; j < check.GetLength(1); j++) { checkValue[i, j] = int.Parse(data[i][j].ToString()); } } //check from top for (int i = 1; i < check.GetLength(0) - 1; i++) { for (int j = 1; j < check.GetLength(1) - 1; j++) { if (checkValue[i, j] > checkValue[i-1, j]) { check[i, j] = true; } if (checkValue[i, j] < checkValue[i-1, j]) { checkValue[i, j] = checkValue[i-1, j]; } } } //repopulate tree heights for (int i = 0; i < check.GetLength(0); i++) { for (int j = 0; j < check.GetLength(1); j++) { checkValue[i, j] = int.Parse(data[i][j].ToString()); } } //check from right for (int i = check.GetLength(0) - 2; i > 0; i--) { for (int j = check.GetLength(1)-2; j > 0; j--) { if (checkValue[i, j] > checkValue[i, j+1]) { check[i, j] = true; } if (checkValue[i, j] < checkValue[i, j+1]) { checkValue[i, j] = checkValue[i, j+1]; } } } //repopulate tree heights for (int i = 0; i < check.GetLength(0); i++) { for (int j = 0; j < check.GetLength(1); j++) { checkValue[i, j] = int.Parse(data[i][j].ToString()); } } //check from bottom for (int i = check.GetLength(0) - 2; i > 0; i--) { for (int j = check.GetLength(1) - 2; j > 0; j--) { if (checkValue[i, j] > checkValue[i+1, j]) { check[i, j] = true; } if (checkValue[i, j] < checkValue[i+1, j]) { checkValue[i, j] = checkValue[i+1, j]; } } } //calculate how many visible trees for (int i = 0; i < check.GetLength(0); i++) { for (int j = 0; j < check.GetLength(1); j++) { if (check[i, j] == true) step1++; } } Console.WriteLine(); Console.WriteLine("Day8"); Console.Write("Step1 result "+step1+" ");

Dold text

del2

String[] data = File.ReadAllLines("Day8.txt"); int[,] checkValue = new int[99, 99]; int[,] resultN = new int[99, 99]; int[,] resultE = new int[99, 99]; int[,] resultS = new int[99, 99]; int[,] resultW = new int[99, 99]; //populate tree height for (int i = 0; i < checkValue.GetLength(0); i++) { for (int j = 0; j < checkValue.GetLength(1); j++) { checkValue[i, j] = int.Parse(data[i][j].ToString()); } } //check all directions int x = 0; int y=0; for(int i=0; i < checkValue.Length; i++) { if (x == 99) y++; if (x == 99) x = 0; int savey = y; int savex = x; for (int j = x+1; j < checkValue.GetLength(0); j++) { if (checkValue[x, y] > checkValue[j, y]) resultS[x, y]++; else if(checkValue[x, y] <= checkValue[j, y]) { resultS[x, y]++; break; } } x = savex; y = savey; for (int j = y+1; j < checkValue.GetLength(0); j++) { if (checkValue[x, y] > checkValue[x, j]) resultE[x, y]++; else if (checkValue[x, y] <= checkValue[x, j]) { resultE[x, y]++; break; } } x = savex; y = savey; for (int j = x - 1; j > -1 ; j--) { if (checkValue[x, y] > checkValue[j, y]) resultN[x, y]++; else if (checkValue[x, y] <= checkValue[j, y]) { resultN[x, y]++; break; } } x = savex; y = savey; for (int j = y - 1; j > -1; j--) { if (checkValue[x, y] > checkValue[x, j]) resultW[x, y]++; else if (checkValue[x, y] <= checkValue[x, j]) { resultW[x, y]++; break; } } x++; } int svar = 0; //find highest scenic score for (int i = 0; i < checkValue.GetLength(0); i++) { for (int j = 0; j < checkValue.GetLength(1); j++) { if (svar < resultN[i, j] * resultE[i, j] * resultS[i, j] * resultW[i, j]) svar = resultN[i, j] * resultE[i, j] * resultS[i, j] * resultW[i, j]; } } Console.Write("Step2 "+svar);

Dold text
PermalÀnk
Medlem
●

Dag: 8
SprÄk: C#

NÀmen ett gridpussel, vem kunde ana det Har lite gridfunktioner frÄn förra Ärets AOC som kom till perfekt anvÀndning idag.

namespace AOC2022.Puzzles; internal class Puzzle8 : Puzzle<int> { protected override void Solve(string[] lines) { var trees = GetTreeViews(lines).ToList(); One = trees.Count(tree => tree.Visible); Two = trees.Max(tree => tree.Score); } private static IEnumerable<(bool Visible, int Score)> GetTreeViews(string[] lines) { var grid = Grid.CreateGrid(lines); return Grid.Iterate(grid) .Select(cell => { var (treeHeight, treeVisible, totalScore) = (grid[cell.x, cell.y], false, 1); foreach (var (dx, dy) in Grid.NeighborOffsets) { var (clearSight, score, neighbour) = (true, 0, cell); while (!Grid.IsOutOfRange(grid, neighbour = (neighbour.x + dx, neighbour.y + dy))) { score++; if (grid[neighbour.x, neighbour.y] >= treeHeight) { clearSight = false; break; } } totalScore *= score; treeVisible |= clearSight; } return (treeVisible, totalScore); }); } }

Dold text
PermalÀnk
Medlem ★
●

Dag: 8
SprÄk: Kotlin

val intTreeGrid = treeGrid.lines().map { it.map { it.digitToInt() } } val directions = listOf(Pair(-1, 0), Pair(1, 0), Pair(0, -1), Pair(0, 1)) println(intTreeGrid.indices.maxOf { y -> intTreeGrid[y].indices.maxOf { x-> directions.fold(1) { acc, pair -> acc*treeView(Pair(y, x), intTreeGrid, pair, intTreeGrid[y][x]) }}}) println(intTreeGrid.indices.sumOf { y -> intTreeGrid[y].indices.count { x -> !directions.none { isVisible(Pair(y, x), intTreeGrid, it, intTreeGrid[y][x]) }}}) } fun isVisible(position: Pair<Int, Int>, grid: List<List<Int>>, direction: Pair<Int, Int>, height: Int): Boolean{ var newPosition = Pair(position.first + direction.first, position.second + direction.second) while (newPosition.first in grid.indices && newPosition.second in grid.first().indices) { if (grid[newPosition.first][newPosition.second] >= height) return false newPosition = Pair(newPosition.first + direction.first, newPosition.second + direction.second) } return true } fun treeView(position: Pair<Int, Int>, grid: List<List<Int>>, direction: Pair<Int, Int>, height: Int): Int { var distance = 0 var newPosition = Pair(position.first + direction.first, position.second + direction.second) while (newPosition.first in grid.indices && newPosition.second in grid.first().indices && grid[newPosition.first][newPosition.second] < height) { distance ++ newPosition = Pair(newPosition.first + direction.first, newPosition.second + direction.second) } if (newPosition.first in grid.indices && newPosition.second in grid.first().indices) distance++ return distance }

Dold text
Visa signatur

i5-7600k . GTX 1080 . 16 GB