Addizione-sottrazione di numeri all'interno della stringa


14

Prendi una stringa come input ed esegui l'aggiunta / sottrazione di tutte le cifre nella stringa e genera la somma di tali operazioni come risultato.

Regole

  • Le cifre nella stringa vengono lette da sinistra a destra
  • Se una cifra (n) è dispari, eseguire l'aggiunta con la cifra successiva (n + n1)
  • Se una cifra (n) è pari, eseguire la sottrazione con la cifra successiva (n - n1)
  • Se hai raggiunto l'ultima cifra nella stringa, esegui l'operazione con la prima cifra nella stringa
  • L'output sarà la somma di tutti i valori risultanti
  • Se nella stringa è presente solo una cifra, eseguire l'operazione con se stessa (n + n o nn)
  • Se non ci sono cifre nella stringa, l'output è 0

Esempio

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

Appunti

  • È accettata la funzione o il programma completo
  • La lunghezza massima di input dipende dal limite della tua lingua per un input di stringa
  • Nessuna restrizione all'immissione dei caratteri, ma solo le cifre a metà larghezza contano ai fini dell'output
  • Vince il minor numero di byte

4
Un altro paio di esempi andrebbero bene
Dylnan il

2
Consiglio di aggiungere un caso di test che termina con una cifra dispari.
Arnauld,

3
TestCase suggerita: "", "0","1"
TSH

1
Possiamo prendere l'input come una matrice di caratteri anziché come stringa? (Julia fa una distinzione tra quei due.)
Sundar - Ripristina Monica il

4
@sundar Il consenso attuale è che una stringa è definita come una sequenza di caratteri. La mia comprensione è che le matrici di caratteri sono quindi consentite per impostazione predefinita anche se la tua lingua ha un tipo di stringa nativo .
Arnauld,

Risposte:


6

Gelatina , 17 15 12 byte

fØDV€ḂT‘ịƲSḤ

Provalo online!

Prova i casi di test.

Il programma mantiene solo le cifre che seguono una cifra dispari quindi calcola il doppio della somma.

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

Soluzione:

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

Provalo online!

Spiegazione:

Rimuovi tutto dalla stringa che non è un numero (durante la conversione), modulo 2, moltiplica per 2, moltiplica con x ruotato di 1 e riassumi.

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

Soluzione ingenua:

Rimuovi tutto dalla stringa che non è un numero (durante la conversione), prendi la finestra scorrevole di 2 elementi, scopri se sono pari o dispari, applica aggiungi / sottrai come appropriato, quindi riassumi.

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

Provalo online!

Appunti:

  • -4 byte grazie a @ngn grazie a un modo più intelligente di filtrare l'input
  • -3 byte usando la finestra scorrevole anziché rimodellare
  • -9 byte porting della soluzione di ngn (approccio non ingenuo)

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

Ho scritto la soluzione in q / kdb + quindi portato su oK ... potrebbe essere ancora in grado di spremere qualche byte in più da questo!
streetster

1
Ho pubblicato una risposta separata in ngn / k, sentiti libero di portare idee da lì. Penso che OK finirà per essere il più corto, dato che il mio parser è spazzatura al momento - non analizza correttamente il compito modificato. A proposito, non ero a conoscenza di ':"finestra scorrevole" - interessante.
ngn,

Sembra che tu abbia familiarità con k. Se hai mai voglia di discutere cose di programmazione vettoriale con persone affini o semplicemente guardare il resto di noi discutere, abbiamo questa chat room . La maggior parte delle battute riguarda APL, ma anche k e J sono in tema.
ngn,



2

Powershell, 80 78 76 byte

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

-2 byte grazie Neil con soluzione Retina

-2 byte grazie AdmBorkBork

Script di prova:

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

&$f 'r5e6o9mm!/3708dvc'

Spiegazione

Prima di tutto: dovrebbe aggiungere 2 * n se la cifra precedente è dispari e 0 se una cifra precedente è pari.

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

Ispirato da @Neil. Le cifre di corrispondenza di Regex solo con "la cifra precedente è dispari". Matchesè una variabile automatica .

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

1
Salva uno scambio di byte |?{$_}per -ne''un altro spostando $d="$args"-split'\D*'-ne''in parentesi come ($d="$args"-split'\D*'-ne'')+$d[0].
AdmBorkBork,

2

MATL , 18 17 byte

t4Y2m)!Ut1YSof)sE

Provalo online!

(-1 byte grazie a Luis Mendo / Giuseppe / entrambi!)

Spiegazione:

     % 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

L'idea di base è che i numeri che seguono numeri pari possono essere ignorati, mentre quelli che seguono numeri dispari vengono raddoppiati e il risultato finale è la somma di quei valori raddoppiati.

Non pensavo che fdopo il controllo di parità osarebbe stato necessario, ma per qualche motivo MATL non vede l'array di 0 e 1 risultante da oun array logico, ma li porta come indici numerici e indici in posizioni 1e end.


Penso che tu possa usare al !Uposto di 48-. La trasposizione non sembra fare alcun male qui. operché l' doubleinput è giusto mod(...,2), quindi l'output è double. Bel NaNtrucco di input! Se questo ha lo scopo di risolvere l'output estraneo in STDOUT, Dennis ha avuto un'idea e probabilmente lo risolverà presto
Luis Mendo,

!Uanziché48-
Giuseppe

@LuisMendo welp, mi hai battuto sul pugno!
Giuseppe,

@Giuseppe :-D MrGreen
Luis Mendo il

Grazie ad entrambi, modificato. @LuisMendo Quando orestituisce quindi un output di array logico o no? (Devo confessare di non aver mai veramente esaminato il sistema di tipi numerici di MATLAB.) E sì, ho pensato che NaNsarebbe diventata una bella sentinella poiché è improbabile che sia un input effettivo ovunque, ma è bello sapere che non sarà necessario per molto più tempo !
Sundar - Ripristina Monica il

2

K (ngn / k) , 33 byte

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

Provalo online!

{ } è una funzione con argomento x

!10 è l'elenco 0 1 ... 9

$ converti in stringhe

,/ concatenare

x^significa xsenza ciò che è sulla destra

x^x^significa xintersecato con ciò che è sulla destra, ovvero mantenere solo le cifre dax

-48+sottrai 48, che è il codice ASCII di"0"

x: assegnato a x

2! mod 2

2* moltiplicato per 2

1_x,*xè una goccia di: xseguita dalla prima di x; cioè xruotato a sinistra di un passo

+/ somma


2

Japt (v2.0a0), 25 19 byte

-6 byte grazie a Shaggy .

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

Provalo qui .

Funziona senza cifre questa volta! L'input è un elenco di caratteri.


19 byte , incluso il passaggio a Japt v2. Non contento dell'array nella xfunzione, però. Ping me in chat se avete domande.
Shaggy,

Aspetta, ho appena notato che questo non funzionerà affatto se l'input non contiene cifre.
Shaggy,

Inoltre, dov'è la fonte per v2.0a0, @Shaggy? Non riesco a trovarlo nel repository.
LegionMammal978,

Questa è v1 e questa è v2.
Shaggy,

Nel caso in cui te lo fossi perso in chat, ho ridotto questo valore a 12 byte .
Shaggy,

2

05AB1E , 12 9 byte

Salva 1 byte sul metodo ingenuo utilizzando il trucco di parità di dylnan
Salvato 3 byte grazie a Mr. Xcoder

þDÁ€ÉÏSO·

Provalo online!

Spiegazione

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

Hmm, sarebbe þÀIþ€ÉÏSO·, þÀDÁ€ÉÏSO·, þÀ¹þ€ÉÏSO·o þÀsþ€ÉÏSO·superare tutti i test per l'-2 byte?
Mr. Xcoder,

@ Mr.Xcoder: Ah, sì. Bello! Possiamo anche fare þDÁ€ÉÏSO·per -3 :)
Emigna il

1

Retina , 37 byte

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

Provalo online! Spiegazione:

(\d).*
$&$1

Aggiungi un duplicato della prima cifra.

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

Abbina qualsiasi cosa la cui prima cifra precedente è dispari.

2**

Converti tutte le partite in unario e raddoppiale. (Le cifre non numeriche vengono considerate pari a zero.)

_

Prendi la somma. Se non ci sono state corrispondenze, questo produce zero come richiesto.

Il meglio che potevo fare in Retina 0.8.2 era di 44 byte:

[^\d]

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

.
$*
.
..
.

Provalo online! Spiegazione:

[^\d]

Elimina non cifre.

(.).*
$&$1

Aggiungi una copia della prima cifra.

(?<![13579]).

Elimina le cifre che non seguono una cifra dispari.

.
$*

Converti in unario.

.
..

Raddoppiali.

.

Prendi la somma.


Temo che il risultato non sarà corretto se l'ultima cifra non è dispari
mazzy

1
@mazzy Quando dici l'ultima cifra, intendi prima o dopo aver copiato la prima cifra alla fine?
Neil,

'all'estremità'. il passaggio "Aggiungi un duplicato della prima cifra" sta copiando fino alla fine? ok. freddo. Grazie
mazzy il


1

JavaScript (ES6), 56 byte

Accetta input come una matrice di caratteri.

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

Provalo online!

Commentate

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 grazie a ovs

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

Provalo online!

Accetta l'input della stringa, trova le cifre come una matrice di caratteri o restituisce una matrice vuota se non ne viene trovata nessuna, quindi utilizza la coercizione del tipo per garantire che i valori vengano aggiunti / sottratti correttamente. La ricerca diretta preincrementa l'indice e utilizza un controllo nullo per brevità, quindi la parte finale verifica se il numero è dispari o anche per forzare l'addizione o la sottrazione (+ e - è -, ecc.)


n-0può essere+n
ovs

Benvenuti in 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)

Provalo online!


67 byte se non ti dispiace l' arrayoutput.
Giuseppe,

1
hmm in realtà non è possibile utilizzare il prodotto punto a causa dell'array vuoto in xxxmodo che sia 68 byte utilizzando la modifica dell'indicizzazione aper generare y.
Giuseppe,

@Giuseppe: modificato, grazie :)
digEmAll

@Giuseppe: ti chiedo la tua opinione dato che sei un giocatore di codice più saggio ... dai commenti sembra che possiamo usare un vettore di caratteri, in questo caso sono possibili 61 byte: provalo online! cosa pensi ?
digEmAll

usare strtoiinvece di as.double, ma sì, dovrebbe andare bene.
Giuseppe,

0

Perl 5 , 48 byte

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

Provalo online!

Mi piace quanto sia criptico questo aspetto, ma è un ciclo piuttosto semplice attorno a tutti i numeri della stringa.



0

C Sharp 180 byte

Questo non è un ottimo golf, 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;
}

0

Stax , 14 byte

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

Esegui ed esegui il debug

Disimballato, non golfato e commentato, sembra così.

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

Esegui questo


0

JavaScript (ES6), 52 byte

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

Si aspetta input come una matrice di caratteri. Avvertenza: a causa dell'utilizzo del bit-shifting, l'uscita ha un limite superiore di2^31-1

Provalo online!

Spiegazione

Raddoppia essenzialmente la somma delle cifre che seguono valori dispari.

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)
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.