Sign in

Muhammad Khan

@muhammadkhan.dev
76 followers 109 following 158 posts

Despite being terribly unreasonable, I like to think of myself as rational & practical. He/Him 📍 Lahore, Pakistan

PostsRepliesMedia
Muhammad Khan @muhammadkhan.dev · 02/02/2026
github.com/muhammadk160...
export const nearestPerfectMonths = (year: number) => {
  const result = { prev: new Date(year, 0, 1), next: new Date(year + 1, 0, 1) };

  while (![4, 5].includes(result.prev.getDay())) {
    result.prev = new Date(result.prev.getFullYear() - 1, 0, 1);
  }
  while (![4, 5].includes(result.next.getDay())) {
    result.next = new Date(result.next.getFullYear() + 1, 0, 1);
  }

  return {
    prev: `${result.prev.getFullYear()}-02`,
    next: `${result.next.getFullYear()}-02`,
  };
};
020
Muhammad Khan @muhammadkhan.dev · 26/01/2026
github.com/muhammadk160...
const countVowels = (word: string) => word.match(/[aeiou]/gi)?.length || 0;

export const flippedy = (str: string) => {
  const words = str.split(" ");

  const firstWord = words[0];

  if (!firstWord) return str;

  const vowelCount = countVowels(firstWord);

  return words.reduce((acc, word) => {
    if (countVowels(word) === vowelCount) {
      return acc + " " + word.split("").reverse().join("");
    }

    return acc + " " + word;
  });
};
030
Muhammad Khan @muhammadkhan.dev · 12/01/2026
github.com/muhammadk160... I consider this a one-liner, :)
export const hungryBears = (bears: { name: string; hunger: number }[]) =>
  bears
    .filter(bear => bear.hunger > bears.reduce((sum, bear) => sum + bear.hunger, 0) / bears.length)
    .sort((a, b) => a.name.localeCompare(b.name))
    .map(bear => bear.name);
030
Muhammad Khan @muhammadkhan.dev · 08/09/2025
github.com/muhammadk160...
export const sumOfNeighbors = (arr: number[]): number => {
  let sum = 0;

  for (let i = 0; i < arr.length; i++) {
    sum += (arr[i - 1] || 0) + (arr[i] || 0) + (arr[i + 1] || 0);
  }

  return sum;
};
030
Muhammad Khan @muhammadkhan.dev · 28/07/2025
github.com/muhammadk160... Hexagons are Bestagons!
export const canFormHexagon = (sides: number[]): boolean => {
  if (sides.length !== 6) return false;

  const sideCount: Record<number, number> = {};
  for (const side of sides) {
    sideCount[side] = (sideCount[side] || 0) + 1;
  }

  return Object.values(sideCount).filter(count => count >= 2).length === 3;
};
020
Muhammad Khan @muhammadkhan.dev · 30/06/2025
github.com/muhammadk160...
export const nonRepeat = (str: string): string => {
  const charCount: Record<string, number> = {};

  for (const char of str) {
    charCount[char] = (charCount[char] || 0) + 1;
  }

  for (let i = str.length - 1; i >= 0; i--) {
    const char = str[i] || "";
    if (charCount[char] === 1) return char;
  }

  return "";
};
020
Muhammad Khan @muhammadkhan.dev · 16/06/2025
github.com/muhammadk160...
const ROMAN_MAP = {
  I: 1,
  V: 5,
  X: 10,
  L: 50,
  C: 100,
  D: 500,
  M: 1000,
} as const;

const romanToInt = (roman: string): number => {
  let total = 0;
  let prevValue = 0;

  for (let i = roman.length - 1; i >= 0; i--) {
    const currentValue = ROMAN_MAP[roman[i] as keyof typeof ROMAN_MAP];

    if (currentValue < prevValue) total -= currentValue;
    else total += currentValue;
    prevValue = currentValue;
  }

  return total;
};

