gpt4 book ai didi

wolfram-mathematica - 无法从 {2,3,4,5,6,7,8} 获得的最小整数(Mathematica)

转载 作者:行者123 更新时间:2023-12-04 08:55:47 25 4
gpt4 key购买 nike

我正在尝试使用 Mathematica 解决以下问题:

从集合 {2,3,4,5,6,7,8} 中无法获得的最小正整数是多少?通过算术运算 {+,-,*,/} 、求幂和括号。集合中的每个数字必须恰好使用一次。不允许一元运算(例如,1 不能在不使用 0 的情况下转换为 -1)。

例如,号码 1073741824000000000000000可通过 (((3+2)*(5+4))/6)^(8+7) 获得.

我是 Mathematica 的初学者。我已经编写了我认为可以解决集合 {2,3,4,5,6,7} 问题的代码(我得到了 2249 作为我的答案),但是我的代码效率不够高,无法使用集合 {2,3,4,5,6,7,8} . (我的代码在 {2,3,4,5,6,7} 上运行已经需要 71 秒)

我非常感谢任何使用 Mathematica 解决这个更难问题的技巧或解决方案,或者关于如何加速现有代码的一般见解。

我现有的代码使用蛮力递归方法:

(* 这将一组 1 个数字的组合定义为该 1 个数字的集合 *)

combinations[list_ /; Length[list] == 1] := list

(* 这测试是否可以对两个数字取幂,包括(有点)任意限制以防止溢出 *)
oktoexponent[number1_, number2_] :=

If[number1 == 0, number2 >= 0,
If[number1 < 0,
(-number1)^number2 < 10000 \[And] IntegerQ[number2],
number1^number2 < 10000 \[And] IntegerQ[number2]]]

(* 这需要一个列表并删除分母大于 100000 的分数 *)
cleanup[list_] := Select[list, Denominator[#] < 100000 &]

(* 这定义了一组 2 个数字的组合 - 并返回一组通过 + - * 应用获得的所有可能数字/由 oktoexponent 和清理规则过滤 *)
combinations[list_ /; Length[list] == 2 && Depth[list] == 2] :=
cleanup[DeleteCases[#, Null] &@DeleteDuplicates@
{list[[1]] + list[[2]],
list[[1]] - list[[2]],
list[[2]] - list[[1]],
list[[1]]*list[[2]],
If[oktoexponent[list[[1]], list[[2]]], list[[1]]^list[[2]],],
If[oktoexponent[list[[2]], list[[1]]], list[[2]]^list[[1]],],
If[list[[2]] != 0, list[[1]]/list[[2]],],
If[list[[1]] != 0, list[[2]]/list[[1]],]}]

(* 这扩展了组合以使用集合 *)
combinations[
list_ /; Length[list] == 2 && Depth[list] == 3] :=
Module[{m, n, list1, list2},
list1 = list[[1]];
list2 = list[[2]];
m = Length[list1]; n = Length[list2];
cleanup[
DeleteDuplicates@
Flatten@Table[
combinations[{list1[[i]], list2[[j]]}], {i, m}, {j, n}]]]

(* 对于给定的集合,partition 将所有分区的集合返回为两个非空子集 *)
partition[list_] := Module[{subsets},
subsets = Select[Subsets[list], # != {} && # != list &];
DeleteDuplicates@
Table[Sort@{subsets[[i]], Complement[list, subsets[[i]]]}, {i,
Length[subsets]}]]

(* 这最终扩展了组合以使用任何大小的集合 *)
combinations[list_ /; Length[list] > 2] := 
Module[{partitions, k},
partitions = partition[list];
k = Length[partitions];
cleanup[Sort@
DeleteDuplicates@
Flatten@(combinations /@
Table[{combinations[partitions[[i]][[1]]],
combinations[partitions[[i]][[2]]]}, {i, k}])]]

Timing[desiredset = combinations[{2, 3, 4, 5, 6, 7}];]

{71.5454, Null}

Complement[
Range[1, 3000], #] &@(Cases[#, x_Integer /; x > 0 && x <= 3000] &@
desiredset)

{2249, 2258, 2327, 2509, 2517, 2654, 2789, 2817, 2841, 2857, 2990, 2998}

最佳答案

这无济于事,但我今天无用的胡言乱语已超出我的配额:

(* it turns out the symbolizing + * is not that useful after all *) 
f[x_,y_] = x+y
fm[x_,y_] = x-y
g[x_,y_] = x*y
gd[x_,y_] = x/y

(* power properties *)
h[h[a_,b_],c_] = h[a,b*c]
h[a_/b_,n_] = h[a,n]/h[b,n]
h[1,n_] = 1

(* expand simple powers only! *)
(* does this make things worse? *)
h[a_,2] = a*a
h[a_,3] = a*a*a

(* all symbols for two numbers *)
allsyms[x_,y_] := allsyms[x,y] =
DeleteDuplicates[Flatten[{f[x,y], fm[x,y], fm[y,x],
g[x,y], gd[x,y], gd[y,x], h[x,y], h[y,x]}]]

allsymops[s_,t_] := allsymops[s,t] =
DeleteDuplicates[Flatten[Outer[allsyms[#1,#2]&,s,t]]]

Clear[reach];
reach[{}] = {}
reach[{n_}] := reach[n] = {n}
reach[s_] := reach[s] = DeleteDuplicates[Flatten[
Table[allsymops[reach[i],reach[Complement[s,i]]],
{i,Complement[Subsets[s],{ {},s}]}]]]

这里的一般想法是避免计算幂(这是
昂贵且不可交换),同时使用
加法/乘法的交换性/结合性以减少
到达基数[]。

上面的代码也可以在:

https://github.com/barrycarter/bcapps/blob/master/playground.m#L20

以及数千兆字节的其他无用代码、数据和幽默。

关于wolfram-mathematica - 无法从 {2,3,4,5,6,7,8} 获得的最小整数(Mathematica),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13977107/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com