Introdução
Então, eu perdi meu tempo novamente pesquisando algoritmos de classificação de sufixos, avaliando novas idéias manualmente e em código. Mas sempre luto para lembrar o tipo dos meus sufixos! Você pode me dizer qual é o tipo dos meus sufixos?
Mais à esquerda o que?
Muitos algoritmos de classificação de sufixos (SAIS, KA, meu próprio daware) agrupam sufixos em tipos diferentes para classificá-los. Existem dois tipos básicos: S-tipo e tipo L sufixos. Os sufixos do tipo S são sufixos lexicograficamente menores ( S maller) do que o sufixo a seguir e o tipo L, se for lexicograficamente maior ( L arger). O tipo S mais à esquerda ( tipo LMS ) é exatamente isso: Um sufixo do tipo S precedido por um sufixo do tipo L.
O que há de especial nesses sufixos do tipo LMS é que, quando os classificamos, podemos classificar todos os outros sufixos em tempo linear! Isso não é incrível?
O desafio
Dada uma string, suponha que ela seja finalizada por um caractere especial menor que qualquer outro caractere da string (por exemplo, menor que o byte nulo). Saída de um tipo de caractere corrosivo para cada sufixo.
Você pode escolher livremente qual char para usar para que tipo, mas eu prefiro L, S and *
para L-, S- and LMS-type
contanto que eles são todos de impressão ( 0x20 - 0x7E
).
Exemplo
Dada a mmiissiissiippi
saída da string (ao usar L, S and *
):
LL*SLL*SLL*SLLL
Por exemplo, o primeiro L
se deve ao fato de mmiissiissiippi$
ser lexicograficamente maior que miissiissiippi$
(o $
representa o caractere mínimo adicionado):
L - mmiissiissiippi$ > miissiissiippi$
L - miissiissiippi$ > iissiissiippi$
* - iissiissiippi$ < issiissiippi and preceeded by L
S - issiissiippi$ < ssiissiippi$
L - ssiissiippi$ > siissiippi$
L - siissiippi$ > iissiippi$
* - iissiippi$ < issiippi$ and preceeded by L
S - issiippi$ < ssiippi$
L - ssiippi$ > siippi$
L - siippi$ > iippi$
* - iippi$ < ippi$ and preceeded by L
S - ippi$ < ppi$
L - ppi$ > pi$
L - pi$ > i$
L - i$ > $
Mais alguns exemplos:
"hello world" -> "L*SSL*L*LLL"
"Hello World" -> "SSSSL*SSLLL"
"53Ab§%5qS" -> "L*SSL*SLL"
Objetivo
Não estou aqui para irritar Peter Cordes (vou fazer isso no stackoverflow algum dia); Eu sou apenas muito preguiçoso, então isso é claro, código-golfe ! A resposta mais curta em bytes vence.
Edit: A ordem dos caracteres é dada pelo valor em bytes. Isso significa que comparar deve ser como C's strcmp
.
Edit2: Como indicado na saída de comentários, deve haver um único caractere para cada caractere de entrada. Embora eu tenha assumido que isso seria entendido como "retornar uma string", parece que pelo menos 1 resposta retorna uma lista de caracteres únicos. Para não invalidar as respostas existentes, permitirei que você retorne uma lista de caracteres únicos (ou números inteiros que, quando impressos, resultam em apenas 1 caractere).
Dicas para o tempo linear:
- Isso pode ser feito em 2 iterações para frente paralelas ou em uma única iteração para trás.
- O estado de cada sufixo depende apenas dos 2 primeiros caracteres e do tipo do segundo.
- Digitalizando a entrada na direção inversa, é possível determinar L ou S assim:
$t=$c<=>$d?:$t
(PHP 7), onde$c
é o caractere atual,$d
o tipo anterior e$t
o anterior. - Veja minha resposta em PHP . Amanhã vou premiar a recompensa.
c++
strings de estilo. Pense nisso como dados binários.*
significa isso ?*
significa que o sufixo correspondente é do tipoleft most s-type
.A S-type suffix that is preceeded by a L-type suffix.
.Respostas:
Haskell ,
64534842 bytesExperimente online!
Ungolfed, com em
Char
vez deInt
:fonte
z=
possam ser removidas.go
função leva dois argumentos. O primeiro é o personagem que representa o que deve ser usado para descrever aS
situação. O segundo é uma string. Ele percorre essa sequência recursivamente, removendo o primeiro caractere a cada etapa (é o quetail
ocorre). O truque é que o primeiro argumento seja definido como*
quando o resultado anterior foi aL
ouS
não. Dessa forma, no caso em que um*
ou umS
deve ser usado, esse primeiro argumento pode ser usado diretamente. Espero que isso faça sentido.Geléia ,
25 23 21 2019 bytesUm programa completo que imprime a lista de caracteres, usando:
(Como um link, ele retorna uma lista em que todos os itens são caracteres, exceto o último, que é zero.)
Experimente online! ou veja a suíte de testes (com conversão para
LS*
).Como?
fonte
+
em cordas parece vectorize mas os resultados subjacentes não são realmente Jelly iterables mas cordas (por exemplo, tentar (!)+@/L€
Ou+@/L€€
ou ...)+
produz uma string real. Este é um recurso não documentado, ou o que você chama de bug.Python 3,
9287746965 bytesUsa
0
paraL
,1
paraS
e2
para*
. Quebra a seqüência de entrada em caracteres de aspas; Eu acredito que isso é permitido por convenção.Experimente online!
Exemplo de uso:
economizou 5 bytes graças a Leaky Nun, 4 bytes graças a ovs
fonte
JavaScript (ES6),
5145 bytesGuardado 6 bytes graças a @Neil.
Uma solução recursiva para o exercício.
fonte
f=(c,d)=>c&&(d<(d=c<(c=c.slice(1))))+d+f(c,d)
JavaScript (ES6), 52 bytes
Porto da resposta do @ L3viathan.
fonte
c=1
comoc=0
...C (clang) , 88 bytes
Experimente online!
fonte
Haskell ,
7775 bytes, tempo linearExperimente online!
Como funciona
Isso usa recursão, removendo um caractere de cada vez desde o início da string. (O tipo de sequência Haskell é uma lista de caracteres vinculados individualmente, portanto, cada uma dessas etapas é de tempo constante.)
fonte
S, L and *
?[1,1,2,0,1,1,2,0,1,1,2,0,1,1,1]
é uma lista de números de um dígito, não uma lista de caracteres únicos. No meu caso, acho que a saída de uma lista de números não me salvaria em bytes.Python 2 ,
6555 bytesVersão recursiva, baseada na resposta de L3viathan , usando
012
comoLS*
:Experimente online!
Python 3 ,
6559 bytesSolução recursiva utilizando
L
,S
e*
:Executa a string pela frente e substitui todas as instâncias de
LS
porL*
Experimente online!
fonte
blah if s else''
→s and blah
salva seis bytes. No Python 2,str(blah)
→`blah`
salva outros três bytes na segunda solução.PHP, 82 bytes, tempo linear
Percorre a entrada da direita para a esquerda e substitui cada caractere pelo tipo.
Calcula o tipo dado o atual e o caractere anterior (-1 ou 1). Se igual, o tipo não muda.
fonte
strtr
PHP , 70 bytes
L = 1, S = 0, * = 2
Suporte de vários bytes é necessária para a última Testcase com as
§
+3 Bytesmb_substr
vezsubstr
Experimente online!
PHP , 71 bytes
L = 1, S = 0, * = 2
Experimente online!
PHP , 74 bytes
Experimente online!
fonte
$s=&$argn
bastante inteligente ! Mas tenho certeza de que há uma resposta melhor;) Espero que alguém venha com ela :) #mb_substr
vez desubstr
se a entrada não estiver no intervalo simples de ascii. É necessário suportar o último caso de teste?§