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