🌟 Advent of Code (AoC) 2023 🌟

PermalÀnk
Medlem
●

Dag: 3
SprÄk: C#

Har en "grid"-klass frÄn tidigare AOC, sÄ med hjÀlp av den sÄ blev dagens uppgift rÀtt enkel att lösa.

namespace AOC2023.Puzzles; internal class Puzzle3 : Puzzle<int> { protected override void Solve(string[] lines) { var grid = Grid.CreateGrid(lines, x => x); var (partsSum, gearRatio) = (0, 0); foreach (var (x,y) in Grid.Iterate(grid)) { var val = grid[x, y]; if (!char.IsNumber(val) && val != '.') { var parts = new HashSet<int>(); foreach (var (nx, ny) in Grid.GetNeighbours(grid, (x,y), true)) { var nVal = grid[nx, ny]; if (char.IsNumber(nVal)) { var (nStart, nEnd) = (nx, nx); while (nStart > 0 && char.IsDigit(grid[nStart - 1, ny])) { nStart--; } while (nEnd < (grid.GetLength(0) - 1) && char.IsDigit(grid[nEnd + 1, ny])) { nEnd++; } parts.Add(int.Parse(string.Concat(Enumerable.Range( nStart, nEnd - nStart + 1).Select(p => grid[p, ny])))); } } partsSum += parts.Sum(); if (val == '*' && parts.Count == 2) { gearRatio += parts.Aggregate((x, y) => x * y); } } } One = partsSum; Two = gearRatio; } }

Dold text
PermalÀnk
Hedersmedlem ★
●

Dag: 3
SprÄk: Python

############ SKA BRYTAS UT TILL EGEN FIL ############## from typing import Any, Sequence, Generic, TypeVar class Cell: def __init__(self, contents: Any): self.contents = contents def __repr__(self): return f"{self.contents}" T = TypeVar('T', bound=Cell) class GenericGrid(Generic[T]): def __init__(self, data: Sequence[Sequence[T]], wrapping = False, default_value = None): self.data = data self.row_count = len(self.data) self.col_count = len(self.data[0]) if len(self.data) > 0 else 0 # If wrapping = True, accessing one to the right of the rightmost column will wrap to the leftmost column, and so on # If wrapping = False, the grid is padded in all directions by infinitely many default_value cells self.wrapping = wrapping self.default_value = default_value def row(self, y) -> Sequence[T]: return self.data[y] def rows(self) -> Sequence[Sequence[T]]: return self.data def cols(self) -> Sequence[Sequence[T]]: # TODO: implement assert(False) def cell_at(self, x, y) -> T | None: if x >= 0 and y >= 0 and x < self.col_count and y < self.row_count: return self.data[y][x] elif self.wrapping: # TODO: implement -- using Python's default indexing behavior where possible assert(False) elif x < 0 or y < 0: return None else: # Not wrapping and x >= self.col_count or y >= self.row_count return None def contents_at(self, x, y) -> Any: cell = self.cell_at(x, y) return cell.contents if cell else self.default_value def neighbors(self, x, y) -> list[T | None]: """ Return a list of all neighboring cells, wrapping or inserting default valued cells if needed. """ cells = [] for offset_x in (-1, 0, 1): for offset_y in (-1, 0, 1): if not (offset_x == 0 and offset_y == 0): cells.append(self.cell_at(x + offset_x, y + offset_y)) assert(len(cells) == 8) return cells class CharacterGrid(GenericGrid): """ Each cell is one character, usually ASCII, created from a list of strings """ def __init__(self, lines: Sequence[str], wrapping = False, default_value = None): data: list[list[Cell]] = [] for line in lines: row = list(map(Cell, list(line))) data.append(row) super().__init__(data, wrapping, default_value) def print(self): for row in self.data: print(''.join(map(lambda c: c.contents, row))) ############ SLUT BRYT UT TILL EGEN FIL ############## from itertools import takewhile class GroupedCharacterGrid(CharacterGrid): def __init__(self, lines): super().__init__(lines, wrapping = False, default_value = '.') id = 1 self.groups = {} for y in range(self.row_count): # Ugly, ugly. I want a C-style for loop here (to easily skip multiple iterations with x += ...) x = -1 while (x := x + 1) < self.col_count: if not self.contents_at(x, y).isdigit(): continue # This is the first digit of a number; let's fetch the rest digit_cells = list(takewhile(lambda c: c.contents.isdigit(), self.row(y)[x:])) # Set the group ID for each digit for digit_cell in digit_cells: digit_cell.group_id = id # Store them as a group digits = list(map(lambda c: c.contents, digit_cells)) value = int("".join(digits)) self.groups[id] = value x += len(digits) id += 1 def all_groups(self): """ Returns a dictionary of all groups, with the id as the key """ return self.groups def cell_contains_symbol(cell): return cell and cell.contents != '.' and not cell.contents.isdigit() if __name__=='__main__': lines = open('data/day3.txt').read().splitlines() grid = GroupedCharacterGrid(lines) # Calculate which groups/numbers have an adjacent symbol groups_with_adjacent_symbol = set() for y in range(grid.row_count): for x in range(grid.col_count): if (c := grid.cell_at(x, y)) and c.contents.isdigit(): if any([cell_contains_symbol(cell) for cell in grid.neighbors(x, y)]): # Digit has an adjacent symbol groups_with_adjacent_symbol.add(c.group_id) # Add up all groups/numbers with an adjacent symbol sum = 0 for group_id, group_value in grid.all_groups().items(): if group_id in groups_with_adjacent_symbol: sum += group_value print(f"Part 1: {sum}") # Part 2: locate all *, skip if there aren't exactly two groups adjacent, multiply the two values sum = 0 all_groups = grid.all_groups() for y in range(grid.row_count): for x in range(grid.col_count): if (c := grid.cell_at(x, y)) and c.contents == '*': digits = filter(lambda c: c and c.contents.isdigit(), grid.neighbors(x, y)) group_ids = set(map(lambda c: c.group_id, digits)) # Skip if there aren't exactly two groups adjacent if len(group_ids) != 2: continue # Extract the two groups/numbers and multiply them a, b = group_ids ratio = all_groups[a] * all_groups[b] sum += ratio print(f"Part 2: {sum}")

Dold text

Herrrregud vad jag överkomplicerade denna. Delvis med mening dock, jag rÀknar med att det kommer vara flera uppgifter dÀr funktioner för 2D-arrayer/grids/matriser behövs, sÄ jag gjorde klasser för det som jag nu nÀr jag skickat in detta inlÀgg bryter ut till en fil som kan ÄteranvÀndas andra dagar.
Men Àven med det i Ätanke skulle jag tro att min lösning Àr den kanske enskilt klumpigaste hÀr.

Visa signatur

Asus ROG STRIX B550-F / Ryzen 5800X3D / 48 GB 3200 MHz CL14 / Asus TUF 3080 OC / WD SN850 1 TB, Kingston NV1 2 TB + NAS / Corsair RM650x V3 / Acer XB271HU (1440p165) / LG C1 55"
Mobil: Moto G200

PermalÀnk
Datavetare ★
●

Dag: 3
SprÄk: Python

Skapade en lista med (nummer, positioner-lista) samt en dict med {position: symbol}, löser del 1.
För del 2 skapades en till dict med {position: (id, nummer)} sÄ man kan gÄ igenom '*' i symbol-dict och kolla vilka nummer som ligger intill.

