8
votes

Permutations de capitalisation

Je voulais écrire un extrait de rubis qui prendrait une chaîne et de produire toutes les permutations possibles des capitalisations. Fondamentalement, j'ai un mot de passe que je me souviens, mais je ne me souviens pas comment il est capitalisé.

J'ai ce qui suit jusqu'à présent: p> xxx pré>

Ceci fonctionne assez bien , mais je me demandais si des rubyistes là-bas pouvaient m'aider à affiner pour que cela ne soit pas obligé de fonctionner inutilement sur des chaînes avec des chiffres. p>

Par exemple, la chaîne "TST1" génère: P >

tst1
tsT1
tSt1
tST1
Tst1
TsT1
TSt1
TST1


0 commentaires

9 Réponses :


0
votes

Eh bien, je ne sais pas Ruby, donc je me trompe, mais il me semble que le code fonctionne. C'est juste que pour vous ne prenez pas compte de chiffres lorsque vous effectuez des permutations de capitalisation. Le chiffre seulement a une seule version pour que la capitalisation ressemble au même. Par conséquent: "TST1" et "TST1", "TST1" et "TST1" et ainsi de suite ..

Avez-vous essayé le code avec "ACB"? Cela fonctionne-t-il bien ou obtenez-vous le même problème?


1 commentaires

Alors pourquoi pas simplement mettre une condition pour ne pas périter des chiffres?



0
votes

Une approche simple peut être de supprimer les chiffres de la chaîne, de transmettre les résultats à la fonction que vous avez déjà écrite, puis de remettre les numéros dans le même index.


0 commentaires

0
votes

Peut-être pas la solution la plus élégante, mais vous pouvez changer xxx pré>

à p> xxx pré>

et après la boucle p>

puts passwords.uniq


0 commentaires

0
votes

Comme ça? XXX


3 commentaires

Eh bien, ce code est beaucoup plus compact, mais les doublons sont toujours là. Il ne devrait y avoir que 8 lignes de sortie pour cette chaîne.


Oui, mais cela ne fonctionne que si le mot de passe s'est terminé par un seul chiffre.


Un seul chiffre .. Je ne suis pas suivi?



0
votes

Légère mod au programme d'origine
#!/usr/local/bin/ruby
$result = []
def permute(str)
  perms = Array.new
  (2 ** str.size).times { perms << str }
  perms.each_index do |i|
    binary = i.to_s(2)
    str_arr = perms[i].split(//)
    bin_arr = binary.split(//)
    while ( bin_arr.size < str_arr.size )
      bin_arr.unshift('0')
    end
    bin_arr.each_index do |b|
      str_arr[b].upcase! if bin_arr[b] == '1'
    end
    $result << str_arr.to_s
  end
  $result
end
puts permute(ARGV[0]).uniq


0 commentaires

2
votes

Essayez John The Ripper, ou Cain et capable, ou n'importe quel logiciel de craquage de mot de passe


2 commentaires

Qu'est-ce que cela a à voir avec la question à la main?


Eh bien, elle résout le problème plutôt que de se concentrer sur la question. Agréable :-)



2
votes

Vous devez créer un autre tableau et au lieu de mettre code> simplement les inclure dans le tableau s'il n'est pas déjà inclus dans le tableau. Ensuite, après votre boucle, rejoignez-les avec un \ n code> ou tout ce que vous voulez.

>> permute("tst1")
tst1
tsT1
tSt1
tST1
Tst1
TsT1
TSt1
TST1


1 commentaires

Pourquoi cela est-il voté, il fait exactement ce que la personne demande la question qui veut?



13
votes

Quelle est une excellente occasion de mettre mes cours de "dérivation d'algorithmes", la méthode de Dijkstra, de retour des jours de l'université en pratique ici. Ceci est la version 'propre> forte> xxx pré>

edit forte>: Dijkstra nous a appris à ne pas optimiser prématurément, donc je pensais que la version de la matrice serait mieux être ajouté séparément :-): p> xxx pré>

et pour la blâtrer rapidement, on se convertit dans la récursion de la queue, à l'aide d'un argument de méthode supplémentaire: P>

tail: 0.982241
normal: 0.285104
superfast: 0.168895


1 commentaires

Le plus grand bonus de la méthode Dijkstra est que personne ne cassait / toucher votre code, car il sera trop dense pour lire. Vous ne pouvez pas jouer avec cela, vous devez «grok '» avant de les altérer :-)



1
votes

Une autre solution (qui peut résister à l'essayer de l'essayer?):

require 'pp'
class String
  def permute
    return [self, self.upcase].uniq if size <= 1
    [self[0..0], self[0..0].upcase].uniq.map do |x|
      self[1..-1].permute.map {|y| x+y}
    end.flatten
  end
end
pp 'tst1'.permute


2 commentaires

Le retour dans la première ligne de la définition du permatchose pourrait être amélioré pour "retourner [auto-nise, auto-curse] .uniq si la taille <= 1" pour couvrir également le cas de la chaîne "permutée" a des lettres majuscules.


Et la deuxième ligne de la définition du permutation pourrait être simplifiée à "auto [0..0] .permute.map do | x |" (plus court, mais légèrement plus lent).