Skip to content

Commit

Permalink
Merge pull request #1 from peter-afs/master
Browse files Browse the repository at this point in the history
hide solutions
  • Loading branch information
kelsny committed Dec 25, 2023
2 parents 88ff188 + 4714620 commit c917f56
Show file tree
Hide file tree
Showing 32 changed files with 126 additions and 120 deletions.
3 changes: 1 addition & 2 deletions src/DeleteCharacter.ts
Expand Up @@ -11,8 +11,7 @@
*/

import { Assert, Equals } from "./common";

type DeleteCharacter<S extends string, C extends string> = S extends `${infer A}${C}${infer B}` ? DeleteCharacter<`${A}${B}`, C> : S;
import { DeleteCharacter } from "./solutions/DeleteCharacter";

type T01 = Assert<Equals<DeleteCharacter<"hello world", "o">, "hell wrld">>;
type T02 = Assert<Equals<DeleteCharacter<"hate this challenge", "h">, "ate tis callenge">>;
Expand Down
3 changes: 1 addition & 2 deletions src/EachAsSingle.ts
Expand Up @@ -11,8 +11,7 @@
*/

import { Assert, Equals, Never } from "./common";

type EachAsSingle<T> = T extends T ? { wrapped: T } : never;
import { EachAsSingle } from "./solutions/EachAsSingle";

type T01 = Assert<
Equals<
Expand Down
8 changes: 1 addition & 7 deletions src/FirstFew.ts
Expand Up @@ -11,13 +11,7 @@
*/

import { Assert, Equals } from "./common";
import { Increment, UnknownArray } from "./utility";

type FirstFew<T extends UnknownArray, N extends number = 0, R extends UnknownArray = [], I extends number = 0> = I extends N
? R
: T[I] extends undefined
? R
: FirstFew<T, N, [...R, T[I]], Increment[I]>;
import { FirstFew } from "./solutions/FirstFew";

type T01 = Assert<Equals<FirstFew<[1, 2, 3, 4, 5], 3>, [1, 2, 3]>>;
type T02 = Assert<Equals<FirstFew<[], 0>, []>>;
Expand Down
3 changes: 1 addition & 2 deletions src/IncludesString.ts
Expand Up @@ -11,8 +11,7 @@
*/

import { Assert, Equals } from "./common";

type IncludesString<S extends string, C extends string> = S extends `${string}${C}${string}` ? true : false;
import { IncludesString } from "./solutions/IncludesString";

type T01 = Assert<Equals<IncludesString<"a long string for testing", "string" | "for">, true>>;
type T02 = Assert<Equals<IncludesString<"a long string for testing", "ing">, true>>;
Expand Down
3 changes: 1 addition & 2 deletions src/IsEven.ts
Expand Up @@ -11,8 +11,7 @@
*/

import { Assert, Equals } from "./common";

type IsEven<N extends number> = `${N}` extends `${string}${"0" | "2" | "4" | "6" | "8"}` ? true : false;
import { IsEven } from "./solutions/IsEven";

type T01 = Assert<Equals<IsEven<0>, true>>;
type T02 = Assert<Equals<IsEven<42>, true>>;
Expand Down
3 changes: 1 addition & 2 deletions src/IsNever.ts
Expand Up @@ -11,8 +11,7 @@
*/

import { Assert, Equals } from "./common";

type IsNever<T> = [T] extends [never] ? true : false;
import { IsNever } from "./solutions/IsNever";

type T01 = Assert<Equals<IsNever<void>, false>>;
type T02 = Assert<Equals<IsNever<unknown>, false>>;
Expand Down
3 changes: 1 addition & 2 deletions src/IsNotNumberLiteral.ts
Expand Up @@ -11,8 +11,7 @@
*/

import { Assert, Equals } from "./common";

type IsNotNumberLiteral<T> = T extends number ? (0 extends T ? (1 extends T ? false : true) : true) : never;
import { IsNotNumberLiteral } from "./solutions/IsNotNumberLiteral";

type T01 = Assert<Equals<IsNotNumberLiteral<number>, false>>;
type T02 = Assert<Equals<IsNotNumberLiteral<string>, never>>;
Expand Down
3 changes: 1 addition & 2 deletions src/MakeExciting.ts
Expand Up @@ -11,8 +11,7 @@
*/

import { Assert, Equals } from "./common";

type MakeExciting<S extends string> = `${S}!`;
import { MakeExciting } from "./solutions/MakeExciting";

type T01 = Assert<Equals<MakeExciting<"hello world">, "hello world!">>;
type T02 = Assert<Equals<MakeExciting<"">, "!">>;
Expand Down
44 changes: 1 addition & 43 deletions src/MergeSort.ts
Expand Up @@ -11,49 +11,7 @@
*/

import { Assert, Equals, Unreadonly } from "./common";
import { Decrement, UnknownArray } from "./utility";

type GreaterThan<A extends number, B extends number> = A extends B ? false : B extends 0 ? true : A extends 0 ? false : GreaterThan<Decrement[A], Decrement[B]>;

type Merge<Left extends UnknownArray, Right extends UnknownArray, Result extends UnknownArray = readonly []> = Left extends readonly []
? readonly [...Result, ...Right]
: Right extends readonly []
? readonly [...Result, ...Left]
: Left extends readonly [infer LFirst, ...infer LRest]
? Right extends readonly [infer RFirst, ...infer RRest]
? RFirst extends number
? LFirst extends number
? GreaterThan<RFirst, LFirst> extends true
? Merge<LRest, Right, readonly [...Result, LFirst]>
: Merge<Left, RRest, readonly [...Result, RFirst]>
: never
: never
: never
: never;

type Halves<
Target extends UnknownArray,
Left extends UnknownArray = readonly [],
Right extends UnknownArray = readonly []
> = `${Target["length"]}` extends `${string}${"1" | "3" | "5" | "7" | "9"}`
? Target extends readonly [...infer Rest, infer Last]
? Halves<Rest, readonly [], readonly [Last]>
: never
: Target extends readonly []
? readonly [Left, Right]
: Target extends readonly [infer LFirst, ...infer Rest, infer RFirst]
? Halves<Rest, readonly [...Left, LFirst], readonly [RFirst, ...Right]>
: never;

type MergeSort<M extends UnknownArray> = M extends readonly [] | readonly [unknown]
? M
: Halves<M> extends readonly [infer Left, infer Right]
? Left extends UnknownArray
? Right extends UnknownArray
? Merge<MergeSort<Left>, MergeSort<Right>>
: never
: never
: never;
import { MergeSort } from "./solutions/MergeSort";

type T01 = Assert<Equals<Unreadonly<MergeSort<[1, 2, 3]>>, [1, 2, 3]>>;
type T02 = Assert<Equals<Unreadonly<MergeSort<[1, 2, 3, 4, 5]>>, [1, 2, 3, 4, 5]>>;
Expand Down
30 changes: 1 addition & 29 deletions src/MiddleCharacter.ts
Expand Up @@ -11,35 +11,7 @@
*/

import { Assert, Equals } from "./common";
import { UnknownArray } from "./utility";

type Split<S extends string, R extends UnknownArray = readonly []> = S extends `${infer C}${infer M}` ? Split<M, readonly [...R, C]> : R;

type IsOdd<N extends number> = `${N}` extends `${string}${"1" | "3" | "5" | "7" | "9"}` ? true : false;

type Halves<Target extends UnknownArray, Left extends UnknownArray = readonly [], Right extends UnknownArray = readonly []> = IsOdd<
Target["length"]
> extends true
? Target extends readonly [...infer Rest, infer Last]
? Halves<Rest, readonly [], readonly [Last]>
: never
: Target extends readonly []
? readonly [Left, Right]
: Target extends readonly [infer LFirst, ...infer Rest, infer RFirst]
? Halves<Rest, readonly [...Left, LFirst], readonly [RFirst, ...Right]>
: never;

