UNPKG

@nguyenhuu/adventofcode

Version:
30 lines (26 loc) 18.6 kB
import{Option as N,program as J}from"commander";import{dirname as tr}from"path";import{fileURLToPath as rr}from"url";import or from"react";import{render as sr}from"ink";import We from"os";import{v5 as ue}from"uuid";import M from"chalk";import ze from"dotenv";import{v5 as Ve}from"uuid";ze.config();var k=["2015","2016","2017","2018","2019","2020","2021","2022","2023","2024"];var X=t=>M.bold(M.greenBright(t)),T=t=>M.bold(M.yellowBright(t)),ne=`Instructions: ${T("0-9")}: Run ${X("partX")} solution ${T("Enter")}: Re-run solution ${T("U")} : Submit solution ${T("X")} : Terminate solution ${T("S")} : Run solution with ${X("sample")} ${T("H")} : Print the instructions ${T("I")} : Run solution with ${X("input")} ${T("Q")} : Quit application`;var ae,ce,pe;ae="@nguyenhuu/adventofcode",ce="1.1.3",pe="6a6c22ecfe13c59e56e59e3fcbb56fc8";var _=ae,D=ce,Q=pe,Ye="6ba7b812-9dad-11d1-80b4-00c04fd430c8",Z=Ve(Q,Ye);var le=()=>{let t=We.networkInterfaces();for(let e of Object.keys(t)){let r=t[e];if(r){for(let o of r)if(!o.internal&&o.mac&&o.mac!=="00:00:00:00:00:00")return o.mac}}return""},qe=t=>{let e=t||le();return ue(e,Z)},Je=()=>{let t=le();return ue(t,Z)},f={sessionToken:process.env.SESSION||"",logLevel:process.env.LOG_LEVEL||"info",logDir:process.env.LOG_DIR||"logs",amplitudeApiKey:Q,userId:qe(process.env.SESSION||""),deviceId:Je(),telemetryEnabled:process.env.DISABLE_TELEMETRY!=="true",appName:_,appVersion:D};import $ from"enquirer";var me="python",ge={Python:"python",python:"python",Javascript:"javascript",javascript:"javascript",Java:"java",java:"java",Golang:"go",go:"go",golang:"go","C++":"cpp",cpp:"cpp",Ruby:"ruby",ruby:"ruby"},de=async t=>{let{year:e,day:r,part:o,language:s}=t;if(s)s=ge[s]||me;else{let i=await $.prompt({type:"select",name:"language",message:"Select programming language",choices:[{name:"Python"},{name:"Javascript"},{name:"Java"},{name:"C++"},{name:"Ruby"},{name:"Golang"}]});s=ge[i.language]||me}return e||(e=(await $.prompt({type:"input",name:"year",message:"Select year"})).year),r||(r=(await $.prompt({type:"input",name:"day",message:"Select day"})).day),o||(o=(await $.prompt({type:"select",name:"part",message:"Select part",choices:[{name:"Part 1"},{name:"Part 2"}]})).part==="Part 1"?"1":"2"),{year:e,day:r,part:o,language:s}};import{useStore as Xt}from"zustand";import O,{useEffect as Qt,useMemo as Zt}from"react";import{Box as Ke}from"ink";import{useStore as st}from"zustand";import{useCallback as it}from"react";import{spawn as fe}from"child_process";var m=class t{constructor(e){this.options=e;this.options=e}static currentProcess=null;static DEFAULT_STDIO=["pipe","pipe","pipe","ipc"];static COMPILATION_STDIO=["ignore","ignore","pipe"];setCurrentProcess(e){t.currentProcess=e}getSolutionFilePath(){return this.options.solutionFile}getInputFilePath(){return this.options.inputFile}getDriverPath(){return`${this.options.baseDir}/drivers/${this.options.language}`}static terminate(){t.currentProcess&&!t.currentProcess.killed&&t.currentProcess.kill("SIGKILL")}spawnProcess(e,r,o={}){let s=fe(e,r,{...o,stdio:o.stdio||t.DEFAULT_STDIO});return this.setCurrentProcess(s),s}createErrorProcess(e){let r=e instanceof Error?e.message:String(e),o=fe("echo",[r],{stdio:t.DEFAULT_STDIO});return setTimeout(()=>{o&&!o.killed&&o.kill("SIGKILL")},100),o}};import{execSync as Xe}from"child_process";import{resolve as Qe}from"path";var U=class extends m{execute(){let e=this.getSolutionFilePath(),r=this.getInputFilePath(),o=this.getDriverPath();try{Xe(`g++ -o ${o}/solution_cpp ${o}/main.cpp ${e}`,{stdio:m.COMPILATION_STDIO})}catch(s){return this.createErrorProcess(s)}return this.spawnProcess(o+"/solution_cpp",[r.replace("./",Qe("./")+"/")],{cwd:o})}};import{execSync as Ze}from"child_process";import{resolve as et}from"path";var G=class extends m{execute(){let e=this.getSolutionFilePath(),r=this.getInputFilePath(),o=this.getDriverPath();try{Ze(`javac -d ${o} ${e}`,{stdio:m.COMPILATION_STDIO})}catch(s){return this.createErrorProcess(s)}return this.spawnProcess("java",["-cp","gson-2.10.1.jar:.","JavaRunner",r.replace("./",et("./")+"/")],{cwd:o})}};var j=class extends m{execute(){let e=this.getSolutionFilePath(),r=this.getInputFilePath(),o=this.getDriverPath();return this.spawnProcess("python3",["-u",o+"/python.py",e,r])}};var B=class extends m{execute(){let e=this.getSolutionFilePath(),r=this.getInputFilePath(),o=this.getDriverPath();return this.spawnProcess("ruby",[o+"/ruby.rb",e,r])}};var K=class extends m{execute(){let e=this.getSolutionFilePath(),r=this.getInputFilePath(),o=this.getDriverPath();return this.spawnProcess("node",[o+"/javascript.js",e,r])}};import{execSync as tt}from"child_process";var R=class extends m{getDriverPath(){return`${this.options.baseDir}/drivers/golang`}execute(){let e=this.getSolutionFilePath(),r=this.getInputFilePath(),o=this.getDriverPath();try{tt(`go build -buildmode=plugin -o ${o}/golang.so ${e}`,{stdio:m.COMPILATION_STDIO})}catch(s){return this.createErrorProcess(s)}return this.spawnProcess("go",["run",o+"/golang.go",r,`${o}/golang.so`],{cwd:"."})}};var ee=class t{static instance;executors;constructor(){this.executors=new Map}static getInstance(){return t.instance||(t.instance=new t),t.instance}registerExecutor(e,r){this.executors.set(e,r)}createExecutor(e){let r=this.executors.get(e.language);if(!r)throw new Error(`No executor registered for language: ${e.language}`);return new r(e)}},rt=t=>{t.registerExecutor("javascript",K),t.registerExecutor("python",j),t.registerExecutor("ruby",B),t.registerExecutor("go",R),t.registerExecutor("java",G),t.registerExecutor("cpp",U)},he=ee.getInstance();rt(he);var ot=he,Se=t=>(m.terminate(),ot.createExecutor(t).execute());var w=t=>{let{baseDir:e,language:r,setAnswer:o,setPerfLog:s,setLoading:i,appendOutput:n,clearOutput:p}=st(t);return it(()=>{let u=t.getState().getSolutionFile(),d=t.getState().getInputFile();if(!u||!d)return;i(!0),p();let c=Se({solutionFile:u,inputFile:d,language:r,baseDir:e});c.on("message",a=>{o(a.result+""),s(a.time)}),c.on("close",()=>{}),c.on("exit",a=>{a!==0&&(o("-"),s("-")),i(!1)}),c.stdout&&(c.stdout.setEncoding("utf8"),c.stdout.on("data",function(a){let l=a.toString();l.startsWith("Command failed")&&(o("-"),s("-")),n(l)})),c.stderr&&(c.stderr.setEncoding("utf8"),c.stderr.on("data",function(a){n(a.toString())}))},[])};import{create as mt}from"zustand";var Ee={javascript:"mjs",python:"py",java:"java",go:"go",ruby:"rb",cpp:"cpp"},nt=`#include <iostream> using namespace std; string solution(const string& input_content) { return "0"; } `,at=`def solution(input): pass `,ct=`def solution(input) return nil end `,pt=`export const solution = input => { return null; } `,ut=`class Solution { public static String solve(String input) { return null; } }`,lt=t=>`package main func Part${t.part}(input string) interface{} { return nil } `,xe={javascript:pt,python:at,java:ut,go:lt,cpp:nt,ruby:ct};var ye=t=>mt((e,r)=>({inputMode:t.inputMode??"sample",output:"",answer:"",perfLog:"",loading:!1,...t,setInputMode:o=>e({inputMode:o}),setPart:o=>e({part:o}),setOutput:o=>e({output:o}),clearOutput:()=>e({output:""}),appendOutput:o=>e(s=>({output:s.output+o})),setAnswer:o=>e({answer:o}),setPerfLog:o=>e({perfLog:o}),setLoading:o=>e({loading:o}),getRelativeDir:()=>`./${r().year}/day${r().day}/`,getSolutionFile:()=>`./${r().year}/day${r().day}/part${r().part}.${Ee[r().language]}`,getInputFile:()=>`./${r().year}/day${r().day}/${r().inputMode}.txt`}));import{useStore as It}from"zustand";import{useCallback as At}from"react";import{useInput as Ft}from"ink";import{track as dt,flush as ft,init as ht}from"@amplitude/analytics-node";import{v4 as St}from"uuid";import Ie from"path";import z from"pino";import H from"fs";var g=class{static exists(e){return H.existsSync(e)}static createDirectory(e){H.mkdirSync(e,{recursive:!0})}static writeFile(e,r,o){H.writeFileSync(e,r,o)}static getFileStats(e){return H.statSync(e)}};var gt="logs",te=class t{static instance;logger;constructor(){if(!f.logLevel){this.logger=z({enabled:!1});return}try{let e=Ie.resolve(process.cwd(),f.logDir||gt);g.exists(e)||g.createDirectory(e);let r=Ie.join(e,"app.log");this.logger=z({level:f.logLevel,timestamp:z.stdTimeFunctions.isoTime,transport:{target:"pino-pretty",options:{colorize:!1,translateTime:"SYS:standard",ignore:"pid,hostname",destination:r}}})}catch(e){console.error("Failed to create log directory:",e),this.logger=z({enabled:!1})}}static getInstance(){return t.instance||(t.instance=new t),t.instance}info(e,...r){this.logger.info(e,...r)}warn(e,...r){this.logger.warn(e,...r)}error(e,...r){this.logger.error(e,...r)}debug(e,...r){this.logger.debug(e,...r)}},F=te.getInstance();var re=class t{static instance;sessionId;constructor(){if(this.sessionId=St(),!f.amplitudeApiKey){F.warn("Amplitude API key not set. Analytics will be disabled.");return}ht(f.amplitudeApiKey),this.track("start_session"),["SIGINT","SIGTERM","exit"].forEach(r=>{process.on(r,async()=>{this.track("end_session"),await ft().promise,process.exit()})})}static getInstance(){return t.instance||(t.instance=new t),t.instance}track(e,r){f.telemetryEnabled&&dt(e,{...r,session_id:this.sessionId,event_type:e,time:Date.now(),platform:"CLI",app_name:f.appName,app_version:f.appVersion},{user_id:f.userId,device_id:f.deviceId})}},Ae=re.getInstance();import b from"chalk";import{useStore as Pt}from"zustand";import{useCallback as yt}from"react";import Et from"axios";var oe=class t{client;constructor(){this.client=Et.create({baseURL:"https://adventofcode.com",headers:{Cookie:f.sessionToken?`session=${f.sessionToken}`:"","User-Agent":`Advent Of Code Runner (${_}@${D})`}})}static instance;static getInstance(){return t.instance||(t.instance=new t),t.instance}async fetchInput(e,r){if(!f.sessionToken)throw new Error("SESSION is required to fetch input");return(await this.client.get(`/${e}/day/${r}/input`)).data}async fetchProblem(e,r){if(!f.sessionToken)throw new Error("SESSION is required to fetch problem");return(await this.client.get(`/${e}/day/${r}`)).data}async submitAnswer(e,r,o,s){if(!f.sessionToken)throw new Error("SESSION is required to submit answer");let n=(await this.client.post(`/${e}/day/${r}/answer`,`level=${o}&answer=${encodeURIComponent(s)}`,{headers:{"Content-Type":"application/x-www-form-urlencoded"}})).data,p=n.includes("That's the right answer!"),S=n.includes("That's not the right answer; your answer is too low."),u=n.includes("That's not the right answer; your answer is too high."),d=n.includes("You don't seem to be solving the right level."),c=n.includes("You gave an answer too recently"),a="Unknown response",l;if(p)a="Correct answer!";else if(S)a="Too low";else if(u)a="Too high";else if(d)a="Already completed";else if(c){a="Rate limited";let h=n.match(/have ([0-9msh ]+) left to wait/);h&&(l=h[1])}else a="Incorrect answer";return{correct:p,message:a,waitingTime:l}}},v=oe.getInstance();import{useStore as xt}from"zustand";var L=t=>{let{year:e,day:r,part:o,language:s,inputMode:i}=xt(t);return{track:(p,S)=>{Ae.track(p,{...S,year:e,day:r,part:o,language:s,inputMode:i})}}};var Te=t=>{let{year:e,day:r,answer:o,setAnswer:s,setOutput:i,part:n}=Pt(t),{track:p}=L(t);return{submit:yt(async()=>{if(o)try{let u=await v.submitAnswer(e,r,parseInt(n,10),o);if(F.debug(`Submit result: ${JSON.stringify(u)}`),p("submission",{success:u.correct}),u.correct)i(b.bold(b.greenBright("Right answer! \u{1F929}")));else{let d=b.bold(b.red("Wrong answer! \u{1F979}"));u.waitingTime&&(d+=b.bold(b.redBright(` Waiting ${u.waitingTime} \u23F3`))),i(d)}return s(u.message),u}catch(u){let d=u instanceof Error?u.message:"Failed to submit answer";throw s(d),i(b.bold(b.red(`Cannot submit answer: ${d}`))),p("submission",{success:!1}),u}},[e,r,n,o,p])}};var we=t=>{let{inputMode:e,part:r,loading:o,setInputMode:s,setPart:i,setOutput:n,appendOutput:p,clearOutput:S}=It(t),u=w(t),{submit:d}=Te(t),{track:c}=L(t),a=At(async(l,h)=>{let E={};switch(h.return?E={key:"enter"}:h.upArrow?E={key:"up"}:h.downArrow?E={key:"down"}:l?E={key:l.toLowerCase()}:E={key:"unknown"},c("key_press",E),l.toLowerCase()){case"q":{m.terminate(),process.exit();break}case"i":{s("input");break}case"s":{s("sample");break}case"c":S();break;case"0":case"1":case"2":case"3":case"4":case"5":case"6":case"7":case"8":case"9":{i(l);break}case"x":{o&&(m.terminate(),setTimeout(()=>n("Terminated!"),100));break}case"h":{n(ne);break}case"u":{d();break}default:{h.downArrow&&s("input"),h.upArrow&&s("sample"),h.return&&u();break}}},[r,e,o,s,i,n,p,S,u,d,c]);Ft(a)};import{useStore as Ct}from"zustand";import{useCallback as Nt,useEffect as Mt,useState as ve}from"react";var Tt={"&gt;":">","&lt;":"<","&amp;":"&","&quot;":'"',"&apos;":"'"},wt=["<code>","</code>","<em>","</em>","<pre>","</pre>"],bt=t=>{if(!t)return"";try{let e=t;for(let[r,o]of Object.entries(Tt))e=e.replaceAll(r,o);for(let r of wt)e=e.replaceAll(r,"");return e.trim()}catch(e){return F.error(`Error in decode function ${e}`),t}},vt=t=>!Array.isArray(t)||t.length===0?"":t.reduce((e,r)=>r.length>e.length?r:e,""),be=t=>{let e=/<code>(<em>)?([\s\S]+?)(<\/em>)?<\/code>/g,r=t.match(e);return r?bt(vt(r)).trim():""};import Ot from"chokidar";import{useEffect as Lt}from"react";var V=Ot.watch([]),Y=({filePath:t,onChange:e})=>{Lt(()=>{if(t)return V.add(t),V.removeAllListeners("change"),V.on("change",e),()=>{V.unwatch(t)}},[t,e])};var Oe=t=>{let[e,r]=ve(""),[o,s]=ve(0),{year:i,day:n,inputMode:p,getRelativeDir:S,getInputFile:u}=Ct(t),d=S(),c=u(),{track:a}=L(t),l=w(t),h=Nt(()=>{l()},[l]);return Y({filePath:e,onChange:h}),Mt(()=>{g.exists(d)||g.createDirectory(d),g.exists(c)||g.writeFile(c,"",{flag:"as+"});let E=g.getFileStats(c);r(c),s(E.size),k.includes(i)&&(E.size===0&&p==="input"&&v.fetchInput(i,n).then(x=>{if(x){g.writeFile(c,x);let A=g.getFileStats(c);s(A.size),a("input_fetch",{success:!0})}}).catch(x=>{a("input_fetch",{success:!1}),F.error(`Failed to fetch input: ${x}`)}),E.size===0&&p==="sample"&&v.fetchProblem(i,n).then(x=>{if(x){let A=be(x);if(A){g.writeFile(c,A);let He=g.getFileStats(c);s(He.size),a("sample_fetch",{success:!0})}}}).catch(x=>{a("sample_fetch",{success:!0}),F.error(`Failed to fetch problem: ${x}`)}))},[d,c,i,n,p,a]),{name:e,size:o}};import{useStore as Dt}from"zustand";import{useCallback as $t,useEffect as Ut,useState as Ce}from"react";import{exec as kt}from"child_process";import{useCallback as _t}from"react";var Le=()=>({openFile:_t(e=>{if(process.env.TERM_PROGRAM==="vscode"){let r=`code --reuse-window ${e}`;kt(r,()=>{})}},[])});var Ne=t=>{let{year:e,day:r,part:o,language:s,getRelativeDir:i,getSolutionFile:n}=Dt(t),[p,S]=Ce(""),[u,d]=Ce(0),{openFile:c}=Le(),a=i(),l=n(),h=w(t),E=$t(()=>{h()},[h]);return Y({filePath:p,onChange:E}),Ut(()=>{if(g.exists(a)||g.createDirectory(a),!g.exists(l)){let A=xe[s];A&&(typeof A=="function"?g.writeFile(l,A({year:e,day:r,part:o}),{flag:"as+"}):g.writeFile(l,A,{flag:"as+"}))}let x=g.getFileStats(l);S(l),d(x.size),c(l)},[a,l,c]),{name:p,size:u}};import{useStore as Gt}from"zustand";import{useEffect as jt,useState as Me}from"react";var Bt=/class="user">(.+?) ?</,Kt=/class="star-count">(.+?)\*</,ke=t=>{let e=Gt(t,n=>n.year),[r,o]=Me(""),[s,i]=Me("");return jt(()=>{if(!k.includes(e)){o("");return}v.fetchProblem(e,"1").then(n=>{let p=Bt.exec(n);p&&o(p[1]);let S=Kt.exec(n);S&&i(S[1])})},[e]),{userName:r,star:s}};import W from"chalk";import q from"react";import{Box as _e,Text as De}from"ink";var Rt=({solutionFileName:t,solutionFileSize:e,inputFileName:r,inputFileSize:o})=>q.createElement(_e,{width:100},q.createElement(_e,{flexDirection:"column",width:70},q.createElement(De,null,`Solution file: ${W.bold(W.magentaBright(t.slice(2)))} ${e} bytes`),q.createElement(De,null,` Input file: ${W.bold(W.magentaBright(r.slice(2)))} ${o} bytes`))),$e=Rt;import P from"react";import{Box as Ht,Text as I}from"ink";var zt=({year:t,day:e,part:r,language:o,userName:s,star:i})=>P.createElement(Ht,null,P.createElement(I,null,"\u{1F4C6} Year:"),P.createElement(I,{italic:!0,bold:!0,color:"#FF8800"}," ",t," "),P.createElement(I,null,"Day:"),P.createElement(I,{italic:!0,bold:!0,color:"#FF8800"}," ",e," "),P.createElement(I,null,"Part:"),P.createElement(I,{italic:!0,bold:!0,color:"#FF8800"}," ",r," "),P.createElement(I,null,"| \u{1F4D8} Language:"),P.createElement(I,{italic:!0,bold:!0,color:"#FF8800"}," ",o," "),s&&P.createElement(P.Fragment,null,P.createElement(I,null,"| \u{1F464} Username:"),P.createElement(I,{italic:!0,bold:!0,color:"#FF8800"}," ",s," ")),i&&P.createElement(I,{italic:!0,bold:!0,color:"#FF8800"},i,"\u2B50\uFE0F"," ")),Ue=zt;import y from"react";import{Box as ie,Text as C}from"ink";import Vt from"cli-spinners";import Ge,{useEffect as Yt,useState as Wt}from"react";import{Text as je}from"ink";function qt({type:t="dots",loading:e=!1}){let[r,o]=Wt(0),s=Vt[t];return Yt(()=>{if(e){let i=setInterval(()=>{o(n=>n===s.frames.length-1?0:n+1)},s.interval);return()=>{clearInterval(i)}}return()=>{}},[s,e]),e?Ge.createElement(je,null,s.frames[r]):Ge.createElement(je,null,s.frames[0])}var se=qt;var Jt=({loading:t,answer:e,perfLog:r,output:o})=>y.createElement(y.Fragment,null,y.createElement(ie,null,y.createElement(C,{color:"yellowBright"},y.createElement(se,{type:"earth",loading:t})),y.createElement(C,{color:"green"},"Result: "),y.createElement(C,{color:"green",bold:!0},t?y.createElement(se,{type:"simpleDots",loading:!0}):e),e&&!t&&y.createElement(C,null,` \u23F1 ${r}`)),!!o&&y.createElement(y.Fragment,null,y.createElement(ie,{height:1}),y.createElement(ie,{borderTop:!0,flexDirection:"column"},y.createElement(C,null,o)))),Be=Jt;var er=({promptInput:t})=>{let e=Zt(()=>ye(t),[]),{year:r,day:o,language:s,part:i,output:n,answer:p,perfLog:S,loading:u}=Xt(e),{userName:d,star:c}=ke(e),{name:a,size:l}=Ne(e),{name:h,size:E}=Oe(e),x=w(e);return Qt(()=>{!a||!h||x()},[a,h]),we(e),O.createElement(O.Fragment,null,O.createElement(Ue,{year:r,day:o,part:i,language:s,userName:d,star:c}),O.createElement(Ke,{height:1}),O.createElement($e,{solutionFileName:a,solutionFileSize:l,inputFileName:h,inputFileSize:E}),O.createElement(Ke,{height:1}),O.createElement(Be,{loading:u,answer:p,perfLog:S,output:n}))},Re=er;var ir=rr(import.meta.url),nr=tr(ir);console.clear();J.addOption(new N("-y, --year <year>")).addOption(new N("-l, --language <language>")).addOption(new N("-d, --day <day>")).addOption(new N("-p, --part <part>")).addOption(new N("--disable-telemetry","Disable telemetry"));J.parse();f.telemetryEnabled=!J.opts().disableTelemetry;de(J.opts()).then(t=>{sr(or.createElement(Re,{promptInput:{...t,baseDir:nr}}))}).catch(()=>{process.exit(1)});