Skip to content

Instantly share code, notes, and snippets.

@weapp
Created June 16, 2015 22:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save weapp/9afc558a26502e161615 to your computer and use it in GitHub Desktop.
Save weapp/9afc558a26502e161615 to your computer and use it in GitHub Desktop.
#!/usr/bin/env ruby
# require 'bundler/setup'
# Bundler.require(:default)
module F
ZERO = -> p { -> x { x } }
ONE = -> p { -> x { p[x] } }
TWO = -> p { -> x { p[p[x]] } }
THREE = -> p { -> x { p[p[p[x]]] } }
FOUR = -> p { -> x { p[p[p[p[x]]]] } }
FIVE = -> p { -> x { p[p[p[p[p[x]]]]] } }
TRUE = -> x { -> y { x } }
FALSE = -> x { -> y { y } }
IF = -> b { b }
IS_ZERO = -> n { n[-> x { FALSE }][TRUE] }
INCREMENT = -> n { -> p { -> x { p[n[p][x]] } } }
DECREMENT = -> n { -> f { -> x { n[-> g { -> h { h[g[f]] } }] \
[-> y { x }][-> y { y }] } } }
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] } }
IS_LESS_OR_EQUAL = -> m { -> n {
IS_ZERO[SUBTRACT[m][n]]
} }
# Y = -> f { -> x { f[x[x]] }
# [-> x { f[x[x]] }] }
Z = -> f { -> x { f[-> y { x[x][y] }] } \
[-> x { f[-> y { x[x][y] }] }] }
MOD = Z[-> f { -> m { -> n {
IF[IS_LESS_OR_EQUAL[n][m]][
-> x {
f[SUBTRACT[m][n]][n][x]
}
][
m
]
} } }]
PAIR = -> x { -> y { -> f { f[x][y] } } }
LEFT = -> p { p[-> x { -> y { x } } ] }
RIGHT = -> p { p[-> x { -> y { y } } ] }
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]] } }
]
} }
TEN = MULTIPLY[TWO][FIVE]
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]
DIV =
Z[-> f { -> m { -> n {
IF[IS_LESS_OR_EQUAL[n][m]][
-> x {
INCREMENT[f[SUBTRACT[m][n]][n]][x]
}
][
ZERO
]
} } }]
PUSH =
-> l {
-> x {
FOLD[l][UNSHIFT[EMPTY][x]][UNSHIFT]
}
}
TO_DIGITS =
Z[-> f { -> n { PUSH[
IF[IS_LESS_OR_EQUAL[n][DECREMENT[TEN]]][
EMPTY
][
-> x {
f[DIV[n][TEN]][x]
}
]
][MOD[n][TEN]] } }]
def self.to_integer(proc)
proc[-> n { n + 1 }][0]
end
def self.to_boolean(proc)
IF[proc][true][false]
end
def self.to_array(proc)
array = []
until to_boolean(IS_EMPTY[proc])
array.push(FIRST[proc])
proc = REST[proc]
end
array
end
def self.to_char(c)
'0123456789BFiuz'.slice(to_integer(c))
end
def self.to_string(s)
to_array(s).map { |c| to_char(c) }.join
end
my_list =
UNSHIFT[
UNSHIFT[
UNSHIFT[EMPTY][THREE]
][TWO]
][ONE]
# puts to_integer(FIVE)
# puts to_integer(ONE[INCREMENT][TWO])
puts to_integer(DECREMENT[FIVE])
# puts to_integer(SUBTRACT[THREE][FIVE])
p to_boolean(TRUE)
p to_integer(FIRST[my_list])
p to_array(REST[my_list]).map { |p| to_integer(p) }
HUNDRED = MULTIPLY[TEN][TEN]
FIFTEEN = MULTIPLY[THREE][FIVE]
t = MAP[RANGE[ONE][FIFTEEN]][-> 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]
]]]
}]
to_array(t).each do |c|
p to_string(c)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment