this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

use workers!

+68 -13
+38
2023/day05/part2-worker.ts
··· 1 + import { assert } from "https://deno.land/std@0.208.0/assert/mod.ts"; 2 + import { MapRanges } from "./part2.ts"; 3 + 4 + type MessageData = { 5 + range: [number, number]; 6 + mapRanges: MapRanges[]; 7 + }; 8 + 9 + self.onmessage = ({ data: { range, mapRanges } }: { data: MessageData }) => { 10 + const [from, to] = range; 11 + console.log(`(start) worker ${from}-${to}`); 12 + let minLocNum = Infinity; 13 + for (let j = 0; j < to - from; j++) { 14 + const seed = from + j; 15 + const locNum = getLocationNumber(seed, mapRanges); 16 + if (locNum < minLocNum) minLocNum = locNum; 17 + } 18 + self.postMessage({ minLocNum }); 19 + console.log(`(end) worker ${from}-${to}: ${minLocNum}`); 20 + self.close(); 21 + }; 22 + 23 + function getLocationNumber(seed: number, mapRanges: MapRanges[]): number { 24 + let current = "seed"; 25 + let currentNum = seed; 26 + while (current !== "location") { 27 + const mapRange = mapRanges.find(({ from }) => from === current); 28 + assert(mapRange, `mapRange not found for: ${current}`); 29 + 30 + const range = mapRange.ranges.find( 31 + (r) => currentNum >= r.fromStart && currentNum <= r.fromStart + r.range, 32 + ); 33 + if (range) currentNum = currentNum + (range.toStart - range.fromStart); 34 + 35 + current = mapRange.to; 36 + } 37 + return currentNum; 38 + }
+30 -13
2023/day05/part2.ts
··· 9 9 console.log(await answer(input)); 10 10 } 11 11 12 - type Range = { 12 + export type Range = { 13 13 fromStart: number; 14 14 toStart: number; 15 15 range: number; 16 16 }; 17 17 18 - type MapRanges = { 18 + export type MapRanges = { 19 19 from: string; 20 20 to: string; 21 21 ranges: Range[]; ··· 50 50 const to = from + seedRangeLines[i + 1]; 51 51 seedRanges.push([from, to]); 52 52 } 53 - const rangeMins = await Promise.all( 54 - seedRanges.map( 55 - ([from, to]) => 56 - new Promise<number>((resolve) => { 57 - let minLocNum = Infinity; 58 - for (let j = 0; j < to - from; j++) { 59 - const seed = from + j; 60 - const locNum = getLocationNumber(seed, mapRanges); 61 - if (locNum < minLocNum) minLocNum = locNum; 62 - } 63 - return resolve(minLocNum); 53 + 54 + const rangeMins: number[] = await Promise.all( 55 + splitRanges(seedRanges).map( 56 + (range) => 57 + new Promise((resolve, reject) => { 58 + const worker = new Worker( 59 + new URL("./part2-worker.ts", import.meta.url).href, 60 + { 61 + type: "module", 62 + }, 63 + ); 64 + worker.postMessage({ range, mapRanges }); 65 + worker.onmessage = ({ data }) => { 66 + if (typeof data?.minLocNum !== "number") { 67 + return reject(new Error(`invalid message: ${data}`)); 68 + } 69 + return resolve(data.minLocNum); 70 + }; 64 71 }), 65 72 ), 66 73 ); 67 74 68 75 return Math.min(...rangeMins); 76 + } 77 + 78 + function splitRanges(ranges: [number, number][]): [number, number][] { 79 + const newRanges: [number, number][] = []; 80 + for (const [from, to] of ranges) { 81 + const middle = Math.ceil(from + (to - from) / 2); 82 + newRanges.push([from, middle]); 83 + newRanges.push([middle + 1, to]); 84 + } 85 + return newRanges; 69 86 } 70 87 71 88 function getLocationNumber(seed: number, mapRanges: MapRanges[]): number {