Somme d'entiers dans une chaîne, séparés par des nombres non numériques tels que «a» et «Y»

14

Créez un programme qui additionne tous les entiers trouvés dans une chaîne qui est définie comme une variable dans le programme (ainsi, le programme n'a à gérer aucune entrée). Les nombres entiers sont séparés par des nombres non numériques (tout sauf 0, 1, 2, 3 ... 9).

Exemples:

  • e7rde f ,fe 43 jfj 54f4sD = 7 + 43 + 54 + 4 = 108
  • 5 = 5
  • 64 545,5445-32JIFk0ddk = 64 + 545 + 5445 + 32 + 0 = 6086
  • 0ab0 = 0 + 0 = 0

Notes supplémentaires:

  • Le support Unicode n'est pas nécessaire, mais autorisé
  • -n(où nest un entier) n'est pas compté comme un négatif n, mais comme un trait d'union suivi de n.

La réponse peut être imprimée à l'écran (mais pas obligatoire).

Réponse la plus courte (en caractères) gagne.

Anto
la source
Faut-il aussi imprimer le résultat? (Vous ne mentionnez pas d'E / S).
Dogbert
@Dogbert - Je n'y ai pas pensé. Désolé, oui. Je mettrai à jour le message.
Anto
Changé car certaines personnes avaient déjà des réponses et ne voulaient pas les "blesser". Je suppose que je devrais dormir maintenant, donc je penserai un peu plus clairement;)
Anto
2
Anto: Une tâche où une solution n'a pas d'effets secondaires observables n'est cependant pas très agréable.
Joey
Un cas de test intéressant que je viens de rencontrer serait 5a-3(mon code sauterait -s'il suit immédiatement un numéro, mais pas s'il y avait un non-numéro avant).
Martin Ender

Réponses:

10

Perl, 15

Entrée $_, somme $c:

s/\d+/$c+=$&/ge
JB
la source
14

Ruby 1.9, 21 caractères

eval a.scan(/\d+/)*?+

Pour imprimer la solution sur stdout, 2 caractères supplémentaires sont requis:

p eval a.scan(/\d+/)*?+

Et pour lire à partir de stdin au lieu d'utiliser une variable prédéfinie, 3 autres caractères doivent être utilisés:

p eval gets.scan(/\d+/)*?+

Pour Ruby 1.8, remplacez ?+par "+"pour obtenir une solution de travail en 22 caractères.

Ventero
la source
L'entrée est censée provenir d'une variable, pas de stdin. Est également scanplus court que split. Votre solution devient donc eval s.scan(/\d+/)*?+- 21 caractères.
sepp2k
@ sepp2k: Oui, je n'ai pas lu correctement la description. Je suis juste habitué aux autres tâches de golf, où vous devez généralement lire depuis stdin et imprimer vers stdout. Bon point avec scan, merci!
Ventero
+1, grande utilisation de evalet* '+'
Dogbert
6

Python (60)

import re;print sum(map(int,filter(len,re.split(r'\D',s))))
Hoa Long Tam
la source
5

Rubis - 36 34 caractères

s.scan(/\d+/).map(&:to_i).reduce:+

36 caractères si vous voulez que le résultat soit imprimé.

p s.scan(/\d+/).map(&:to_i).reduce:+

Suppose que l'entrée est présente sous forme de chaîne dans s.

Dogbert
la source
4

JavaScript (ES6), 30

c=0,s.replace(/\d+/g,d=>c+=+d)

Version annotée:

// Store the sum.
c=0,
// Process every number found in the `s`.
s.replace(/\d+/g,
  // Convert the number into an integer.
  // Add it to the sum.
  d => c += +d
)
Florent
la source
3

Windows PowerShell, 23 25 29 31

Avec sortie.

$x-replace'\D','+0'|iex

En fait, sans que la sortie soit exactement la même, il suffit de la diriger ailleurs où elle est nécessaire.

Joey
la source
2

J - 40 38 caractères

Version paresseuse. Nécessite la bibliothèque de chaînes.

+/".(,' ',.~a.-.'0123456789')charsub y
MPelletier
la source
Prend en charge Unicode. Prend en charge l'encodage, pensez-y!
MPelletier
2

Java

hors concours;)

