Cross-Implementation Deterministic Array # shuffle

Możliwe jest przekazanie generatora liczb losowych doArray#shuffle to sprawia, że ​​losowanie jest deterministyczne.

Na przykład w MRI 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]

Jednak przypadkowa implementacja generatora liczb losowych nie jest określona. Z tego powodu inne implementacje Rubiego mają różne wyniki.

W Rubinius 2.0.0rc1 (1.9.3 wydanie 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]

Nawiasem mówiąc, jruby-1.7.1 używa tego samego generatora liczb losowych co MRI 1.9.3p327, ale jest to przypadkowe, nie gwarantowane.

Aby uzyskać deterministyczne tasowanie deterministyczne w całej implementacji, chciałbym przekazać niestandardowy generator liczb losowychArray#shuffle. Myślałem, że to będzie banalne, ale okazuje się dość skomplikowane.

Oto, co próbowałem najpierw w MRI:

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]

Spodziewałem sięNoMethodError informując mnie o interfejsie, który musiałem wdrożyć.

Jakieś spostrzeżenia?

AKTUALIZACJA:

Jak wskazuje @glebm,NotRandom dziedzicznyKernel#rand, który jest potrzebny interfejs. Jest to łatwe do obejścia, ale niestety nie oferuje rozwiązania.

class NotRandom
  def rand(*args)
    0
  end
end

W RBX:

[1, 2, 3, 4].shuffle(random: NotRandom.new) # => [1, 2, 3, 4]

W MRI:

[1, 2, 3, 4].shuffle(random: NotRandom.new) # => [2, 3, 4, 1]

questionAnswers(1)

yourAnswerToTheQuestion