diff --git a/README.md b/README.md index ca64350..875c488 100644 --- a/README.md +++ b/README.md @@ -5,3 +5,4 @@ | Day | Name | Part 1 | Part 2 | | :-: | :-------------- | :----: | :----: | | 1 | Secret Entrance | ⭐ | ⭐ | +| 2 | Gift Shop | ⭐ | ⭐ | diff --git a/src/__tests__/day_2_test.ts b/src/__tests__/day_2_test.ts new file mode 100644 index 0000000..b802a37 --- /dev/null +++ b/src/__tests__/day_2_test.ts @@ -0,0 +1,20 @@ +import { assertEquals } from "@std/assert"; +import { + count_invalid_ids_sum, + count_new_invalid_ids_sum, + read_id_ranges, +} from "../exercises/day_2.ts"; + +const FILE_PATH = "src/exercises/assets/day_2_test_input.txt"; + +Deno.test("Day 2 - A", async () => { + const id_ranges = await read_id_ranges(FILE_PATH); + const invalid_sum = count_invalid_ids_sum(id_ranges); + assertEquals(invalid_sum, 1227775554); +}); + +Deno.test("Day 2 - B", async () => { + const id_ranges = await read_id_ranges(FILE_PATH); + const invalid_sum = count_new_invalid_ids_sum(id_ranges); + assertEquals(invalid_sum, 4174379265); +}); diff --git a/src/exercises/assets/day_2_input.txt b/src/exercises/assets/day_2_input.txt new file mode 100644 index 0000000..cc522c9 --- /dev/null +++ b/src/exercises/assets/day_2_input.txt @@ -0,0 +1 @@ +385350926-385403705,48047-60838,6328350434-6328506208,638913-698668,850292-870981,656-1074,742552-796850,4457-6851,138-206,4644076-4851885,3298025-3353031,8594410816-8594543341,396-498,1558-2274,888446-916096,12101205-12154422,2323146444-2323289192,37-57,101-137,46550018-46679958,79-96,317592-341913,495310-629360,33246-46690,14711-22848,1-17,2850-4167,3723700171-3723785996,190169-242137,272559-298768,275-365,7697-11193,61-78,75373-110112,425397-451337,9796507-9899607,991845-1013464,77531934-77616074 diff --git a/src/exercises/assets/day_2_test_input.txt b/src/exercises/assets/day_2_test_input.txt new file mode 100644 index 0000000..a3f22ef --- /dev/null +++ b/src/exercises/assets/day_2_test_input.txt @@ -0,0 +1 @@ +11-22,95-115,998-1012,1188511880-1188511890,222220-222224,1698522-1698528,446443-446449,38593856-38593862,565653-565659,824824821-824824827,2121212118-2121212124 diff --git a/src/exercises/day_2.ts b/src/exercises/day_2.ts new file mode 100644 index 0000000..4ec77aa --- /dev/null +++ b/src/exercises/day_2.ts @@ -0,0 +1,95 @@ +interface Range { + init: number; + end: number; +} + +export default async function GiftShop() { + const input_ranges = await read_id_ranges( + "src/exercises/assets/day_2_input.txt", + ); + const invalid_id_count = count_invalid_ids_sum(input_ranges); + const new_invalid_id_count = count_new_invalid_ids_sum(input_ranges); + console.log(">> Invalid id count: ", invalid_id_count, new_invalid_id_count); +} + +// Repeating numbers are the invalid ids +// Leading zeroes are invalid ids +export function count_invalid_ids_sum(id_ranges: Range[]): number { + let invalid_id_sum: number = 0; + id_ranges.forEach((range) => { + for (let i = range.init; i <= range.end; i++) { + if (is_id_mirror(i)) { + invalid_id_sum += i; + } + } + }); + return invalid_id_sum; +} + +export function count_new_invalid_ids_sum(id_ranges: Range[]): number { + let invalid_id_sum: number = 0; + id_ranges.forEach((range) => { + for (let i = range.init; i <= range.end; i++) { + if (is_id_repeating(i)) { + invalid_id_sum += i; + } + } + }); + return invalid_id_sum; +} + +function is_id_repeating(id: number): boolean { + const str_id = id.toString(); + + if (str_id[0] === "0") { + return false; + } + + for (let size = 1; size <= str_id.length / 2; size++) { + const baselise_slice: string = str_id.slice(0, size); + + if (str_id.length % size !== 0) { + continue; + } + + let is_repeating = true; + + for (let pos = size; pos <= str_id.length - size; pos += size) { + const current_slice = str_id.slice(pos, pos + size); + + if (current_slice !== baselise_slice) { + is_repeating = false; + } + } + + if (is_repeating) { + return true; + } + } + + return false; +} + +function is_id_mirror(id: number): boolean { + const str_id = id.toString(); + if (str_id.length % 2 !== 0) { + return false; + } + const half_point = str_id.length / 2; + const left_side = str_id.slice(0, half_point); + const right_side = str_id.slice(half_point, str_id.length); + return left_side === right_side; +} + +export async function read_id_ranges(path: string): Promise { + const raw_ranges = await Deno.readTextFile(path); + const raw_range_array = raw_ranges.split(","); + const id_range_list: Range[] = raw_range_array.map((range) => { + const value_array = range.split("-"); + return { + init: parseInt(value_array[0]), + end: parseInt(value_array[1]), + }; + }); + return id_range_list; +}