型定義に時間かかってもいいから型補完の利く環境で解きたい人向けのテンプレートです。ただしpaizaの回答提出はTSに対応していないため、JSDocをフル活用して同様の環境を作ります。
またVSCodeでコーディングするものとし(流石に普通の開発みたくeslintとprittier入りディレクトリ作るのはやりすぎ感あるので、自分はlintをVSCode付属のTSパーサーに任せる形でやってます)、動作確認だけ回答欄なりpaiza.ioに張り付ける形で解いています。
テンプレート全文
// @ts-check
/**
* @typedef {unknown} Info
*/
/**
*
* @param {ReadonlyArray<String>} inputs
* @returns {Info}
*/
const getInfo = (inputs) => {
const lines = inputs.filter((line) => line !== "") //最後に空文字が飛んでくるのでフィルターしておく
const deliminator = " "
const getNumber = (numberText) => parseInt(numberText)
// @type {Info}
const info = {
};
return info;
};
/**
*
* @param {Info} info
* @returns {unknown}
*/
const getAnswer = (info) => {
const answer = info
return answer;
};
// @ts-ignore
const inputs = require("fs").readFileSync("/dev/stdin", "utf8").split("\n");
const info = getInfo(inputs);
const answer = getAnswer(info);
console.log(answer);
解説および使い方
標準入力をgetInfo
関数で解析し、各パラメーターをinfoにまとめて返し、(あくまで標準入力をバラして各パラメータをオブジェクトにまとめるまでを責務とするのがおすすめ)、そのinfoをgetAnswer
関数で解いて最後はconsole.logで出力するというフローです。getInfoから順を追って進めやすいよう、初期状態はinfo自体を出力するようにしてあります。
getInfo
まず最初にinfo
を組み立てますが、初期はunknown
に指定してあるので好きなようにまとめて、完成間近で@typedef unknown
を書き換えて渡したい形に直す感じですね。
またオブジェクトの組み立て中に変数に型指定したい場面もあるかと思いますが、以下のように定義します。
/**
* @typedef {{x:number, y:number}} Point
* @typedef {Point} Info
*
*/
const header = lines[0]
const [x,y] = header.split(deliminator).map(getNumber)
/**
* @type Point
*
*/
const point = {x,y}
const Info = {point}
みたいな感じでやってますね。別に下の所で@typedef
してもいいんですが、paizaの問題レベルのコード量だと頭に固めた方がやりやすい気がします。どうせInfoの中でも型定義使うことになりますし。
getAnswer
読んで字のごとくinfoを受けてanswerを返す関数です。ここにだら書きして肥大化 or 最初から明確に切り出した方がいいと検討ついたら、getAnswer
とgetInfo
の間のスペースに関数として切り出す感じですね。A~Bランクだと大体2個ぐらい切り出してますね。
あと直接console.logに出力してるので、回答データから特定の書式への変換(配列から半角スペース区切りの文字列化等)が必要な場合もこの関数の責務になります。