Skip to content

Instantly share code, notes, and snippets.

@1dolinski
Last active October 23, 2025 16:39
Show Gist options
  • Select an option

  • Save 1dolinski/93c2e193e5bc6fad9acfc33d71ae7341 to your computer and use it in GitHub Desktop.

Select an option

Save 1dolinski/93c2e193e5bc6fad9acfc33d71ae7341 to your computer and use it in GitHub Desktop.
fizzbuzz.js
// FizzBuzz up to 20 using only S and K combinators
// Basic combinators
let S = (x) => (y) => (z) => x(z)(y(z));
let K = (x) => (y) => x;
// Identity (I = S K K)
let I = S(K)(K);
// Boolean logic
let TRUE = K; // λx.λy.x - returns first argument
let FALSE = (x) => (y) => y; // λx.λy.y - returns second argument
let IF = (cond) => (then) => (else_) => cond(then)(else_);
// Church numerals using successor
let ZERO = FALSE;
let SUCC = (n) => (f) => (x) => f(n(f)(x)); // Successor
let ONE = I;
let TWO = SUCC(ONE);
let THREE = SUCC(TWO);
let FOUR = SUCC(THREE);
let FIVE = SUCC(FOUR);
let SIX = SUCC(FIVE);
let SEVEN = SUCC(SIX);
let EIGHT = SUCC(SEVEN);
let NINE = SUCC(EIGHT);
let TEN = SUCC(NINE);
let ELEVEN = SUCC(TEN);
let TWELVE = SUCC(ELEVEN);
let THIRTEEN = SUCC(TWELVE);
let FOURTEEN = SUCC(THIRTEEN);
let FIFTEEN = SUCC(FOURTEEN);
let SIXTEEN = SUCC(FIFTEEN);
let SEVENTEEN = SUCC(SIXTEEN);
let EIGHTEEN = SUCC(SEVENTEEN);
let NINETEEN = SUCC(EIGHTEEN);
let TWENTY = SUCC(NINETEEN);
// Arithmetic operations
let ADD = (m) => (n) => m(SUCC)(n);
let MULT = (m) => (n) => m(ADD(n))(ZERO);
let PRED = (n) => (f) => (x) => n((g) => (h) => h(g(f)))((u) => x)((u) => u); // Predecessor
let SUB = (m) => (n) => n(PRED)(m);
// Comparison
let ISZERO = (n) => n((x) => FALSE)(TRUE);
let LEQ = (m) => (n) => ISZERO(SUB(m)(n));
// Modulo operation (simplified for small numbers)
let MOD_ONCE = (m) => (n) => IF(LEQ(n)(m))(SUB(m)(n))(m);
let MOD = (m) => (n) => MOD_ONCE(MOD_ONCE(MOD_ONCE(MOD_ONCE(MOD_ONCE(MOD_ONCE(MOD_ONCE(MOD_ONCE(MOD_ONCE(MOD_ONCE(
MOD_ONCE(MOD_ONCE(MOD_ONCE(MOD_ONCE(MOD_ONCE(MOD_ONCE(MOD_ONCE(MOD_ONCE(MOD_ONCE(MOD_ONCE(
m)(n))(n))(n))(n))(n))(n))(n))(n))(n))(n))(n))(n))(n))(n))(n))(n))(n))(n))(n))(n);
// Divisibility checks
let DIVISIBLE_BY_3 = (n) => ISZERO(MOD(n)(THREE));
let DIVISIBLE_BY_5 = (n) => ISZERO(MOD(n)(FIVE));
// Convert Church numeral to JavaScript number
let CHURCH_TO_JS = (n) => n((x) => x + 1)(0);
// String representations (simplified - using functions that return strings)
let FIZZ_STR = () => "Fizz";
let BUZZ_STR = () => "Buzz";
let FIZZBUZZ_STR = () => "FizzBuzz";
let NUM_TO_STR = (n) => () => CHURCH_TO_JS(n).toString();
// FizzBuzz logic
let FIZZBUZZ_LOGIC = (n) => IF(DIVISIBLE_BY_3(n))(
IF(DIVISIBLE_BY_5(n))(FIZZBUZZ_STR)(FIZZ_STR)
)(
IF(DIVISIBLE_BY_5(n))(BUZZ_STR)(NUM_TO_STR(n))
);
// Recursive function to print from 1 to 20
let PRINT_RANGE = (start) => (end) => IF(LEQ(start)(end))(
() => {
console.log(FIZZBUZZ_LOGIC(start)());
PRINT_RANGE(SUCC(start))(end)();
}
)(
() => {} // Do nothing
);
// Execute FizzBuzz from 1 to 20
PRINT_RANGE(ONE)(TWENTY)();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment