#include <stdio.h>
#include <functional>
using namespace std;
template<typename A, typename B>
using F = function<A(B)>;
template<typename A>
using CN = F<F<A, A>, F<A, A>>;
template<typename A>
CN<A> zero() {
return [](F<A,A>) -> F<A,A> {
return [](A i) -> A {return i;};
};
}
template<typename A>
CN<A> inc(CN<A> n) {
return [=](F<A,A> f) -> F<A,A> {
return [=](A a) -> A {
return n(f)(f(a));
};
};
}
template<typename A>
CN<A> operator*(CN<A> a, CN<A> b) {
return [=](F<A,A> f) -> F<A,A> {
return b(a(f));
};
}
template<typename A>
CN<A> operator+(CN<A> a, CN<A> b) {
return [=](F<A,A> f) -> F<A,A> {
return [=](A i) -> A {
auto i1 = a(f)(i);
return b(f)(i1);
};
};
}
CN<unsigned int> i2c(unsigned int n) {
auto l = zero<unsigned int>();
for(int i = 0; i<n; i++)
l = inc(l);
return l;
}
unsigned int c2i(CN<int> n) {
auto n2 = n([&](int a)->int {return a+1;});
return n2(0);
}
int multiply(unsigned int a, unsigned int b) {
return c2i(i2c(a) * i2c(b));
}
int main() {
unsigned int a, b;
a = 4;
b = 3;
printf("%d*%d=%d", a, b, multiply(a, b));
return 0;
}
I2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxmdW5jdGlvbmFsPgoKdXNpbmcgbmFtZXNwYWNlIHN0ZDsKCnRlbXBsYXRlPHR5cGVuYW1lIEEsIHR5cGVuYW1lIEI+CnVzaW5nIEYgPSBmdW5jdGlvbjxBKEIpPjsKCnRlbXBsYXRlPHR5cGVuYW1lIEE+CnVzaW5nIENOID0gRjxGPEEsIEE+LCBGPEEsIEE+PjsKCnRlbXBsYXRlPHR5cGVuYW1lIEE+CkNOPEE+IHplcm8oKSB7CiByZXR1cm4gW10oRjxBLEE+KSAtPiBGPEEsQT4gewogICAgcmV0dXJuIFtdKEEgaSkgLT4gQSB7cmV0dXJuIGk7fTsKIH07Cn0KCnRlbXBsYXRlPHR5cGVuYW1lIEE+CkNOPEE+IGluYyhDTjxBPiBuKSB7CiAgICByZXR1cm4gWz1dKEY8QSxBPiBmKSAtPiBGPEEsQT4gewogICAgICAgIHJldHVybiBbPV0oQSBhKSAtPiBBIHsKICAgICAgICAgICAgcmV0dXJuIG4oZikoZihhKSk7CiAgICAgICAgfTsKICAgIH07Cn0KCnRlbXBsYXRlPHR5cGVuYW1lIEE+CkNOPEE+IG9wZXJhdG9yKihDTjxBPiBhLCBDTjxBPiBiKSB7CiAgICByZXR1cm4gWz1dKEY8QSxBPiBmKSAtPiBGPEEsQT4gewogICAgICAgIHJldHVybiBiKGEoZikpOwogICAgfTsKfQoKdGVtcGxhdGU8dHlwZW5hbWUgQT4KQ048QT4gb3BlcmF0b3IrKENOPEE+IGEsIENOPEE+IGIpIHsKICAgIHJldHVybiBbPV0oRjxBLEE+IGYpIC0+IEY8QSxBPiB7CiAgICAgICAgcmV0dXJuIFs9XShBIGkpIC0+IEEgewogICAgICAgICAgICBhdXRvIGkxID0gYShmKShpKTsKICAgICAgICAgICAgcmV0dXJuIGIoZikoaTEpOwogICAgICAgIH07CiAgICB9Owp9CgpDTjx1bnNpZ25lZCBpbnQ+IGkyYyh1bnNpZ25lZCBpbnQgbikgewoJYXV0byBsID0gemVybzx1bnNpZ25lZCBpbnQ+KCk7Cglmb3IoaW50IGkgPSAwOyBpPG47IGkrKykKCQlsID0gaW5jKGwpOwoJcmV0dXJuIGw7Cn0KCnVuc2lnbmVkIGludCBjMmkoQ048aW50PiBuKSB7CiAgICBhdXRvIG4yID0gbihbJl0oaW50IGEpLT5pbnQge3JldHVybiBhKzE7fSk7CiAgICByZXR1cm4gbjIoMCk7Cn0KCmludCBtdWx0aXBseSh1bnNpZ25lZCBpbnQgYSwgdW5zaWduZWQgaW50IGIpIHsKCXJldHVybiBjMmkoaTJjKGEpICogaTJjKGIpKTsKfQoKaW50IG1haW4oKSB7Cgl1bnNpZ25lZCBpbnQgYSwgYjsKCWEgPSA0OwoJYiA9IDM7CglwcmludGYoIiVkKiVkPSVkIiwgYSwgYiwgbXVsdGlwbHkoYSwgYikpOwoJcmV0dXJuIDA7Cn0=