Phép cộng - Phép trừ số trong chuỗi


14

Lấy một chuỗi làm đầu vào và thực hiện phép cộng / trừ tất cả các chữ số trong chuỗi và xuất tổng của các hoạt động đó làm kết quả.

Quy tắc

  • Các chữ số trong chuỗi được đọc từ trái sang phải
  • Nếu một chữ số (n) là số lẻ, hãy thực hiện phép cộng với chữ số tiếp theo (n + n1)
  • Nếu một chữ số (n) chẵn, thực hiện phép trừ với chữ số tiếp theo (n - n1)
  • Nếu bạn đã đạt đến chữ số cuối cùng trong chuỗi, hãy thực hiện thao tác với chữ số đầu tiên trong chuỗi
  • Đầu ra sẽ là tổng của tất cả các giá trị kết quả
  • Nếu chỉ có một chữ số trong chuỗi, hãy thực hiện thao tác với chính nó (n + n hoặc nn)
  • Nếu không có chữ số trong chuỗi, đầu ra là 0

Thí dụ

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

Ghi chú

  • Chức năng hoặc chương trình đầy đủ được chấp nhận
  • Độ dài đầu vào tối đa sẽ phụ thuộc vào giới hạn ngôn ngữ của bạn cho đầu vào chuỗi
  • Không có giới hạn đối với đầu vào ký tự, nhưng chỉ các chữ số nửa chiều rộng được tính vào đầu ra
  • Ít byte nhất sẽ thắng

4
Một vài ví dụ nữa cũng sẽ tốt
dylnan

2
Tôi khuyên bạn nên thêm một trường hợp thử nghiệm kết thúc bằng một chữ số lẻ.
Arnauld

3
Testcase gợi ý: "", "0","1"
tsh

1
Chúng ta có thể lấy đầu vào là một mảng các ký tự thay vì một chuỗi không? (Julia làm cho một sự khác biệt giữa hai người đó.)
- Phục hồi Monica

4
@sundar Sự đồng thuận hiện tại là một chuỗi được định nghĩa là một chuỗi các ký tự. Do đó, tôi hiểu rằng các mảng ký tự được cho phép theo mặc định ngay cả khi ngôn ngữ của bạn có loại chuỗi gốc .
Arnauld

Câu trả lời:


6

Thạch , 17 15 12 byte

fØDV€ḂT‘ịƲSḤ

Hãy thử trực tuyến!

Hãy thử các trường hợp thử nghiệm.

Chương trình chỉ giữ các chữ số theo sau một chữ số lẻ sau đó tính hai lần tổng.

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 byte

Giải pháp:

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

Hãy thử trực tuyến!

Giải trình:

Xóa mọi thứ khỏi chuỗi không phải là số (đồng thời chuyển đổi), modulo 2, nhân với 2, nhân với x được xoay bởi 1 và tổng hợp.

