算术和中缺少数字


14

挑战

给定一个有效的算术和,并包含一些缺失的数字,输出完整的表达式。

例:

    1#3                 123
+   45#     =>     +    456
--------            --------
    579                 579

输入值

  • 表达式格式可以是数组["1#3", "45#", "579"],字符串"1#3+45#=579"或3个输入f("1#3","45#","579")

输出量

  • 与输入相同
  • 您不需要输出结果

笔记

  • 缺失的数字将使用#或您想要的任何其他恒定非数字字符表示
  • 假设结果不会缺少数字
  • 假设输入/输出包含2个项和一个最终结果
  • 假设两项> 0且结果> = 2
  • 可能有多种解决方案。您可以输出任何人,只要总和结果匹配

具有可能的输出的测试用例(漂亮的格式)

    #79                     879
+   44#         =>      +   444
--------                --------
    1323                   1323

    5#5                     555
+   3#3         =>      +   343
--------                --------
    898                     898

      #                       1
+     #         =>      +     1
--------                --------
      2                       2

    ###                     998
+   ###         =>      +     1     PD: there are a lot of possible outputs for this one
--------                --------
    999                     999


    123                     123
+     #         =>      +     1
--------                --------
    124                     124


      9                       9
+    #6         =>      +    46
--------                --------
     55                      55


    #123651                     1123651
+      #98#         =>      +      7981
------------                -----------
    1131632                     1131632

适用标准规则


我们是否需要去除前导零?

@助记符不一定
Luis

我可以=交换周围的边来接受输入吗?例如579=1#3+45#
dzaima

2
“假设两个项均大于0”是否“假设”是指我必须输出两个项均大于0,或者我可以假定总有一个解决方案,两个项均大于0,但输出什么呢?
dzaima

1
您添加的测试用例也完全避免了我要的内容-前导零
dzaima

Answers:


9

Brachylog22 16字节

{Ṣ∧Ị∋|}ᵐ²ịᵐ.k+~t

在线尝试!

-6个字节,感谢@Fatelize

说明

{Ṣ∧Ị∋|}ᵐ²ịᵐ.k+~t
{     }ᵐ²                   #   for each letter in each string
 Ṣ∧Ị∋                       #       if " " return a digit; else input
     |                      #
         ịᵐ                 #   cast each string to number
            k+              #   the sum of all but the last one
              ~t            #       is equal to the last one
           .                #   output that list

1
{"#"∧Ị∋|}ᵐ²ịᵐ.k+~t短4个字节。我不确定为什么您要在地图上做这些复杂的事情。
致命的

由于我们可以使用任何非数字字符,因此应使用例如空格代替"#",否则将节省两个字节。
致命的

8

JavaScript(ES6), 74 57字节

将输入作为(a)(b)(result),其中ab是具有.未知数字和结果的字符串是整数。返回2个整数的数组。

a=>b=>F=(c,n)=>`${r=[c,n]}`.match(`^`+[a,b])?r:F(c-1,-~n)

在线尝试!

已评论

a => b =>                // a, b = term patterns (e.g. a = ".79", b = "44.")
  F = (c,                // c = expected result (e.g. 1323)
          n) =>          // n = guessed value of b, initially undefined
    `${r = [c, n]}`      // we coerce r = [c, n] to a string (e.g. "879,444")
                         // if n is still undefined, this gives just c followed by a comma
    .match(`^` + [a, b]) // we coerce [a, b] to a string, prefixed with "^" (e.g. "^.79,44.")
    ?                    // this is implicitly turned into a regular expression; if matching:
      r                  //   return r
    :                    // else:
      F(c - 1, -~n)      //   decrement c, increment n and do a recursive call

啊,就是这样。昨天,我试图不加解释地理解您的代码(我对JS很不好),但不明白为什么-~n不公正n+1以及如何F=(c,n)=>使用。现在您已经添加了解释,这一切都说得通了。c是第三个输入,n未定义(并且~undefined变得不-1一样undefined+1)。现在一切都清楚了(不幸的是,我无法移植到Java上,这主要是为什么我试图通过xD来理解它)。PS:昨天已经投票,所以我只是投票了您的其他答案之一(我还没有投票,没有很多可用..); p
Kevin Cruijssen,

@KevinCruijssen FWIW,我前段时间对此写过一个提示。但是,是的……这是一个JS东西,可能无法移植到许多其他语言中。
阿纳尔德

好吧,我也许可以半移植它,但只需创建一个递归的第二种方法,然后使用三元if进行检查null,即可将其手动转换为-1。但是,Java有一个(非常)有限的递归StackOverflow限制,因此使用具有随机性的递归方法希望它在大约1024个递归调用中最终正确,这在Java中还是行不通的。呃,好吧。我赞成你的建议。周末愉快!:)
Kevin Cruijssen

@KevinCruijssen我的第一个JS尝试正是这样做的:使用递归函数尝试随机值。而且它通常比使用计数器进行的迭代少得多。有趣的事实:即使是###+###=999,您的几率也是1000的1。因此,进行1024次迭代后,成功的几率要大于失败的几率。:)
Arnauld '18

7

MATLAB,143个 134 132 119 115字节

function[m]=f(x,y,r),p=@(v)str2num(strrep(v,'#',char(randi([48,57]))));m=[1,1];while sum(m)-r,m=[p(x),p(y)];end;end

-4个字节感谢@Luismendo

在线尝试


很大又很蠢。它只是将所有#数字替换为随机数字,直到找到正确的数字为止。


5

R67 51字节

简单摇滚,可伸缩,只需grep所有总和即可。采用 ”。” 对于未知数字。它不会找到与第4个测试用例相同的答案,但是它将给出一个可能的答案,该答案遵循给出的规则字母。

-16字节通过形成输出和更换后grepping paste?运算符。

function(x,y,z,`?`=paste)grep(x?y,1:z?z:1-1,v=T)[1]

在线尝试!


1
很棒的主意,我永远也不会想到。您可以使用*代替grepl来节省一些字节:tio.run
##

1
我一直在寻找各种运营商,您想出了?...我认为这是第一次。顺便说一句,我忘记了是否已经告诉过您,但我们正在努力让R 提名当月的9月语言 -如果尚未完成,您可以投票。
JayCe '18年

我可以选择任何优先级较低的东西。感觉应该有更好的方法来获得比赛...
J.Doe

3

木炭,32字节

F²⊞υ0W⁻ζΣIυ≔E⟦θη⟧⭆κ⎇⁼μ#‽χμυ←Eυ⮌ι

在线尝试!链接是详细版本的代码。说明:

F²⊞υ0

将两个字符串0s 推送到预定义的空列表u以获取while循环。

W⁻ζΣIυ

在将值强制转换u为整数的总和不等于所需的结果时,请重复。

≔E⟦θη⟧

创建两个输入的数组并映射。

⭆κ⎇⁼μ#‽χμυ

#随机数替换每个数字,然后将结果分配回u

←Eυ⮌ι

正确打印结果。(左对齐只是υ为了节省4个字节。)



3

05AB1E(旧版),23 20 字节

[²³«εð9ÝΩ:}²gôJDO¹Q#

-3个字节,感谢@Emigna

未知数字为空格( )。输入顺序应为:预期结果;最长的字符串 最短的字符串。

在线尝试

说明:

[                 # Start an infinite loop
 ²³«              #  Take the second and third inputs, and merge them together
               #   i.e. " 79" and " 4 " → " 79 4 "
    ε     }    #  Map each character to:
     ð   :     #   Replace a space with:
      9ÝΩ      #   A random digit in the range [0,9]
               #    i.e. " 79 4 " → ['3','7','9','2','4','3']
               #    i.e. " 79 4 " → ['5','7','9','7','4','4']
²g             #  Get the length of the second input
               #   i.e. " 79" → 3
  ô            #  And split it into two numbers again
               #   i.e. ['3','7','9','2','4','3'] and 3 → [['3','7','9'],['2','4','3']]
               #   i.e. ['5','7','9','7','4','4'] and 3 → [['5','7','9'],['7','4','4']]
   J           #  Join each list together to a single number
               #   i.e. [['3','7','9'],['2','4','3']] → [379,243]
               #   i.e. [['5','7','9'],['7','4','4']] → [579,744]
    D          #  Duplicate this list
     O         #  Sum the list
               #   i.e. [379,243] → 622
               #   i.e. [579,744] → 1323
      ¹Q#      #  If it's equal to the first input: stop the infinite loop
               #  (and output the duplicate list implicitly)
               #   i.e. 1323 and 622 → 0 (falsey) → continue the loop
               #   i.e. 1323 and 1323 → 1 (truthy) → stop the loop and output [579,744]

1
替换在if上保存3。
Emigna '18

@Emigna啊,当然。谢谢!
凯文·克鲁伊森

3

Perl 6的81 74个字节

-7个字节感谢nwellnhof!

{first {try S/\=/==/.EVAL},map {$^a;S:g[\#]=$a[$++]},[X] ^10 xx.comb('#')}

在线尝试!

将输入作为包含算术表达式的字符串作为输入的匿名代码块,例如“ 12#+ 45#= 579”。每个替代#与数字可能的排列,取代了===和找到的第一个有效的结果。

说明:

{  # Anonymous code block                                                      }
 first   # Find the first of:
                                                               ^10  # The range of 0 to 9
                                                                   xx.comb('#') # Multiplied by the number #s in the code
                                                          ,[X]  # The cross-product of these lists
                          map   # Map each crossproduct to:
                              {$^a;.trans: "#"=>{$a[$++]}}  # The given string with each # translated to each element in the list
      {try S/\=/==/.EVAL}, # Find which of these is true when = are changed to == and it is eval'd

您可以使用S:g[\#]=$a[$++],而不是trans74个字节
nwellnhof '18

@nwellnhof我不知道您可以使用S///这种语法!谢谢!
Jo King


2

Java的10,203个 198 193字节

(a,b,c)->{int A=0,B=0,l=a.length();for(a+=b,b="";A+B!=c;A=c.valueOf(b.substring(0,l)),B=c.valueOf(b.substring(l)),b="")for(var t:a.getBytes())b+=t<36?(t*=Math.random())%10:t-48;return A+"+"+B;}

在线尝试。

说明:

(a,b,c)->{           // Method with 2 Strings & integer parameters and String return-type
  int A=0,B=0,       //  Result-integers, starting both at 0
      l=a.length();  //  Length of the first String-input
  for(a+=b,          //  Concat the second String-input to the first
      b="";          //  Reuse `b`, and start it as an empty String
      A+B!=c         //  Loop as long as `A+B` isn't equal to the integer-input
      ;              //    After every iteration:
       A=c.valueOf(b.substring(0,l)),
                     //     Set `A` to the first String-part as integer
       B=c.valueOf(n.substring(l)),
                     //     Set `B` to the second String-part as integer
       b="")         //     Reset `b` to an empty String
    for(var t:a.getBytes())
                     //   Inner loop over the characters of the concatted String inputs
      b+=t<36?       //    If the current character is a '#':
          (t*=Math.random())%10
                     //     Append a random digit to `b`
         :           //    Else (it already is a digit):
          t-48;      //     Append this digit to `b`
  return A+"+"+B;}   //  After the loop, return `A` and `B` as result

2

C(GCC) 228个 213 203 172 170字节

-15个字节,感谢@ceilingcat。我从没用过index

-10个字节感谢@Logem。预处理魔术

exit(0)以puts作为参数的重构调用。

char*c,*p[9],k;main(i,v)int**v;{for(i=X[1],35))||X[2],35))?p[k++]=c,main(*c=57,v):k;!c*i--;)47==--*p[i]?*p[i]=57:Y[1])+Y[2])^Y[3])?main(i,v):exit(puts(v[2],puts(v[1])));}

在线尝试!



您可以保存两个字节,在最后一条评论-DX=c=index(v中用-DX=(c=index(vTIO链接替换宏。
Logern

谢谢你们。看起来好像我以前都没有试过高尔夫……
cleblanc 18/09/25

1

C#的.NET,225个 220 196字节

(a,b,c)=>{int A=0,B=0,l=a.Length;for(a+=b,b="";A+B!=c;A=int.Parse(b.Substring(0,l)),B=int.Parse(b.Substring(l)),b="")foreach(var t in a)b+=(t<36?new System.Random().Next(10):t-48)+"";return(A,B);}

我的Java 10答案端口。
(我在C#.NET打高尔夫球时非常生锈,因此可以肯定地打高尔夫球。)

-3个字节隐式感谢@ user82593他添加的这个新C#技巧
-29字节感谢@hvd

在线尝试。

说明:

(a,b,c)=>{        // Method with 2 string & int parameters and int-tuple return-type
  int A=0,B=0,    //  Result-integers, starting both at 0
      l=a.Length; //  Length of the first string-input
  for(a+=b,       //  Concat the second string-input to the first
      b="";       //  Reuse `b`, and start it as an empty string
      A+B!=c      //  Loop as long as `A+B` isn't equal to the integer-input
      ;           //    After every iteration:
       A=int.Parse(b.Substring(0,l)),
                  //     Set `A` to the first string-part as integer
       B=int.Parse(b.Substring(l)),
                  //     Set `B` to the second string-part as integer
       b="")      //     Reset `b` to an empty string
    foreach(var t in a)
                  //   Inner loop over the characters of the concatted string inputs
      b+=(t<36?   //    If the current character is a '#':
           new System.Random().Next(10)
                  //     Use a random digit
          :       //    Else (it already is a digit):
           t-48)  //     Use this digit as is
         +"";     //    And convert it to a string so it can be appended to the string
  return(A,B);}   //  After the loop, return `A` and `B` in a tuple as result

您可以改用常规代码using System;,它比短namespace System{}
hvd

@hvd就是这样!..我已经好几年没有做C#了,大声笑using System.*;。忘了我必须删除该.*部分。。感谢-5个字节。
凯文·克鲁伊森

1
现在重新阅读,实际上是次优的建议。您可以写入int.Parse(-4),使用new System.Random()(+7)和拖放using System;(-13)保存另外10个字节。:)另外,您不需要.ToCharArray(),它又可以占用14个字节。
hvd

@hvd谢谢!不知道我怎么忘了int.Parsevs System.Int32.Parse。。。基本上与System.Stringand string.. 相同,而且不知道没有。也可以遍历字符.ToCharArray()。感谢您提供另外-24个字节。:D
凯文·克鲁伊森

1

Python 3中121个 155 152 149字节

import re
def f(i,k=0,S=re.sub):s=S('#','%s',i)%(*list('%0*d'%(i.count('#'),k)),);print(s)if eval(S('=','==',S('\\b0*([1-9])','\\1',s)))else f(i,k+1)

在线尝试!

+34使用正则表达式的新解决方案来规避python不支持带前导零的数字这一事实。

-3感谢@Jonathan Frech


如果#是任意数字中的第一个字符(因为eval不接受前导零),则旧解决方案不起作用,因此无效:(

def f(i,k=0):
 s=i.replace('#','%s')%(*list('%0*d'%(i.count('#'),k)),)
 print(s)if eval(s.replace('=','=='))else f(i,k+1)

在线尝试!


1
由于帖子中所述原因,我担心此提交内容无效。
暴民埃里克(Erik the Outgolfer)'18年

2
由于您的函数不包含任何复合语句,因此您只能将其压缩为一行。
乔纳森·弗雷希

0

PHP,112字节

me脚蛮力解决方案

for(;$s=$argn;eval(strtr($s,['='=>'==','#'=>0]).'&&die($s);'))for($k=$n++;$k;$k=$k/10|0)$s[strpos($s,35)]=$k%10;

将字符串作为输入,在第一个解决方案处停止。与管道一起运行-nR在线尝试


0

Powershell,91字节

该脚本查找所有解决方案。迭代的总数是10乘以字符数#。递归深度等于字符数#

filter f{$h,$t=$_-split'#',2
if($t){0..9|%{"$h$_$t"}|f}elseif($h-replace'=','-eq'|iex){$h}}

测试脚本:

filter f{$h,$t=$_-split'#',2
if($t){0..9|%{"$h$_$t"}|f}elseif($h-replace'=','-eq'|iex){$h}}

@(
    ,('1#3+45#=579','123+456=579')
    ,('#79+44#=1323','879+444=1323')
    ,('5#5+3#3=898','505+393=898 515+383=898 525+373=898 535+363=898 545+353=898 555+343=898 565+333=898 575+323=898 585+313=898 595+303=898')
    ,('#+#=2','0+2=2 1+1=2 2+0=2')
    ,('9+#6=55','9+46=55')
    ,('123+##=124','123+01=124')
    ,('#123651+#98#=1131632','1123651+7981=1131632')
    ,('##+##=2','00+02=2 01+01=2 02+00=2')
    ,('##+##=99','00+99=99 01+98=99 02+97=99 03+96=99 04+95=99 05+94=99 06+93=99 07+92=99 08+91=99 09+90=99 10+89=99 11+88=99 12+87=99 13+86=99 14+85=99 15+84=99 16+83=99 17+82=99 18+81=99 19+80=99 20+79=99 21+78=99 22+77=99 23+76=99 24+75=99 25+74=99 26+73=99 27+72=99 28+71=99 29+70=99 30+69=99 31+68=99 32+67=99 33+66=99 34+65=99 35+64=99 36+63=99 37+62=99 38+61=99 39+60=99 40+59=99 41+58=99 42+57=99 43+56=99 44+55=99 45+54=99 46+53=99 47+52=99 48+51=99 49+50=99 50+49=99 51+48=99 52+47=99 53+46=99 54+45=99 55+44=99 56+43=99 57+42=99 58+41=99 59+40=99 60+39=99 61+38=99 62+37=99 63+36=99 64+35=99 65+34=99 66+33=99 67+32=99 68+31=99 69+30=99 70+29=99 71+28=99 72+27=99 73+26=99 74+25=99 75+24=99 76+23=99 77+22=99 78+21=99 79+20=99 80+19=99 81+18=99 82+17=99 83+16=99 84+15=99 85+14=99 86+13=99 87+12=99 88+11=99 89+10=99 90+09=99 91+08=99 92+07=99 93+06=99 94+05=99 95+04=99 96+03=99 97+02=99 98+01=99 99+00=99')
) | % {
    $s,$e = $_
    $r = $s|f
    "$($e-eq$r): $r"
}

Powershell,“假设两个词均> 0”是必需的,110字节

filter f{$h,$t=$_-split'#',2
if($t){0..9|%{"$h$_$t"}|f}else{$a,$b,$c=$_-split'\D'
$_|?{+$a*+$b*!(+$a+$b-$c)}}}
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.