Expandir uma sequência codificada

18

Existe a codificação e decodificação clássica do comprimento da execução.

input   output
a3b2c5  aaabbccccc

E isso é bastante direto e feito antes.

O desafio é também responsável por um comportamento não-padrão quando vários caracteres preceder a extensão da execução (um único dígito 0-9). Cada caractere antes do dígito do comprimento da execução (o último dígito antes de um não dígito ou final da sequência) tem esse valor aplicado individualmente e impresso em ordem.

Algumas entradas e saídas de teste, incluindo alguns casos extremos:

input   output
ab3c5   aaabbbccccc
a0b3    bbb  
13b1    111b
a13b1   aaa111b
a123b1  aaa111222b
aa2a1b1 aaaaab
  • Uma sequência de caracteres ( [a-zA-Z0-9]+) deve ser seguida pelo comprimento da execução ( [0-9])
  • Somente entradas válidas precisam ser consideradas ( ([a-zA-Z0-9]+[0-9])*)
    • sim, uma string vazia é uma entrada válida.
  • Entrada é via entrada padrão, saída via saída padrão

Este é o código golf, o número de bytes determina o vencedor.


fonte
@AlexA. Corrigir. Há alguns esolangs que eu gosto de ver de tempos em tempos que são penalizados pela contagem de bytes. (Eu certamente estou aberto a sugestões sobre por que isso pode ser um erro para contar dessa maneira) #
4
@MichaelT A pontuação por caracteres incentiva fortemente a compactação do código-fonte no UTF32, que permite a codificação de até 4 bytes por caractere, mas é completamente ilegível.
Isaacg
@isaacg fair 'nuff. Vou editar para mudar para bytes. Vou pensar em uma maneira de expressar o estilo do sclipting para ser aceitável para desafios futuros.
Nossa submissão deve ser concluída sem erro se a entrada for a string vazia? O consenso sobre a meta é que a saída para STDERR pode ser ignorada, mas desde que você a mencionou explicitamente, tenho que perguntar.
Dennis
@ Dennis uma string vazia como a entrada deve, deve parar. Não deve entrar em um loop infinito ou imprimir outro texto na saída padrão.

Respostas:

3

Pip, 22 + 1 = 23 bytes

Usa -rsinalizador. Observe que isso exige que você 1) insira um EOF após a entrada (Ctrl-D no Linux, Ctrl-Z no Windows) ou 2) canalize a entrada de outro lugar.

(^_@<v)X_@vMa@`\D*\d+`

Explicação:

                        a is first line of stdin (from -r flag) and v is -1 (implicit)
              `\D*\d+`  Pattern (regex) object that matches zero or more non-digits
                        followed by at least one digit
            a@          Find all non-overlapping matches in a, returning a list of strings
           M            To that list, map a lambda function:
  _@<v                    Argument sans last character (equivalent to Python a[:-1])
(^    )                   Split into a list of characters
        _@v               Last character of argument
       X                  Repeat each character of the list that many times
                          (String multiplication X, like most operators, works item-wise
                          on lists)
                        Auto-print (implicit)

O resultado da operação do mapa é na verdade uma lista de listas, mas por padrão as listas são simplesmente concatenadas quando impressas, portanto, nenhuma conversão manual em string é necessária.

Exemplo, com entrada a13b1:

Var a gets        "a13b1"
After regex match  ["a13" "b1"]
After map          [["aaa" "111"] ["b"]]
Final output       aaa111b

Pip tem suporte básico a regex a partir de ... 2 dias atrás . Ótimo momento!

DLosc
fonte
Aquele funciona (e o mestre também) com a -rbandeira. (A questão especifica que a entrada tem de vir do STDIN.)
Dennis
@ Dennis Oops, senti falta disso. Adicionado sinalizador para contagem de bytes. Eu deveria ter sido capaz de usar a variável especial em qvez de asem sinalizadores extras, mas parece haver um bug e está solicitando a entrada duas vezes.
DLosc
Finalmente, uma linguagem de golfe com suporte a regex!
Dennis
@ Dennis vejo você mudando para pip agora!
Optimizer
8

Perl / Bash 54 40 + 1 = 41 bytes

perl -pe's:(\D*\d*)(\d):"\$1=~s/./\$&x$2/egr":ege'

É basicamente uma regex dentro de uma regex. E um pouco de mágica.

Explicação

A regex externa /(\D*\d*)(\d)/gextrai cada grupo codificado em toda a execução. Capturamos o material para repetir $1e o número de repetições $2. Agora, substituímos cada um desses grupos pela expansão desse grupo. Para isso, avaliamos o código "\$1=~s/./\$&x$2/egr" duas vezes (como pela /eebandeira na substituição externa).

A primeira avaliação interpola apenas o número de repetições na string - as outras variáveis ​​são protegidas por uma barra invertida. Então, assumindo a entrada a14, agora teríamos o código $1=~s/./$&x4/egr, que será avaliado novamente.

Isso aplicará a substituição ao conteúdo de $1(o material a repetir a1). A substituição corresponde a cada caractere .. A $&variável mantém toda a correspondência, que repetimos x4vezes. Fazemos isso /gglobalmente para cada correspondência e /rretornamos a string substituída em vez de modificar a $1variável (que é somente leitura). Portanto, o resultado da substituição interna é aaaa1111.

A -pbandeira aplica a substituição a cada linha de entrada e imprime o resultado.

amon
fonte
3
É comum pontuar isso como uma solução Perl, onde você adiciona apenas 1 byte ao -pmodificador. Eu conto 45 bytes. Além disso, você deve poder usar em \Dvez de [a-z], o que também eliminou a necessidade i.
Dennis
7

CJam, 33 31 27 bytes

Ughh, a falta de expressões regulares torna isso muito longo ...

qN+{:XA,s&L\:L>{])~e*[}&X}%

Como funciona

Percorremos todos os caracteres da sequência de entrada e, em cada iteração, controlamos o último caractere encontrado (começando com um caractere vazio pela primeira vez). Em seguida, verificamos se o caractere atual não é numérico e o último caractere é numérico. Nesse caso, repetimos cada caractere anterior (que ainda não foi repetido), o número de vezes.

(Uma expansão de código um pouco desatualizada)

q{                       }%        e# Read the input (q) and loop through each character
  L                                e# Put variable L (initially empty character) on stack
   A,                              e# Put variable A (equals 10) and create an array 0..9
     s                             e# Convert the array to string "0123456789"
      &                            e# Do a set intersect b/w previous char and 0-9 string
                                   e# If numeric, it gives 1 char string, otherwise 0
       \:LA,s&                     e# Swap to bring current character on top. Store it in L
                                   e# and do the same set intersect with it
              >                    e# Means we are checking that current char is non-numeric
                                   e# and previous numeric
               {      }&           e# Run this block if above is true
                ])~                e# Wrap everything not already repeated in an array and
                                   e# take out the last character and convert it to integer.
                                   e# This is the run length of the preceding string
                   e*              e# Repeat each character in the string, run length times
                     [             e# Start a new array to help when next run length is found
                        L          e# Restore the current character back on stack to be used
                                   e# in next iteration
                           )~e*    e# The last string-run-length pair is not decoded..
                                   e# So we do that now

Experimente online aqui

Optimizer
fonte
Agradeço a demonstração do problema que o qualificador de bytes causa. Obrigado. Estou pensando um pouco sobre como definir a qualificação de modo que idiomas em que uma única instrução seja um caractere de vários bytes não sejam penalizados por esse estilo de linguagem sem permitir a codificação UTF que você mostrou através da brecha. PS Eu realmente gosto de ver o detalhamento algorítmico que você fornece.
6

rs , 43 71 caracteres

Bem, isso virou muito rapidamente. Números estúpidos ...

(\d)(\D)/\1 \2
+(\w)(\w+?)(\d)(?= |$)/\1\3 \2\3
(\w)(\d)/(\1)^^(\2)
 /

Experimente aqui!

Versão original (não funcionou com entradas como 123):

+(\D)(\D+)(\d)/\1\3\2\3
(\D)(\d)/(\1)^^(\2)

Explicação

A primeira linha coloca espaços entre as execuções que contêm números, por exemplo, se transformando a313em a3 13.

A segunda linha expande continuamente as codificações compactadas como aa5a a5a5.

A terceira linha converte todas as instâncias a5em aaaaausando o operador de repetição .

A última linha remove os espaços.

kirbyfan64sos
fonte
Como ele lida a123b1?
Optimizer
@ Otimizador Não está bem. Eu preciso ajustá-lo um pouco ...
kirbyfan64sos
@Optimizer Fixed.
Kirbyfan64sos
5

Javascript ( ES6 ), 86 83 bytes

alert(prompt().replace(/(.+?)(\d)(?!\d)/g,(a,b,c)=>b.replace(/./g,y=>y.repeat(c))))

Comentado:

alert( // output final result
    prompt(). // take input
    replace(/(.+?)(\d)(?!\d)/g, // replace ungreedy capture group of any characters 
                                // followed by a digit (captured)
                                // and not followed by a digit (negative lookahead)
        (a, b, c)=> // replace with a function
            b.replace(/./g, // replace all characters in b
                y=>y.repeat(c) // with that character repeated c times
            )
    )
)
nderscore
fonte
Não alert(prompt().replace(/(.+?)(\d)(?!\d)/g,(a,b,c)=>Array(c+1).join(b)))fará o mesmo? Tem apenas 71 bytes de comprimento.
Ismael Miguel
@IsmaelMiguel que só funcionaria se houvesse um único caractere antes do dígito. A compreensão da matriz lida com a repetição de cada caractere individualmente.
Ndscore
Tente Array(6).join('12')e ele retornará '1212121212'.
Ismael Miguel
Este funciona: alert(prompt().replace(/(.+?)(\d)(?!\d)/g,(a,b,c)=>Array(-~c).join(b)))(mesmos 71 bytes de comprimento, testado em es6fiddle.net/ia7gocwg )
Ismael Miguel
1
Eu encontrei uma maneira diferente (óbvio) para dizer 3 bytes embora: D
nderscore
4

CJam, 27 25 bytes

r_'A+1>.{64&1$>{])~f*o}&}

Experimente on-line no intérprete CJam .

Como funciona

r_                        e# Read a token from STDIN and push a copy.
  'A+                     e# Append the character A to the copy.
     1>                   e# Discard the first character of the copy.
       .{               } e# For each character C of the input string and the
                          e# corresponding character D of the copy:
         64&              e#   Take the bitwise and of D and 64. This pushes @
                          e#   if D is a letter and NUL if it is a digit.
            1$>           e#   Compare the result to a copy of C. This pushes 1
                          e#   if and only if D is a letter and C is a digit.
               {      }&  e#   If the result was 1, do the following:
                ]         e#     Wrap the stack in an array.
                 )~       e#     Pop and evaluate the last character.
                   f*     e#     Repeat each char in the array that many times.
                     o    e#     Print all characters.
Dennis
fonte
3

Pitão, 33 32 28 bytes

ssmm*vedkPdPcz-hMJf<@zT\=UzJ

Experimente on-line: demonstração ou equipamento de teste

Explicação

Vou explicar o código usando a entrada de exemplo aa1a23b2. Espero que isso seja um pouco mais fácil de seguir do que sem.

                               implicit: z = input string = 'aa1a23b2'
                         Uz    the indices of z: [0, 1, 2, 4, 5, 6, 7]
                  f            filter for indices T, which satisfy:
                   <@zT\=        z[T] < "="
                               this gives us the list of indices [2, 4, 5, 7], 
                               which correspond to digits in z. 
                 J             assignment, J = [2, 4, 5, 7]
               hMJ             increment all element in J: [3, 5, 6, 8]
              -            J   and remove the elements of J:
                                 [3, 5, 6, 8] - [2, 4, 5, 7] = [3, 6, 8]
            cz                 split z at these indices: ['aa1', 'a23', 'b2', '']
           P                   remove last element: ['aa1', 'a23', 'b2']
  m                            map each string d to:
   m     Pd                      map each string k of d-without-last-char to:
     ved                           int(last element of d)
    *   k                          * k
                               this creates [['a', 'a'], ['aaa', '222'], ['bb']]
 s                             sum the lists: ['a', 'a', 'aaa', '222', 'bb']
s                              sum the strings: 'aaaaa222bb'
Jakube
fonte
2

Ruby 73

gets.split(/(\d)(?!\d)/).each_slice(2){|s,i|s.chars.map{|c|$><<c*i.to_i}}

Testes: http://ideone.com/L1fssb

Cristian Lupascu
fonte
2

JavaScript 112

alert(prompt().replace(/.*?\d+/g,function(m){for(i=n=m.length-1,o="";i--;){j=m[n];while(j--)o=m[i]+o}return o}))

martelo de lobo
fonte
2

Python 2.7, 98 bytes

import re
print"".join(c*int(m[-1])for m in 
re.findall(r".+?\d(?!\d)",raw_input())for c in m[:-1])

Isso apenas faz uma pesquisa simples em regex por dígitos que não são seguidos por um dígito e, em seguida, faz a aritmética da string em cada grupo e junta todos eles novamente.

recursivo
fonte
Você pode economizar 2 bytes alternando do Python 2 para o 3. raw_inputtorna-se inputmas printprecisa de parênteses.
Alex A.
É verdade, mas eu prefiro jogar golfe em python 2.7.
recursivo
1

