Erhöhen Sie jede Zahl in einer Zeichenfolge

11

Bei einer Zeichenfolge mit Dezimalzahlen:

teststring134this 123test string54 100

Erhöhen Sie jede Zahl in dieser Zeichenfolge um eins, um die neue Zeichenfolge zu erhalten

teststring135this 124test string55 101.

Die Zeichenfolge kann wie folgt bereitgestellt werden:

  • ein Befehlszeilenargument
  • STDIN
  • eine fest codierte Variable oder ein Funktionsargument

Decken Sie alle möglichen Positionen für eine Nummer ab:

  • als Präfix für ein Wort; 123test124test
  • als Suffix für ein Wort; test123test124
  • in einem Wort; te123stte124st
  • allein test 123 testtest 124 test

Hier ist eine Lösung ohne 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'))

Dies ist eine code-golfFrage, der kürzeste Code gewinnt.

The6P4C
quelle
5
Unterhaltsame Tatsache: Dies kann mit 3 reinen Regex-Substitutionen (keine Rückrufe) erfolgen. Stackoverflow.com/questions/12941362/… (das wäre allerdings nicht der beste Weg)
Martin Ender
4
Sie haben die Eingabe angegeben, aber nicht die Ausgabe. Von Ihrer Eingabespezifikation gehe ich davon aus, dass sowohl STDOUT als auch der Rückgabewert in Ordnung sind. Aber können wir das Ergebnis auch in einer fest codierten Variablen speichern (so wie wir Eingaben daraus ziehen können)?
Martin Ender
1
Was ist mit tragen? Was passiert mit 999?
flauschige
3
mögliches Duplikat von Multiplizieren Sie alle Zahlen in einer Zeichenfolge
Digital Trauma
7
Was ist mit negativen Zahlen? Was ist mit Zahlen mit einem Dezimalpunkt? Was ist mit Zahlen mit einem Dezimalpunkt und nichts davor (außer vielleicht einem Minuszeichen)?
Peter Taylor

Antworten:

23

Perl, 14 Bytes

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

Benötigt den -pSchalter, den ich als ein Byte gezählt habe.

Beispiellauf

$ perl -p <(echo 's/\d+/$&+1/ge') <<< 'teststring134this 123test string54 100'
teststring135this 124test string55 101
Dennis
quelle
5
Sehr ähnlich zu meiner Antwort hier haha codegolf.stackexchange.com/a/37113/29438
hmatt1
12

Ruby, 30 24 Bytes

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

Erwartet, dass die Eingabe in gespeichert wird s.

Martin Ender
quelle
3
Konnte nicht $1.nextim Block verwendet werden?
August
@ August schön, danke! Ich wusste nicht, nextdass es so raffiniert ist.
Martin Ender
11

Vim - 13 Tastenanschläge

0qqqqq^Al@qq@q

Erwartet, dass die Eingabe die aktuelle Zeile ist.

Oder für endlich viele Zahlen (z. B. 999) in Tastenanschlägen mit 8 + Ceil (log (n)):

0qq^Alq999@q
Coyotebush
quelle
Ich kann nicht scheinen, diese Arbeit zu machen .... (Ich benutze vim 7.0.237)
Jerry Jeremiah
10

JavaScript (ES6) - 28

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

Führen Sie mit aus H("test 123 234t").

soktinpk
quelle
1
Sie können das herausnehmen H=und es einfach zu einer anonymen Funktion machen.
Mama Fun Roll
8

Perl, 23

Angenommen, die Eingabezeichenfolge ist zugewiesen $_

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

Python 2 - 59

Geben Sie den String als Variable an n

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

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

Bearbeiten: Sowohl GCC 4.9.0 (mit -std = c99) als auch Visual C ++ 2013 erstellen erfolgreich (mit Warnungen) denselben Code ohne die Includes. Ich wusste nicht, dass du das kannst! Danke für den Tipp.

Bearbeiten: Mir ist nicht einmal in den Sinn gekommen, dass ich es im laufenden Betrieb auf den Bildschirm schreiben sollte, anstatt die Zeichenfolge zu erstellen und sie dann zu drucken. Das macht einen großen Unterschied. Danke Dennis!

