Implementação cruzada Deterministic Array # shuffle
É possível passar um gerador de números aleatórios paraArray#shuffle
isso faz o shuffle determinístico.
Por exemplo, na RM 1.9.3p327:
[1, 2, 3, 4].shuffle(random: Random.new(0)) # => [1, 2, 4, 3]
[1, 2, 3, 4].shuffle(random: Random.new(0)) # => [1, 2, 4, 3]
No entanto, a implementação do gerador de números aleatórios de aleatório não é especificada. Devido a isso, outras implementações do Ruby têm resultados diferentes.
No Rubinius 2.0.0rc1 (versão 1.9.3 2012-11-02 JI):
[1, 2, 3, 4].shuffle(random: Random.new(0)) # => [1, 3, 2, 4]
[1, 2, 3, 4].shuffle(random: Random.new(0)) # => [1, 3, 2, 4]
Incidentalmente, o jruby-1.7.1 usa o mesmo gerador de números aleatórios que o MRI 1.9.3p327, mas isso é apenas por acaso, não garantido.
Para ter um shuffle determinístico de implementação consistente, gostaria de passar um gerador de números aleatórios personalizado paraArray#shuffle
. Eu pensei que isso seria trivial de fazer, mas acaba por ser bastante complicado.
Aqui está o que eu tentei primeiro, em ressonância magnética:
class NotRandom; end
[1, 2, 3, 4].shuffle(random: NotRandom.new) # => [4, 3, 2, 1]
[1, 2, 3, 4].shuffle(random: NotRandom.new) # => [4, 2, 1, 3]
Eu esperava umNoMethodError
me dizendo a interface que eu precisava implementar.
Alguma ideia?
ATUALIZAR:
Como @glebm aponta,NotRandom
herdadoKernel#rand
, que é a interface necessária. Isso é facilmente contornado, mas infelizmente não oferece uma solução.
class NotRandom
def rand(*args)
0
end
end
Na RBX:
[1, 2, 3, 4].shuffle(random: NotRandom.new) # => [1, 2, 3, 4]
Na ressonância magnética:
[1, 2, 3, 4].shuffle(random: NotRandom.new) # => [2, 3, 4, 1]