enum Point { FILLED = "#", EMPTY = ".", } type Present = Point[][]; type Region = { width: number; height: number; }; interface Tree { region: Region; presents: number[]; } interface SituationSummary { presents: Present[]; trees: Tree[]; } export default async function ChristmasTreeFarm() { } function do_presents_fit(tree: Tree, presents: Present[]): boolean { } function do_present_pair_fit(tree: Tree, p_a: Present, p_b: Present): boolean { } function rotate_present_90_deg(present: Present): Present { } function flip_present_horizontal(present: Present): Present { } function flip_present_vertical(present: Present): Present { } export async function read_situation_summary( path: string, ): Promise { const txt_input = await Deno.readTextFile(path); // NOTE: should be done with splits to avoid performance issues on final sample const block_list = txt_input.split("\n\n"); const present_list: Present[] = []; const tree_list: Tree[] = []; block_list.forEach((block) => { if (block.includes("x")) { // Tree const raw_trees = block.split("\n"); raw_trees.forEach((t) => { if (!t || t.length < 1) { return; } const [raw_region, raw_presents] = t.split(": "); const region: Tree["region"] = { width: parseInt(raw_region.split("x")[0]), height: parseInt(raw_region.split("x")[1]), }; const presents: Tree["presents"] = raw_presents.split(" ").map((p) => { const p_n = parseInt(p); if (p_n === p_n) { return p_n; } return undefined; }).filter((p) => p !== undefined); tree_list.push({ region, presents }); }); } else { // Present const raw_present = block.split("\n").slice(1); const present: Present = raw_present.map((line) => line.split("").map((p) => p === Point.FILLED ? Point.FILLED : Point.EMPTY ) ); present_list.push(present); } }); return { presents: present_list, trees: tree_list, }; }