Intro
J'ai donc perdu mon temps à rechercher des algorithmes de tri de suffixes, à évaluer de nouvelles idées à la main et dans le code. Mais j'ai toujours du mal à me souvenir du type de mes suffixes! Pouvez-vous me dire de quel type sont mes suffixes?
À gauche quoi?
De nombreux algorithmes de tri des suffixes (SAIS, KA, mon propre daware) regroupent les suffixes en différents types afin de les trier. Il existe deux types de base: type S et de type L suffixes. Les suffixes de type S sont des suffixes qui sont lexicographiquement moins ( S maller) que le suffixe suivant et le type L s'il est lexicographiquement plus grand ( L arger). Un type S le plus à gauche ( type LMS ) n'est que cela: un suffixe de type S précédé d'un suffixe de type L.
La particularité de ces suffixes de type LMS est qu'une fois que nous les avons triés, nous pouvons trier tous les autres suffixes en temps linéaire! N'est-ce pas génial?
Le défi
Étant donné une chaîne, supposons qu'elle se termine par un caractère spécial qui est inférieur à tout autre caractère de cette chaîne (par exemple, plus petit que même l'octet nul). Sortez un caractère corrospondant pour chaque suffixe.
Vous pouvez librement choisir ombles à utiliser pour quel type , mais je préfère L, S and *
pour L-, S- and LMS-type
aussi longtemps qu'ils sont imprimables ( 0x20 - 0x7E
).
Exemple
Étant donné la mmiissiissiippi
sortie de la chaîne (lors de l'utilisation L, S and *
):
LL*SLL*SLL*SLLL
Par exemple, le premier L
est dû au fait qu'il mmiissiissiippi$
est lexicographiquement supérieur à miissiissiippi$
(le $
représente le caractère minimal ajouté):
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$ > $
Quelques exemples supplémentaires:
"hello world" -> "L*SSL*L*LLL"
"Hello World" -> "SSSSL*SSLLL"
"53Ab§%5qS" -> "L*SSL*SLL"
Objectif
Je ne suis pas ici pour ennuyer Peter Cordes (je vais faire ça sur stackoverflow un jour); Je suis juste très paresseux donc c'est bien sûr du code-golf ! La réponse la plus courte en octets l'emporte.
Edit: l'ordre des caractères est donné par leur valeur d'octet. Cela signifie comparer devrait être comme C de strcmp
.
Edit2: Comme indiqué dans les commentaires, la sortie doit être un seul caractère pour chaque caractère d'entrée. Bien que je suppose que cela serait compris comme "renvoyer une chaîne", il semble qu'au moins 1 réponse renvoie une liste de caractères uniques. Afin de ne pas invalider les réponses existantes, je vous permettrai de renvoyer une liste de caractères uniques (ou entiers qui, une fois imprimés, ne donneront que 1 caractère).
Conseils pour le temps linéaire:
- Cela peut être fait en 2 itérations en avant parallèles ou en une seule itération en arrière.
- L'état de chaque suffixe ne dépend que des 2 premiers caractères et du type du second.
- En balayant l'entrée dans le sens inverse, vous pouvez déterminer L ou S comme ceci:
$t=$c<=>$d?:$t
(PHP 7), où$c
est le caractère actuel$d
du type précédent et$t
précédent. - Voir ma réponse PHP . Demain, je décernerai la prime.
c++
chaînes de style. Considérez-le comme des données binaires.*
dire?*
signifie que le suffixe correspondant est de typeleft most s-type
.A S-type suffix that is preceeded by a L-type suffix.
.Réponses:
Haskell ,
64534842 octetsEssayez-le en ligne!
Non golfé, avec
Char
au lieu deInt
:la source
z=
peuvent être supprimées.go
fonction prend deux arguments. Le premier est le caractère qui représente ce qui devrait être utilisé pour décrire laS
situation. Le second est une chaîne. Il parcourt cette chaîne récursivement, en supprimant le premier caractère à chaque étape (c'est ce quitail
fait). L'astuce est que le premier argument est défini sur*
lorsque le résultat précédent était unL
, ouS
autrement. De cette façon, dans le cas où un*
ou unS
doit être utilisé, ce premier argument peut être utilisé directement. J'espère que cela a du sens.Gelée ,
25 23 21 2019 octetsUn programme complet qui imprime la liste des caractères, en utilisant:
(En tant que lien, il retourne une liste où tous les éléments sont des caractères sauf le dernier, qui est un zéro.)
Essayez-le en ligne! ou voir la suite de tests (avec conversion en
LS*
).Comment?
la source
+
les chaînes semblent vectoriser mais les résultats sous-jacents ne sont pas en fait des itérables Jelly mais des chaînes (!) (Par exemple, essayez+@/L€
ou+@/L€€
ou ...)+
produit une chaîne réelle. Il s'agit d'une fonctionnalité non documentée, ou ce que vous appelez un bogue.Python 3,
9287746965 octetsUtilise
0
pourL
,1
pourS
et2
pour*
. Enveloppez la chaîne d'entrée en guillemets; Je pense que cela est autorisé par la convention.Essayez-le en ligne!
Exemple d'utilisation:
économisé 5 octets grâce à Leaky Nun, 4 octets grâce à ovs
la source
JavaScript (ES6),
5145 octets6 octets enregistrés grâce à @Neil.
Une solution récursive à l'exercice.
la source
f=(c,d)=>c&&(d<(d=c<(c=c.slice(1))))+d+f(c,d)
JavaScript (ES6), 52 octets
Port de la réponse de @ L3viathan.
la source
c=1
commec=0
...C (clang) , 88 octets
Essayez-le en ligne!
la source
Haskell ,
7775 octets, temps linéaireEssayez-le en ligne!
Comment ça fonctionne
Cela utilise la récursivité, supprimant un caractère à la fois depuis le début de la chaîne. (Le type de chaîne Haskell est une liste de caractères à liaison unique, donc chacune de ces étapes est à temps constant.)
la source
S, L and *
?[1,1,2,0,1,1,2,0,1,1,2,0,1,1,1]
c'est une liste de nombres à un chiffre, pas une liste de caractères uniques. Dans mon cas, je pense que la sortie d'une liste de nombres ne me ferait pas économiser d'octets.Python 2 ,
6555 octetsVersion récursive, basée sur la réponse de L3viathan , utilisant
012
commeLS*
:Essayez-le en ligne!
Python 3 ,
6559 octetsSolution récursive à l' aide
L
,S
et*
:Exécute la chaîne depuis l'avant et remplace toutes les instances de
LS
avecL*
Essayez-le en ligne!
la source
blah if s else''
→s and blah
enregistre six octets. En Python 2,str(blah)
→`blah`
enregistre trois autres octets sur la deuxième solution.PHP, 82 octets, temps linéaire
Parcourt l'entrée de droite à gauche et remplace chaque caractère par le type.
Calcule le type en fonction du caractère actuel et du caractère précédent (-1 ou 1). Si égal, le type ne change pas.
la source
strtr
PHP , 70 octets
L = 1, S = 0, * = 2
La prise en charge multi-octets est nécessaire pour le dernier cas de test avec les
§
+3 octets à lamb_substr
placesubstr
Essayez-le en ligne!
PHP , 71 octets
L = 1, S = 0, * = 2
Essayez-le en ligne!
PHP , 74 octets
Essayez-le en ligne!
la source
$s=&$argn
Plutot malin ! Je suis quasiment sûr qu'il y a une meilleure réponse cependant;) J'espère que quelqu'un arrivera avec ça :)mb_substr
au lieu desubstr
si l'entrée n'est pas dans la plage ascii simple. Est-il nécessaire de supporter le dernier cas de test?§