การบวกลบเลขภายในสตริง


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

2
ฉันขอแนะนำให้เพิ่มกรณีทดสอบที่ลงท้ายด้วยเลขคี่
Arnauld

3
testcase แนะนำ: "", "0","1"
TSH

1
เราสามารถรับอินพุตเป็นอาร์เรย์ของอักขระแทนสตริงได้หรือไม่? (จูเลียสร้างความแตกต่างระหว่างสองคนนี้)
sundar - Reinstate Monica

4
@sundar ฉันทามติปัจจุบันคือสตริงถูกกำหนดเป็นลำดับของอักขระ ความเข้าใจของฉันคือการอนุญาตให้ใช้อาร์เรย์ของอักขระตามค่าเริ่มต้นแม้ว่าภาษาของคุณจะมีชนิดสตริงดั้งเดิม
Arnauld

คำตอบ:


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}

ลองออนไลน์!

หมายเหตุ:

  • -4 ไบต์ขอบคุณ @ngn เนื่องจากวิธีการกรองอินพุตที่ชาญฉลาด
  • -3 ไบต์โดยใช้หน้าต่างบานเลื่อนแทนที่จะปรับรูปร่าง
  • -9 bytes porting solution ของ ngn (วิธีการที่ไม่ไร้เดียงสา)

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

ฉันเขียนวิธีแก้ปัญหาใน q / kdb + จากนั้นส่งไปยัง oK ... อาจบีบขนาดออกอีกสองสามไบต์!
streetster

1
ฉันโพสต์คำตอบแยกต่างหากใน ngn / k รู้สึกฟรีเพื่อนำแนวคิดมาจากที่นั่น ฉันคิดว่า oK จะจบลงด้วยการที่สั้นที่สุดเนื่องจาก parser ของฉันเป็นขยะในขณะนี้ - มันไม่ได้แยกวิเคราะห์แก้ไขมอบหมายอย่างถูกต้อง โดยวิธีการที่ฉันไม่ทราบ':ว่าเป็น "หน้าต่างบานเลื่อน" - น่าสนใจ
ngn

คุณดูเหมือนจะคุ้นเคยดีกับเค หากคุณรู้สึกอยากคุยเรื่องการเขียนโปรแกรมเวกเตอร์กับคนที่มีใจเดียวกันหรือเพียงแค่ดูพวกเราที่เหลือก็เถียงกัน - เรามีห้องแชทนี้ ผู้เล่นส่วนใหญ่เกี่ยวกับ APL แต่ k และ J ก็อยู่ในหัวข้อเดียวกันด้วย
ngn



2

Powershell, 80 78 76 ไบต์

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

-2 bytes ขอบคุณ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 Regex จับคู่ตัวเลขด้วย 'ตัวเลขก่อนหน้านี้เป็นเลขคี่' เท่านั้น 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''เข้า parens ($d="$args"-split'\D*'-ne'')+$d[0]เช่น
AdmBorkBork

2

MATL , 18 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 ไม่เห็นอาร์เรย์ของ 0 และ 1 ที่เกิดจากการที่oเป็น array ตรรกะแทนที่จะใช้เวลาพวกเขาเป็นดัชนีตัวเลขและดัชนีในตำแหน่งและ1end


ฉันคิดว่าคุณสามารถใช้แทน!U 48-การย้ายดูเหมือนจะไม่ทำอันตรายใด ๆ ที่นี่ oสำหรับdoubleการป้อนข้อมูลเป็นเพียงเพื่อให้ออกเป็นmod(...,2) เคล็ดลับการป้อนข้อมูลที่doubleดีNaN! หากที่หมายถึงการแก้ปัญหาการส่งออกภายนอกใน STDOUT เดนนิสมีความคิดและอาจจะแก้ไขว่าเร็ว ๆ นี้
หลุยส์ Mendo

!Uแทน48-
Giuseppe

@ LuisMendo welp คุณชนะฉันไปชก!
Giuseppe

@Giuseppe :-D :-D
Luis Mendo

ขอบคุณทั้งคู่แก้ไขแล้ว @LuisMendo เมื่อใดที่oให้เอาต์พุตอาร์เรย์แบบลอจิคัลแล้ว - หรือไม่ (ฉันต้องยอมรับว่าฉันไม่เคยมองเข้าไปในระบบตัวเลขของ MATLAB) และใช่ฉันคิดว่าNaNน่าจะเป็นยามรักษาการณ์ที่ดีเพราะมันไม่น่าจะเป็นอินพุตจริงได้ทุกที่ แต่ดีที่รู้ว่าไม่จำเป็นอีกต่อไป !
sundar - Reinstate Monica

2

K (ngn / k) , 33 ไบต์

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

ลองออนไลน์!

{ } เป็นฟังก์ชั่นที่มีข้อโต้แย้ง x

!10 เป็นรายการ 0 1 ... 9

$ แปลงเป็นสตริง

,/ concatenate

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 ไบต์ขอบคุณที่มีขนดก

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

ลองมันนี่

มันใช้งานได้โดยไม่มีตัวเลขในครั้งนี้! อินพุตคือรายการของอักขระ


19 ไบต์รวมถึงการสลับเป็น Japt v2 ไม่พอใจกับอาเรย์ในxฟังก์ชั่น Ping ฉันในการแชทหากคุณมีคำถามใด ๆ
Shaggy

รอสักครู่เพิ่งสังเกตเห็นว่าสิ่งนี้จะไม่ทำงานเลยหากอินพุตไม่มีตัวเลขใด ๆ
Shaggy

นอกจากนี้แหล่งที่มาของ v2.0a0, @Shaggy อยู่ที่ไหน ฉันหามันไม่ได้ใน repo
LegionMammal978

นี่คือ v1 และนี่คือ v2
Shaggy

ในกรณีที่คุณพลาดในการแชทฉันได้รับมันถึง12 ไบต์สำหรับคุณ
Shaggy

2

05AB1E , 12 9 ไบต์

บันทึก 1 ไบต์บนวิธีการที่ไร้เดียงสาโดยใช้เคล็ดลับพาริตี้ของ dylnan
บันทึก 3 ไบต์ขอบคุณMr. Xcoder

þ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 ไบต์?
Mr. Xcoder

@ Mr.Xcoder: อ่าใช่ ดี! เราสามารถทำได้þDÁ€ÉÏSO·เพื่อ -3: :)
Emigna

1

เรติน่า 37 ไบต์

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

ลองออนไลน์! คำอธิบาย:

(\d).*
$&$1

ต่อท้ายสำเนาหลักแรก

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

จับคู่สิ่งที่มีตัวเลขก่อนหน้าแรกเป็นเลขคี่

2**

แปลงการแข่งขันทั้งหมดเป็น unary และเพิ่มเป็นสองเท่า (ไม่ใช่ตัวเลขจะถือว่าเป็นศูนย์)

_

รับผลรวม หากไม่มีการแข่งขันสิ่งนี้จะสร้างศูนย์ตามต้องการ

สิ่งที่ดีที่สุดที่ฉันสามารถทำได้ใน Retina 0.8.2 คือ 44 ไบต์:

[^\d]

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

.
$*
.
..
.

ลองออนไลน์! คำอธิบาย:

[^\d]

ลบไม่ใช่ตัวเลข

(.).*
$&$1

ต่อท้ายสำเนาหลักแรก

(?<![13579]).

ลบตัวเลขที่ไม่เป็นไปตามเลขคี่

.
$*

แปลงเป็นเอก

.
..

เพิ่มเป็นสองเท่า

.

รับผลรวม


ฉันเกรงว่าผลลัพธ์จะไม่ถูกต้องหากตัวเลขหลักสุดท้ายไม่แปลก
mazzy

1
@mazzy เมื่อคุณพูดตัวเลขสุดท้ายคุณหมายถึงก่อนหรือหลังการคัดลอกตัวเลขแรกไปยังจุดสิ้นสุดหรือไม่
Neil

'ถึงจุดจบ' ขั้นตอน 'ต่อท้ายสำเนาหลักแรก' กำลังคัดลอกไปยังจุดสิ้นสุดหรือไม่ ตกลง. เย็น. ขอบคุณ
mazzy


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)

ลองออนไลน์!

รับค่าสตริงค้นหาตัวเลขเป็นอาร์เรย์ของอักขระหรือส่งคืนอาร์เรย์ว่างถ้าไม่พบจากนั้นใช้การข่มขู่ประเภทเพื่อให้แน่ใจว่ามีการเพิ่ม / ลบค่าอย่างถูกต้อง การค้นหาไปข้างหน้าจะทำดัชนีไว้ล่วงหน้าและใช้การตรวจสอบความว่างเปล่าก่อนจากนั้นส่วนสุดท้ายจะตรวจสอบว่าจำนวนคี่หรือแม้กระทั่งจากนั้นบังคับให้เติมหรือลบ (+ และ - คือ - ฯลฯ )


n-0สามารถ+n
ovs

ยินดีต้อนรับสู่ PPCG!
Conor O'Brien

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จึงเป็น 68 ไบต์โดยใช้การเปลี่ยนแปลงในการจัดทำดัชนีในการสร้างa y
จูเซปเป้

@Giuseppe: แก้ไขแล้วขอบคุณ :)
digEmAll

@Giuseppe: ฉันถามความคิดเห็นของคุณเพราะคุณเป็นนักเล่นรหัสฉลาด ... จากความคิดเห็นดูเหมือนว่าเราสามารถใช้เวกเตอร์ของตัวละครในกรณีนี้ 61 ไบต์เป็นไปได้: ลองออนไลน์! คุณคิดอย่างไร ?
digEmAll

ใช้strtoiแทนas.doubleแต่ใช่ว่าควรจะดี
Giuseppe



0

ชาร์ป 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;}}

Ungolfed:

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♥

เรียกใช้และแก้ไขข้อบกพร่อง

คลายกล่อง ungolfed และแสดงความคิดเห็นมันมีลักษณะเช่นนี้

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

คาดว่าอินพุตเป็นอาร์เรย์ของอักขระ Caveat: เนื่องจากการใช้การเลื่อนบิตเอาต์พุตมีขอบเขตด้านบน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)
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.