Skip to content

Instantly share code, notes, and snippets.

@MasterTuto
Created January 4, 2023 23:48
Show Gist options
  • Save MasterTuto/208f3653c047153cc565937c2e2aa374 to your computer and use it in GitHub Desktop.
Save MasterTuto/208f3653c047153cc565937c2e2aa374 to your computer and use it in GitHub Desktop.
Calculadora em TypeScript
type IncrementTable = {
'0': '1',
'1': '2',
'2': '3',
'3': '4',
'4': '5',
'5': '6',
'6': '7',
'7': '8',
'8': '9',
'9': '0',
}
type Increment<A extends string> = A extends `${infer FirstPart}9`
? (
FirstPart extends '' ? '10' : `${Increment<FirstPart>}0`
) : (
A extends `${infer A1 extends keyof IncrementTable}${infer A2}`
? (
A2 extends '' ? IncrementTable[A1] : `${A1}${Increment<A2>}`
) : never
);
type DecrementTable = {
'1': '0',
'2': '1',
'3': '2',
'4': '3',
'5': '4',
'6': '5',
'7': '6',
'8': '7',
'9': '8',
'0': '9',
}
type Remove0<T> = T extends `0${infer Anything}` ? Remove0<Anything> : T;
type Decrement<A extends string> = A extends `${infer FirstPart}0`
? Remove0<(
FirstPart extends '' ? '' : `${Decrement<FirstPart>}9`
)> : (
A extends `${infer A1 extends keyof DecrementTable}${infer A2}`
? (
A2 extends '' ? DecrementTable[A1] : `${A1}${Decrement<A2>}`
) : never
);
type AddAuxiliar<A extends string, B extends string> = B extends '0' ? A : Add<Increment<A>, Decrement<B>>;
type Add<A extends string, B extends string> = B extends '0' ? A : Add<Increment<A>, Decrement<B>>;
type XXXX = Increment<'22'>;
type XXXXX = Decrement<'1'>;
type TwoPlusFive = Add<'1995', '28'>;
@natanfeitosa
Copy link

Agora fica Turing completa

type Multiply<A extends string, B extends string, Result extends string = '0'> = B extends '0'
    ? Result
    : Multiply<A, Decrement<B>, Add<Result, A>>;

type Sub<A extends string, B extends string> = B extends '0' ? A : Sub<Decrement<A>, Decrement<B>>

type Divide<A extends string, B extends string, Quotient extends string = '0'> = 
    B extends '0' ? never : // Divisão por zero não é permitida
    A extends '0' ? Quotient : (
        Sub<A, B> extends infer Subtracted extends string
        ? Divide<Subtracted, B, Increment<Quotient>>
        : never
    );

type Power<A extends string, B extends string> = B extends '0'
    ? '1'
    : Multiply<A, Power<A, Decrement<B>>>;

type TestIt<A extends string, B extends string> = B extends A ? true : `Error: Expected ${B}, but got ${A}`

type Tests = [
  TestIt<Multiply<'2', '10'>, '20'>,
  TestIt<Multiply<'20', '10'>, '200'>,
  TestIt<Multiply<'200', '10'>, '2000'>,
  TestIt<Sub<'20', '10'>, '10'>,
  TestIt<Sub<'200', '10'>, '190'>,
  TestIt<Sub<'2000', '10'>, '1990'>,
  TestIt<Divide<'20', '10'>, '2'>,
  TestIt<Divide<'200', '10'>, '20'>,
  TestIt<Divide<'2000', '10'>, '200'>,
  TestIt<Power<'2', '2'>, '4'>,
  TestIt<Power<'2', '3'>, '8'>,
  TestIt<Power<'2', '4'>, '16'>,
]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment