Incrementa cada número en una cadena

11

Dada una cadena que contiene números decimales:

teststring134this 123test string54 100

incremente cada número en esta cadena por uno para dar la nueva cadena

teststring135this 124test string55 101.

La cadena se puede proporcionar como:

  • un argumento de línea de comando
  • STDIN
  • una variable codificada o argumento de función

Cubra todas las posiciones posibles para un número:

  • como prefijo de una palabra; 123test124test
  • como sufijo de una palabra; test123test124
  • dentro de una palabra; te123stte124st
  • solo test 123 testtest 124 test

Aquí hay una solución sin golf 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'))

Esta es una code-golfpregunta, el código más corto gana.

The6P4C
fuente
55
Dato curioso: esto se puede hacer con 3 sustituciones de expresiones regulares puras (sin devoluciones de llamada) stackoverflow.com/questions/12941362/… (sin embargo, esa no sería la forma más elegante)
Martin Ender
44
Especificó entrada pero no salida. De su especificación de entrada, supongo que tanto STDOUT como el valor de retorno están bien. Pero, ¿podemos también almacenar el resultado en una variable codificada (tal como podemos obtener información de él)?
Martin Ender
1
¿Qué hay de llevar? ¿Qué le pasa al 999?
esponjoso
3
posible duplicado de Multiplicar todos los números en una cadena
Digital Trauma
77
¿Qué pasa con los números negativos? ¿Qué pasa con los números con un punto decimal? ¿Qué pasa con los números con un punto decimal y nada antes (excepto quizás por un signo menos)?
Peter Taylor

Respuestas:

23

Perl, 14 bytes

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

Requiere el -pinterruptor, que he contado como un byte.

Ejecución de ejemplo

$ perl -p <(echo 's/\d+/$&+1/ge') <<< 'teststring134this 123test string54 100'
teststring135this 124test string55 101
Dennis
fuente
55
Muy similar a mi respuesta aquí jaja codegolf.stackexchange.com/a/37113/29438
hmatt1
12

Ruby, 30 24 bytes

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

Espera que la entrada se almacene en s.

Martin Ender
fuente
3
¿No se pudo $1.nextusar en el bloque?
Agosto
@August agradable, gracias! No sabía nextque era tan sofisticado.
Martin Ender
11

Vim - 13 pulsaciones de teclas

0qqqqq^Al@qq@q

Espera que la entrada sea la línea actual.

O para un número finito de números (por ejemplo, 999) en 8 + ceil (log (n)) pulsaciones de teclas:

0qq^Alq999@q
coyotebush
fuente
Parece que no puedo hacer que esto funcione ... (Estoy usando vim 7.0.237)
Jerry Jeremiah
10

JavaScript (ES6) - 28

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

Ejecutar usando H("test 123 234t").

soktinpk
fuente
1
Puede eliminar el H=y simplemente hacer que sea una función anónima.
Mama Fun Roll
8

Perl, 23

Asume que la cadena de entrada está asignada a $_

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

Python 2 - 59

Suministrar la cadena como variable n

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

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

Editar: Tanto GCC 4.9.0 (con -std = c99) como Visual C ++ 2013 compilan con éxito (con advertencias) el mismo código sin las inclusiones. ¡No sabía que podías hacer eso! Gracias por la pista.

Editar: Ni siquiera se me ocurrió que debería escribirlo en la pantalla sobre la marcha en lugar de crear la cadena y luego imprimirla. Eso hace una gran diferencia. Gracias Dennis!

Esto está usando una cadena codificada pero el contenido de la cadena no se cuenta hacia el total (se cuenta el = "").

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

Básicamente se ejecuta a través de la cadena un carácter a la vez comprobando cada uno para ver si es un número entero. Si es así, incrementa el número entero y lo escribe en la salida; de lo contrario, copia el carácter actual en la salida.

Esto filtra la cadena codificada porque incrementa s.

Jerry Jeremiah
fuente
1
Estoy seguro de que puedes deshacerte de algunos de los includes y aún se compilará bien con gcc.
Martin Ender
1
¿Funcionará esto con una cadena que contiene, por ejemplo 99?
anatolyg
@ MartinBüttner: Sí, pero no sería una C válida, sino algo que funciona en gcc.
R .. GitHub DEJA DE AYUDAR AL HIELO
@R .. Sin embargo, eso generalmente está permitido en PPCG. Lo he visto (y luego lo he hecho) con bastante frecuencia sin que nadie se queje.
Martin Ender
Sí, y es una molestia general mía. El lenguaje debe aparecer como "GCC" o "C en [arco particular / etc. Los hacks funcionan]] o similar, en lugar de C, si no es realmente válido C. :-)
R .. GitHub STOP AYUDANDO AL HIELO
5

J (20)

Espera que la entrada se almacene en la variable a.

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

Prueba:

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

(f?) lex (39)

Archivo inc.l:

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

Compilar:

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

Correr:

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

No probé esto con el original lex. Comentarios son bienvenidos


fuente
1
Puede dejar el final %%ya que este no es un código de usuario: flex.sourceforge.net/manual/…
Josh
Oye ... si! Lo intenté pero sin seguir la nueva línea y eso falló ... luego no intenté agregar la nueva línea final ... ;-) ... ¡error estúpido!
3

Emacs - 20 caracteres

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

Requiere que se procese el texto para estar presente en el búfer actual. Conté CM-% como un carácter aquí, ya que se puede ingresar con una pulsación de tecla al mantener presionados tres modificadores.

usuario16727
fuente
3

GNU sed, 304 (incluido 1 para el indicador -r)

Voté esta pregunta como un posible duplicado, pero quizás esto sea contrario a eso porque esta respuesta no se puede cambiar trivialmente para que funcione allí. Sin embargo, con mucho, la respuesta más larga.

Inspirado en este ejemplo de la documentación de sed , aunque necesitaba algo de trabajo para manejar múltiples números en una cadena:

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

Salida:

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

Tenga en cuenta esta inserta temporalmente _caracteres, por lo que podría dar lugar a resultados incorrectos si hay _en el flujo de entrada. Como mitigación de esto, podemos reemplazar el _script en el sed con algún carácter no imprimible (por ejemplo, ASCII 0x07 BEL), y asumir que la secuencia de entrada contiene solo ASCII imprimible. Esto parece funcionar bien cuando lo pruebo.

Trauma digital
fuente
3

Raqueta 74

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

Lua - 68 caracteres

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

Espera que la entrada se almacene en s.

AndoDaan
fuente
2

CJam, 67 58 53 48 31 caracteres

Esta pregunta es como la peor pregunta para CJam. Sin expresiones regulares, sin coincidencia de patrones, sin captura de excepciones. Pero aquí vamos (#YOLO)

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

Éste divide la cadena en un grupo de solo alfabetos y solo dígitos. Incrementa cada dígito y une las dos matrices tomando un elemento de cada una a la vez.


Solución previa:

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

Pruébalo en línea aquí

Cómo funciona:

La idea básica es seguir almacenando el carácter por separado en una cadena si es un dígito y volcar el valor incrementado en la cadena final una vez que obtengamos un carácter que no sea un dígito.

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";
Optimizador
fuente
1

Cobra - 88

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

C # - 178 169 157 caracteres

Esto supone que los números como 999 pueden desbordarse a 000 y que - + ,. E no son parte de un número.

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

Mejor forma legible:

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

Soy nuevo aquí, nunca probé el código golf antes, solo lo intenté :)

Me pregunto si alguien tiene ideas para hacerlo aún más corto ...

Para participar con C #, sería bueno si pudiéramos omitir todo el marco necesario alrededor del código real, entonces esto solo tendría 82 caracteres, y eso sin llamar a ninguna función de sistema potente.


Lo mismo con los punteros (182 caracteres):

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

Ahora sin desbordarse, esto maneja correctamente el caso 999 (223 caracteres):

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

Otro más antiguo, se lee desde la entrada estándar y usa la recursividad:

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();y la cadena en sí no debe contarse.

Ya mejoré esto varias veces, ver comentarios. Todavía hay espacio para más mejoras, diría :) Y perdón por la duración, pero creo que las diferentes versiones son lo suficientemente interesantes como para mantenerlas ...

maf-soft
fuente
no, no está permitido deshacerse del "medio ambiente". Calculo en su segundo código después de if(c==57)que podría escribir en c--;lugar de c=48;, ¿qué pasa con el operador ternario también? De hecho, hay muchos trucos de golf. tal vez deberías visitar codegolf.stackexchange.com/questions/2203/tips-for-golfing-in-c
proud haskeller el
Gracias, no sé nada sobre golf :) todo lo que ves aquí fue inventado por mí ;-) 57-1 no es 48. Así que no entiendo.
maf-soft
Oops :-) :-) :-) :-)
proud haskeller
Realmente no conozco bien C #, pero supongo que puedes usar algún operador para unirlos como... ? ... : c++*b--
orgulloso Haskeller el
por cierto, lo siento por enviarle las sugerencias de C en lugar de las sugerencias de C #: codegolf.stackexchange.com/questions/173/…
orgulloso Haskeller
1

Groovy, 38 bytes

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

Uggghhh ... Odio absolutamente las palabras replacey allarruinan todos los campos de golf regex para mí.

Urna de pulpo mágico
fuente
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;

No quería usar expresiones regulares. PHP no es capaz de incrementar directamente un desplazamiento de cadena, por lo tanto, necesitaba agregar algunos bytes en el paso de incremento. Este script de una línea me recuerda una época muy oscura de los scripts PHP ...

Alexandre Teles
fuente
Acabo de observar que la pregunta le pide que incremente el número de resultado de una secuencia de algarismos. Esta respuesta es incorrecta. Pero realmente siento que la operación debería agregar más detalles sobre lo que quiere.
Alexandre Teles
0

K, 56

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

sed y bash - 40 (incluyendo invocación y tuberías)

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

Salidas:

teststring135this 124test string55 101
124test
test124
te124st
test 124 test
mgjk
fuente
Probé esta cadena de prueba: 42;rm -rf /funcionó la primera vez.
Dennis
2
Puede cambiar \0a &(-1 caracteres), $((…))a $[…](-2 caracteres), s/^/echo /a iecho \\(-2 caracteres) para acortar su código actual . Sin embargo, corrige mejor el error mencionado por @Dennis primero. (Él escribió “Se trabajó la primera vez” para la diversión y como pista sobre el tema En realidad el código de falla en la información que contiene. ;, #, `…`, $(…)Y tal vez otros caracteres especiales también.)
manatwork
La ejecución de código arbitrario es una característica :-)
mgjk
Puede que no haya manera de seguir esta ruta sin algún tipo de restricciones de entrada y mantener el código pequeño. La naturaleza de la solución es traducir la entrada y usar un intérprete para hacer los cálculos, ya que sed no puede hacerlo. Tan pronto como la entrada del usuario llega a un intérprete, el escape se vuelve loco. A falta del ejemplo anterior de sed, sed no puede hacer matemáticas.
mgjk
Algo más corto: sin eval echo `sed 's/[0-9]\+/$[&+1]/g'`embargo, todavía tiene el problema de inyección de código, según mi respuesta a otra pregunta similar 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);}

Si el requisito es un programa en lugar de solo una función, entonces son 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 y código de prueba:

Pruébalo aquí.

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

Salida:

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

Gema, 14 personajes

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

Ejecución de muestra:

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

DASH , 16 bytes (sin competencia)

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

Esto devuelve una función / aplicación parcial.

Uso:

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

Explicación

rstr[          #. replace any parts of the input
  R "\d+" "g"  #. matching /\d+/g
  +1           #. with its incremented form
]
Mama Fun Roll
fuente
¿Es esta respuesta no competitiva?
Dennis
oh rip :( De alguna manera pensé que era una pregunta del catálogo.
Mama Fun Roll
0

CJam, 18 bytes

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

Pruébalo aquí.

Explicación

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

R, 83 bytes

Tarde a la fiesta. Asume que la entrada se almacena en variable x. Probablemente no sea necesario usarlo regmatchespara resolver esto, pero no pude encontrar reemplazos vectorizados sin ningún paquete externo.

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

Desengañado y explicado

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

Salida de ejemplo

input: 
"teststring135this 124test string55 101"

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

C # (compilador interactivo de Visual C #) con opción de línea de comandos /u:System.Text.RegularExpressions.Regex;System.Int32, 40 bytes

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

Espera que la entrada esté en una variable llamada n.

Pruébalo en línea!

Encarnación de la ignorancia
fuente
2
No válido, no se puede esperar la entrada en una variable
solo ASCII el
@ ascii-only Esta pregunta parece permitirlo explícitamente 'aunque personalmente, trataría de cumplir con los estándares de entrada de hoy
Jo King
Oh, espera: ew esta pregunta
solo ASCII el