Incrementa ogni numero in una stringa


11

Data una stringa contenente numeri decimali:

teststring134this 123test string54 100

incrementa ogni numero in questa stringa di uno per dare la nuova stringa

teststring135this 124test string55 101.

La stringa può essere fornita come:

  • un argomento da riga di comando
  • STDIN
  • una variabile codificata o un argomento di funzione

Copri tutte le posizioni possibili per un numero:

  • come prefisso per una parola; 123test124test
  • come suffisso per una parola; test123test124
  • dentro una parola; te123stte124st
  • da solo test 123 testtest 124 test

Ecco una soluzione senza golf in 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'))

Questa è una code-golfdomanda, vince il codice più corto.


5
Curiosità: questo può essere fatto con 3 sostituzioni regex pure (senza callback) stackoverflow.com/questions/12941362/… (che non sarebbe il modo più golfoso)
Martin Ender,

4
Hai specificato input ma non output. Dalle vostre specifiche di input presumo che sia STDOUT sia il valore restituito vadano bene. Ma possiamo anche archiviare il risultato in una variabile hardcoded (proprio come possiamo ricavarne input)?
Martin Ender,

1
Che ne dici di portare? Cosa succede al 999?
soffice


7
E i numeri negativi? Che dire dei numeri con un punto decimale? Che dire dei numeri con un punto decimale e niente prima (tranne forse per un segno meno)?
Peter Taylor,

Risposte:


23

Perl, 14 byte

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

Richiede l' -pinterruttore, che ho contato come un byte.

Esempio di esecuzione

$ perl -p <(echo 's/\d+/$&+1/ge') <<< 'teststring134this 123test string54 100'
teststring135this 124test string55 101

5
Molto simile alla mia risposta qui haha codegolf.stackexchange.com/a/37113/29438
hmatt1

12

Rubino, 30 24 byte

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

Si aspetta che l'input venga archiviato s.


3
Non potrebbe $1.nextessere utilizzato nel blocco?
Agosto

@Agosto bello, grazie! Non sapevo nextfosse così sofisticato.
Martin Ender,

11

Vim - 13 sequenze di tasti

0qqqqq^Al@qq@q

Si aspetta che l'input sia la riga corrente.

O per molti numeri finiti (ad es. 999) in sequenze di tasti 8 + ceil (log (n)):

0qq^Alq999@q

Non riesco a farlo funzionare .... (Sto usando vim 7.0.237)
Jerry Jeremiah,

10

JavaScript (ES6) - 28

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

Eseguire utilizzando H("test 123 234t").


1
Puoi eliminare il H=e avere solo una funzione anonima.
Mama Fun Roll

8

Perl, 23

Presuppone che la stringa di input sia assegnata $_

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

8

Python 2 - 59

Fornire la stringa come variabile n

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

6

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

Modifica: Sia GCC 4.9.0 (con -std = c99) che Visual C ++ 2013 creano correttamente (con avvertenze) lo stesso codice senza le inclusioni. Non sapevo che potresti farlo! Grazie per il suggerimento.

Modifica: non mi è nemmeno venuto in mente che avrei dovuto scriverlo sullo schermo al volo invece di creare la stringa e quindi stamparla. Questo fa una differenza enorme. Grazie Dennis!

Questo utilizza una stringa codificata ma i contenuti della stringa non vengono conteggiati per il totale (viene contato = "").

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

Fondamentalmente scorre attraverso la stringa un carattere alla volta controllando ciascuno per vedere se è un numero intero. In tal caso, incrementa il numero intero e lo scrive nell'output, altrimenti copia il carattere corrente nell'output.

Ciò perde la stringa codificata perché aumenta di s.


1
Sono sicuro che puoi sbarazzarti di alcuni dei messaggi di posta includeelettronica e verrà comunque compilato bene con gcc.
Martin Ender,

1
Funzionerà con una stringa contenente ad esempio 99?
Anatolyg,

@ MartinBüttner: Sì, ma non sarebbe valido C, solo qualcosa che funziona su gcc.
R .. GitHub smette di aiutare ICE il

@R .. Questo è generalmente consentito su PPCG però. L'ho visto (e successivamente fatto) abbastanza spesso senza che nessuno si lamentasse.
Martin Ender,

Sì, ed è una mia peeve generale. Il linguaggio dovrebbe essere elencato come "GCC" o "C su [particolare arco / ecc. Su cui gli hack funzionano]] o simile, piuttosto che su C, se non è effettivamente valido C. :-)
R .. GitHub STOP AIUTO A GHIACCIO

5

J (20)

Si aspetta che l'input venga archiviato nella variabile a.

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

Test:

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

5

(f?) lex (39)

File inc.l:

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

Compilare:

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

Correre:

$ 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 :-)

Non ho provato questo con l'originale lex. I commenti sono ben accetti


1
È possibile eliminare il trascinamento %%poiché questo non è un codice utente: flex.sourceforge.net/manual/…
Josh

Ehi ... si! Ci ho provato ma senza trascinare la nuova riga e questo non è riuscito ... quindi non ho provato ad aggiungere la nuova riga finale ... ;-) ... stupido errore!

3

Emacs - 20 caratteri

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

Richiede che il testo da elaborare sia presente nel buffer corrente. Ho contato CM-% come un carattere qui poiché può essere inserito con un solo tasto tenendo premuti tre modificatori.


3

GNU sed, 304 (di cui 1 per -r flag)

Ho votato da vicino questa domanda come possibile duplicato, ma questo è forse contrario a questo perché questa risposta non può essere banalmente cambiata per funzionare lì. Di gran lunga la risposta più lunga però.

Ispirato da questo esempio dalla documentazione di sed , anche se aveva bisogno di un po 'di lavoro per gestire più numeri in una stringa:

: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/

Produzione:

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

Nota che questo inserisce temporaneamente i _caratteri, quindi potrebbe portare a risultati errati se ci sono _nel flusso di input. Come mitigazione di ciò, possiamo sostituire lo _script sed con un carattere non stampabile (es. ASCII 0x07 BEL) e supporre che il flusso di input contenga solo ASCII stampabile. Questo sembra funzionare bene quando lo collaudo.


3

Racchetta 74

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

2

Lua - 68 caratteri

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

Si aspetta che l'input venga archiviato in s.


2

CJam, 67 58 53 48 31 caratteri

Questa domanda è la peggior domanda per CJam. Nessuna regex, nessuna corrispondenza di pattern, nessuna cattura di eccezione. Ma eccoci (#YOLO)

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

Questo divide la stringa in un gruppo di soli alfabeti e solo cifre. Incrementa ogni cifra e ricucisce i due array prendendo un elemento di ciascuno alla volta.


Soluzione precedente:

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

Provalo online qui

Come funziona:

L'idea di base è quella di continuare a memorizzare il carattere separatamente in una stringa se è una cifra e scaricare il valore incrementato nella stringa finale una volta ottenuto un carattere non cifra.

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 caratteri

Ciò presuppone che numeri come 999 possano traboccare a 000 e che - +, E non facciano parte di un numero.

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);}}

Forma più leggibile:

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();
    }
}

Sono nuovo qui, non ho mai provato il golf del codice prima, ho solo provato :)

Mi chiedo se qualcuno abbia idee per renderlo ancora più breve ...

Partecipare con C # sarebbe bello se potessimo omettere tutto il framework necessario attorno al codice reale - allora questo avrebbe solo 82 caratteri, e quello senza chiamare nessuna potente funzione di sistema.


Lo stesso con i puntatori (182 caratteri):

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();
    }
}

Ora senza overflow, questo gestisce correttamente il caso 999 (223 caratteri):

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 altro diverso più vecchio, legge dallo standard input e usa la ricorsione:

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();
        }
    }
}

Nota: Console.ReadKey();e la stringa stessa non deve essere conteggiata.

L'ho già migliorato più volte, vedi commenti. C'è ancora spazio per ulteriori miglioramenti, direi :) E scusami per la lunghezza, ma penso che le diverse versioni siano abbastanza interessanti da tenerle ...


no, sbarazzarsi dell '"ambiente" non è permesso. secondo il tuo secondo codice dopo if(c==57)che potresti scrivere c--;invece c=48;che dire dell'operatore ternario. ci sono infatti molti trucchi per il golf. forse dovresti visitare codegolf.stackexchange.com/questions/2203/tips-for-golfing-in-c
orgoglioso haskeller il

Grazie, non so nulla del golf :) tutto quello che vedi qui è stato inventato da me ;-) 57-1 non è 48. Quindi non capisco.
maf-soft,

Oops :-) :-) :-) :-)
orgoglioso haskeller il

