Public
Edited
Dec 3, 2023
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
owners = [
{ name: "visnup", id: 429910, code: "429910-12bd4fb4" },
{ name: "AlexeyMK", id: 376508, code: "376508-edee0081" },
{ name: "HN Tokyo", id: 598660, code: "598660-c7d60c7a" },
{ name: "mythmon", id: 217121 },
{ name: "daicoden", id: 190852 }
]
Insert cell
names = new Set(
Object.values(data.members)
.filter((d) => d.stars)
.sort((a, b) => b.local_score - a.local_score)
.map((d) => d.name || d.id)
)
Insert cell
domains = ({
score: [0, Object.keys(data.members).length * 25 * 2],
days: d3
.cross(d3.range(1, 26), d3.range(1, 3))
.map(([d, s]) => [dayFormat(d), s].join(",")),
time: [new Date(year, 11, 1), new Date(year, 11, 31)]
})
Insert cell
pointsComplete = points.filter((d) => !d.incomplete)
Insert cell
points = {
const start = active.length ? names.size : Object.keys(data.members).length,
points = [],
scores = {};

for (const [day, stars] of Object.entries(days).sort((a, b) =>
a[0].localeCompare(b[0])
)) {
stars.sort((a, b) => a.ts - b.ts);
const missing = new Set(names);
const fastest = stars[0].ts;
let p = start;
for (const star of stars) {
const score = (scores[star.name] = (scores[star.name] || 0) + p);
points.push({
...star,
day,
points: p--,
score,
minutes: (star.ts - fastest) / 1000 / 60
});
missing.delete(star.name);
}
for (const name of missing) {
points.push({
name,
day,
incomplete: true,
points: 0,
score: scores[name],
minutes: Infinity
});
}
let rank = 1;
for (const p of points
.slice(points.length - names.size)
.sort((a, b) => b.score - a.score))
p.rank = rank++;
}

for (const last of d3
.rollup(
points.filter((d) => !d.incomplete),
(d) => d[d.length - 1],
(d) => d.name
)
.values())
last.last = true;

return points;
}
Insert cell
days = {
const days = {};
for (const { id, name, completion_day_level } of Object.values(data.members)) {
for (const [day, parts] of Object.entries(completion_day_level)) {
for (const [part, { get_star_ts }] of Object.entries(parts)) {
const key = [dayFormat(day), part];
(days[key] = days[key] || []).push({
name: name || id,
ts: new Date(get_star_ts * 1000)
});
}
}
}
return days;
}
Insert cell
Insert cell
data = yours
? JSON.parse(yours)
: fetch(
`https://aoc-leaderboard.vercel.app/api?year=${year}&id=${owner.id}`
).then((res) => res.json())
Insert cell
Insert cell
tickFormat = (d) => (d.includes(",2") ? null : d.split(",")[0].trim())
Insert cell
dayFormat = d3.format('2d')
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more