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
import { expect } from "https://esm.town/v/karfau/chai";
import countBy from "npm:lodash.countby";
let verbose = true;
const CARDS = "23456789TJQKA";
const CARDSJ = "J23456789TQKA";
const ORDERC = "ABCDEFGHIJKLM";
const FIVE_OAK = 6;
const FOUR_OAK = 5;
const FULL_HOUSE = 4;
const THREE_OAK = 3;
const TWO_PAIRS = 2;
const ONE_PAIR = 1;
const HIGH_HAND = 0;
const sample = `32T3K 765
T55J5 684
KK677 28
KTJJT 220
QQQJA 483`;
expect(
firstStar(sample),
"*1 sample 1",
).to.equal(6440);
// expect(firstStar(``), "*1 sample 2").to.equal("?");
function firstStar(input: string) {
const bids = Object.fromEntries(
input.split("\n").map(l => {
const [set, bid] = l.split(" ");
return [set, toInt(bid)];
}),
);
const tSets = Object.fromEntries(
Object.keys(bids).map(set => {
const tSet = set.split("").map((c, i) => ORDERC[CARDS.indexOf(c)]).join("");
const counted = Object.values(countBy(set)).sort((a, b) => b - a);
switch (counted[0]) {
case 5:
return [`${FIVE_OAK}${tSet}`, set];
case 4:
return [`${FOUR_OAK}${tSet}`, set];
case 3:
return [`${counted[1] === 2 ? FULL_HOUSE : THREE_OAK}${tSet}`, set];
case 2:
return [`${counted[1] === 2 ? TWO_PAIRS : ONE_PAIR}${tSet}`, set];
default:
return [`${HIGH_HAND}${tSet}`, set];
}
}),
);
const sortedTSets = Object.keys(tSets).sort();
return sortedTSets.map(tSet => tSets[tSet])
.map((set, i) => {
return (i + 1) * bids[set];
}).reduce(sum, 0);
}
// as as soon as the assertions pass, the solution is calculated
console.log("solution *1:", firstStar(input()));
expect(secondStar(sample), "*2 sample 1").to.equal(5905);
// expect(secondStar(``), "*2 sample 2").to.equal("?");
function withJokers(jokers: number, first: number, second: number) {
switch (first) {
case 5:
return FIVE_OAK;
case 4:
// either 4 jokers or 1 joker leads to 5 of a kind
return jokers ? FIVE_OAK : FOUR_OAK;
case 3:
if (jokers === 3) return second === 2 ? FIVE_OAK : FOUR_OAK;
if (jokers === 2) return FIVE_OAK;
if (jokers === 1) return FOUR_OAK;
return second === 2 ? FULL_HOUSE : THREE_OAK;
case 2:
if (jokers === 2) return second === 2 ? FOUR_OAK : THREE_OAK;
if (jokers === 1) return second === 2 ? FULL_HOUSE : THREE_OAK;
return second === 2 ? TWO_PAIRS : ONE_PAIR;
case 1:
if (jokers) return ONE_PAIR;
}
return HIGH_HAND;
}
function secondStar(input: string) {
const bids = Object.fromEntries(
input.split("\n").map(l => {
const [set, bid] = l.split(" ");
return [set, toInt(bid)];
}),
);
const tSets = Object.fromEntries(
Object.keys(bids).map(set => {
const tSet = set.split("").map((c, i) => ORDERC[CARDSJ.indexOf(c)]).join("");
const countedEntries = Object.entries(countBy(set)).sort(([, a], [, b]) => b - a);
const jokers = countedEntries.find(([l]) => l === "J")?.[1] ?? 0;
const first = countedEntries[0][1];
const second = countedEntries[1]?.[1] ?? 0;
const result = [`${withJokers(jokers, first, second)}${tSet}`, set];
// jokers && debug(...result);
Val Town is a social website to write and deploy JavaScript.
Build APIs and schedule functions from your browser.
Comments
Nobody has commented on this val yet: be the first!
December 8, 2023