Quelles sont les approches intelligentes (brèves et idiomatiques) pour prendre une liste de chaînes et renvoyer une seule chaîne correctement ponctuée construite à partir de la liste, avec chaque élément cité.
Cela m'est venu en expérimentant avec Groovy , pour lequel ma solution trop littérale, mais illustrative est
def temp = things.collect({"\'${it}\'"})
switch (things.size()) {
case 1:
result = temp[0]
break
case 2:
result = temp.join(" and ")
break
default:
result = temp.take(temp.size()-1).join(", ") + ", and " + temp[-1]
break
}
Autrement dit, ['1']
devrait céder '1'
, ['1','2']
devrait céder '1 and 2'
, [voyez ce que j'ai fait là-bas?] Et ['1','2','3']
devrait céder '1, 2, and 3'
.
J'ai de bonnes réponses pour Groovy, mais j'aimerais voir ce que d'autres langues peuvent faire.
Quelles sont les approches intelligentes compactes dans diverses langues qui tirent parti des fonctionnalités et des idiomes de ces langues?
['we invited the stripper','JFK','Stalin']
Réponses:
CSS,
132116115 octetsAfficher l'extrait de code
CSS n'est pas vu trop souvent dans le golf de code car il ne peut que formater du texte, mais il fonctionne réellement pour ce défi et j'ai pensé que ce serait amusant à faire. Voyez-le en action en utilisant l'extrait de code ci-dessus (cliquez sur "Afficher l'extrait de code").
La liste doit être dans un fichier HTML lié avec chaque élément entouré de
<a>
balises et séparé par des sauts de ligne. Les éléments de la liste doivent être les seuls éléments de leur élément parent, par exempleExplication
Prenons la version non golfée ci-dessus. Si vous n'êtes pas familier avec le fonctionnement de CSS, tout ce qui se trouve en dehors des accolades est un sélecteur qui détermine l'ensemble des éléments HTML auxquels s'appliquent les déclarations à l'intérieur des accolades. Chaque paire sélecteur-déclaration est appelée une règle . (C'est plus compliqué que cela, mais suffira pour cette explication.) Avant d'appliquer un style, la liste apparaît séparée uniquement par des espaces.
Nous voulons ajouter des virgules après chaque mot, sauf le dernier, à l'exception des listes de deux mots, qui n'obtiennent aucune virgule. Le premier sélecteur,,
a:not(:last-child):nth-child(n+2):after
sélectionne tous les éléments à l'exception du premier et du dernier.:nth-child(n+2)
est une façon plus courte de dire:not(:first-child)
, et cela fonctionne essentiellement en sélectionnant des éléments dont l'index (à partir de 1) est supérieur ou égal à 2. (Oui, cela m'embrouille encore un peu. Les documents MDN pourraient aider.)Il nous suffit maintenant de sélectionner le premier élément pour obtenir une virgule s'il y a trois éléments ou plus au total.
a:nth-last-child(n+3):after
fonctionne comme:nth-child
, mais en comptant de l'arrière, donc il sélectionne tous les éléments sauf les deux derniers. La virgule prend l'union des deux ensembles, et nous utilisons le:after
pseudo-élément pour ajoutercontent
immédiatement après chaque élément sélectionné.La deuxième règle est plus simple. Nous devons ajouter "et" avant le dernier élément de la liste, sauf s'il s'agit d'un seul élément. En d'autres termes, nous devons sélectionner le dernier élément précédé d'un autre élément.
+
est le sélecteur frère adjacent en CSS.la source
<li>
.<li>
serait idéal, mais cela ajouterait deux caractères supplémentaires aux sélecteurs. J'ai choisi<a>
car il s'agit d'une seule lettre et n'applique pas sa propre mise en forme.Haskell:
81, 7774 caractèresCaractéristiques Haskell: Correspondance de motifs
la source
f[x,y,z]
f["a","b","c"]
est censé l'être,"a, b, and c"
mais c'est le cas"a,b and c"
y++", and "++z
parf[y++",",z]
:)Rubis, 47 octets
Explication
$*
).$*
a un troisième élément ($*[2]
ne renvoie pas nil), prenez tous les éléments moins le dernier et transformez-les en une chaîne séparée par des virgules à l'aide deArray#*
. Enfin, ajoutez une virgule supplémentaire, la chaîne" and "
et le dernier argument de ligne de commande.$*
n'y a pas de troisième élément, deux, un ou zéro arguments ont été donnés. Les arguments peuvent être joints en toute sécurité à la chaîne" and "
et produire le résultat correct.la source
Python 2 (61)
L'astuce principale est de couper une partie du menuisier final
", and "
pour un et deux éléments. Pour un, tout est coupé, et pour deux, la virgule est supprimée. Cela se fait en découpant[8-7*len(s):]
(en notant ques
c'est un plus court après lepop
).Malheureusement,
d
ne peut pas simplement être remplacé par son expression oupop
cela arriverait trop tard.la source
s
pars=input()
et supprimer la première ligne, si je ne me trompe pas. Enregistre 2 caractères.s
plusieurs fois.CSS,
62 caractères112 caractèresInspiré des autres entrées, encore plus court. Notez qu'il nécessite que les éléments A ne soient pas séparés par des espaces blancs:
http://jsfiddle.net/olvlvl/1Ls79ocb/
Correction du "un et deux", comme l'a souligné Dennis:
http://jsfiddle.net/olvlvl/1Ls79ocb/3/
la source
Perl (v 5.10+) -
37353428pour être exécuté avec
perl -ape
, l'espace de liste fourni étant séparéSTDIN
.Sortie pour différentes entrées:
la source
s/(\S+)$/and $1/
$
ancre dans votre modification, donc une entrée defoo bar baz
devientfoo, and bar, baz
. En outre, vous pouvez supprimer l' un des espaces en faisants/( \S+)$/ and$1/
$#F>1
que de@F>2
se raser un plus. Désolé pour toutes les suggestions d'améliorations micro, j'aime vraiment cette réponse :)echo -n ... | wc -c)
. Si vous manquez l'espace avant(\S+)
d'obtenir 33 caractères, mais si vous insérez,test this
vous obtiendreztest and this
(deux espaces aprèstest
), donc sans plus Je pense que c'est faux.Javascript (63)
l=a.length;l>2&&(a[l-1]='and '+a[l-1]);a.join(l>2?', ':' and ')
Cas:
a = [1]
=>1
a = [1, 2]
=>1 and 2
a = [1, 2, 3]
=>1, 2, and 3
Mise en garde: cela modifiera le dernier élément d'un tableau de longueur> 2.
la source
&&
GNU sed - 69 caractères dont 1 pour le
-r
drapeauPrend une liste séparée par des espaces (assez idiomatique pour les scripts shell).
Exemple
la source
1 and 2
au lieu de1, 2
Python 2 -
71, 7068Nombre de caractères incluant les deux,
input
etprint
.la source
Rubis, 57 octets
Je rejoins la chaîne avec
,
puis je remplace la dernière virgule de la chaîne par unand
(et une virgule facultative en fonction de la longueur de la liste).la source
Cobra - 60
La
List<of T>.join
fonction de Cobra vous permet de spécifier un séparateur différent pour les deux derniers éléments de la liste, ce qui rend cela si court.la source
Perl - 59
Joint la liste avec des virgules, puis si la liste a plus d'un élément, soit ajoute
' and'
après la dernière virgule (si longueur> = 3), ou remplace la dernière virgule par elle (si longueur == 2).la source
PHP,
192167146136 136 caractères:Basé sur une fonction que j'ai écrite il y a des années à http://www.christopherbloom.com/2011/05/21/join-implode-an-array-of-string-values-with-formatting/
la source
Lot - 151 octets
Remarque; vous devez appeler le script
cmd
avec le/v
commutateur défini commeon
, c'est ainsi je n'ai pas à inclure le longsetLocal enableDelayedExpansion
dans le script. Sinon, ajoutez 30 au nombre d'octets et appelez le script normalement.la source
Groovy,
47 4357 caractères, JavaScript ES6 56 caractèresSensationnel:
Puisque le tableau est rempli de caractères, nous pouvons remplacer
a.size>1
para[1]
JavaScript, ES6:
Les deux cas supposent que la variable a a le tableau en question.
la source
PHP,
8684 caractèresAvec le tableau initialisé, nous commençons à compter:
Prettifié:
Le dernier élément de la liste est modifié. Cela devrait être correct car en PHP, les affectations de tableaux et les appels de fonction effectuent des copies.
la source
CJam,
35302827 octetsIl s'agit d'un programme qui lit depuis STDIN et imprime vers STDOUT. Essayez-le en ligne.
Comment ça marche
Exemple d'exécution
la source
Google Sheets,
67686792 octetsL'entrée commence à la cellule
A1
et continue vers le bas pour autant d'entrées existent.JOIN
les fusionne tous en une chaîne avec un espace virgule entre chacun.FILTER
supprime tous les non-blancs afin que vous ne vous retrouviez pas avec des virgules infinies à la fin.SUBSTITUTE
remplace la dernière virgule (trouvée parCOUNTA
comptant les entrées non vides).Ce n'est pas très excitant mais c'est faisable dans une seule cellule.
la source
)
de cette formule pour -1 octet; Eh bien dang, c'était le montage le plus rapide que j'aie jamais vu +1A:A>""
devraient être converties enA:A<>""
et cela n'implémente pas l'omission de la virgule oxford sur les cas de seulement 2 objets>""
. La correction rapide que j'ai faite plus tôt n'a clairement pas été testée. Je n'aime pas la direction qui est allée ...JavaScript (ES6) 60
En supposant qu'aucune chaîne vide dans le tableau d'entrée
Test dans la console FireFox / Firebug
Sortie
la source
node --harmony
avec un tableau de chaînesvar a = 'abcdefgh'.split('');
, mais il se trouve juste là avec un...
et semble ne rien faire. +1 également pour l'utilisation de la fonction ES6 unique()=>
.f=(a,b=a.pop())=>a[0]?a.join(', ')+', and '+b:b
c'est aussi correct et 13 octets plus court.JavaScript -
6056716763Pas exactement une approche idiomatique, mais je me suis amusé à l'écrire et j'aime l'expression régulière.
En supposant que le tableau est stocké dans
var a
:Raccourci en vérifiant simplement l'index
[2]
: (yay coercition booléenne)Apparemment, je suis nul lors des tests et j'ai sauté un test à entrée unique. Voici la version fixe:
Rasé 2 caractères en inversant mes booléens et 3 autres en déplaçant l'espace de la concaténation dans le puis / sinon du premier ternaire:
Merci à @tomsmeding de m'avoir rappelé que je n'ai pas à contraindre mes booléens car JS le fait pour moi. J'ai également réalisé que j'avais oublié de supprimer les parenthèses séparant le premier ternaire de la concaténation à l'intérieur du
join()
:Est-ce que j'ai bien fait ça? Nouvelles excuses obligatoires des golfeurs.
la source
!!
;a[2]?A:B
fonctionne déjà. Vous devrez peut-être inverser à nouveau vos booléens .a[i]
équivaut à true . Enfin presque. Je suppose que si vous obtenez 2 entrées, votre tableau a une longueur de deux. Puisa[2]===undefined
etundefined
évalue àfalse
. EDIT: votre montage est ce que je voulais dire :)Golfscript -
31393430Bonjour le monde! Je suis un rôdeur de longue date, première affiche. Voici ma solution de 30 octets dans Golfscript (étant donné que le tableau tel que [1 2 3] est déjà sur la pile).
Les résultats sont valables pour tous les cas de test.
EDIT: Prenez ça, CJam!
la source
Xojo,
527183 caractèresNotez que UBound est un de moins que la longueur du tableau.
la source
Excel VBA, 108 octets
Fonction de fenêtre immédiate VBE anonyme qui prend les entrées en tant que tableau délimité par des espaces de la plage
A1
et les sorties vers la fenêtre immédiate VBE.la source
Raquette 87
la source
Python 62 caractères
En supposant que i est la liste des chaînes:
la source
Caractères C # 102
la source
Julia (53 ans)
Prend les arguments de STDIN et sort vers STDOUT
Solution utilisant Base.join (items, delim [, last])
Modifier:
Cas de test
1
1 et 2
1, 2 et 3
la source
1, 2, and 3
, non1, 2 and 3
.Coup de gueule (108)
Non golfé:
Usage:
Essayez-le en ligne
la source
Pyth, 28
Exemples:
la source
TypeError: can only concatenate list (not "str") to list
). Cela fonctionne très bien avec la dernière version.PHP - 72
Configurez l'entrée:
Et puis le processus:
la source