加而不加(或4个基本算术运算符中的任何一个)


40

问题:

您的目标是不使用以下任何数学运算符就添加两个输入数字:+,-,*,/

此外,您不能使用旨在取代这些数学运算符的任何内置函数。

得分:

最小的代码(以字节数为单位)获胜。

更新资料

我见过的大多数程序都将包含它们的数字的两个数组连接在一起,或者将first number一个字符组成,追加second number字符,然后将它们全部计数。

最短的数组计数器:Tobia的8个字符的APL

最短数组连接:Doorknob编写的具有4个字符的Golfscript

最短的对数解决方案:Quincunx编写的具有19个字符的TI-89 Basic

集成解决方案:具有45个字符的Mathematica,作者:Michael Stern

在我看来,最酷:javascript中的按位运算符,作者:dave


它会浮起来吗?
伊斯梅尔·米格尔

7
它会有负数吗?(当前,所有答案均假设数字为正,因此您可能不应更改该数字)
Doorknob

4
数学解又如何呢?你忘了列出那些!这种集成和这个剧本的,对数
贾斯汀

3
您为什么接受其中一种较长的解决方案?是因为它接受负数而最短的解决方案(thisthis)不接受吗?如果是这样,我的答案支持负数(它也支持浮点数),并且比这一数字短。您将此问题标记为code-golf,因此必须接受最短的解决方案。
贾斯汀

2
定义“数字”。有整数吗?非负整数?他们必须以10为基数吗?
SuperJedi224

Answers:


2

小话,21 13

以下所有内容仅适用于正整数。请参阅其他Smalltalk答案以获取严肃答案。

版本1

移至一个大整数并要求其提供高位索引(不好的是,ST索引是基于1的,所以我需要额外的右移):

(((1<<a)<<b)>>1)highBit

版本2

相似,甚至更短(由于Smalltalk优先规则,不需要右移):

1<<a<<b log:2 

版本3


给定两个数字a和b,“收集-询问分配大小”主题的另一种形式,

((Array new:a),(Array new:b)) size

使用Intervals作为集合,我们得到21个字符的内存更友好版本;-):

((1to:a),(1to:b))size

不过,不建议用于大量运算。

版本4

为了娱乐起见,如果您想用时间来换取内存,请尝试:

Time secondsToRun:[
   Delay waitForSeconds:a.
   Delay waitForSeconds:b.
]

通常足够准确(但不能保证;-)))

版本5

写入文件并询问其大小

(
    [
        't' asFilename 
            writingFileDo:[:s |
                a timesRepeat:[ 'x' printOn:s ].
                b timesRepeat:[ 'x' printOn:s ]];
            fileSize 
    ] ensure:[
        't' asFilename delete
    ]
) print

45

Javascript(25)

while(y)x^=y,y=(y&x^y)<<1

这仅使用按位运算就将两个变量x和y相加,并将结果存储在x中。

这也适用于负数。


1
@dave,如果您要切换到一会儿,则可以使用while(y)x^=y,y=(y&x^y)<<1!保存另外两个字符。
Dom Hastings


3
@ user3125280,问题不是“不做加法就做加法”(这有点荒谬),而是“没有基础数学运算符就可以做加法”
Brian S

8
@ user3125280,很抱歉,但您从我的评论中解释的任何粗鲁行为都不是故意的。我确实认为您很难找到很多人,他们同意XOR应该与PLUS一起归为“基本算术”类别。除了找到同意的人之外,OP还明确指出不允许使用哪些运算符,而XOR也不是其中之一。嗯,这是一个有效的答案。
Brian S

3
for(;y;y=(y&x^y)<<1)x^=y短了1个字节:)
William Barbosa 2014年

22

C-38个字节

main(){return printf("%*c%*c",3,0,4);}

我在这里有点作弊,OP表示不使用任何数学运算符。

*printf()格式装置,其宽度用于打印字符的字段是从一个参数采取printf(),在这种情况下,3和4的返回值printf()是打印的字符数。因此,它打印一个' '字段宽度为3的字符,而打印字段宽度为4的字符,则总共打印3 + 4个字符。

返回值是printf()呼叫中增加的数字。


3
您应该设置3和4参数,而该函数不必是main。另外,如果您不在乎打印的内容,则可以将其中一个替换为' '0而忽略第二个。
ugoren 2014年

17

Python-49个字节

假设通过将输入放置在变量x和中y

from math import*
print log(log((e**e**x)**e**y))

这个61字节的解决方案是一个完整的程序:

from math import*
print log(log((e**e**input())**e**input()))

考虑到您没有禁止取幂,我不得不发布此信息。使用对数属性简化表达式时,您只需获得print input() + input()

这支持负数和浮点数。

注意:我遵循了gnibbler的建议,并将此答案分为三个部分。这是Mathematica解决方案,这是TI-89 Basic解决方案


我试图用javascript做类似的事情,但是忘记了什么公式,因为距我上次看到它已经有好几年了,并且正在互联网上搜索它。
维克多·斯塔夫萨

4
@Victor我自己创建了公式。我很清楚地记得数学。
贾斯汀

1
您的Mathematica非常接近,您只需要大写内置符号即可。Log [Log [(E ^ E ^ x)^(E ^ y)]]有效(23个字符,如果使用@表示法进行外部函数包装,则为22个字符)。
迈克尔·斯特恩

“如果允许我通过放置变量x和y来假设输入。”我想你可以-其他人也可以。
blabla999

@MichaelStern:您可以跳过括号,再保存两个字符E^y。使用Log[Log[(E^E^x)^E^y]]似乎可以正常工作。
alexwlchan 2014年

14

JavaScript [25字节]

~eval([1,~x,~y].join(''))

1
您的答案看起来很糟糕(而且很吸引人),但这实际上是一个不错的答案。请删除此文件以摆脱掉票,并用一些说明它的文字重新发布。我会支持您的新答案。
Victor Stafusa 2014年

1
现在看起来真的很好,我喜欢。当然值得更多支持。
2014年

13

Mathematica,21个字节

Mathematica中有许多方法可以做到这一点。第一,使用“累加”功能,将除最终数字以外的所有数字扔掉。与下面的其他解决方案一样,我假设输入数字在变量a和中b。21个字节

Last@Accumulate@{a, b}

尽管它是45个字符,但更有趣的是,使用数字来定义一行并集成在其下。

Integrate[Fit[{{0, a}, {2, b}}, {x, 1}, x], {x, 0, 2}]

另外,这两种解决方案都适用于所有复数,而不仅仅是其他一些整数,似乎不仅仅是正整数。


2
我喜欢整合!(尽管严格来说,这加起来有一些东西)。+1
blabla999

第一个解决方案无效。引用挑战的作者:“此外,您不能使用任何旨在替代这些数学运算符的内置函数。” 我已经给出了以下解决方案:function _(){return array_sum(func_get_args());}。我不得不删除它,因为我找不到“修复”它的简短方法。
Ismael Miguel 2014年

@Ismael Miguel Accumulate []不能替代Plus。它恰好在其输出中给出了一个数字列表的总和,我利用了这一点。
迈克尔·斯特恩

但这确实是该列表中所有元素的总和,对吗?我认为,如果确实如此,它与array_sum()在php中使用一样无效,后者的作用相同。
Ismael Miguel

3
@Ismael Miguel存在一个Mathematica函数,该函数求和一个数组,称为Total []。我同意这将违反使用该功能所指定的规则,但我没有这样做。Accumulate [{a,b}]的输出不是a + b。
Michael Stern

12

GolfScript,6 4个字符/字节

10, 5(=> 15)的形式输入。

~,+,

+是阵列串联,而不是加法。

它是如何工作的,,用于创建长度为(0,1,...,n-2,n-1)的数组。对两个数字都执行此操作,然后将数组连接起来。,再次用于不同的目的,以找到结果数组的长度。

现在,这就是窍门。我真的很喜欢这个,因为它滥用了输入格式。它看起来像它的只是输入一个数组,但实际上,由于输入被作为GolfScript代码执行,第一个,已经为我做的!(旧的6个字符的版本~,\,+,具有输入格式10 5,我通过消除\,(交换数组)减少了2个字符)。

旧版本(12)

创建一个函数f

{n*\n*+,}:f;

*+分别是串重复和级联,而不是算术函数。

说明:n创建一个单字符字符串(换行符)。然后重复此操作a,然后使用进行相同的操作b。字符串被连接起来,然后,用于字符串长度。


它也适用于负数吗?
2014年

@MichaelStern不,但是这个问题从未提到过。嗯,我添加了一条评论。大多数(实际上是全部)其他答案也都为肯定。
门把手

请参阅我的Mathematica解决方案。用正确的语言,可以解决负数问题。
迈克尔·斯特恩

@MichaelStern大声笑@“正确的语言”在所有地方的这个站点上…
Tobia

10

C,29 27字节

使用指针算法:

f(x,y)char*x;{return&x[y];}

x 被定义为指针,但调用方应传递一个整数。

匿名用户建议以下内容-也为27个字节,但参数为整数:

f(x,y){return&x[(char*)y];}

如果intint具有32位和指针具有64位的常见系统上传递两个s,则第一种形式可能会严重破坏。第二个避免了这个问题。
2014年

@hvd,两者都可以工作,至少在Linux 64bit上有效。无论如何,整数参数都会扩展到机器寄存器的大小。
ugoren 2014年

嗯,很公平,他同意这很可能是常见的情况。不过,如果我能找到一个不起作用的具体示例,请再次发表评论。:)
hvd 2014年

8

Brainf * ck,9月 36日

,>,[-<+>]

++[->,[->>[>]+[<]<]<]>>>[<[->+<]>>]<

无需使用简单的加法即可工作;它经过并留下1的尾数,然后对它们进行计数

注意:+-仅是一个增量,没有它们就无法在Brainf * ck中完成。它们并不是真正的加法/减法,因此我认为这仍然很重要。


-1。这是简单的加法。如果您执行的操作不是加法,乘法等,那么它就算了,但是就算这样也不算。
贾斯汀2014年

@Quincunx我修复了它;我做到了,然后留下一堆人的足迹,然后扫过并“捡起”那条足迹
ASKASK 2014年

3
颠倒了。不错的工作。
贾斯汀

6

J(6)

您没有说我们不能使用succ函数:

>:@[&0

用法:

   9>:@[&0(8)
17

它只重复9次 >: 8。

列表串联方法也适用:#@,&(#&0)。而且-我知道这是违反规则的-如果没有最J的解决方案,我不能放过这个答案:(*&.^乘幂运算)。


5

后记41

我们定义表达式长度为41个字节的函数为:

/a{0 moveto 0 rmoveto currentpoint pop}def

然后我们称它为:

gs -q -dBATCH -c '/a{0 moveto 0 rmoveto currentpoint pop}def' -c '10 15 a ='

这使

25.0

与大多数竞争对手不同,它可以轻松处理负片和浮点:-)



4

Smalltalk(现在很认真),123118105(*)

很抱歉回答两次,但认为这是一个严肃的答案,而另一个回答更像是幽默。目前,实际上已经在我们所有的机器上执行了以下操作(尽管在硬件中)。奇怪的是,没有人想到...

通过组合两个半加法器,并并行处理单词的所有位,我们得到(输入a,b;以s输出)可读版本:

  s := a bitXor: b.            
  c := (a & b)<<1.             

  [c ~= 0] whileTrue:[        
     cn := s & c.
     s := s bitXor: c.
     c := cn<<1.
     c := c & 16rFFFFFFFF.
     s := s & 16rFFFFFFFF.
  ].
  s           

该循环用于进位传播。掩码可确保处理带符号整数(如果没有,则只能使用无符号数字)。它们还定义了字长,以上是针对32位操作的。如果您喜欢68位加法,请更改为16rFFFFFFFFFFFFFFFFFFF。

高尔夫版本(123个字符)(通过重复使用m来避免长面具):

[:a :b||s c n m|s:=a bitXor:b.c:=(a&b)<<1.[c~=0]whileTrue:[n:=s&c.s:=s bitXor:c.c:=n<<1.c:=c&m:=16rFFFFFFFF.s:=s&m].s]

(*)通过使用-1而不是16rFFFFFFFF,我们可以更好地打高尔夫球,但是该代码不再适用于任意精度数字,仅适用于机器字大小的smallIntegers(Ansi标准中未定义largeIntegers的表示形式):

[:a :b||s c n|s:=a bitXor:b.c:=(a&b)<<1.[c~=0]whileTrue:[n:=s&c.s:=s bitXor:c.c:=n<<1.c:=c&-1.s:=s&-1].s]

这使代码大小降至105个字符。


这是代码高尔夫球,因此请高枕无忧。
Victor Stafusa 2014年

1
没有机会获胜,但我会为您做到;-)
blabla999

很高兴看到Smalltalk答案!
牙刷

4

APL,8和12

这里没有什么新鲜的,数组计数版本:

{≢∊⍳¨⍺⍵}

和日志○日志版本:

{⍟⍟(**⍺)**⍵}

我只是认为他们在APL中看起来很棒!

