Skip to content

Instantly share code, notes, and snippets.

@trvswgnr
Last active November 28, 2024 05:25
Show Gist options
  • Save trvswgnr/4c005331db1d69d28b5fa76d52f94b2c to your computer and use it in GitHub Desktop.
Save trvswgnr/4c005331db1d69d28b5fa76d52f94b2c to your computer and use it in GitHub Desktop.

Revisions

  1. trvswgnr revised this gist Nov 28, 2024. 1 changed file with 14 additions and 2 deletions.
    16 changes: 14 additions & 2 deletions index.ts
    Original file line number Diff line number Diff line change
    @@ -14,6 +14,18 @@ type Gift = typeof Gift;
    type GiftName = keyof Gift;
    type GiftValue = Gift[GiftName];

    type Valid = {
    [T in keyof Gift]: Gift[T] extends `${infer A extends number|GiftName} ${infer O extends Op} ${infer B extends number|GiftName}`
    ? `${A} ${O} ${B}`
    : Gift[T] extends '0'
    ? '0'
    : false;
    }[keyof Gift] extends string ? true : false;

    type Expect<T extends true> = T
    type t0 = Expect<Valid>;
    // ^?

    const evaluateExpression = (expression: string, lookup: Record<string, number>): number => {
    const tokens = expression.split(' ');

    @@ -56,6 +68,6 @@ const assertEq = (a: any, b: any) => {
    }
    };

    const t0 = assertEq(giftLookup.TikTokPremium, 8);
    const t1 = assertEq(giftLookup.Traditional, 3);
    const t1 = assertEq(giftLookup.TikTokPremium, 8);
    const t2 = assertEq(giftLookup.Traditional, 3);
    console.log("all tests passed");
  2. trvswgnr revised this gist Nov 28, 2024. 1 changed file with 1 addition and 3 deletions.
    4 changes: 1 addition & 3 deletions index.ts
    Original file line number Diff line number Diff line change
    @@ -18,13 +18,11 @@ const evaluateExpression = (expression: string, lookup: Record<string, number>):
    const tokens = expression.split(' ');

    if (tokens.length === 1) {
    // Single value (e.g., "0" or a named gift)
    const token = tokens[0];
    return isNaN(Number(token)) ? lookup[token] : Number(token);
    }

    if (tokens.length === 3) {
    // Binary operation (e.g., "1 << 2" or "Train | Bicycle")
    const [left, operator, right] = tokens;

    const leftValue = isNaN(Number(left)) ? lookup[left] : Number(left);
    @@ -60,4 +58,4 @@ const assertEq = (a: any, b: any) => {

    const t0 = assertEq(giftLookup.TikTokPremium, 8);
    const t1 = assertEq(giftLookup.Traditional, 3);
    console.log("All tests passed!");
    console.log("all tests passed");
  3. trvswgnr revised this gist Nov 28, 2024. No changes.
  4. trvswgnr renamed this gist Nov 28, 2024. 1 changed file with 0 additions and 0 deletions.
    File renamed without changes.
  5. trvswgnr revised this gist Nov 28, 2024. 1 changed file with 46 additions and 15 deletions.
    61 changes: 46 additions & 15 deletions index.ta
    Original file line number Diff line number Diff line change
    @@ -1,32 +1,63 @@
    type Op = "<<" | "&";
    type Op = '<<' | '&' | '|';

    const Gift = {
    TikTok: '1 << 3'
    Coal: '0',
    Train: '1 << 0',
    Bicycle: '1 << 1',
    SuccessorToTheNintendoSwitch: '1 << 2',
    TikTokPremium: '1 << 3',
    Vape: '1 << 4',
    Traditional: 'Train | Bicycle',
    } as const;

    type Gift = typeof Gift;

    type GiftName = keyof Gift;
    // type GiftName = "TikTok"

    type GiftValue = Gift[GiftName];

    type Test = Gift[GiftName];
    // type Test = "1 << 3"
    const evaluateExpression = (expression: string, lookup: Record<string, number>): number => {
    const tokens = expression.split(' ');

    if (tokens.length === 1) {
    // Single value (e.g., "0" or a named gift)
    const token = tokens[0];
    return isNaN(Number(token)) ? lookup[token] : Number(token);
    }

    if (tokens.length === 3) {
    // Binary operation (e.g., "1 << 2" or "Train | Bicycle")
    const [left, operator, right] = tokens;

    const leftValue = isNaN(Number(left)) ? lookup[left] : Number(left);
    const rightValue = isNaN(Number(right)) ? lookup[right] : Number(right);

    switch (operator as Op) {
    case '<<':
    return leftValue << rightValue;
    case '&':
    return leftValue & rightValue;
    case '|':
    return leftValue | rightValue;
    default:
    throw new Error(`Unsupported operator: ${operator}`);
    }
    }

    throw new Error(`Invalid expression: ${expression}`);
    };

    type Validate<T extends GiftName> =
    Gift[T] extends `${infer A extends number} ${infer O extends Op} ${infer B extends number}`
    ? `${A} ${O} ${B}`
    : never;
    const giftLookup: Record<GiftName, number> = {} as Record<GiftName, number>;

    type V1 = Validate<GiftName>;
    // type V1 = "1 << 3"
    for (const key in Gift) {
    giftLookup[key as GiftName] = evaluateExpression(Gift[key as GiftName], giftLookup);
    }

    // tests
    const assertEq = (a: any, b: any) => {
    if (a !== b) {
    throw `${a} !== ${b}`;
    }
    };

    const t0 = assertEq(eval(Gift.TikTok), 8);
    console.log("passed!");
    const t0 = assertEq(giftLookup.TikTokPremium, 8);
    const t1 = assertEq(giftLookup.Traditional, 3);
    console.log("All tests passed!");
  6. trvswgnr created this gist Nov 28, 2024.
    32 changes: 32 additions & 0 deletions index.ta
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,32 @@
    type Op = "<<" | "&";

    const Gift = {
    TikTok: '1 << 3'
    } as const;

    type Gift = typeof Gift;

    type GiftName = keyof Gift;
    // type GiftName = "TikTok"

    type GiftValue = Gift[GiftName];

    type Test = Gift[GiftName];
    // type Test = "1 << 3"

    type Validate<T extends GiftName> =
    Gift[T] extends `${infer A extends number} ${infer O extends Op} ${infer B extends number}`
    ? `${A} ${O} ${B}`
    : never;

    type V1 = Validate<GiftName>;
    // type V1 = "1 << 3"

    const assertEq = (a: any, b: any) => {
    if (a !== b) {
    throw `${a} !== ${b}`;
    }
    };

    const t0 = assertEq(eval(Gift.TikTok), 8);
    console.log("passed!");