day14+15
This commit is contained in:
parent
083e0bbe32
commit
68938c4eed
|
|
@ -0,0 +1,38 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace AoCCSharp
|
||||||
|
{
|
||||||
|
internal class Day15 {
|
||||||
|
|
||||||
|
internal void Solve() {
|
||||||
|
string input = "0,8,15,2,12,1,4";
|
||||||
|
int numberAt2020 = 30000000;
|
||||||
|
|
||||||
|
var numbers = input.Split(",").Select(int.Parse).ToList();
|
||||||
|
Dictionary<int, int> numberAge = numbers
|
||||||
|
.Select((n, i) => (n, i))
|
||||||
|
.ToDictionary(tuple => tuple.n, tuple => tuple.i);
|
||||||
|
|
||||||
|
int currentNumber = 0; // initial numbers are unique
|
||||||
|
int nextNumber;
|
||||||
|
int count = numbers.Count;
|
||||||
|
do {
|
||||||
|
if (numberAge.ContainsKey(currentNumber)) {
|
||||||
|
nextNumber = count - numberAge[currentNumber];
|
||||||
|
numberAge[currentNumber] = count;
|
||||||
|
} else {
|
||||||
|
nextNumber = 0;
|
||||||
|
numberAge[currentNumber] = count;
|
||||||
|
}
|
||||||
|
count += 1;
|
||||||
|
if (count < numberAt2020) {
|
||||||
|
currentNumber = nextNumber;
|
||||||
|
}
|
||||||
|
} while (count < numberAt2020);
|
||||||
|
|
||||||
|
Console.WriteLine(currentNumber);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,103 @@
|
||||||
|
import { readFileSync } from 'fs';
|
||||||
|
|
||||||
|
const lines = readFileSync('day14/input').toString().split(/\r?\n/).filter(s => s != "");
|
||||||
|
|
||||||
|
type Mask = {
|
||||||
|
mask: string,
|
||||||
|
maskOne: bigint,
|
||||||
|
maskZero: bigint
|
||||||
|
}
|
||||||
|
|
||||||
|
type MemoryToChange = {
|
||||||
|
memPos: number,
|
||||||
|
newValue: bigint
|
||||||
|
}
|
||||||
|
|
||||||
|
type Memory = { [id: number] : bigint; }
|
||||||
|
|
||||||
|
let curMask: Mask;
|
||||||
|
|
||||||
|
const maskPrefix = "mask = ";
|
||||||
|
const maskX = /X/g;
|
||||||
|
|
||||||
|
const memRegex = new RegExp('mem\\[(?<mem>\\d+)\\] = (?<num>\\d+)');
|
||||||
|
let memoryPart1: Memory = {};
|
||||||
|
let memoryPart2: Memory = {};
|
||||||
|
|
||||||
|
const calculateMask = (line: string): Mask => {
|
||||||
|
const mask = line.substr(maskPrefix.length);
|
||||||
|
return {
|
||||||
|
mask,
|
||||||
|
maskOne: BigInt("0b" + mask.replace(maskX, '1')),
|
||||||
|
maskZero: BigInt("0b" + mask.replace(maskX, '0')),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const getMemory = (line: string): MemoryToChange => {
|
||||||
|
const match = memRegex.exec(line);
|
||||||
|
if (match == null || match.groups == undefined) {
|
||||||
|
throw new Error("regex could not find anything");
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
memPos: parseInt(match.groups['mem']),
|
||||||
|
newValue: BigInt(match.groups['num'])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const changeMemoryPart1 = (memory: Memory, mask: Mask, memoryToChange: MemoryToChange) => {
|
||||||
|
memory[memoryToChange.memPos] = mask.maskZero | (mask.maskOne & memoryToChange.newValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
const memoryPosCombinations = (memPosWithX: string, index: number): string[] => {
|
||||||
|
if (index > memPosWithX.length) {
|
||||||
|
return [""];
|
||||||
|
}
|
||||||
|
const partialMemPositions = memoryPosCombinations(memPosWithX, index + 1);
|
||||||
|
if (memPosWithX[index] != 'X') {
|
||||||
|
return partialMemPositions.map(partialMemPos => memPosWithX[index] + partialMemPos);
|
||||||
|
}
|
||||||
|
return partialMemPositions.map(partialMemPos => '0' + partialMemPos).concat(partialMemPositions.map(partialMemPos => '1' + partialMemPos));
|
||||||
|
}
|
||||||
|
|
||||||
|
const combineMaskAndMemPos = (memPosAsBinary: string): ((mask: string, i: number) => string) => {
|
||||||
|
return (mask, i) => {
|
||||||
|
if (mask == '0') {
|
||||||
|
return memPosAsBinary[i];
|
||||||
|
} else {
|
||||||
|
return mask
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const parseBinaryInt = (s: string): number => parseInt(s, 2);
|
||||||
|
|
||||||
|
const calculateMemoryPositions = (mask: string, memPos: number): number[] => {
|
||||||
|
const memPosAsBinary = memPos.toString(2).padStart(mask.length, "0");
|
||||||
|
const memPosWithMask = mask.split('').map(combineMaskAndMemPos(memPosAsBinary)).join('');
|
||||||
|
|
||||||
|
return memoryPosCombinations(memPosWithMask, 0).map(parseBinaryInt);
|
||||||
|
}
|
||||||
|
|
||||||
|
const changeMemoryPart2 = (memory: Memory, mask: Mask, memoryToChange: MemoryToChange) => {
|
||||||
|
calculateMemoryPositions(mask.mask, memoryToChange.memPos).forEach(pos => memory[pos] = memoryToChange.newValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
curMask = calculateMask(lines[0]);
|
||||||
|
for (const line of lines.slice(1)) {
|
||||||
|
if (line.startsWith(maskPrefix)) {
|
||||||
|
curMask = calculateMask(line);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const memoryToChange = getMemory(line);
|
||||||
|
|
||||||
|
changeMemoryPart1(memoryPart1, curMask, memoryToChange);
|
||||||
|
changeMemoryPart2(memoryPart2, curMask, memoryToChange);
|
||||||
|
}
|
||||||
|
|
||||||
|
const sumOfMemory1 = Object.values(memoryPart1).reduce(((previousValue, currentValue) => previousValue + currentValue), 0n);
|
||||||
|
const sumOfMemory2 = Object.values(memoryPart2).reduce(((previousValue, currentValue) => previousValue + currentValue), 0n);
|
||||||
|
|
||||||
|
console.log(sumOfMemory1);
|
||||||
|
console.log(sumOfMemory2);
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
const input = "0,8,15,2,12,1,4";
|
||||||
|
// const input = "3,1,2";
|
||||||
|
|
||||||
|
const numberAt2020 = 30000000;
|
||||||
|
|
||||||
|
// const numbers = input.split(',').map(parseInt); // does not work
|
||||||
|
const numbers = input.split(',').map(a => parseInt(a));
|
||||||
|
const numberAge = new Map<number, number>();
|
||||||
|
numbers.forEach((e, i) => numberAge.set(e, i));
|
||||||
|
|
||||||
|
let currentNumber = 0; // initial numbers are unique
|
||||||
|
let nextNumber: number;
|
||||||
|
let count = numbers.length;
|
||||||
|
|
||||||
|
do {
|
||||||
|
if (numberAge.has(currentNumber)) {
|
||||||
|
// @ts-ignore
|
||||||
|
nextNumber = count - numberAge.get(currentNumber);
|
||||||
|
numberAge.set(currentNumber, count);
|
||||||
|
} else {
|
||||||
|
nextNumber = 0;
|
||||||
|
numberAge.set(currentNumber, count);
|
||||||
|
}
|
||||||
|
count += 1;
|
||||||
|
if (count < numberAt2020) {
|
||||||
|
currentNumber = nextNumber;
|
||||||
|
}
|
||||||
|
} while (count < numberAt2020);
|
||||||
|
|
||||||
|
const endTime = new Date();
|
||||||
|
|
||||||
|
console.log(currentNumber);
|
||||||
Loading…
Reference in New Issue