Eu nunca vi esse número antes!

31

Escreva um programa que passa por uma sequência de caracteres não-espaço em branco (você pode assumir que eles são dígitos 0para 9, mas nada na forma como eles devem ser processados depende deste) e adiciona espaços de acordo com as seguintes regras.

  1. Deixe que o token atual seja a sequência vazia e os tokens emitidos anteriormente sejam um conjunto vazio.
  2. Repita os caracteres da sequência. Para cada caractere, primeiro acrescente o caractere ao token atual. Se o token atual ainda não estiver no conjunto de tokens emitidos anteriormente, adicione o token atual a esse conjunto e permita que o novo token atual seja a string vazia.
  3. Se quando você chegar ao final da string, o token atual estiver vazio, envie os tokens emitidos anteriormente na ordem de emissão, separados por um caractere de espaço. Caso contrário, imprima a sequência original literalmente.

Entrada

A entrada para o STDIN deve ser uma sequência de dígitos.

Saída

O programa deve imprimir o resultado conforme especificado na etapa 3.

Amostras

Entradas de Amostra

2015
10101010
4815162342
101010101010
3455121372425
123456789101112131415
314159265358979323846264338327950288419716939937

Saídas de amostra

2 0 1 5
10101010
4 8 1 5 16 2 3 42
1 0 10 101 01 010
3 4 5 51 2 1 37 24 25
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
3 1 4 15 9 2 6 5 35 8 97 93 23 84 62 64 33 83 27 95 0 28 841 971 69 39 937

Isso é código de golfe, portanto, as regras padrão de CG se aplicam. O programa mais curto em bytes vence.

(Solicite esclarecimentos nos comentários. Ainda sou novo nisso. Obrigado!)

Arcturus
fonte
10
4815162342Eu vejo o que você fez lá, irmão .
Fatalize 15/09/15
16
Entrada proposta OEIS: números que são divididos em pelo menos dois segmentos por esse processo.
Martin Ender
3
@IsmaelMiguel O passo 5 (como qualquer outro passo) pode avançar apenas um dígito de cada vez. Assim que tiver 1 0 10 , a próxima iteração encontrará 1(já usada), avançará uma para localizar 10(já usada) e depois avançará para encontrar 101, que é novo e seria 'adicionado'. Ele adicionaria um espaço e você chegaria a um novo 0, que já foi usado, mas está aqui no final da string. Portanto, a saída seria 1 0 10 101 0, que é inválida ( 0é repetida), e o script deve então apenas emitir a string de entrada. Só poderia fazer 1010se 101já tivesse sido usado.
Janus Bahs Jacquet
3
@kasperd O número If a unique number cannot be formed at the end of the string, then the input should be printed verbatim10101010 não pode ser dividido, portanto é impresso como está.
edc65 15/09/2015
1
Mas quando você insere a etapa 5, o espaço será posterior a 1, o que seria uma repetição. Então, em vez disso, você move para a direita no espaço 5, depois move para a direita novamente na etapa 4 e entra na etapa 5 novamente e cria 101.
Peter Taylor

Respostas:

9

Pitão, 22 bytes

 faW!}=+kTYY~kdz?tkzsY

O espaço de liderança é importante.

orlp
fonte
13

Retina , 68 61 bytes

+`\b(\w+?)(?<!\b\1 .*)(\w+)$
$1 $2
(?=.* (.+)$(?<=\b\1 .+)) 
<empty>

<empty>é uma linha vazia. Observe o espaço à direita na linha 3. Você pode executar o código acima a partir de um único arquivo com o -ssinalizador.

Explicação

+`\b(\w+?)(?<!\b\1 .*)(\w+)$
$1 $2

Esta primeira etapa implementa as regras 1 a 6. É uma substituição de regex aplicada repetidamente até que a string pare de mudar ( +é para isso que serve). Em cada etapa, adicionamos um único espaço à string da esquerda para a direita (seguindo as regras do desafio). O regex corresponde à sequência mais curta de dígitos que não apareceu na parte já processada da sequência. Garantimos que estamos analisando um prefixo da cadeia restante com a palavra limite \be verificando se podemos chegar ao final da cadeia sem passar espaços com (\w+)$. O último também garante que realizamos apenas uma substituição por etapa.

