-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathday_4.js
More file actions
140 lines (115 loc) · 4.25 KB
/
Copy pathday_4.js
File metadata and controls
140 lines (115 loc) · 4.25 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
const fs = require('fs')
const lineToArray = (line) => line.split(' ').filter(char => char)
const isBingoLine = (board, numbers) => {
const lineKeys = Object.keys(board)
let bingo = false
for (const lineKey of lineKeys) {
const isBingo = board[lineKey].every(num => numbers.includes(num))
if(isBingo) {
bingo = board[lineKey]
break
}
}
return bingo
}
const isBingoColumn = (board, numbers) => {
const lineKeys = Object.keys(board)
let bingo = false
for (let j=0; j<5; j++) {
let column = []
for (const lineKey of lineKeys) {
column.push(board[lineKey][j.toString()])
}
const isBingo = column.every(num => numbers.includes(num))
if (isBingo) {
bingo = column
break
}
}
return bingo
}
const isBoardBingo = (board, numbers) => isBingoLine(board, numbers) || isBingoColumn(board, numbers)
const splitBoards = (boards) => {
const splittedBoards = []
const filledBoards = boards.filter(l => l.length).map(l => l.trim())
for (let i=0; i<filledBoards.length; i+5) {
const arr = filledBoards.splice(i, i+5)
splittedBoards.push({...arr.map(line => lineToArray(line))})
}
return splittedBoards
}
const flattenBoard = (board) => Object.values(board).flat()
const sumOfUnmarkedNumbers = (details, numbersThrown, board) =>
board
.filter(number => ![...details, ...numbersThrown].includes(number))
.map((num) => parseInt(num, 10))
.reduce((acc, curr) => acc + curr)
const getFinalScore = (details, numbersThrown, board, lastFoundNumber) => sumOfUnmarkedNumbers(details, numbersThrown, board) * parseInt(lastFoundNumber)
//PART ONE
fs.readFile('./inputs/4.txt', 'utf-8', (err, response) => {
if (err) throw err
const [data, ...boards] = response.split('\n')
const numbersToThrow = data.split(',')
const splittedBoards = splitBoards(boards)
const boardKeys = (Object.keys(splittedBoards))
let numbersThrown = []
let winningBoard
let lastFoundNumber
let details
for (let i=0; i < numbersToThrow.length; i++) {
numbersThrown.push(numbersToThrow[i])
for (const boardKey of boardKeys) {
const bingo = isBoardBingo(splittedBoards[boardKey], numbersThrown)
if (bingo) {
details = isBingoLine(splittedBoards[boardKey], numbersThrown) || isBingoColumn(splittedBoards[boardKey], numbersThrown)
winningBoard = splittedBoards[boardKey]
lastFoundNumber = numbersToThrow[i]
break
}
}
if (winningBoard) {
break
}
}
const result = getFinalScore(
details,
numbersThrown,
flattenBoard(winningBoard),
lastFoundNumber
)
console.log(result)
})
//PART TWO
fs.readFile('./inputs/4.txt', 'utf-8', (err, response) => {
if (err) throw err
const [data, ...boards] = response.split('\n')
const numbersToThrow = data.split(',')
const splittedBoards = splitBoards(boards)
const boardKeys = (Object.keys(splittedBoards))
let numbersThrown = []
let winningBoards = []
let lastFoundNumber
let details
for (let i=0; i < numbersToThrow.length; i++) {
numbersThrown.push(numbersToThrow[i])
for (const boardKey of boardKeys) {
const bingo = isBoardBingo(splittedBoards[boardKey], numbersThrown)
const hasAlreadyWon = winningBoards.includes(splittedBoards[boardKey])
if (bingo && !hasAlreadyWon) {
details = isBingoLine(splittedBoards[boardKey], numbersThrown) || isBingoColumn(splittedBoards[boardKey], numbersThrown)
winningBoards.push(splittedBoards[boardKey])
lastFoundNumber = numbersToThrow[i]
}
}
}
const lastBoard = winningBoards.pop()
const lastIndex = numbersThrown.findIndex(num => num === lastFoundNumber)
const realNumbersThrown = numbersThrown.slice(0, lastIndex)
const result = getFinalScore(
details,
realNumbersThrown,
flattenBoard(lastBoard),
lastFoundNumber
)
console.log(result)
})