type MiddleCharacter<S extends string> = IsOdd<Split<S>["length"]> extends true
? Halves<Split<S>> extends readonly [unknown, readonly [infer C, ...unknown[]]]
? C
: never
: Halves<Split<S>> extends readonly [readonly [...unknown[], infer A], readonly [infer B, ...unknown[]]]
? A extends string
? B extends string
? `${A}${B}`
: never
: never
: "";
import { MiddleCharacter } from "./solutions/MiddleCharacter";

type T01 = Assert<Equals<MiddleCharacter<"challenge">, "l">>;
type T02 = Assert<Equals<MiddleCharacter<"challenger">, "le">>;
Expand Down
9 changes: 1 addition & 8 deletions src/NoOverlappingKeys.ts
Expand Up @@ -11,14 +11,7 @@
*/

import { Assert, Equals, Never } from "./common";

type NoOverlappingKeys<A, B> = [
{
[K in keyof A]: K extends keyof B ? true : never;
}[keyof A]
] extends [never]
? A & B
: never;
import { NoOverlappingKeys } from "./solutions/NoOverlappingKeys";

type T01 = Assert<Equals<NoOverlappingKeys<{}, {}>, {}>>;
type T02 = Assert<Equals<Never<NoOverlappingKeys<{ foo: number }, { foo: string }>>, true>>;
Expand Down
3 changes: 1 addition & 2 deletions src/PeriodsToUnderscores.ts
Expand Up @@ -11,8 +11,7 @@
*/

import { Assert, Equals } from "./common";

type PeriodsToUnderscores<S extends string> = S extends `${infer A}.${infer B}` ? `${A}_${PeriodsToUnderscores<B>}` : S;
import { PeriodsToUnderscores } from "./solutions/PeriodsToUnderscores";

type T01 = Assert<Equals<PeriodsToUnderscores<"a.b.c">, "a_b_c">>;
type T02 = Assert<Equals<PeriodsToUnderscores<"">, "">>;
Expand Down
6 changes: 1 addition & 5 deletions src/ReverseTuple.ts
Expand Up @@ -11,11 +11,7 @@
*/

import { Assert, Equals } from "./common";
import { RetainMutablity, UnknownArray } from "./utility";

type ReverseTuple<A, R extends UnknownArray = []> = A extends readonly [infer First, ...infer Rest]
? ReverseTuple<RetainMutablity<Rest, A>, [First, ...R]>
: RetainMutablity<R, A>;
import { ReverseTuple } from "./solutions/ReverseTuple";

type T01 = Assert<Equals<ReverseTuple<[1, 2, 3]>, [3, 2, 1]>>;
type T02 = Assert<Equals<ReverseTuple<[3, 2, 1]>, [1, 2, 3]>>;
Expand Down
5 changes: 1 addition & 4 deletions src/RoughlyIncludes.ts
Expand Up @@ -11,10 +11,7 @@
*/

import { Assert, Equals } from "./common";

type MakeMatcher<S extends string, R extends string = `${string}`> = S extends `${infer C}${infer M}` ? MakeMatcher<M, `${R}${C}${string}`> : R;

type RoughlyIncludes<Source extends string, Target extends string> = Source extends MakeMatcher<Target> ? true : false;
import { RoughlyIncludes } from "./solutions/RoughlyIncludes";

type T01 = Assert<Equals<RoughlyIncludes<"hhhhhhheeeeelllllllllllooooo", "hello">, true>>;
type T02 = Assert<Equals<RoughlyIncludes<"hhhhhhhlllllllllllooooo", "hello">, false>>;
Expand Down
4 changes: 1 addition & 3 deletions src/SplitString.ts
Expand Up @@ -11,9 +11,7 @@
*/

import { Assert, Equals } from "./common";
import { UnknownArray } from "./utility";

type SplitString<S extends string, R extends UnknownArray = []> = S extends `${infer C}${infer M}` ? SplitString<M, [...R, C]> : R;
import { SplitString } from "./solutions/SplitString";

type T01 = Assert<Equals<SplitString<"hi!">, ["h", "i", "!"]>>;
type T02 = Assert<Equals<SplitString<"">, []>>;
Expand Down
6 changes: 1 addition & 5 deletions src/SwapIndices.ts
Expand Up @@ -11,11 +11,7 @@
*/

import { Assert, Equals } from "./common";
import { UnknownArray } from "./utility";

type SwapIndices<A extends UnknownArray, T extends number, S extends number> = {
[K in keyof A]: `${T}` extends K ? A[S] : `${S}` extends K ? A[T] : A[K];
};
import { SwapIndices } from "./solutions/SwapIndices";

type T01 = Assert<Equals<SwapIndices<[1, 2, 3], 0, 2>, [3, 2, 1]>>;
type T02 = Assert<Equals<SwapIndices<[1, 2, 3], 0, 1>, [2, 1, 3]>>;
Expand Down
1 change: 1 addition & 0 deletions src/solutions/DeleteCharacter.ts
@@ -0,0 +1 @@
export type DeleteCharacter<S extends string, C extends string> = S extends `${infer A}${C}${infer B}` ? DeleteCharacter<`${A}${B}`, C> : S;
1 change: 1 addition & 0 deletions src/solutions/EachAsSingle.ts
@@ -0,0 +1 @@
export type EachAsSingle<T> = T extends T ? { wrapped: T } : never;
7 changes: 7 additions & 0 deletions src/solutions/FirstFew.ts
@@ -0,0 +1,7 @@
import { Increment, UnknownArray } from "../utility";

export type FirstFew<T extends UnknownArray, N extends number = 0, R extends UnknownArray = [], I extends number = 0> = I extends N
? R
: T[I] extends undefined
? R
: FirstFew<T, N, [...R, T[I]], Increment[I]>;
1 change: 1 addition & 0 deletions src/solutions/IncludesString.ts
@@ -0,0 +1 @@
export type IncludesString<S extends string, C extends string> = S extends `${string}${C}${string}` ? true : false;
1 change: 1 addition & 0 deletions src/solutions/IsEven.ts
@@ -0,0 +1 @@
export type IsEven<N extends number> = `${N}` extends `${string}${"0" | "2" | "4" | "6" | "8"}` ? true : false;
1 change: 1 addition & 0 deletions src/solutions/IsNever.ts
@@ -0,0 +1 @@
export type IsNever<T> = [T] extends [never] ? true : false;
1 change: 1 addition & 0 deletions src/solutions/IsNotNumberLiteral.ts
@@ -0,0 +1 @@
export type IsNotNumberLiteral<T> = T extends number ? (0 extends T ? (1 extends T ? false : true) : true) : never;
1 change: 1 addition & 0 deletions src/solutions/MakeExciting.ts
@@ -0,0 +1 @@
export type MakeExciting<S extends string> = `${S}!`;
43 changes: 43 additions & 0 deletions src/solutions/MergeSort.ts
@@ -0,0 +1,43 @@
import { Decrement, UnknownArray } from "../utility";

type GreaterThan<A extends number, B extends number> = A extends B ? false : B extends 0 ? true : A extends 0 ? false : GreaterThan<Decrement[A], Decrement[B]>;

type Merge<Left extends UnknownArray, Right extends UnknownArray, Result extends UnknownArray = readonly []> = Left extends readonly []
? readonly [...Result, ...Right]
: Right extends readonly []
? readonly [...Result, ...Left]
: Left extends readonly [infer LFirst, ...infer LRest]
? Right extends readonly [infer RFirst, ...infer RRest]
? RFirst extends number
? LFirst extends number
? GreaterThan<RFirst, LFirst> extends true
? Merge<LRest, Right, readonly [...Result, LFirst]>
: Merge<Left, RRest, readonly [...Result, RFirst]>
: never
: never
: never
: never;

type Halves<
Target extends UnknownArray,
Left extends UnknownArray = readonly [],
Right extends UnknownArray = readonly []
> = `${Target["length"]}` extends `${string}${"1" | "3" | "5" | "7" | "9"}`
? Target extends readonly [...infer Rest, infer Last]
? Halves<Rest, readonly [], readonly [Last]>
: never
: Target extends readonly []
? readonly [Left, Right]
: Target extends readonly [infer LFirst, ...infer Rest, infer RFirst]
? Halves<Rest, readonly [...Left, LFirst], readonly [RFirst, ...Right]>
: never;

export type MergeSort<M extends UnknownArray> = M extends readonly [] | readonly [unknown]
? M
: Halves<M> extends readonly [infer Left, infer Right]
? Left extends UnknownArray
? Right extends UnknownArray
? Merge<MergeSort<Left>, MergeSort<Right>>
: never
: never
: never;
29 changes: 29 additions & 0 deletions src/solutions/MiddleCharacter.ts
@@ -0,0 +1,29 @@
import { UnknownArray } from "../utility";

type Split<S extends string, R extends UnknownArray = readonly []> = S extends `${infer C}${infer M}` ? Split<M, readonly [...R, C]> : R;

type IsOdd<N extends number> = `${N}` extends `${string}${"1" | "3" | "5" | "7" | "9"}` ? true : false;

type Halves<Target extends UnknownArray, Left extends UnknownArray = readonly [], Right extends UnknownArray = readonly []> = IsOdd<
Target["length"]
> extends true
? Target extends readonly [...infer Rest, infer Last]
? Halves<Rest, readonly [], readonly [Last]>
: never
: Target extends readonly []
? readonly [Left, Right]
: Target extends readonly [infer LFirst, ...infer Rest, infer RFirst]
? Halves<Rest, readonly [...Left, LFirst], readonly [RFirst, ...Right]>
: never;

export type MiddleCharacter<S extends string> = IsOdd<Split<S>["length"]> extends true
? Halves<Split<S>> extends readonly [unknown, readonly [infer C, ...unknown[]]]
? C
: never
: Halves<Split<S>> extends readonly [readonly [...unknown[], infer A], readonly [infer B, ...unknown[]]]
? A extends string
? B extends string
? `${A}${B}`
: never
: never
: "";
7 changes: 7 additions & 0 deletions src/solutions/NoOverlappingKeys.ts
@@ -0,0 +1,7 @@
export type NoOverlappingKeys<A, B> = [
{
[K in keyof A]: K extends keyof B ? true : never;
}[keyof A]
] extends [never]
? A & B
: never;
1 change: 1 addition & 0 deletions src/solutions/PeriodsToUnderscores.ts
@@ -0,0 +1 @@
export type PeriodsToUnderscores<S extends string> = S extends `${infer A}.${infer B}` ? `${A}_${PeriodsToUnderscores<B>}` : S;
5 changes: 5 additions & 0 deletions src/solutions/ReverseTuple.ts
@@ -0,0 +1,5 @@
import { RetainMutablity, UnknownArray } from "../utility";

export type ReverseTuple<A, R extends UnknownArray = []> = A extends readonly [infer First, ...infer Rest]
? ReverseTuple<RetainMutablity<Rest, A>, [First, ...R]>
: RetainMutablity<R, A>;
3 changes: 3 additions & 0 deletions src/solutions/RoughlyIncludes.ts
@@ -0,0 +1,3 @@
type MakeMatcher<S extends string, R extends string = `${string}`> = S extends `${infer C}${infer M}` ? MakeMatcher<M, `${R}${C}${string}`> : R;

export type RoughlyIncludes<Source extends string, Target extends string> = Source extends MakeMatcher<Target> ? true : false;
3 changes: 3 additions & 0 deletions src/solutions/SplitString.ts
@@ -0,0 +1,3 @@
import { UnknownArray } from "../utility";

export type SplitString<S extends string, R extends UnknownArray = []> = S extends `${infer C}${infer M}` ? SplitString<M, [...R, C]> : R;
5 changes: 5 additions & 0 deletions src/solutions/SwapIndices.ts
@@ -0,0 +1,5 @@
import { UnknownArray } from "../utility";

export type SwapIndices<A extends UnknownArray, T extends number, S extends number> = {
[K in keyof A]: `${T}` extends K ? A[S] : `${S}` extends K ? A[T] : A[K];
};

0 comments on commit c917f56

Please sign in to comment.