Monday Mini-Golf: Une série de courts défis de golf à code , affichés (espérons-le!) Tous les lundis.
De nombreuses applications Web (en particulier les médias sociaux) tronquent automatiquement de longs passages de texte afin qu'ils tiennent dans le formatage de l'application. Dans ce défi, nous allons créer un algorithme pour couper automatiquement un passage de texte à une certaine longueur.
Défi
L'objectif du défi est d'écrire un programme ou une fonction qui accepte deux arguments:
- T , le texte à tronquer.
- L , la longueur maximale à retourner.
Et renvoie T , tronqué avec la logique suivante:
- Si la longueur de T est inférieure ou égale à L , aucune troncature n'est nécessaire. Renvoie la chaîne d'origine.
- Tronquer T à la longueur L -2. Si celui-ci ne contient ni espaces ni tirets, renvoyez T tronqué à exactement L -3 caractères, suivi d'une ellipse
...
. - Sinon, coupez la fin du résultat jusqu'au dernier espace ou trait d'union. Ajoutez des points de suspension
...
et renvoyez le résultat.
Détails
- T et L peuvent être pris dans n'importe quel ordre et dans n'importe quel format.
- Vous pouvez supposer que 3 < L <2 31 .
- Vous ne pouvez pas utiliser les points de suspension horizontaux U + 2026
…
; vous devez utiliser trois périodes. - L'entrée ne commencera pas par un espace ou un trait d'union.
- L'entrée ne contiendra aucun espace autre que des espaces réguliers. (Pas d'onglets, de nouvelles lignes, etc.)
Cas de test
Contributions:
"This is some very long text." 25
"This-is-some-long-hyphen-separated-text." 33
"Programming Puzzles & Code Golf is a question and answer site for programming puzzle enthusiasts and code golfers." 55
"abcdefghijklmnopqrstuvwxyz" 20
"a b c" 4
"Very long." 100
Les sorties:
"This is some very long..."
"This-is-some-long-hyphen..."
"Programming Puzzles & Code Golf is a question and..."
"abcdefghijklmnopq..."
"a..."
"Very long."
(Notez que les guillemets sont juste pour spécifier qu'il s'agit de chaînes; elles n'ont pas besoin d'être incluses.)
Notation
Il s'agit de code-golf , donc le code valide le plus court en octets l'emporte. Tiebreaker va à la soumission qui a atteint son nombre d'octets final en premier. Le gagnant sera choisi lundi 5 octobre prochain. Bonne chance!
Edit: Félicitations à votre gagnant, @Jakube avec Pyth à nouveau, avec 25 octets!
Réponses:
Pyth, 25 octets
Essayez-le en ligne: démonstration ou suite de tests
Explication:
la source
Perl,
695952 octetsCode de 51 octets + ligne de commande de 1 octet. Suppose que l'entrée numérique peut être donnée avec le paramètre -i.
Usage:
la source
Python 2,
7873 octetsLe format d'entrée suit l'exemple d'entrée.
la source
JavaScript (ES6),
123786761 octetsJe ne m'attendais pas à pouvoir réduire cela autant, mais il s'avère que le combo épissage / remplacement est capable de couvrir tous les cas où la troncature est nécessaire.
Le premier argument est la chaîne, le second est la longueur. Un merci spécial à edc65 pour l'optimisation du contrôle de longueur!
Voici le code d'origine (123 octets):
la source
.length
de vérifier la longueur d'un(T,L)=>T[L]?T.slice(0,L-2).replace(/([ -][^ -]*|.)$/,'...'):T
score de chaîne 61[ -][^ -]
par\s\S
pour économiser 5 octets supplémentairesTI-BASIC, 87 octets
TI-BASIC n'a pas beaucoup de commandes de manipulation de chaînes, nous devons donc trouver le dernier index manuellement: si la chaîne ne contient pas la chaîne à rechercher,
inString(
renvoie 0. Nous recherchons des tirets et des espaces à partir de chaque position à partir de 1 àL
et enregistrer le plus grand nombre inférieur ou égal àL-3
. Si ce nombreI
est toujours 0, nous utilisonsL-3
à la place comme index de fin.En raison des limites de la calculatrice, le plus grand index adressable d'une chaîne est 9999; par conséquent, cela échouera pour les chaînes plus grandes.
Je compte sur le comportement de la calculatrice pour initialiser automatiquement la variable
I
à 0, donc supprimezI
ou effacez la mémoire de votre calculatrice avant de l'exécuter.la source
C # .NET,
187169 octetsHmm ...
la source
Python 2, 105 octets
Appelé avec
la source
Groovy, 95 octets
Assez simple, peut probablement être joué plus loin
la source
CJam, 34 octets
Essayez-le en ligne: Chrome | Firefox
la source
T-SQL, 145 octets
usage:
exec a("This is some very long text.", 25) exec a("This-is-some-long-hyphen-separated-text.", 33)
la source
rs , 116
Au moins, c'est plus court que C # ...
Démonstration en direct et cas de test.
la source
Ceylan
386333252230222216171153131 131111Original non golfé:
Cela représente 386 octets / caractères. Quelques fonctionnalités intéressantes ici:
La
x[y:z]
syntaxe est du sucre syntaxique pourx.measure(y, z)
, et renvoie une sous-plagex
commençanty
par la longueurz
- pour les chaînes, il s'agit d'une sous-chaîne. (Il existe également unex[y..z]
syntaxe, qui est une plage allant de l'index y à z, tous deux inclus, ainsi que des plages semi-ouvertesx[...z]
etx[y...]
.)List.lastIndexWhere
prend un prédicat (ie une fonction prenant un élément de liste et retournant un booléen, ie ici unCallable<Boolean, [Character]>
), et donne l'index du dernier élément de liste où le prédicat est rempli (ou nul, s'il n'est jamais rempli). Comme les chaînes sont des listes, cela fonctionne aussi pour les chaînes.Le résultat de ceci,
spaceIndex
est de typeInteger|Null
, ouInteger?
pour faire court - c'est-à-dire qu'il peut être soit un entier ounull
(la seule valeur de typeNull
). (Le nomspaceIndex
vient de quand je ne savais pas que-
c'était aussi spécial - je suppose que cebreakIndex
serait mieux.)Avec
exists spaceIndex
nous pouvons vérifier sispaceIndex
est non nul et faire quelque chose de différent alors. (À l'intérieur de ce bloc if, le compilateur sait qu'il n'est pas nul ... sans cela il se serait plaint si j'avais l'habitudespaceIndex
d'accéder à la chaîne.)Au lieu de la fonction locale,
spacePredicate
nous pouvons également utiliser une fonction anonymeCela nous amène à 333 caractères:
La prochaine optimisation consiste à utiliser des noms de variables et de fonctions plus courts, ce qui nous ramène de 81 octets à 252:
La fonction prédicat n'a pas besoin de déclarer son type d'argument, ce qui peut être déduit par le compilateur. Idem pour le type de
i
(où nous devons encore écrirevalue
pour le marquer comme une déclaration). Maintenant, cette déclaration est suffisamment courte pour tenir sur une seule ligne, ce qui nous ramène à 230:Au lieu de
e == ' ' || e == '-'
nous pouvons également écriree in [' ', '-']
(oue in {' ', '-'}
, c'est un constructeur itérable au lieu d'un tuple). L'in
opérateur est mappé à la méthode Category.contains, ce qui nous amène à l'idée que nous pouvons passer lacontains
méthode de ce tuple directement (c'est un appelable prenant n'importe quel objet, donc acceptant également le caractère), sans le passe-(e) => ...
partout (222 octets):En fait, une autre catégorie contenant les deux mêmes caractères est la chaîne de deux caractères
" -"
. (De plus, il contient également ses sous-chaînes, mais cela ne fait pas de mal ici). 216 octets.Je suppose que nous avons tiré le meilleur parti de cette ligne, passons aux autres ... les deux dernières déclarations de retour ont une certaine similitude que nous pouvons exploiter - elles diffèrent simplement par
i
rapport à vs.l-3
, et utilisenti
juste quand elle n'est pas nulle, sinonl-3
. Heureusement, c'est exactement ce pour quoi l'else
opérateur est fait!(Les parenthèses semblent être nécessaires ici, tout comme celles qui
else
ont une priorité plus faible que[:]
.) Il s'agit de 171 caractères. Maintenant, ili
n'est utilisé qu'une seule fois, nous pouvons donc l'intégrer, ce qui nous amène à 153 caractères:Nous pouvons également remplacer cette
if-return-return
combinaison par une combinaison des opérateursthen
etelse
en unreturn
. (then
renvoie est le deuxième opérande lorsque le premier est vrai, sinon null, ce qui permet ensuiteelse
de renvoyer son deuxième opérande.) 131 octets (bien que certaines des économies soient les espaces blancs dont nous nous débarrasserons de toute façon):Une fonction qui ne contient qu'un seul retour avec une expression peut alternativement être écrite avec la notation "grosse flèche", donnant 123:
Supprimer les espaces blancs inutiles nous donne les 111 derniers octets:
String t(String s,Integer l)=>s.size<l then s else s[0:(s[0:l-2].lastIndexWhere(" -".contains)else l-3)]+"...";
En complément, voici une fonction qui imprime les exemples de la question (en utilisant le nom
t
qui est utilisé après l'étape deux):la source
Shell POSIX + GNU sed, 65 octets
C'est un travail fait pour sed! Mais j'avais besoin de shell pour obtenir la limite de longueur (peut-être que Perl serait mieux). La partie sed se développe en une séquence assez simple, avec des sauts conditionnels à la fin:
la source
Mathematica 192 octets
Appelé comme
la source
> <>, 74 octets
Cette solution nécessite que la chaîne soit tronquée et
L
qu'elle se trouve déjà dans la pile, dans cet ordre.Il y a 7 octets perdus causés par des problèmes d'alignement, essayant toujours de les jouer au golf.
la source
C # (157):
Basé sur la réponse de Salah Alami , mais plus court. La classe de chaîne dérive de
IEnumerable<char>
, donc au lieu deT.Contains(" ")||T.Contains("-")
, j'utilise" -".Any(x=>T.Contains(x))
.Solution:
Non golfé:
Mise à jour:
Enregistré 6 octets grâce au commentaire de SLuck49, en utilisant
Any(T.Contains)
au lieu deAny(x=>T.Contains(x))
.la source
.Any(x=>T.Contains(x))
vous pouvez directement utiliser la méthode au lieu d'un lambda comme.Any(T.Contains)
pour économiser 6 octetsGS2 , 29 octets
Ce programme prend une entrée standard. La première ligne est la chaîne et la seconde est le numéro de longueur cible.
Le code GS2 peut parfois être un peu difficile à lire. :) Voici quelques commentaires.
la source
Groovy, 56 octets
Copie la réponse de Kleyguerth en premier, d'où les mêmes noms de variables ...
Coupez la chaîne de 2 caractères, puis la plupart du travail est effectué par l'expression régulière, remplacez un tiret ou un espace suivi d'un nombre quelconque de caractères qui ne sont pas un tiret ou un espace à la fin de la chaîne avec un "." OU remplacez n'importe quel caractère à la fin de la chaîne si tous les caractères qui le précèdent ne sont ni un tiret ni un espace avec un ".". Plus difficile à mettre en mots que d'écrire l'expression régulière ...
Edit: En fait, il suffit de supprimer la partie de la chaîne qui correspond à l'expression régulière et d'ajouter "..." à la fin:
la source
Gelée , 29 octets
Essayez-le en ligne!
Programme complet.
la source
Nettoyer , 89 octets
Essayez-le en ligne!
En tant que fonction
$ :: Int String -> String
la source
C # (Visual C # Interactive Compiler) , 117 octets
Basé sur @ Abba, qui est basé sur la réponse de @Salah Alami. Au lieu d'utiliser
Contains
et unSubstring
appel inutile , il utilise IndexOf pour vérifier si un trait d'union ou un espace existe dans la chaîne tronquée.Essayez-le en ligne!
la source