Je suis tombé sur cette question sur SO et j'ai pensé que cela ferait un beau défi de golf. Voici donc:
Défi:
Écrivez un programme qui lit une séquence de chaînes de caractères, une par ligne, et génère une liste de toutes les positions où chaque chaîne a le même caractère.
Entrée et sortie:
L'entrée consiste en une ou plusieurs lignes de caractères ASCII non blancs imprimables, chacune suivie d'une nouvelle ligne. Vous pouvez supposer que toutes les lignes d'entrée ont la même longueur. La nouvelle ligne ne doit pas être considérée comme faisant partie de l'entrée (c'est-à-dire que vous ne devez pas la sortir en tant que caractère correspondant).
Exemple d'entrée (sans vergogne volé à la question SO):
abcdefg
avcddeg
acbdeeg
Après avoir lu l'entrée, votre programme doit imprimer les positions de chaque colonne correspondante et les caractères qu'elles contiennent. (Votre programme peut, mais pas nécessairement, arrêter de lire d'autres entrées s'il peut déterminer tôt qu'il n'y a pas de colonnes correspondantes.) Tout format de sortie raisonnable est autorisé; en particulier, vous pouvez utiliser une indexation basée sur 0 ou 1 pour les positions.
Exemple de sortie pour l'entrée ci-dessus (en utilisant l'indexation basée sur 0):
0: a
3: d
6: g
Notation:
C'est le golf de code, donc la réponse la plus courte l'emporte. En cas d'égalité, des caractères de bris d'égalité fractionnaires peuvent être attribués pour des fonctionnalités supplémentaires:
- −½ caractères pour gérer correctement les lignes d'entrée de longueur inégale. (La sortie ne doit pas contenir de positions après la fin de la ligne d'entrée la plus courte.)
- −¼ caractères pour gérer correctement l'entrée composée de caractères Unicode codés UTF-8 arbitraires.
Pour vous inspirer, vous pouvez trouver des solutions non golfées à la question SO (voir ci-dessus).
Clarifications:
La simple concaténation des positions et des caractères, comme dans
0a3d6g
, ne compte pas comme "sortie raisonnable". Vous devez fournir une sorte de séparateur (tel qu'un espace) entre chaque élément de la sortie afin qu'il puisse être analysé sans ambiguïté.L'entrée sera fournie sur le flux d'entrée standard (
stdin
), ou en utilisant le mécanisme d'entrée de fichier texte le plus naturel pour la langue de votre choix. (Si la langue que vous avez choisie n'a pas de mécanisme naturel pour la saisie de fichiers, faites ce qui vous semble le plus proche dans l'esprit.)L'entrée se termine lorsqu'il n'y a plus de données à lire (c'est-à-dire lorsqu'une condition de fin de fichier se produit). Si vous le souhaitez, vous pouvez exiger que l'entrée soit terminée par une ligne vierge (que vous ne devez alors pas compter comme partie de l'entrée, évidemment). Si vous le faites, veuillez le mentionner dans votre réponse afin que d'autres puissent fournir une entrée correcte pour les tests.
Chaque ligne d'entrée, y compris la dernière, se termine par un caractère de nouvelle ligne. Votre réponse ne doit pas signaler cette nouvelle ligne comme colonne correspondante. (Ce n'est pas grave si votre solution peut également gérer des entrées où la dernière ligne ne se termine pas par une nouvelle ligne, mais ce n'est pas obligatoire.)
Réponses:
APL, 25 caractères
J'ai utilisé Dyalog APL (version 13) comme interprète. Il gère à la fois les entrées de longueur inégale et les caractères Unicode (UTF-8).
Exemples:
Explication, un peu de droite à gauche:
⍵
.0=⍴⍵:⍬
est notre première expression, et il vérifie si nous avons obtenu une ligne vide (c'est-à-dire que nous avons terminé). Il utilise un garde (une construction familière à de nombreux programmeurs fonctionnels) pour exécuter conditionnellement l'expression à droite des deux-points. Dans ce cas, si 0 est égal à la forme / longueur (⍴
) de l'argument de droite, nous renvoyons l'ensemble vide (⍬
).⋄
sépare les deux expressions au sein de la fonction. Si l'expression précédente n'a pas été évaluée (et n'a donc rien renvoyé), nous passons à l'expression suivante.∇
). L'argument de la fonction est une ligne d'entrée utilisateur non évaluée, donnée par quote-quad (⍞
).⊂⍵,⍨¨⍳⍴⍵
crée des paires pour chaque caractère de la chaîne, où le premier élément de chaque paire est sa position dans la chaîne et son deuxième élément est le caractère.⍳⍴⍵
donne un vecteur de 1 à⍴⍵
, ou la longueur de la chaîne d'entrée.⍵,⍨¨
applique la fonction de concaténation commuée (,⍨
) à chaque¨
élément ( ) à sa gauche (⍵
, dans ce cas, l'entrée de l'utilisateur) et à sa droite. La commutation de la fonction de concaténation entraîne l'échange de ses arguments gauche et droit.⊂
, afin de pouvoir différencier les lignes d'entrée.⍞
)./
) notre vecteur de vecteurs de paires résultant en utilisant la fonction d'intersection (∩
), ce qui donne les paires que l'on trouve dans tous les sous-vecteurs.la source
Golfscript (28 caractères)
Il y a des problèmes de jeu de caractères lors de la transmission d'Unicode, donc pas de bonus d'un quart de point.
la source
J,
57514440 caractèresJ'y arrive lentement mais sûrement. C'est encore loin d'être idéal même si je pense.
J'étais convaincu que l'utilisation d'un crochet serait la réponse, mais malheureusement pas (44 caractères):
J'ai peut-être besoin d'une méthode complètement différente pour raccourcir.
la source
Haskell, 64 caractères
Gère les lignes de longueur inégale. La prise en charge Unicode dépend des paramètres régionaux actuels.
Exemple de sortie:
la source
Python 2, score 81,5 (
11694868382 octets moins bonus)la source
[:-1]
n'est pas nécessaire à moins de supprimer une nouvelle ligne superflue à la fin de l'entrée (qui ne semble même pas être là dans la question).zip(*sys.stdin)
est[('a', 'a', 'a'), ('b', 'v', 'c'), ('c', 'c', 'b'), ('d', 'd', 'd'), ('e', 'd', 'e'), ('f', 'e', 'e'), ('g', 'g', 'g'), ('\n', '\n', '\n')]
. Je ne vois aucun moyen d'éviter de supprimer ce dernier tuple de nouvelles lignes. Veuillez me corriger si j'ai mal compris. Merci pour le vote positif.[:-1]
. Par exemplezip([1,2,3,4],[1,2,3])=> [(1, 1), (2, 2), (3, 3)]
(Bash) Shell Scripting, 105 caractères
Si quelqu'un a d'autres astuces pour cela, veuillez remplir gratuitement pour commenter!
Résultat:
la source
/tmp/cols.sh: line 2: [1: command not found
et rien d'autre.[
; et $ {y: 3} le fera fonctionner uniquement avec exactement 3 lignes d'entrée. La correction et l'optimisation des rendements (100 caractères)while((++i%`tail -1 $1|wc -c`));do x=`cut -c$i $1`;((`uniq|wc -l`==1))<<<"$x"&&echo $i ${x: -1};done
et l'utilisation des valeurs par défaut devraient permettre d'en enregistrer un de plus avecfor((;++i<`tail -1 $1|wc -c`;))do
mais il y a un bug non corrigé dans bash.Perl, 87 caractères (−½ char bonus tie-break)
Voici une version golfée de ma propre solution à partir du thread SO :
Contrairement à la version SO, celle-ci utilise des index basés sur 1 pour la sortie. Il utilise la fonctionnalité Perl 5.10
say
, doit donc être exécuté avecperl -M5.010
(ou avecperl -E
).Comme la version SO, ces manches lignes de code de longueur variable, et ne traitent entrée Unicode arbitraire si l'entrée standard et la sortie sont en mode UTF-8. Hélas, par défaut, ils ne le sont pas, sauf si l'on spécifie le commutateur de ligne de commande non libre
-CS
. Ainsi, il gagne le bonus de -½ char, mais pas le -¼.Edit: +1 caractère pour corriger un bug: ce n'est pas parce que les chaînes d'entrée ne contiennent pas de sauts de ligne qu'ils ne peuvent pas se retrouver
$a
(par exemple"+" & "J" eq "\n"
).la source
chop
au lieu dechomp
.m
pour l'instant, ce n'est pas comme si cela faisait une différence pour le classement en ce moment. :)T-SQL
la source
Scala
115107: (−¼ pour la manipulation de l'UTF-8)non golfé, et
Source.fromFile ("f")
au lieu destdin
pour une meilleure testabilité:Résultat:
Merci à Gareth pour la réduction de la taille 8 pour l'utilisation
stdin
.la source
stdin
au lieu defromFile("f")
pour enregistrer 8 caractères?VBA (
307,25284 - 0,75 bonus = 283,25)Je sais que cela a déjà été gagné, mais voici ma photo (ne pas lire un fichier, juste une chaîne - doit avoir l'io ajouté). J'aime que j'ai pu utiliser
l()
récursivement. Je n'ai généralement pas besoin de récursivité ma programmation réelle. Je n'ai fait que beaucoup de tests, mais je pense que cela couvre la stipulation des points bonus unicode. Il suppose également qu'ilvbCr
s'agit du terminateur de ligne. Cela peut ne pas se traduire sur tous les systèmes à cause de cela.Code:
Exemple d'entrée / sortie:
la source
Q, 32
usage
K, 22
La solution ci-dessus peut être réduite à 22 en l'écrivant complètement en K plutôt qu'en passant les fonctions K à un interpréteur Q, réduisant ainsi le nombre de parenthèses requises.
la source
PHP,
123127 :(Je ne suis pas satisfait (il y a forcément des améliorations à apporter), mais voici:
Preuve que ça marche.
Si quelqu'un peut penser à un moyen plus intelligent d'initialiser $ a et $ b, faites-le moi savoir. À l'origine, j'avais
$a=$b=$n=''
et $ b était finalement correct, mais[empty] & [anything] == [empty]
$ a n'a jamais eu de contenu.Edit: a dû corriger la gestion de la nouvelle ligne (+6) mais a supprimé la balise de fermeture (-2).
la source
?>
. Cependant, je viens de remarquer que votre code a un bug: il affiche une correspondance supplémentaire si toutes les lignes contiennent un retour à la ligne comme spécifié.JavaScript (125
134140)Démo: http://jsfiddle.net/Fv7kY/4/
Edit 1 : Réorganisez les boucles pour éviter les accolades. Initialisez i avec
[]
pour combiner avecs
. Déplacez l'w
incrément dans l'expression.Edit 2 : paramétrez
S=I
pour capturer le dernier mot entré et enregistrez-le avecs[1]
. Combinezr=1
et++c<S.length
. PlacezC=s[c]
dans la boucle intérieure et comparez àC
au lieu des mots précédents et suivants pour raccourcir l'expressions[w][c]==s[w++][c]
à justes[w++][c]==C
. Enregistré un total de 9 caractères. Défini égalementw=r=...
parce que lorsque c'est vrai,w=1
c'est avec quoi nous devons initialiserw
.la source
Rubis (71)
production:
la source
t[i]
avec Ruby 1.8, remplacez part[i,1]
.Lisp commun,
183165 caractèresFormat lisible:
Saisissez-le directement dans le REPL et entrez les lignes, en terminant par une ligne vide.
la source
C, 126 caractères
J'ai regardé ça mais je ne peux pas le réduire. Une nouvelle approche peut être nécessaire.
(Pas de points bonus; il ne gère les lignes de tailles différentes que si la première ligne est la plus courte.)
la source
C # avec .NET 4 (280)
Version lisible
Réponse originale
en utilisant c = System.Console; classe P {static void Main () {char [] a; var b = c.ReadLine (); a = b.ToCharArray (); while (b! = "") {for (int i = 0; iVersion lisible:
la source
0: a 1: b 2: c 3: d 4: e 5: f 6: g 0: a 2: c 3: d 6: g 0: a 3: d 6: g
. Le résultat attendu serait0: a 3: d 6: g
.python 122 caractères :
la source
)
etfor
. Donc, au lieu de…str(x[0]) for i,x…
, vous pouvez le faire…str(x[0])for i,x…
. Il arrive également àtuple(x) for
et.split()])) if
Rubis (242)
la source
STDIN
(ARGF
ou tout simplementgets
).C #
la source