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.
limit to bitwise and evaluate strings
type Op = '<<' | '&' | '|';
const Gift = {
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 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(' ');
if (tokens.length === 1) {
const token = tokens[0];
return isNaN(Number(token)) ? lookup[token] : Number(token);
}
if (tokens.length === 3) {
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}`);
};
const giftLookup: Record<GiftName, number> = {} as Record<GiftName, number>;
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 t1 = assertEq(giftLookup.TikTokPremium, 8);
const t2 = assertEq(giftLookup.Traditional, 3);
console.log("all tests passed");
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment