Addition-Subtraktion von Zahlen innerhalb eines Strings

14

Nehmen Sie eine Zeichenfolge als Eingabe und führen Sie eine Addition / Subtraktion aller Stellen in der Zeichenfolge durch und geben Sie die Summe dieser Operationen als Ergebnis aus.

Regeln

  • Die Ziffern in der Zeichenfolge werden von links nach rechts gelesen
  • Wenn eine Ziffer (n) ungerade ist, Addition mit der nächsten Ziffer (n + n1) durchführen
  • Wenn eine Ziffer (n) gerade ist, subtrahieren Sie mit der nächsten Ziffer (n - n1)
  • Wenn Sie die letzte Ziffer in der Zeichenfolge erreicht haben, führen Sie den Vorgang mit der ersten Ziffer in der Zeichenfolge aus
  • Die Ausgabe ist die Summe aller resultierenden Werte
  • Wenn die Zeichenfolge nur eine Ziffer enthält, führen Sie die Operation mit sich selbst aus (n + n oder nn).
  • Wenn die Zeichenfolge keine Ziffern enthält, ist die Ausgabe 0

Beispiel

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

Anmerkungen

  • Es wird entweder die Funktion oder das vollständige Programm akzeptiert
  • Die maximale Länge der Eingabe hängt von der Beschränkung Ihrer Sprache für eine Zeichenfolge ab
  • Keine Einschränkungen bei der Zeicheneingabe, sondern nur Ziffern mit halber Breite werden für die Ausgabe berücksichtigt
  • Wenigste Bytes gewinnt
Noir Antares
quelle
4
Ein paar weitere Beispiele wären auch gut
dylnan
2
Ich würde empfehlen, einen Testfall hinzuzufügen, der mit einer ungeraden Ziffer endet.
Arnauld
3
Empfohlene Testfall: "", "0","1"
tsh
1
Können wir Eingaben als Array von Zeichen anstelle einer Zeichenfolge annehmen? (Julia macht einen Unterschied zwischen diesen beiden.)
Sundar - Wiedereinsetzung von Monica
4
@sundar Der aktuelle Konsens ist, dass eine Zeichenfolge als Folge von Zeichen definiert ist. Meines Erachtens sind daher Arrays von Zeichen standardmäßig zulässig, auch wenn Ihre Sprache einen systemeigenen Zeichenfolgentyp hat .
Arnauld

Antworten:

6

Jelly , 17 15 12 Bytes

fØDV€ḂT‘ịƲSḤ

Probieren Sie es online!

Probieren Sie Testfälle aus.

Das Programm behält nur die Ziffern bei, die auf eine ungerade Ziffer folgen, und berechnet dann die doppelte Summe.

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.
dylnan
quelle
3

K (oK) , 47 43 40 31 Bytes

Lösung:

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

Probieren Sie es online!

Erläuterung:

Entfernen Sie alles aus dem String, das keine Zahl ist (und konvertieren Sie gleichzeitig), modulo 2, multiplizieren Sie mit 2, multiplizieren Sie mit x, das um 1 gedreht wurde, und addieren Sie.

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

Naive Lösung:

Entfernen Sie alles aus einer Zeichenfolge, die keine Zahl ist (und konvertieren Sie gleichzeitig), nehmen Sie ein Schiebefenster mit zwei Elementen, ermitteln Sie, ob sie ungerade oder gerade sind, und wenden Sie gegebenenfalls Addieren / Subtrahieren an.

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

Probieren Sie es online!

Anmerkungen:

  • -4 Bytes dank @ngn dank einer intelligenteren Art, die Eingabe zu filtern
  • -3 Bytes durch Verwenden von Schiebefenstern anstelle von Umformen
  • -9 Bytes für die Portierung der ngn-Lösung (nicht naiver Ansatz)
Streetster
quelle
1
x:48!x@&x in,/$!10->x^:(x-:48)^!10
ngn
Ich habe die Lösung in q / kdb + geschrieben und dann nach oK portiert ... könnte noch ein paar Bytes mehr herausholen!
Streetster
1
Ich habe eine separate Antwort in ngn / k gepostet. Sie können gerne Ideen von dort einbringen. Ich denke, OK wird am Ende die kürzeste sein, da mein Parser im Moment Müll ist - er analysiert die geänderte Zuweisung nicht richtig. Übrigens war ich mir ':als "Schiebefenster" nicht bewusst - interessant.
ngn
Sie scheinen mit k gut vertraut zu sein. Wenn Sie jemals Lust haben, mit Gleichgesinnten über Vektorprogrammierung zu diskutieren oder nur zuzusehen, wie wir uns streiten - wir haben diesen Chatroom . Der Großteil der Scherze dreht sich um APL, aber k und J sind auch ein Thema.
ngn
2

Perl 6 , 41 Bytes

{2*sum rotate($!=.comb(/\d/))Z*(@$! X%2)}

Probieren Sie es online!

Verwendet die gleiche Logik wie Dylnans Gelee-Antwort . Dies summiert nur Ziffern, die auf eine ungerade Zahl folgen und multipliziert dann mit 2.

Scherzen
quelle
2

Powershell, 80 78 76 Bytes

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

-2 Bytes danke Neil mit Retina-Lösung

-2 Bytes danke AdmBorkBork

Testskript:

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

&$f 'r5e6o9mm!/3708dvc'

Erläuterung

Zuallererst: Es wird 2 * n addiert, wenn die vorherige Ziffer ungerade ist, und 0, wenn die vorherige Ziffer gerade ist.

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

Extra 99 Bytes

Inspiriert von @Neil. Regex-Übereinstimmungsziffern mit der vorherigen Ziffer sind ungerade. Matchesist eine automatische Variable .

param($d)$d+($d-match'\d')+$Matches[0]|sls '(?<=[13579]\D*)\d'-a|%{$_.Matches.Value|%{$s+=2*$_}};$s
mazzy
quelle
1
Speichern Sie ein Byte, das |?{$_}für -ne''und ein anderes $d="$args"-split'\D*'-ne''ausgetauscht wird, indem Sie in Parens wie wechseln ($d="$args"-split'\D*'-ne'')+$d[0].
AdmBorkBork
2

MATL , 18 17 Bytes

t4Y2m)!Ut1YSof)sE

Probieren Sie es online!

(-1 Byte dank Luis Mendo / Giuseppe / beiden!)

Erläuterung:

     % 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

Die Grundidee ist, dass Zahlen, die auf gerade Zahlen folgen, ignoriert werden können, während Zahlen, die auf ungerade Zahlen folgen, verdoppelt werden - und das Endergebnis ist die Summe dieser verdoppelten Werte.

Ich dachte nicht, dass eine fParitätsprüfung onotwendig wäre, aber aus irgendeinem Grund sieht MATL das Array von 0 und 1, das sich aus dem ergibt, nicht oals logisches Array, sondern nimmt sie stattdessen als numerische Indizes und Indizes in Positionen 1und end.

Sundar - Setzen Sie Monica wieder ein
quelle
Ich denke, Sie können !Uanstelle von verwenden 48-. Die Transponierung scheint hier nichts auszusetzen. ofür die doubleEingabe ist nur mod(...,2), so ist die Ausgabe double. Netter NaNEingabetrick! Dennis hatte eine Idee und wird diese wahrscheinlich bald beheben
Luis Mendo
!Ustatt48-
Giuseppe
@ LuisMendo welp, du hast mich geschlagen!
Giuseppe
@ Giuseppe :-D :-D
Luis Mendo
Vielen Dank an beide, bearbeitet. @LuisMendo Wann wird dann oein logisches Array ausgegeben - oder nicht? (Ich muss gestehen, dass ich mich noch nie mit dem numerischen Typensystem von MATLAB befasst habe.) Und ja, ich dachte, es NaNwäre ein netter Sentinel, da es wahrscheinlich nirgendwo eine tatsächliche Eingabe gibt, aber gut zu wissen, dass es nicht mehr lange benötigt wird !
Sundar - Wiedereinsetzung von Monica
2

K (ngn / k) , 33 Bytes

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

Probieren Sie es online!

{ } ist eine Funktion mit Argument x

!10 ist die Liste 0 1 ... 9

$ in Strings konvertieren

,/ verketten

x^bedeutet xohne was auf der rechten Seite

x^x^bedeutet xgekreuzt mit dem, was auf der rechten Seite ist, dh nur die Ziffern behaltenx

-48+subtrahieren 48, das ist der ASCII-Code von"0"

x: zuweisen x

2! mod 2

2* multipliziert mit 2

1_x,*xist ein Tropfen von: xgefolgt von dem ersten von x; dh xum einen Schritt nach links gedreht

+/ Summe

ngn
quelle
2

Japt (v2.0a0), 25 bis 19 Byte

-6 Bytes dank Shaggy .

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

Probieren Sie es hier aus .

Diesmal funktioniert es ohne Ziffern! Die Eingabe ist eine Liste von Zeichen.

LegionMammal978
quelle
19 Bytes , einschließlich der Umstellung auf Japt v2. Nicht zufrieden mit dem Array in der xFunktion. Pingen Sie mich im Chat an, wenn Sie Fragen haben.
Shaggy
Warten Sie, nur bemerkt, dass dies überhaupt nicht funktioniert, wenn die Eingabe keine Ziffern enthält.
Shaggy
Wo ist die Quelle für v2.0a0, @Shaggy? Ich kann es nicht im Repo finden.
LegionMammal978
Das ist v1 und das ist v2.
Shaggy
Falls Sie es im Chat verpasst haben, habe ich es für Sie auf 12 Bytes reduziert.
Shaggy
2

05AB1E , 12 9 Bytes

Spart 1 Byte gegenüber der naiven Methode durch Verwendung des Paritätstricks von Dylnan. Sparte
3 Byte dank Mr. Xcoder

þDÁ€ÉÏSO·

Probieren Sie es online!

Erläuterung

þ              # push only digits of input
 D             # duplicate
  Á            # rotate right
   ۃ          # get the parity of each
     Ï         # keep only true items
      SO       # calculate digit-sum
        ·      # double
Emigna
quelle
Hmm, würde þÀIþ€ÉÏSO·, þÀDÁ€ÉÏSO·, þÀ¹þ€ÉÏSO·oder þÀsþ€ÉÏSO·passieren alle Testfälle für -2 Bytes?
Mr. Xcoder
@ Mr.Xcoder: Ah ja. Nett! Wir können sogar þDÁ€ÉÏSO·für -3 tun :)
Emigna
1

Retina , 37 Bytes

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

Probieren Sie es online! Erläuterung:

(\d).*
$&$1

Fügen Sie ein Duplikat der ersten Ziffer hinzu.

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

Finde alles, dessen erste vorherige Ziffer ungerade ist.

2**

Wandle alle Übereinstimmungen in unäre um und verdopple sie. (Nicht-Ziffern werden als Null behandelt.)

_

Nimm die Summe. Wenn es keine Übereinstimmungen gab, ergibt dies nach Bedarf Null.

Das Beste, was ich in Retina 0.8.2 machen konnte, waren 44 Bytes:

[^\d]

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

.
$*
.
..
.

Probieren Sie es online! Erläuterung:

[^\d]

Nicht-Ziffern löschen.

(.).*
$&$1

Fügen Sie eine Kopie der ersten Ziffer an.

(?<![13579]).

Löschen Sie Ziffern, die keiner ungeraden Ziffer folgen.

.
$*

In Unary konvertieren.

.
..

Verdopple sie.

.

Nimm die Summe.

Neil
quelle
Ich fürchte, das Ergebnis wird falsch sein, wenn die letzte Ziffer nicht ungerade ist
mazzy
1
@mazzy Wenn Sie die letzte Ziffer sagen, meinen Sie das vor oder nach dem Kopieren der ersten Ziffer bis zum Ende?
Neil
'bis zum Ende'. Der Schritt 'Ein Duplikat der ersten Ziffer anhängen' wird bis zum Ende kopiert. in Ordnung. cool. Danke
mazzy
1

JavaScript (ES6), 56 Byte

Nimmt die Eingabe als Array von Zeichen.

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

Probieren Sie es online!

Kommentiert

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
Arnauld
quelle
1

JavaScript (Node.js) , 85 84 83 82 Byte

-1 Bytes dank ovs

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

Probieren Sie es online!

Übernimmt die Zeichenfolgeeingabe, findet die Ziffern als ein Array von Zeichen oder gibt ein leeres Array zurück, wenn keines gefunden wird, und verwendet dann Typenzwang, um sicherzustellen, dass die Werte korrekt addiert / subtrahiert werden. Die Vorwärtssuche erhöht den Index vor und verwendet eine Nullprüfung, um die Kürze zu verbessern. Anschließend überprüft der letzte Teil, ob die Zahl ungerade oder gerade ist, um dann die Addition oder Subtraktion zu erzwingen (+ und - sind - usw.).

Bluefinger
quelle
n-0kann sein+n
ovs
Willkommen bei PPCG!
Conor O'Brien
1

R , 58 Bytes

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

Probieren Sie es online!

  • mit Dylnans Paritätstrick
  • -8 Bytes, die Zeichenvektoren anstelle von Zeichenfolgen akzeptieren
  • -3 Byte danke an @Giuseppe
digEmAll
quelle
67 Bytes, wenn Ihnen die arrayAusgabe nichts ausmacht .
Giuseppe
1
Hmm, tatsächlich können Sie das Skalarprodukt wegen des leeren Arrays in nicht verwenden, xxxsodass es 68 Bytes umfasst, wenn Sie die Änderung in der Indexierung verwenden a, um zu generieren y.
Giuseppe
@ Giuseppe: geändert, danke :)
digEmAll
@ Giuseppe: Ich frage Sie nach Ihrer Meinung, da Sie ein weiserer Code-Golfer sind. Aus Kommentaren geht hervor, dass wir einen Vektor von Zeichen verwenden können. In diesem Fall sind 61 Bytes möglich: Probieren Sie es online aus! was denkst du ?
digEmAll
Verwenden Sie strtoistatt as.double, aber ja, das sollte in Ordnung sein.
Giuseppe
0

Perl 5 , 48 Bytes

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

Probieren Sie es online!

Ich mag, wie kryptisch das aussieht, aber es ist eine ziemlich unkomplizierte Schleife um alle Zahlen in der Zeichenfolge.

Dom Hastings
quelle
0

Julia 0,6 , 77 69 Bytes

s->(s=s.-'0';s=s[0.<=s.<=9];endof(s)>0?sum(2(s%2).*[s[2:end];s[]]):0)

Probieren Sie es online!

Sundar - Setzen Sie Monica wieder ein
quelle
0

C Scharfe 180 Bytes

Das ist nicht sehr gut Golfen, 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;}}

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;
}
IEatBagels
quelle
0

Stax , 14 Bytes

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

Führen Sie es aus und debuggen Sie es

Ausgepackt, ungolfed und kommentiert sieht es so aus.

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

Führen Sie dieses aus

rekursiv
quelle
0

JavaScript (ES6), 52 Byte

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

Erwartet die Eingabe als Array von Zeichen. Vorsichtsmaßnahme: Aufgrund der Bitverschiebung hat die Ausgabe eine Obergrenze von2^31-1

Probieren Sie es online!

Erläuterung

Verdoppelt im Wesentlichen die Summe der Ziffern nach ungeraden Werten.

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)
Redundanz
quelle