Non conosco bene C #, ma immagino che tu possa usare un operatore per metterli insieme come... ? ... : c++*b--
orgoglioso haskeller il

a proposito scusa per averti inviato i suggerimenti C anziché i suggerimenti C #: codegolf.stackexchange.com/questions/173/…
orgoglioso haskeller il

1

Groovy, 38 byte

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

Uggghhh ... Odio assolutamente le parole replacee mi allrovinano tutti i golf regex.


1
(it as int)+1it.next()
arte

0

PHP - 91 byte

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

Non volevo usare espressioni regolari. PHP non è in grado di incrementare direttamente un offset di stringa, quindi avevo bisogno di aggiungere alcuni byte nel passaggio di incremento. Questo script a una riga mi ricorda un'epoca molto buia dello scripting PHP ...


Ho osservato proprio ora che la domanda ti chiede di aumentare il numero di risultati di una sequenza di algarismi. Questa risposta non è corretta Ma credo davvero che l'operazione dovrebbe aggiungere ulteriori dettagli su ciò che vuole.
Alexandre Teles,

0

K, 56

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

0

sed e bash - 40 (compresi invocazione e pipe)

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

Uscite:

teststring135this 124test string55 101
124test
test124
te124st
test 124 test

Ho provato questa stringa di test: ha 42;rm -rf /funzionato la prima volta.
Dennis,

2
È possibile passare \0a &(-1 caratteri), $((…))a $[…](-2 caratteri), s/^/echo /a iecho \\(-2 caratteri) per abbreviare il codice corrente . Comunque meglio risolvere il bug menzionato per primo da @Dennis. (Ha scritto “Ha funzionato la prima volta” per divertimento e come suggerimento sulla questione In realtà il codice non riesce su input che contiene. ;, #, `…`, $(…)E forse altri caratteri speciali anche.)
manatwork

L'esecuzione di codice arbitrario è una caratteristica :-)
mgjk,

Potrebbe non esserci modo di percorrere questa strada senza qualche tipo di restrizione di input e mantenendo il codice minuscolo. La natura della soluzione è tradurre l'input e usare un interprete per fare i calcoli poiché sed non può farlo. Non appena l'input dell'utente colpisce un interprete, la fuga è pazzesca. A parte il precedente esempio di sed, sed non può fare matematica.
mgjk,

Un po 'più breve: eval echo `sed 's/[0-9]\+/$[&+1]/g'`- ha ancora il problema dell'iniezione di codice, secondo la mia risposta a un'altra domanda simile codegolf.stackexchange.com/a/37145/11259
Digital Trauma,

0

Java 7, 119 byte

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

Se il requisito è un programma anziché solo una funzione, allora è 149 byte:

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);}}

Codice non testato e test:

Provalo qui.

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

Produzione:

124test
test124
te124st
test 124 test
8teststring135this 124test string60 101

0

Gema, 14 personaggi

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

Esecuzione di esempio:

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

0

DASH , 16 byte (non competitivo)

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

Ciò restituisce una funzione / un'applicazione parziale.

Uso:

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

Spiegazione

rstr[          #. replace any parts of the input
  R "\d+" "g"  #. matching /\d+/g
  +1           #. with its incremented form
]

Questa risposta è non competitiva?
Dennis,

oh rip :( In qualche modo ho pensato che fosse una domanda da catalogo.
Mama Fun Roll,

0

CJam, 18 byte

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

Provalo qui.

Spiegazione

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 byte

In ritardo alla festa. Presuppone che l'input sia archiviato in una variabile x. Probabilmente non è necessario usarlo regmatchesper risolvere questo problema, ma non sono riuscito a capire sostituzioni vettoriali senza pacchetti esterni.

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

Ungolfed e spiegato

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

Esempio di output

input: 
"teststring135this 124test string55 101"

output:
[1] "teststring136this 125test string56 102"

0

C # (compilatore interattivo Visual C #) con opzione della riga di comando /u:System.Text.RegularExpressions.Regex;System.Int32, 40 byte

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

Si aspetta che l'input sia in una variabile chiamata n.

Provalo online!


2
Non valido, impossibile aspettarsi input in una variabile
solo ASCII

@ ascii-only Questa domanda sembra consentirla esplicitamente "anche se personalmente, proverei ad attenermi agli standard di input di oggi
Jo King

Oh aspetta: / ew questa domanda
solo ASCII il
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.