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.


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


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

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.


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

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").


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

8

Python 2 - 59

Fournissez la chaîne comme variable n

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

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.


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

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.


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.


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.



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.


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";

1

Cobra - 88

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

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 ...


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.


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 ...


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}

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

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

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

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
]

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.

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"

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!


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
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.