Hierbei wird eine fest codierte Zeichenfolge verwendet, der Inhalt der Zeichenfolge wird jedoch nicht zur Gesamtsumme gezählt (das = "" wird gezählt).

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

Grundsätzlich durchläuft es die Zeichenfolge zeichenweise und prüft jeweils, ob es sich um eine Ganzzahl handelt. Wenn dies der Fall ist, wird die Ganzzahl inkrementiert und in die Ausgabe geschrieben, andernfalls wird das aktuelle Zeichen in die Ausgabe kopiert.

Dadurch wird die fest codierte Zeichenfolge verloren, da s erhöht wird.

Jerry Jeremiah
quelle
1
Ich bin sicher, Sie können einige der includes loswerden und es wird immer noch gut mit gcc kompiliert.
Martin Ender
1
Funktioniert dies mit einer Zeichenfolge, die z 99.
Anatolyg
@ MartinBüttner: Ja, aber dann wäre es kein gültiges C, nur etwas, das zufällig auf gcc funktioniert.
R .. GitHub STOP HELPING ICE
@R .. Das ist bei PPCG generell erlaubt. Ich habe es ziemlich oft gesehen (und später getan), ohne dass sich jemand beschwert hat.
Martin Ender
Ja, und es ist ein allgemeiner Ärger von mir. Die Sprache sollte als "GCC" oder "C auf [bestimmten Bogen / etc. Die Hacks funktionieren zufällig]" oder ähnlich aufgeführt sein, anstatt C, wenn sie nicht wirklich gültig ist C. :-)
R .. GitHub STOP HILFE EIS
5

J (20)

Erwartet, dass die Eingabe in der Variablen gespeichert wird a.

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

Prüfung:

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

(f?) Lex (39)

Datei inc.l:

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

Kompilieren:

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

Lauf:

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

Ich habe dies nicht mit dem Original getestet lex. Kommentare sind willkommen.


quelle
1
Sie können das Trailing löschen,%% da dies kein Benutzercode ist: flex.sourceforge.net/manual/…
Josh
Hey ... ja! Ich habe es versucht, aber ohne nachgestellte Newline und das ist fehlgeschlagen ... dann habe ich nicht versucht, die letzte Newline hinzuzufügen ... ;-) ... dummer Fehler!
3

Emacs - 20 Zeichen

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

Erfordert, dass zu verarbeitender Text im aktuellen Puffer vorhanden ist. Ich habe CM-% hier als ein Zeichen gezählt, da es mit einem Tastendruck eingegeben werden kann, wenn drei Modifikatoren gedrückt gehalten werden.

user16727
quelle
3

GNU sed, 304 (einschließlich 1 für -r Flagge)

Ich habe diese Frage als mögliches Duplikat knapp gewählt, aber das widerspricht vielleicht dem, weil diese Antwort nicht trivial geändert werden kann, um dort zu funktionieren. Mit Abstand die längste Antwort.

Inspiriert von diesem Beispiel aus der sed-Dokumentation , obwohl einige Arbeiten erforderlich waren, um mehrere Zahlen in einer Zeichenfolge zu verarbeiten:

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

Ausgabe:

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

Beachten Sie, dass dadurch vorübergehend _Zeichen eingefügt werden , die zu falschen Ergebnissen führen können, wenn sie _im Eingabestream vorhanden sind . Um dies zu vermeiden, können wir das _im sed-Skript durch ein nicht druckbares Zeichen (z. B. ASCII 0x07 BEL) ersetzen und davon ausgehen, dass der Eingabestream nur druckbares ASCII enthält. Dies scheint gut zu funktionieren, wenn ich es teste.

Digitales Trauma
quelle
3

Schläger 74

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

Lua - 68 Zeichen

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

Erwartet, dass die Eingabe in s gespeichert wird.

AndoDaan
quelle
2

CJam, 67 58 53 48 31 Zeichen

Diese Frage ist wie die schlimmste Frage für CJam. Kein Regex, kein Pattern Matching, kein Ausnahmefang. Aber los geht's (#YOLO)

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

Dieser teilt die Zeichenfolge in eine Gruppe von nur Alphabeten und nur Ziffern auf. Das erhöht jede Ziffer und stickt die beiden Arrays zurück, wobei jeweils ein Element verwendet wird.


Vorherige Lösung:

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

Probieren Sie es hier online aus

Wie es funktioniert:

Die Grundidee besteht darin, das Zeichen weiterhin separat in einer Zeichenfolge zu speichern, wenn es sich um eine Ziffer handelt, und den inkrementierten Wert auf die endgültige Zeichenfolge zu übertragen, sobald ein nicht-stelliges Zeichen angezeigt wird.

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";
Optimierer
quelle
1

Cobra - 88

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

C # - 178 169 157 Zeichen

Dies setzt voraus, dass Zahlen wie 999 auf 000 überlaufen dürfen und dass - +, E nicht Teil einer Zahl sind.

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

Besser lesbare Form:

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

Ich bin neu hier, habe noch nie Code Golf ausprobiert, habe es einfach ausprobiert :)

Ich frage mich, ob jemand Ideen hat, um es noch kürzer zu machen ...

Um mit C # teilzunehmen, wäre es schön, wenn wir alle notwendigen Frameworks um den eigentlichen Code weglassen könnten - dann hätte dies nur 82 Zeichen, und das ohne Aufrufen leistungsfähiger Systemfunktionen.


Das gleiche gilt für Zeiger (182 Zeichen):

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

Jetzt, ohne überzulaufen, wird der 999-Fall (223 Zeichen) korrekt behandelt:

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

Ein anderes älteres, es liest von der Standardeingabe und verwendet Rekursion:

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

Hinweis: Console.ReadKey();und die Zeichenfolge selbst sollte nicht gezählt werden.

Ich habe dies bereits mehrfach verbessert, siehe Kommentare. Es gibt noch Raum für weitere Verbesserungen, würde ich sagen :) Und entschuldigen Sie die Länge, aber ich denke, die verschiedenen Versionen sind interessant genug, um sie beizubehalten ...

maf-soft
quelle
Nein, die "Umgebung" loszuwerden ist nicht erlaubt. Ich rechne mit Ihrem zweiten Code, nachdem if(c==57)Sie c--;stattdessen schreiben konnten c=48;, was ist mit dem ternären Operator? Es gibt tatsächlich viele Golf-Tricks. Vielleicht sollten Sie codegolf.stackexchange.com/questions/2203/tips-for-golfing-in-c
stolzer Haskeller
Danke, ich weiß nichts über Golf :) Alles, was du hier siehst, wurde von mir erfunden ;-) 57-1 ist nicht 48. Also verstehe ich nicht.
Maf-Soft
Ups :-) :-) :-) :-)
stolzer Haskeller
Ich kenne C # nicht wirklich gut, aber ich denke, Sie können einen Operator verwenden, um sie zusammenzuhalten wie... ? ... : c++*b--
stolzer Haskeller
Übrigens, entschuldigen Sie, dass Sie die C-Tipps anstelle der C # -Tipps erhalten haben: codegolf.stackexchange.com/questions/173/…
stolzer Haskeller
1

Groovy, 38 Bytes

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

Uggghhh ... Ich hasse die Worte absolut replaceund allsie ruinieren alle Regex-Golfplätze für mich.

Magische Krakenurne
quelle
1
(it as int)+1it.next()
Manatwork
0

PHP - 91 Bytes

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

Ich wollte keine regulären Ausdrücke verwenden. PHP kann einen String-Offset nicht direkt inkrementieren, daher musste ich beim Inkrementierungsschritt einige Bytes hinzufügen. Dieses einzeilige Skript erinnert mich an ein sehr dunkles Zeitalter des PHP-Skripts ...

Alexandre Teles
quelle
Ich habe gerade beobachtet, dass die Frage Sie auffordert, die Ergebnisnummer einer Folge von Algarismen zu erhöhen. Diese Antwort ist falsch. Aber ich bin wirklich der Meinung, dass die Operation mehr Details darüber hinzufügen sollte, was er will.
Alexandre Teles
0

K, 56

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

sed und bash - 40 (einschließlich Anrufung und Pipes)

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

Ausgänge:

teststring135this 124test string55 101
124test
test124
te124st
test 124 test
mgjk
quelle
Ich habe diesen Teststring ausprobiert: 42;rm -rf /Es hat beim ersten Mal funktioniert.
Dennis
2
Sie können \0zu &(-1 Zeichen), zu (-2 Zeichen) , $((…))zu $[…](-2 Zeichen) wechseln , um Ihren aktuellen Code zu verkürzen . Beheben Sie jedoch besser zuerst den von @Dennis erwähnten Fehler. (Er schrieb „es das erste Mal arbeitete“ für Spaß und als Hinweis auf die Ausgabe Eigentlich Code bei der Eingabe nicht enthalten. , , , Und vielleicht andere Sonderzeichen auch.)s/^/echo /iecho \\;#`…`$(…)
Manatwork
Die Ausführung von willkürlichem Code ist eine Funktion :-)
mgjk
Es gibt möglicherweise keinen Weg, diesen Weg zu gehen, ohne Eingaben einzuschränken und den Code winzig zu halten. Die Art der Lösung besteht darin, die Eingabe zu übersetzen und einen Interpreter zu verwenden, um die Mathematik durchzuführen, da sed dies nicht kann. Sobald die Benutzereingabe einen Interpreter trifft, ist die Flucht verrückt. Kurz vor dem vorherigen sed-Beispiel kann sed nicht rechnen.
mgjk
Etwas kürzer: eval echo `sed 's/[0-9]\+/$[&+1]/g'`- hat immer noch das Problem der Code-Injektion, wie aus meiner Antwort auf eine andere ähnliche Frage hervorgeht. Codegolf.stackexchange.com/a/37145/11259
Digital Trauma
0

Java 7, 119 Bytes

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

Wenn die Anforderung ein Programm statt nur einer Funktion ist, sind es 149 Bytes:

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

Ungolfed & Testcode:

Probieren Sie es hier aus.

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

Ausgabe:

124test
test124
te124st
test 124 test
8teststring135this 124test string60 101
Kevin Cruijssen
quelle
0

Gema, 14 Zeichen

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

Probelauf:

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

DASH , 16 Bytes (nicht konkurrierend)

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

Dies gibt eine Funktion / Teilanwendung zurück.

Verwendung:

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

Erläuterung

rstr[          #. replace any parts of the input
  R "\d+" "g"  #. matching /\d+/g
  +1           #. with its incremented form
]
Mama Fun Roll
quelle
Ist diese Antwort nicht konkurrierend?
Dennis
oh rip :( Ich dachte irgendwie, das wäre eine Katalogfrage.
Mama Fun Roll
0

CJam, 18 Bytes

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

Probieren Sie es hier aus.

Erläuterung

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
quelle
0

R, 83 Bytes

Spät zur Party. Angenommen, die Eingabe wird in einer Variablen gespeichert x. Es wird wahrscheinlich nicht benötigt, um dies regmatcheszu lösen, aber ich konnte keine vektorisierten Ersetzungen ohne externe Pakete herausfinden.

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

Ungolfed und erklärt

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

Beispielausgabe

input: 
"teststring135this 124test string55 101"

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

C # (Visual C # Interactive Compiler) mit Befehlszeilenoption /u:System.Text.RegularExpressions.Regex;System.Int32, 40 Byte

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

Erwartet, dass sich die Eingabe in einer Variablen mit dem Namen n befindet.

Probieren Sie es online aus!

Verkörperung der Unwissenheit
quelle
2
Ungültig, kann keine Eingabe in eine Variable erwarten
ASCII-
@ ascii-only Diese Frage scheint es ausdrücklich zu erlauben, obwohl ich persönlich versuchen würde, mich an die heutigen Eingabestandards zu halten
Jo King
Oh warte: / ew diese Frage
ASCII-nur