def parse_engine_schematic(input): numbersAndPos = [] posToIdAndNumber = {} posToSymbols = {} (num, isInNum, numPositions, numId) = (0, False, [], 0) for y, line in enumerate(input): for x, ch in enumerate(line.strip()+'.'): if ch != '.' and not ch.isdigit(): posToSymbols[(x, y)] = ch if ch.isdigit(): isInNum = True num = 10 * num + int(ch) numPositions.append((x, y)) elif isInNum: numbersAndPos.append((num, numPositions)) for pos in numPositions: posToIdAndNumber[pos] = (numId, num) (num, isInNum, numPositions, numId) = (0, False, [], numId+1) return (numbersAndPos, posToSymbols, posToIdAndNumber) def adjacent_positions(center): d = [-1, 0, 1] for pos in [(center[0]+dx, center[1]+dy) for dy in d for dx in d if dx != 0 or dy != 0]: yield pos def is_adjacent_to_symbol(posToSymbols, position): return any([adjPos in posToSymbols for adjPos in adjacent_positions(position)]) def sum_part_numbers(numbersAndPos, posToSymbols): return sum([ number for (number, positions) in numbersAndPos if any([is_adjacent_to_symbol(posToSymbols, p) for p in positions]) ]) def get_adjacent_numbers(posToIdAndNumber, position): numbers = [] seenIds = set() for adjPos in adjacent_positions(position): if adjPos in posToIdAndNumber: (id, number) = posToIdAndNumber[adjPos] if not id in seenIds: # Two distinct numbers with same value still got different ID's numbers.append(number) seenIds.add(id) return numbers def sum_gear_ratios(posToIdAndNumber, posToSymbols): sum = 0 for (position, symbol) in posToSymbols.items(): if symbol == '*': adjacentNumbers = get_adjacent_numbers(posToIdAndNumber, position) if len(adjacentNumbers) == 2: sum += adjacentNumbers[0] * adjacentNumbers[1] return sum def solve(input): (numbersAndPos, posToSymbols, posToIdAndNumber) = parse_engine_schematic(input) print(f'{sum_part_numbers(numbersAndPos, posToSymbols)}') print(f'{sum_gear_ratios(posToIdAndNumber, posToSymbols)}') if __name__ == '__main__': solve(open('input/day3.txt').readlines())

Dold text
Visa signatur

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

PermalÀnk
Medlem
●

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

from __future__ import annotations import dataclasses import enum import itertools import pathlib import typing class OutOfBoundsError(Exception): pass @dataclasses.dataclass class Cell: x: int y: int character: str @classmethod def create(cls, x: int, y: int, character: str) -> Cell: if character.isdigit(): return Digit(x, y, character, None) if character == "*": return Cogwheel(x, y, character) if character in ("+", "%", "=", "-", "#", "/", "&", "@", "$"): return Symbol(x, y, character) if character == ".": return Whitespace(x, y, character) else: return Cell(x, y, character) def __eq__(self, other: Cell): return (self.x, self.y, self.character) == (other.x, other.y, other.character) def __hash__(self): return hash(str(self.x) + str(self.y) + self.character) @dataclasses.dataclass class Digit(Cell): belongs_to: typing.Optional[Part] def __hash__(self): return super().__hash__() @dataclasses.dataclass class Cogwheel(Cell): pass @dataclasses.dataclass class Symbol(Cell): pass @dataclasses.dataclass class Whitespace(Cell): pass class Part(int): _cells: list[Digit] @property def cells(self) -> tuple[Digit, ...]: return tuple(self._cells) def __init__(self, cells: list[Digit]): self._cells = cells for cell in self._cells: cell.belongs_to = self def __new__(cls, cells: list[Digit]): value = str().join((cell.character for cell in cells)) value = int(value) if value else 0 return super().__new__(cls, value) def __hash__(self): return hash(tuple(self._cells)) class Direction(enum.Flag): NORTH = enum.auto() SOUTH = enum.auto() WEST = enum.auto() EAST = enum.auto() class Schematic: _cells: list[list[Cell | None]] _parts: list[Part] def __init__(self, columns: int, rows: int): self._cells = list() self._cells = [[None for _ in range(columns)] for _ in range(rows)] self._gears = list() self._parts = list() @property def columns(self) -> int: return len(self._cells[0]) @property def rows(self) -> int: return len(self._cells) @property def parts(self) -> list[Part]: return self._parts def set_cell(self, cell: Cell): if cell.x < 0 or cell.x > self.columns: raise OutOfBoundsError() if cell.y < 0 or cell.y > self.rows: raise OutOfBoundsError() self._cells[cell.x][cell.y] = cell def get_cell( self, x: int, y: int, direction: typing.Optional[Direction] = None ) -> Cell: if direction: if Direction.NORTH in direction: y -= 1 elif Direction.SOUTH in direction: y += 1 if Direction.WEST in direction: x -= 1 elif Direction.EAST in direction: x += 1 if x < 0 or x >= self.columns: raise OutOfBoundsError() if y < 0 or y >= self.rows: raise OutOfBoundsError() return self._cells[x][y] def get_neighbours(self, x: int, y: int): neighbours = list() for direction in [ Direction.NORTH, Direction.NORTH | Direction.WEST, Direction.NORTH | Direction.EAST, Direction.SOUTH, Direction.SOUTH | Direction.WEST, Direction.SOUTH | Direction.EAST, Direction.WEST, Direction.EAST ]: try: cell = self.get_cell(x, y, direction) neighbours.append(cell) except OutOfBoundsError: continue return neighbours @classmethod def create(cls, array: list[list[str]]): schematic = cls(len(array[0]), len(array)) digits = list() for x, y in itertools.product( range(schematic.columns), range(schematic.rows) ): cell = Cell.create(x, y, array[x][y]) schematic.set_cell(cell) if isinstance(cell, Digit): digits.append(cell) else: if digits: schematic.parts.append(Part(digits)) digits = list() parts = list() for part in schematic.parts: for cell in part.cells: cells = schematic.get_neighbours(cell.x, cell.y) cells = [cell for cell in cells if isinstance(cell, (Cogwheel, Symbol))] if cells: parts.append(part) break schematic.parts.clear() schematic.parts.extend(parts) return schematic def solve(path: pathlib.Path) -> int: array = list() with open(path) as file: for line in file: row = [character for character in line.strip()] array.append(row) schematic = Schematic.create(array) return sum(schematic.parts) if __name__ == "__main__": print(f"Result: {solve(...)}")

Dold text

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

