DEV Community

Discussion on: Advent of Code 2019 Solution Megathread - Day 8: Space Image Format

Collapse
 
nordfjord profile image
Einar Norðfjörð

Functional JS style today

const input = require('fs')
  .readFileSync(0)
  .toString()

const WIDTH = 25
const HEIGHT = 6
const layerSize = WIDTH * HEIGHT

const Id = x => ({
  value: x,
  map(fn) {
    return Id(fn(x))
  }
})

const splitEvery = n => list => {
  const result = []
  let idx = 0
  while (idx < list.length) {
    result.push(list.slice(idx, (idx += n)))
  }
  return result
}
const replace = regx => repl => str => str.replace(regx, repl)
const join = w => list => list.join(w)
const map = fn => list => list.map(fn)
const reduce = reducer => initial => list => list.reduce(reducer, initial)
const count = (x, str) => str.match(new RegExp(x, 'g')).length

function part1(input) {
  return Id(input)
    .map(splitEvery(layerSize))
    .map(
      map(x => ({
        0: count(0, x),
        1: count(1, x),
        2: count(2, x),
        x
      }))
    )
    .map(reduce((p, v) => (p[0] < v[0] ? p : v))({ 0: Infinity }))
    .map(l => l[1] * l[2]).value
}

function part2(input) {
  return Id(input)
    .map(splitEvery(layerSize))
    .map(layers =>
      Array.from({ length: layerSize }).map(
        (_, i) => layers.find(l => l[i] !== '2')[i]
      )
    )
    .map(join(''))
    .map(replace(/0/g)(' '))
    .map(replace(/1/g)('#'))
    .map(splitEvery(WIDTH))
    .map(join('\n')).value
}

console.log(part1(input))
console.log(part2(input))