J'ai fait un kata sur CodeWars , dont le résumé est de prendre un nombre et de renvoyer C'est l'une des meilleures solutions: p > Ceci est mon propre code: Je ne comprends pas comment " Jumping !! " si les chiffres sont à moins de 1 l'un de l'autre (par exemple 2345 code >, 4323 , 7898 ) et "Not !!" sinon. Tous les chiffres uniques (par exemple 5 , 7 , 9 ) sont des nombres sautants. def jumping_number(n)
n.to_s.chars.map(&:to_i).each_cons(2) { |x, y| return "Not!!" if (x - y).abs != 1 }
return "Jumping!!"
end
def jumping_number(n)
n.to_s.chars.map(&:to_i).each_cons(2).all? { |x, y| (x - y).abs == 1 } ? "Jumping!!" : "Not!!"
end
each_con [sic] travaux. Comment la condition de ces méthodes peut-elle (correctement) retourner true lorsque n est un seul chiffre? Le consécutif est soit nil ou 0 qui, lorsqu'il est utilisé dans le calcul, ne doit pas renvoyer true , et pourtant c'est le cas. P >
3 Réponses :
Voici votre malentendu:
Le consécutif est soit nul, soit 0 qui, lorsqu'il est utilisé dans le calcul, ne devrait pas renvoyer vrai (et pourtant c'est le cas!)
Ce n'est ni nul ni 0 . Cela n'existe tout simplement pas du tout. L'énumérateur est vide.
Malheureusement, cela n'est pas documenté dans la documentation de Enumerable # each_cons . La solution à votre casse-tête est que si la taille que vous demandez pour le contre est plus petite que la taille de l'énumérable, alors il n'y aura pas de contre:
[5, 6, 7].each_cons(2).to_a #=> [[5, 6], [6, 7]] [5, 6, 7].each_cons(3).to_a #=> [5, 6, 7] [5, 6, 7].each_cons(4).to_a #=> []
En d'autres termes: le bloc n'est jamais exécuté, il n'y aura donc jamais d'erreur.
... et l'autre solution mentionnée revient à [] .all? {} # => true (lorsque le tableau est de taille 1), c'est pourquoi cela fonctionne.
ne serait-il pas plus agréable que ruby renvoie un élément nul si la taille de la requête est plus grande que le con? [5, 6, 7] .each_cons (4) .to_a # => [5, 6, 7, nil] ou au moins # => [ 5, 6, 7]
Jörg a répondu à votre question, mais voici une autre façon d'effectuer le test.
123.digits #=> [3, 2, 1] 123.to_s.chars.map(&:to_i) #=> [1, 2, 3]
Notez que j'ai utilisé Entier # chiffres plutôt que Entier # to_s pour séparer les chiffres:
def jumping_number(n)
enum = n.digits.to_enum
loop { return "Not!!" unless (enum.next - enum.peek).abs == 1 }
"Jumping!!"
end
jumping_number 5 #=> "Jumping!!"
jumping_number 12321 #=> "Jumping!!"
jumping_number 1243 #=> "Not!!"
Les ordres des éléments du tableau produit ne sont pas les mêmes, mais ce n'est pas grave pour ce problème.
Enumerator # peek déclenche une exception StopInteration lorsqu'il est exécuté après Enumerator # next a provoqué la génération du dernier élément de l'énumérateur. Kernel # loop puis gère l'exception en sortir de la boucle.
Une autre solution possible consiste à utiliser Enumerable #chunk_ while puis mesurer la taille du tableau retourné.
Comment ça marche:
def jumping_number(n)
n.digits.chunk_while{ |x, y| (x-y).abs == 1 }.to_a.size == 1 ? "Jumping!!" : "Not!!"
end
Donc, en l'utilisant dans une méthode:
[1,2,3].chunk_while{ |x, y| (x-y).abs == 1 }.to_a #=> [[1, 2, 3]]
[1].chunk_while{ |x, y| (x-y).abs == 1 }.to_a #=> [[1]]
[1,2,4].chunk_while{ |x, y| (x-y).abs == 1 }.to_a #=> [[1, 2], [4]]
(Merci @Cary Swoveland de se souvenir que Integer #digits existe.)
Le consécutif n'est ni
0ninil(il n'existe pas du tout). Si vous aviez une pomme et que je disais m'en donner 2 ou les à la fois, et je n'en accepterai que 2 à la fois, ou je n'accepterai rien, vous seriez coincé en me donnant rien car c'est physiquement impossible autrement['apple']. each_cons (2) .to_a # => []."Chaque roi des Etats-Unis est ..." est vrai quelle que soit la proposition que vous mettez "...". La phrase entière est satisfaite dans le vide.