Incrémentez chaque nombre dans une chaîne

11

Étant donné une chaîne contenant des nombres décimaux:

teststring134this 123test string54 100

incrémenter chaque numéro de cette chaîne de un pour donner la nouvelle chaîne

teststring135this 124test string55 101.

La chaîne peut être fournie sous la forme:

  • un argument de ligne de commande
  • STDIN
  • une variable codée en dur ou un argument de fonction

Couvrir toutes les positions possibles pour un certain nombre:

  • comme préfixe pour un mot; 123test124test
  • comme suffixe pour un mot; test123test124
  • à l'intérieur d'un mot; te123stte124st
  • seul test 123 testtest 124 test

Voici une solution non golfée en Python:

NUMBERS = '0123456789'

def increment(s):
    out = ''

    number = ''
    for c in s:
        if c in NUMBERS:
            number += c
        else:
            if number != '':
                out += str(int(number) + 1)
                number = ''
            out += c

    if number != '':
        out += str(int(number) + 1)
        number = ''

    return out


print "\"%s\"" % (increment('teststring134this 123test string54 100'))

C'est une code-golfquestion, le code le plus court gagne.

The6P4C
la source
5
Fait amusant: cela peut être fait avec 3 substitutions de regex pures (pas de rappels) stackoverflow.com/questions/12941362/… (ce ne serait pas la façon la plus golfique cependant)
Martin Ender
4
Vous avez spécifié l'entrée mais pas la sortie. D'après vos spécifications d'entrée, je suppose que STDOUT et la valeur de retour sont corrects. Mais pouvons-nous également stocker le résultat dans une variable codée en dur (tout comme nous pouvons en tirer des entrées)?
Martin Ender
1
Et le port? Qu'arrive-t-il au 999?
moelleux
3
doublon possible de Multipliez tous les nombres dans une chaîne
Digital Trauma
7
Et les nombres négatifs? Qu'en est-il des nombres avec un point décimal? Qu'en est-il des nombres avec un point décimal et rien avant (sauf peut-être pour un signe moins)?
Peter Taylor

Réponses:

23

Perl, 14 octets

s/\d+/$&+1/ge

Nécessite le -pcommutateur, que j'ai compté comme un octet.

Exemple d'exécution

$ perl -p <(echo 's/\d+/$&+1/ge') <<< 'teststring134this 123test string54 100'
teststring135this 124test string55 101
Dennis
la source
5
Très similaire à ma réponse ici haha codegolf.stackexchange.com/a/37113/29438
hmatt1
12

Rubis, 30 24 octets

$><<s.gsub(/\d+/,&:next)

S'attend à ce que l'entrée soit stockée s.

Martin Ender
la source
3
Impossible d' $1.nextutiliser dans le bloc?
Août
@August gentil, merci! Je ne savais pas que nextc'était sophistiqué.
Martin Ender
11

Vim - 13 frappes

0qqqqq^Al@qq@q

Attend que l'entrée soit la ligne actuelle.

Ou pour un nombre fini de nombres (par exemple 999) dans 8 + ceil (log (n)) touches:

0qq^Alq999@q
coyotebush
la source
Je n'arrive pas à faire fonctionner cela .... (j'utilise vim 7.0.237)
Jerry Jeremiah
10

JavaScript (ES6) - 28

H=k=>k.replace(/\d+/g,k=>++k)

Exécutez en utilisant H("test 123 234t").

soktinpk
la source
1
Vous pouvez supprimer le H=et le faire simplement être une fonction anonyme.
Mama Fun Roll
8

Perl, 23

Suppose que la chaîne d'entrée est affectée à $_

s/\d+/@{[$&+1]}/g;print
grc
la source
8

Python 2 - 59

Fournissez la chaîne comme variable n

import re;print re.sub('\d+',lambda x:`int(x.group())+1`,n)
Beta Decay
la source
6

C99 - 86 (GCC 4.9.0 et Visual C ++ 2013)

Modifier: GCC 4.9.0 (avec -std = c99) et Visual C ++ 2013 ont réussi à générer (avec des avertissements) le même code sans les inclusions. Je ne savais pas que tu pouvais faire ça! Merci pour l'astuce.

Edit: Il ne m'est même pas venu à l'esprit que je devrais l'écrire à l'écran à la volée au lieu de créer la chaîne et de l'imprimer. Cela fait une énorme différence. Merci Dennis!

Cela utilise une chaîne codée en dur mais le contenu de la chaîne n'est pas compté dans le total (le = "" est compté).

main(i){for(char*q,*s="test123test999test-1test";i=strtol(s,&q,0),*s;q>s?printf("%d",i+1,s=q):putchar(*s++));}

Fondamentalement, il parcourt la chaîne un caractère à la fois en vérifiant chacun pour voir s'il s'agit d'un entier. Si c'est le cas, il incrémente l'entier et l'écrit dans la sortie, sinon il copie le caractère actuel dans la sortie.

Cela fuit la chaîne codée en dur car elle incrémente s.

Jerry Jeremiah
la source
1
Je suis sûr que vous pouvez vous débarrasser de certains des includes et il compilera toujours très bien avec gcc.
Martin Ender
1
Est-ce que cela fonctionnera avec une chaîne contenant par exemple 99?
anatolyg
@ MartinBüttner: Oui, mais ce ne serait pas un C valide, juste quelque chose qui se passe sur gcc.
R .. GitHub STOP HELPING ICE
@R .. C'est généralement autorisé sur PPCG. Je l'ai vu (et par la suite fait) assez souvent sans que personne ne se plaigne.
Martin Ender
Oui, et c'est une bête générale à moi. Le langage doit être répertorié comme "GCC" ou "C sur [arch particulier / etc. Les hacks fonctionnent sur]] ou similaire, plutôt que C, si ce n'est pas réellement valide C. :-)
R .. GitHub STOP HELPING ICE
5

J (20)

Attend que l'entrée soit stockée dans la variable a.

'\d+'>:&.".rxapply a

Tester:

   a=:'teststring134this 123test string54 100'
   '\d+'>:&.".rxapply a
teststring135this 124test string55 101
marinus
la source
5

(f?) lex (39)

Fichier inc.l:

%%
[0-9]+ printf("%d",atoi(yytext)+1);

Compiler:

$ flex inc.l
$ gcc lex.yy.c -o inc -lfl

Courir:

$ echo 'teststring134this 123test string54 100' | ./inc
teststring135this 124test string55 101

$ i='(-: 2 empty bottles of beer :-)'
$ tty=$(tty)
$ for n in {2..5} ; do i=$(./inc<<<$i|tee $tty) ; done
(-: 3 empty bottles of beer :-)
(-: 4 empty bottles of beer :-)
(-: 5 empty bottles of beer :-)
(-: 6 empty bottles of beer :-)

Je n'ai pas testé cela avec l'original lex. Les commentaires sont les bienvenus.


la source
1
Vous pouvez supprimer la fin %%car il ne s'agit pas d'un code utilisateur: flex.sourceforge.net/manual/…
Josh
Hé ... oui! J'ai essayé mais sans traîner la nouvelle ligne et cela a échoué ... alors je n'ai pas essayé d'ajouter la dernière ligne finale ... ;-) ... stupide erreur!
3

Emacs - 20 caractères

C-M-% [0-9]+ RET \,(1+ \#0) RET !

Nécessite que le texte à traiter soit présent dans le tampon actuel. J'ai compté CM-% comme un caractère ici car il peut être entré en appuyant sur une touche lorsque vous maintenez trois modificateurs enfoncés.

user16727
la source
3

GNU sed, 304 (dont 1 pour le drapeau -r)

J'ai voté de près sur cette question en tant que doublon possible, mais c'est peut-être contraire à cela car cette réponse ne peut pas être trivialement modifiée pour y fonctionner. De loin la réponse la plus longue.

Inspiré par cet exemple de la documentation sed , bien qu'il ait fallu du travail pour gérer plusieurs nombres dans une chaîne:

:d
s/9([^0-9]+|$)/_\1/g
td
s/8(_*)([^0-9]+|$)/9\1\2/g
s/7(_*)([^0-9]+|$)/8\1\2/g
s/6(_*)([^0-9]+|$)/7\1\2/g
s/5(_*)([^0-9]+|$)/6\1\2/g
s/4(_*)([^0-9]+|$)/5\1\2/g
s/3(_*)([^0-9]+|$)/4\1\2/g
s/2(_*)([^0-9]+|$)/3\1\2/g
s/1(_*)([^0-9]+|$)/2\1\2/g
s/0(_*)([^0-9]+|$)/1\1\2/g
s/(^|[^0-9_]+)(_+)/\11\2/g
y/_/0/

Production:

$ for s in "teststring134this 123test string54 100" "123test" "test123" "te123st" "test 123 test" ; do echo "$s" | sed -rf incr.sed ; done
teststring135this 124test string55 101
124test
test124
te124st
test 124 test
$ 

Notez que cela insère temporairement des _caractères, ce qui pourrait entraîner des résultats incorrects s'il y en a _dans le flux d'entrée. Pour atténuer cela, nous pouvons remplacer le _dans le script sed par un caractère non imprimable (par exemple ASCII 0x07 BEL), et supposer que le flux d'entrée contient uniquement de l'ASCII imprimable. Cela semble bien fonctionner quand je le teste.

Traumatisme numérique
la source
3

Raquette 74

(define(f x)(regexp-replace* #px"\\d+"x(λ(m)(~a(+ 1(string->number m))))))
Matthew Butterick
la source
2

Lua - 68 caractères

d='(%D-)'for k,i,j in s:gmatch(d..'(%d+)'..d)do io.write(k,i+1,j)end

S'attend à ce que l'entrée soit stockée dans l'art.

AndoDaan
la source
2

CJam, 67 58 53 48 31 caractères

Cette question est comme la pire question pour CJam. Aucune expression régulière, aucune correspondance de modèle, aucune capture d'exception. Mais c'est parti (#YOLO)

Sl+_A,sNerN%\[_A,s-Ner~]:)]zs1>

Celui-ci divise la chaîne en groupe d'alphabets et de chiffres uniquement. Les incréments de chaque chiffre et recoud les deux tableaux en prenant un élément de chacun à la fois.


Solution précédente:

L_l{:Ci57-zA<:RC*+:N\R!N*NNW?i):NL?+RLC?@R*}/NL?

Essayez-le en ligne ici

Comment ça fonctionne:

L'idée de base est de continuer à stocker le caractère séparément dans une chaîne s'il s'agit d'un chiffre et de vider la valeur incrémentée dans la chaîne finale une fois que nous obtenons un caractère non numérique.

L_                                               "Push two empty strings to stack,"
                                                 "first representing the final string"
                                                 "and second, the current ongoing number";
  l{                                       }/    "Run this block for each character of input string";
    :Ci                                          "Store the character to C and convert to"
                                                 "its ASCII equivalent integer";
       57-zA<:R                                  "Subtract 57 from the integer and compare"
                                                 "its absolute value with 10. Numeric character"
                                                 "would result to true here. Store the result in R";
               C*+:N                             "Take either 0 or 1 characters from C based"
                                                 "on value of R, add it to the second string"
                                                 "from first step. Also store the value in N";
                    \                            "Switch the strings. Now the string containing"
                                                 "the final result string is at top of stack";
                     R!N*                        "If the character was not a digit and N contains a number in it";
                         NNW?i):NL?+             "Convert N to number and increment it."
                                                 "If N is blank, take 0 instead. Put the final"
                                                 "value back in N and add it to the final result string";
                                    RLC?         "If the character was not a digit, push it to stack";
                                        @R*      "Put the ongoing numeric string back to top of stack";
                                             NL? "This is to handle the case when the last number"
                                                 "is not followed by a string, so stack will"
                                                 "have a string at top. Push the value of N to stack in that case";
Optimiseur
la source
1

Cobra - 88

do(s='')=RegularExpressions.Regex.replace(s,'\d+',do(m as Match)='[int.parse("[m]")+1]')
Οurous
la source
1

C # - 178 169 157 157 caractères

Cela suppose que des nombres comme 999 peuvent déborder à 000 et que - + ,. E ne font pas partie d'un nombre.

class T{static void Main(){var a="".ToCharArray();for(int b=1,c,i=a.Length;i-->0;b=48>c|c>57?7:b>0?c>56?a[i]='0':++a[i]*0:b)c=a[i];System.Console.Write(a);}}

Forme mieux lisible:

class T
{
    static void Main()
    {
        var a="7teststring134this 123test string59 100".ToCharArray();

        for (int b=3, c, i=a.Length; i-->0;
            b=48>c|c>57
                ?7
                :b>2
                    ?c>56?a[i]='0':++a[i]*0
                    :b
        ) c=a[i];

        System.Console.Write(a);
        System.Console.ReadKey();
    }
}

Je suis nouveau ici, je n'ai jamais essayé le golf de code auparavant, j'ai juste essayé :)

Je me demande si quelqu'un a des idées pour le raccourcir encore ...

Pour participer avec C #, ce serait bien si nous pouvions omettre tout le framework nécessaire autour du code réel - alors cela n'aurait que 82 caractères, et cela sans appeler de fonctions système puissantes.


La même chose avec les pointeurs (182 caractères):

class T
{
    unsafe static void Main()
    {
        char[] a="7teststring134this 123test string59 100".ToCharArray();

        int b=3;
        fixed (char* s=&a[0])
            for (var p=s+a.Length; p-->s; )
                b=*p<48|*p>57
                    ?7
                    :b>2
                        ?*p>56?*p='0':++*p*0
                        :b;

        System.Console.Write(a);
        System.Console.ReadKey();
    }
}

Maintenant, sans débordement, cela gère correctement le cas 999 (223 caractères):

class T
{
    static void Main()
    {
        var s=new System.Text.StringBuilder("9999teststring134this 123test string99 100");

        for (int b=3, c, i=s.Length; i-->0; )
        {
            c=s[i];
            b=48>c|c>57
                ?b>8?8:7
                :b>2
                    ?c>56?c-(s[i]='0'):++s[i]*0
                    :b;
            if (b>8&i<1|b==8) s.Insert(i+9-b, '1');
        }

        System.Console.Write(s);
        System.Console.ReadKey();
    }
}

Un autre plus ancien, il lit à partir de l'entrée standard et utilise la récursivité:

namespace System {
    using C=Console;
    class T {
        class t {
            byte b=1;
            string s="";
            void R() {
                var c=C.Read();
                if (c>31) {
                    R();
                    if (48>c|c>57) b=1;
                    else if (b==1) c=c==57?48:++c*b--;
                    s=(char)c+s;
                }
            }
            public t() {
                R();
                C.Write(s);
            }
        }
        static void Main() {
            new t();
            C.ReadKey();
        }
    }
}

Remarque: Console.ReadKey();et la chaîne elle-même ne doit pas être comptée.

J'ai déjà amélioré cela plusieurs fois, voir les commentaires. Il y a encore de la place pour plus d'améliorations, je dirais :) Et désolé pour la longueur, mais je pense que les différentes versions sont assez intéressantes pour les garder ...

maf-soft
la source
non, se débarrasser de "l'environnement" n'est pas autorisé. je compte dans votre deuxième code après avoir if(c==57)pu écrire c--;au lieu de c=48;, qu'en est-il de l'opérateur ternaire aussi. il y a beaucoup de tours de golf. vous devriez peut-être visiter codegolf.stackexchange.com/questions/2203/tips-for-golfing-in-c
proud haskeller
Merci, je ne connais rien au golf :) tout ce que vous voyez ici a été inventé par moi ;-) 57-1 n'est pas 48. Donc je ne comprends pas.
maf-soft
Oups :-) :-) :-) :-)
fier haskeller
Je ne connais pas vraiment bien C #, mais je suppose que vous pouvez utiliser un opérateur pour les coller ensemble comme... ? ... : c++*b--
fier haskeller
btw désolé de vous avoir envoyé les astuces C au lieu des astuces C #: codegolf.stackexchange.com/questions/173/…
fier haskeller
1

Groovy, 38 octets

{it.replaceAll(/\d+/,{(it as int)+1})}

Uggghhh ... Je déteste absolument les mots replaceet allils ruinent tous les golfs regex pour moi.

Urne de poulpe magique
la source
1
(it as int)+1it.next()
manatwork
0

PHP - 91 octets

<?$i=fgets(STDIN);for($n=0;$n<strlen($i);$n++)if(is_numeric($i[$n]))$i[$n]=$i[$n]+1;echo$i;

Je ne voulais pas utiliser d'expressions régulières. PHP n'est pas capable d'incrémenter directement un décalage de chaîne, j'ai donc dû ajouter quelques octets à l'étape d'incrémentation. Ce script d'une ligne me rappelle un âge très sombre du script PHP ...

Alexandre Teles
la source
J'ai observé tout à l'heure que la question vous demande d'augmenter le nombre de résultats d'une séquence d'algarismes. Cette réponse est incorrecte. Mais je pense vraiment que l'op devrait ajouter plus de détails sur ce qu'il veut.
Alexandre Teles
0

K, 56

{" "/:{,/$(`$a)^`$$1+"I"$a:_[;x]@&~~':x in .Q.n}'" "\:x}
tmartin
la source
0

sed et bash - 40 (y compris invocation et tuyaux)

$ cat << EOF |sed 's/[0-9]\+/$((\0+1))/g;s/^/echo /'|bash
teststring134this 123test string54 100
123test
test123
te123st
test 123 test
EOF

Les sorties:

teststring135this 124test string55 101
124test
test124
te124st
test 124 test
mgjk
la source
J'ai essayé cette chaîne de test: 42;rm -rf /cela a fonctionné la première fois.
Dennis
2
Vous pouvez passer \0à &(-1 caractère), $((…))à $[…](-2 caractères), s/^/echo /à iecho \\(-2 caractères) pour raccourcir votre code actuel . Cependant, mieux vaut d'abord corriger le bogue mentionné par @Dennis. (Il a écrit « Il a travaillé pour la première fois » pour le plaisir et comme indice sur la question En fait , votre code échoue sur l' entrée contenant. ;, #, `…`, $(…)Et peut - être d' autres caractères spéciaux aussi.)
manatwork
L'exécution de code arbitraire est une fonctionnalité :-)
mgjk
Il n'y a peut-être aucun moyen de suivre cette voie sans une sorte de restriction d'entrée et en gardant le code petit. La nature de la solution est de traduire l'entrée et d'utiliser un interpréteur pour faire le calcul car sed ne peut pas le faire. Dès que l'entrée utilisateur frappe un interpréteur, l'échappement est fou. À part l'exemple précédent de sed, sed ne peut pas faire de maths.
mgjk
Un peu plus court: eval echo `sed 's/[0-9]\+/$[&+1]/g'`- a toujours le problème d'injection de code cependant, selon ma réponse à une autre question similaire codegolf.stackexchange.com/a/37145/11259
Digital Trauma
0

Java 7, 119 octets

void c(String s){for(String x:s.split("(?=[^\\d]+)|(?<=[^\\d]+)"))System.out.print(x.matches("\\d+")?new Long(x)+1:x);}

Si l'exigence est un programme au lieu d'une simple fonction, alors c'est 149 octets:

class M{public static void main(String[]a){for(String x:a[0].split("(?=[^\\d]+)|(?<=[^\\d]+)"))System.out.print(x.matches("\\d+")?new Long(x)+1:x);}}

Code non testé et testé:

Essayez-le ici.

class M{
  static void c(String s){
    for(String x : s.split("(?=[^\\d]+)|(?<=[^\\d]+)")){
      System.out.print(x.matches("\\d+")
                        ? new Long(x) + 1
                        : x);
    }
  }

  public static void main(String[] a){
    c("123test");
    System.out.println();
    c("test123");
    System.out.println();
    c("te123st");
    System.out.println();
    c("test 123 test");
    System.out.println();
    c("7teststring134this 123test string59 100");
  }
}

Production:

124test
test124
te124st
test 124 test
8teststring135this 124test string60 101
Kevin Cruijssen
la source
0

Gema, 14 personnages

<D>=@add{$1;1}

Exemple d'exécution:

bash-4.3$ gema '<D>=@add{$1;1}' <<< 'teststring134this 123test string54 100'
teststring135this 124test string55 101
homme au travail
la source
0

DASH , 16 octets (sans concurrence)

rstr[R"\d+""g"+1

Cela renvoie une fonction / application partielle.

Usage:

rstr[R"\d+""g"+1]"test 123 234t"

Explication

rstr[          #. replace any parts of the input
  R "\d+" "g"  #. matching /\d+/g
  +1           #. with its incremented form
]
Mama Fun Roll
la source
Cette réponse est-elle non concurrente?
Dennis
oh rip :( Je pensais que c'était une question de catalogue.
Mama Fun Roll
0

CJam, 18 octets

q_A,s-_:(:`ers~]:)

Essayez-le ici.

Explication

q         e# Read input.
_A,s-     e# Duplicate and remove digits.
_         e# Duplicate.
:(:`      e# Decrement and get the string representation of each character.
er        e# Map the characters to the decremented string representation.
s~        e# Flatten to string and evaluate.
]:)       e# Wrap in an array and increment each element.
jimmy23013
la source
0

R, 83 octets

Tard à la fête. Suppose que l'entrée est stockée dans une variable x. Il n'est probablement pas nécessaire de l'utiliser regmatchespour résoudre ce problème, mais je n'ai pas pu comprendre les remplacements vectorisés sans packages externes.

paste0(el(r(x,m<-gregexpr("\\d+",x),T)),c(as.numeric(el(r(x,m)))+1,""),collapse="")

Non golfé et expliqué

r=regmatches                                        # Alias for regmatch
y=r(x<-scan(,""),m<-gregexpr("\\d+",x))             # return match digits
i=r(x,m,T)                                          # return inverted match (non-digits)
paste0(el(i),c(as.numeric(el(y))+1,""),collapse="") # join digits+1 and non-digits, element-wise

Exemple de sortie

input: 
"teststring135this 124test string55 101"

output:
[1] "teststring136this 125test string56 102"
Billywob
la source
0

C # (Visual C # Interactive Compiler) avec option de ligne de commande /u:System.Text.RegularExpressions.Regex;System.Int32, 40 octets

Replace(n,"\\d+",m=>Parse(m.Value)+1+"")

Attend que l'entrée soit dans une variable nommée n.

Essayez-le en ligne!

Incarnation de l'ignorance
la source
2
Non valide, ne peut pas s'attendre à une entrée dans une variable
ASCII uniquement
@ ascii-only Cette question semble l'autoriser explicitement 'bien que personnellement, j'essaierais de m'en tenir aux normes d'entrée d'aujourd'hui
Jo King
Oh, attendez: / ew cette question
ASCII uniquement