Created
December 3, 2023 09:41
-
-
Save mochaaP/d1b936b47355638209e2734eb3ea5f74 to your computer and use it in GitHub Desktop.
advent of code 2023 done wrong
This file contains 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
module AoC2023.Day01 where | |
import Data.Char (isDigit) | |
main :: IO () | |
main = do | |
res <- readFile "input/1.txt" | |
let i = lines res | |
-- part one | |
$ ( sum | |
. map | |
( \line -> | |
let n = filter isDigit line | |
in read [head n, last n] :: Int | |
) | |
) | |
i | |
-- part two | |
$ ( sum | |
. map | |
asNum | |
) | |
i | |
asNum :: String -> Int | |
asNum x = read [numl "" x, numr "" x] :: Int | |
numl :: String -> String -> Char | |
numl "" (x : xs) | |
| isDigit x = x | |
| otherwise = numl [x] xs | |
numl acc (x : xs) | |
| acc == "one" = '1' | |
| acc == "two" = '2' | |
| acc == "three" = '3' | |
| acc == "four" = '4' | |
| acc == "five" = '5' | |
| acc == "six" = '6' | |
| acc == "seven" = '7' | |
| acc == "eight" = '8' | |
| acc == "nine" = '9' | |
| isDigit x = x | |
| otherwise = numl (acc ++ [x]) xs | |
numr :: String -> String -> Char | |
numr "" x | |
| isDigit $ last x = last x | |
| otherwise = numr [last x] $ init x | |
numr acc x | |
| acc == "one" = '1' | |
| acc == "two" = '2' | |
| acc == "three" = '3' | |
| acc == "four" = '4' | |
| acc == "five" = '5' | |
| acc == "six" = '6' | |
| acc == "seven" = '7' | |
| acc == "eight" = '8' | |
| acc == "nine" = '9' | |
| isDigit $ last x = last x | |
| otherwise = numr (last x : acc) (init x) |
This file contains 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
namespace Multiply { | |
type Reverse<A extends string | number | bigint> = | |
`${A}` extends `${infer AH}${infer AT}` ? `${Reverse<AT>}${AH}` : ""; | |
type DigsNext = { | |
"0": "1"; | |
"1": "2"; | |
"2": "3"; | |
"3": "4"; | |
"4": "5"; | |
"5": "6"; | |
"6": "7"; | |
"7": "8"; | |
"8": "9"; | |
}; | |
type DigsPrev = { [K in keyof DigsNext as DigsNext[K]]: K }; | |
type AddOne<A> = A extends `${infer AH}${infer AT}` | |
? AH extends "9" | |
? `0${AddOne<AT>}` | |
: `${DigsNext[AH & keyof DigsNext]}${AT}` | |
: "1"; | |
type SubOne<A> = A extends `${infer AH}${infer AT}` | |
? AH extends "0" | |
? `9${SubOne<AT>}` | |
: `${DigsPrev[AH & keyof DigsPrev]}${AT}` | |
: never; | |
type Add<A, B> = A extends `${infer AH}${infer AT}` | |
? B extends `${infer BH}${infer BT}` | |
? BH extends "0" | |
? `${AH}${Add<AT, BT>}` | |
: Add<AddOne<A>, SubOne<B>> | |
: A | |
: B; | |
type Mul<A extends string, B extends string, R = "0"> = A extends "0" | |
? R | |
: B extends "0" | |
? R | |
: A extends `${infer AH}${infer AT}` | |
? AH extends "0" | |
? Mul<AT, `0${B}`, R> | |
: Mul<SubOne<A>, B, Add<R, B>> | |
: R; | |
export type Multiply< | |
A extends string | number | bigint, | |
B extends string | number | bigint, | |
> = Reverse<Mul<Reverse<A>, Reverse<B>>>; | |
} | |
namespace Sum { | |
type Or<left extends boolean, right extends boolean> = left extends true | |
? true | |
: right extends true | |
? true | |
: false; | |
type CoalesceToString<n extends string | number | bigint> = n extends string | |
? n | |
: `${n}`; | |
type Digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"; | |
type SubOneFromDigit<digit extends Digit> = digit extends "1" | |
? "0" | |
: digit extends "2" | |
? "1" | |
: digit extends "3" | |
? "2" | |
: digit extends "4" | |
? "3" | |
: digit extends "5" | |
? "4" | |
: digit extends "6" | |
? "5" | |
: digit extends "7" | |
? "6" | |
: digit extends "8" | |
? "7" | |
: digit extends "9" | |
? "8" | |
: digit extends "10" | |
? "9" | |
: never; | |
type AddOneToDigit<digit extends Digit> = digit extends "0" | |
? { result: "1"; carry: false } | |
: digit extends "1" | |
? { result: "2"; carry: false } | |
: digit extends "2" | |
? { result: "3"; carry: false } | |
: digit extends "3" | |
? { result: "4"; carry: false } | |
: digit extends "4" | |
? { result: "5"; carry: false } | |
: digit extends "5" | |
? { result: "6"; carry: false } | |
: digit extends "6" | |
? { result: "7"; carry: false } | |
: digit extends "7" | |
? { result: "8"; carry: false } | |
: digit extends "8" | |
? { result: "9"; carry: false } | |
: digit extends "9" | |
? { result: "0"; carry: true } | |
: never; | |
type SingleDigitSumResult<result extends Digit, carry extends boolean> = { | |
result: result; | |
carry: carry; | |
}; | |
type SumSingleDigits< | |
left extends Digit, | |
right extends Digit, | |
carryIn extends boolean = false, | |
carryOut extends boolean = false, | |
> = carryIn extends true | |
? AddOneToDigit<left> extends SingleDigitSumResult< | |
infer leftIncremented, | |
infer carryOutFromIncrement | |
> | |
? SumSingleDigits<leftIncremented, right, false, carryOutFromIncrement> | |
: never | |
: right extends "0" | |
? { result: left; carry: carryOut } | |
: AddOneToDigit<left> extends SingleDigitSumResult< | |
infer leftIncremented, | |
infer carryOutFromIncrement | |
> | |
? SumSingleDigits< | |
leftIncremented, | |
SubOneFromDigit<right>, | |
false, | |
Or<carryOut, carryOutFromIncrement> | |
> | |
: never; | |
type RightMostDigitResult<rest extends string, digit extends Digit> = { | |
rest: rest; | |
digit: digit; | |
}; | |
type RightMostDigit<s extends string> = s extends `${infer rest}${Digit}` | |
? s extends `${rest}${infer digit}` | |
? { rest: rest; digit: digit } | |
: never | |
: never; | |
type SumStrings< | |
left extends string, | |
right extends string, | |
accumulatedResultDigits extends string = "", | |
carry extends boolean = false, | |
> = "" extends left | |
? // Left is empty | |
"" extends right | |
? // Right is empty | |
carry extends true | |
? `1${accumulatedResultDigits}` | |
: accumulatedResultDigits | |
: // Right has value | |
RightMostDigit<right> extends RightMostDigitResult< | |
infer remainingRight, | |
infer rightDigit | |
> | |
? SumSingleDigits<"0", rightDigit, carry> extends SingleDigitSumResult< | |
infer resultDigit, | |
infer resultCarry | |
> | |
? SumStrings< | |
"", | |
remainingRight, | |
`${resultDigit}${accumulatedResultDigits}`, | |
resultCarry | |
> | |
: never | |
: never | |
: // Left has value | |
"" extends right | |
? // Right has no value | |
RightMostDigit<left> extends RightMostDigitResult< | |
infer remainingLeft, | |
infer leftDigit | |
> | |
? SumSingleDigits<"0", leftDigit, carry> extends SingleDigitSumResult< | |
infer resultDigit, | |
infer resultCarry | |
> | |
? SumStrings< | |
remainingLeft, | |
"", | |
`${resultDigit}${accumulatedResultDigits}`, | |
resultCarry | |
> | |
: never | |
: never | |
: // Right has value | |
RightMostDigit<left> extends RightMostDigitResult< | |
infer remainingLeft, | |
infer leftDigit | |
> | |
? RightMostDigit<right> extends RightMostDigitResult< | |
infer remainingRight, | |
infer rightDigit | |
> | |
? SumSingleDigits< | |
leftDigit, | |
rightDigit, | |
carry | |
> extends SingleDigitSumResult<infer resultDigit, infer resultCarry> | |
? SumStrings< | |
remainingLeft, | |
remainingRight, | |
`${resultDigit}${accumulatedResultDigits}`, | |
resultCarry | |
> | |
: never | |
: never | |
: never; | |
export type Sum< | |
left extends string | number | bigint, | |
right extends string | number | bigint, | |
> = SumStrings<CoalesceToString<left>, CoalesceToString<right>>; | |
} | |
namespace Comparison { | |
export type Lower = -1; | |
export type Equal = 0; | |
export type Greater = 1; | |
export type Comparator< | |
A extends number | string, | |
B extends number | string, | |
> = ComparePositives<`${A}`, `${B}`>; | |
// Compares two positive long numbers | |
type ComparePositives< | |
A extends string, | |
B extends string, | |
ByLength = CompareByLength<A, B>, | |
> = ByLength extends Comparison.Equal ? CompareByDigits<A, B> : ByLength; | |
// Compares two strings by length | |
type CompareByLength< | |
A extends string, | |
B extends string, | |
> = A extends `${infer _}${infer AR}` | |
? B extends `${infer _}${infer BR}` | |
? CompareByLength<AR, BR> | |
: Comparison.Greater | |
: B extends `${infer _}${infer __}` | |
? Comparison.Lower | |
: Comparison.Equal; | |
// Compares two positive long numbers of the same length | |
type CompareByDigits< | |
A extends string, | |
B extends string, | |
> = `${A}|${B}` extends `${infer AF}${infer AR}|${infer BF}${infer BR}` | |
? CompareDigits<AF, BF> extends Comparison.Equal | |
? CompareByDigits<AR, BR> | |
: CompareDigits<AF, BF> | |
: Comparison.Equal; | |
// Compares two digits | |
type CompareDigits<A extends string, B extends string> = A extends B | |
? Comparison.Equal | |
: "0123456789" extends `${string}${A}${string}${B}${string}` | |
? Comparison.Lower | |
: Comparison.Greater; | |
} | |
import Input from "./input/2.ts"; | |
type Color = "red" | "green" | "blue"; | |
type AllTrySatisfied<T extends Try[]> = T extends [infer A extends Try] | |
? Satisfies<A> | |
: T extends [infer A extends Try, ...infer Rest extends Try[]] | |
? Satisfies<A> & AllTrySatisfied<Rest> | |
: never; | |
type Attempt<T extends string> = T extends `${infer A}; ${infer Rest}` | |
? [Count<A>, ...Attempt<Rest>] | |
: T extends `${infer A}` | |
? [Count<A>] | |
: never; | |
type Count<T extends string> = | |
T extends `${infer N extends number} ${infer K extends Color}, ${infer Rest}` | |
? { [_ in K]: N } & { [R in keyof Count<Rest>]: Count<Rest>[R] } | |
: T extends `${infer N extends number} ${infer K extends Color}` | |
? { [_ in K]: N } | |
: never; | |
type MergedGame<T extends string> = T extends `${number}: ${infer F}` | |
? MergeAttempt<Attempt<F>> extends { | |
red: infer R extends number; | |
green: infer G extends number; | |
blue: infer B extends number; | |
} | |
? Multiply.Multiply< | |
Multiply.Multiply<R, G>, | |
B | |
> extends `${infer N extends number}` | |
? N | |
: never | |
: 0 | |
: never; | |
type GameSatisfied<T extends string> = | |
T extends `${infer I extends number}: ${infer F}` | |
? AllTrySatisfied<Attempt<F>> extends never | |
? 0 | |
: I | |
: never; | |
type Satisfies<T extends Try> = (T["red"] extends number | |
? Comparison.Comparator<T["red"], 12> extends | |
| Comparison.Equal | |
| Comparison.Lower | |
? true | |
: false | |
: true) & | |
(T["green"] extends number | |
? Comparison.Comparator<T["green"], 13> extends | |
| Comparison.Equal | |
| Comparison.Lower | |
? true | |
: false | |
: true) & | |
(T["blue"] extends number | |
? Comparison.Comparator<T["blue"], 14> extends | |
| Comparison.Equal | |
| Comparison.Lower | |
? true | |
: false | |
: true); | |
type MergeAttempt<T extends Try[]> = T extends [infer x extends Try] | |
? x | |
: T extends [infer x extends Try, ...infer xs extends Try[]] | |
? MergeTry<x, MergeAttempt<xs>> | |
: never; | |
type MergeTry<L extends Try, R extends Try> = { | |
red: L["red"] extends number | |
? R["red"] extends number | |
? Comparison.Comparator<L["red"], R["red"]> extends | |
| Comparison.Equal | |
| Comparison.Greater | |
? L["red"] | |
: R["red"] | |
: L["red"] | |
: R["red"]; | |
green: L["green"] extends number | |
? R["green"] extends number | |
? Comparison.Comparator<L["green"], R["green"]> extends | |
| Comparison.Equal | |
| Comparison.Greater | |
? L["green"] | |
: R["green"] | |
: L["green"] | |
: R["green"]; | |
blue: L["blue"] extends number | |
? R["blue"] extends number | |
? Comparison.Comparator<L["blue"], R["blue"]> extends | |
| Comparison.Equal | |
| Comparison.Greater | |
? L["blue"] | |
: R["blue"] | |
: L["blue"] | |
: R["blue"]; | |
}; | |
type Try = { [_ in Color]?: number }; | |
type MergedTry<Line extends string> = | |
Line extends `Game ${infer G}\nGame ${infer G_}\nGame ${infer G__}\n${infer More}` | |
? [MergedGame<G>, MergedGame<G_>, MergedGame<G__>, ...MergedTry<More>] | |
: Line extends `Game ${infer G}\nGame ${infer G_}\n${infer More}` | |
? [MergedGame<G>, MergedGame<G_>, ...MergedTry<More>] | |
: Line extends `Game ${infer G}\n${infer More}` | |
? [MergedGame<G>, ...MergedTry<More>] | |
: Line extends `Game ${infer G}` | |
? [MergedGame<G>] | |
: never; | |
type Satisfied<Line extends string> = | |
Line extends `Game ${infer G}\nGame ${infer G_}\nGame ${infer G__}\n${infer More}` | |
? [ | |
GameSatisfied<G>, | |
GameSatisfied<G_>, | |
GameSatisfied<G__>, | |
...Satisfied<More>, | |
] | |
: Line extends `Game ${infer G}\nGame ${infer G_}\n${infer More}` | |
? [GameSatisfied<G>, GameSatisfied<G_>, ...Satisfied<More>] | |
: Line extends `Game ${infer G}\n${infer More}` | |
? [GameSatisfied<G>, ...Satisfied<More>] | |
: Line extends `Game ${infer G}` | |
? [GameSatisfied<G>] | |
: never; | |
type Trys = MergedTry<typeof Input>; | |
type Sums = Satisfied<typeof Input>; | |
type CalcSum<T extends number[]> = T extends [infer Con extends number] | |
? Con | |
: T extends [infer Con extends number, ...infer Rest extends number[]] | |
? Sum.Sum<Con, CalcSum<Rest>> extends `${infer N extends number}` | |
? N | |
: never | |
: T extends [ | |
infer Con extends number, | |
infer Cons extends number, | |
...infer Rest extends number[], | |
] | |
? Sum.Sum< | |
Sum.Sum<Con, Cons>, | |
CalcSum<Rest> | |
> extends `${infer N extends number}` | |
? N | |
: never | |
: never; | |
type Chunk< | |
T extends unknown[], | |
N extends number, | |
Swap extends unknown[] = [], | |
> = Swap["length"] extends N | |
? [Swap, ...Chunk<T, N>] | |
: T extends [infer K, ...infer L] | |
? Chunk<L, N, [...Swap, K]> | |
: Swap extends [] | |
? Swap | |
: [Swap]; | |
type ChunkedCalcSum<T extends number[][]> = T extends [ | |
infer Con extends number[], | |
] | |
? CalcSum<Con> | |
: T extends [infer Con extends number[], ...infer Rest extends number[][]] | |
? Sum.Sum< | |
CalcSum<Con>, | |
ChunkedCalcSum<Rest> | |
> extends `${infer N extends number}` | |
? N | |
: never | |
: never; | |
type ChunkedSum = Chunk<Sums, 10>; | |
type ChunkedTrys = Chunk<Trys, 10>; | |
export type Solution1 = ChunkedCalcSum<ChunkedSum>; | |
export type Solution2 = ChunkedCalcSum<ChunkedTrys>; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment