Created
October 24, 2015 09:23
-
-
Save cohama/ee7ad0a5a75f0bdc4e09 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"use strict" | |
const ZERO = f => x => x | |
const ONE = f => x => f(x) | |
const TWO = f => x => f(f(x)) | |
const THREE = f => x => f(f(f(x))) | |
const FOUR = f => x => f(f(f(f(x)))) | |
const FIVE = f => x => f(f(f(f(f(x))))) | |
const SUCC = n => f => x => n(f)(f(x)) | |
const SLIDE = p => PAIR(SND(p))(SUCC(SND(p))) | |
const PRED = n => FST(n(SLIDE)(PAIR(ZERO)(ZERO))) | |
const ADD = n => m => m(SUCC)(n) | |
const SUBTRACT = n => m => m(PRED)(n) | |
const MULTIPLY = n => m => m(ADD(n))(ZERO) | |
const POWER = n => m => m(MULTIPLY(n))(ONE) | |
const TEN = MULTIPLY(TWO)(FIVE) | |
const FIFTEEN = MULTIPLY(THREE)(FIVE) | |
const HUNDRED = POWER(TEN)(TWO) | |
const MOD_BAD = n => m => | |
IF(LTEQ(m)(n)) ( | |
x => MOD(SUBTRACT(n)(m))(m)(x) | |
) ( | |
n | |
) | |
const Z = f => (x => f(y => x(x)(y)))(x => f(y => x(x)(y))) | |
const FLIP = f => x => y => f(y)(x) | |
const MOD = Z(mod => n => m => | |
IF(LTEQ(m)(n)) ( | |
x => mod(SUBTRACT(n)(m))(m)(x) | |
) ( | |
n | |
) | |
) | |
const DIV = n => m => | |
Z(div => ( | |
i => j => | |
IF (GTEQ(i)(j)) ( | |
x => SUCC(div(SUBTRACT(i)(j))(j))(x) | |
) ( | |
ZERO | |
) | |
))(n)(m) | |
const TO_DIGIT = n => REVERSE(Z(toDigit => | |
i => | |
IF (GTEQ(i)(TEN)) ( | |
x => CONS(MOD(i)(TEN))(toDigit(DIV(i)(TEN)))(x) | |
) ( | |
y => CONS(i)(NIL)(y) | |
) | |
)(n)) | |
const TRUE = o => x => o | |
const FALSE = o => x => x | |
const IF = b => b | |
const IS_ZERO = n => n(_ => FALSE)(TRUE) | |
const NOT = b => b(FALSE)(TRUE) | |
const LTEQ = n => m => IS_ZERO(SUBTRACT(n)(m)) | |
const LT = n => m => LTEQ(SUCC(n))(m) | |
const GT = FLIP(LT) | |
const GTEQ = FLIP(LTEQ) | |
const PAIR = x => y => f => f(x)(y) | |
const FST = p => p(o => _ => o) | |
const SND = p => p(_ => o => o) | |
const NIL = PAIR(TRUE)(TRUE) | |
const CONS = x => xs => PAIR(FALSE)(PAIR(x)(xs)) | |
const IS_EMPTY = FST | |
const HEAD = xs => FST(SND(xs)) | |
const TAIL = xs => SND(SND(xs)) | |
const RANGE = Z(range => n => m => | |
IF(LTEQ(n)(m)) ( | |
x => CONS(n)(range(SUCC(n))(m))(x) | |
) ( | |
NIL | |
) | |
) | |
const FOLDL = Z(foldl => f => init => xs => | |
IF (IS_EMPTY(xs)) ( | |
init | |
) ( | |
y => foldl(f)(f(init)(HEAD(xs)))(TAIL(xs))(y) | |
) | |
) | |
const FOLDR = Z(foldr => f => init => xs => | |
IF (IS_EMPTY(xs)) ( | |
init | |
) ( | |
y => f(HEAD(xs))(foldr(f)(init)(TAIL(xs)))(y) | |
) | |
) | |
const REVERSE = FOLDL(FLIP(CONS))(NIL) | |
const MAP = f => FOLDR(h => CONS(f(h)))(NIL) | |
const CONCAT = FLIP(FOLDR(CONS)) | |
const ChrF = MULTIPLY(TWO)(FIVE) | |
const Chri = SUCC(ChrF) | |
const Chrz = SUCC(Chri) | |
const ChrB = SUCC(Chrz) | |
const Chru = SUCC(ChrB) | |
const STR_FIZZ = CONS(ChrF)(CONS(Chri)(CONS(Chrz)(CONS(Chrz)(NIL)))) | |
const STR_BUZZ = CONS(ChrB)(CONS(Chru)(CONS(Chrz)(CONS(Chrz)(NIL)))) | |
const STR_FIZZBUZZ = CONCAT(STR_FIZZ)(STR_BUZZ) | |
const jsNumber = n => n(x => x + 1)(0) | |
const jsBool = b => b(true)(false) | |
const jsPair = p => p(a => b => [a, b]) | |
const jsArray = xs => { | |
let a = [] | |
while (jsBool(NOT(IS_EMPTY(xs)))) { | |
a.push(HEAD(xs)) | |
xs = TAIL(xs) | |
} | |
return a | |
} | |
const jsNumArray = xs => jsArray(xs).map(jsNumber) | |
const jsString = s => { | |
const base = '0123456789FizBu' | |
return jsArray(s).reduce((a, x) => { | |
return a + base[jsNumber(x)] | |
}, "") | |
} | |
const FIZZBUZZ_SOLUTION = | |
MAP(i => | |
IF (IS_ZERO(MOD(i)(FIFTEEN))) ( | |
STR_FIZZBUZZ | |
) (IF (IS_ZERO(MOD(i)(FIVE))) ( | |
STR_BUZZ | |
) (IF (IS_ZERO(MOD(i)(THREE))) ( | |
STR_FIZZ | |
) ( | |
TO_DIGIT(i) | |
))) | |
)(RANGE(ONE)(HUNDRED)) | |
console.log(jsArray(FIZZBUZZ_SOLUTION).map(jsString)); | |
/* eslint-env es6 */ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment