字符串中数字的加减法


14

以一个字符串作为输入,并对字符串中的所有数字进行加/减,并输出这些运算的总和作为结果。

规则

  • 字符串中的数字从左到右读取
  • 如果数字(n)为奇数,请与下一个数字(n + n1)进行加法运算
  • 如果数字(n)为偶数,则用下一个数字(n-n1)进行减法。
  • 如果到达字符串的最后一位,请使用字符串的第一位执行操作
  • 输出将是所有结果值的总和
  • 如果字符串中只有一位数字,请自己执行操作(n + n或nn)
  • 如果字符串中没有数字,则输出为0

Input: r5e6o9mm!/3708dvc    
Process: (5+6) + (6-9) + (9+3) + (3+7) + (7+0) + (0-8) + (8-5)
Output: 32

笔记

  • 接受功能或完整程序
  • 最大输入长度将取决于您的语言对字符串输入的限制
  • 字符输入无限制,但只有半角数字计入输出
  • 最少的字节数获胜

4
还有另外几个例子也很好
dylnan '18

2
我建议添加一个以奇数结尾的测试用例。
Arnauld

3
建议测试用例:"""0""1"
TSH

1
我们可以将输入作为字符数组而不是字符串吗?(朱莉娅在这两个方面进行了区分。)
sundar-恢复莫妮卡

4
@sundar 当前共识是将字符串定义为字符序列。我的理解是,即使您的语言具有本地字符串类型,默认情况下也允许使用字符数组。
Arnauld

Answers:


6

果冻17 15 12字节

fØDV€ḂT‘ịƲSḤ

在线尝试!

尝试测试用例。

该程序仅保留跟随奇数位的数字,然后计算总和的两倍。

fØDV€ḂT‘ịƲSḤ   
f                   Remove anything that isn't...
 ØD                 a digit.
   V€               Cast each digit to an integer
         Ʋ          Monad:
     Ḃ              Parity of each digit.
      T             Indices of truthy elements (odd digits).
       ‘            Increment.
        ị           Index into list of digits.
                    Wraps to beginning and if there are no digits this returns 0.
          S         Sum.
           Ḥ        Double.

3

K(oK)47 43 40 31字节

解:

{+/(1_x,*x)*2*2!x^:(x-:48)^!10}

在线尝试!

说明:

从字符串中除去不是数字的所有内容(也进行转换),取模2,乘以2,乘以x旋转1,然后求和。

{+/(1_x,*x)*2*2!x^:(x-:48)^!10} / solution
{                             } / lambda taking implicit x
                           !10  / range 0..10
                          ^     / except
                   (     )      / do this together
                    x-:48       / subtract 48 from x (type fudging char ascii value -> ints), save back into x
                x^:             / x except right, and save back to x
              2!                / modulo 2
            2*                  / multiply by 2
           *                    / multiply by
   (      )                     / do this together
        *x                      / first element of x
       ,                        / append to
      x                         / x
    1_                          / drop first (ie rotate everything by 1)
 +/                             / sum, add (+) over (/)

天真的解决方案:

从字符串中删除不是数字的所有内容(也可以转换),获取2个项目的滑动窗口,弄清楚它们是奇数还是偶数,适当地应用加/减,然后求和。

{+/((-;+)2!x).'2':(1+#x)#x^:(x-:48)^!10}

在线尝试!

笔记:

  • @ngn得-4个字节,这归功于更聪明的输入过滤方法
  • 通过使用滑动窗口而不是整形来获得-3字节
  • -9字节移植ngn的解决方案(非幼稚的方法)

1
x:48!x@&x in,/$!10->x^:(x-:48)^!10
ngn

我在q / kdb +中编写了解决方案,然后移植到了OK ...也许还可以再压缩几个字节!
streetster

1
我在ngn / k中发布了单独的答案,请随时从那里提出想法。我认为ok最终将是最短的,因为我的解析器目前处于垃圾状态-它无法正确解析修改后的分配。顺便说一句,我没有意识到':“滑动窗口”-很有趣。
ngn

您似乎对k很熟悉。如果您想与志趣相投的人讨论矢量编程的知识,或者只是看着我们其余的人争论不休,那么我们这里有此聊天室。大部分玩笑都与APL有关,但k和J也是话题。
ngn



2

Powershell,80 78 76字节

($d="$args"-split'\D*'-ne'')+$d[0]|?{$p-match'[13579]';$p=$_}|%{$s+=2*$_};$s

-2个字节,感谢Neil使用Retina解决方案

-2个字节,感谢AdmBorkBork

测试脚本:

$f = {
($d="$args"-split'\D*'-ne'')+$d[0]|?{$p-match'[13579]';$p=$_}|%{$s+=2*$_};$s
}

&$f 'r5e6o9mm!/3708dvc'

说明

首先:如果前一位为奇数,则加2 * n,如果前一位为偶数,则加0。

($d="$args"-split'\D*'-ne'')+ # let $d is array contains digits only, each element is a digit
$d[0]|                        # apend first digit to the end of the array
?{                            # where for each digit
    $p-match'[13579]'         # predicate is 'previous digit is odd' (it is false on the first iteration because $p is null)
    $p=$_                     # let previous digit is current
}|
%{                            # for each digit matched to the predicate
    $s+=2*$_                  # add current digit multiply 2 to $s. 
}
$s                            # return sum

额外的99字节

受到@Neil的启发。正则表达式仅将匹配数字与“前一位数字为奇数”。Matches是一个自动变量

param($d)$d+($d-match'\d')+$Matches[0]|sls '(?<=[13579]\D*)\d'-a|%{$_.Matches.Value|%{$s+=2*$_}};$s

1
通过移入类似的括号|?{$_}来节省一个-ne''和另一个字节的交换。$d="$args"-split'\D*'-ne''($d="$args"-split'\D*'-ne'')+$d[0]
AdmBorkBork

2

MATL18 17字节

t4Y2m)!Ut1YSof)sE

在线尝试!

(-1字节感谢Luis Mendo / Giuseppe /两者!)

说明:

     % Implicit input
 t   % duplicate input
     % stack: ['r5e6o9mm!/3708dvc' 'r5e6o9mm!/3708dvc']
 4Y2 % push inbuilt literal, characters '0':'9'
     % stack: ['r5e6o9mm!/3708dvc' 'r5e6o9mm!/3708dvc' '0123456789']
 m)  % extract only characters from input that belong to '0':'9'
     % stack: ['5693708']
 !U  % transpose and convert each value from string to number
     % stack: [5 6 9 3 7 0 8]
 t   % duplicate that
 1YS % circular shift by 1
     % stack: [[5 6 9 3 7 0 8] [8 5 6 9 3 7 0]]
 o   % parity check - 1 for odd, 0 for even
     % stack: [[5 6 9 3 7 0 8] [0 1 0 1 1 1 0]]
 f   % find non-zero value indices in last array
     % stack: [[5 6 9 3 7 0 8] [2 4 5 6]]
 )   % index at those places in the first array
 s   % sum
 E   % multiply by 2
     % (implicit) convert to string and display

基本思想是可以忽略偶数之后的数字,而奇数后面的数字则加倍-最终结果是这些翻倍值的总和。

我认为f在进行奇偶校验后没有o必要,但是由于某些原因,MATL不会将由oa 产生的0和1的数组视为逻辑数组,而是将它们作为数字索引并将其索引为position 1end


我认为您可以使用!U代替48-。转置在这里似乎没有任何危害。o对于double输入只是mod(...,2),所以输出double。不错的NaN输入技巧!如果那是为了解决STDOUT中多余的输出,Dennis 有了一个想法,并且可能会很快解决
Luis Mendo

!U而不是48-
朱塞佩

@LuisMendo哭了,你击败了我!
朱塞佩

@Giuseppe :-D :-D
路易斯·门多

谢谢大家,编辑。@LuisMendo何时o提供逻辑数组输出-否则不提供?(我必须承认,我从未真正研究过MATLAB的数值类型系统。)是的,我认为NaN这将是一个不错的标记,因为它不太可能在任何地方进行实际输入,但是很高兴知道它不再需要很长时间了。 !
sundar-恢复莫妮卡

2

K(ngn / k),33个字节

{+/(1_x,*x)*2*2!x:-48+x^x^,/$!10}

在线尝试!

{ } 是带有参数的函数 x

!10 是清单 0 1 ... 9

$ 转换为字符串

,/ 级联

x^意味着x没有正确的东西

x^x^表示x与右边的内容相交,即仅保留x

-48+减去48,这是的ASCII码"0"

x: 分配给 x

2! Mod 2

2* 乘以2

1_x,*x是的一滴:x其次是的第一个x;即x向左旋转一步

+/


2

Japt(v2.0a0),25 19字节

-6个字节,感谢Shaggy

kè\D
íȰ*2*Y°u}Ué)x

在这里尝试。

这次没有数字了!输入是一个字符列表。


19个字节,包括切换到Japt v2。x但是,对函数中的数组不满意。如有任何疑问,请在聊天中与我联系。
毛茸茸的

等等,只是注意到如果输入不包含任何数字,则根本无法使用。
毛茸茸的

另外,@ Shaggy v2.0a0的来源在哪里?我在存储库中找不到它。
LegionMammal978 '18

是v1,是v2。
毛茸茸的

万一您在聊天中错过了它,我为您节省了12个字节
毛茸茸的

2

05AB1E12 9字节

利用dylnan的奇偶校验技巧,比朴素的方法节省了1个
字节由于Xcoder先生,节省了3个字节

þDÁ€ÉÏSO·

在线尝试!

说明

þ              # push only digits of input
 D             # duplicate
  Á            # rotate right
   ۃ          # get the parity of each
     Ï         # keep only true items
      SO       # calculate digit-sum
        ·      # double

嗯,会þÀIþ€ÉÏSO·þÀDÁ€ÉÏSO·þÀ¹þ€ÉÏSO·或者þÀsþ€ÉÏSO·通过所有测试案例-2个字节?
Xcoder先生18年

@ Mr.Xcoder:嗯,是的。真好!我们甚至可以þDÁ€ÉÏSO·为-3 做:)
Emigna '18

1

视网膜,37字节

(\d).*
$&$1
L$`(?<=[13579]\D*).
2**
_

在线尝试!说明:

(\d).*
$&$1

追加第一个数字的重复项。

L$`(?<=[13579]\D*).

匹配前一位数字为奇数的任何内容。

2**

将所有匹配项转换为一元并对其加倍。(非数字被视为零。)

_

求和 如果没有匹配项,则根据需要产生零。

我在Retina 0.8.2中能做的最好的事情是44个字节:

[^\d]

(.).*
$&$1
(?<![13579]).

.
$*
.
..
.

在线尝试!说明:

[^\d]

删除非数字。

(.).*
$&$1

附加第一个数字的副本。

(?<![13579]).

删除不跟奇数位的数字。

.
$*

转换为一元。

.
..

加倍。

.

求和


如果最后一位数字不奇数,恐怕结果将是不正确的
mazzy '18

1
@mazzy当您说最后一位数字时,是指将第一位数字复制到末尾之前还是之后?
尼尔

'到最后'。“附加第一位数字的重复”步骤是否复制到末尾?好。凉。谢谢
mazzy '18


1

JavaScript(ES6),56个字节

将输入作为字符数组。

s=>s.map(c=>1/c?r+=p*(p=c*2&2,n=n||c,c):0,n=p=r=0)|r+p*n

在线尝试!

已评论

s =>                     // given the input array s[]
  s.map(c =>             // for each character c in s[]:
    1 / c ?              //   if c is a digit:
      r +=               //     update r:
        p * (            //       p = either 0 or 2 (always 0 on the 1st iteration)
          p = c * 2 & 2, //       p = 0 if c is even, 2 if c is odd
          n = n || c,    //       if n is still equal to 0 (as an integer), set it to c
          c              //       compute p * c
        )                //     add the result to r
    :                    //   else:
      0,                 //     do nothing
    n = p = r = 0        //   n = first digit, p = previous digit, r = result
  )                      // end of map()
  | r + p * n            // compute the last operation with the 1st digit and add it to r

1

JavaScript(Node.js)85 84 83 82字节

-1字节归功于ovs

s=>(s.match(/\d/g)||[]).reduce((r,n,i,a)=>r+(+n)+a[a[++i]!=null?i:0]*-(1-n%2*2),0)

在线尝试!

接受字符串输入,将数字查找为字符数组,如果找不到则返回空数组,然后使用强制类型以确保正确添加/减去值。前向查询会预先增加索引,并为简洁起见使用null检查,然后最后一部分检查数字是奇数还是偶数,然后强制加法或减法(+和-为-等)


n-0可以+n
ovs '18

欢迎来到PPCG!
科纳·奥布莱恩

1

R,58个字节

function(x,y=strtoi(x[x%in%0:9]))sum(c(y[-1],y[1])*y%%2*2)

在线尝试!


67个字节(如果您不介意array输出)。
朱塞佩

1
嗯,实际上由于空数组,您不能使用点积,xxx因此使用索引更改a来生成它为68个字节y
朱塞佩

@ Giuseppe:修改,谢谢:)
digEmAll

@Giuseppe:我问您的意见,因为您是一个明智的代码...从评论中看来,我们可以使用字符向量,在这种情况下,可以使用61个字节:在线尝试!你怎么看 ?
digEmAll

使用strtoi代替as.double,但是是的,应该没问题。
朱塞佩



0

C Sharp 180字节

打高尔夫不是很好,大声笑。

s=>{var q=new Queue<int>(s.Where(Char.IsNumber).Select(n=>n-48));q.Enqueue(q.First());int t,o=0;o=q.Dequeue();try{while(true){t+=o+(o%2==0?-1:1)*(o=q.Dequeue());}}catch{return t;}}

松散

var q = new Queue<int>(s.Where(Char.IsNumber).Select(n=>n-48));
int t,o=0;

q.Enqueue(q.First());    
o=q.Dequeue();

try{
    while(true){
        t += o + (o%2==0?-1:1) * (o=q.Dequeue());
    }
}
catch {
    return t;
}

0

Stax,14 个字节

ÿ←«4é■≥B▬ê→█T♥

运行并调试

拆开包装,松开包装并进行评论,看起来像这样。

Vd|&    filter out non-digits
c|(\    zip into pairs after rotating right
F       for each digit pair
  B2%s  first-of-pair % 2, then swap top two stack elements
  eH*   eval digit as integer, double, then multiply
  +     add to running total

运行这个


0

JavaScript(ES6),52个字节

s=>s.filter(t=>1/t&&~(a+=u*t,u=t%2),a=u=0)[0]*u+a<<1

期望输入为字符数组。注意:由于使用了移位,输出的上限为2^31-1

在线尝试!

说明

本质上是将奇数之后的数字之和加倍。

s => s.filter(             // filter to preserve the first digit
    t =>
        1/t &&             // short-circuits if NaN
        ~(                 // coerce to truthy value
            a += u * t,    // adds value only if previous digit is odd
            u = t%2        // store parity of current digit
        ),
    a = u = 0
)[0]                       // first digit
* u + a
<< 1                       // bit-shift to multiply by 2 (also coerces a NaN resulting from a string devoid of digits to 0)
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.