UNPKG

aoc-copilot

Version:

Advent of Code automatic runner for examples and inputs

127 lines 5.72 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.avoidedAttempt = avoidedAttempt; exports.finish = finish; exports.incorrectAttempt = incorrectAttempt; exports.print = print; exports.solvedElsewhere = solvedElsewhere; exports.startPart1 = startPart1; exports.sync = sync; const promises_1 = require("node:fs/promises"); const cache_1 = require("./cache"); const site_1 = require("./site"); let deleteOldLocation = false; function readStatsFile(year) { let newLocation = true; return (0, promises_1.readFile)(`stats_${year}.json`, { encoding: 'utf-8' }) .catch(() => { newLocation = false; return (0, cache_1.read)(`${year}/stats.json`); }).then(file => { if (!newLocation) deleteOldLocation = true; return JSON.parse(file); }).catch(() => []); } function getDayStats(stats, day) { return stats.find(stat => stat.day === day) || (stats.push({ day, part1Started: '', part1Finished: '', part2Finished: '', part1AvoidedAttempts: 0, part2AvoidedAttempts: 0, part1IncorrectAttempts: 0, part2IncorrectAttempts: 0, part1SolvedElsewhere: false, part2SolvedElsewhere: false }), stats.at(-1)); } async function updateStatsFile(year, stats) { if (deleteOldLocation) { // Move to new location (delete then write) await (0, cache_1.remove)(`${year}/stats.json`); deleteOldLocation = false; } return (0, promises_1.writeFile)(`stats_${year}.json`, JSON.stringify(stats), { encoding: 'utf-8' }); } async function startPart1(year, day) { const stats = await readStatsFile(year); const dayStats = getDayStats(stats, day); if (dayStats.part1Started === '') dayStats.part1Started = new Date().toJSON(); return updateStatsFile(year, stats); } async function finish(year, day, part) { const stats = await readStatsFile(year); const dayStats = getDayStats(stats, day); const timestamp = new Date().toJSON(); if (part === 1 && dayStats.part1Finished === '') dayStats.part1Finished = timestamp; else if (part === 2 && dayStats.part2Finished === '') dayStats.part2Finished = timestamp; await updateStatsFile(year, stats); return dayStats; } async function avoidedAttempt(year, day, part) { const stats = await readStatsFile(year); const dayStats = getDayStats(stats, day); if (part === 1) dayStats.part1AvoidedAttempts++; else dayStats.part2AvoidedAttempts++; return updateStatsFile(year, stats); } async function incorrectAttempt(year, day, part) { const stats = await readStatsFile(year); const dayStats = getDayStats(stats, day); if (part === 1) dayStats.part1IncorrectAttempts++; else dayStats.part2IncorrectAttempts++; return updateStatsFile(year, stats); } async function solvedElsewhere(year, day, part) { const stats = await readStatsFile(year); const dayStats = getDayStats(stats, day); const timestamp = new Date().toJSON(); if (part === 1) { dayStats.part1SolvedElsewhere = true; if (dayStats.part1Finished === '') dayStats.part1Finished = timestamp; } else { dayStats.part2SolvedElsewhere = true; if (dayStats.part2Finished === '') dayStats.part2Finished = timestamp; } return updateStatsFile(year, stats); } async function print(year) { const stats = await readStatsFile(year); const times = stats.map(stat => [ stat.day.toString().padStart(3, ' '), stat.part1Finished === '' ? '' : (0, site_1.hms)(Date.parse(stat.part1Finished) - Date.parse(stat.part1Started)), stat.part2Finished === '' ? '' : (0, site_1.hms)(Date.parse(stat.part2Finished) - Date.parse(stat.part1Finished)) ]); // Print table const width1 = times.reduce((pv, cv) => Math.max(pv, cv[1].length), 6); const width2 = times.reduce((pv, cv) => Math.max(pv, cv[2].length), 6); const col1 = '-'.repeat(Math.ceil((width1 - 6) / 2)) + 'Part 1' + '-'.repeat(Math.floor((width1 - 6) / 2)); const col2 = '-'.repeat(Math.ceil((width2 - 6) / 2)) + 'Part 2' + '-'.repeat(Math.floor((width2 - 6) / 2)); console.log(`Day ${col1} ${col2}`); times.toReversed().forEach(time => console.log(`${time[0]} ${time[1].padStart(width1, ' ')} ${time[2].padStart(width2, ' ')}`)); } /** * Sync local stats file to site leaderboard service * @param year Year * @param id Leaderboard ID * @param memberId (optional) Member ID; defaults to same as Leaderboard ID */ async function sync(year, id, memberId = id, syncIfPossible = false, force = false) { const stats = await readStatsFile(year); const leaderboard = await (0, site_1.getLeaderboard)(year, id, syncIfPossible); for (let [day, stars] of Object.entries(leaderboard.members[memberId].completion_day_level)) { const stat = getDayStats(stats, parseInt(day)); for (let [part, star] of Object.entries(stars)) { if (part === '1' && (force || stat.part1Finished === '')) stat.part1Finished = new Date(star.get_star_ts * 1000).toJSON(); else if (part === '2' && (force || stat.part2Finished === '')) stat.part2Finished = new Date(star.get_star_ts * 1000).toJSON(); } if (stat.part1Finished < stat.part1Started || stat.part2Finished < stat.part1Finished) { console.error(`Your local stats file has start time(s) that are after your actual`, `finish time(s). This can happen when you use multiple development environments`, `so try syncing with your repository and trying again.`); return; } } await updateStatsFile(year, stats); } //# sourceMappingURL=stats.js.map