Addition-soustraction de nombres dans une chaîne

14

Prenez une chaîne en entrée, effectuez l'addition / la soustraction de tous les chiffres de la chaîne et sortez la somme de ces opérations comme résultat.

Règles

  • Les chiffres de la chaîne sont lus de gauche à droite
  • Si un chiffre (n) est impair, effectuez l'addition avec le chiffre suivant (n + n1)
  • Si un chiffre (n) est pair, effectuez la soustraction avec le chiffre suivant (n - n1)
  • Si vous avez atteint le dernier chiffre de la chaîne, effectuez l'opération avec le premier chiffre de la chaîne
  • La sortie sera la somme de toutes les valeurs résultantes
  • S'il n'y a qu'un seul chiffre dans la chaîne, effectuez l'opération avec lui-même (n + n ou nn)
  • S'il n'y a pas de chiffres dans la chaîne, la sortie est 0

Exemple

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

Remarques

  • La fonction ou le programme complet est accepté
  • La longueur d'entrée maximale dépend de la limite de votre langue pour une entrée de chaîne
  • Aucune restriction sur la saisie de caractères, mais seuls les chiffres de demi-largeur comptent pour la sortie
  • Le moins d'octets gagne
Noir Antares
la source
4
Quelques autres exemples seraient bien aussi
dylnan
2
Je recommanderais d'ajouter un cas de test se terminant par un chiffre impair.
Arnauld
3
Testcase suggéré: "", "0","1"
tsh
1
Pouvons-nous prendre l'entrée comme un tableau de caractères au lieu d'une chaîne? (Julia fait une distinction entre ces deux-là.)
sundar - Réinstallez Monica
4
@sundar Le consensus actuel est qu'une chaîne est définie comme une séquence de caractères. Ma compréhension est que les tableaux de caractères sont donc autorisés par défaut même si votre langue a un type de chaîne natif .
Arnauld

Réponses:

6

Gelée , 17 15 12 octets

fØDV€ḂT‘ịƲSḤ

Essayez-le en ligne!

Essayez des cas de test.

Le programme ne conserve que les chiffres qui suivent un chiffre impair puis calcule le double de la somme.

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
la source
3

K (oK) , 47 43 40 31 octets

Solution:

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

Essayez-le en ligne!

Explication:

Supprimez tout de la chaîne qui n'est pas un nombre (tout en convertissant également), modulo 2, multipliez par 2, multipliez avec x tourné de 1 et résumez.

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

Solution naïve:

Supprimez tout de la chaîne qui n'est pas un nombre (tout en convertissant également), prenez une fenêtre coulissante à 2 éléments, déterminez s'ils sont impairs ou pairs, appliquez ajouter / soustraire selon le cas, puis résumez.

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

Essayez-le en ligne!

Remarques:

  • -4 octets grâce à @ngn grâce à une manière plus intelligente de filtrer l'entrée
  • -3 octets en utilisant une fenêtre coulissante plutôt que de remodeler
  • -9 octets portant la solution de ngn (approche non naïve)
streetster
la source
1
x:48!x@&x in,/$!10->x^:(x-:48)^!10
ngn
J'ai écrit la solution en q / kdb + puis porté sur oK ... je pourrais peut-être encore en extraire quelques octets!
streetster
1
J'ai posté une réponse séparée en ngn / k, n'hésitez pas à apporter des idées à partir de là. Je pense que oK finira par être le plus court, car mon analyseur est un déchet pour le moment - il n'analyse pas correctement l'affectation modifiée. Soit dit en passant, je n'étais pas au courant de ':la "fenêtre coulissante" - intéressante.
ngn
Vous semblez bien connaître k. Si jamais vous avez envie de discuter de choses sur la programmation vectorielle avec des personnes partageant les mêmes idées ou simplement de regarder le reste d'entre nous discuter - nous avons cette salle de chat . La plupart des plaisanteries concernent APL, mais k et J sont également sur le sujet.
ngn
2

Powershell, 80 78 76 octets

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

-2 octets merci Neil avec la solution Retina

-2 octets merci AdmBorkBork

Script de test:

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

&$f 'r5e6o9mm!/3708dvc'

Explication

Tout d'abord: il devrait ajouter 2 * n si le chiffre précédent est impair et 0 si un chiffre précédent est pair.

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

Inspiré par @Neil. Regex correspond aux chiffres avec «le chiffre précédent est impair» uniquement. Matchesest une variable automatique .

param($d)$d+($d-match'\d')+$Matches[0]|sls '(?<=[13579]\D*)\d'-a|%{$_.Matches.Value|%{$s+=2*$_}};$s
mazzy
la source
1
Enregistrez un échange d'octets |?{$_}pour -ne''un autre en passant $d="$args"-split'\D*'-ne''à des parens comme ($d="$args"-split'\D*'-ne'')+$d[0].
AdmBorkBork
2

MATL , 18 17 octets

t4Y2m)!Ut1YSof)sE

Essayez-le en ligne!

(-1 octet grâce à Luis Mendo / Giuseppe / les deux!)

Explication:

     % 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'idée de base est que les nombres qui suivent des nombres pairs peuvent être ignorés, tandis que ceux qui suivent des nombres impairs sont doublés - et le résultat final est la somme de ces valeurs doublées.

Je ne pensais pas fqu'après le contrôle de parité oserait nécessaire, mais pour une raison quelconque MATL ne voit pas le tableau de 0 et de 1 qui résultent du ocomme un tableau logique, les prend plutôt comme des indices numériques et des index dans les positions 1et end.

Sundar - Rétablir Monica
la source
Je pense que vous pouvez utiliser à la !Uplace de 48-. La transposition ne semble pas faire de mal ici. opour l' doubleentrée est juste mod(...,2), donc la sortie l'est double. Belle NaNastuce d'entrée! Si cela est censé résoudre la sortie étrangère dans STDOUT, Dennis a eu une idée et corrigera probablement cela bientôt
Luis Mendo
!Uau lieu de48-
Giuseppe
@LuisMendo welp, vous m'avez battu au poinçon!
Giuseppe
@Giuseppe :-D :-D
Luis Mendo
Merci à vous deux, édité. @LuisMendo Quand odonne-t-il alors une sortie de tableau logique - ou non? (Je dois avouer que je n'ai jamais vraiment examiné le système de type numérique de MATLAB.) Et oui, je pensais que NaNcela ferait une belle sentinelle car il est peu probable que ce soit une entrée réelle n'importe où, mais bon de savoir qu'il ne sera pas nécessaire longtemps !
sundar
2

K (ngn / k) , 33 octets

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

Essayez-le en ligne!

{ } est une fonction avec argument x

!10 est la liste 0 1 ... 9

$ convertir en chaînes

,/ enchaîner

x^signifie xsans ce qui est à droite

x^x^signifie xintersecté avec ce qui est à droite, c'est-à-dire ne garder que les chiffres dex

-48+soustraire 48, qui est le code ASCII de"0"

x: affecter à x

2! mod 2

2* multiplié par 2

1_x,*xest une goutte de: xsuivie de la première de x; c'est x-à- dire tourné vers la gauche d'un pas

+/ somme

ngn
la source
2

Japt (v2.0a0), 25 19 octets

-6 octets grâce à Shaggy .

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

Essayez-le ici .

Cela fonctionne sans chiffres cette fois! L'entrée est une liste de caractères.

LegionMammal978
la source
19 octets , y compris le passage à Japt v2. Pas satisfait du tableau dans la xfonction, cependant. Envoyez-moi un ping dans le chat si vous avez des questions.
Shaggy
Attendez, juste remarqué que cela ne fonctionnera pas du tout si l'entrée ne contient aucun chiffre.
Shaggy
Aussi, où est la source de la v2.0a0, @Shaggy? Je ne le trouve pas dans le repo.
LegionMammal978
C'est v1 et c'est v2.
Shaggy
Au cas où vous l'auriez manqué dans le chat, je l'ai réduit à 12 octets pour vous.
Shaggy
2

05AB1E , 12 9 octets

Enregistre 1 octet par rapport à la méthode naïve en utilisant l' astuce de parité de dylnan
Sauvegardé 3 octets grâce à M. Xcoder

þDÁ€ÉÏSO·

Essayez-le en ligne!

Explication

þ              # push only digits of input
 D             # duplicate
  Á            # rotate right
   ۃ          # get the parity of each
     Ï         # keep only true items
      SO       # calculate digit-sum
        ·      # double
Emigna
la source
Hmm, serait þÀIþ€ÉÏSO·, þÀDÁ€ÉÏSO·, þÀ¹þ€ÉÏSO·ou þÀsþ€ÉÏSO·passer tous les tests pour -2 octets?
M. Xcoder
@ Mr.Xcoder: Ah, oui. Agréable! On peut même faire þDÁ€ÉÏSO·pour -3 :)
Emigna
1

Rétine , 37 octets

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

Essayez-le en ligne! Explication:

(\d).*
$&$1

Ajoutez un double du premier chiffre.

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

Correspond à tout ce dont le premier chiffre précédent est impair.

2**

Convertissez tous les matchs en unaire et doublez-les. (Les non-chiffres sont traités comme zéro.)

_

Prenez la somme. S'il n'y avait pas de correspondance, cela produit zéro comme requis.

Le mieux que j'ai pu faire dans Retina 0.8.2 était de 44 octets:

[^\d]

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

.
$*
.
..
.

Essayez-le en ligne! Explication:

[^\d]

Supprimer les non-chiffres.

(.).*
$&$1

Ajoutez une copie du premier chiffre.

(?<![13579]).

Supprimez les chiffres qui ne suivent pas un chiffre impair.

.
$*

Convertissez en unaire.

.
..

Doublez-les.

.

Prenez la somme.

Neil
la source
Je crains que le résultat ne soit incorrect si le dernier chiffre n'est pas impair
mazzy
1
@mazzy Lorsque vous dites le dernier chiffre, voulez-vous dire avant ou après avoir copié le premier chiffre à la fin?
Neil
'jusqu'à la fin'. l'étape 'Ajouter un double du premier chiffre' est en train de copier à la fin? D'accord. cool. Merci
mazzy
1

JavaScript (ES6), 56 octets

Prend l'entrée comme un tableau de caractères.

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

Essayez-le en ligne!

Commenté

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
la source
1

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

-1 octets grâce aux ovs

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

Essayez-le en ligne!

Prend l'entrée de chaîne, recherche les chiffres sous forme de tableau de caractères ou renvoie un tableau vide s'il n'en trouve pas, puis utilise la contrainte de type pour s'assurer que les valeurs sont ajoutées / soustraites correctement. La recherche directe pré-incrémente l'index et utilise une vérification nulle pour la brièveté, puis la dernière partie vérifie si le nombre est impair ou même pour forcer ensuite l'addition ou la soustraction (+ et - est -, etc.)

bluefinger
la source
n-0peut être+n
ovs
Bienvenue chez PPCG!
Conor O'Brien
1

R , 58 octets

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

Essayez-le en ligne!

  • en utilisant le tour de parité de dylnan
  • -8 octets acceptant un vecteur de caractères au lieu de chaînes
  • -3 octets grâce à @Giuseppe
digEmAll
la source
67 octets si cela ne vous dérange pas de arraysortie.
Giuseppe
1
hmm en fait, vous ne pouvez pas utiliser le produit scalaire à cause du tableau vide xxx, il est donc de 68 octets en utilisant le changement d'indexation apour générer y.
Giuseppe
@Giuseppe: modifié, merci :)
digEmAll
@Giuseppe: Je vous demande votre avis puisque vous êtes un golfeur de code plus sage ... d'après les commentaires, il semble que nous pouvons utiliser un vecteur de caractères, dans ce cas 61 octets sont possibles: Essayez-le en ligne! Qu'est-ce que tu penses ?
digEmAll
utiliser à la strtoiplace de as.double, mais oui, ça devrait aller.
Giuseppe
0

Perl 5 , 48 octets

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

Essayez-le en ligne!

J'aime à quel point cela semble cryptique, mais c'est une boucle assez simple autour de tous les nombres de la chaîne.

Dom Hastings
la source
0

Julia 0,6 , 77 69 octets

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

Essayez-le en ligne!

Sundar - Rétablir Monica
la source
0

C Sharp 180 octets

Ce n'est pas un très bon 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;}}

Non golfé:

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
la source
0

Stax , 14 octets

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

Exécuter et déboguer

Déballé, non golfé et commenté, il ressemble à ceci.

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

Exécutez celui-ci

récursif
la source
0

JavaScript (ES6), 52 octets

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

Attend une entrée sous forme de tableau de caractères. Mise en garde: en raison de l'utilisation du décalage binaire, la sortie a une limite supérieure de2^31-1

Essayez-le en ligne!

Explication

Double essentiellement la somme des chiffres suivant les valeurs impaires.

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)
redondance
la source