{+/(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 (/)

Giải pháp ngây thơ:

Xóa mọi thứ khỏi chuỗi không phải là số (đồng thời chuyển đổi), lấy cửa sổ trượt 2 mục, tìm hiểu xem chúng là số lẻ hay chẵn, áp dụng cộng / trừ khi thích hợp, sau đó tổng hợp.

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

Hãy thử trực tuyến!

Ghi chú:

  • -4 byte nhờ @ngn do cách lọc đầu vào thông minh hơn
  • -3 byte bằng cách sử dụng cửa sổ trượt thay vì định hình lại
  • -9 byte chuyển giải pháp của ngn (cách tiếp cận không ngây thơ)

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

Tôi đã viết giải pháp bằng q / kdb + sau đó được chuyển sang oK ... có thể có thể nén thêm một vài byte trong số này!
streetster

1
Tôi đã đăng một câu trả lời riêng trong ngn / k, cứ tự nhiên đưa ra ý tưởng từ đó. Tôi nghĩ rằng oK cuối cùng sẽ là ngắn nhất, vì trình phân tích cú pháp của tôi là rác rưởi vào lúc này - nó không phân tích cú pháp sửa đổi đúng. Nhân tiện, tôi không biết ':là "cửa sổ trượt" - thú vị.
ngn

Bạn có vẻ quen thuộc với k. Nếu bạn từng cảm thấy muốn thảo luận về công cụ lập trình vector với những người cùng chí hướng hoặc chỉ xem phần còn lại của chúng tôi tranh luận - chúng tôi đã có phòng trò chuyện này . Hầu hết các trò đùa là về APL, nhưng k và J cũng thuộc chủ đề.
ngn



2

Powershell, 80 78 76 byte

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

-2 byte cảm ơn Neil với giải pháp Retina

-2 byte cảm ơn admBorkBork

Kịch bản thử nghiệm:

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

&$f 'r5e6o9mm!/3708dvc'

Giải trình

Trước hết: phải thêm 2 * n nếu chữ số trước là số lẻ và 0 nếu chữ số trước là số chẵn.

($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

Thêm, 99 byte

Lấy cảm hứng từ @Neil. Regex khớp các chữ số với 'chữ số trước là số lẻ'. Matcheslà một biến tự động .

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

1
Lưu một byte hoán đổi |?{$_}cho -ne''và khác bằng cách di chuyển $d="$args"-split'\D*'-ne''vào parens như ($d="$args"-split'\D*'-ne'')+$d[0].
admBorkBork

2

MATL , 18 17 byte

t4Y2m)!Ut1YSof)sE

Hãy thử trực tuyến!

(-1 byte nhờ Luis Mendo / Giuseppe / cả hai!)

Giải trình:

     % 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

Ý tưởng cơ bản là các số theo số chẵn có thể bị bỏ qua, trong khi những số theo số lẻ được nhân đôi - và kết quả cuối cùng là tổng của các giá trị nhân đôi đó.

Tôi đã không nghĩ rằng fsau khi kiểm tra chẵn lẻ olà cần thiết, nhưng vì một số lý do, MATL không thấy mảng 0 và 1 là kết quả của omảng logic, thay vào đó lấy chúng làm chỉ số và chỉ mục số vào vị trí 1end.


Tôi nghĩ bạn có thể sử dụng !Uthay vì 48-. Transpose dường như không gây hại gì ở đây. ocho doubleđầu vào là chỉ mod(...,2), vì vậy đầu ra là double. NaNThủ thuật đầu vào đẹp ! Nếu điều đó có nghĩa là giải quyết đầu ra không liên quan trong STDOUT, Dennis đã có một ý tưởng và có thể sẽ khắc phục điều đó sớm
Luis Mendo

!Uthay vì48-
Giuseppe

@LuisMendo welp, bạn đánh tôi với cú đấm!
Giuseppe

@Giuseppe :-D :-D
Luis Mendo

Cảm ơn cả hai, đã chỉnh sửa. @LuisMendo Khi nào thì ođưa ra một đầu ra mảng logic - hay không? (Tôi phải thú nhận tôi chưa bao giờ thực sự nhìn vào hệ thống kiểu số MATLAB.) Và yeah, tôi nghĩ NaNsẽ làm cho một sentinel đẹp vì nó dường như không có bất cứ nơi nào đầu vào thực tế, nhưng tốt để biết nó sẽ không cần thiết cho lâu hơn nữa !
- Phục hồi Monica

2

K (ngn / k) , 33 byte

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

Hãy thử trực tuyến!

{ } là một hàm với đối số x

!10 là danh sách 0 1 ... 9

$ chuyển đổi thành chuỗi

,/ ghép

x^có nghĩa là xkhông có những gì bên phải

x^x^có nghĩa là xgiao nhau với những gì ở bên phải, tức là chỉ giữ các chữ số từx

-48+trừ 48, là mã ASCII của"0"

x: giao cho x

2! mod 2

2* nhân với 2

1_x,*xlà một giọt của: xtiếp theo là đầu tiên của x; tức là xquay sang trái một bước

+/ Tổng


2

Japt (v2.0a0), 25 19 byte

-6 byte nhờ Shaggy .

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

Hãy thử nó ở đây .

Nó hoạt động không có chữ số lần này! Đầu vào là một danh sách các ký tự.


19 byte , bao gồm chuyển sang Japt v2. Không hài lòng với các mảng trong xchức năng, mặc dù. Ping tôi trong trò chuyện nếu bạn có bất kỳ câu hỏi.
Shaggy

Đợi đã, chỉ cần lưu ý rằng điều này sẽ không hoạt động nếu đầu vào không chứa bất kỳ chữ số nào.
Shaggy

Ngoài ra, nguồn cho v2.0a0, @Shaggy ở đâu? Tôi không thể tìm thấy nó trong repo.
LegionMammal978

Đây là v1 và đây là v2.
Shaggy

Trong trường hợp bạn bỏ lỡ nó trong trò chuyện, tôi đã giảm xuống còn 12 byte cho bạn.
Xù xì

2

05AB1E , 12 9 byte

Lưu 1 byte qua phương thức ngây thơ bằng cách sử dụng thủ thuật chẵn lẻ của dylnan
Lưu 3 byte nhờ vào ông Xcoder

þDÁ€ÉÏSO·

Hãy thử trực tuyến!

Giải trình

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

Hmm, sẽ þÀIþ€ÉÏSO·, þÀDÁ€ÉÏSO·, þÀ¹þ€ÉÏSO·hoặc þÀsþ€ÉÏSO·vượt qua tất cả các trường hợp thử nghiệm cho -2 byte?
Ông Xcoder

@ Mr.Xcoder: À, vâng. Đẹp! Chúng tôi thậm chí có thể làm þDÁ€ÉÏSO·cho -3 :)
Emigna

1

Võng mạc , 37 byte

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

Hãy thử trực tuyến! Giải trình:

(\d).*
$&$1

Nối một bản sao của chữ số đầu tiên.

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

Khớp bất cứ thứ gì có chữ số đầu tiên là số lẻ.

2**

Chuyển đổi tất cả các trận đấu để unary và nhân đôi chúng. (Không phải chữ số được coi là số không.)

_

Lấy tổng. Nếu không có kết quả khớp, thì điều này tạo ra số 0 theo yêu cầu.

Điều tốt nhất tôi có thể làm trong Retina 0.8.2 là 44 byte:

[^\d]

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

.
$*
.
..
.

Hãy thử trực tuyến! Giải trình:

[^\d]

Xóa các chữ số không.

(.).*
$&$1

Nối một bản sao của chữ số đầu tiên.

(?<![13579]).

Xóa các chữ số không theo một chữ số lẻ.

.
$*

Chuyển đổi sang unary.

.
..

Nhân đôi chúng.

.

Lấy tổng.


Tôi sợ kết quả sẽ không chính xác nếu chữ số cuối cùng không phải là số lẻ
mazzy

1
@mazzy Khi bạn nói chữ số cuối cùng, bạn có nghĩa là trước hoặc sau khi sao chép chữ số đầu tiên vào cuối?
Neil

'đến cuối cùng'. Bước 'Nối một bản sao của chữ số đầu tiên' đang sao chép đến cuối? đồng ý. mát mẻ. Cảm ơn
mazzy


1

JavaScript (ES6), 56 byte

Đưa đầu vào như một mảng các ký tự.

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

Hãy thử trực tuyến!

Đã bình luậ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 byte

-1 byte nhờ vào lò nướng

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

Hãy thử trực tuyến!

Lấy đầu vào chuỗi, tìm các chữ số dưới dạng một mảng các ký tự hoặc trả về mảng trống nếu không tìm thấy, sau đó sử dụng kiểu ép buộc để đảm bảo các giá trị được thêm / bớt một cách chính xác. Tra cứu về phía trước tạo ra chỉ số và sử dụng kiểm tra null cho phép ngắn gọn, và sau đó phần cuối cùng kiểm tra xem số đó là số lẻ hay thậm chí để buộc cộng hoặc trừ (+ và - là -, v.v.)


n-0có thể+n
OVS

Chào mừng đến với PPCG!
Conor O'Brien

1

R , 58 byte

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

Hãy thử trực tuyến!


67 byte nếu bạn không nhớ arrayđầu ra.
Giuseppe

1
hmm thực sự bạn không thể sử dụng sản phẩm dấu chấm vì mảng trống trong xxxđó là 68 byte bằng cách sử dụng thay đổi trong lập chỉ mục ađể tạo y.
Giuseppe

@Giuseppe: đã sửa đổi, cảm ơn :)
digEmAll

@Giuseppe: Tôi hỏi ý kiến ​​của bạn vì bạn là người chơi mã thông minh hơn ... từ các bình luận có vẻ như chúng ta có thể sử dụng một vectơ ký tự, trong trường hợp này có thể có 61 byte: Hãy thử trực tuyến! bạn nghĩ sao ?
digEmAll

sử dụng strtoithay vì as.double, nhưng vâng, điều đó sẽ ổn thôi.
Giuseppe

0

Perl 5 , 48 byte

$;=$;[++$-%@;],$\+=$_%2?$_+$;:$_-$;for@;=/\d/g}{

Hãy thử trực tuyến!

Tôi khá thích cách mã hóa này trông như thế nào, nhưng đó là một vòng lặp khá đơn giản xung quanh tất cả các số trong chuỗi.



0

C sắc nét 180 byte

Đây không phải là chơi golf rất tốt, lol.

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;}}

Ung dung:

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 byte

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

Chạy và gỡ lỗi nó

Giải nén, không được chỉnh sửa và nhận xét, nó trông như thế này.

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

Chạy cái này


0

JavaScript (ES6), 52 byte

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

Mong đợi đầu vào như một mảng các ký tự. Hãy cẩn thận: Do sử dụng dịch chuyển bit, đầu ra có giới hạn trên là2^31-1

Hãy thử trực tuyến!

Giải trình

Về cơ bản nhân đôi tổng các chữ số sau các giá trị lẻ.

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)
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.