Il s'agit de relever le défi de trouver la solution la plus élégante en JavaScript, Ruby ou autre à un problème relativement trivial.
Ce problème est un cas plus spécifique de la Problème de la plus longue sous-chaîne commune . Je dois seulement trouver le plus long point commun démarrage sous-chaîne dans un tableau. Cela simplifie grandement le problème.
Par exemple, la plus longue sous-chaîne dans [interspecies, interstelar, interstate]
est "inters". Cependant, je n'ai pas besoin de trouver "ific" dans [specifics, terrific]
.
J'ai résolu le problème en codant rapidement une solution en JavaScript dans le cadre de mon projet de réponse à propos de la saisie par tabulation de type shell ( page de test ici ). Voici cette solution, légèrement modifiée :
function common_substring(data) {
var i, ch, memo, idx = 0
do {
memo = null
for (i=0; i < data.length; i++) {
ch = data[i].charAt(idx)
if (!ch) break
if (!memo) memo = ch
else if (ch != memo) break
}
} while (i == data.length && idx < data.length && ++idx)
return (data[0] || '').slice(0, idx)
}
Ce site Le code est disponible dans ce Gist ainsi qu'une solution similaire en Ruby. Vous pouvez cloner le gist comme un repo git pour l'essayer :
$ git clone git://gist.github.com/257891.git substring-challenge
Je ne suis pas très satisfait de ces solutions. J'ai le sentiment qu'elles pourraient être résolues avec plus d'élégance et moins de complexité d'exécution - c'est pourquoi je publie ce défi.
Je vais accepter comme réponse la solution que je trouve la plus élégante ou la plus concise. Voici par exemple un hack Ruby un peu fou que j'ai inventé : définir la fonction &
sur une chaîne :
# works with Ruby 1.8.7 and above
class String
def &(other)
difference = other.to_str.each_char.with_index.find { |ch, idx|
self[idx].nil? or ch != self[idx].chr
}
difference ? self[0, difference.last] : self
end
end
class Array
def common_substring
self.inject(nil) { |memo, str| memo.nil? ? str : memo & str }.to_s
end
end
Les solutions en JavaScript ou Ruby sont préférées, mais vous pouvez présenter une solution intelligente dans d'autres langages tant que vous expliquez ce qui se passe. Seulement le code de la bibliothèque standard s'il vous plaît.
Mise à jour : mes solutions préférées
J'ai choisi le Solution de triage JavaScript par kennebec comme la "réponse" parce qu'elle m'a paru à la fois inattendue et géniale. Si nous ne tenons pas compte de la complexité du tri réel (imaginons qu'il soit optimisé à l'infini par l'implémentation du langage), la complexité de la solution consiste simplement à comparer deux chaînes de caractères.
D'autres solutions intéressantes :
- "avidité de regex" par FM prend une minute ou deux à saisir, mais ensuite l'élégance de la chose vous frappe. Yehuda Katz a également fait une solution regex mais c'est plus complexe
-
commonprefix
en Python - Roberto Bonvallet a utilisé une fonction conçue pour gérer les chemins du système de fichiers pour résoudre ce problème. - Haskell one-liner est courte comme si elle était comprimée, et belle
- le langage simple et direct de Ruby
Merci de votre participation ! Comme vous pouvez le voir dans les commentaires, j'ai beaucoup appris (même sur Ruby).