Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

4518 - Fill (simplest solution) #21503

Open
MajorLift opened this issue Jan 4, 2023 · 1 comment
Open

4518 - Fill (simplest solution) #21503

MajorLift opened this issue Jan 4, 2023 · 1 comment
Labels
4518 answer Share answers/solutions to a question en in English

Comments

@MajorLift
Copy link
Contributor

MajorLift commented Jan 4, 2023

/**
 * @typedef Fill
 * @params START_SAFE?, END_SAFE?: target range of fill operation adjusted for out-of-bounds input
 * @params COUNT?: number of consecutive elements to replace with fill operation
 * @returns START > END ? T : [...T.slice(0, START_SAFE), ...new Array(COUNT).fill(V), ...T.slice(END_SAFE)]
 */
type Fill<
  T extends unknown[],
  V extends unknown,
  START extends number = 0,
  END extends number = T["length"],
  START_SAFE extends number = LessThan<T["length"], START> extends true ? T["length"] : START,
  END_SAFE extends number = LessThan<T["length"], END> extends true ? T["length"] : END,
  COUNT extends number = Subtract<END_SAFE, START_SAFE>,
  RESULT extends unknown[] = LessThan<END, START> extends true 
    ? T
    : [...Pop<T, Subtract<T["length"], START_SAFE>>, ...Repeat<COUNT, V>, ...Shift<T, END_SAFE>],
> = RESULT;
;
/** Utilities */
type Shift<T extends any[], N extends number = 1> = 
  N extends 0 ? T 
    : T extends [infer _, ...infer Rest]
      ? Shift<Rest, Subtract<N, 1>>
      : [];

type Pop<T extends any[], N extends number = 1> = 
  N extends 0 ? T
    : T extends [...infer Rest, infer _]
      ? Pop<Rest, Subtract<N, 1>> 
      : [];

type LessThan<T extends number, U extends number> = 
  Equal<T, U> extends true ? false
    : Subtract<T, U> extends never ? true : false;

type Subtract<M extends number, S extends number> = 
  Repeat<M> extends [...Repeat<S>, ...infer Rest] ? Rest["length"] : never;

type Repeat<N extends number, T extends unknown = null, M extends T[] = []> = 
  M["length"] extends N ? M : Repeat<N, T, [...M, T]>;

See also: 216 - Slice #21502

@MajorLift MajorLift added answer Share answers/solutions to a question en in English labels Jan 4, 2023
@github-actions github-actions bot added the 4518 label Jan 4, 2023
MajorLift added a commit to MajorLift/type-challenges that referenced this issue Jan 4, 2023
…ot inverted

- Currently, solutions can pass all test cases without returning `T` for `End >= Start >= T["length"]`.

- Example: type-challenges#21503
@MajorLift
Copy link
Contributor Author

MajorLift commented Jan 4, 2023

Added new test case #21521:

Expect<Equal<Fill<[1, 2, 3], true, 10, 20>, [1, 2, 3]>>
  • Previously, solutions could pass all test cases without returning T if End >= Start >= T["length"].
// Example: `Fill<[1, 2, 3], true, 10, 20>` resolves to `never`, but passes all test cases.
    : [...Pop<T, Subtract<T["length"], Start>>, ...Repeat<M, N>, ...Shift<T, End>]
// Fix: `Fill<[1, 2, 3], true, 10, 20>` correctly resolves to `[1, 2, 3]`
    : [...Pop<T, Subtract<T["length"], MStart>>, ...Repeat<M, N>, ...Shift<T, MEnd>]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
4518 answer Share answers/solutions to a question en in English
Projects
None yet
Development

No branches or pull requests

1 participant