Last active
October 7, 2018 21:19
-
-
Save vbjay/35dea6a965de4668f195b014244f97cc to your computer and use it in GitHub Desktop.
Random numbers generator
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<Query Kind="VBProgram"> | |
<Namespace>System.Security.Cryptography</Namespace> | |
</Query> | |
Sub Main | |
Dim numRange As Integer = Integer.Parse(Util.ReadLine("Enter how many random numbers you want", "1000000")) | |
Dim min As Integer = Integer.Parse(Util.ReadLine("Enter smallest number you want", "0")) | |
Dim max As Integer = Integer.Parse(Util.ReadLine("Enter largest number you want", "900")) | |
Dim msg As String = $"creating {numRange:n0} random numbers" | |
msg.Dump | |
Dim sw As New Stopwatch | |
sw.Start | |
Dim bytes = GetRandomBytes(numRange) | |
sw.Stop | |
Dim timing = $"Bytes filled in: {sw.Elapsed}" | |
timing.Dump | |
sw.Restart | |
Dim output = ToInt(bytes) | |
sw.Stop | |
timing = $"Array generated in: {sw.Elapsed}" | |
timing.Dump | |
sw.Restart | |
output = ForceRange(output, min, max) | |
sw.Stop | |
timing = $"Array forced to range in: {sw.Elapsed}" | |
timing.Dump | |
Dim byNumber = output.GroupBy(Function(n) n).Select(Function(g) New With {Key .Number = g.Key, Key .Count = g.Count}).OrderByDescending(Function(n) n.Count).ToArray | |
byNumber.Dump | |
Dim multiples = byNumber.Where(Function(g) g.Count > 1).OrderByDescending(Function(g) g.Count).ThenBy(Function(n) n.Number).ToArray | |
msg = $"There are {byNumber.Except(multiples).Count:n0} non repeated numbers that were generated. {byNumber.Except(multiples).Count / byNumber.Count:P} and {multiples.Count:n0} numbers were repeated. The numbers ranged between {output.Min} and {output.max}." | |
msg &= If(multiples.Count > 0, $" The smallest number that was reapeated the most is {multiples.First.Number:n0} and was repeated {multiples.First.Count:n0} times.", "") | |
msg.Dump | |
byNumber.Take(10).Chart(Function(num) num.count, Function(num) num.number, Util.SeriesType.BevelledPie).DumpInline("Top 10 numbers") | |
End Sub | |
' Define other methods and classes here | |
Function ForceRange(numbers As Integer(), Min As Integer, max As Integer) As Integer() | |
Return numbers.Select(Function(n) ((n - min) Mod (max + 1 - min) + max + 1 - min) Mod (max + 1 - min) + min).ToArray | |
End Function | |
Function ToInt(bytes As Byte()) As Integer() | |
Const requiredLen = 4 ' 4 bytes in an int32(vb integer) | |
If bytes.Count Mod requiredLen <> 0 Then Throw New ArgumentException($"Must be a Byte() with a length divisible by {requiredLen}") | |
Return Enumerable.Range(0, bytes.Count \ 4). | |
Select(Function(n) {bytes(n * 4), bytes(n * 4 + 1), bytes(n * 4 + 2), bytes(n * 4 + 3)}).' create batches of (4 byte) arrays | |
Select(Function(b) BitConverter.ToInt32(b, 0)).' for each batch convert the bytes into an integer | |
ToArray | |
End Function | |
Function GetRandomBytes(Size As Integer) As Byte() | |
Using rng As RNGCryptoServiceProvider = RNGCryptoServiceProvider.Create | |
Dim data = Enumerable.Range(0, size * 4).Select(Function(n) CByte(0)).ToArray ' Array of bytes of the correct size | |
rng.GetNonZeroBytes(data) 'bytes filled | |
Return data | |
End Using | |
End Function |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment