Incremente cada número em uma sequência


11

Dada uma sequência contendo números decimais:

teststring134this 123test string54 100

incremente cada número dessa sequência em um para fornecer a nova

teststring135this 124test string55 101.

A cadeia pode ser fornecida como:

  • um argumento de linha de comando
  • STDIN
  • um argumento de função ou variável codificado

Cubra todas as posições possíveis para um número:

  • como um prefixo para uma palavra; 123test124test
  • como sufixo para uma palavra; test123test124
  • dentro de uma palavra; te123stte124st
  • sozinho test 123 testtest 124 test

Aqui está uma solução não-golfe no 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 é uma code-golfpergunta, o código mais curto vence.


5
Curiosidade: isso pode ser feito com 3 substituições regex puros (sem chamadas de retorno) stackoverflow.com/questions/12941362/... (que não seria o caminho golfiest embora)
Martin Ender

4
Você especificou entrada, mas não saída. Pela sua especificação de entrada, presumo que STDOUT ee o valor de retorno estão corretos. Mas também podemos armazenar o resultado em uma variável codificada (da mesma forma que podemos extrair informações dela)?
Martin Ender

1
Que tal carregar? O que acontece com o 999?
fluffy


7
E os números negativos? E os números com um ponto decimal? E os números com um ponto decimal e nada antes (exceto talvez por um sinal de menos)?
Peter

Respostas:


23

Perl, 14 bytes

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

Requer a -popção, que contei como um byte.

Exemplo de execução

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

5
Muito semelhante à minha resposta aqui haha codegolf.stackexchange.com/a/37113/29438
hmatt1

12

Ruby, 30 24 bytes

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

Espera que a entrada seja armazenada s.


3
Não pôde $1.nextser usado no bloco?
agosto

@ Agosto agradável, obrigado! Eu não sabia nextque era tão sofisticado.
Martin Ender

11

Vim - 13 pressionamentos de teclas

0qqqqq^Al@qq@q

Espera que a entrada seja a linha atual.

Ou para muitos números finitos (por exemplo, 999) em pressionamentos de tecla 8 + ceil (log (n)):

0qq^Alq999@q

Parece que não consigo fazer isso funcionar .... (Estou usando o vim 7.0.237)
Jerry Jeremiah

10

JavaScript (ES6) - 28

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

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


1
Você pode remover H=e apenas ter uma função anônima.
Mama Fun rolo

8

Perl, 23

Assume que a sequência de entrada está atribuída a $_

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

8

Python 2-59

Forneça a string como a variável 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)

Editar: o GCC 4.9.0 (com -std = c99) e o Visual C ++ 2013 criam com êxito (com avisos) o mesmo código sem as inclusões. Eu não sabia que você poderia fazer isso! Obrigado pela dica.

Editar: nem me ocorreu que eu deveria escrevê-lo na tela em tempo real, em vez de criar a sequência e imprimi-la. Isso faz uma enorme diferença. Graças à dennis!

Isso está usando uma sequência codificada, mas o conteúdo da sequência não é contado no total (o = "" é contado).

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

Basicamente, ele percorre a string, um caractere de cada vez, verificando cada um para ver se é um número inteiro. Se for, ele incrementa o número inteiro e o grava na saída, caso contrário, ele copia o caractere atual para a saída.

Isso vaza a string codificada porque aumenta s.


1
Tenho certeza de que você pode se livrar de alguns dos se includeele ainda será compilado com o gcc.
Martin Ender

1
Isso funcionará com uma string contendo, por exemplo 99?
precisa saber é o seguinte

@ MartinBüttner: Sim, mas não seria C válido, apenas algo que funciona no gcc.
R .. GitHub Pare de ajudar o gelo

@R .. Isso geralmente é permitido no PPCG. Eu já vi (e subseqüentemente) várias vezes sem queixas.
Martin Ender

Sim, e é uma irritação geral minha. O idioma deve estar listado como "GCC" ou "C em [arch particular / etc. Os hacks funcionam]]" ou similar, em vez de C, se não for realmente válido C. :-)
R .. GitHub STOP HELPING ICE

5

J (20)

Espera que a entrada seja armazenada na variável a.

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

Teste:

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

5

(f?) lex (39)

Arquivo inc.l:

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

Compilar:

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

Corre:

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

Não testei isso com o original lex. Comentários são bem-vindos.


1
Você pode descartar o final, %%já que este não é um código de usuário: flex.sourceforge.net/manual/…
Josh

Ei ... sim! Tentei, mas sem rastrear a nova linha e isso falhou ... então não tentei adicionar a nova linha final ... ;-) ... erro estúpido!

3

Emacs - 20 caracteres

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

Requer que o texto a ser processado esteja presente no buffer atual. Contei CM-% como um caractere aqui, pois ele pode ser digitado com um toque de tecla ao pressionar três modificadores.


3

GNU sed, 304 (incluindo 1 para sinalizador -r)

Votei de perto essa questão como uma possível duplicata, mas isso talvez seja contrário a isso, porque essa resposta não pode ser trivialmente alterada para funcionar lá. De longe, a resposta mais longa.

Inspirado neste exemplo da documentação sed , apesar de precisar de algum trabalho para lidar com vários números em uma string:

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

Resultado:

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

Observe que isso insere _caracteres temporariamente ; portanto, isso pode levar a resultados incorretos se houver _no fluxo de entrada. Como uma mitigação disso, podemos substituir o _script sed por algum caractere não imprimível (por exemplo, ASCII 0x07 BEL) e assumir que o fluxo de entrada contém apenas ASCII imprimível. Isso parece funcionar bem quando eu testo.



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 a entrada seja armazenada em s.


2

CJam, 67 58 53 48 31 caracteres

Esta pergunta é como a pior pergunta para CJam. Sem regex, sem correspondência de padrões, sem captura de exceção. Mas aqui vamos nós (#YOLO)

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

Este divide a string no grupo de apenas alfabetos e apenas dígitos. Ele incrementa cada dígito e costura a matriz dois, obtendo um elemento de cada vez.


Solução anterior:

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

Experimente online aqui

Como funciona:

A idéia básica é continuar armazenando o caractere separadamente em uma string, se for um dígito, e despejar o valor incrementado na string final assim que obtivermos um caractere sem 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";

1

Cobra - 88

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

1

C # - 178 169 157 caracteres

Isso pressupõe que números como 999 podem transbordar para 000 e que - +, E não fazem parte de um 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);}}

Melhor forma legível:

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

Eu sou novo aqui, nunca tentei código de golfe antes, apenas tentei :)

Gostaria de saber se alguém tem idéias para torná-lo ainda mais curto ...

Para participar do C #, seria bom se pudéssemos omitir toda a estrutura necessária em torno do código real - isso teria apenas 82 caracteres, e isso sem chamar nenhuma função poderosa do sistema.


O mesmo com ponteiros (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();
    }
}

Agora, sem transbordar, isso manipula corretamente o gabinete 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();
    }
}

Outra versão mais antiga, lê da entrada padrão e usa recursão:

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 a string em si não deve ser contada.

Eu melhorei isso já várias vezes, veja os comentários. Ainda há espaço para mais melhorias, eu diria :) E desculpe pelo tamanho, mas acho que as diferentes versões são interessantes o suficiente para mantê-las ...


não, não é permitido se livrar do "ambiente". i contar em sua segunda código depois if(c==57)que você poderia escrever c--;em vez de c=48;, o que acontece com o operador ternário também. há muitos truques de golfe. talvez você deve visitar codegolf.stackexchange.com/questions/2203/tips-for-golfing-in-c
haskeller orgulhoso

Obrigado, não sei nada sobre golfe :) tudo o que você vê aqui foi inventado por mim ;-) 57-1 não tem 48 anos. Então, eu não entendo.
Maf-soft

Oops :-) :-) :-) :-)
haskeller orgulhoso

Eu realmente não sei C # bem, mas eu acho que você pode usar algum operador para colocá-los juntos como... ? ... : c++*b--
haskeller orgulhoso

btw pena para enviar-lhe as dicas C em vez das dicas C #: codegolf.stackexchange.com/questions/173/...
haskeller orgulhoso

1

Groovy, 38 bytes

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

Uggghhh ... Eu absolutamente odeio as palavras replacee all, elas arruinam todos os golfe regex para mim.


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;

Eu não queria usar expressões regulares. O PHP não é capaz de incrementar diretamente um deslocamento de string, portanto, eu precisava adicionar alguns bytes na etapa de incremento. Este script de uma linha lembra-me de uma idade muito sombria dos scripts PHP ...


Eu observei agora que a pergunta pede para você aumentar o número de resultados de uma sequência de algarismos. Esta resposta está incorreta. Mas realmente sinto que a operação deve adicionar mais detalhes sobre o que ele deseja.
Alexandre Teles

0

K, 56

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

0

sed e bash - 40 (incluindo invocação e tubulações)

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

Saídas:

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

Eu tentei esta sequência de teste: 42;rm -rf /funcionou pela primeira vez.
Dennis

2
Você pode alterar \0para &(-1 char), $((…))para $[…](-2 chars), s/^/echo /para iecho \\(-2 chars) para encurtar seu código atual . No entanto, é melhor corrigir o erro mencionado por @Dennis primeiro. (Ele escreveu “Ele trabalhou pela primeira vez” para se divertir e como dica sobre a questão Na verdade o seu código de falha na entrada contendo. ;, #, `…`, $(…)E talvez outros caracteres especiais também.)
manatwork

Execução de código arbitrário é uma característica :-)
mgjk

Pode não haver maneira de seguir esse caminho sem algum tipo de restrição de entrada e mantendo o código pequeno. A natureza da solução é traduzir a entrada e usar um intérprete para fazer as contas, pois o sed não pode fazê-lo. Assim que a entrada do usuário atinge um intérprete, a fuga é louca. Além do exemplo anterior do sed, o sed não pode fazer contas.
mgjk

Um pouco mais curto: eval echo `sed 's/[0-9]\+/$[&+1]/g'`- ainda tem o problema de injeção de código, de acordo com minha resposta a outra pergunta semelhante 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);}

Se o requisito for um programa em vez de apenas uma função, serão 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 & código de teste:

Experimente aqui.

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

Resultado:

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

0

Gema, 14 caracteres

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

Exemplo de execução:

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

0

DASH , 16 bytes (não competitivo)

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

Isso retorna uma função / aplicativo parcial.

Uso:

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

Explicação

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

Esta resposta não é competitiva?
Dennis

oh rip :( alguma maneira eu pensei que esta era uma questão catálogo.
Mama Fun rolo

0

CJam, 18 bytes

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

Experimente aqui.

Explicação

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 bytes

Tarde para a festa. Assume entrada é armazenado na variável x. Provavelmente não é necessário usá-lo regmatchespara resolver isso, mas não consegui descobrir substituições vetorizadas sem nenhum pacote externo.

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

Ungolfed e explicou

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

Saída de exemplo

input: 
"teststring135this 124test string55 101"

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

0

C # (Visual C # Interactive Compiler) com opção de linha de comando /u:System.Text.RegularExpressions.Regex;System.Int32, 40 bytes

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

Espera que a entrada esteja em uma variável chamada n.

Experimente online!


2
Inválido, não pode esperar entrada em uma variável
somente ASCII em

@ ASCII-only Esta questão parece permitir explicitamente 'embora, pessoalmente, eu tentasse seguir os padrões de entrada de hoje'
Jo King

Oh espera: / ew esta pergunta
somente ASCII
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.