export const sortMonarchs = (monarchs: string[]): string[] => {
  return monarchs.sort((a, b) => {
    const [nameA, ordinalA] = a.split(" ") as [string, string];
    const [nameB, ordinalB] = b.split(" ") as [string, string];

    const numberA = romanToInt(ordinalA);
    const numberB = romanToInt(ordinalB);

    // If years are the same, compare by name
    return nameA.localeCompare(nameB) || numberA - numberB;
  });
};
020
Muhammad Khan @muhammadkhan.dev · 13/06/2025
Source Code at: github.com/muhammadk160...
github.com
GitHub - muhammadk1607/sbp-war-api: This is an API that returns weighted average buying and selling rates of major foreign currencies against the Pakistani Rupee (provided by State Bank of Pakistan).
This is an API that returns weighted average buying and selling rates of major foreign currencies against the Pakistani Rupee (provided by State Bank of Pakistan). - muhammadk1607/sbp-war-api
010
Muhammad Khan @muhammadkhan.dev · 13/06/2025
I just released a new publicly available API This API bridges that gap. - Programmatic access to SBP daily weighted average buying rates (in JSON format) - Updated daily at 4:00 PM PKT (excluding Bank Holidays) - Built with FastAPI Try it out: sbp-war-api.muhammadkhan.dev/docs
sbp-war-api.muhammadkhan.dev
FastAPI - Swagger UI
112
Muhammad Khan @muhammadkhan.dev · 10/06/2025
github.com/muhammadk160...
export type TrafficLight = "red" | "green" | "yellow";
export const isValidTrafficSequence = (sequence: TrafficLight[]): boolean => {
  let prevLight: TrafficLight | null = null;

  for (let i = 0; i < sequence.length; i++) {
    const light = sequence[i] as TrafficLight;

    if (prevLight === "red" && light !== "green") return false;
    if (prevLight === "green" && light !== "yellow") return false;
    if (prevLight === "yellow" && light !== "red") return false;

    prevLight = light;
  }

  return true;
};
010
Muhammad Khan @muhammadkhan.dev · 02/06/2025
github.com/muhammadk160... I have only one question regarding this task: "But why?"
export const nestArray = (array: any[]): any[] => {
  const result: any[] = [];
  let current = result;

  for (let i = 0; i < array.length; i++) {
    current.push(array[i]);

    if (i === array.length - 1) break;

    const nextLevel: any[] = [];
    current.push(nextLevel);
    current = nextLevel;
  }

  return result;
};
130
Muhammad Khan @muhammadkhan.dev · 30/05/2025
github.com/muhammadk160...
export const oddSum = (first: number[], second: number[]): number[][] => {
  const result: number[][] = [];

  first.forEach(x => {
    second.forEach(y => {
      if ((x + y) % 2 !== 0) {
        result.push([x, y]);
      }
    });
  });

  return result;
};
030
Muhammad Khan @muhammadkhan.dev · 20/05/2025
Baseline shamelessly "borrowed" from @tenzhiyang.com github.com/muhammadk160...
const CORNER = "+";
const VERTICAL = "|";
const HORIZONTAL = "-";
const DIAGONAL = "/";
const SPACE = " ";

const NUMBER_OF_HORIZONTAL_LINES = 3;

export const drawCube = (size: number) => {
  const horizontalLine = Array.from({ length: size * 2 + 2 })
    .map((_, i, { length }) => (i === 0 || i === length - 1 ? CORNER : HORIZONTAL))
    .join("");
  const padding = Math.floor(size / 2);
  const rows = Array.from({ length: size + NUMBER_OF_HORIZONTAL_LINES + padding });

  return (
    "\n" +
    rows
      .map((_, i, { length }) => {
        if (i === 0) {
          return SPACE.repeat(padding + 1) + horizontalLine;
        } else if (i > 0 && i < padding + 1) {
          return (
            SPACE.repeat(padding + 1 - i) +
            DIAGONAL +
            SPACE.repeat(size * 2) +
            DIAGONAL +
            SPACE.repeat(Math.max(i - 1, 0)) +
            VERTICAL
          );
        } else if (i === padding + 1) {
          return horizontalLine + SPACE.repeat(padding) + VERTICAL;
        } else if (i > padding + 1 && i < length - 1) {
          let endItem = VERTICAL;
          let paddingEnd = padding;
          if (i === size + 1) {
            endItem = CORNER;
          }
          if (i > size + 1) {
            endItem = DIAGONAL;
            paddingEnd = length - i - 2;
          }
          return VERTICAL + SPACE.repeat(size * 2) + VERTICAL + SPACE.repeat(paddingEnd) + endItem;
        } else if (i === length - 1) {
          return horizontalLine;
        } else {
          return SPACE;
        }
      })
      .join("\n") +
    "\n"
  );
};
030
Muhammad Khan @muhammadkhan.dev · 16/05/2025
github.com/muhammadk160...
export const addOperators = (origin: number, target: number): string[] => {
  const digits = origin.toString().split("");
  const result: string[] = [];

  const dfs = (index: number, path: string, currentNumber: number) => {
    if (index === digits.length) {
      if (currentNumber === target) result.push(path);
      return;
    }

    for (let i = index; i < digits.length; i++) {
      const digit = digits[i];
      const newNumber = Number(digit);

      dfs(i + 1, `${path}+${digit}`, currentNumber + newNumber);
      dfs(i + 1, `${path}-${digit}`, currentNumber - newNumber);

      // Multiply but only if BODMAS is not violated
      if (!(path.includes("+") || path.includes("-")))
        dfs(i + 1, `${path}*${digit}`, currentNumber * newNumber);
    }
  };

  // Start DFS from the first digit
  const firstDigit = digits[0] as string;
  const firstNumber = Number(firstDigit);
  dfs(1, firstDigit, firstNumber);

  return result;
};
010
Muhammad Khan @muhammadkhan.dev · 07/05/2025
"Never think that war, no matter how necessary, nor how justified, is not a crime." ~ Ernest Hemingway

I wish for calmer heads to prevail.
010
Muhammad Khan @muhammadkhan.dev · 06/05/2025
No worries, we all get it. If anything confusing requirements add to the realism. 🤣
140
Muhammad Khan @muhammadkhan.dev · 05/05/2025
github.com/muhammadk160...
export const longestCommonPrefix = (strings: string[]): string => {
  let prefix = strings[0] || "";

  for (let i = 1; i < strings.length; i++) {
    while (strings[i]?.indexOf(prefix) !== 0) {
      prefix = prefix.slice(0, -1);
      if (prefix === "") return "";
    }
  }

  return prefix;
};
010
Muhammad Khan @muhammadkhan.dev · 05/05/2025
This is what I assumed, since the example function is being called "longestCommonPrefix".
100
Muhammad Khan @muhammadkhan.dev · 28/04/2025
github.com/muhammadk160...
export const compress = (characters: string[]): string[] => {
  const compressed: string[] = [];

  let currentChar = characters[0] as string;
  let count = 1;

  for (let i = 1; i <= characters.length; i++) {
    if (characters[i] === currentChar) {
      count++;
    } else {
      compressed.push(currentChar);
      if (count > 1) {
        compressed.push(count.toString());
      }
      currentChar = characters[i] as string;
      count = 1;
    }
  }

  return compressed;
};
030
Muhammad Khan @muhammadkhan.dev · 23/04/2025
List comprehensions 💜
020
Muhammad Khan @muhammadkhan.dev · 21/04/2025
github.com/muhammadk160...
export type TIngredient = {
  name: string;
  amount: number;
};

export const calculateIngredients = (
  ingredients: TIngredient[],
  targetServings: number,
): TIngredient[] =>
  ingredients.map(ingredient => ({
    ...ingredient,
    amount: ingredient.amount * targetServings,
  }));
030
Muhammad Khan @muhammadkhan.dev · 16/04/2025
I am starting to think that noUncheckedIndexedAccess rule is overkill. github.com/muhammadk160...
const DIRECTIONS = [
  [0, 1],
  [1, 0],
  [0, -1],
  [-1, 0],
] as const;

export const largestPathSum = (grid: number[][]): number => {
  const rows = grid.length;

  if (!grid[0]) return 0;

  const cols = grid[0].length;

  let maxSum = 0;

  function dfs(x: number, y: number, visited: boolean[][], currentSum: number) {
    maxSum = Math.max(maxSum, currentSum);

    for (const [dx, dy] of DIRECTIONS) {
      const nx = x + dx;
      const ny = y + dy;

      if (!visited[nx] || !grid[nx]) continue;

      if (nx >= 0 && ny >= 0 && nx < rows && ny < cols && !visited[nx][ny]) {
        visited[nx][ny] = true;
        dfs(nx, ny, visited, currentSum + (grid[nx][ny] || 0));
        visited[nx][ny] = false;
      }
    }
  }

  for (let i = 0; i < rows; i++) {
    for (let j = 0; j < cols; j++) {
      const visited = Array.from({ length: rows }, () => Array(cols).fill(false));

      // @ts-ignore
      visited[i][j] = true;
      // @ts-ignore
      dfs(i, j, visited, grid[i][j]);
    }
  }

  return maxSum;
};
020
Muhammad Khan @muhammadkhan.dev · 07/04/2025
github.com/muhammadk160...
const getLeylandNumbers = (n: number): number[] => {
  let count = n;
  let leylandNumbers: number[] = [];

  let x = 2;

  while (count > 0) {
    for (let i = 2; i <= x; i++) {
      leylandNumbers.push(Math.pow(i, x) + Math.pow(x, i));
    }
    x++;
    count--;
  }

  return leylandNumbers.toSorted((a, b) => a - b).slice(0, n);
};
020
Muhammad Khan @muhammadkhan.dev · 01/04/2025
No, you aren't wrong. That example is incorrect.
110
Muhammad Khan @muhammadkhan.dev · 01/04/2025
github.com/muhammadk160...
const getMinutes = (time: string): number => {
  const [hours, minutes] = time.split(":").map(Number);

  if (hours === undefined || minutes === undefined)
    throw new Error(`Invalid time format: ${time}`);

  return hours * 60 + minutes;
};

export const findLongestTimeGap = (times: string[]): number => {
  let longestGap = 0;

  for (let i = 0; i < times.length - 1; i++) {
    const current = times[i] as string;
    const next = times[i + 1] as string;

    longestGap = Math.max(longestGap, getMinutes(next) - getMinutes(current));
  }

  return longestGap;
};
020
Muhammad Khan @muhammadkhan.dev · 25/03/2025
github.com/muhammadk160...
export const findLongestStreak = (values: boolean[]) => {
  let max = 0;

  for (let i = 0; i < values.length; i++) {
    let current = 0;
    while (values[i]) {
      current++;
      i++;
    }

    if (current > max) {
      max = current;
    }
  }

  return max;
}
010
Muhammad Khan @muhammadkhan.dev · 19/03/2025
www.citationneeded.news/free-and-ope...
citationneeded.news
“Wait, not like that”: Free and open access in the age of generative AI
The real threat isn’t AI using open knowledge — it’s AI companies killing the projects that make knowledge free
020
Muhammad Khan @muhammadkhan.dev · 11/03/2025
Thanks for forcing me to learn some basic Music Theory 😀 github.com/muhammadk160...
const SEMITONES = {
  C: 0,
  D: 2,
  E: 4,
  F: 5,
  G: 7,
  A: 9,
  B: 11,
};

export const findLargestInterval = (keys: string[]): number => {
  const intervals = keys.map(key => {
    const note = key[0] as keyof typeof SEMITONES;
    const octave = Number(key[1]);
    return SEMITONES[note] + octave * 12;
  });

  let largestInterval = 0;

  for (let i = 0; i < intervals.length - 1; i++) {
    const current = intervals[i] as number;
    const next = intervals[i + 1] as number;

    largestInterval = Math.max(largestInterval, Math.abs(current - next));
  }

  return largestInterval;
};
120
Muhammad Khan @muhammadkhan.dev · 11/03/2025
This has better documentation than half of the production code I write. 😆 Gorgeous.
120
Muhammad Khan @muhammadkhan.dev · 03/03/2025
github.com/muhammadk160... Skipped last week's problem since I felt like the solution I came up with wasn't mine. 😀
export const calculatePrice = (closingDate: string, visitDate: string, price: number): number => {
  const closingDateTimestamp = new Date(closingDate).getTime();
  const visitDateTimestamp = new Date(visitDate).getTime();

  if (visitDateTimestamp > closingDateTimestamp) return price;

  const weeks = Math.floor(
    (closingDateTimestamp - visitDateTimestamp) / (1000 * 60 * 60 * 24 * 7),
  );

  for (let i = 0; i < weeks; i++) {
    price -= price * 0.1;
  }

  return price;
};
020
Muhammad Khan @muhammadkhan.dev · 17/02/2025
github.com/muhammadk160...
export const findShieldBreak = (attacks: number[], shield: number): number => {
  for (let i = 0; i < attacks.length; i++) {
    shield -= attacks[i] as number;
    if (shield < 0) return i;
  }

  return -1;
};
030
Muhammad Khan @muhammadkhan.dev · 16/02/2025
Just ran a 5k. Not gonna lie, 50% of my motivation came just from seeing all these tech people running marathons. Do I get to join the cool kids club now?
Me holding a medal for finishing a 5K run, in front of a banner saying "I am a finisher"
020
Muhammad Khan @muhammadkhan.dev · 13/02/2025
Standing strong for equality and justice at Aurat March in Lahore. 💜✊🏽 Equality should never be up for debate. #AuratMarch #EqualityForAll
My sister and I holding placards during Aurat March in Lahore.

The signs are written in Urdu. My sister is holding a sign that says: "Izzat nahi, jaan bachao", which means "Save lives not honour" I am holding a sign that says: "Ziyada soch mat bas barabar samajh", which means "Don't think too much, just think of all as equals".
020
Muhammad Khan @muhammadkhan.dev · 10/02/2025
github.com/muhammadk160...
export type TPosition = "QB" | "RB" | "WR" | "TE" | "OL" | "DL" | "LB" | "DB" | "K" | "LS";
type TRange = {
  min: number;
  max: number;
};

const ranges: Record<TPosition, TRange[]> = {
  QB: [{ min: 1, max: 19 }],
  RB: [
    { min: 1, max: 49 },
    { min: 80, max: 89 },
  ],
  WR: [
    { min: 1, max: 49 },
    { min: 80, max: 89 },
  ],
  TE: [
    { min: 1, max: 49 },
    { min: 80, max: 89 },
  ],
  OL: [{ min: 50, max: 79 }],
  DL: [
    { min: 50, max: 79 },
    { min: 90, max: 99 },
  ],
  LB: [
    { min: 1, max: 59 },
    { min: 90, max: 99 },
  ],
  DB: [{ min: 1, max: 49 }],
  K: [
    { min: 1, max: 49 },
    { min: 90, max: 99 },
  ],
  LS: [{ min: 1, max: 99 }],
};

export const availableNumbers = (position: TPosition, numbers: number[]): number[] => {
  const validRanges = ranges[position];
  let availableNumbers: number[] = [];

  for (const range of validRanges) {
    for (let i = range.min; i <= range.max; i++) {
      if (!numbers.includes(i)) {
        availableNumbers.push(i);
      }
    }
  }

  return availableNumbers;
};
030
Muhammad Khan @muhammadkhan.dev · 03/02/2025
github.com/muhammadk160...
type Operator = "+" | "-" | "*" | "/";

const isOperator = (char: string): char is Operator => {
  return char === "+" || char === "-" || char === "*" || char === "/";
};

const operate = (operand1: number, operand2: number, operator: Operator): number => {
  if (operator === "/") {
    return Math.floor(operand1 / operand2);
  } else if (operator === "*") {
    return operand1 * operand2;
  } else if (operator === "+") {
    return operand1 + operand2;
  } else {
    return operand1 - operand2;
  }
};

export const evaluatePostfix = (expression: string): number => {
  const stack: number[] = [];

  for (let i = 0; i < expression.length; i++) {
    const char = expression[i] as string;

    if (isOperator(char)) {
      const operand2 = stack.pop();
      const operand1 = stack.pop();

      if (operand1 === undefined || operand2 === undefined) {
        throw new Error("Invalid expression");
      }

      const result = operate(operand1, operand2, char);
      stack.push(result);
    } else {
      stack.push(Number(char));
    }
  }

  return stack.pop() || 0;
};
030
Reposted by Muhammad Khan
George Takei @georgetakei.bsky.social · 31/01/2025
This is what the government did with 120K+ Japanese Americans in 1942. I know. I was there in those camps.
34549891531616
Reposted by Muhammad Khan
John Scalzi @scalzi.com · 29/01/2025
OpenAI right now
Scene from The Princess Bride where Vizzinni says "You're trying to kidnap what I've rightfully stolen"
287435396257
Muhammad Khan @muhammadkhan.dev · 27/01/2025
github.com/muhammadk160...
const getAnagrams = (s: string): string[] => {
  const anagrams: string[] = [];

  const generateAnagrams = (str: string, anagram: string) => {
    if (str.length === 0) {
      anagrams.push(anagram);
      return;
    }

    for (let i = 0; i < str.length; i++) {
      generateAnagrams(str.slice(0, i) + str.slice(i + 1), anagram + str[i]);
    }
  };

  generateAnagrams(s, "");

  return anagrams;
};

export const findAnagrams = (s: string, p: string): number[] => {
  const result: number[] = [];

  if (s.length < p.length) return result;

  const pAnagrams = getAnagrams(p);

  for (let i = 0; i < s.length - p.length + 1; i++) {
    const subStr = s.slice(i, i + p.length);
    if (pAnagrams.includes(subStr)) {
      result.push(i);
    }
  }

  return result;
};
030
Muhammad Khan @muhammadkhan.dev · 24/01/2025
A bit of old news but this screenshot shows the reason why I switched banks. This is like a textbook answer to the question, "Tell me you are storing passwords in plaintext without telling me you are using passwords in plaintext"
A screenshot of the login page from the web portal of Askari Bank Pakistan is attached.

The text reads: "Please enter 1st, 3rd, 7th and 8th characters of your password."
010
Muhammad Khan @muhammadkhan.dev · 23/01/2025
🧹 Clean up your cluttered git workspaces by removing all stale merged branches ⚠️ No warranty for important branches you forgot to name properly! If you called it fix-final-final-really-final, that one's on you.
# Remove all merged branches from local except main, prod and dev
git branch --merged | grep -Ev "(^\*|^\+|main|prod|dev)" | xargs --no-run-if-empty git branch -d

# Get rid of remote tracking branches
git remote prune origin
020
Muhammad Khan @muhammadkhan.dev · 20/01/2025
github.com/muhammadk160...
export const longestSubsequence = (sequence: number[]): number => {
  let longest = -Infinity;
  let current = 1;
  let prev = sequence[0];

  if (prev === undefined) return 0;

  for (const num of sequence.slice(1)) {
    if (Math.abs(num - prev) === 1) current++;
    else {
      longest = Math.max(longest, current);
      current = 1;
    }
    prev = num;
  }

  return Math.max(longest, current);
};
010
Muhammad Khan @muhammadkhan.dev · 13/01/2025
github.com/muhammadk160...
const NATO_ALPHABET_MAP = {
  a: "Alpha",
  b: "Bravo",
  c: "Charlie",
  d: "Delta",
  e: "Echo",
  f: "Foxtrot",
  g: "Golf",
  h: "Hotel",
  i: "India",
  j: "Juliett",
  k: "Kilo",
  l: "Lima",
  m: "Mike",
  n: "November",
  o: "Oscar",
  p: "Papa",
  q: "Quebec",
  r: "Romeo",
  s: "Sierra",
  t: "Tango",
  u: "Uniform",
  v: "Victor",
  w: "Whiskey",
  x: "X-ray",
  y: "Yankee",
  z: "Zulu",
  " ": "(space)",
  1: "One",
  2: "Two",
  3: "Three",
  4: "Four",
  5: "Five",
  6: "Six",
  7: "Seven",
  8: "Eight",
  9: "Nine",
  0: "Zero",
  ".": "Stop",
  ",": "Comma",
  "!": "Exclamation mark",
  "?": "Question mark",
  "'": "Apostrophe",
  "“": "Quote",
  "”": "Unquote",
  "-": "Hyphen",
  _: "Underscore",
  ":": "Colon",
  ";": "Semicolon",
  "(": "Bracket on",
  ")": "Bracket off",
  "/": "Slant",
  "\\": "Backslant",
} as const;

type NATO_KEY = keyof typeof NATO_ALPHABET_MAP;

export const natoify = (s: string) => {
  let result = "";
  for (const char of s) {
    const lowerChar = char.toLowerCase();

    if (lowerChar in NATO_ALPHABET_MAP) {
      result += NATO_ALPHABET_MAP[lowerChar as NATO_KEY] + " ";
    } else {
      result += char;
    }
  }

  return result.trim();
};
010
Muhammad Khan @muhammadkhan.dev · 10/01/2025
www.chess.com/awards/muham... Yay, 1500 by end of 2025 is suddenly not looking like an insurmountable task.
Stat card showing 1203 Rapid Rating on Chess.com.
020
Reposted by Muhammad Khan
Molly White @molly.wiki · 08/01/2025
any billionaire buying Wikipedia would be a tragedy, "on the good side" or not. we need to stop divvying up all the important institutions along billionaires and then relying on their good graces — look how it's gone so far.
13973451257
Muhammad Khan @muhammadkhan.dev · 07/01/2025
getfreewrite.com/blogs/writin...
getfreewrite.com
What Does the World Lose When a Language Dies?
Every 40 days, another one dies — becoming extinct forever. By the year 2100, that will be 3,500 lost. We’re not talking about a species of animal, or variety of plant. We’re talking about languages —...
010
Muhammad Khan @muhammadkhan.dev · 06/01/2025
github.com/muhammadk160...
export const permute = (s: string) => {
  if (s.length === 0) return [""];

  const result: string[] = [];

  for (let i = 0; i < s.length; i++) {
    const rest = s.slice(0, i).concat(s.slice(i + 1));
    permute(rest).forEach(restPermutation => {
      result.push(s[i] + restPermutation);
    });
  }

  return result;
};
010
Muhammad Khan @muhammadkhan.dev · 01/01/2025
Wow, great start to 2025. Hoping to reach 1500+ by end of this year
Screenshot of Unlocked Achievement on Chess.com for reaching a rating of 1100 in Rapid Chess
000
Reposted by Muhammad Khan
Erik Rasmussen @erikras.com · 30/12/2024
Works.
49715
Muhammad Khan @muhammadkhan.dev · 30/12/2024
Nice, Intl API is amazing.
010
Muhammad Khan @muhammadkhan.dev · 30/12/2024
github.com/muhammadk160... Happy New Year
export const DAYS = [
  "Sunday",
  "Monday",
  "Tuesday",
  "Wednesday",
  "Thursday",
  "Friday",
  "Saturday",
] as const;
export type Day = (typeof DAYS)[number];

export const newYearsDay = (year: number) => DAYS[new Date(year, 0).getDay()] as Day;
020