# 8640-生成一定范围内的数字.

# 题目描述

Sometimes we want to limit the range of numbers... For examples.

type result = NumberRange<2 , 9> //  | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9

# 分析

这道题目其实有点类似于 4518-fill,都是要在一定范围内执行,这题的思路如下:

  1. 构建辅助元组,从 0 开始计数
  2. 当元组长度等于起始值时,在联合中加入该值,同时设置一个标志位为 true
  3. 当元组长度等于结束值时,在联合中加入该值,此时可以直接结束递归
  4. 当元组长度不等于起始和结束值时,沿用标志位,如果标志位为 true,就在联合中加入,否则就不加入。

# 题解

type NumberRange<
  L,
  H,
  // 辅助元组,用于计数
  Arr extends 1[] = [],
  // 存放标志位
  inRange extends boolean = L extends Arr['length'] ? true : false,
  // 存放结果的联合
  R = never,
> =
  // 如果辅助元组等于 L
  Arr['length'] extends L
    ? // 将 inRange 置为 true,并将 L 纳入结果 R 中
      NumberRange<L, H, [...Arr, 1], true, R | Arr['length']>
    : // 如果到了 H,那么就将 H 纳入结果中,结束递归,此时 H = Arr['length']
    Arr['length'] extends H
    ? R | Arr['length']
    : // 否则,不断递归计数,如果 inrange 为 true,就将当前值纳入 R 中,否则,纳入 never
      NumberRange<
        L,
        H,
        [...Arr, 1],
        inRange,
        R | (inRange extends true ? Arr['length'] : never)
      >;

# 知识点

  1. 辅助元组计数
  2. 标记位处理范围问题
Last Updated: 2023/5/16 06:00:28