from __future__ import annotations import dataclasses import enum import itertools import pathlib import typing class OutOfBoundsError(Exception): pass @dataclasses.dataclass class Cell: x: int y: int character: str @classmethod def create(cls, x: int, y: int, character: str) -> Cell: if character.isdigit(): return Digit(x, y, character, None) if character == "*": return Cogwheel(x, y, character) if character in ("+", "%", "=", "-", "#", "/", "&", "@", "$"): return Symbol(x, y, character) if character == ".": return Whitespace(x, y, character) else: return Cell(x, y, character) def __eq__(self, other: Cell): return (self.x, self.y, self.character) == (other.x, other.y, other.character) def __hash__(self): return hash(str(self.x) + str(self.y) + self.character) @dataclasses.dataclass class Digit(Cell): belongs_to: typing.Optional[Part] def __hash__(self): return super().__hash__() @dataclasses.dataclass class Cogwheel(Cell): pass @dataclasses.dataclass class Symbol(Cell): pass @dataclasses.dataclass class Whitespace(Cell): pass class Part(int): _cells: list[Digit] @property def cells(self) -> tuple[Digit, ...]: return tuple(self._cells) def __init__(self, cells: list[Digit]): self._cells = cells for cell in self._cells: cell.belongs_to = self def __new__(cls, cells: list[Digit]): value = str().join((cell.character for cell in cells)) value = int(value) if value else 0 return super().__new__(cls, value) def __hash__(self): return hash(tuple(self._cells)) class Gear(int): cell: Cogwheel n1: Part n2: Part def __new__(cls, cell: Cogwheel, p1: Part, p2: Part): return super().__new__(cls, p1 * p2) class Direction(enum.Flag): NORTH = enum.auto() SOUTH = enum.auto() WEST = enum.auto() EAST = enum.auto() class Schematic: _cells: list[list[Cell | None]] _gears: list[Gear] _parts: list[Part] def __init__(self, columns: int, rows: int): self._cells = list() self._cells = [[None for _ in range(columns)] for _ in range(rows)] self._gears = list() self._parts = list() @property def columns(self) -> int: return len(self._cells[0]) @property def rows(self) -> int: return len(self._cells) @property def gears(self) -> list[Gear]: return self._gears @property def parts(self) -> list[Part]: return self._parts def set_cell(self, cell: Cell): if cell.x < 0 or cell.x > self.columns: raise OutOfBoundsError() if cell.y < 0 or cell.y > self.rows: raise OutOfBoundsError() self._cells[cell.x][cell.y] = cell def get_cell( self, x: int, y: int, direction: typing.Optional[Direction] = None ) -> Cell: if direction: if Direction.NORTH in direction: y -= 1 elif Direction.SOUTH in direction: y += 1 if Direction.WEST in direction: x -= 1 elif Direction.EAST in direction: x += 1 if x < 0 or x >= self.columns: raise OutOfBoundsError() if y < 0 or y >= self.rows: raise OutOfBoundsError() return self._cells[x][y] def get_neighbours(self, x: int, y: int): neighbours = list() for direction in [ Direction.NORTH, Direction.NORTH | Direction.WEST, Direction.NORTH | Direction.EAST, Direction.SOUTH, Direction.SOUTH | Direction.WEST, Direction.SOUTH | Direction.EAST, Direction.WEST, Direction.EAST ]: try: cell = self.get_cell(x, y, direction) neighbours.append(cell) except OutOfBoundsError: continue return neighbours @classmethod def create(cls, array: list[list[str]]): schematic = cls(len(array[0]), len(array)) digits = list() for x, y in itertools.product( range(schematic.columns), range(schematic.rows) ): cell = Cell.create(x, y, array[x][y]) schematic.set_cell(cell) if isinstance(cell, Digit): digits.append(cell) else: if digits: schematic.parts.append(Part(digits)) digits = list() parts = list() for part in schematic.parts: for cell in part.cells: cells = schematic.get_neighbours(cell.x, cell.y) cells = [cell for cell in cells if isinstance(cell, (Cogwheel, Symbol))] if cells: parts.append(part) break schematic.parts.clear() schematic.parts.extend(parts) gears = list() for x, y in itertools.product( range(schematic.columns), range(schematic.rows) ): cell = schematic.get_cell(x, y) if isinstance(cell, Cogwheel): cells = schematic.get_neighbours(cell.x, cell.y) cells = [cell for cell in cells if isinstance(cell, Digit)] parts = set(cell.belongs_to for cell in cells) if len(parts) == 2: gears.append(Gear(cell, *parts)) schematic.gears.clear() schematic.gears.extend(gears) return schematic def solve(path: pathlib.Path) -> int: array = list() with open(path) as file: for line in file: row = [character for character in line.strip()] array.append(row) schematic = Schematic.create(array) return sum(schematic.gears) if __name__ == "__main__": print(f"Result: {solve(...)}")

Dold text
PermalÀnk
Medlem ★
●

Dag: 3
SprÄk: Matlab

Tog mig orimligt lÄng tid idag. Hade blivit bÀttre om man hade vetat frÄgan till del 2 innan man gjorde del 1. NÄja, det funkar i alla fall.

fid=fopen('day3.txt'); lnum = 1; while ~feof(fid) line = fgetl(fid); lineStr(lnum).symx = regexp(line, "[^.1234567890]"); lineStr(lnum).gearx = regexp(line, '*'); lineStr(lnum).gear = []; lineStr(lnum).num = extract(line, digitsPattern()); %Get digits digits = strfind(line, digitsPattern()); %Find index of digits if ~isempty(digits) lineStr(lnum).numx = digits([true, diff(digits)~=1]); %Cull consec. end lnum=lnum+1; end Score1=[]; for k = 1:length(lineStr) for l = 1:length(lineStr(k).num) Scorediff=Score1; nx = lineStr(k).numx(l); n = double(string(lineStr(k).num(l))); a = max(lineStr(max(k-1, 1)).symx - 1, 1); b = min(lineStr(max(k-1, 1)).symx + 1, length(line)); c = max(lineStr(k).symx - 1, 1); d = min(lineStr(k).symx + 1, length(line)); e = max(lineStr(min(k+1, length(lineStr))).symx - 1, 1); f = min(lineStr(min(k+1, length(lineStr))).symx + 1, length(line)); if sum((nx+length(char(lineStr(k).num(l)))>a) & nx<=b) Score1 = [Score1 n]; elseif sum((nx+length(char(lineStr(k).num(l)))>c) & nx<=d) Score1 = [Score1 n]; elseif k<length(lineStr) && ... sum((nx+length(char(lineStr(k).num(l)))>e) & nx<=f) Score1 = [Score1 n]; end end end Score2=0; for k = 1:length(lineStr) for l=1:length(lineStr(k).gearx) gearMultipliers = []; for m = 1:length(lineStr(k).numx) if (lineStr(k).gearx(l) >= (lineStr(k).numx(m) - 1)) && ... (lineStr(k).gearx(l) <= (lineStr(k).numx(m) + ... length(char(lineStr(k).num(m))))) gearMultipliers = [gearMultipliers lineStr(k).num(m)]; end end if k>1 for m = 1:length(lineStr(k-1).numx) if (lineStr(k).gearx(l) >= (lineStr(k-1).numx(m) - 1)) &&... (lineStr(k).gearx(l) <= (lineStr(k-1).numx(m) + ... length(char(lineStr(k-1).num(m))))) gearMultipliers = [gearMultipliers lineStr(k-1).num(m)]; end end end if k<length(lineStr) for m = 1:length(lineStr(k+1).numx) if (lineStr(k).gearx(l) >= (lineStr(k+1).numx(m) - 1)) &&... (lineStr(k).gearx(l) <= (lineStr(k+1).numx(m) + ... length(char(lineStr(k+1).num(m))))) gearMultipliers = [gearMultipliers lineStr(k+1).num(m)]; end end end if numel(gearMultipliers)==2 Score2=Score2 + prod(double(string(gearMultipliers)), "all"); end end end disp(['Task 1: ', num2str(sum(Score1))]) disp(['Task 2: ', num2str(Score2)]) fclose(fid);

Dold text
PermalÀnk
TangentbordskonnĂ€ssör ★
●

Inte fÄtt tid att börja fören idag, sÄ ligger lite efter. FÄ se om man hinner ikapp.
TÀnkte testa pÄ lite kluringar i Erlang som kanske inte Àr bÀst för just sÄnna hÀr uppgifter.

Dag 1
SprÄk Erlang

GitHub

-module(day1). -export([part1/1, part2/1, find_numbers_from_text1/1, read_file/1]). part1(InputFile) -> List = case InputFile of example -> read_file("example2.txt"); _ -> read_file(InputFile) end, Numbers = lists:foldl( fun(X, NrAccu) -> Numbers0 = lists:filtermap( fun(Char) -> lists:member(Char, "0123456789") end, X), case length(Numbers0) of 0 -> NrAccu; _ -> Numbers1 = list_to_binary(Numbers0), case string:length(Numbers1) of 1 -> [binary_to_integer(<<Numbers1/binary, Numbers1/binary>>) | NrAccu]; 2 -> [binary_to_integer(Numbers1) | NrAccu]; _ -> First = binary:part(Numbers1, {0,1}), Last = binary:part(Numbers1, {byte_size(Numbers1),-1}), [binary_to_integer(<<First/binary, Last/binary>>) | NrAccu] end end end, [], List), lists:sum(Numbers). part2(InputFile) -> List = case InputFile of example -> read_file("example2.txt"); _ -> read_file(InputFile) end, Numbers = lists:foldl( fun(X, NrAccu) -> Numbers0 = find_numbers_from_text1(X), case length(Numbers0) of 0 -> NrAccu; _ -> Numbers1 = list_to_binary(Numbers0), case string:length(Numbers1) of 1 -> [binary_to_integer(<<Numbers1/binary, Numbers1/binary>>) | NrAccu]; 2 -> [binary_to_integer(Numbers1) | NrAccu]; _ -> First = binary:part(Numbers1, {0,1}), Last = binary:part(Numbers1, {byte_size(Numbers1),-1}), [binary_to_integer(<<First/binary, Last/binary>>) | NrAccu] end end end, [], List), lists:sum(Numbers). read_file(Filename) -> {ok, FileContent} = file:read_file(Filename), Lines = binary:split(FileContent, <<"\n">>, [global]), Strings = [binary_to_list(Line) || Line <- Lines], Strings. find_numbers_from_text1(Input) -> List = ["one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "1", "2", "3", "4", "5", "6", "7", "8", "9"], List1 = lists:map( fun(Word) -> Word1 = string:to_lower(Word), Input1 = string:to_lower(Input), {Word1, string:str(Input1, Word1), string:rstr(Input1, Word1)} end, List), NumberList = lists:filter( fun(X) -> case X of {_, 0, _} -> false; _ -> true end end, List1), Sorted = lists:keysort(2, NumberList), {{First, _},{Last, _}} = lists:foldl( fun(X, {{LowestValue, LowestPos}, {HighestValue, HighestPos}}) -> case X of {_, 0, _} -> {{LowestValue, LowestPos}, {HighestValue, HighestPos}}; {Value, First, Last} -> {CurrentLowestValue, CurrentLowestPos} = if LowestPos == 0 -> {only_digits(Value), First}; LowestPos > First -> {only_digits(Value), First}; true -> {LowestValue, LowestPos} end, {CurrentHighestValue, CurrentHighestPos} = if HighestPos < Last -> {only_digits(Value), Last}; true -> {HighestValue, HighestPos} end, {{CurrentLowestValue, CurrentLowestPos}, {CurrentHighestValue, CurrentHighestPos}} end end, {{"", 0},{"", 0}}, Sorted), First ++ Last. only_digits(Input) -> OnlyNumbers1 = re:replace(Input, "one", "1", [global, {return, list}]), OnlyNumbers2 = re:replace(OnlyNumbers1, "two", "2", [global, {return, list}]), OnlyNumbers3 = re:replace(OnlyNumbers2, "three", "3", [global, {return, list}]), OnlyNumbers4 = re:replace(OnlyNumbers3, "four", "4", [global, {return, list}]), OnlyNumbers5 = re:replace(OnlyNumbers4, "five", "5", [global, {return, list}]), OnlyNumbers6 = re:replace(OnlyNumbers5, "six", "6", [global, {return, list}]), OnlyNumbers7 = re:replace(OnlyNumbers6, "seven", "7", [global, {return, list}]), OnlyNumbers8 = re:replace(OnlyNumbers7, "eight", "8", [global, {return, list}]), OnlyNumbers9 = re:replace(OnlyNumbers8, "nine", "9", [global, {return, list}]), OnlyNumbers9.

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

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

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

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

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

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

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

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

till

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

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

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

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

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

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

och uppgift tvÄ genom att:

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

Dold text

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

Det tog ett eller tvÄ försök innan jag kom pÄ hur jag ville lösa del 2, men inga fel-inskick och en kul uppgift.

Visa signatur

:(){ :|:& };:

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

PermalÀnk
Medlem ★
●

Dag: 4
SprÄk: Python

Blev ganska elegant i dag.

def collect_cards(winning_numbers): counts = [1] * len(winning_numbers) for i, win in enumerate(winning_numbers): for j in range(i + 1, i + 1 + win): counts[j] += counts[i] return sum(counts) winning_numbers = [len(set.intersection(*list(map(lambda ns: set(int(n) for n in ns.split(" ") if n), line.split(":")[1].split("|"))))) for line in open("input04.txt").readlines()] print(sum(map(lambda count: (1 << count) // 2, winning_numbers)), collect_cards(winning_numbers))

Dold text
PermalÀnk
●

Dag 4
SprÄk: C

Ganska rakt pÄ sak idag.

Men vad mycket av koden som bara Àr inlÀsning. Kanske jag kan göra det snyggare i eftermiddag.

#include <stdio.h> #include <stdlib.h> #include <string.h> #define LINELEN 200 #define NUMWINNERS 10 #define MAXCARDS 300 int numwins(char* line); int main() { int part1 = 0; int part2 = 0; int* numcards = calloc(MAXCARDS, sizeof(int)); int card = 0; char line[LINELEN]; FILE* fptr = fopen("input", "r"); while (fgets(line, sizeof line, fptr) != NULL && ++card) { int score = numwins(line); // Part 1. part1 += score == 0 ? 0 : 1 << score-1; // Part 2. // Add original card to count and update part2 total. part2 += ++numcards[card]; // Give bonus cards based on score and number of cards. for (int i=1; i<=score; ++i) numcards[card + i] += numcards[card]; } printf("Part 1: %i\nPart 2: %i\n", part1, part2); } // Return the number of winning numbers on a card. int numwins(char* line) { int* winningnumbers = calloc(NUMWINNERS, sizeof(int)); int numpos = 0; int linepos = strpbrk(line, ":") - line + 1; // Position of ':' + 1. // Read winning numbers. while (line[linepos] != '|' && numpos < NUMWINNERS) { if (line[linepos] >= '0' && line[linepos] <= '9') winningnumbers[numpos] = 10 * winningnumbers[numpos] + line[linepos] - '0'; else if (line[linepos] == ' ' && winningnumbers[numpos] > 0) ++numpos; ++linepos; } // Check card numbers against winning numbers. int score = 0; int number = 0; while (1) { if (line[linepos] >= '0' && line[linepos] <= '9') number = 10 * number + line[linepos] - '0'; else if (line[linepos] == ' ' || line[linepos] == '\n') { if (number != 0) { // See if number is a winning number. for (int i=0; i<NUMWINNERS; ++i) if (number == winningnumbers[i]) ++score; } number = 0; } if (line[linepos++] == '\n') break; } free(winningnumbers); return score; }

Dold text
PermalÀnk
●

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

Den hÀr kÀndes vÀldigt trevlig, lite lagom klurig.

Det jag fastnade pÄ var att jag anvÀnde en dictionary för att spara mina resultat. Och dÄ nÀr jag loopade över nycklarna fick jag dom sÄklart inte i rÀtt ordning...

Dold text
PermalÀnk
Medlem ★
●

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

Som andra, trevlig dag idag. Första gÄngen som white-space behövde hanteras lite bÀttre vilket var bra för mitt mÄl att lÀra mig nom. Börjar helt klart flyta mycket smidigare nu.

PermalÀnk
Medlem
●

Dag: 4
SprÄk: TypeScript

Uppgift 1:

import fs from 'fs' interface Card { id: number winningNumbers: string[] playersNumbers: string[] points?: number } export default function calculateTotalPointsInTickets (): void { const lines = fs.readFileSync('./src/04/input/04.txt', 'utf-8').trim().split('\n') const allCards: Card[] = [] lines.forEach((line) => { const card = line.match(/Card\s+(\d+): (.+)/) let cardID let numbers if (card !== null) { cardID = parseInt(card[1], 10) numbers = card[2].split('|').map((item) => item.trim()) } const currentCard: Card = { id: cardID, winningNumbers: numbers[0].split(' ').filter(Boolean), playersNumbers: numbers[1].split(' ').filter(Boolean) } currentCard.points = getTotalPointsForCard(currentCard) allCards.push(currentCard) }) console.log('Total score of cards: ', calcTotalScore(allCards)) } function getTotalPointsForCard (card: Card): number { let totalPoints = 0 card.playersNumbers.forEach((number) => { if (card.winningNumbers.includes(number)) { totalPoints = totalPoints === 0 ? 1 : totalPoints * 2 } }) return totalPoints } function calcTotalScore (cards: Card[]): number { let total = 0 cards.forEach((card) => { total += card.points ?? 0 }) return total }

Dold text

Uppgift 2:

import fs from 'fs' interface Card { id: number winningNumbers: string[] playersNumbers: string[] matchingNumbers: number } interface PlayerCard { card: Card amount: number } export default function calculateTotalAmountOfScratchcards (): void { const lines = fs.readFileSync('./src/04/input/04.txt', 'utf-8').trim().split('\n') const allCards: Card[] = [] const playersCards: PlayerCard[] = [] // Build card array lines.forEach((line) => { const card = line.match(/Card\s+(\d+): (.+)/) let cardID let numbers if (card !== null) { cardID = parseInt(card[1], 10) numbers = card[2].split('|').map((item) => item.trim()) } const currentCard: Card = { id: cardID, winningNumbers: numbers[0].split(' ').filter(Boolean), playersNumbers: numbers[1].split(' ').filter(Boolean), matchingNumbers: 0 } currentCard.matchingNumbers = getTotalMatchingNumbersForCard(currentCard) allCards.push(currentCard) // Player should start with 1 copy of each card playersCards.push({ card: currentCard, amount: 1 }) }) playersCards.forEach((currentCard, cardIndex) => { if (currentCard.card.matchingNumbers > 0) { // Add amount to each looped through card for (let i = 1; i <= currentCard.card.matchingNumbers; i++) { playersCards[cardIndex + i].amount += currentCard.amount } } }) console.log('Total amount of cards: ', calcTotalScore(playersCards)) } function getTotalMatchingNumbersForCard (card: Card): number { let totalMatches = 0 card.playersNumbers.forEach((number) => { if (card.winningNumbers.includes(number) && number !== '') { totalMatches++ } }) return totalMatches } function calcTotalScore (cards: PlayerCard[]): number { let total = 0 cards.forEach((card) => { total += card.amount ?? 0 }) return total }

Dold text
Visa signatur

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

PermalÀnk
Medlem ★
●

Dag: 4
SprÄk: F#

Gick pÄ det stora hela bra, förutom att jag strulade till det syntaxmÀssigt pÄ del tvÄ ( int*Set<int>*Set<int> Àr naturligtvis inte samma sak som int*(Set<int>*Set<int>) ).

open System let parseRow (input: string) = let parts = input.Split(':', '|') let numbersToSet (c: string) = c.Split(" ", (StringSplitOptions.TrimEntries ||| StringSplitOptions.RemoveEmptyEntries)) |> Seq.map Int32.Parse |> Set.ofSeq let winningNumbers = parts[1] |> numbersToSet let drawnNumbers = parts[2] |> numbersToSet (winningNumbers, drawnNumbers) let winning (winningNumbers, drawnNumbers) = winningNumbers |> Set.intersect drawnNumbers |> Set.count let calculatePoints = winning >> fun c -> pown 2 (c - 1) let task1 = List.sumBy calculatePoints let task2 input = let cardCopies = List.replicate (List.length input) 1 |> List.indexed |> Map.ofList let games = List.indexed input let updateTable curState game = let gameId, (winningNumbers, draws) = game let numWins = winning (winningNumbers, draws) let copiesToAdd = Map.find gameId curState let AddCopiesToTable table gameId = Map.change gameId (fun x -> Some(x.Value + copiesToAdd)) table [ (gameId + 1) .. (gameId + numWins) ] |> List.fold AddCopiesToTable curState let result = List.fold updateTable cardCopies games result |> Map.values |> Seq.sum let input = System.IO.File.ReadAllLines "input.txt" |> Seq.toList |> List.map parseRow printfn $"Task 1: %A{input |> task1}" printfn $"Task 1: %A{input |> task2}"

Dold text
Visa signatur

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

PermalÀnk
Hedersmedlem ★
●

Dag: 4
SprÄk: Python

import re NUMBER_REGEX = re.compile(r'\d+') if __name__=='__main__': lines = open('data/day4.txt').read().splitlines() card_match_count = {} # Map of card ID -> # of matching numbers on that card card_instances = {} # Map of card ID -> # of copies we have of that card # Parse cards and calculate score for part 1 score = 0 for line in lines: card, winning, my = re.split('[:|]', line) card_number = int(NUMBER_REGEX.search(card).group(0)) winning_numbers = NUMBER_REGEX.findall(winning) my_numbers = NUMBER_REGEX.findall(my) num_matches = len(set(my_numbers) & set(winning_numbers)) card_match_count[card_number] = num_matches card_instances[card_number] = 1 card_score = 2**(num_matches - 1) if num_matches > 0 else 0 score += card_score print(f"Part 1: {score}") # Calculate card instances for part 2 for card, num_matches in card_match_count.items(): for instance in range(card_instances[card]): # num_matches matches gives one copy of each card in the range card + 1 to card + num_matches (inclusive) for c in range(card + 1, card + num_matches + 1): card_instances[c] += 1 print(f"Part 2: {sum(card_instances.values())}")

Dold text

Ganska kort lösning, speciellt relativt gÄrdagens. HÄller med om att det kÀndes lagom idag.

Visa signatur

Asus ROG STRIX B550-F / Ryzen 5800X3D / 48 GB 3200 MHz CL14 / Asus TUF 3080 OC / WD SN850 1 TB, Kingston NV1 2 TB + NAS / Corsair RM650x V3 / Acer XB271HU (1440p165) / LG C1 55"
Mobil: Moto G200

PermalÀnk
Medlem ★
●

Dag: 1
SprÄk: F#

Riktigt hemsk för en amatör som mig. LÀmnar kvar lite kladd i koden men det fÄr ni leva med!

let input = File.ReadAllLines @.\input.txt |> Array.toList // Part 1 let filterNumbers input = input |> Seq.filter Char.IsDigit |> Seq.toArray let getResult (inputList: string list) : int list = inputList |> List.map (fun x -> let numbersOnly = filterNumbers x // printfn "%A%s" numbersOnly x if numbersOnly.Length > 1 then (numbersOnly.[0] |> Char.ToString) + (numbersOnly |> Array.last |> Char.ToString) else (numbersOnly.[0] |> Char.ToString) + (numbersOnly.[0] |> Char.ToString)) |> List.map (fun z -> printfn "%s" z int z) // |> List.sum // getResult input // Part 2 let wordNumberMap = Map.ofList [ "one", "o1e" "two", "t2o" "three", "t3e" "four", "f4r" "five", "f5e" "six", "s6x" "seven", "s7n" "eight", "e8t" "nine", "n9e" ] let wordsToNumbers (str: string) : string = wordNumberMap |> Map.fold (fun acc key value -> acc.Replace(key, value)) str let partTwoResult = List.map wordsToNumbers input |> getResult |> List.sum

Dold text
Visa signatur

Grubblare

PermalÀnk
Medlem ★
●

Dag: 4
SprÄk: Matlab

SnÀllare uppgift idag. Tog ungefÀr en lunchrast

fid = fopen('day4.txt'); Score1 = 0; lnum = 0; Score2 = 1; while ~feof(fid) line = fgetl(fid); line = extractAfter(line, ': '); lnum = lnum + 1; win = double(string(split(extractBefore(line, " | "), " ")))'; draw = double(string(split(extractAfter(line, " | "), " ")))'; Score1 = [Score1 floor(2^(numel(intersect(draw, win)) - 1))]; if length(Score2)<lnum + max(1, numel(intersect(draw, win))) Score2(end+1:lnum + max(1, numel(intersect(draw, win)))) = 1; end Score2(lnum+1:lnum + numel(intersect(draw, win))) = ... Score2(lnum+1:lnum + numel(intersect(draw, win))) + ... Score2(lnum); if feof(fid) Score2(lnum + 1:end) = []; end end fclose(fid); disp(['Task 1: ', num2str(sum(Score1))]) disp(['Task 2: ', num2str(sum(Score2))])

Dold text
PermalÀnk
Medlem ★
●

Dag: 4
SprÄk: C#

public static void Run() { var scratchies = FileReader.ReadLines("Day4.txt") .Select(x => { var idAndGameDetails = x.Split(":", StringSplitOptions.RemoveEmptyEntries); var id = int.Parse(idAndGameDetails[0].Split(" ", StringSplitOptions.RemoveEmptyEntries)[1]); var numbers = idAndGameDetails[1].Split("|", StringSplitOptions.TrimEntries); var winningNumbers = numbers[0].Split(" ", StringSplitOptions.RemoveEmptyEntries).Select(x => int.Parse(x)).ToList(); var scratchyNumbers = numbers[1].Split(" ", StringSplitOptions.RemoveEmptyEntries).Select(x => int.Parse(x)).ToList(); return new Scratchy(id, winningNumbers, scratchyNumbers); }).ToList(); var part1Res = scratchies.Select(x => { var numOfIntersection = x.WinningNumbers.Intersect(x.ScratchysNumbers).Count(); return numOfIntersection > 1 ? Math.Floor(Math.Pow(2, numOfIntersection-1)) : numOfIntersection; }).Sum(); Console.WriteLine(part1Res); for (int i = 0; i < scratchies.Count; i++) { var scratchy = scratchies[i]; for (int j = 0; j < scratchy.Instances; j++) { var numOfIntersection = scratchy.WinningNumbers.Intersect(scratchy.ScratchysNumbers).Count(); var lastIndex = numOfIntersection <= scratchies.Count - 1 ? numOfIntersection + i + 1 : scratchies.Count - 1; for (int k = i + 1; k < lastIndex; k++) { var scratchyCopy = scratchies[k] with { Instances = scratchies[k].Instances + 1 }; scratchies[k] = scratchyCopy; } } } Console.WriteLine(scratchies.Sum(x => x.Instances)); } internal record Scratchy(int Id, IReadOnlyList<int> WinningNumbers, IReadOnlyList<int> ScratchysNumbers, int Instances = 1);

Dold text
PermalÀnk
Medlem
●

Dag: 3 - En dag sent, fastnade totalt pÄ denna dagen haha, men bÀttre sent Àn aldrig
SprÄk: TypeScript

Uppgift 1 - Inte nöjd alls med denna, men den gav rÀtt svar LÀr göra om nÀr tid finns

import fs from 'fs' export default function getSumOfEngineParts (): void { const lines = fs.readFileSync('./src/03/input/03.txt', 'utf-8').trim().split(/\r\n/) const partsToSum: number[] = [0] lines.forEach((line, currentLineIndex) => { // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-expect-error const elementsPerLine: string[] = line.split('.').flatMap((part) => { if (part === '\r' || part === '') { return [] } else { // Separate numbers and symbols const matches = part.match(/(\d+|\D+)/g) return matches } }) elementsPerLine.forEach((el, index) => { let currentOcc = 1 for (let i = 0; i < index; i++) { let editableLine = elementsPerLine[i] do { if (editableLine.includes(el)) { currentOcc++ editableLine = editableLine.replace(el, '') } } while (editableLine.includes(el)) } const elementStartIndex: number = findNthOccurrence(line, el, currentOcc) const elementEndIndex: number = elementStartIndex + el.length - 1 if (isNaN(parseInt(el, 10))) return for (let i = currentLineIndex - 1; i <= currentLineIndex + 1; i++) { if (i < 0 || i >= lines.length) continue let hasAdjacent = false const currentLine: string = lines[i] for (let j = elementStartIndex - 1; j <= elementEndIndex + 1; j++) { if (j < 0 || j >= currentLine.length) continue if (isCharSymbol(currentLine[j])) { partsToSum.push(parseInt(el)) hasAdjacent = true break } } if (hasAdjacent) break } }) }) console.log('Sum of engine parts: ', partsToSum.reduce((sum, nextVal) => sum + nextVal)) } function isCharSymbol (char: string): boolean { const result = char !== '.' && char !== '\r' && !/\s/.test(char) && !/\d/.test(char) return result } function findNthOccurrence (mainString: string, substring: string, n: number): number { let currentIndex = -1 for (let i = 0; i < n; i++) { currentIndex = mainString.indexOf(substring, currentIndex + 1) if (currentIndex === -1) { // If substring is not found or there are fewer occurrences than n return -1 } } return currentIndex }

Dold text

Uppgift 2 - Tog tid, men nöjd med resultatet

import fs from 'fs' const GEAR_SYMBOL: string = '*' const FILE_PATH = './src/03/input/03.txt' interface Gear { x: number y: number adjacentNumbers: GridNumber[] } interface GridNumber { value: number row: number startIndex: number endIndex: number } export default function calculateGearRatios (): void { const lines = fs.readFileSync(FILE_PATH, 'utf-8').trim().split('\n') const gridNumbers: GridNumber[] = buildGridNumbersArray(lines) const grid: string[][] = buildCharGrid(lines) const gears: Gear[] = buildGearArray(grid, gridNumbers) console.log('Total gear ratio: ', calculateTotalGearRatio(gears.filter((gear) => gear.adjacentNumbers.length === 2))) } function calculateTotalGearRatio (gears: Gear[]): number { let total: number = 0 gears.forEach((gear) => { if (gear.adjacentNumbers.length === 0) return let gearRatio = 1 gear.adjacentNumbers.forEach((num) => { gearRatio *= num.value }) total += gearRatio }) return total } function buildCharGrid (lines: string[]): string[][] { const charGrid: string[][] = [] // Initialize charGrid with empty arrays for each line lines.forEach(() => { charGrid.push([]) }) lines.forEach((line, lineIndex) => { line.split('').forEach((char, charIndex) => { if (char !== '\r') { charGrid[lineIndex][charIndex] = char } }) }) return charGrid } function buildGridNumbersArray (lines: string[]): GridNumber[] { const grid: GridNumber[] = [] lines.forEach((row, rowIndex) => { const matches = row.match(/\d+/g) let previousEndIndex = 0 if (matches !== null) { matches.forEach((match) => { const startIndex = row.indexOf(match, previousEndIndex) const endIndex = startIndex + match.length - 1 previousEndIndex = endIndex const gridNumber: GridNumber = { value: parseInt(match), row: rowIndex, startIndex, endIndex } grid.push(gridNumber) }) } }) return grid } function buildGearArray (grid: string[][], gridNumbersArr: GridNumber[]): Gear[] { const gears: Gear[] = [] grid.forEach((row, rowIx) => { row.forEach((col, colIx) => { if (col === GEAR_SYMBOL) { const gear: Gear = { x: colIx, y: rowIx, adjacentNumbers: getAdjacentGridNumbers(colIx, rowIx, gridNumbersArr) } gears.push(gear) } }) }) return gears } function getAdjacentGridNumbers (x: number, y: number, gridNumbersArr: GridNumber[]): GridNumber[] { const adjacentGridNumbers: GridNumber[] = [] const adjacentRowsGridNumbers: GridNumber[] = gridNumbersArr.filter((num) => num.row >= y - 1 && num.row <= y + 1) adjacentRowsGridNumbers.forEach((num) => { if (num.startIndex <= x + 1 && num.endIndex >= x - 1) { adjacentGridNumbers.push(num) } }) return adjacentGridNumbers }

Dold text
Visa signatur

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

PermalÀnk
Medlem ★
●

Dag: 4
SprÄk: C#

Som vanligt sÄ Àr 99% av uppgiften att förstÄ vad som efterfrÄgas. Sen oftast inte sÄ farligt att implementera. Denna gÄngern Àr jag vÀl ganska nöjd tycker jag. GÄr sÀkert att göra mycket renare som man kommer se hÀr frÄn andra

public override object PartOne(string data) { return data.Split("\r\n") .Select(line => line[(line.IndexOf(':') + 2)..] .Split('|') .Select(card => card.Split(' ', StringSplitOptions.RemoveEmptyEntries)).ToList()) .Select(cards => cards[0].Select(int.Parse).Intersect(cards[1].Select(int.Parse)).Count()) .Where(wins => wins > 0) .Select(l => Math.Pow(2, l - 1)) .Sum(); } public override object PartTwo(string data) { int sum = 0; var wins = data.Split("\r\n") .Select(line => line[(line.IndexOf(':') + 2)..] .Split('|') .Select(card => card.Split(' ', StringSplitOptions.RemoveEmptyEntries)).ToList()) .Select((cards, index) => new { Index = index, Wins = cards[0].Select(int.Parse).Intersect(cards[1].Select(int.Parse)) }) .ToDictionary(x => x.Index + 1, y => y.Wins.Count()); Queue<int> cards = new Queue<int>(wins.Keys); while (cards.Count > 0) { var current = cards.Dequeue(); sum += 1; if (wins[current] == 0) continue; for (int i = 1; i <= wins[current]; i++) { cards.Enqueue(current + i); } } return sum; }

Dold text
stÀdade lite
PermalÀnk
Medlem
●

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

from __future__ import annotations import pathlib def solve(path: pathlib.Path) -> int: points: list[int] = list() with open(path) as file: for line in file: _, rest = line.split(":") left, right = rest.split("|") left = set([int(x) for x in left.split()]) right = set([int(x) for x in right.split()]) intersection = right.intersection(left) if len(intersection) > 0: points.append(2 ** (len(intersection) - 1)) return sum(points) if __name__ == "__main__": print(f"Result: {solve(...)}")

Dold text

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

from __future__ import annotations import dataclasses import enum import functools import itertools import pathlib import typing @dataclasses.dataclass class Card: id: int left: set[int] right: set[int] def scratch(card: Card, cards: list) -> list[int]: intersection = card.right.intersection(card.left) start, end = card.id + 1, card.id + 1 + len(intersection) return functools.reduce( lambda x, y: x + y, [ scratch(card, cards) for card in cards[start:end] ] + [[card.id]]) def solve(path: pathlib.Path) -> int: cards: list[Card] = list() with open(path) as file: for line in file: identity, rest = line.split(":") _, identity = identity.split() index = int(identity) - 1 left, right = rest.split("|") left = {int(x) for x in left.split()} right = {int(x) for x in right.split()} cards.append(Card(index, left, right)) return sum([len(scratch(card, cards)) for card in cards]) if __name__ == "__main__": print(f"Result: {solve(...)}")

Dold text
PermalÀnk
Medlem ★
●

Nu behöver jag, Àven om det tar emot, lite hjÀlp med första delen av dag 3. Min kod klarar all test-input jag kan hitta pÄ t.ex. reddit, men jag fÄr ett för högt svar pÄ min input. NÄgon som skrivit ihop nÄgot riktigt elakt test ni kan dela? Eller som lite hastigt och enkelt kan se vad jag missat?

import re def not_empty(str): return not str == "." and not str.isdigit() with open('input.txt') as file: lines=file.readlines() schematic = [] schematic.append("."*(len(lines[0])+2)) for line in lines: schematic.append("." + line + ".") schematic.append("."*(len(lines[0])+2)) sum = 0 for x, line in enumerate(schematic): for m in re.finditer("\d+", line): isolated = True if not_empty(schematic[x-1][m.start()-1]) or not_empty(schematic[x][m.start()-1]) or not_empty(schematic[x+1][m.start()-1]): isolated = False for y in range(m.start(), m.end()): if not_empty(schematic[x-1][y]) or not_empty(schematic[x+1][y]): isolated = False if not_empty(schematic[x-1][m.end()]) or not_empty(schematic[x][m.end()]) or not_empty(schematic[x+1][m.end()]): isolated = False if not isolated: sum+=int(m.group(0)) print("Part one:", sum)

Dold text
PermalÀnk
Medlem ★
●

Del 2 kÀndes som rekursion passade bra pÄ, sÄ körde pÄ det.
Inte den mest effektiva lösningen dock

Dag 4 (Del 1 och 2)
SprÄk: TypeScript

const AmoutOfWinsMap = new Map<number, number>() const getWins = (line: string, index: number) => { if(AmoutOfWinsMap.has(index)) { return AmoutOfWinsMap.get(index) || 0 } const [winningNumbers, actualNumbers] = line.split('|') const winningNumbersArray = winningNumbers.split(' ') const actualNumbersArray = actualNumbers.split(' ') const intersection = winningNumbersArray.filter((number: string) => parseInt(number) && actualNumbersArray.includes(number)) const wins = intersection.length AmoutOfWinsMap.set(index, wins) return wins } const part1 = (input: string[]) => { return input.reduce((acc: number, curr: string, index) => { const wins = getWins(curr, index) if(wins === 0) return acc const lineSum = Math.pow(2, wins-1) return acc + lineSum }, 0) } const countTotalCards = (allLines: string[], index: number) : number => { if(index >= allLines.length - 1) return 1 const wins = getWins(allLines[index], index) if(wins === 0) return 1 let totalCards = 1 for(let i=1; i<=wins; i++) { if(index + i < allLines.length){ totalCards += countTotalCards(allLines, index + i); } } return totalCards } const part2 = (input: string[]) => { return input.reduce((acc: number, curr: string, index: number) => { const wins = countTotalCards(input, index) return acc + wins }, 0) }

Dold text
Visa signatur

10700K | NVIDIA RTX 3080

PermalÀnk
●
Skrivet av jaqob:

Nu behöver jag, Àven om det tar emot, lite hjÀlp med första delen av dag 3. Min kod klarar all test-input jag kan hitta pÄ t.ex. reddit, men jag fÄr ett för högt svar pÄ min input. NÄgon som skrivit ihop nÄgot riktigt elakt test ni kan dela? Eller som lite hastigt och enkelt kan se vad jag missat?

NÀr du lÀgger till en punkt pÄ slutet av raderna missar du att ta bort radbrytningen först.

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

Del 2 kÀndes som rekursion passade bra pÄ, sÄ körde pÄ det.
Inte den mest effektiva lösningen dock

Dag 4 (Del 1 och 2)
SprÄk: TypeScript

const AmoutOfWinsMap = new Map<number, number>() const getWins = (line: string, index: number) => { if(AmoutOfWinsMap.has(index)) { return AmoutOfWinsMap.get(index) || 0 } const [winningNumbers, actualNumbers] = line.split('|') const winningNumbersArray = winningNumbers.split(' ') const actualNumbersArray = actualNumbers.split(' ') const intersection = winningNumbersArray.filter((number: string) => parseInt(number) && actualNumbersArray.includes(number)) const wins = intersection.length AmoutOfWinsMap.set(index, wins) return wins } const part1 = (input: string[]) => { return input.reduce((acc: number, curr: string, index) => { const wins = getWins(curr, index) if(wins === 0) return acc const lineSum = Math.pow(2, wins-1) return acc + lineSum }, 0) } const countTotalCards = (allLines: string[], index: number) : number => { if(index >= allLines.length - 1) return 1 const wins = getWins(allLines[index], index) if(wins === 0) return 1 let totalCards = 1 for(let i=1; i<=wins; i++) { if(index + i < allLines.length){ totalCards += countTotalCards(allLines, index + i); } } return totalCards } const part2 = (input: string[]) => { return input.reduce((acc: number, curr: string, index: number) => { const wins = countTotalCards(input, index) return acc + wins }, 0) }

Dold text

Är nyfiken pĂ„ hur du lĂ€ser in filerna. Gör det sjĂ€lv i JS men tycker det Ă€r den osmidiga delen.

Visa signatur

CPU: Ryzen 5600xGPU: 1080 TI ROG Strix RAM:2x16GB G.skill Trident @ 3600MHz MoBo: Asus B550FPSU: Corsair SF750
En resa till Nordkorea
2 dagar i Tjernobyl

PermalÀnk
Medlem ★
●
Skrivet av Gubbjekeln:

NÀr du lÀgger till en punkt pÄ slutet av raderna missar du att ta bort radbrytningen först.

Dold text

Tack!!

lines=file.read().splitlines() istÀllet för lines=file.readlines() löste det hela. Och det Àr sÄ klart typ den enda kodraden jag har som inte Àr delad mellan test-input och riktig input... DÄ spelade det ju inte sÄ stor roll att jag skrev ut min modifierade tabell för att hitta fel som detta...

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

Är nyfiken pĂ„ hur du lĂ€ser in filerna. Gör det sjĂ€lv i JS men tycker det Ă€r den osmidiga delen.

HÀr fÄr du den biten Sista biten Àr bara att splitta pÄ '|' sÄ fÄr du vinster i arr[0] och dina kort i arr[1] (som jag gör i getWins)

const parseLine = (line: string) => { const newLine = line.split(':') // Plockar bort "Card 1" eftersom den hamnar i newLine[0] sÄ returnerar jag allt till höger. return newLine[1].trim() } const file = readFileSync('testInput.txt', 'utf-8') .split('\n') .map((line: string) => parseLine(line))

Dold text
Visa signatur

10700K | NVIDIA RTX 3080

PermalÀnk
Medlem ★
●
Skrivet av kwame:

HÀr fÄr du den biten Sista biten Àr bara att splitta pÄ '|' sÄ fÄr du vinster i arr[0] och dina kort i arr[1] (som jag gör i getWins)

const parseLine = (line: string) => { const newLine = line.split(':') // Plockar bort "Card 1" eftersom den hamnar i newLine[0] sÄ returnerar jag allt till höger. return newLine[1].trim() } const file = readFileSync('testInput.txt', 'utf-8') .split('\n') .map((line: string) => parseLine(line))

Dold text

All splitting osv har jag löst, det Àr bara att jag hittade ingen bra lösning förf att lÀsa in filer sÄ blev fs readstream vilket Àr lite osmidigt...

Visa signatur

CPU: Ryzen 5600xGPU: 1080 TI ROG Strix RAM:2x16GB G.skill Trident @ 3600MHz MoBo: Asus B550FPSU: Corsair SF750
En resa till Nordkorea
2 dagar i Tjernobyl

PermalÀnk
Medlem
●

Alla 4 dagar pÄ en gÄng.
Efter dag 1 kÀndes det inte sÄ bra med att lÀgga ut koden.

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

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

Dag 3 (Del 1 & 2)
SprÄk: Java
GitHub
Viss uns av galenskap var involverat.

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

Dag 2 och 4 var okej, men dag 1 var verkligen elak för den första dagen. Dag 3 del 1 var okej men vad i helvete var del 2.
Koden fungerar men effektiv och genomtÀnkt Àr den verkligen inte.

PermalÀnk
Medlem ★
●
Skrivet av Pelegrino:

All splitting osv har jag löst, det Àr bara att jag hittade ingen bra lösning förf att lÀsa in filer sÄ blev fs readstream vilket Àr lite osmidigt...

Jag kör uppgifterna i nodejs och kör nÄgot sÄdant hÀr:

const fs = require('fs'); const allFileContents = fs.readFileSync('advent04.txt', 'utf-8'); allFileContents.split(/\r?\n/).forEach(line => { console.log(`Line from file: ${line}`); });

Inte optimalt men tillrÀckligt smidigt att anvÀnda för den hÀr typen av slit-och-slÀng-kod

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

Jag kör uppgifterna i nodejs och kör nÄgot sÄdant hÀr:

const fs = require('fs'); const allFileContents = fs.readFileSync('advent04.txt', 'utf-8'); allFileContents.split(/\r?\n/).forEach(line => { console.log(`Line from file: ${line}`); });

Inte optimalt men tillrÀckligt smidigt att anvÀnda för den hÀr typen av slit-och-slÀng-kod

Tack för tipset, otroligt mycket smidigare Àn nedan

const fs = require('fs'); const readline = require('readline'); const fileStream2 = fs.createReadStream('input.txt'); const fileStream = fs.createReadStream('input.txt'); let count = 0; let res = 0; let map = {} const rl2 = readline.createInterface({ input: fileStream2, crlfDelay: Infinity, // Detects all line endings (\r\n, \n, \r) }); rl2.on('line', line => { map[count] = 1; count++; }) const rl = readline.createInterface({ input: fileStream, crlfDelay: Infinity, // Detects all line endings (\r\n, \n, \r) }); let currentLine = 0; rl.on('line', line => { const split = line.split('|'); let occurences = 0; let myNumbers = split[1].trim().split(" "); let winningNumbers = split[0].split(":")[1].trim().split(" "); winningNumbers = winningNumbers.filter(x => x !== ""); myNumbers = myNumbers.filter(x => x !== ""); myNumbers = myNumbers.map(x => Number(x)) winningNumbers = winningNumbers.map(x => Number(x)) occurences = myNumbers.filter(x => winningNumbers.includes(x)).length for (let i = 1; i < occurences + 1; i++){ if (i + currentLine < count){ map[i + currentLine] += 1 * map[currentLine]; } } res+=map[currentLine]; currentLine++; }) rl.on('close', () => { console.log(res) })

Dold text
Visa signatur

CPU: Ryzen 5600xGPU: 1080 TI ROG Strix RAM:2x16GB G.skill Trident @ 3600MHz MoBo: Asus B550FPSU: Corsair SF750
En resa till Nordkorea
2 dagar i Tjernobyl