(?=.* (.+)$(?<=\b\1 .+)) 
<empty>

Isso corresponde a qualquer espaço (que está no final da regex), desde que o último segmento da string seja igual a qualquer outro segmento da string e os substitua pela string vazia. Ou seja, desfazemos a primeira etapa se ela resultou em um segmento final inválido, implementando a regra 7.

Martin Ender
fonte
11

Pyth, 24 23 bytes

VzI!}=+kNYaY~k"";?kzjdY

Experimente aqui .

VzI!}=+kNYaY~k"";?kzjdY    Implicit: z=input(), k='', Y=[], d=' '
Vz              ;          For N in z:
     =+kN                    Append N to k
  I!}    Y                   Is the above not in Y?
          aY k               Append k to Y
            ~k""             After append, reset k to ''
                 ?k        Is k truthy (i.e. not '')
                   z       Print original input
                    jdY    Otherwise print Y joined on spaces

Obrigado a @FryAmTheEggman por salvar um byte: o)

Sok
fonte
@FryAmTheEggman uma boa chamada, fiquei muito apanhados na tentativa de preservar o valor original de k
Sok
8

Python 3, 92 bytes

i,n,*o=input(),""
for c in i:n+=c;o,n=[o+[n],o,"",n][n in o::2]
print([" ".join(o),i][n>""])

Basicamente, uma versão altamente golfe da solução da @ Willem.

orlp
fonte
[" ".join(o),i][n>""]
FryAmTheEggman 15/09/2015
@FryAmTheEggman Ah legal, eu tentei com isso, bool(n)mas não pensei nisso n>"".
orlp
6

Python 3, 100 99 bytes

o=[];n="";i=input()
for c in i:
 n+=c
 if not n in o:o.append(n);n=""
print(i if n else" ".join(o))
Willem
fonte
2
Corrigi sua contagem de bytes. Além disso, você deve remover o espaço de else ".
mbomb007
1
Alguns golfe comuns Além disso, acho que sua pontuação original era de 100 bytes.
FryAmTheEggman 15/09/2015
Legal obrigado! Eu não sabia que o espaço após "else" poderia ser removido. Outro dia vivido, mais um dia aprendeu :)
Willem
5

Braquilog , 91 bytes

:_:_{h:0<|bhN,?hh:NrcH,?hB(l1,-1=A;BbA),?rhL:I(mH:Ar:[L]c:1&;:[H]:\"~w \"w,L:[H]c:_:Ar:1&)}

Isso me fez perceber que há muitas coisas sobre a sintaxe que preciso mudar ...

Explicação

:_:_              § Creates a list [Input,[],[]] 
{...}             § Define a new predicate between the brackets and call it with the previous list as input
h:0<              § If the head of the input is negative, stop
|                 § Else
bhN,              § Second element of Input is called N
?hh:NrcH,         § N concatenated with the first element of Input is H
?hB(l1,-1=A;BbA), § Remaining digits A are either -1 if there's only one digit left or all the digits but the head otherwise
?rhL:I            § List of used integers is called L
(
   mH:Ar:[L]c:1&  § If H is already in L, call the predicate with input [A,H,L]
   ;              § Else
   :[H]:\"~w \"w, § Print H followed by a space
   L:[H]c:_:Ar:1& § Call the predicate with input [A,[],M] where M is L with H appended to it
)
Fatalizar
fonte
4

CJam, 26 bytes

LLq{+_a2$&{a+L}|}/:X+X!S**

Teste aqui.

Explicação

L        e# Push an empty array to keep track if the previous segments.
L        e# Push an empty array to build the current segment.
q{       e# For each character in the input...
  +      e#   Add it to the current segment.
  _a2$&  e#   Duplicate and check if it's already in the segment list.
  {      e#   If not...
    a+L  e#     Add it to the list and push a new empty array for the next segment.
  }|
}/
:X+      e# Store the trailing segment in X and add it's *characters* to the list.
         e# For valid splittings, this trailing segment will be empty, so that the
         e# list remains unchanged.
X!       e# Push X again and take the logical NOT.
S*       e# Get that many spaces, i.e. 1 for valid segments and 0 otherwise.
*        e# Join the list with this string between elements.
Martin Ender
fonte
3

JavaScript (ES6), 109

Meu formato de saída não é exatamente o mesmo dos exemplos de saída na questioin (existe um espaço à esquerda). Não vejo isso como uma falha, pois o formato de saída não está especificado (apenas O programa deve imprimir o número após o número ... )

Teste a execução do snippet abaixo em um navegador compatível com EcmaScript 6. Desenvolvido com Firefox, testado e em execução no Chrome mais recente.

/* Test: redirect console.log */ console.log=x=>O.innerHTML+=x+'\n';

F=s=>{for(z=s,b=l=o=' ';s[+l];)~o.search(b+(n=s.slice(0,++l)+b))||(s=s.slice(l),o+=n,l=0);console.log(s?z:o)}

/* Test cases */
test = [
  '2015',
,'10101010'
,'4815162342'
,'101010101010'
,'3455121372425'
,'123456789101112131415'
,'11312123133'
,'314159265358979323846264338327950288419716939937']

test.forEach(t=>{console.log('\n'+t);F(t)})
<pre id=O></pre>

edc65
fonte
2

GNU sed, 83 77 73 71 bytes

(Marque um extra porque exigimos -rsinalização)

h
s/./&_/
:
/(\b[^ ]+).*\b\1_/{
s/_(.)/\1_/
t
g
}
s/_(.)/ \1_/
t
s/_//

O loop interno testa uma sequência repetida e acrescenta caracteres conforme necessário até que um número exclusivo apareça após o separador _. O loop externo se move _.

Versão anotada e expandida:

#!/bin/sed -rf

# Stash original in hold space
h

# Add separator
s/./&_/

:
# If current candidate is a duplicate, ...
/(\b[^ ]+).*\b\1_/{
#  ...then attempt to lengthen it ...
s/_(.)/\1_/
# ... and repeat if we succeeded, ...
t
# ... otherwise, restore original string
g
}
# Insert a space, and move our separator along
s/_(.)/ \1_/
t

# Remove the separator if we still have it
s/_//
Toby Speight
fonte
Você pode combinar os dois tem um.
precisa saber é o seguinte
Também /((\b[^ ]+).*\b\2)_/{pode ser reescrito como /(\b[^ ]+).*\b\1_/{, sem motivo para 2 grupos de captura.
precisa saber é o seguinte
Não tem problema :), você precisa alterar a referência \1!
usar o seguinte comando
1

Ruby, 57 + 1 = 58 bytes

s=''
l={}
$_.chars{|c|l[s<<c]||=s=''}
l[s]||$_=l.keys*' '

Usa o sinalizador da linha de comando -p(ou plse sua entrada tiver uma nova linha à direita). Explora várias características dos dicionários Ruby Hash: você pode alterar com segurança a string usada para definir uma chave sem alterar a chave (que não funciona para outros tipos mutáveis), .keysretorna as chaves na ordem em que foram inseridas e o []||=operador fornece uma maneira concisa de ramificar se uma determinada chave já está lá.

histocrata
fonte
1

Haskell, 105 bytes

f faz isso.

e""s""=unwords s
e t s""=concat s++t
e t s(c:r)|t&c`elem`s=e(t&c)s r|0<1=e""(s&(t&c))r
a&b=a++[b]
f=e""[]
Leif Willerts
fonte
1

PHP - 148 bytes

Desafio legal, muita diversão!

$x=fgets(STDIN);$w=array();$k='';$l='';for($i=0;$i<strlen($x);$i++){$k.=$x[$i];if(!isset($w[$k])){$l.=$k.' ';$w[$k]=1;$k='';}}echo strlen($k)?$x:$l;

fonte