Files
advent-of-code/2023/day07/index.js
2024-12-20 13:04:37 +01:00

145 lines
4.3 KiB
JavaScript

import fs from 'node:fs'
/* https://adventofcode.com/2023/day/7
Camel Cards
32T3K 765
T55J5 684
KK677 28
KTJJT 220
QQQJA 483
33332 100
2AAAA 100
77888 100
77788 100
*/
function init() {
const data = fs.readFileSync('example.txt', { encoding: 'utf-8' }, data => data)
const games = data.split('\n')
const poker = new Poker()
for (let game of games) {
poker.hand = game.split(' ')[0].split('')
poker.bid = parseInt(game.split(' ')[1])
poker.play()
}
poker.score()
}
class Poker {
constructor(hand, bid) {
this.hand = []
this.ranking = []
this.bid = 0
this.results = 0
this.order = [
{ name: 'A', value: 13 },
{ name: 'K', value: 12 },
{ name: 'Q', value: 11 },
{ name: 'J', value: 10 },
{ name: 'T', value: 9 },
{ name: '9', value: 8 }, { name: '8', value: 7 }, { name: '7', value: 6 }, { name: '6', value: 5 }, { name: '5', value: 4 }, { name: '4', value: 3 },
{ name: '3', value: 2 }, { name: '2', value: 1 }
]
}
getOccurences() {
return this.hand.reduce((acc, curr) => {
return acc[`${curr}`] ? ++acc[curr] : acc[`${curr}`] = 1, acc
}, new Object())
}
getValueOfCard(card) {
return this.order.find(c => c.name === card).value
}
isTwoPair() {
const result = this.getOccurences()
return Object.values(result)
.filter(numbers => numbers === 2)
.length === 2
}
isFullHouse() {
const result = this.getOccurences()
return Object.values(result).indexOf(3) > -1
&& Object.values(result).indexOf(2) > -1
}
hasMultiple(number) {
const result = this.getOccurences()
return Object.values(result).indexOf(number) > -1
}
testResults() {
return {
'FiveOfAKind': this.hasMultiple(5),
'FourOfAKind': this.hasMultiple(4),
'FullHouse': this.isFullHouse(),
'ThreeOfAKind': this.hasMultiple(3),
'TwoPair': this.isTwoPair(),
'OnePair': this.hasMultiple(2)
}
}
rank() {
const results = this.testResults()
let rank = 0
switch (true) {
case results.FiveOfAKind:
rank = 1_000_000_000_000
return rank
case results.FourOfAKind:
rank = 900_000_000_000
return rank
case results.FullHouse:
rank = 800_000_000_000
return rank
case results.ThreeOfAKind:
rank = 700_000_000_000
return rank
case results.TwoPair:
rank = 600_000_000_000
return rank
case results.OnePair:
rank = 500_000_000_000
return rank
default:
rank = 400_000_000_000
break
}
return rank
}
score() {
const sorted_list = this.ranking.sort((a, b) => a.rank - b.rank)
for (let i = 0; i < sorted_list.length; i++) {
this.results += (i + 1) * sorted_list[i].bid
console.log(sorted_list[i].cards, `${i + 1} * ${sorted_list[i].bid} = ${(i + 1) * sorted_list[i].bid}`)
}
console.log(sorted_list.length)
console.log(this.results)
}
play() {
let rank = this.rank()
const cardValues = this.hand.map(card => this.getValueOfCard(card))
/*
This did only work on the input example.
Quirkier solution is to simply map card values to their string representation
with padded 0 and pass that to the ranking.
for (let i = 0; i < cardValues.length; i++) {
let cardValue = cardValues[i]
rank += cardValue * (cardValues.length - i) * 10 ** (cardValues.length - i)
}
*/
let stringValues = cardValues.map(value => String(value).padStart(2, 0))
rank += parseInt(stringValues.join(""))
this.ranking.push({ rank: rank, bid: this.bid, cards: this.hand.join("") })
}
rankPosition(position, iterator) {
return (position - iterator) * 10 ** position
}
}
init()