# Advent of Code 2021 - Day 4

Maybe it wants to play bingo?

## Day 4a

``````const is = (x: any) => x !== '' && x !== null && x !== undefined
const parse10 = (s: string) => parseInt(s, 10)
const clean = (s: string) => s.trim().replace(/^[^\S\n]+/gm, '')
const paragraphs = (s: string) => clean(s).split(/\n{2,}/)
const ints = (s: string) => clean(s).split(/\D+/).map(parse10)
const max = (ns: number[]) => Math.max.apply(null, ns)
const min = (ns: number[]) => Math.min.apply(null, ns)
const sum = (ns: number[]) => reduce(ns, (sum, n) => sum + n, 0)

const ranks = <T>(xs: T[], n: number): T[][] =>
R.times(Math.ceil(xs.length / n), i => xs.slice(n * i, n * (i + 1)))

const files = <T>(xs: T[], n: number): T[][] =>
R.times(Math.ceil(xs.length / n), i =>
R.times(n, j => xs[i + j * n]).filter(is),
)
``````

And my solution:

``````const d4 = ({
input = inputs.d4,
dbg,
pick,
}: DayProps & {pick: typeof R.last}) => {
const {draws, boards} = R.pipe(paragraphs(input), ([ds, ...bs]) => ({
draws: ints(ds),
boards: bs.map(ints),
}))
const edge = Math.sqrt(boards[0].length)

// Reverse lookup from a drawn number to its position in line.
const order = reduce.indexed(
R.uniq(draws),
(order, draw, i) => ((order[draw] = i), order),
[] as number[],
)

// Boards sorted in the order they win.
const bingos = R.pipe(
boards,
R.map.indexed((board, num) => {
const rows = [...ranks(board, edge), ...files(board, edge)]
const orders = rows.map(r => r.map(draw => order[draw]))
const turn = min(orders.map(max))
return {board, num, rows, orders, turn}
}),
R.sort((a, b) => a.turn - b.turn),
)

// Pick the winning (or losing) board.
const winning = pick(bingos)

// Unmarked numbers are those that haven't been called by the winning.turn
const unmarked = sum(winning.board.filter(x => order[x] > winning.turn))

// Which number was called on the winning turn?
const winner = draws[winning.turn]

dbg({...R.pick(winning, ['num', 'turn']), unmarked, winner})
return `Final score: \${unmarked * winner}`
}

export const d4a = (props: DayProps) => d4({...props, pick: R.first})
``````

Sample output:

My output:

## Day 4b

Got lucky here with my implementation for the first part:

``````export const d4b = (props: DayProps) => d4({...props, pick: R.last})
``````

Sample output:

My output: