TRUE = -> x { -> y { x } }
FALSE = -> x { -> y { y } }
IF = -> b { b }
Z = -> f { -> x { f[-> y { x[x][y] }] }[-> x { f[-> y { x[x][y] }] }] }
PAIR = -> x { -> y { -> f { f[x][y] } } }
LEFT = -> p { p[-> x { -> y { x } } ] }
RIGHT = -> p { p[-> x { -> y { y } } ] }
ZERO = -> p { -> x { x } }
ONE = -> p { -> x { p[x] } }
INCREMENT = -> n { -> p { -> x { p[n[p][x]] } } }
SLIDE = -> p { PAIR[RIGHT[p]][INCREMENT[RIGHT[p]]] }
DECREMENT = -> n { LEFT[n[SLIDE][PAIR[ZERO][ZERO]]] }
IS_ZERO = -> n { n[-> x { FALSE }][TRUE] }
IS_LESS_OR_EQUAL =
-> m { -> n {
IS_ZERO[SUBTRACT[m][n]]
} }
ADD = -> m { -> n { n[INCREMENT][m] } }
SUBTRACT = -> m { -> n { n[DECREMENT][m] } }
MULTIPLY = -> m { -> n { n[ADD[m]][ZERO] } }
POWER = -> m { -> n { n[MULTIPLY[m]][ONE] } }
DIV =
Z[-> f { -> m { -> n {
IF[IS_LESS_OR_EQUAL[n][m]][
-> x {
INCREMENT[f[SUBTRACT[m][n]][n]][x]
}
][
ZERO
]
} } }]
MOD =
Z[-> f { -> m { -> n {
IF[IS_LESS_OR_EQUAL[n][m]][
-> x {
f[SUBTRACT[m][n]][n][x]
}
][
m
]
} } }]
TWO = INCREMENT[ONE]
THREE = INCREMENT[TWO]
FOUR = INCREMENT[THREE]
FIVE = INCREMENT[FOUR]
TEN = MULTIPLY[TWO][FIVE]
FIFTEEN = ADD[TEN][FIVE]
HUNDRED = MULTIPLY[TEN][TEN]
EMPTY = PAIR[TRUE][TRUE]
UNSHIFT = -> l { -> x {
PAIR[FALSE][PAIR[x][l]]
} }
IS_EMPTY = LEFT
FIRST = -> l { LEFT[RIGHT[l]] }
REST = -> l { RIGHT[RIGHT[l]] }
RANGE =
Z[-> f {
-> m { -> n {
IF[IS_LESS_OR_EQUAL[m][n]][
-> x {
UNSHIFT[f[INCREMENT[m]][n]][m][x]
}
][
EMPTY
]
} }
}]
FOLD =
Z[-> f {
-> l { -> x { -> g {
IF[IS_EMPTY[l]][
x
][
-> y {
g[f[REST[l]][x][g]][FIRST[l]][y]
}
]
} } }
}]
MAP =
-> k { -> f {
FOLD[k][EMPTY][
-> l { -> x { UNSHIFT[l][f[x]] } }
]
} }
PUSH =
-> l {
-> x {
FOLD[l][UNSHIFT[EMPTY][x]][UNSHIFT]
}
}
B = TEN
F = INCREMENT[B]
I = INCREMENT[F]
U = INCREMENT[I]
ZED = INCREMENT[U]
FIZZ = UNSHIFT[UNSHIFT[UNSHIFT[UNSHIFT[EMPTY][ZED]][ZED]][I]][F]
BUZZ = UNSHIFT[UNSHIFT[UNSHIFT[UNSHIFT[EMPTY][ZED]][ZED]][U]][B]
FIZZBUZZ = UNSHIFT[UNSHIFT[UNSHIFT[UNSHIFT[BUZZ][ZED]][ZED]][I]][F]
TO_DIGITS =
Z[-> f { -> n { PUSH[
IF[IS_LESS_OR_EQUAL[n][DECREMENT[TEN]]][
EMPTY
][
-> x {
f[DIV[n][TEN]][x]
}
]
][MOD[n][TEN]] } }]
SOLUTION = MAP[RANGE[ONE][HUNDRED]][-> n {
IF[IS_ZERO[MOD[n][FIFTEEN]]][
FIZZBUZZ
][IF[IS_ZERO[MOD[n][THREE]]][
FIZZ
][IF[IS_ZERO[MOD[n][FIVE]]][
BUZZ
][
TO_DIGITS[n]
]]]
}]
def to_integer(proc)
proc[-> n { n + 1 }][0]
end
def to_boolean(proc)
proc[true][false]
end
def to_array(proc)
array = []
until to_boolean(IS_EMPTY[proc])
array.push(FIRST[proc])
proc = REST[proc]
end
array
end
def to_char(c)
'0123456789BFiuz'.slice(to_integer(c))
end
def to_string(s)
to_array(s).map { |c| to_char(c) }.join
end
to_array(SOLUTION).each do |p|
puts to_string(p)
end