来做几道小学奥数题:
数据发生器源码 [data_generator.py]:
# encoding=utf8
import itertools
class DataGenerator(object):
"""
DataGenerator:数生成器
""" def __init__(self, count=6, digitals=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]):
super(DataGenerator, self).__init__()
self._count = count
self._digitals = digitals
def get_digitals(self):
return self._digitals
def generate_numbers(self):
"""
获取定长的由数字组成的数,例如:
_count = 6, 返回所有的可能数字组合,对应的数,对应的逆序数
5 -> [([1, 2, 3, 4, 5], 12345, 54321), [1, 2, 3, 4, 6], 12346, 64321), ...]
"""
all = list(itertools.permutations(self._digitals, self._count))
return [(x,
self._generate_numbers_from_digit_list(x),
self._generate_numbers_from_digit_list(x, True))
for x in all if len(set(x)) == self._count and x[-1] != 0]
def _generate_numbers_from_digit_list(self, digit_list, revert=False):
"""
由一个数字列表返回对应的数,例如:
[1, 2, 3, 4, 5], False -> 12345
[1, 2, 3, 4, 5], True -> 54321
"""
return sum([digit * 10**index for index, digit in enumerate(digit_list if not revert else digit_list[::-1])])
class NumberAttr(object):
"""
NumberAttr:数属性
"""
def __init__(self, number):
super(NumberAttr, self).__init__()
self._number = number
def get_digit_by_pos(self, pos):
"""
获取数某个位置上的数字
1234, 1 -> 4
4321, 1 -> 1
"""
number = self._number
while pos:
(div, mod) = divmod(number, 10)
number = div
pos -= 1
return mod
def get_number_bits(self):
"""
获取数共有多少位
123 -> 3
4321 -> 4
"""
number = self._number
count = 0
while number:
(div, mod) = divmod(number, 10)
number = div
count += 1
return count
解奥数题源码 [olympic_maths.py]:
# encoding=utf8
from data_generator import DataGenerator
from data_generator import NumberAttr
def abcde_multiple_f_edcba():
# 红花映绿叶 * 春 = 叶绿映花红
generator = DataGenerator(5)
datas = generator.generate_numbers()
digitals = generator.get_digitals()
for numbers in datas:
(x, abcde, edcba) = numbers
if edcba > abcde and not edcba % abcde: # 可以整除
f = edcba // abcde
if f not in x and f in digitals:
print("{} X {} = {}".format(abcde, f, edcba))
def abcedf_multiple_f_gggggg():
# 我们热爱科学 * 学 = 好好好好好好
count = 6
generator = DataGenerator(count)
datas = generator.generate_numbers()
for numbers in datas:
(x, abcdef, _) = numbers
f = x[0]
gggggg = abcdef * f
(div, mod) = divmod(gggggg, 111111)
attr = NumberAttr(gggggg)
if attr.get_number_bits() == count and not mod and div <= 9:
print("{} X {} = {}".format(abcdef, f, gggggg))
def abcdef_add_abcdef_gehiba():
# 少年早立志向 + 少年早立志向 = 有志何惧少年
count = 6
generator = DataGenerator(count)
datas = generator.generate_numbers()
for numbers in datas:
(x, abcdef, _) = numbers
gehiba = abcdef + abcdef
attr = NumberAttr(gehiba)
a = attr.get_digit_by_pos(1)
b = attr.get_digit_by_pos(2)
i = attr.get_digit_by_pos(3)
h = attr.get_digit_by_pos(4)
e = attr.get_digit_by_pos(5)
g = attr.get_digit_by_pos(6)
if a == x[5] and b == x[4] and e == x[1] and \
g not in x and h not in x and i not in x and \
g != h and g != i and h != i and \
attr.get_number_bits() == count:
print("{} + {} = {}".format(abcdef, abcdef, gehiba))
def abcd_add_bcd_add_cd_2004():
# 学生 + 好学生 + 三好学生 = 2004
generator = DataGenerator(4)
datas = generator.generate_numbers()
for numbers in datas:
(x, abcd, _) = numbers
cd = x[0] + 10 * x[1]
bcd = cd + 100 * x[2]
if abcd + bcd + cd == 2004:
print("{} + {} + {} = 2004".format(abcd, bcd, cd))
if __name__ == "__main__":
abcde_multiple_f_edcba()
abcedf_multiple_f_gggggg()
abcdef_add_abcdef_gehiba()
abcd_add_bcd_add_cd_2004()
pass
输出结果:
21978 X 4 = 87912
142857 X 7 = 999999
468532 + 468532 = 937064
1468 + 468 + 68 = 2004
[Finished in 3.2s]