Praming Puzles & Colf: condensar uma corda

25

Tendo passado algum tempo neste site, passei a gostar de coisas o mais curtas possível. Essa pode ser a razão pela qual recentemente me ofendi com seqüências contendo os mesmos caracteres mais de uma vez. Seu trabalho é escrever uma função ou programa que condense uma determinada sequência de acordo com as seguintes regras:

  • Comece com uma condensação 0 , ou seja, procure o primeiro par (mais à esquerda) dos mesmos caracteres com 0 outros caracteres entre eles. Se esse par for encontrado, remova um dos dois caracteres e reinicie o algoritmo executando outra condensação 0 . Se nenhum par for encontrado, continue com a próxima etapa. Exemplos:
    programming-C0-> programing
    aabbcc-C0-> abbcc
    test-C0->test

  • Em seguida, execute uma condensação 1 , ou seja, procure o primeiro par de caracteres iguais com 1 outro caractere entre eles. Se esse par for encontrado, remova um deles e todos os caracteres entre eles e reinicie com uma condensação 0 . Se nenhum par for encontrado, continue com a próxima etapa. Exemplos:
    abacac-C1-> acac
    java-C1->ja

  • Continue com uma condensação 2 e assim por diante até uma condensação n, com n sendo o comprimento da corda original, reiniciando cada vez que uma condensação remove algumas letras. Exemplos:
    programing-C2-> -C3- praming
    abcdafg>afg

A sequência resultante é chamada condensada e contém cada caractere no máximo uma vez.


Entrada:

Uma sequência minúscula de caracteres ascii imprimíveis.

Saída:

o corda condensada de acordo com as regras acima.

Exemplos:

examples     -> es
programming  -> praming
puzzles      -> puzles
codegolf     -> colf
andromeda    -> a
abcbaccbabcb -> acb
if(x==1):x++ -> if(x+
fnabnfun     -> fun
abcdefae     -> abcde

Exemplos detalhados para esclarecer como o algoritmo funciona:

fnabnfun -C0-> fnabnfun -C1-> fnabnfun -C2-> fnfun -C0-> fnfun -C1-> fun -C0-> fun 
 -C1-> fun -C2-> ... -C8-> fun

abcbaccbabcb -C0-> abcbacbabcb -C0-> abcbacbabcb -C1-> abacbabcb -C0-> abacbabcb 
 -C1-> acbabcb -C0-> acbabcb -C1-> acbcb -C0-> acbcb -C1-> acb -C0-> acb 
 -C1-> ... -C12-> acb

Sua abordagem não precisa implementar o algoritmo de cima, desde que sua solução e o algoritmo retornem a mesma saída para todas as entradas permitidas. Este é um desafio do .


Obrigado a @Linus pelos comentários úteis sobre o sandbox!

Laikoni
fonte
@MartinEnder O caso de teste de Riley ainda é necessário, porque é o único em que minha solução Retina não funciona.
mbomb007
@ mbomb007 Ah, entendo. Bom ponto.
Martin Ender
A sequência de entrada conterá caracteres não imprimíveis, como espaços?
mbomb007
@ mbomb007 Não, assumir apenas caracteres ascii imprimíveis é bom.
Laikoni 27/09/16
@ mbomb007 No entanto, até onde eu sei, um espaço é considerado um caractere ASCII imprimível, por exemplo, aqui .
Laikoni 27/09/16

Respostas:

6

JavaScript (ES6), 74 bytes

f=
(s,n=0,m=s.match(`(.).{${n}}\\1`))=>s[n]?m?f(s.replace(...m)):f(s,n+1):s
;
<input oninput=o.textContent=f(this.value)><pre id=o>

Neil
fonte
Muito bom, mais curto do que aquilo que eu teria pensado.
ETHproductions
5

Perl, 38 31 30 29 bytes

Isso deve deixar para trás os idiomas não relacionados ao golfe ...

-1 por $-[0]agradecimentos a Riley

-1 por @{-}agradecimentos a Dada

Inclui +1 para -p

Dê entrada no STDIN

condense.pl:

#!/usr/bin/perl -p
s/(.)\K.{@{-}}\1// while/./g

Esta versão de 27 bytes deve funcionar, mas não porque o perl não interpola @-em uma regex (consulte /programming/39521060/why-are-etc-not-interpolated-in-strings )

#!/usr/bin/perl -p
s/(.)\K.{@-}\1// while/./g
Ton Hospel
fonte
Como a @{\@-}peça funciona? Eu pensei que @-mantinha os índices de cada partida, então como "conta" em todas as iterações. Além disso, se você imprimir @{\@-}antes e após cada substituição só vez imprime 1 ou 2.
Riley
1
@Riley O /./gprogresso progride em 1 na cadeia de caracteres a cada vez, exceto quando a cadeia é alterada, e é redefinida para 0. Se você imprimir @-após o /./ganterior, mas antes de s///ver a subida (use um teste em que o restante da cadeia seja grande o suficiente)
Ton Hospel 27/09/16
A impressão $-[0]fornece os números que eu esperaria. Funciona @{\@-}como $-[0]por causa do contexto regex, mas não ao imprimir por algum motivo? $-[0]é um byte mais curto do que @{\@-}se for o mesmo.
Riley
"@{\@-}"não é o mesmo que @{\@-}(sem ").
Riley
@Riley Não, mas "@{\@-}"é o mesmo que "@-". E isso também deve ser verdade para uma substituição de regex, mas não é. Simularmente $-[0]deve funcionar, mas não funciona. PS: contexto escalar Você provavelmente de alguma forma tinha aplicado para @-quando você fez a sua impressão, assim você sempre tem 1 ou 2
Ton Hospel
3

CJam , 35 bytes

rL{_,{{(_@_@#I={I)>]sj}*}h]s}fI}j

Experimente online!


rL{                            }j   | run recursion on input
   _,{                      }fI     | for I from 0 to length(input)
      {                 }h]s        | one pass & clean up
       (_@                          | slice and store leading element A
          _@#I={      }*            | if next A is I steps away
                I)>                 | slice off I+1 element
                   ]sj              | clean up & recursion

Você pode ver as condensações individuais inserindoed

Linus
fonte
2

Python 2, 117 104 101 bytes

Recursivamente, faça as substituições necessárias. Eu construo o regex dinamicamente.

import re
def f(s,i=0):t=re.sub(r"(.)%s\1"%("."*i),r"\1",s);e=s==t;return i>len(t)and t or f(t,i*e+e)

Experimente online

mbomb007
fonte
As duas linhas de retorno pode ser condensado em return i>len(t) and t or s!=t and f(t) or f(t,i+1)um líquido de bytes -4
Quelklef
Outros 2 bytes podem ser removidos alterando-os parareturn t if i>len(t)else s!=t and f(t)or f(t,i+1))
Quelklef
Ainda mais e=s==t;return i>len(t)and t or f(t,i*e+e)depois, você pode remover o i=0na definição de função, mas precisará chamar com 0 start.
Quelklef 26/09/16
Eu vou assumir que os quatro espaços estão lá não porque você está usando quatro espaços, mas porque o SE os expande automaticamente. Se não for esse o caso, você poderá alterar todos os seus espaços para tabulações ou um espaço único para -9 bytes.
Fund Monica's Lawsuit
@Quelklef A meta proíbe a tomada de parâmetros adicionais.
mbomb007
1

Perl 53 52

Inclui +1 para -p

for($i=0;$i<length;){$i=(s/(.).{$i}\1/\1/)?0:$i+1;}

Experimente em ideone .

Riley
fonte
1

Mathematica, 101 bytes

NestWhile[i=0;StringReplace[#,a_~~_~RepeatedNull~i++~~a_:>a,1]&,#,SameQ,2,ByteCount@#]&~FixedPoint~#&

Deve haver uma maneira de tornar isso mais curto ...

JungHwan Min
fonte
1

PHP, 90 bytes

for($s=$argv[$c=1];$s[$i=++$i*!$c];)$s=preg_replace("#(.).{{$i}}\\1#","$1",$s,1,$c);echo$s;

ou 92 bytes

for($s=$argv[1];$s[$i];$i=++$i*!$c)$s=preg_replace("#(.).{".+$i."}\\1#","$1",$s,1,$c);echo$s;   
Jörg Hülsermann
fonte
1
1) primeira versão: em +$ivez de $i+=0(-2). 2) forloop em vez de whilepode salvar dois bytes e permitir remover curvas (-4). 3) em $i=++$i*!$cvez de $i=$c?0:$i+1(-1). 4) \\2não é necessário, remova os parênteses (-2). 5) Você pode permitir limite em 9vez de 1velocidade (+0)
Titus
@Titus idéias muito boas. Eu não vi isso Obrigado
Jörg Hülsermann
Agora que penso novamente ... +$inão funciona em todos os casos. Tente hammer. O PHP não reclama das chaves vazias no regex; mas não corresponde ao desejado. A propósito: conto 91, não 90. Mas tente o novo 1)for($s=$argv[$c=1];$s[$i=++$i*!$c];)
Tito
@ Titus Sim, na verdade eu volto $i+=0e tentarei sua proposta mais tarde. O que significa com martelo?
Jörg Hülsermann
@ Titus ok, o mesmo problema, se puzzleou algo assim, (.)//1mas está tudo bem com a sua proposta ou com o$i´=0
Jörg Hülsermann
1

Ruby, 75 64 57 bytes

(56 bytes de código + p opção de linha de comando.)

Usando a interpolação de cadeia de caracteres dentro de uma regex para controlar o comprimento das correspondências que são substituídas.

i=0
~/(.).{#{i}}\1/?sub($&,$1)&&i=0: i+=1while i<$_.size

Teste:

$ ruby -p condense.rb <<< fnabnfun
fun
daniero
fonte
1

Haskell , 97 88 bytes

(0?)
(a:s)!(b:t)|a==b=a:t|1<3=a:s!t
s!_=s
m?s|length s<m=s|a<-s!drop m s=sum[m+1|a==s]?a

Experimente online!


Bersão antiga de 97 bytes:

(a:s)!(b:t)|a==b=a:t|1<3=a:s!t
s!_=s
m?s|length s==m=s|a<-s!drop m s=(last$0:[m+1|a==s])?a
c=(0?)

Experimente em ideone .

Explicação:

(a:s)!(b:t)|a==b = a:t         --perform condensation
           |1<3  = a:s!t       --recursively compare further
 s   ! _         = s           --no condensation performed

A (!)função executa uma n-condensação quando uma string é dada uma vez inteira e uma vez com os primeiros n caracteres removidos, por exemplo, abcdbee cdbepara uma 2-condensação, comparando recursivamente os dois caracteres iniciais.

m?s|length s==m   = s         --stop before performing length-s-condensation
   |a <- s!drop m s           --a is the m-condensation of s
    = (last$0:[m+1|a==s])?a   --disguised conditional:
                              -- if a==s       if the m-condensation did not change s
                              -- then (m+1)?a  then perform m+1-condensation
                              -- else 0?a      else restart with a 0-condensation

c=(0?)                        -- main function, initialise m with 0
Laikoni
fonte