Skip to content

Commit

Permalink
2018 16-19 tries
Browse files Browse the repository at this point in the history
  • Loading branch information
Kr0nox committed Sep 24, 2024
1 parent ba27a2f commit 6a64550
Show file tree
Hide file tree
Showing 8 changed files with 671 additions and 0 deletions.
29 changes: 29 additions & 0 deletions 2018/16/runner.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { readFile } from "fs/promises";
import { taskOne, taskTwo } from "./task";

async function main() {
let lastArgument = process.argv.pop() as string;
let taskNumber = 1;
let isTest = false;

if (lastArgument === "test") {
isTest = true;
taskNumber = parseInt(process.argv.pop() as string);
} else {
taskNumber = parseInt(lastArgument)
}

const fileToLoad = isTest ? "test.in" : "solve.in";
const fileContents = await readFile(fileToLoad, "utf-8")

const lines = fileContents.split("\n");

if (taskNumber === 1) {
await taskOne(lines);
}
if (taskNumber === 2) {
await taskTwo(lines);
}
}

void main();
170 changes: 170 additions & 0 deletions 2018/16/task.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
export async function taskOne(input: string[]): Promise<void> {
let i = 0;
const instructions: BeforeAfter[] = []
while(input[i].startsWith('Before')) {
instructions.push({
before: JSON.parse(input[i].substring(8)),
command: input[i+1].split(' ').map(Number),
after: JSON.parse(input[i+2].substring(8))
})
i += 4
}

console.log(instructions.map(i => getOptions(i).length).filter(i => i>=3).length)

}

export async function taskTwo(input: string[]): Promise<void> {
let i = 0;
const bfs: BeforeAfter[] = []
while(input[i].startsWith('Before')) {
bfs.push({
before: JSON.parse(input[i].substring(8)),
command: input[i+1].split(' ').map(Number),
after: JSON.parse(input[i+2].substring(8))
})
i += 4
}
const options: Record<number, string[]> = {}
for (let j = 0; j < 16; j++) {
options[j] = commands
}
for (const bf of bfs) {
const r = getOptions(bf)
options[bf.command[0]] = getIntersection(r, options[bf.command[0]])
}
const reverseOptions: Record<string, number[]> = {}
for (const c of commands) {
reverseOptions[c] = []
}
for (let j = 0; j < 16; j++) {
for (const c of options[j]) {
reverseOptions[c].push(j)
}
}
const finalMapping: Record<number, string> = {}
while(Object.keys(finalMapping).length != 16) {
let found = false
do {
found = false
for (const c of commands) {
if (reverseOptions[c].length == 1) {
finalMapping[reverseOptions[c][0]] = c
removeFromOldMapping(c, reverseOptions[c][0])
found = true
}
}
} while(found);
}

while(input[i].trim() == '') i++
let registers = [0,0,0,0]
while(i < input.length) {
const com = input[i].split(' ').map(Number)
registers = execute(registers, {
ins: finalMapping[com[0]],
a: com[1],
b: com[2],
c: com[3]
})
i++
}
console.log(registers[0])

function removeFromOldMapping(com: string, num: number) {
for (const c of commands) {
const idx = reverseOptions[c].indexOf(num)
if (idx != -1) {
reverseOptions[c].splice(idx, 1)
}
}
for (let j = 0; j < 16; j++) {
const idx = options[j].indexOf(com)
if (idx != -1) {
options[j].splice(idx, 1)
}
}
}
}

interface BeforeAfter {
before: number[]
command: number[]
after: number[]
}

interface Command {
ins: string,
a: number,
b: number,
c: number
}

const commands = ['addr', 'addi', 'mulr', 'muli', 'banr', 'bani', 'borr', 'bori', 'setr', 'seti',
'gtir', 'gtri', 'gtrr', 'eqir', 'eqri', 'eqrr']

function getOptions(bf: BeforeAfter) {
const results: string[] = []
for (const c of commands) {
const r = execute(bf.before, {ins: c, a: bf.command[1], b: bf.command[2], c: bf.command[3]})
let matches = true
for (let i = 0; i < r.length; i++) {
if (r[i] != bf.after[i]) {
matches = false
break
}
}
if (matches) results.push(c)
}
return results
}

function getIntersection(a: string[], b: string[]) {
return a.filter(i => b.indexOf(i) != -1)
}

function execute(input: number[], c: Command) {
const output = [input[0], input[1], input[2], input[3]]
function get(x: number, i: boolean) {
if (i) return x
return input[x]
}
if (c.ins.startsWith('gt') || c.ins.startsWith('eq')) {
const aI = c.ins[2] == 'i'
const bI = c.ins[3] == 'i'
const a = get(c.a, aI)
const b = get(c.b, bI)
let cond = false
if (c.ins.startsWith('gt')) {
cond = a > b
} else {
cond = a == b
}
output[c.c] = cond ? 1 : 0
} else if (c.ins.startsWith("set")) {
const isI = c.ins[3] == 'i'
const a = get(c.a, isI)
output[c.c] = a
} else {
const isI = c.ins[3] == 'i'
const a = get(c.a, false)
const b = get(c.b, isI)
let out = 0
switch(c.ins.substring(0,3)) {
case 'add':
out = a+b
break
case 'mul':
out = a*b
break;
case 'ban':
out = a&b
break
case 'bor':
out = a|b
break
}
output[c.c] = out
}
return output
}
29 changes: 29 additions & 0 deletions 2018/17/runner.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { readFile } from "fs/promises";
import { taskOne, taskTwo } from "./task";