public static long sum(String s) {
    long sum = 0;
    String p = "";
    char[] ch = s.toCharArray();
    for (int i = 0; i < ch.length; i++) {
        boolean c = false;
        if (Character.isDigit(ch[i])) {
            if (i + 1 < ch.length) {
                if (Character.isDigit(ch[i + 1])) {
                    p += ch[i];
                    c = true;
                }
            }
            if (!c) {
                p += ch[i];
                sum += Integer.valueOf(p);
                p = "";
                c = false;
            }
        }
    }
    return sum;
}
Włodar
la source
2

JavaScript [30 octets]

eval(s.match(/\d+/g).join('+'))
Vision
la source
2

Labyrinthe , 29 21 octets

(Avertissement: Labyrinth est plus récent que ce défi.)

En outre, Labyrinth n'a pas de variables, donc je suis allé avec un programme d'entrée / sortie normal.

)_"+`
( "?"
";;,;;(!@

C'était assez simple à cause de la façon dont les commandes d'entrée de Labyrinth fonctionnent. ?essaie de lire un entier signé de STDIN et s'arrête au premier non-chiffre. S'il ne peut pas lire un entier (parce que le caractère suivant n'est -pas suivi d'un chiffre, ou de tout autre non-chiffre, ou nous avons atteint EOF), il reviendra à la 0place. ,d'autre part lit tout octet suivant et pousse la valeur d'octet. Si celui-ci est appelé à l'EOF, il reviendra-1 place.

Voici donc un pseudocode pour la solution:

running total = 0
while(true)
  while(true)
    try reading a non-zero integer N with ?
    if(N < 0)
      running total -= N
    else if(N > 0)
      running total += N
    else
      break
  // We've either read a zero or hit a something that isn't a number
  try reading a character with ,
  if(that returned -1)
    break
print running total

Gérer correctement les nombres négatifs complique beaucoup cette solution. Si ce n'était pas pour ceux-là, j'aurais cette solution à 8 octets:

?+
;,;!@
Martin Ender
la source
1

PHP - 37

Sans impression;

<?array_sum(@split("[^0-9]+",`cat`));

Avec impression (38):

<?=array_sum(@split("[^0-9]+",`cat`));
Arnaud Le Blanc
la source
1

Perl, 16 caractères

s/\d+/$r+=$&/ge;

Prend l'entrée $_, la sortie continue $r. Le dernier point-virgule est superflu, mais il sera probablement nécessaire lorsque le programme fera plus de choses. Ajouter say$rpour la sortie.

ninjalj
la source
Oups, je n'ai pas vu exactement la même réponse quand j'ai posté. Bien que j'aie compté un caractère de plus même sans le point-virgule.
JB
@JB: Je ne peux pas compter! : P. En fait, j'ai fait l'erreur de faire écho à une chaîne entre guillemets doubleswc -c .
ninjalj
1

J - 23 caractères

Pas un gagnant, mais nous voyons une primitive assez rare en action.

+/".(,_=_"."0 y)}y,:' '

Expliqué:

  • _"."0 y - Pour chaque caractère de la chaîne d'entrée y , essayez de le lire sous forme de nombre. Si vous ne le pouvez pas, utilisez _plutôt la valeur par défaut (infini).

  • ,_= - Vérifiez chaque résultat pour _ , puis exécutez le tableau final de 0 et de 1 dans un vecteur. ( "."0ajoute toujours une dimension de trop au résultat, nous corrigeons donc cela ici.)

  • y,:' ' - Ajoutez une rangée d'espaces sous la chaîne d'entrée.

  • }- Utilisé tel qu'il est ici, }est appelé Item Amend , et il utilise la liste des 0 et des 1 à gauche comme indices pour sélectionner la ligne à partir de laquelle l'argument de droite est utilisé. Donc, ce qui se passe, c'est que pour chaque colonne du côté droit, nous prenons le caractère d'origine s'il peut être lu comme un nombre, sinon nous prenons l'espace en dessous. Par conséquent, nous couvrons tous les caractères non numériques avec des espaces.

  • +/". - Convertissez maintenant cette chaîne entière en une liste de nombres et additionnez-les.

algorithmshark
la source
1

gs2, 4 octets

W#Θd

Encodé en CP437 ; le troisième octet est E9.

Wlit tous les nombres /-?\d+/d'une chaîne, mappe la valeur absolue, les dsommes.

(gs2 est également plus récent que ce défi, mais sa read-numscommande est une coïncidence totale.)

Lynn
la source
0

Smalltalk (Smalltalk / X) (51 caractères)

en utilisant le paquet regex:

(s regex:'\d+' matchesCollect:[:n|n asNumber])sum

wo regex:

((s asCollectionOfSubCollectionsSeparatedByAnyForWhich:[:c|c isDigit not]) map:#asNumber)sum

entrée en s

blabla999
la source
0

R, 30

sum(scan(t=gsub("\\D"," ",x)))

Ici, x le nom de la variable.

Exemple:

> x  <- "e7rde f ,fe 43 jfj 54f4sD"
> sum(scan(t=gsub("\\D"," ",x)))
Read 4 items
[1] 108
Sven Hohenstein
la source
0

Javascript - 43 caractères

Je sais que c'est long, mais il n'y avait pas de solution JS donc :)

c=0
a=a.split(/[^\d]/g)
for(i in a)c+=+a[i]

aest la chaîne. ccontient la réponse.

Gaurang Tandon
la source
0

Tcl, 30

expr [regsub -all \\D+ $a.0 +]

Il suppose que l'entrée se trouve dans la variable $a(officiellement, dans a) et stocke la réponse dans le résultat de l'interpréteur. Les E / S sont laissées en exercice.

Associés Donal
la source
0

APL, 16 octets

{+/⍎b\⍵/⍨b←⍵∊⎕d}

⎕dest un intégré contenant les chiffres (0-9). best affecté à un vecteur de 0/1 où 1 est donné aux caractères qui sont des chiffres. best utilisé pour compresser le tableau de caractères donné, puis réutilisé pour le développer, ce qui insère des espaces. est l' eval d'APL qui convertit une chaîne en un vecteur entier, dans ce cas. +/calcule la somme.

lstefano
la source
Longueur égale, mais intéressante:+/2⊃⍞⎕VFI⍨⎕AV~⎕D
Adám
0

Swift 3, 78

s.characters.split{!("0"..."9"~=$0)}.flatMap{Int(String($0))}.reduce(0){$0+$1}

sest la chaîne

Kametrixom
la source
0

Perl - 24 caractères

warn eval join'+',/\d+/g

L'entrée est en $ _

Kaundur
la source
0

En fait, 14 octets (non concurrents)

9u▀8╙r♂┌-@s♂≈Σ

Essayez-le en ligne!

Cette soumission n'est pas concurrentielle, car elle est en fait un peu plus récente que ce défi.

Ce programme prend en charge la page de codes CP437 pour la saisie.

Explication:

9u▀8╙r♂┌-@s♂≈Σ
9u▀             base 10 digits (0-9)
   8╙r♂┌        all characters in CP437 (map(ord_cp437, range(2**8)))
        -       set difference
         @s     split input on any value in the resulting list
           ♂≈Σ  convert to ints and sum
Mego
la source
0

C 100

t=0;main(i,v)char**v;{for(char*q,*s=v[1];i=strtol(s,&q,0),*s;q>s?t+=abs(i),s=q:s++);printf("%d",t);}

Essayez-le en ligne!

Une version antérieure de 85 octets qui triche un peu en codant en dur la chaîne à l'intérieur du programme:

t=0;main(i){for(char*q,*s;i=strtol(s,&q,0),*s;q>s?t+=abs(i),s=q:s++);printf("%d",t);}

Pour utiliser réellement le programme de 85 octets, vous devez affecter la variable comme suit:

t=0;main(i){for(char*q,*s="text";i=strtol(s,&q,0),*s;q>s?t+=abs(i),s=q:s++);printf("%d",t);}
Jerry Jeremiah
la source