Source code for titan_pylib.algorithm.random.random
1from typing import Any
2
3
[docs]
4class Random:
5 """Random
6 乱数系のライブラリです。
7 標準ライブラリよりも高速なつもりでいます。
8 """
9
10 def __init__(self) -> None:
11 self._x = 123456789
12 self._y = 362436069
13 self._z = 521288629
14 self._w = 88675123
15
16 def _xor(self) -> int:
17 t = (self._x ^ ((self._x << 11) & 0xFFFFFFFF)) & 0xFFFFFFFF
18 self._x, self._y, self._z = self._y, self._z, self._w
19 self._w = (self._w ^ (self._w >> 19)) ^ (
20 t ^ ((t >> 8)) & 0xFFFFFFFF
21 ) & 0xFFFFFFFF
22 return self._w
23
[docs]
24 def random(self) -> float:
25 """0以上1以下の一様ランダムな値を1つ生成して返すはずです。
26 :math:`O(1)` です。
27 """
28 return self._xor() / 0xFFFFFFFF
29
[docs]
30 def randint(self, begin: int, end: int) -> int:
31 """``begin`` 以上 ``end`` **以下** のランダムな整数を返します。
32 :math:`O(1)` です。
33
34 制約:
35 :math:`begin \\leq end`
36 """
37 assert begin <= end
38 return begin + self._xor() % (end - begin + 1)
39
[docs]
40 def randrange(self, begin: int, end: int) -> int:
41 """``begin`` 以上 ``end`` **未満** のランダムな整数を返します。
42 :math:`O(1)` です。
43
44 制約:
45 :math:`begin < end`
46 """
47 assert begin < end
48 return begin + self._xor() % (end - begin)
49
[docs]
50 def shuffle(self, a: list[Any]) -> None:
51 """``a`` をインプレースにシャッフルします。
52 :math:`O(n)` です。
53
54 Args:
55 a (list[Any]): ``a`` をシャッフルします。
56 """
57 n = len(a)
58 for i in range(n - 1):
59 j = self.randrange(i, n)
60 a[i], a[j] = a[j], a[i]