diff --git a/src/__tests__/day_9_test.ts b/src/__tests__/day_9_test.ts index 503888c..a6ed60e 100644 --- a/src/__tests__/day_9_test.ts +++ b/src/__tests__/day_9_test.ts @@ -1,5 +1,9 @@ import { assertEquals } from "@std/assert"; -import { get_largest_area, read_tile_floor } from "../exercises/day_9.ts"; +import { + get_largest_area, + get_largest_green_area, + read_tile_floor, +} from "../exercises/day_9.ts"; Deno.test("Day 9 - A", async () => { const floor = await read_tile_floor( @@ -8,3 +12,11 @@ Deno.test("Day 9 - A", async () => { const result = get_largest_area(floor); assertEquals(result, 50); }); + +Deno.test("Day 9 - B", async () => { + const floor = await read_tile_floor( + "src/exercises/assets/day_9_test_input.txt", + ); + const result = get_largest_green_area(floor); + assertEquals(result, 24); +}); diff --git a/src/exercises/day_9.ts b/src/exercises/day_9.ts index 37720ad..5e4579e 100644 --- a/src/exercises/day_9.ts +++ b/src/exercises/day_9.ts @@ -14,6 +14,10 @@ export default async function MovieTheater() { "src/exercises/assets/day_9_input.txt", ); console.log(">> Largest red-tile area: ", get_largest_area(floor)); + console.log( + ">> Largest red-green-tile area: ", + get_largest_green_area(floor), + ); } export function get_largest_area(floor: Floor): number { @@ -43,6 +47,87 @@ export function get_largest_area(floor: Floor): number { return largest_area; } +export function get_largest_green_area(floor: Floor): number { + let largest_area: number = 0; + floor.red_tiles.forEach((tile, tile_i) => { + for ( + let inner_i = tile_i + 1; + inner_i < floor.red_tiles.length; + inner_i++ + ) { + const inner_tile = floor.red_tiles[inner_i]; + if (is_area_red_green(floor, tile, inner_tile)) { + const height = calc_distance({ x: tile.x, y: tile.y }, { + x: tile.x, + y: inner_tile.y, + }); + const width = calc_distance({ x: tile.x, y: tile.y }, { + x: inner_tile.x, + y: tile.y, + }); + const new_area = (width + 1) * (height + 1); // NOTE: +1 to count also the outer tiles + if (new_area > largest_area) { + largest_area = new_area; + } + } + } + }); + + return largest_area; +} + +function is_area_red_green( + floor: Floor, + a: Coordinate, + b: Coordinate, +): boolean { + const max_x = Math.max(a.x, b.x); + const max_y = Math.max(a.y, b.y); + const min_x = Math.min(a.x, b.x); + const min_y = Math.min(a.y, b.y); + + const tl_corner: Coordinate = { x: min_x, y: min_y }; + const tr_corner: Coordinate = { x: max_x, y: min_y }; + const bl_corner: Coordinate = { x: min_x, y: max_y }; + const br_corner: Coordinate = { x: max_x, y: max_y }; + + // Find valid closers + // Every corner needs to be surrounded + + // NOTE: I don't think this will be enough + // Maybe not cover corners and cover verticals + // l + const l_cover = + floor.red_tiles.some((tile) => + tile.x <= tl_corner.x && tile.y <= tl_corner.y + ) && floor.red_tiles.some((tile) => + tile.x <= bl_corner.x && tile.y >= bl_corner.y + ); + // r + const r_cover = + floor.red_tiles.some((tile) => + tile.x >= tr_corner.x && tile.y <= tr_corner.y + ) && floor.red_tiles.some((tile) => + tile.x >= br_corner.x && tile.y >= br_corner.y + ); + // b + const b_cover = + floor.red_tiles.some((tile) => + tile.x <= bl_corner.x && tile.y >= bl_corner.y + ) && floor.red_tiles.some((tile) => + tile.x >= br_corner.x && tile.y >= br_corner.y + ); + // t + const t_cover = + floor.red_tiles.some((tile) => + tile.x <= tr_corner.x && tile.y <= tr_corner.y + ) && floor.red_tiles.some((tile) => + tile.x >= tl_corner.x && tile.y <= tl_corner.y + ); + + return l_cover && r_cover && b_cover && t_cover; +} + function calc_distance(a: Coordinate, b: Coordinate): number { return Math.sqrt(Math.pow(a.x - b.x, 2) + Math.pow(a.y - b.y, 2)); }