Created
December 14, 2023 12:07
-
-
Save gigobyte/775524266192ad4e3c3ef78ba649a83e to your computer and use it in GitHub Desktop.
Tech night
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
type input = `Card 1: 41 48 83 86 17 | 83 86 6 31 17 9 48 53 | |
Card 2: 13 32 20 16 61 | 61 30 68 82 17 32 24 19 | |
Card 3: 1 21 53 59 44 | 69 82 63 72 16 21 14 1 | |
Card 4: 41 92 73 84 69 | 59 84 76 51 58 5 54 83 | |
Card 5: 87 83 26 28 32 | 88 30 70 12 93 22 82 36 | |
Card 6: 31 18 13 56 72 | 74 77 10 23 35 67 36 11`; | |
type Split< | |
Str extends string, | |
Separator extends string, | |
Result extends string[] = [] | |
> = Str extends `${infer chunk}${Separator}${infer restOfString}` | |
? Split<restOfString, Separator, [...Result, chunk]> | |
: [...Result, Str]; | |
type RemovePrefix< | |
Str extends string, | |
Prefix extends string | |
> = Str extends `${Prefix}${infer restOfString}` ? restOfString : Str; | |
type RemovePrefixes< | |
Strings extends string[], | |
Prefix extends string, | |
Result extends string[] = [] | |
> = Strings extends [infer head extends string, ...infer tail extends string[]] | |
? RemovePrefixes<tail, Prefix, [...Result, RemovePrefix<head, Prefix>]> | |
: Result; | |
type ParseNumber<T extends string> = T extends `${infer n extends number}` | |
? n | |
: -1; | |
type ParseNumbers< | |
Strings extends string[], | |
Result extends number[] = [] | |
> = Strings extends [infer head extends string, ...infer tail extends string[]] | |
? ParseNumbers<tail, [...Result, ParseNumber<head>]> | |
: Result; | |
type ParseCard<Str extends string> = | |
Str extends `${infer winningNumbers} | ${infer pickedNumbers}` | |
? [ | |
ParseNumbers<Split<winningNumbers, " ">>, | |
ParseNumbers<Split<pickedNumbers, " ">> | |
] | |
: never; | |
type ParseCards< | |
Strings extends string[], | |
Result extends any[] = [] | |
> = Strings extends [infer head extends string, ...infer tail extends string[]] | |
? ParseCards<tail, [...Result, ParseCard<head>]> | |
: Result; | |
type Filter< | |
Arr extends any[], | |
Unwanted, | |
Result extends any[] = [] | |
> = Arr extends [infer head, ...infer tail] | |
? head extends Unwanted | |
? Filter<tail, Unwanted, Result> | |
: Filter<tail, Unwanted, [...Result, head]> | |
: Result; | |
type FilterInvalidNumbers<Cards, Result extends any[] = []> = Cards extends [ | |
infer head extends [any[], any[]], | |
...infer tail | |
] | |
? FilterInvalidNumbers< | |
tail, | |
[...Result, [Filter<head[0], -1>, Filter<head[1], -1>]] | |
> | |
: Result; | |
type Intersect< | |
Arr1 extends any[], | |
Arr2 extends any[], | |
Result extends any[] = [] | |
> = Arr1 extends [infer fst, ...infer rest] | |
? fst extends Arr2[number] | |
? Intersect<rest, Arr2, [...Result, fst]> | |
: Intersect<rest, Arr2, Result> | |
: Result; | |
type GetWinningNumbersCount< | |
ParsedCards, | |
Result extends any[] = [] | |
> = ParsedCards extends [infer head extends [any[], any[]], ...infer tail] | |
? GetWinningNumbersCount< | |
tail, | |
[...Result, Intersect<head[0], head[1]>["length"]] | |
> | |
: Result; | |
type ArrayOfNLength< | |
Length, | |
Result extends any[] = [] | |
> = Result["length"] extends Length | |
? Result | |
: ArrayOfNLength<Length, [...Result, any]>; | |
type Add<T, U> = [...ArrayOfNLength<T>, ...ArrayOfNLength<U>]["length"]; | |
type Pop<Arr> = Arr extends [infer _, ...infer tail] ? tail : never; | |
type PopNTimes< | |
Arr, | |
Times, | |
Looper extends any[] = ArrayOfNLength<Times> | |
> = Looper["length"] extends 0 ? Arr : PopNTimes<Pop<Arr>, Times, Pop<Looper>>; | |
type Subtract<T, U> = PopNTimes< | |
ArrayOfNLength<T>, | |
U | |
> extends infer result extends any[] | |
? result["length"] | |
: never; | |
type Multiply<T, U> = U extends 1 ? T : Add<T, Multiply<T, Subtract<U, 1>>>; | |
type Pow<T, U> = U extends 0 | |
? 1 | |
: U extends 1 | |
? T | |
: Multiply<T, Pow<T, Subtract<U, 1>>>; | |
type CalculateScore<T extends number> = T extends 0 | |
? 0 | |
: Pow<2, Subtract<T, 1>>; | |
type GetScores< | |
Numbers extends any[], | |
Result extends any[] = [] | |
> = Numbers extends [infer head extends number, ...infer tail] | |
? GetScores<tail, [...Result, CalculateScore<head>]> | |
: Result; | |
type Sum<Arr, Acc extends number = 0> = Arr extends [ | |
infer fst extends number, | |
...infer rest | |
] | |
? Sum< | |
rest, | |
Add<fst, Acc> extends infer result extends number ? result : never | |
> | |
: Acc; | |
type result = Sum< | |
GetScores< | |
GetWinningNumbersCount< | |
FilterInvalidNumbers< | |
ParseCards<RemovePrefixes<Split<input, "\n">, `Card ${string}: `>> | |
> | |
> | |
> | |
>; | |
const start = performance.now(); | |
const result: result = 13; | |
const end = performance.now(); | |
console.log(`Result: ${result}, execution time: ${end - start}ms`); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment