Lab3 部分question
- Q5:It's Always a Good Prime
- Q6:Church numerals
Q5:It’s Always a Good Prime
Implement
div_by_primes_under
, which takes in an integern
and returns an n-divisibility checker. An n-divisibility-checker is a function that takes in an integer k and returns whetherk
is divisible by any integers between 2 andn
, inclusive. Equivalently, it returns whether k is divisible by any primes less than or equal ton
.Review the Disc 01
is_prime
problem for a reminder about prime numbers.You can also choose to do the no lambda version, which is the same problem, just with defining functions with def instead of lambda.
def div_by_primes_under(n):
"""
>>> div_by_primes_under(10)(11)
False
>>> div_by_primes_under(10)(121)
False
>>> div_by_primes_under(10)(12)
True
>>> div_by_primes_under(5)(1)
False
"""
checker = lambda x: False
i = _____________________________
while _______________________________:
if not checker(i):
checker = (lambda f, i: lambda x: ___________)(checker, i)
i = _____________________________
return __________________________
这里是 Disc 1 的 is_prime
函数:
def is_prime(n):
"""
>>> is_prime(10)
False
>>> is_prime(7)
True
>>> is_prime(1) #one is not a prime number !!
False
"""
if n == 1:
return False
k = 2
while k < n:
if n % k == 0:
return False
k += 1
return True
根据 s_prime
函数,我们可以推出 i 就类似与is_prime
中 k,checker
是分离出 n 的质数。最后通过checker
判断 x 是否能够整除这些质数,如果能,则返回 True。
根据题目给出的框架,我们可以进一步实现:
def div_by_primes_under(n):
checker = lambda x: False
i = 2
while i <= n:
if not checker(i):
checker = (lambda f, i: lambda x: _____________)(checker, i)
i += 1
return checker
checker = (lambda f, i: lambda x: _____________)(checker, i)
我们分析这个赋值语句,从左到右,第一个 lambda 函数有两个参数 f,i;第二个 lambda 函数有一个参数 x。
如果 checker
函数返回 True(只要不是 n 的质数),这个语句就不会执行。很自然,空白处肯定有
x % i == 0
。
checker = (lambda f, i: lambda x: x % i == 0)(checker, i)
上式是会一直得到 True,由于 i % i 会一直是 0。我们需要能够“存储”小于n的质数。f 就起作用了。
checker = (lambda f, i : lambda x: x % i == 0 or f(x))(checker, i)
上述是div_by_primes_under(5)(2)
的例子:
通过反复调用 checker
来保存小于 n 的质数,最后当 x = 2 时,通过不断回退函数,从 i = 5 、i = 3 最后到 i = 2,一步步判断,得到结果。
最终答案:
def div_by_primes_under(n):
checker = lambda x: False
i = 2
while i <= n:
if not checker(i):
checker = (lambda f, i: lambda x: (x % i == 0) or f(x))(checker, i)
i = i + 1
return checker
Q6:Church numerals
The logician Alonzo Church invented a system of representing non-negative integers entirely using functions. The purpose was to show that functions are sufficient to describe all of number theory: if we have functions, we do not need to assume that numbers exist, but instead we can invent them.
Your goal in this problem is to rediscover this representation known as Church numerals. Church numerals are a way to represent non-negative integers via repeated function application. Specifically, church numerals (such as
zero
,one
, andtwo
below) are functions that take in a functionf
and return a new function which, when called, repeats f a number of times on some argumentx
. Here are the definitions ofzero
, as well as asuccessor
function, which takes in a church numeraln
as an argument and returns a function that represents the church numeral one higher thann
:
def zero(f):
return lambda x: x
def successor(n):
return lambda f: lambda x: f(n(f)(x))
First, define functions
one
andtwo
such that they have the same behavior assuccessor(zero)
andsuccesssor(successor(zero))
respectively, but do not callsuccessor
in your implementation.
Next, implement a function
church_to_int
that converts a church numeral argument to a regular Python integer.
Finally, implement functions
add_church
,mul_church
, andpow_church
that perform addition, multiplication, and exponentiation on church numerals.
要求是实现丘奇数,其中zero
、one
、two
分别是丘奇数中的 0、1、2。
最终实现如下:
def zero(f):
return lambda x: x
def successor(n):
return lambda f: lambda x: f(n(f)(x))
def one(f):
"""Church numeral 1: same as successor(zero)"""
"*** YOUR CODE HERE ***"
return lambda x: f(x)
def two(f):
"""Church numeral 2: same as successor(successor(zero))"""
"*** YOUR CODE HERE ***"
return lambda x: f(f(x))
#three = successor(two)
def three(f):
return lambda x: f(f(f(x)))
def church_to_int(n):
"""Convert the Church numeral n to a Python integer.
>>> church_to_int(zero)
0
>>> church_to_int(one)
1
>>> church_to_int(two)
2
>>> church_to_int(three)
3
"""
"*** YOUR CODE HERE ***"
return n(increment)(0)
def add_church(m, n):
"""Return the Church numeral for m + n, for Church numerals m and n.
>>> church_to_int(add_church(two, three))
5
"""
"*** YOUR CODE HERE ***"
return lambda f: lambda x: m(f)(n(f)(x))
def mul_church(m, n):
"""Return the Church numeral for m * n, for Church numerals m and n.
>>> four = successor(three)
>>> church_to_int(mul_church(two, three))
6
>>> church_to_int(mul_church(three, four))
12
"""
"*** YOUR CODE HERE ***"
return lambda f : m(n(f))
def pow_church(m, n):
"""Return the Church numeral m ** n, for Church numerals m and n.
>>> church_to_int(pow_church(two, three))
8
>>> church_to_int(pow_church(three, two))
9
"""
"*** YOUR CODE HERE ***"
return n(m)
如果对细节不是很清楚可以参考博客:https://www.cnblogs.com/Shimarin/p/13823520.html
和 https://zhuanlan.zhihu.com/p/267917164。