[英]how get list of all the possible combinations of 4 digit numbers whose individual digit sum is 13 and last digit is 5 in that number
[英]Performing arithmetic calculations on all possible digit combinations in a list
我以这样的格式创建数据:
initial_data = [
"518-2", '533-3', '534-0',
'000-3', '000-4']
我需要对连字符之前的部分执行几个操作(add、sub、div、mult、factorial、power_to、root),看看是否有一个方程等于连字符之后的部分。
像这样:
#5182
-5 - 1 + 8 = 2 or 5*(-1) - 1 + 8 = 2
#000-3
number, solution, number_of_solutions
000-3,(0! + 0!) + 0! = 3,2
or
000-4,,0
or
533-3,5 - (3! / 3) = 3,5
连字符之前的部分中的每个数字都可以有相反的符号,所以我发现了这个:
def inverter(data):
inverted_data = [-x for x in data]
res = list(product(*zip(data, inverted_data)))
return res
我应该像上面的示例一样创建一个 CSV 文件,但我还没有完成那部分,这似乎是最简单的部分。 我所拥有的是几个不同的部分,我无法以合理的方式连接它们:
import numpy as np
from itertools import product
from math import factorial
def plus(a, b):
return a + b
def minus(a, b):
return a - b
def mult(a, b):
return a * b
def div(a, b):
if b!=0:
if a%b==0:
return a//b
return np.nan
def the_factorial(a, b):
try:
return factorial(int(a))
except ValueError:
return np.nan
def power_to(a:int, b:int)->int:
try:
return int(a**b)
except ValueError:
return np.nan
def root(a:int, b:int)->int:
try:
return int(b**(1 / a))
except (TypeError, ZeroDivisionError, ValueError):
return np.nan
def combinations(nums, funcs):
"""Both arguments are lists"""
t = []
for i in range(len(nums)-1):
t.append(nums)
t.append(funcs)
t.append(nums)
return list(itertools.product(*t))
def solve(instance):
instance = list(instance)
for i in range(len(instance)//2):
b = instance.pop()
func = instance.pop()
a = instance.pop()
instance.append(func(a, b))
return instance[0]
def main():
try:
# a = [1, 3 ,4]
a = [int(-5), int(-1), int(8)]
func = [plus, minus, mult, div, the_factorial, power_to, root]
combs = combinations(a, func)
solutions = [solve(i) for i in combs]
for i, j in zip(combs, solutions):
print(i, j)
except ValueError:
#If there's too many combinations
return np.nan
我在将数据从 initial_data 转换为 inverter 到 main 时遇到问题,目前仅适用于一个示例,并返回一个丑陋的读数,中间为 function object。
提前致谢。
我认为这会对你有很大帮助(调整在你身上)但它不会写在 CSV 中,我留给你尝试,只是考虑到有数千种可能的组合,在某些情况下,结果真的很大(请参阅main()
中的注释)。
为了清晰和成功的linting (与旧的 Python 版本兼容),我在 function 声明中添加了缺失的类型。 另外,我认为不需要 function combinations()
所以我删除了它。 在我提议的代码中,function solve()
是一个神奇的代码:)
说了这么多,这里是完整的代码:
import numpy as np
from itertools import product
from math import factorial
from typing import Union, Callable, Tuple, List, Set
def plus(a: int, b: int) -> int:
return a + b
def minus(a: int, b: int) -> int:
return a - b
def mult(a: int, b: int) -> int:
return a * b
def div(a: int, b: int) -> Union[int, float]:
try:
retval = int(a / b)
except (ValueError, ZeroDivisionError):
retval = np.nan
return retval
def the_factorial(a: int) -> Union[int, float]:
try:
return factorial(int(a))
except ValueError:
return np.nan
except OverflowError:
return np.inf
def power_to(a: int, b: int) -> Union[int, float]:
try:
return int(a ** b)
except (ValueError, ZeroDivisionError):
return np.nan
def root(a: int, b: int) -> Union[int, float]:
try:
return int(b ** (1 / a))
except (TypeError, ZeroDivisionError, ValueError):
return np.nan
def solve(values: Tuple[int, int, int], ops: List[Callable]) -> list[Tuple[str, int]]:
# Iterate over available functions.
combs = list()
for f in FACTORS:
# Get values to operate with.
x, y, z = values
sx, sy, sz = x, y, z
a, b, c = f
# Calculate the factorial for the values (if applicable).
if a == 1:
sx = f"{x}!"
x = the_factorial(x)
if b == 1:
sy = f"{y}!"
y = the_factorial(y)
if c == 1:
sz = f"{z}!"
z = the_factorial(z)
for ext_op in ops: # External operation.
for int_op in ops: # Internal operation.
# Create equations by grouping the first 2 elements, e.g.: ((x + y) * z).
eq_str = f"{ext_op.__name__}({int_op.__name__}({sx}, {sy}), {sz})"
eq_val = ext_op(int_op(x, y), z)
combs.append((eq_str, eq_val))
# Create equations by grouping the last 2 elements, e.g.: (x + (y * z)).
eq_str = f"{ext_op.__name__}({sx}, {int_op.__name__}({sy}, {sz}))"
eq_val = ext_op(x, int_op(y, z))
combs.append((eq_str, eq_val))
return combs
def inverter(data: List[int]) -> List[Tuple[int, int, int]]:
inverted_data = [-x for x in data]
res = list(product(*zip(data, inverted_data)))
return res
# Data to process.
INITIAL_DATA: List[str] = [
"518-2",
'533-3',
# '534-0',
# '000-3',
# '000-4'
]
# Available functions.
FUNCTIONS: List[Callable] = [ # the_factorial() removed, see solve().
plus,
minus,
mult,
div,
power_to,
root
]
# Get posible combinations to apply the factor operation.
FACTORS: Set[Tuple] = set(product([1, 0, 0], repeat=3))
def main():
cases = 0 # Count all possible cases (for each input value).
data = list() # List with all final data to be dumped in CSV.
print("number, solution, number_of_solutions")
# Iterate over all initial data.
for eq in INITIAL_DATA:
# Get values before and after the hyphen.
nums, res = eq.split('-')
res = int(res)
# Get combinations with inverted values.
combs = inverter([int(n) for n in list(nums)])
# Iterate over combinations and generate a list with their many possible solutions.
sol_cnt = 0 # Number of solutions (for each input value).
solutions = list() # List with all final data to be dumped in CSV.
for i in [solve(i, FUNCTIONS) for i in combs]:
for j in i:
str_repr, value = j
# Some values exceed the 4300 digits, hence the 'try-catch'.
# The function 'sys.set_int_max_str_digits()' may be used instead to increase the str() capabilites.
try:
str(value)
except ValueError:
value = np.inf
if value == res:
sol_cnt += 1
solutions.append((eq, str_repr, value))
cases += 1
# Iterate over all data gathered, and add number of solutions.
for i in range(len(solutions)):
eq, str_repr, value = solutions[i]
solutions[i] += (sol_cnt,)
print(f"{eq}, {str_repr} = {value}, {sol_cnt}")
data.extend(solutions)
# Print all the solutions for this input.
print(f"\nThese are the {sol_cnt} solutions for input {eq}:")
solutions = [s for s in solutions if (type(s[2]) is int and s[2] == res)]
for i in range(len(solutions)):
print(f" {i:4}. {solutions[i][1]}")
print()
print(f"\nTotal cases: {cases}")
对于 output,请注意解决方案是使用您的函数名称打印/格式化的,而不是数学运算符。 这只是 output 的摘录,它使用第 1 位和第 3 位阶乘为initial_data
中的第一个值生成:
number, solution, number_of_solutions
518-2, plus(plus(5!, 1), 8!) = 40441, 12
518-2, plus(5!, plus(1, 8!)) = 40441, 12
518-2, plus(minus(5!, 1), 8!) = 40439, 12
518-2, plus(5!, minus(1, 8!)) = -40199, 12
518-2, plus(mult(5!, 1), 8!) = 40440, 12
518-2, plus(5!, mult(1, 8!)) = 40440, 12
518-2, plus(div(5!, 1), 8!) = 40440, 12
518-2, plus(5!, div(1, 8!)) = 120, 12
518-2, plus(power_to(5!, 1), 8!) = 40440, 12
518-2, plus(5!, power_to(1, 8!)) = 121, 12
518-2, plus(root(5!, 1), 8!) = 40321, 12
518-2, plus(5!, root(1, 8!)) = 40440, 12
...
These are the 12 solutions for input 518-2:
0. plus(minus(-5, 1!), 8)
1. minus(-5, minus(1!, 8))
2. plus(minus(-5, 1), 8)
3. minus(-5, minus(1, 8))
4. minus(-5, plus(1!, -8))
5. minus(minus(-5, 1!), -8)
6. minus(-5, plus(1, -8))
7. minus(minus(-5, 1), -8)
8. plus(plus(-5, -1), 8)
9. plus(-5, plus(-1, 8))
10. plus(-5, minus(-1, -8))
11. minus(plus(-5, -1), -8)
Total cases: 4608
请注意,仅针对initial_data
中的第一个值处理了4608 个案例,因此我建议您先尝试使用此案例,然后添加 rest,因为对于某些案例,它可能会花费大量处理时间。
另外,我注意到您正在截断div()
和root()
中的值,因此请记住这一点。 您会在完整的 output 中看到很多nan
和inf
,因为有巨大的值和条件,如div/0
,所以这是意料之中的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.