Care About Your Craft: Why spend your life developing software unless you care about doing it well? - The Pragmatic Programmer
đ Advent of Code (AoC) 2022 đ
Dag: 10
SprÄk: Python
Det gick att knöka ihop denna lösning som en oneliner i Python, men det krÀvdes en del trixande.
for s in (lambda d, fs: [f(d) for f in fs])(
reduce(lambda x, f: f(x),
map(lambda x: [lambda y: lambda z: (z[0], z[1] + [z[0]]),
lambda y: lambda z: (z[0] + int(y[5:]),
z[1] + [z[0], z[0] + int(y[5:])])]
[x[0] == 'a'](x),
open("input10").read().splitlines()), (1, [1]))[1],
[lambda during: sum([i * during[i] for i in range(20, len(during), 40)]),
lambda during: (lambda s: "\n".join([s[i: i + 39] for i in range(0, len(s), 40)]))
("".join([".#"[during[i] in [(i - 1) % 40, i % 40, (i + 1) % 40]] for i in range(240)]))
]): print(s)
Jag har löst del 2, jÀmförde med andras kod hÀr, men jag kan inte se vad det ska vara för bokstÀver.
En av mina "bokstÀver" ser ut exakt som en 7:a, men det var inte rÀtt svar
Dag: 9
SprÄk: Go
package main
import "fmt"
type KnotPos struct {
X, Y int
}
type KnotMove struct {
Direction KnotPos
Steps int
}
type KnotVisited map[KnotPos]bool
var directions = map[byte]KnotPos{
'U': {0, -1},
'D': {0, 1},
'L': {-1, 0},
'R': {1, 0},
}
func (a KnotPos) adjacent(b KnotPos) bool {
dx := a.X - b.X
dy := a.Y - b.Y
return (dx >= -1 && dx <= 1) && (dy >= -1 && dy <= 1)
}
func (a *KnotPos) add(b KnotPos) {
a.X += b.X
a.Y += b.Y
}
func dStep(d int) int {
switch {
case d > 0:
return 1
case d < 0:
return -1
return 0
}
func (a KnotPos) delta(b KnotPos) KnotPos {
if a.adjacent(b) {
return KnotPos{}
}
return KnotPos{dStep(b.X - a.X), dStep(b.Y - a.Y)}
}
func updateVisited(visited [2]KnotVisited, pos []KnotPos) {
visited[0][pos[1]] = true
visited[1][pos[len(pos)-1]] = true
}
func visitedPositions(moves []KnotMove, numKnots int) [2]KnotVisited {
visited := [2]KnotVisited{{}, {}}
pos := make([]KnotPos, numKnots)
updateVisited(visited, pos)
for _, move := range moves {
for step := 0; step < move.Steps; step++ {
pos[0].add(move.Direction)
for k := 1; k < numKnots; k++ {
pos[k].add(pos[k].delta(pos[k-1]))
}
updateVisited(visited, pos)
}
}
return visited
}
func parseMoves(input []string) []KnotMove {
moves := []KnotMove{}
var dir string
var steps int
for _, row := range input {
if _, err := fmt.Sscanf(row, "%v %d", &dir, &steps); err != nil {
panic("Failed to parse move")
}
moves = append(moves, KnotMove{directions[byte(dir[0])], steps})
}
return moves
}
func day9(input []string) {
moves := parseMoves(input)
visited := visitedPositions(moves, 10)
fmt.Println(len(visited[0]))
fmt.Println(len(visited[1]))
}
func init() {
Solutions[9] = day9
}
goos: darwin
goarch: arm64
pkg: aoc2022
BenchmarkDay9_parsing-8 1772 677240 ns/op 255836 B/op 4391 allocs/op
BenchmarkDay9_part1-8 1171 1024400 ns/op 748813 B/op 286 allocs/op
BenchmarkDay9_part2-8 924 1288776 ns/op 563975 B/op 225 allocs/op
PASS
ok aoc2022 3.983s
Dag: 10
SprÄk: Go
package main
import "fmt"
const (
CRT_WIDTH = 40
CRT_HEIGHT = 6
SPRITE_WIDTH = 3
)
type CrtImage [CRT_HEIGHT][CRT_WIDTH]byte
func parseCrtXs(input []string) []int {
x := 1
xs := []int{}
var arg int
for _, instr := range input {
xs = append(xs, x)
if _, err := fmt.Sscanf(instr, "addx %d", &arg); err == nil {
xs = append(xs, x)
x += arg
} else if instr != "noop" {
panic("Invalid input: " + instr)
}
}
return xs
}
func signalStrengthSum(xs []int) int {
sum := 0
for _, i := range []int{20, 60, 100, 140, 180, 220} {
sum += i * xs[i-1]
}
return sum
}
func renderCrtImage(xs []int) CrtImage {
image := CrtImage{}
xPos := 0
yPos := 0
for _, spriteXPos := range xs {
if xPos == CRT_WIDTH {
yPos++
xPos = 0
}
if spriteXPos >= xPos-1 && spriteXPos < xPos+SPRITE_WIDTH-1 {
image[yPos][xPos] = '#'
} else {
image[yPos][xPos] = '.'
}
xPos++
}
return image
}
func displayCrtImage(image CrtImage) {
for _, line := range image {
fmt.Println(string(line[:]))
}
}
func day10(input []string) {
crtXs := parseCrtXs(input)
fmt.Println(signalStrengthSum(crtXs))
displayCrtImage(renderCrtImage(crtXs))
}
func init() {
Solutions[10] = day10
}
func BenchmarkDay10_parsing(b *testing.B) {
input := parseInput(10)
for n := 0; n < b.N; n++ {
parseCrtXs(input)
}
}
func BenchmarkDay10_part1(b *testing.B) {
xs := parseCrtXs(parseInput(10))
for n := 0; n < b.N; n++ {
signalStrengthSum(xs)
}
}
func BenchmarkDay10_part2(b *testing.B) {
xs := parseCrtXs(parseInput(10))
for n := 0; n < b.N; n++ {
renderCrtImage(xs)
}
}
goos: darwin
goarch: arm64
pkg: aoc2022
BenchmarkDay10_parsing-8 28023 40203 ns/op 14068 B/op 393 allocs/op
BenchmarkDay10_part1-8 343980196 3.454 ns/op 0 B/op 0 allocs/op
BenchmarkDay10_part2-8 3373190 356.0 ns/op 0 B/op 0 allocs/op
PASS
ok aoc2022 4.992s
Verkar gjort lite annorlunda mot de flesta andra. RÀknade ut vÀrdet pÄ register X för varje cykel, vilket förenklade hanteringen av bÄde del 1 och del 2
Care About Your Craft: Why spend your life developing software unless you care about doing it well? - The Pragmatic Programmer
Jag har löst del 2, jÀmförde med andras kod hÀr, men jag kan inte se vad det ska vara för bokstÀver.
En av mina "bokstÀver" ser ut exakt som en 7:a, men det var inte rÀtt svar
Kolla att du inte har ett off by one-error nÄgonstans. Jag hade det t.ex. nÀr jag skrev ut tecken i CRT-outputen vilket gjorde min olÀsbar.
CPU: 7950X | RAM: 32GB | GPU: 3090 w/ AlphaCool Eisblock Aurora
Ljudkort: Modius + Magnius | Lurar: GoldPlanar GL2000 / Sennheiser HD 650 / Philips Fidelio X3
Dag: 10
SprÄk: C#
Har gjort tidigare dagar ocksÄ men inte orkat lÀgga upp med jobb och sÄnt!
Lagom lÀsbart och lagom snabbt!
| Method | Mean | Error | StdDev | Gen0 | Gen1 | Allocated |
|------- |---------:|----------:|----------:|-------:|-------:|----------:|
| Run_A | 6.056 us | 0.0497 us | 0.0441 us | 1.7548 | 0.0381 | 14.34 KB |
| Run_B | 6.871 us | 0.0690 us | 0.0539 us | 1.8845 | 0.0458 | 15.43 KB |
Ni som Àr grymma kan vÀl ha med lite benchmarks sÄ man kan se hur dÄlig ens kod Àr i jÀmförelse
public sealed class CathodeRayCube : Puzzle<int>
{
public override int A(string data)
{
int sum = 0, c = 0, reg = 1;
int[] reportCycles = {20, 60, 100, 140, 180, 220};
int reportCount = 0;
foreach (var line in data.Split("\r\n"))
{
if (reportCount == reportCycles.Length)
break;
if (line[..4] == "noop")
{
sum += GetSum(reportCycles, ref reportCount, ref c, reg);
}
else
{
sum += GetSum(reportCycles, ref reportCount, ref c, reg);
sum += GetSum(reportCycles, ref reportCount, ref c, reg);
reg += int.Parse(line[4..].Trim());
}
}
return sum;
}
public override int B(string data)
{
char[] screen = CreateScreen();
int reg = 1, x = 0;
foreach (var line in data.Split("\r\n"))
{
if (line[..4] == "noop")
{
Draw(screen, ref x, reg);
}
else
{
Draw(screen, ref x, reg);
Draw(screen, ref x, reg);
reg += int.Parse(line[4..].Trim());
}
}
PrintScreen(screen);
return 0;
}
private static void Draw(char[] screen, ref int x, int registerValue)
{
if (registerValue == x % 40 - 1 || registerValue == x % 40 || registerValue == x % 40 + 1)
{
screen[x] = '#';
}
x++;
}
private static int GetSum(int[] reportCycles, ref int reportCount, ref int instruction, int registerValue)
{
int sum = 0;
instruction++;
if (instruction != reportCycles[reportCount]) return sum;
sum += instruction * registerValue;
reportCount++;
return sum;
}
private static char[] CreateScreen()
{
const int width = 40;
const int height = 6;
var screen = new char[width * height];
Array.Fill(screen, '.');
return screen;
}
private void PrintScreen(char[] screen)
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < screen.Length; i++)
{
if (i != 0 && i % 40 == 0)
sb.Append(Environment.NewLine);
sb.Append(screen[i]);
}
Console.WriteLine(sb.ToString());
}
}
Dag: 10
SprÄk: C#
Har gjort tidigare dagar ocksÄ men inte orkat lÀgga upp med jobb och sÄnt!
Lagom lÀsbart och lagom snabbt!
| Method | Mean | Error | StdDev | Gen0 | Gen1 | Allocated |
|------- |---------:|----------:|----------:|-------:|-------:|----------:|
| Run_A | 6.056 us | 0.0497 us | 0.0441 us | 1.7548 | 0.0381 | 14.34 KB |
| Run_B | 6.871 us | 0.0690 us | 0.0539 us | 1.8845 | 0.0458 | 15.43 KB |
Ni som Àr grymma kan vÀl ha med lite benchmarks sÄ man kan se hur dÄlig ens kod Àr i jÀmförelse
public sealed class CathodeRayCube : Puzzle<int>
{
public override int A(string data)
{
int sum = 0, c = 0, reg = 1;
int[] reportCycles = {20, 60, 100, 140, 180, 220};
int reportCount = 0;
foreach (var line in data.Split("\r\n"))
{
if (reportCount == reportCycles.Length)
break;
if (line[..4] == "noop")
{
sum += GetSum(reportCycles, ref reportCount, ref c, reg);
}
else
{
sum += GetSum(reportCycles, ref reportCount, ref c, reg);
sum += GetSum(reportCycles, ref reportCount, ref c, reg);
reg += int.Parse(line[4..].Trim());
}
}
return sum;
}
public override int B(string data)
{
char[] screen = CreateScreen();
int reg = 1, x = 0;
foreach (var line in data.Split("\r\n"))
{
if (line[..4] == "noop")
{
Draw(screen, ref x, reg);
}
else
{
Draw(screen, ref x, reg);
Draw(screen, ref x, reg);
reg += int.Parse(line[4..].Trim());
}
}
PrintScreen(screen);
return 0;
}
private static void Draw(char[] screen, ref int x, int registerValue)
{
if (registerValue == x % 40 - 1 || registerValue == x % 40 || registerValue == x % 40 + 1)
{
screen[x] = '#';
}
x++;
}
private static int GetSum(int[] reportCycles, ref int reportCount, ref int instruction, int registerValue)
{
int sum = 0;
instruction++;
if (instruction != reportCycles[reportCount]) return sum;
sum += instruction * registerValue;
reportCount++;
return sum;
}
private static char[] CreateScreen()
{
const int width = 40;
const int height = 6;
var screen = new char[width * height];
Array.Fill(screen, '.');
return screen;
}
private void PrintScreen(char[] screen)
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < screen.Length; i++)
{
if (i != 0 && i % 40 == 0)
sb.Append(Environment.NewLine);
sb.Append(screen[i]);
}
Console.WriteLine(sb.ToString());
}
}
| Method | Mean | Error | StdDev | Gen0 | Gen1 | Allocated |
|-------- |---------:|--------:|--------:|-------:|-------:|----------:|
| SolveAB | 369.7 ns | 7.35 ns | 8.47 ns | 0.0834 | 0.0024 | 1.37 KB |
Dock printar jag inte till Console, vilket Àr vad som skulle ta mest tid om det var med i benchmarken. Jag returnerar bara svaren frÄn metoden. LÀsa frÄn fil Àr inte heller medrÀknat. Resultatet beror ju ocksÄ pÄ vilken CPU man har, sÄ kan ju vara att jÀmföra Àpplen och pÀron!
CPU: 7950X | RAM: 32GB | GPU: 3090 w/ AlphaCool Eisblock Aurora
Ljudkort: Modius + Magnius | Lurar: GoldPlanar GL2000 / Sennheiser HD 650 / Philips Fidelio X3
Jag har löst del 2, jÀmförde med andras kod hÀr, men jag kan inte se vad det ska vara för bokstÀver.
En av mina "bokstÀver" ser ut exakt som en 7:a, men det var inte rÀtt svar
Vad har du för input?
Hint som kan vara hjÀlpsam:
Hur mÄnga rader skriver du ut? Borde bli 6 sÄ jag tÀnker om 7 Àr Z och att nÄgot i slutet inte Àr reko
Att föresprÄka Mac pÄ Swec Àr som att föresprÄka hybridbilar pÄ en raggartrÀff i Mora.
Nuvarande stationÀr: 7800X3D, 128Gb ram, 4Tb nvme, 3x8Tb sata-ssd, 4070 Ti S
Dag: 10
SprÄk: js
readAllLinesInFile ger mig en array med en rad pÄ varje plats.
Trodde detta skulle bli betydligt mer kod nÀr jag började lÀsa uppgiften men det blev inte sÄ farligt.
Delade koden i tvÄ delar eftersom cycle hanteras annorlunda i del 2.
KÀnslan nÀr man kör med den riktiga datan och ser att det faktiskt blir bokstÀver som gÄr att lÀsa: chef's-kiss
Del 1
import { readAllLinesInFile } from '../helpers.mjs';
const allLines = readAllLinesInFile("10data").map(line => {
const parts = line.split(" ");
return parts[0] === "addx" ? [2,Number(parts[1])] : [1, 0];
});
let x = 1;
let cycle = 0;
let cycleSum = 0;
allLines.forEach((line) => {
for(let cycleCount = line[0]; cycleCount>0; cycleCount--){
cycle++;
if((cycle -20)%40 === 0 || cycle === 20){
cycleSum += x * cycle;
}
x+= cycleCount === 1 ? line[1] : 0;
}
});
console.log("Part 1:", cycleSum);
Del 2
import { readAllLinesInFile } from '../helpers.mjs';
const allLines = readAllLinesInFile("10data").map(line => {
const parts = line.split(" ");
return parts[0] === "addx" ? [2,Number(parts[1])] : [1, 0];
});
let x = 1;
let cycle = 0;
let output = "";
allLines.forEach((line) => {
for(let cycleCount = line[0]; cycleCount>0; cycleCount--){
output += Math.abs(x - cycle) <2 ? "#" : ".";
cycle = ++cycle % 40;
if(cycle === 0){
console.log(output);
output = "";
}
x+= cycleCount === 1 ? line[1] : 0;
}
});
Att föresprÄka Mac pÄ Swec Àr som att föresprÄka hybridbilar pÄ en raggartrÀff i Mora.
Nuvarande stationÀr: 7800X3D, 128Gb ram, 4Tb nvme, 3x8Tb sata-ssd, 4070 Ti S
Du visar inte vad du har med och inte i din benchmark, sÄ kan vara att jÀmföra Àpplen och pÀron.
Nu blev jag konfunderad Ăr det din data Mickur eller Gorgonzolas?
Att föresprÄka Mac pÄ Swec Àr som att föresprÄka hybridbilar pÄ en raggartrÀff i Mora.
Nuvarande stationÀr: 7800X3D, 128Gb ram, 4Tb nvme, 3x8Tb sata-ssd, 4070 Ti S
Nu blev jag konfunderad Ăr det din data Mickur eller Gorgonzolas?
Jag som inte kollar vad du citerat, trodde du var l4nky Jag har nog lite för mÄnga bollar i luften samtidigt, hehe!
CPU: 7950X | RAM: 32GB | GPU: 3090 w/ AlphaCool Eisblock Aurora
Ljudkort: Modius + Magnius | Lurar: GoldPlanar GL2000 / Sennheiser HD 650 / Philips Fidelio X3
Day: 8
SprÄk: C++
#include "../AoCHelper/AoCHelper.h"
#include <vector>
bool go_up(std::vector<std::vector<int>> input, int height, int x, int y, int &steps)
{
if (y == 0)
{
return true;
}
if (input[y - 1][x] >= height)
{
steps++;
return false;
}
steps++;
return go_up(input, height, x, y - 1, steps);
}
bool go_left(std::vector<std::vector<int>> input, int height, int x, int y, int &steps)
{
if (x == 0)
{
return true;
}
if (input[y][x - 1] >= height)
{
steps++;
return false;
}
steps++;
return go_left(input, height, x - 1, y, steps);
}
bool go_right(std::vector<std::vector<int>> input, int height, int x, int y, int &steps)
{
if (x == input[y].size() - 1)
{
return true;
}
if (input[y][x + 1] >= height)
{
steps++;
return false;
}
steps++;
return go_right(input, height, x + 1, y, steps);
}
bool go_down(std::vector<std::vector<int>> input, int height, int x, int y, int &steps)
{
if (y == input.size() - 1)
{
return true;
}
if (input[y + 1][x] >= height)
{
steps++;
return false;
}
steps++;
return go_down(input, height, x, y + 1, steps);
}
void puzzle(std::vector<std::string> rawInput)
{
std::vector<std::vector<int>> input;
size_t highestScenicScore{};
for (std::string row : rawInput)
{
std::vector<int> temp;
for (char c : row)
{
temp.push_back(c - '0');
}
input.push_back(temp);
}
int answer{(input.size() * 2) + ((input[0].size() - 2) * 2)};
for (int i = 1; i < input.size() - 1; i++)
{
for (int j = 1; j < input[i].size() - 1; j++)
{
int currentHeight = input[i][j];
int steps_up{};
int steps_down{};
int steps_left{};
int steps_right{};
bool canGoUp = go_up(input, currentHeight, j, i, steps_up);
bool canGoDown = go_down(input, currentHeight, j, i, steps_down);
bool canGoLeft = go_left(input, currentHeight, j, i, steps_left);
bool canGoRight = go_right(input, currentHeight, j, i, steps_right);
if (canGoDown || canGoLeft || canGoRight || canGoUp)
{
answer++;
}
size_t scenicScore = steps_up * steps_down * steps_left * steps_right;
if (scenicScore > highestScenicScore)
{
highestScenicScore = scenicScore;
}
}
}
std::cout << "Puzzle one: " << answer << std::endl;
std::cout << "Puzzle two: " << highestScenicScore << std::endl;
}
int main()
{
std::vector<std::string> exampleInput{"30373",
"25512",
"65332",
"33549",
"35390"};
AoCHelper a1{"2022", "8"};
std::vector<std::string> result = a1.get_input();
puzzle(result);
}
Day: 9
SprÄk: C++
Spenderade alldeles för lÄng tid pÄ att försöka tolka vad som menades med hur svansen skulle röra sig och lyckades missuppfatta uppgiften bÄde en och tvÄ gÄnger... Frustrerande.
#include <vector>
#include "../AoCHelper/AoCHelper.h"
struct Knot {
int x;
int y;
};
bool isHeadAndTailTouching(Knot head, Knot tail) {
if (head.x == tail.x && head.y == tail.y ||
head.x == tail.x + 1 && head.y == tail.y ||
head.x == tail.x - 1 && head.y == tail.y ||
head.x == tail.x && head.y == tail.y + 1 ||
head.x == tail.x && head.y == tail.y - 1 ||
head.x == tail.x + 1 && head.y == tail.y + 1 ||
head.x == tail.x - 1 && head.y == tail.y - 1 ||
head.x == tail.x + 1 && head.y == tail.y - 1 ||
head.x == tail.x - 1 && head.y == tail.y + 1) {
return true;
}
return false;
}
void print2dMap(Knot head, Knot tail) {
std::vector<std::vector<char>> map(35, std::vector<char>(35, '.'));
map[head.y][head.x] = 'H';
map[tail.y][tail.x] = 'T';
for (int i = map.size() - 1; i >= 0; i--) {
for (int j = map.size() - 1; j >= 0; j--) {
std::cout << map[i][j] << " ";
}
std::cout << std::endl;
}
std::cout << std::endl;
}
// print all knots in vector on a 2d map
void print2dMap(Knot head, std::vector<Knot*>& knots) {
std::vector<std::vector<char>> map(35, std::vector<char>(35, '.'));
int x_offset = map.size() / 2;
int y_offset = map.size() / 2;
map[y_offset][x_offset] = 's';
for (int i = knots.size() - 1; i >= 0; i--) {
Knot* knot = knots[i];
map[knot->y + y_offset][knot->x + x_offset] =
std::to_string(i + 1).c_str()[0];
}
map[head.y + y_offset][head.x + x_offset] = 'H';
for (int i = map.size() - 1; i >= 0; i--) {
for (int j = 0; j < map.size(); j++) {
std::cout << map[i][j] << " ";
}
std::cout << std::endl;
}
std::cout << std::endl;
}
// print tail map
void print2dmapTailMoves(std::vector<Knot>& tailMoves) {
std::vector<std::vector<char>> map(35, std::vector<char>(35, '.'));
int x_offset = map.size() / 2;
int y_offset = map.size() / 2;
for (int i = tailMoves.size() - 1; i >= 0; i--) {
Knot knot = tailMoves[i];
map[knot.y + y_offset][knot.x + x_offset] = '#';
}
map[y_offset][x_offset] = 's';
for (int i = map.size() - 1; i >= 0; i--) {
for (int j = 0; j < map.size(); j++) {
std::cout << map[i][j] << " ";
}
std::cout << std::endl;
}
std::cout << std::endl;
}
bool isHeadAndTailOnSameRow(Knot head, Knot tail) {
if (head.y == tail.y) {
return true;
}
return false;
}
bool isHeadAndTailOnSameColumn(Knot head, Knot tail) {
if (head.x == tail.x) {
return true;
}
return false;
}
void registerMove(Knot& tail, std::vector<Knot>& tailMoves) {
if (!std::any_of(tailMoves.begin(), tailMoves.end(),
[tail](Knot t) { return t.x == tail.x && t.y == tail.y; })) {
tailMoves.push_back(tail);
}
}
void puzzle_one(std::vector<std::string> input) {
int answer{};
Knot head{0, 0};
Knot tail{0, 0};
std::vector<Knot> tailMoves{tail};
for (std::string row : input) {
char moveDir = myLib::split(row, ' ')[0][0];
int movePos = std::stoi(myLib::split(row, ' ')[1]);
// move head
switch (moveDir) {
case 'R':
head.x += movePos;
break;
case 'L':
head.x -= movePos;
break;
case 'U':
head.y += movePos;
break;
case 'D':
head.y -= movePos;
break;
}
if (!isHeadAndTailTouching(head, tail)) {
while (!isHeadAndTailOnSameColumn(head, tail) &&
!isHeadAndTailOnSameRow(head, tail) &&
!isHeadAndTailTouching(head, tail)) {
// move diagonally towards head
if (head.x > tail.x && head.y > tail.y) {
tail.x += 1;
tail.y += 1;
} else if (head.x > tail.x && head.y < tail.y) {
tail.x += 1;
tail.y -= 1;
} else if (head.x < tail.x && head.y > tail.y) {
tail.x -= 1;
tail.y += 1;
} else if (head.x < tail.x && head.y < tail.y) {
tail.x -= 1;
tail.y -= 1;
}
registerMove(tail, tailMoves);
}
if (isHeadAndTailOnSameRow(head, tail)) {
while (!isHeadAndTailTouching(head, tail)) {
if (head.x > tail.x) {
tail.x += 1;
} else {
tail.x -= 1;
}
registerMove(tail, tailMoves);
}
} else if (isHeadAndTailOnSameColumn(head, tail)) {
while (!isHeadAndTailTouching(head, tail)) {
if (head.y > tail.y) {
tail.y += 1;
} else {
tail.y -= 1;
}
registerMove(tail, tailMoves);
}
}
}
registerMove(tail, tailMoves);
}
answer = tailMoves.size();
std::cout << "Puzzle one: " << answer << std::endl;
}
void puzzle_two(std::vector<std::string> input) {
int answer{};
Knot head{0, 0};
Knot knot{0, 0};
Knot knot2{0, 0};
Knot knot3{0, 0};
Knot knot4{0, 0};
Knot knot5{0, 0};
Knot knot6{0, 0};
Knot knot7{0, 0};
Knot knot8{0, 0};
Knot knot9{0, 0};
std::vector<Knot*> knots{&knot, &knot2, &knot3, &knot4, &knot5,
&knot6, &knot7, &knot8, &knot9};
std::vector<Knot> tailMoves{knot9};
for (std::string row : input) {
char moveDir = myLib::split(row, ' ')[0][0];
int movePos = std::stoi(myLib::split(row, ' ')[1]);
for (size_t i = 0; i < movePos; i++) {
switch (moveDir) {
case 'R':
head.x++;
break;
case 'L':
head.x--;
break;
case 'U':
head.y++;
break;
case 'D':
head.y--;
break;
}
for (size_t i = 0; i < knots.size(); i++) {
Knot* previousKnot{};
if (i == 0) {
previousKnot = &head;
} else {
previousKnot = knots[i - 1];
}
Knot* tail = knots[i];
if (!isHeadAndTailTouching(*previousKnot, *tail)) {
if (!isHeadAndTailOnSameColumn(*previousKnot, *tail) &&
!isHeadAndTailOnSameRow(*previousKnot, *tail)) {
// move diagonally towards previousKnot
if (previousKnot->x > tail->x && previousKnot->y > tail->y) {
tail->x += 1;
tail->y += 1;
} else if (previousKnot->x > tail->x && previousKnot->y < tail->y) {
tail->x += 1;
tail->y -= 1;
} else if (previousKnot->x < tail->x && previousKnot->y > tail->y) {
tail->x -= 1;
tail->y += 1;
} else if (previousKnot->x < tail->x && previousKnot->y < tail->y) {
tail->x -= 1;
tail->y -= 1;
}
if (i == 8) registerMove(knot9, tailMoves);
}
if (isHeadAndTailOnSameRow(*previousKnot, *tail) &&
!isHeadAndTailTouching(*previousKnot, *tail)) {
if (previousKnot->x > tail->x) {
tail->x += 1;
} else {
tail->x -= 1;
}
if (i == 8) registerMove(knot9, tailMoves);
} else if (isHeadAndTailOnSameColumn(*previousKnot, *tail) &&
!isHeadAndTailTouching(*previousKnot, *tail)) {
if (previousKnot->y > tail->y) {
tail->y += 1;
} else {
tail->y -= 1;
}
if (i == 8) registerMove(knot9, tailMoves);
}
}
if (i == 8) registerMove(knot9, tailMoves);
}
}
}
answer = tailMoves.size();
std::cout << "Puzzle two: " << answer << std::endl;
}
int main() {
std::vector<std::string> exampleInput{"R 4", "U 4", "L 3", "D 1",
"R 4", "D 1", "L 5", "R 2"};
std::vector<std::string> exampleInput2{"R 5", "U 8", "L 8", "D 3",
"R 17", "D 10", "L 25", "U 20"};
AoCHelper a1{"2022", "9"};
std::vector<std::string> result = a1.get_input();
puzzle_one(result);
puzzle_two(result);
}
Day: 10
SprÄk: C++
Rolig dag! Misstolkade att flera cykler inte kunde exekveras asynkront sÄ brÄkade lite med det, hade skapat en lösning med hjÀlp av tvÄ köer för att hÄlla kolla pÄ vilka kommandon som skulle exekveras hÀr nÀst i varenda cykel, men man skulle ju inte göra nÄgon ytterligare inmatning tills exekveringen av föregÄende kommando var fÀrdig.
#include <vector>
#include "../AoCHelper/AoCHelper.h"
void determineSignalStrength(int& answer, int& cycle, int& x) {
if (cycle == 20 || cycle == 60 || cycle == 100 || cycle == 140 ||
cycle == 180 || cycle == 220) {
answer += (x * (cycle));
}
}
void printCrtScreen(std::vector<int>& crtMap) {
std::vector<std::vector<char>> map(6, std::vector<char>(40, '.'));
for (int i = 0; i < crtMap.size(); i++) {
int j = crtMap[i] % 40;
int v = crtMap[i] / 40;
map[v][j] = '#';
}
for (int i = 0; i < map.size(); i++) {
for (int j = 0; j < map[0].size(); j++) {
std::cout << map[i][j];
}
std::cout << std::endl;
}
std::cout << std::endl;
}
void puzzle(std::vector<std::string> input) {
int partOneanswer{};
int x{1};
int totalCycles{0};
int crtCycle{0};
std::vector<int> crtMap{};
for (std::string row : input) {
int calculationCycles{1};
int value{0};
std::string instruction = row.substr(0, 4);
if (instruction != "noop") {
value = std::stoi(row.substr(5, row.size()));
calculationCycles = 2;
}
for (int i = 1; i <= calculationCycles; i++) {
if (crtCycle == x - 1 || crtCycle == x || crtCycle == x + 1) {
crtMap.push_back(totalCycles);
}
totalCycles++;
crtCycle = totalCycles % 40;
determineSignalStrength(partOneanswer, totalCycles, x);
}
x += value;
}
std::cout << "Puzzle one: " << partOneanswer << std::endl;
std::cout << "Puzzle two: " << std::endl;
printCrtScreen(crtMap);
}
int main() {
AoCHelper a1{"2022", "10"};
std::vector<std::string> result = a1.get_input();
puzzle(result);
}
Vad har du för input?
Hint som kan vara hjÀlpsam:
Hur mÄnga rader skriver du ut? Borde bli 6 sÄ jag tÀnker om 7 Àr Z och att nÄgot i slutet inte Àr reko
Tack, det var precis vad felet var. 2 andra lösningar hÀr hade samma fel som jag la till en PrintLine pÄ slutet och fick ut sista raden
Tack, det var precis vad felet var. 2 andra lösningar hÀr hade samma fel som jag la till en PrintLine pÄ slutet och fick ut sista raden
Niiiice
Att föresprÄka Mac pÄ Swec Àr som att föresprÄka hybridbilar pÄ en raggartrÀff i Mora.
Nuvarande stationÀr: 7800X3D, 128Gb ram, 4Tb nvme, 3x8Tb sata-ssd, 4070 Ti S
Dag: 10
SprÄk: Kotlin
Rolig uppgift
val xChanges = input.lines()
.map { line -> if (line[0] == 'a') listOf(0, parseIntString(line).first()) else listOf(0) }.flatten()
val xValues = MutableList(xChanges.size) { 1 }
for (i in xValues.indices - 0)
xValues[i] = xValues[i - 1] + xChanges[i - 1]
var sum = 0
for (i in 20..220 step 40)
sum += i*xValues[i]
println(sum)
for (row in 0..5)
for (col in 0..39) {
if (col in xValues[40 * row + col] - 1..xValues[40 * row + col] + 1)
print("â")
else
print(" ")
}
println()
}
i5-7600k . GTX 1080 . 16 GB
Dag:9
SprÄk: Scala
extension (t1: (Int, Int))
def + (t2: (Int, Int)) = (t1._1 + t2._1, t1._2 + t2._2)
def diff(t2: (Int, Int)) = ((t1._1 - t2._1).sign, (t1._2 - t2._2).sign)
def isAdjacentTo(t2: (Int, Int)) = (t1._1 - t2._1).abs <= 1 && (t1._2 - t2._2).abs <= 1
val input = Using.resource(Source.fromFile("""9.txt"""))(_.getLines().toList)
def parse(input: List[String]) = input.flatMap {
case s"U $n" => List.fill(n.toInt)((0, 1))
case s"D $n" => List.fill(n.toInt)((0, -1))
case s"L $n" => List.fill(n.toInt)((-1, 0))
case s"R $n" => List.fill(n.toInt)((1, 0))
}
def solve(moves: List[(Int, Int)], n: Int): Int = moves
.scanLeft(List.fill(n)((0, 0)))((rope, move) =>
rope.tail.scanLeft(rope.head + move)((prev, curr) =>
if prev.isAdjacentTo(curr) then curr else curr + prev.diff(curr)))
.map(_.last)
.distinct
.size
solve(parse(input), 2)
solve(parse(input), 10)
Dag:10
SprÄk: Dyalog APL
âIOâ0
dâ+\ÂŻ1â1,â{âœâ5ââ”,' 0'}šââNGET'10.txt'1
+/{â”Ăd[â”-1]}20+40Ăâł6 â del1
6 40âŽ'.#'[1â„|d-âš(âąd)âŽâł40] â del2
Dag: 10
SprÄk: C#
Har gjort tidigare dagar ocksÄ men inte orkat lÀgga upp med jobb och sÄnt!
Lagom lÀsbart och lagom snabbt!
| Method | Mean | Error | StdDev | Gen0 | Gen1 | Allocated |
|------- |---------:|----------:|----------:|-------:|-------:|----------:|
| Run_A | 6.056 us | 0.0497 us | 0.0441 us | 1.7548 | 0.0381 | 14.34 KB |
| Run_B | 6.871 us | 0.0690 us | 0.0539 us | 1.8845 | 0.0458 | 15.43 KB |
Ni som Àr grymma kan vÀl ha med lite benchmarks sÄ man kan se hur dÄlig ens kod Àr i jÀmförelse
public sealed class CathodeRayCube : Puzzle<int>
{
public override int A(string data)
{
int sum = 0, c = 0, reg = 1;
int[] reportCycles = {20, 60, 100, 140, 180, 220};
int reportCount = 0;
foreach (var line in data.Split("\r\n"))
{
if (reportCount == reportCycles.Length)
break;
if (line[..4] == "noop")
{
sum += GetSum(reportCycles, ref reportCount, ref c, reg);
}
else
{
sum += GetSum(reportCycles, ref reportCount, ref c, reg);
sum += GetSum(reportCycles, ref reportCount, ref c, reg);
reg += int.Parse(line[4..].Trim());
}
}
return sum;
}
public override int B(string data)
{
char[] screen = CreateScreen();
int reg = 1, x = 0;
foreach (var line in data.Split("\r\n"))
{
if (line[..4] == "noop")
{
Draw(screen, ref x, reg);
}
else
{
Draw(screen, ref x, reg);
Draw(screen, ref x, reg);
reg += int.Parse(line[4..].Trim());
}
}
PrintScreen(screen);
return 0;
}
private static void Draw(char[] screen, ref int x, int registerValue)
{
if (registerValue == x % 40 - 1 || registerValue == x % 40 || registerValue == x % 40 + 1)
{
screen[x] = '#';
}
x++;
}
private static int GetSum(int[] reportCycles, ref int reportCount, ref int instruction, int registerValue)
{
int sum = 0;
instruction++;
if (instruction != reportCycles[reportCount]) return sum;
sum += instruction * registerValue;
reportCount++;
return sum;
}
private static char[] CreateScreen()
{
const int width = 40;
const int height = 6;
var screen = new char[width * height];
Array.Fill(screen, '.');
return screen;
}
private void PrintScreen(char[] screen)
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < screen.Length; i++)
{
if (i != 0 && i % 40 == 0)
sb.Append(Environment.NewLine);
sb.Append(screen[i]);
}
Console.WriteLine(sb.ToString());
}
}
StÀdade bort massa onödigt i min kod och la till lite mikrooptimeringar
int.Parse utan Culture och numberstyle tog förvÄnansvÀrt mycket av tiden pga hÀmtning av vÀrdena. SÄ skjuta in dessa hjÀlpte en del.
Jag mÀter inte heller IO eller Console writes. DÀremot sÄ kommer jag aldrig förbi 14% av min CPU ÀndÄ (Ryzen 3600X)
| Method | Mean | Error | StdDev | Gen0 | Allocated |
|------- |---------:|----------:|----------:|-------:|----------:|
| Run_A | 4.988 us | 0.0981 us | 0.1665 us | 1.2207 | 9.98 KB |
| Run_B | 6.759 us | 0.0882 us | 0.0782 us | 1.4267 | 11.7 KB |
public sealed class CathodeRayCube : Puzzle<int>
{
public override int A(string data)
{
int c = 0, sum = 0, reg = 1;
void Cycle()
{
c++;
if (c != 20 && c % 40 != 20) return;
sum += c * reg;
}
var reader = new StringReader(data);
while (reader.ReadLine() is { } line)
{
if (c == 220) break;
Cycle();
if (line[0] != 'a') continue;
Cycle();
reg += int.Parse(line[4..].Trim(), NumberStyles.Integer, CultureInfo.InvariantCulture);
}
return sum;
}
public override int B(string data)
{
var sb = new StringBuilder();
int reg = 1, x = 0;
void Cycle()
{
sb.Append(reg == x % 40 - 1 || reg == x % 40 || reg == x % 40 + 1 ? '#' : '.');
x++;
if (x % 40 == 0) sb.Append(Environment.NewLine);
}
var reader = new StringReader(data);
while (reader.ReadLine() is { } line)
{
Cycle();
if (line[0] != 'a') continue;
Cycle();
reg += int.Parse(line[4..].Trim(), NumberStyles.Integer, CultureInfo.InvariantCulture);
}
// Console.WriteLine(sb);
return 0;
}
}
Dag: 10
SprÄk: C#
using System.Text;
namespace AOC2022.Puzzles;
internal class Puzzle10 : Puzzle<int, string>
{
private const int CrtPixels = 40;
protected override void Solve(string[] lines)
{
var (x, totalCycles, signalStrengths, drawer) = (1, 0, new Dictionary<int, int>(), new StringBuilder());
foreach (var line in lines)
{
var (cycles, addx) = ParseInstruction(line);
foreach (var currCycle in Enumerable.Range(totalCycles + 1, cycles))
{
signalStrengths[currCycle] = x * currCycle;
var crtIndex = (currCycle - 1) % CrtPixels;
var pixel = crtIndex >= x - 1 && crtIndex <= x + 1 ? '#' : '.';
drawer.Append(pixel);
if (currCycle / CrtPixels > ((currCycle - 1) / CrtPixels))
{
drawer.AppendLine();
}
}
totalCycles += cycles;
x += addx;
}
One = Enumerable.Range(0, 6).Select(x => signalStrengths[20 + 40 * x]).Sum();
Two = Environment.NewLine + Environment.NewLine + drawer.ToString();
}
private static (int cycles, int addx) ParseInstruction(string instruction) => instruction switch
{
"noop" => (1, 0),
_ => (2, int.Parse(instruction.Split(' ')[1]))
};
}
Dag: 10
SprÄk: Go
type instruction string
const (
noop instruction = "noop"
addx instruction = "addx"
)
func main() {
input, err := helpers.ReadLines(os.Args[1])
if err != nil {
panic(err)
}
sum, pixels := executeInstructions(input)
fmt.Println(sum)
for i := 0; i < len(pixels); i = i + 40 {
row := pixels[i : i+40]
fmt.Println(row)
}
}
func executeInstructions(instructions []string) (int, []string) {
crt := make([]string, 240)
cycle := 1
rX := 1
sum := 0
for _, i := range instructions {
ins := i[0:4]
if instruction(ins) == noop {
crt[cycle-1] = checkPixel(cycle-1, rX)
cycle++
sum += addToSum(cycle, rX)
} else {
arg := helpers.GetInt(i[5:])
crt[cycle-1] = checkPixel(cycle-1, rX)
cycle++
sum += addToSum(cycle, rX)
crt[cycle-1] = checkPixel(cycle-1, rX)
cycle++
rX += arg
sum += addToSum(cycle, rX)
}
}
return sum, crt
}
func addToSum(cycle int, rX int) int {
if cycle == 20 || (cycle-20)%40 == 0 {
return cycle * rX
}
return 0
}
func checkPixel(cycle int, midPoint int) string {
if cycle%40 >= midPoint-1 && cycle%40 <= midPoint+1 {
return "#"
}
return "."
}
Dag: 10
SprÄk: C
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int x = 1;
int cycles = 0;
int sum = 0;
#define CRT_WIDTH 40
#define SPRITE_LEN 1
void updateScreen() { // part 2
int spriteStart = x-SPRITE_LEN, spriteStop = x+SPRITE_LEN;
int pixel = cycles%CRT_WIDTH;
if (spriteStart <= pixel && pixel <= spriteStop)
putchar('#');
else
putchar('.');
if (pixel == CRT_WIDTH-1)
putchar('\n');
}
void incCycles() {
updateScreen();
cycles++;
if ((cycles-20)%40 == 0) // part 1
sum += x*cycles;
}
int main(void) {
char *line = NULL;
size_t len = 0;
ssize_t nread;
FILE *fp = fopen("d10_input.txt", "r");
if (!fp) {
perror("Failed to open file");
exit(EXIT_FAILURE);
}
while ((nread = getline(&line, &len, fp)) != -1) {
int i;
incCycles();
if (!strcmp("noop\n", line))
continue;
if (sscanf(line, "addx %d\n", &i) == 1) {
incCycles();
x += i;
}
}
free(line);
fclose(fp);
printf("sum: %d\n", sum);
exit(EXIT_SUCCESS);
}
Dag: 10
SprÄk: Python 3
Lösning: GitHub
Taskigt att lÀgga ett U
i output pÄ Del 2. Jag trodde det var ett V
.
Dag: 11
SprÄk: Python 3
Lösning: GitHub
à rets första "Del 2 ökar bara antalet iterationer men det gÄr inte att köra bruteforce"-uppgift. FÄr gÀrna vara Ärets sista ocksÄ
:(){ :|:& };:
đđ»ââïž Â đŽđ»ââïž Â đđ»ââïž Â â
Jag hade ju stÀllt klockan... Men min mobil dog under natten... Ajja, here goes!
Edit 1: NÀr jag försöker lösa del 2 sÄ slÀngs det tydligen fel ibland, ugh. Börjar bli riktigt jobbiga uppgifter, mycket att lÀsa om man missar nÄgon kritisk liten detalj nÄgonstans.
Edit 2: Jag tror jag förstÄr problemet med vÀldigt stora tal... Men jag vet inte riktigt hur jag ska lösa det.
Edit 3: Ger snart upp, men jag förstÄr att man mÄste kasta en trollformel pÄ tal nÄgonstans.
CPU: 7950X | RAM: 32GB | GPU: 3090 w/ AlphaCool Eisblock Aurora
Ljudkort: Modius + Magnius | Lurar: GoldPlanar GL2000 / Sennheiser HD 650 / Philips Fidelio X3
Dag: 11
SprÄk: Python
Dagens lÀrdom: det var inte samma primfaktorer i exemplet och i min personliga input...
from math import prod
input = [[l.split(": ")[1] for l in m.split('\n')[1:]]
for m in open("input11").read().split('\n\n')]
monkeys = [[int(l.split()[-1]) if i else eval(f"lambda old:{l[6:]}")
for i, l in enumerate(m[1:])]
for m in input]
for n, f in [(20, lambda x: x // 3),
(10000, lambda x: x % prod([m[1] for m in monkeys]))]:
state = [[0, list(map(int, m[0].split(", ")))] for m in input]
for _ in range(n):
for i, m in enumerate(monkeys):
while state[i][1]:
state[i][0] += 1
nw = f(m[0](state[i][1].pop(0)))
state[m[2 + (nw % m[1] != 0)]][1].append(nw)
print(prod(sorted([s[0] for s in state])[-2:]))
Dag 9
SprÄk: C#
En hemsk lösning med mycket kod pÄ ett problem som jag hade svÄrt att lösa och ens förstÄ hur dom ville att repet skulle röra sig, jag tyckte min rörelse var mner logisk! Men det gick till slut, huva.
String[] data = File.ReadAllLines("Day9.txt");
bool[,] visited = new bool[1000, 1000];
bool[,] visited2 = new bool[1000, 1000];
int[] head = { 500, 500 };
int[] tail = { 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, };
int step1 = 0;
int step2 = 0;
visited[tail[0], tail[1]] = true;
visited2[tail[16], tail[17]] = true;
for (int i = 0; i < data.Length; i++)
{
string[] check = data[i].Split(" ");
for (int j = 0; j < int.Parse(check[1]); j++)
{
if (check[0] == "U")
{
head[0] = head[0] - 1;
if (head[0] < tail[0] - 1)
{
tail[0] = tail[0] - 1;
if (tail[1] != head[1])
{
if (tail[1] < head[1]) tail[1]++;
else tail[1]--;
}
}
}
if (check[0] == "R")
{
head[1] = head[1] + 1;
if (head[1] > tail[1] + 1)
{
tail[1] = tail[1] + 1;
if (tail[0] != head[0])
{
if (head[0] > tail[0]) tail[0]++;
else tail[0]--;
}
}
}
if (check[0] == "D")
{
head[0] = head[0] + 1;
if (head[0] > tail[0] + 1)
{
tail[0] = tail[0] + 1;
if (tail[1] != head[1])
{
if (tail[1] < head[1]) tail[1]++;
else tail[1]--;
}
}
}
if (check[0] == "L")
{
head[1] = head[1] - 1;
if (head[1] < tail[1] - 1)
{
tail[1] = tail[1] - 1;
if (tail[0] != head[0])
{
if (tail[0] < head[0]) tail[0]++;
else tail[0]--;
}
}
}
visited[tail[0], tail[1]] = true;
for (int k = 2; k < 18; k = k + 2)
{
if (tail[k - 2] < tail[k] - 1)
{
tail[k] = tail[k] - 1;
if (tail[k + 1] != tail[k - 1])
{
if (Math.Abs(tail[k + 1] - tail[k - 1]) > 2) tail[k + 1] = tail[k - 1];
else if (tail[k + 1] < tail[k - 1]) tail[k + 1]++;
else tail[k + 1]--;
}
}
if (tail[k - 1] > tail[k + 1] + 1)
{
tail[k + 1] = tail[k + 1] + 1;
if (tail[k] != tail[k - 2])
{
if (Math.Abs(tail[k] - tail[k - 2]) > 2) tail[k] = tail[k - 2];
else if (tail[k] < tail[k - 2]) tail[k]++;
else tail[k]--;
}
}
if (tail[k - 2] > tail[k] + 1)
{
tail[k] = tail[k] + 1;
if (tail[k + 1] != tail[k - 1])
{
if (Math.Abs(tail[k + 1] - tail[k - 1]) > 2) tail[k + 1] = tail[k - 1];
else if (tail[k + 1] < tail[k - 1]) tail[k + 1]++;
else tail[k + 1]--;
}
}
if (tail[k - 1] < tail[k + 1] - 1)
{
tail[k + 1] = tail[k + 1] - 1;
if (tail[k] != tail[k - 2])
{
if (Math.Abs(tail[k] - tail[k - 2]) > 2) tail[k] = tail[k - 2];
else if (tail[k] < tail[k - 2]) tail[k]++;
else tail[k]--;
}
}
}
visited2[tail[16], tail[17]] = true;
}
}
for (int i = 0; i < visited.GetLength(0); i++)
{
for (int j = 0; j < visited.GetLength(0); j++)
{
if (visited[i, j] == true) step1 = step1 + 1;
if (visited2[i, j] == true) step2 = step2 + 1;
}
}
Console.WriteLine();
Console.WriteLine("Day9");
Console.WriteLine("Step1 " + step1 + " Step2 " + step2);
+
Dag: 11
SprÄk: C#
Kommentar: Fyfan. Behövdes alldeles för mycket hjÀrngympa innan jag kom pÄ hur man tar itu med alla nummer. Skiter fullstÀndigt i hur koden ser ut, den gav mig rÀtt svar...
Kod
using System.Diagnostics;
using System.Numerics;
using AoCUtils;
Console.WriteLine("Mickur's Advent of Code 2022 - Day 11!");
// Setup
var input = File.ReadAllLines("input.txt");
var monkeyList = new List<Monkey>();
var sw = new Stopwatch();
sw.Start();
// Parse Monkeys
for (var i = 0; i < input.Length; i++)
{
// If it starts with an M, it's a new monkey
if (input[i][0] == 'M')
{
var monkey = new Monkey();
// Parse items
var itemsString = input[i + 1].AsSpan(18).ToString();
var items = itemsString.Split(", ");
for (var j = 0; j < items.Length; j++)
{
monkey.Items.Enqueue(ulong.Parse(items[j]));
}
// Parse operation
var operation = input[i + 2][23];
var operationValue = input[i + 2].AsSpan(25).ToString();
monkey.Operation = (operation, operationValue);
// Parse test
monkey.TestDivision = ulong.Parse(input[i + 3].AsSpan(21));
monkey.TestTargets = (AoCParsing.FastIntParse(input[i + 4].AsSpan(29)) , AoCParsing.FastIntParse(input[i + 5].AsSpan(30)));
monkeyList.Add(monkey);
i += 6;
}
}
// Rounds
for (var i = 0; i < 10000; i++)
{
// Monkeys
for (var j = 0; j < monkeyList.Count; j++)
{
// Get product of all division tests
ulong testsProduct = 1;
for (int k = 0; k < monkeyList.Count; k++)
{
testsProduct *= monkeyList[k].TestDivision;
}
// Items
while (monkeyList[j].Items.Count != 0)
{
var item = monkeyList[j].Inspect(testsProduct);
monkeyList[item.Item2].Items.Enqueue(item.Item1);
}
}
if (i == 0 || i == 19 || i == 999 || i == 9999)
{
Console.WriteLine($"== After round {i + 1} ==");
for (var j = 0; j < monkeyList.Count; j++)
{
Console.WriteLine($"Monkey {j} inspected items {monkeyList[j].activity} times.");
}
}
}
sw.Stop();
Console.WriteLine($"Finished in {sw.ElapsedMilliseconds} ms ({sw.ElapsedTicks} ticks)");
monkeyList.Sort(delegate(Monkey m1, Monkey m2)
{
if (m1.activity < m2.activity)
return 1;
if (m1.activity > m2.activity)
return -1;
return 0;
});
ulong answerA = monkeyList[0].activity * monkeyList[1].activity;
Console.WriteLine(answerA);
class Monkey
{
public Queue<ulong> Items = new ();
public (char, string) Operation = new();
public ulong TestDivision = 0;
public (int, int) TestTargets = new();
public ulong activity = 0;
public (ulong, int) Inspect(ulong divideBy = 0)
{
if (Items.Count == 0)
Console.WriteLine("UH OH");
activity++;
var item = Items.Dequeue();
switch (Operation.Item1)
{
case '+':
item += Operation.Item2 == "old" ? item : ulong.Parse(Operation.Item2);
break;
case '*':
item *= Operation.Item2 == "old" ? item : ulong.Parse(Operation.Item2);
break;
}
if (divideBy > 0)
{
item %= divideBy;
}
else
{
item /= 3;
}
return item % TestDivision == 0 ? (item, TestTargets.Item1) : (item, TestTargets.Item2);
}
}
Benchmark (inte nödvÀndigtvis samma kod som ovan)
BenchmarkDotNet=v0.13.2, OS=Windows 11 (10.0.22621.900)
AMD Ryzen 9 7950X, 1 CPU, 32 logical and 16 physical cores
.NET SDK=7.0.100
[Host] : .NET 7.0.0 (7.0.22.51805), X64 RyuJIT AVX2
.NET 7.0 : .NET 7.0.0 (7.0.22.51805), X64 RyuJIT AVX2
Job=.NET 7.0 Runtime=.NET 7.0
| Method | Mean | Error | StdDev | Gen0 | Allocated |
|------------- |-------------:|-----------:|-----------:|-------:|----------:|
| SolvePartOne | 26.46 us | 0.092 us | 0.086 us | 0.3662 | 6.46 KB |
| SolvePartTwo | 12,753.91 us | 213.036 us | 199.274 us | - | 6.7 KB |
// * Hints *
Outliers
Benchmarker.SolvePartTwo: .NET 7.0 -> 2 outliers were detected (12.37 ms, 12.38 ms)
// * Legends *
Mean : Arithmetic mean of all measurements
Error : Half of 99.9% confidence interval
StdDev : Standard deviation of all measurements
Gen0 : GC Generation 0 collects per 1000 operations
Allocated : Allocated memory per single operation (managed only, inclusive, 1KB = 1024B)
1 us : 1 Microsecond (0.000001 sec)
CPU: 7950X | RAM: 32GB | GPU: 3090 w/ AlphaCool Eisblock Aurora
Ljudkort: Modius + Magnius | Lurar: GoldPlanar GL2000 / Sennheiser HD 650 / Philips Fidelio X3
Dag 11
SprÄk: Rust
use std::collections::VecDeque;
#[derive(Debug)]
struct Monkey {
items: VecDeque<u64>,
op: (Op, Val),
test: u64,
if_true: usize,
if_false: usize,
num_inspects: usize,
}
#[derive(Debug)]
enum Op {
Add,
Mul,
}
#[derive(Debug)]
enum Val {
Val(u64),
Old,
}
fn parse(input: &str) -> Vec<Monkey> {
let mut monkeys = vec![];
for line in input.lines() {
let mut parts = line.trim().split_whitespace();
match parts.next() {
Some("Monkey") => {
monkeys.push(Monkey {
items: VecDeque::new(),
op: (Op::Add, Val::Val(0)),
test: 0,
if_true: 0,
if_false: 0,
num_inspects: 0,
});
},
Some("Starting") => {
parts.next();
monkeys.last_mut().unwrap().items = parts.map(|s| s.replace(",", "").parse().expect("item to be a number")).collect();
},
Some("Operation:") => {
parts.next();
parts.next();
parts.next();
let op = match parts.next() {
Some("+") => Op::Add,
Some("*") => Op::Mul,
_ => panic!("Unknown operation: {}", line),
};
let val = match parts.next() {
Some("old") => Val::Old,
Some(val) => Val::Val(val.parse().expect("val to be a number")),
_ => panic!("missing value: {}", line),
};
monkeys.last_mut().unwrap().op = (op, val);
},
Some("Test:") => {
parts.next();
parts.next();
monkeys.last_mut().unwrap().test = parts.next().unwrap().parse().expect("test to be a number");
},
Some("If") => match parts.next() {
Some("true:") => {
parts.next();
parts.next();
parts.next();
monkeys.last_mut().unwrap().if_true = parts.next().unwrap().parse().expect("monkey to be a number");
},
Some("false:") => {
parts.next();
parts.next();
parts.next();
monkeys.last_mut().unwrap().if_false = parts.next().unwrap().parse().expect("monkey to be a number");
},
_ => panic!("Unknown line: {}", line),
},
None => {},
_ => panic!("Unknown line: {}", line),
}
}
monkeys
}
fn round(monkeys: &mut Vec<Monkey>, calm_down: Option<u64>, reduce: Option<u64>) -> () {
for i in 0..monkeys.len() {
let monkey = &mut monkeys[i];
let mut items_to_throw = VecDeque::new();
while let Some(item) = monkey.items.pop_front() {
monkey.num_inspects += 1;
let val = match monkey.op.1 {
Val::Val(val) => val,
Val::Old => item,
};
let mut worry_level = match monkey.op.0 {
Op::Add => item + val,
Op::Mul => item * val,
};
if let Some(calm_down) = calm_down {
if worry_level > calm_down {
worry_level /= calm_down;
}
}
if let Some(reduce) = reduce {
if worry_level > reduce {
worry_level %= reduce;
}
}
let throw_to_monkey = if worry_level % monkey.test == 0 {
monkey.if_true
} else {
monkey.if_false
};
items_to_throw.push_back((worry_level, throw_to_monkey));
}
while let Some((item, monkey)) = items_to_throw.pop_front() {
monkeys[monkey].items.push_back(item);
}
}
}
pub fn one() {
let input = include_str!("input1.txt");
let mut monkeys = parse(input);
println!("Round 0: {:?}", monkeys);
for i in 1..=20 {
round(&mut monkeys, Some(3), None);
println!("Round {i}: {:?}", monkeys);
}
monkeys.sort_by_key(|m| m.num_inspects);
monkeys.reverse();
let result = monkeys[0].num_inspects * monkeys[1].num_inspects;
println!("Day 11, part 1: {}", result);
}
pub fn two() {
let input = include_str!("input1.txt");
let mut monkeys = parse(input);
let test_product = monkeys.iter().map(|m| m.test).product();
println!("test_product = {}", test_product);
for _ in 1..=10000 {
round(&mut monkeys, None, Some(test_product));
}
monkeys.sort_by_key(|m| m.num_inspects);
monkeys.reverse();
let result = monkeys[0].num_inspects * monkeys[1].num_inspects;
println!("Day 11, part 2: {:?}", result);
}
Dag: 11
SprÄk: Go
package main
import (
"encoding/csv"
"fmt"
"strconv"
"strings"
)
type WorryLevel uint64
type Items []WorryLevel
type WorryLevelAdjustment func(WorryLevel) WorryLevel
type Monkey struct {
items Items
inspect WorryLevelAdjustment
divisor WorryLevel
recipients [2]int
inspections WorryLevel
}
type Monkeys []Monkey
// Item receiver functions
func (items Items) empty() bool {
return len(items) == 0
}
func (items *Items) enqueue(item WorryLevel) {
*items = append(*items, item)
}
func (items *Items) dequeue() WorryLevel {
first := (*items)[0]
*items = (*items)[1:]
return first
}
// Monkeys receiver functions
func (monkeys *Monkeys) doRound(reliefValue WorryLevel) {
for m := 0; m < len(*monkeys); m++ {
monkey := &(*monkeys)[m]
for !monkey.items.empty() {
newWorryLevel := monkey.inspect(monkey.items.dequeue())
if reliefValue == 3 {
newWorryLevel /= reliefValue
} else {
newWorryLevel %= reliefValue
}
recipient := monkey.recipients[1]
if newWorryLevel%monkey.divisor == 0 {
recipient = monkey.recipients[0]
}
(*monkeys)[recipient].items.enqueue(newWorryLevel)
monkey.inspections++
}
}
}
func (monkeys *Monkeys) doNRounds(n int, reliefDivisor WorryLevel) {
for round := 0; round < n; round++ {
monkeys.doRound(reliefDivisor)
}
}
func (monkeys Monkeys) clone() Monkeys {
clones := Monkeys{}
for _, m := range monkeys {
clone := m
m.items = append(Items{}, m.items...)
clones = append(clones, clone)
}
return clones
}
// Functions
func monkeyBusinessAfter(monkeys Monkeys, rounds int, reliefDivisor WorryLevel) WorryLevel {
monkeys.doNRounds(rounds, reliefDivisor)
return monkeyBusiness(monkeys)
}
func monkeyBusiness(monkeys Monkeys) WorryLevel {
wls := [2]WorryLevel{}
for _, monkey := range monkeys {
if wls[0] < monkey.inspections {
wls[1] = wls[0]
wls[0] = monkey.inspections
} else if wls[1] < monkey.inspections {
wls[1] = monkey.inspections
}
}
return wls[0] * wls[1]
}
func reliefValue(monkeys Monkeys) WorryLevel {
rd := WorryLevel(1)
for _, monkey := range monkeys {
rd *= monkey.divisor
}
return rd
}
func day11(input []string) {
monkeys := parseMonkeys(input)
fmt.Println(monkeyBusinessAfter(monkeys.clone(), 20, 3))
fmt.Println(monkeyBusinessAfter(monkeys, 10000, reliefValue(monkeys)))
}
func init() {
Solutions[11] = day11
}
// Parsing of input
func parseWorryLevel(s string) WorryLevel {
if wl, err := strconv.Atoi(s); err == nil {
return WorryLevel(wl)
} else {
panic("Failed to parse worry level")
}
}
func parseMonkeyItems(line string) Items {
items := Items{}
parts := strings.Split(line, ": ")
r := csv.NewReader(strings.NewReader(parts[1]))
r.TrimLeadingSpace = true
record, err := r.Read()
if err != nil {
panic("Failed to parse monkey items")
}
for _, worryLevel := range record {
items.enqueue(parseWorryLevel(worryLevel))
}
return items
}
func parseWorryLevelAdjustment(line string) WorryLevelAdjustment {
parts := strings.Fields(line)
secondArg := parts[5]
if secondArg == "old" {
return func(old WorryLevel) WorryLevel { return old * old }
}
arg := parseWorryLevel(secondArg)
operator := parts[4]
if operator == "*" {
return func(old WorryLevel) WorryLevel { return old * arg }
}
return func(old WorryLevel) WorryLevel { return old + arg }
}
func parseDivisor(line string) WorryLevel {
return parseWorryLevel(strings.Fields(line)[3])
}
func parseRecipient(line string) int {
return int(parseWorryLevel(strings.Fields(line)[5]))
}
func parseMonkey(input []string, row *int) Monkey {
monkey := Monkey{}
monkey.items = parseMonkeyItems(input[*row+1])
monkey.inspect = parseWorryLevelAdjustment(input[*row+2])
monkey.divisor = parseDivisor(input[*row+3])
monkey.recipients[0] = parseRecipient(input[*row+4])
monkey.recipients[1] = parseRecipient(input[*row+5])
*row += 7
return monkey
}
func parseMonkeys(input []string) Monkeys {
monkeys := Monkeys{}
row := 0
for row < len(input) {
monkeys = append(monkeys, parseMonkey(input, &row))
}
return monkeys
}
LÀste del 2 femtielva gÄnger för att försöka hitta beskrivningen pÄ vad "dividera med 3" skulle ersÀttas med.
NÀr jag övertygat mig sjÀlv om att det inte fanns nÄgot "fÀrdigt recept" blev nÀsta steg att plocka ut stickprov av exemplen och börja testa vad som gav rÀtt svar.
Enda egentligen konkreta hint:en Àr att alla tal i "Test: divisible by ..." Àr primtal
Inte en favorit-dag. Speciellt inte nÀr parsning tar en hyfsat stor del av lösningen, vill alltid kunna resonera om koden och tycker det Àr betydligt lÀttare om man stoppar in saker i namngivna strukturer.
func BenchmarkDay11_parsing(b *testing.B) {
input := inputAsString(11)
for n := 0; n < b.N; n++ {
parseMonkeys(input)
}
}
func BenchmarkDay11_part1(b *testing.B) {
monkeys := parseMonkeys(inputAsString(11))
for n := 0; n < b.N; n++ {
monkeyBusinessAfter(monkeys.clone(), 20, 3)
}
}
func BenchmarkDay11_part2(b *testing.B) {
monkeys := parseMonkeys(inputAsString(11))
for n := 0; n < b.N; n++ {
monkeyBusinessAfter(monkeys.clone(), 10000, reliefValue(monkeys))
}
}
M1 MacMini
goos: darwin
goarch: arm64
pkg: aoc2022
BenchmarkDay11_parsing-8 129234 9394 ns/op 41232 B/op 178 allocs/op
BenchmarkDay11_part1-8 94996 12582 ns/op 27352 B/op 280 allocs/op
BenchmarkDay11_part2-8 138 8665079 ns/op 11092312 B/op 161090 allocs/op
PASS
ok aoc2022 5.920s
Care About Your Craft: Why spend your life developing software unless you care about doing it well? - The Pragmatic Programmer
Dag: 11
SprÄk: C#
Steg ett gick ju hyfsat enkelt. Men steg tvÄ fastnade jag ordentligt. Jag förstod att det blev alldeles för stora tal och pÄ nÄgot sÀtt behövde talen minskas. Iom man bara kollar delbarhet sÄ förstod jag att man borde kunde minska de pÄ nÄgot sÀtt, men kom inte fram till riktigt hur. Fick ta till mig lite tips och lösningen blev att multiplicera alla apors "divide by" för att fÄ fram en gemensam nÀmnare som man anvÀnde för att minska talen. Logiskt nu i efterhand men hade nog haft svÄrt att komma pÄ det sjÀlv tyvÀrr.
using System.Text.RegularExpressions;
namespace AOC2022.Puzzles;
internal partial class Puzzle11 : Puzzle<long, long>
{
[GeneratedRegex(@Monkey (\d+):)] private static partial Regex MonkeyRegex();
[GeneratedRegex(@(\*|\+{1}))] private static partial Regex OperationRegex();
record Monkey(int Id, List<long> Items, Func<long, long> Operation, int DivisibleBy, int TrueMonkey, int FalseMonkey)
{
public int Inspection = 0;
public IEnumerable<(int MonkeyId, long Item)> MakeTurn(decimal worryRelief, int superModulo)
{
foreach (var item in Items)
{
Inspection++;
var newWorryLevel = (long) Math.Floor(Operation(item) / worryRelief) % superModulo;
yield return (newWorryLevel % DivisibleBy == 0 ? TrueMonkey : FalseMonkey, newWorryLevel);
}
Items.Clear();
}
}
protected override void Solve(string[] lines)
{
One = RunMonkeys(lines, 20);
Two = RunMonkeys(lines, 10000);
}
private static long RunMonkeys(string[] lines, int rounds)
{
var monkeys = lines
.Select((x, i) => x.StartsWith("Monkey") ? i : -1)
.Where(x => x >= 0)
.Select(x =>
{
var monkeyId = int.Parse(MonkeyRegex().Match(lines[x]).Groups[1].Value);
var startingItems = lines[x + 1].Split(": ")[1].Split(',', StringSplitOptions.TrimEntries).Select(long.Parse);
var operation = ParseOperation(lines[x + 2].Split("= ")[1]);
var divisibleBy = int.Parse(lines[x + 3].Split(" ")[^1]);
var trueMonkey = int.Parse(lines[x + 4].Split(" ")[^1]);
var falseMonkey = int.Parse(lines[x + 5].Split(" ")[^1]);
return new Monkey(monkeyId, startingItems.ToList(), operation, divisibleBy, trueMonkey, falseMonkey);
})
.ToDictionary(x => x.Id);
var superModulo = monkeys.Values.Aggregate(1, (current, monkey) => current * monkey.DivisibleBy);
foreach (var (monkeyId, item) in Enumerable.Range(1, rounds)
.SelectMany(x => monkeys.Values)
.SelectMany(x => x.MakeTurn(rounds == 20 ? 3 : 1, superModulo)))
{
monkeys[monkeyId].Items.Add(item);
}
return monkeys.Values.OrderByDescending(x => x.Inspection)
.Take(2).Aggregate(1L, (a, b) => a * b.Inspection);
}
private static Func<long, long> ParseOperation(string op)
{
var test = OperationRegex().Split(op).Select(x => x.Trim()).ToList();
var useMultiply = test[1] == "*";
return worryLevel =>
{
var parts = test
.Where((x, i) => i != 1)
.Select(x =>x switch
{
"old" => worryLevel,
_ => long.Parse(x)
})
.ToList();
return useMultiply ? parts[0] * parts[1] : parts[0] + parts[1];
};
}
}
Dag: 11
SprÄk: Go
Fru och barn har magsjuka, sÄ det var lite svÄrt att fÄ tid att fokusera.
MÄnga slice operationer stÄr sÀkert för majoriteten av tiden, fÄr se ifall jag fÄr tid och göra nÄgot Ät det. Edit, en empty slice pÄ slutet var lite bÀttre Àn att ta bort en i taget.
pkg: aoc2022/11/a
cpu: Intel(R) Core(TM) i7-7920HQ CPU @ 3.10GHz
BenchmarkPartOne-8 56419 20990 ns/op
BenchmarkPartTwo-8 67 17174562 ns/op
package main
import (
"bufio"
"fmt"
"os"
"sort"
"strconv"
"strings"
)
type Monkey struct {
StartItems []int
Operation func(a int, b int) int // new = old * 19
OpValB int
TestDivideByVal int
TestTrueMonkey int
TestFalseMonkey int
InspectCount int
}
func mul(old int, b int) int { return old * b }
func mulOld(old int, b int) int { return old * old }
func add(old int, b int) int { return old + b }
func addOld(old int, b int) int { return old + old }
func calcTopTwoMonkeyInspections(monkeys []Monkey, rounds int, reduceFactor int) int {
for c := 0; c < rounds; c++ {
for i, m := range monkeys {
for _, val := range monkeys[i].StartItems {
worryLevel := monkeys[i].Operation(val, m.OpValB)
if reduceFactor == 3 {
worryLevel /= reduceFactor
} else {
worryLevel %= reduceFactor
}
dstMonkey := 0
if worryLevel%m.TestDivideByVal == 0 {
dstMonkey = m.TestTrueMonkey
} else {
dstMonkey = m.TestFalseMonkey
}
monkeys[dstMonkey].StartItems = append(monkeys[dstMonkey].StartItems, worryLevel)
monkeys[i].InspectCount++
}
monkeys[i].StartItems = monkeys[i].StartItems[:0] // empty slice
}
}
inspectCounts := make([]int, len(monkeys))
for _, m := range monkeys {
inspectCounts = append(inspectCounts, m.InspectCount)
}
sort.Sort(sort.Reverse(sort.IntSlice(inspectCounts)))
return inspectCounts[0] * inspectCounts[1]
}
func getPartOne(monkeys []Monkey) int {
return calcTopTwoMonkeyInspections(monkeys, 20, 3)
}
func getPartTwo(monkeys []Monkey) int {
product := 1
for _, m := range monkeys {
product *= m.TestDivideByVal
}
return calcTopTwoMonkeyInspections(monkeys, 10000, product)
}
func getRows(filename string) []Monkey {
file, err := os.Open(filename)
if err != nil {
panic(err)
}
defer file.Close()
scanner := bufio.NewScanner(file)
monkeys := make([]Monkey, 0)
monkeyId := 0
for scanner.Scan() {
row := scanner.Text()
if strings.Contains(row, "Monkey") {
fmt.Sscanf(row, "Monkey %d:",
&monkeyId)
m := Monkey{}
monkeys = append(monkeys, m)
} else if strings.Contains(row, "Starting items:") {
numberPart := strings.Split(row, ":")[1]
numbers := strings.Split(numberPart, ",")
for _, num := range numbers {
val, err := strconv.Atoi(strings.TrimSpace(num))
if err != nil {
panic(err)
}
monkeys[monkeyId].StartItems = append(monkeys[monkeyId].StartItems, val)
}
} else if strings.Contains(row, "Operation:") {
formulaPart := strings.Split(row, ":")[1]
var f func(a int, b int) int
if strings.Contains(formulaPart, "new = old + old") {
f = addOld
} else if strings.Contains(formulaPart, "new = old * old") {
f = mulOld
} else if strings.Contains(formulaPart, "new = old * ") {
f = mul
num := strings.Replace(formulaPart, "new = old *", "", 1)
val, err := strconv.Atoi(strings.TrimSpace(num))
if err != nil {
panic(err)
}
monkeys[monkeyId].OpValB = val
} else if strings.Contains(formulaPart, "new = old + ") {
f = add
num := strings.Replace(formulaPart, "new = old +", "", 1)
val, err := strconv.Atoi(strings.TrimSpace(num))
if err != nil {
panic(err)
}
monkeys[monkeyId].OpValB = val
}
monkeys[monkeyId].Operation = f
} else if strings.Contains(row, "Test: divisible by ") {
fmt.Sscanf(row, " Test: divisible by %d", &monkeys[monkeyId].TestDivideByVal)
} else if strings.Contains(row, "If true: throw to monkey") {
fmt.Sscanf(row, " If true: throw to monkey %d", &monkeys[monkeyId].TestTrueMonkey)
} else if strings.Contains(row, "If false: throw to monkey") {
fmt.Sscanf(row, " If false: throw to monkey %d", &monkeys[monkeyId].TestFalseMonkey)
}
}
return monkeys
}
func main() {
fmt.Println("Part one:", getPartOne(getRows("../input.txt")))
fmt.Println("Part two:", getPartTwo(getRows("../input.txt")))
}
- Ubiquiti Unifi4,1k
- Unifi/Ubiquiti UAP-AC-PRO17
- Hur flytta backup pÄ ett sÀkert sÀtt?31
- Vad har ni i lön?14k
- Realtek gör 10 Gbit Ethernet billigt136
- In ear hörlurar dÀr man hör sig sjÀlv?0
- Nu fÄr Meta trÀna AI med dina Facebook-inlÀgg24
- Ăvriga Fynd â DiskussionstrĂ„d2,4k
- Dagens fynd â DiskussionstrĂ„den54k
- Home Assistant-trÄden1,2k
- SĂ€ljes Lenovo Legion
- SĂ€ljes ASUS GeForce RTX 3070 ROG STRIX White Edition
- SĂ€ljes RTX 5060 Ti 16gb - Samsung 32â 4k/165hz Mini Led
- SĂ€ljes Gainward RTX 4070 Panther 12GB
- SĂ€ljes Gigabyte Geforce RTX 3070 8GB GAMING OC
- SkÀnkes iiglo MM200 skÀrmstativ
- SĂ€ljes 2st Kingston FURY Beast RGB 64GB DDR5 RAM 5600MT/s CL36 (svart)
- SĂ€ljes rog falchion rx low profile
- SĂ€ljes 28" Samsung U28R55 - 3840x2160 (4k / UHD) - IPS - HDR10
- SĂ€ljes Logitech Mx Master 3S + Mx Keys Wireless
- Radeon RX 9060 XT-mÀtresultat lÀckta3
- Nu fÄr Meta trÀna AI med dina Facebook-inlÀgg24
- Veckans frÄga: Vad gör du med gamla komponenter?54
- Asrock förklarar trasiga Ryzen-processorer18
- AMD fasar ut styrkretsen B65018
- Klarna vill bryta sig loss frÄn BankID79
- Ultran visar upp extrem lagring i ett instickskort12
- Steam OS gör Legion Go betydligt snabbare58
- Intel kan slÀppa B770 i Är13
- MSI:s sÀkra strömkabel har brÀnts igen98
Externa nyheter
Spelnyheter frÄn FZ