Day Seven Part One, Start Part Two
This commit is contained in:
parent
c896fe1d4d
commit
ce50531971
5
index.ts
5
index.ts
|
@ -1,2 +1,3 @@
|
|||
import {runDaySix} from "./src/day_six";
|
||||
runDaySix()
|
||||
import {runDaySeven} from "./src/day_seven";
|
||||
|
||||
runDaySeven();
|
|
@ -0,0 +1,37 @@
|
|||
import {CamelCard, CamelCards} from "./day_seven";
|
||||
|
||||
describe('Day Seven', () => {
|
||||
const input = `32T3K 765
|
||||
T55J5 684
|
||||
KK677 28
|
||||
KTJJT 220
|
||||
QQQJA 483`;
|
||||
|
||||
it.each([
|
||||
['AAAAA', 7], // Five of a kind
|
||||
['AA8AA', 6], // Four of a kind
|
||||
['AABBB', 5], // Full house
|
||||
['T55C5', 4], // Three of a kind
|
||||
['KK677', 3], // Two pairs
|
||||
['32T3K', 2], // One pair
|
||||
['12345', 1], // High card
|
||||
|
||||
['T55J5', 6], // Four of a kind with Joker
|
||||
['KTJJT', 6],
|
||||
['QQQJA', 6]
|
||||
])('should should correctly score %s as %s', (card, score) => {
|
||||
const camelCard = new CamelCard(card);
|
||||
expect(camelCard.score).toEqual(score);
|
||||
});
|
||||
|
||||
it('should correctly compare two clashing cards', () => {
|
||||
const a = new CamelCard('AA2CC');
|
||||
const b = new CamelCard('AATCC');
|
||||
expect(a.compare(b)).toBeLessThan(0);
|
||||
});
|
||||
|
||||
it('should parse the input and calculate the total winnings', () => {
|
||||
const camelCards = new CamelCards(input);
|
||||
expect(camelCards.winnings).toEqual(5905);
|
||||
})
|
||||
});
|
|
@ -0,0 +1,78 @@
|
|||
import {isEqual, zip} from "lodash";
|
||||
import {anyChar, int, newline, rest, space, whitespace} from "parjs";
|
||||
import {stringify, manyBetween, between, then, manySepBy, manyTill} from "parjs/combinators";
|
||||
import fs from "fs";
|
||||
|
||||
const CardLetterScores = ['J', '2', '3', '4', '5', '6', '7', '8', '9', 'T', 'Q', 'K', 'A'];
|
||||
|
||||
export class CamelCard {
|
||||
private readonly hand: Record<string, number>;
|
||||
public readonly score: number;
|
||||
|
||||
constructor(protected readonly card: string) {
|
||||
this.hand = this.card.split('').reduce((cards, char) => {
|
||||
if (!cards[char]) {
|
||||
cards[char] = 0;
|
||||
}
|
||||
|
||||
cards[char] += 1;
|
||||
return cards;
|
||||
}, {} as Record<string, number>)
|
||||
|
||||
this.score = this.calculateScore();
|
||||
}
|
||||
|
||||
public compare(other: CamelCard): number {
|
||||
const diff = this.score - other.score;
|
||||
if (diff !== 0) return diff;
|
||||
|
||||
for (const [a, b] of zip(this.card.split(''), other.card.split('')) as [string, string][]) {
|
||||
if (a !== b) {
|
||||
return CardLetterScores.indexOf(a) - CardLetterScores.indexOf(b)
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
private calculateScore(): number {
|
||||
const cards = Object.values(this.hand).sort((a, b) => b-a);
|
||||
|
||||
if (isEqual(cards, [1, 1, 1, 1, 1])) return 1;
|
||||
if (isEqual(cards, [2, 1, 1, 1])) return 2;
|
||||
if (isEqual(cards, [2, 2, 1])) return 3;
|
||||
if (isEqual(cards, [3, 1, 1])) return 4;
|
||||
if (isEqual(cards, [3, 2])) return 5;
|
||||
if (isEqual(cards, [4, 1])) return 6;
|
||||
if (isEqual(cards, [5])) return 7;
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
const cardParser = anyChar().pipe(manyTill(space()), stringify());
|
||||
const bidParser = int().pipe(between(whitespace()));
|
||||
const parser = cardParser.pipe(then(bidParser), manySepBy(whitespace()));
|
||||
|
||||
export class CamelCards {
|
||||
private cards: [CamelCard, number][] = [];
|
||||
|
||||
constructor(input: string) {
|
||||
const pairs = parser.parse(input).value;
|
||||
|
||||
this.cards = pairs.map(([cards, bid]) => [new CamelCard(cards), bid]);
|
||||
}
|
||||
|
||||
get winnings(): number {
|
||||
this.cards.sort(([a], [b]) => a.compare(b));
|
||||
|
||||
return this.cards.reduce((total, [_, value], index) => total + (value * (index + 1)), 0);
|
||||
}
|
||||
}
|
||||
|
||||
export const runDaySeven = () => {
|
||||
const input = fs.readFileSync('./inputs/day_seven_input.txt', 'utf-8').trimEnd();
|
||||
|
||||
const cards = new CamelCards(input);
|
||||
console.log(cards.winnings);
|
||||
}
|
Loading…
Reference in New Issue