{≢     }       count
  ∊            all the elements in
   ⍳¨          the (two) sequences of naturals from 1 up to
     ⍺⍵        both arguments

 

{⍟⍟        }   the double logarithm of
   (**⍺)       the double exponential of ⍺
        *      raised to
         *⍵    the exponential of ⍵

2
公平地说,APL中的一切看起来都很酷。
迈克尔·斯特恩

你可以做第一个默契前缀功能5:≢∘∊⍳¨
亚当

@Adám是的,但是我不喜欢默认功能,我觉得它们很难阅读。
托比亚

@Tobia也许您不喜欢它们,因为您发现它们难以阅读?我正在为此举办一个讲习班 ……您看过我的课程吗?
亚当

@Adám太好了,谢谢!会检查出来的。
托比亚

4

sed,359字节(无花式格式)

对不起,您回答的太晚了,可能是到目前为止最长的答案。但我想看看sed是否可行:

                       s/([^ ]+) ([^ ]+)/\1:0::\2:/
                       :d /^([^:]+):\1::([^:]+):/tx
                       s/(:[^:]*)9([_:])/\1_\2/g;td
s/(:[^:]*)8(_*:)/\19\2/g;s/(:[^:]*)7(_*:)/\18\2/g;s/(:[^:]*)6(_*:)/\17\2/g
s/(:[^:]*)5(_*:)/\16\2/g;s/(:[^:]*)4(_*:)/\15\2/g;s/(:[^:]*)3(_*:)/\14\2/g
s/(:[^:]*)2(_*:)/\13\2/g;s/(:[^:]*)1(_*:)/\12\2/g;s/(:[^:]*)0(_*:)/\11\2/g
                       s/:(_+:)/:1\1/g; y/_/0/; # #
                       bd;  :x  s/.*::([^:]+):/\1/;
                       # # # # # # #  # # # # # # #

这类似于https://codegolf.stackexchange.com/a/38087/11259,它只是增加字符串中的数字。但是,它循环执行增量操作。

输入来自STDIN,格式为“ x y”。首先将其转换为“ x:0 :: y:”。然后,我们递增所有在“:”字符之后的数字,直到得到“ x:x::( x + y):”。然后,我们最终返回(x + y)。

输出量

$ printf "%s\n" "0 0" "0 1" "1 0" "9 999" "999 9" "12345 67890" "123 1000000000000000000000"  | sed -rf add.sed
0
1
1
1008
1008
80235
1000000000000000000123
$

请注意,这仅适用于自然数。但是(至少在理论上)它适用于任意大整数。因为我们在y上执行x递增运算,所以排序可以极大地提高速度:x <y将比x> y快。


4

短划线,18个字节

time -f%e sleep $@

需要GNU时间1.7或更高。输出到STDERR。

在线尝试!

请注意,这不适用于B灰,因为从GNU时间其内置time命令不同。

\time可以使用一个额外的字节作为代价,而不是time强制Bash使用外部命令。


如果输入之一为负会发生什么?
2014年

4
它失败。就像所有其他答案一样。
丹尼斯

5
鸭!我希望它能在提出问题之前给出结果。
Tobia 2014年

3
是的 我也非常希望通过插入随机数sleep -3可以加快程序速度。真令人失望。
Alfe 2014年

1
@userunknown \time在Bash中也应该工作。
丹尼斯

3

Java语言(67)

可能更好

a=Array;p=Number;r=prompt;alert(a(p(r())).concat(a(p(r()))).length)

在不知道它是否需要浮点数的情况下,不应给出明确的答案。而且它不会处理NaN。但是它是一个很好的代码!
伊斯梅尔·米格尔

我认为所有这些joins都是不必要的。该Array构造使得阵列undefineds,它可以被计算:a=Array;p=parseInt;r=prompt;alert(a(p(r())).concat(a(p(r()))).length)
本帝国

@BenReich,您说得对,谢谢
Michael M.

@Michael此外,Number构造函数还保存了2个字符parseInt
Ben Reich

@Michael另外,如果删除alert,输出仍将进入控制台,但这会使答案变得不太有趣。您还可以重用prompt变量而不是alert(构造函数使用提示来警告参数)。无论如何,不​​错的答案!
Ben Reich 2014年

3

Ruby,18个字符

a.times{b=b.next}

还有另外两个详细变体,共29个字符

[*1..a].concat([*1..b]).size

另一个版本,32个字符