async function main() {
let lastArgument = process.argv.pop() as string;
let taskNumber = 1;
let isTest = false;

if (lastArgument === "test") {
isTest = true;
taskNumber = parseInt(process.argv.pop() as string);
} else {
taskNumber = parseInt(lastArgument)
}

const fileToLoad = isTest ? "test.in" : "solve.in";
const fileContents = await readFile(fileToLoad, "utf-8")

const lines = fileContents.split("\n");

if (taskNumber === 1) {
await taskOne(lines);
}
if (taskNumber === 2) {
await taskTwo(lines);
}
}

void main();
133 changes: 133 additions & 0 deletions 2018/17/task.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
export async function taskOne(input: string[]): Promise<void> {
const ranges = parseInput(input)
let minX = 500
let minY = Infinity
let maxX = 500
let maxY = -Infinity
for (const r of ranges) {
if (r.x1 < minX) minX = r.x1
if (r.x2 > maxX) maxX = r.x2
if (r.y1 < minY) minY = r.y1
if (r.y2 > maxY) maxY = r.y2
}
maxX++
minX--
const grid = Array.from({length: maxX-minX+1}, () => Array.from({length: maxY-minY+1}, ()=>WaterState.NONE))
for (const r of ranges) {
for (let x = r.x1; x <= r.x2; x++) {
for (let y = r.y1; y <= r.y2; y++) {
grid[x-minX][y-minY] = WaterState.SAND
}
}
}
let curFlowSpots: {x:number,y:number}[] = [{x:500-minX, y:0}]
grid[500-minX][0] = WaterState.WATER
//print(grid)

while(curFlowSpots.length > 0) {
let newSpots: {x:number,y:number}[] = []
for (const spot of curFlowSpots) {
if (spot.y+1 >= grid[0].length) continue
if (grid[spot.x][spot.y+1] == WaterState.NONE) {
grid[spot.x][spot.y+1] = WaterState.WATER
newSpots.push({x: spot.x, y: spot.y+1})
} else {
let leftBlocked = false
let x1 = spot.x-1
let leftSand = false
while(x1 >= 0 && grid[x1][spot.y+1] != WaterState.NONE) {
if (grid[x1][spot.y] != WaterState.NONE) {
leftBlocked = true
break
} else if(grid[x1][spot.y+1] == WaterState.SAND) {
leftSand = true
}
x1--
}
if (!leftBlocked && leftSand) {
grid[x1][spot.y] = WaterState.WATER
newSpots.push({x:x1,y:spot.y})
}
let rightBlocked = false
let rightSand = false
let x2 = spot.x+1
while(x2 < grid.length && grid[x2][spot.y+1] != WaterState.NONE) {
if (grid[x2][spot.y] != WaterState.NONE) {
rightBlocked = true
break
} else if(grid[x2][spot.y+1] == WaterState.SAND) {
rightSand = true
}
x2++
}

if (!rightBlocked && rightSand) {
grid[x2][spot.y] = WaterState.WATER
newSpots.push({x:x2,y:spot.y})
}
if (!(!rightBlocked && rightSand) && !(!leftBlocked && leftSand)) {
newSpots.push({x:spot.x,y:spot.y-1})
}
if ((leftSand || leftBlocked) && (rightSand||rightBlocked)) {
for (let x = x1+1; x < x2; x++) {
grid[x][spot.y] = WaterState.WATER
}
}
}
}
curFlowSpots = newSpots
}
let count = 0

for (let x = 0; x < grid.length; x++) {
for (let y = 0; y < grid[x].length; y++) {
if (grid[x][y] == WaterState.WATER) count++
}
}
console.log(count)
}

export async function taskTwo(input: string[]): Promise<void> {
console.log("Unimplemented");
}

interface Range {
x1: number, x2: number, y1: number, y2: number
}

enum WaterState {
NONE, SAND, WATER
}

function parseInput(input: string[]) {
return input.map(i => {
const p = i.split(', ')
const r = {} as Range

const n = Number(p[0].split('=')[1])
const n2 = p[1].split('=')[1].split('..').map(Number)
if (p[0].startsWith('x')) {
r.x1 = n
r.x2 = n
r.y1 = n2[0]
r.y2 = n2[1]
} else {
r.y1 = n
r.y2 = n
r.x1 = n2[0]
r.x2 = n2[1]
}
return r
})
}

function print(grid: WaterState[][]) {
const p = Array.from({length: grid[0].length}, () => Array.from({length: grid.length}, () => ' '))
for (let x = 0; x < grid.length; x++) {
for (let y = 0; y < grid[x].length; y++) {
if (grid[x][y] == WaterState.WATER) p[y][x] = '~'
if (grid[x][y] == WaterState.SAND) p[y][x] = '#'
}
}
p.forEach(i => console.log(i.join('')))
}
29 changes: 29 additions & 0 deletions 2018/18/runner.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { readFile } from "fs/promises";
import { taskOne, taskTwo } from "./task";

async function main() {
let lastArgument = process.argv.pop() as string;
let taskNumber = 1;
let isTest = false;

if (lastArgument === "test") {
isTest = true;
taskNumber = parseInt(process.argv.pop() as string);
} else {
taskNumber = parseInt(lastArgument)
}

const fileToLoad = isTest ? "test.in" : "solve.in";
const fileContents = await readFile(fileToLoad, "utf-8")

const lines = fileContents.split("\n");

if (taskNumber === 1) {
await taskOne(lines);
}
if (taskNumber === 2) {
await taskTwo(lines);
}
}

void main();
Loading

0 comments on commit 6a64550

Please sign in to comment.