首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >用你喜欢的数字(几乎)来解一个方程。

用你喜欢的数字(几乎)来解一个方程。
EN

Code Golf用户
提问于 2017-03-09 18:56:03
回答 4查看 3.3K关注 0票数 28

给定字符串+=-,其中至少有一个=,在所有符号之间插入正整数,并在开始和结尾插入正整数,从而满足数学方程。

例如,给定输入

代码语言:javascript
运行
复制
+-=-=

你需要像这样插入正整数A到F

代码语言:javascript
运行
复制
A+B-C=D-E=F

所以方程都是满足的,即A + B - CD - EF都是相同的数。

有许多可能的方法来做到这一点,因为,只要方程计算出来,任何一组正整数都可以使用。这里的每一行都可能是输入+-=-=的有效输出:

代码语言:javascript
运行
复制
2+3-4=6-5=1
1+1-1=2-1=1
4+2-4=4-2=2
100+1-10=182-91=91
89+231-77=1024-781=243

注意,表达式的值不需要像插入的数字那样是正整数。例如,给定输入-=-,输出1-10=8-17 (evals to -9)和10-1=17-8 (evals to 9)都同样有效。当然,对于一些输入,如=,不可能有负数作为表达式,因为只能插入像5=5这样的正数。

还请注意,零不是正整数。

以字节为单位的最短代码获胜.

您可以将数字作为列表输出,而不是将它们直接插入到字符串中。如果要输出字符串,则可能会有分隔符号和数字的空格。因此,对于输入+-=-=,输出

代码语言:javascript
运行
复制
2, 3, 4, 6, 5, 1

代码语言:javascript
运行
复制
2 + 3 - 4 = 6 - 5 = 1

等于输出

代码语言:javascript
运行
复制
2+3-4=6-5=1

测试用例

代码语言:javascript
运行
复制
Input | One Possible Output
= | 1=1
== | 2=2=2
+= | 1+3=4
=+ | 2=1+1
-= | 30-10=20
=- | 1=2-1
=-= | 3=7-4=3
=+= | 2=1+1=2
=== | 100=100=100=100
+=- | 3+2=7-2
-=+ | 7-2=3+2
+=+ | 3+3=3+3
-=- | 1-10=8-17
--= | 60-1-1=58
++= | 60+1+1=62
-+= | 60-9+1=52
+-= | 60+9-1=68
+-=-= | 2+3-4=6-5=1
--=-- | 2-1-1=2-1-1
==-== | 47=47=50-3=47=47
=++=+-=-+=--= | 3=1+1+1=3+1-1=1-1+3=5-1-1=3
+--++-=-+-+- | 35+10-16-29+20+107-1000=5-4+3-2+1-876
====== | 8=8=8=8=8=8=8
EN

回答 4

Code Golf用户

发布于 2017-03-09 19:50:33

Python 2,76字节

代码语言:javascript
运行
复制
lambda e:sum([[len(e+s)-2*s.count('+')]+[1]*len(s)for s in e.split('=')],[])

在网上试试!

票数 8
EN

Code Golf用户

发布于 2017-03-10 03:46:51

GNU Prolog,156个字节

代码语言:javascript
运行
复制
x(L,R,V)-->{E#>0},({L=[E|R],E=V};x(L,[E|R],X),("+",{V#=X+E};"-",{V#=X-E})).
q(L,R,V)-->x(L,T,V),({T=R};"=",q(T,R,V)).
s(Q,L):-q(L,[],_,Q,[]),fd_labeling(L).

解释

我们有很多方程要解决,为什么不使用一个实际的方程求解器呢?

x基本上是形式+-+方程的方程评估器;除了方程本身之外,它还有两个附加参数(包含方程值的差分列表L,R和方程计算的值V )。在Prolog中,它可以任意循环使用(例如,您可以指定V和获取L,R,指定L,R和获取V,指定两者并验证值是否正确,或者指定在任何情况下都不会对VL,R设置适当的约束)。L,R的“当前元素”名为E,我们还包括一个断言,即E大于0(因为这个问题需要使用正数)。这个函数比我想要的要详细一些,例如,我必须编写两次[E|R]模式匹配/不匹配,因为列表是右关联的,但是加和减是左关联的。可悲的是,我们需要使用一个实际的列表,而不是发明出我们自己的左侧关联列表类型的反单元格,fd_labeling才能工作。

q类似于x,但也包括=。它基本上只是调用x,并递归地调用它自己。顺便说一句,它非常清楚地演示了差异列表是如何工作的,它表明您可以将两个不同列表L,TT,R连接到一个单独的差异列表L,R中。基本思想是,差异列表是一个部分函数,它接受一个参数R,并返回一个值L,该值是R,该列表本身就在其前面。因此,通过识别一个不同列表的参数和另一个不同列表的返回值,我们可以组合函数,从而将列表连接起来。

最后,s是一个包装函数,它实际上解决了问题中的任务,它使用参数调用q。通过提供[]作为参数,将差分列表转换为正则列表,并使用fd_labeling找到我们所建立的方程的解。(默认情况下,如果没有理由将值设置为其他值,则它似乎喜欢将值设置为1。但是,它是可以配置的;例如,value_method(random)给出的“有趣”解决方案比到处放置1s更有趣,而且速度仍然很快。)

样本输出

如所写的程序:

代码语言:javascript
运行
复制
| ?- s("=++=+-=-+=--=", V).

V = [3,1,1,1,3,1,1,3,1,1,5,1,1,3] ?

如果我使程序添加value_method(random)的时间稍微长一点,结果会有所不同,但如下所示:

代码语言:javascript
运行
复制
| ?- s("=++=+-=-+=--=", V).

V = [68,6,12,50,85,114,131,45,3,26,71,1,2,68] ? 

在这两种情况下,输出末尾的?意味着可能有一个以上的解决方案。(当然,在这种情况下,我们知道有不止一个解决方案!)

票数 5
EN

Code Golf用户

发布于 2017-03-09 20:01:14

Mathematica,116个字节

代码语言:javascript
运行
复制
Join@@(Prepend[#^2,1-Min[Tr/@c]+Tr@#]&/@(c=Characters@StringSplit["0"<>#<>"0","="]/."+"->-1/."-"->1/."0"->Nothing))&

以字符串作为输入并返回正整数列表的纯函数。基本策略:我们只添加1,减去1,然后在每个表达式中选择初始值,使一切都相等。

c=Characters@StringSplit[#,"="]/."+"->-1/."-"->1将在每个等号处拆分输入字符串,然后将每个+替换为-1,将每个-替换为1。然而,如果在开头或结尾有一个等号,那么它就会被忽略。因此,我们人为地在每一端添加一个新字符("0"<>#<>"0"),并使其在字符串拆分完成(/."0"->Nothing)之后消失。

每个子列表的总和现在等于一个整数,我们可以把它放在+、S和-s前面,使每个表达式相等。1-Min[Tr/@c]是最小的整数,我们可以把它加到每个总数中,使它们都是正数。因此,Prepend[#^2,1-Min[Tr/@c]+Tr@#]&接受每个子列表( ^2将它们的所有条目转换为1),并以最小的补偿整数作为其总移位的前面。生成的列表将Join编辑在一起以生成输出。

票数 4
EN
页面原文内容由Code Golf提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codegolf.stackexchange.com/questions/112439

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档