(''.rjust(a)<<''.rjust(b)).size

3

C#-动态代码生成

是的,实际上里面有一个加法,但是+运算符甚至没有做加法的框架函数,相反,我们动态地生成了一个执行加法的方法。

public static int Add(int i1, int i2)
{
    var dm = new DynamicMethod("add", typeof(int), new[] { typeof(int), typeof(int) });
    var ilg = dm.GetILGenerator();
    ilg.Emit(OpCodes.Ldarg_0);
    ilg.Emit(OpCodes.Ldarg_1);
    ilg.Emit(OpCodes.Add);
    ilg.Emit(OpCodes.Ret);
    var del = (Func<int, int, int>)dm.CreateDelegate(typeof(Func<int, int, int>));
    return del(i1, i2);
}


2

R 36

function(x,y)length(rep(1:2,c(x,y)))

在这里rep建立一个由x1和y2组成的向量。


2
您可以将程序做的更短一些:length(rep(1:2,scan()))
Masclins

2

TI Basic 89-19字节

在TI-89(主屏幕或编程应用)中运行此命令:

ln(ln((e^e^x)^e^y))

x+y就像此解决方案一样,它使用日志规则进行计算。另外,它适用于十进制和整数。它适用于所有实数。如果对数规则对于复数指数仍然有效,那么这也适用于复数。但是,当我尝试插入复杂的指数时,我的计算器会吐出垃圾。


3
lnTI Basic中不是1个字节吗?另外,您可以删除右括号,将其减小到15个字节。
ɐɔıʇǝɥʇuʎs

2

感谢Michael Stern教给我Mathematica符号

Mathematica- 21 20字节

Log@Log[(E^E^x)^E^y]

这使用与该解决方案相同的方法,但是在Mathematica中将其缩短了。此作品为负和浮点数,以及在整数xy

使用对数规则简化表达式yields x+y,但这是有效的,因为它使用了幂运算,而不是4个基本运算符之一。


您确定它适用于复数吗?
2014年

2

C#-字符串算术

我们将两个数字都转换为字符串,使用字符串切割(加进位和所有内容,您知道)进行加法运算,然后解析回整数。用0..200中的i1测试过的i2,就像一个超级按钮。在这个中找到一个附加项!

public static int Add(int i1, int i2)
{
    var s1 = new string(i1.ToString().Reverse().ToArray());
    var s2 = new string(i2.ToString().Reverse().ToArray());
    var nums = "01234567890123456789";
    var c = '0';
    var ret = new StringBuilder();
    while (s1.Length > 0 || s2.Length > 0 || c != '0')
    {
        var c1 = s1.Length > 0 ? s1[0] : '0';
        var c2 = s2.Length > 0 ? s2[0] : '0';
        var s = nums;
        s = s.Substring(int.Parse(c1.ToString()));
        s = s.Substring(int.Parse(c2.ToString()));
        s = s.Substring(int.Parse(c.ToString()));
        ret.Append(s[0]);
        if (s1.Length > 0)
            s1 = s1.Substring(1);
        if (s2.Length > 0)
            s2 = s2.Substring(1);
        c = s.Length <= 10 ? '1' : '0';
    }
    return int.Parse(new string(ret.ToString().ToCharArray().Reverse().ToArray()));
}





2

K,2个字节

#&

用法示例:

  #&7 212
219

将“ where”运算符(monadic &)应用于输入列表中的数字(可能会随意使用输入格式)。这将产生一个列表,其中包含第一个零和第二个零:

  &3 2
0 0 0 1 1

通常,此运算符用作“集合”以生成布尔列表的非零元素的索引列表,但一般形式有时会派上用场。

然后只需计算该列表的数量(monadic #)。

如果我对输入要求的解释不可接受,则以下稍长的解决方案也有相同的技巧:

{#&x,y}

2

Pyth,29个字节

AQW!qG0=k.&GH=HxGH=k.<k1=Gk)H

在线尝试!

我的第一次提交在这里!

编译为:

assign('Q',eval_input())     # Q
assign('[G,H]',Q)            #A
while Pnot(equal(G,0)):      #  W!qG0
  assign('k',bitand(G,H))    #       =k.&GH
  assign('H',index(G,H))     #             =HxGH  (index in this case is XOR)
  assign('k',leftshift(k,1)) #                  =k.<k1
  assign('G',k)              #                        =Gk)
imp_print(H)                 #                            H

1
欢迎光临本站!
小麦巫师
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.