Julia, 105 99 95 87 bytes

s->join([join([string(b)^(int(p[end])-48)for b=chop(p)])for p=matchall(r"\D*\d*\d",s)])

Isso cria uma função sem nome que recebe uma string como entrada a retorna uma string. Para chamá-lo, dê um nome, por exemplo f=s->....

Aqui são usadas duas compreensões de matriz, uma aninhada na outra. A compreensão externa atua em cada correspondência da sequência de entrada contra a expressão regular \D*\d*\d. A compreensão interna repete cada caractere da correspondência de acordo com o dígito à direita. Os elementos da matriz interna são unidos em uma string, portanto a matriz externa é uma matriz de strings. Estes são unidos e retornados.

Em Julia, cadeias de caracteres podem ser tratadas como matrizes de caracteres. No entanto, observe que os tipos Chare Stringem Julia não têm os mesmos métodos definidos; em particular, não existe método para repetição usando^ para caracteres. Isso usa uma solução alternativa complicada:

  • Faça um loop sobre a sequência que omite o último caractere, que é removido usando chop() .
  • Converta o caractere atual em uma sequência usando string() .
  • Converta o dígito à direita, que também é um caractere, em um número inteiro. No entanto, observe que, por exemplo,int('4') não retorna 4. Em vez disso, ele retorna o ponto de código, que neste caso é 52. Assim, podemos subtrair 48 para recuperar o número inteiro real.
  • Repita de string(b)acordo com int(p[end]) - 48.

Exemplos:

julia> f("ab3c5")
"aaabbbccccc"

julia> f("a0b3")
"bbb"

julia> f("13b1")
"111b"
Alex A.
fonte
1

Python 3, 148 144 136 135 Bytes

w,o,r,d=''.join,'',[],[]
for c in input()+' ':
 if'/'<c<':':d+=[c]
 elif d:o+=w(x*int(w(d))for x in r);r=[c];d=[]
 else:r+=[c]
print(o)

Obrigado a Pietu1998 e mbomb007 pelas sugestões.

Python 2, 161 151 147 139 138 Bytes

Talvez hoje tenha sido apenas um longo dia de trabalho, mas não consigo descobrir como jogar isso ..

w,o,r,d=''.join,'',[],[]
for c in raw_input()+' ':
 if'/'<c<':':d+=[c]
 elif d:o+=w(x*int(w(d))for x in r);r=[c];d=[]
 else:r+=[c]
print o
Kade
fonte
3
Mudar para Python 3 economiza alguns bytes ( raw_fora, parênteses para print). len(d)>0pode ser substituído por duma lista vazia ser falsa e uma lista não vazia ser verdadeira. list(...)pode ir direto para o for. Os colchetes w([...])são desnecessários, pois esse é o único argumento. Você pode remover o espaço ) for. Essas são todas as pequenas coisas que inventei até agora.
PurkkaKoodari
@ Pietu1998 Obrigado pela ajuda!
Kade
Sem alterar muito sua abordagem, você pode se livrar, list()pois as strings são iteráveis. Você pode usar w=r=''. Se você estiver disposto a mudar muito, consulte minha solução. :)
recursivo
if c.isdigit()pode se tornar if'/'<c<':', se não me engano.
DLosc
Obrigado @DLosc, isso parece funcionar.
Kade
0

Java 7, 175 bytes

String c(String s){String r="",a[];for(String x:s.split("(?<=(\\d)(?!\\d))")){a=x.split("");for(int i=0,j,l=a.length-1;i<l;i++)for(j=0;j++<new Short(a[l]);r+=a[i]);}return r;}

O desafio é mais difícil do que parece, imo ..

Ungolfed & código de teste:

Experimente aqui.

class M{
  static String c(String s){
    String r = "",
           a[];
    for(String x : s.split("(?<=(\\d)(?!\\d))")){
      a = x.split("");
      for(int i = 0, j, l = a.length-1; i < l; i++){
        for(j = 0; j++ < new Short(a[l]); r += a[i]);
      }
    }
    return r;
  }

  public static void main(String[] a){
    System.out.println(c("ab3c5"));
    System.out.println(c("a0b3"));
    System.out.println(c("13b1"));
    System.out.println(c("a13b1"));
    System.out.println(c("a123b1"));
    System.out.println(c("aa2a1b1"));
    System.out.println(c("123"));
  }
}

Resultado:

aaabbbccccc
bbb
111b
aaa111b
aaa111222b
aaaaab
111222
Kevin Cruijssen
fonte