random number generator without repetaion - vb.net

I am new to programming. I am making an application in VB.net. I want that on loading of a particular form, a random number will be generated as 1 or 2 or 3. When the form would be loaded 2nd time, a random number would be generated from 1, 2 or 3 but different than it is generated as earlier. And when form would be loaded 3rd time, a random number would be generated from 1, 2 or 3 but different than the previous 2 times, i.e. no repetition of the random numbers.
For example if on first time form load, random number is 3, then second time it should be either 1 or 2. And if second time form load RN is 2, then third time form load it should be 1.
I will be thankful if someone could help me in writing this code in vb.net.

You can get the next random from the list and then remove it so it can't be picked again.
Dim rndList As New List(Of Integer) From {1,2,3}
Static rnd As New Random
Do Until rndlist.Count = 0
'get the index by random
Dim nextValue As Integer = rnd.Next(0, rndList.Count))
'this is the value at the index
Debug.Write(rndList(nextValue))
'remove this item
rndList.RemoveAt(nextValue)
Loop

Related

How do I generate random numbers from a list of specific numbers that I have?

I want my application to populate random sets of numbers using a list of specific numbers that i chose. For example; I have a set of numbers (1,3,5,9,21,70,56). I want to be able to randomize the order in which these numbers are selected. Is that possible?
If you want to generate a list of 1000 numbers using only those you gave:
Dim r as New Random()
Dim thousand as New List(Of Integer)(1000)
'short way to create an array
Dim onlyFrom = {1,3,5,9,21,70,56}
For i = 1 to 1000
thousand.Add(onlyFrom(r.Next(0, onlyFrom.Length)))
Next i
It repeatedly asks a Random for a random integer between 0 and the array length. Next() may return the lower number, but never the upper number. Documentation
If you want to shuffle those numbers you gave into a random order, easy way to use LINQ:
Dim r as New Random()
Dim onlyFrom = {1,3,5,9,21,70,56}
Dim shuffled = onlyFrom.OrderBy(Function(x) r.Next()).ToArray()
Note: Do not use New Random() in a loop
Randomize()
Dim NumberList= {1,3,5,9,21,70,56}
' Generate random value between 1 and 7, or use NumberList length to make it generic
Dim value As Integer = CInt(Int(( 7 * Rnd()) + 1))
return NumberList(value-1)
* The above code may produce the same value multiple times in a series. so if the requirement is that a different value be produced from the array each time when the code is called seven times, this wouldn't work *
If the requirement is to have a different value from the array each time for the first 7 calls, you may use Shuffle function as laid out here Shuffling an array of strings in vb.net

Count Number of instances of text in a text file - VB

I have a need to parse a large, delimited text file (28 million lines plus) and count the number of instances of a particular piece of text in the text file using VB 2015.
The structure of the lines is thus;
123|WD7|ELU|SOD|010116
456|WD9|LFT|AST|010116
135|WD7|TFT|THY|010116
154|AED|ELU|SOD|030116
etc, etc....
My exact requirements are to identify each of the entries in delimited field 2 and delimited field 4 and then count the number of instances of each.
So from the lines above, the items in field 2 would be WD7, WD9 and AED and the number of instances would be WD7 x 2, WD9 x 1 and AED x 1.
Similarly, the items in field 4 would be SOD, AST, THY and SOD and the number of instances would be SOD x 2, THY x 1, AST x 1.
The items in field 2 and field 4 will not be known prior to parsing the file and indeed the parsing is to identify what text is contained in these fields and how many times.
Hopefully that is clear and many thanks for any guidance.
Steve
try this:
Dim textfile As String = "C:/test/test.txt"
Dim stream_reader As New StreamReader(textfil_file)
Dim line As String
line = stream_reader.ReadLine()
Do While Not (line Is Nothing)
Dim parts As String() = line.Split("|")
For Each part In parts
'display them in msgboxes or do whatever you like with them
MsgBox(part(1))
MsgBox(part(3))
Next
line = stream_reader.ReadLine()
Loop
stream_reader.Close()

How to make random number generator not repeat the same number more than twice vb? [duplicate]

I'm trying to randomize a number in VB.NET 3 times. And each time I randomize a number it should be different from the other two numbers.
For example I have 3 integers. Int1,Int2 and Int3. I will randomize Int1 between 1-10 , and then I will randomize Int2 between 1-10 however the value shouldn't be equal to the value I randomized in Int1 and the same goes for Int3 it shouldn't equal to Int1 and Int2.
I have figured out how to randomize a number, this is the code I'm using:
Dim RndNumber As Random
Dim num,num2 As Integer
RndNumber = New Random
num = RndNumber.Next(1, 11)
num2 = RndNumber.Next(1, 11)
Now I'm stuck on how I make num2 randomize a number between 1-10 that is not equals to num.
I appreciate any help, thanks.
In all the examples, RNG is a random number generator created from the NET Random class:
Private RNG = New Random()
Linq
If you only need two or three, you could loop until the current pick is not in the result set. But this is even simpler using some extension methods:
Dim nums = Enumerable.Range(1, 10).
OrderBy(Function(r) RNG.Next).
Take(3).
ToArray()
This starts with all numbers between 1 and 10, puts them in random order, takes the first 3 and stores them in the nums array. I used the multiline form, breaking after the .s to illustrate the steps.
Just change the range, size/count and Take() element as needed. For instance, for something like a lottery with 5 unique numbers 1-69 (condensed form):
Dim winners = Enumerable.Range(1, 69).OrderBy(Function(r) RNG.Next()).Take(5).ToArray()
Dim powerball = Enumerable.Range(1, 26).OrderBy(Function(r) RNG.Next()).Take(1).First
Since the Powerball can be a repeat of the first numbers, it comes from its own pool. Since we only want one, we dont need an array, just the First().
Manual
It is good to know the logic for these things, so this shows a manual version. This does it differently, by picking and actually checking random values:
' picked value storage
Dim picks As New List(Of Int32)
Dim pick As Int32 ' current candidate
Do
pick = RNG.Next(1, 11)
If picks.Contains(pick) = False Then
picks.Add(pick)
End If
Loop Until picks.Count = 3
Rather than loose vars, this uses a list to hold the picks. This makes it easy to see if the current pick has already been selected. For more than just a few values, use a HashSet(Of Int32) rather than a List for performance.
Random Pairs
To create a random sets of numbers with 2 of each, such as for a matching game, just double up the base pool of values then put them in random order:
' create pool of 2 values each for 1-13
Dim nums = Enumerable.Range(1, 13).ToArray()
' concat the set to make 2 of each value, randomize
Dim pool = nums.Concat(nums).OrderBy(Function(r) RNG.Next).ToArray()
For a manual method you would have to check the count of each value in the loop.
'Use up' Picks
One more variation is when you need a pool of randoms used periodically, but you don't know how many you will need in advance. Examples would be the balls for a BINGO game or a deck of cards.
Rather than a global indexer pointing to the last slot used (or next slot to use), a Stack(Of T) (or a Queue) will "use up" values as you need them:
' create, randomize pool of 100 ints
Dim nums = Enumerable.Range(1, 100).OrderBy(Function(r) RNG.Next).ToArray
' use array to create Stack<T>
Dim shoe As New Stack(Of Int32)(nums)
' same as:
Dim shoe = New Stack(Of Int32)(Enumerable.Range(1, 100).
OrderBy(Function(r) RNG.Next).ToArray())
This starts basically the same with 100 integers, randomized and stored in an array, but there is no Take(n) because we want them all. They values are then stored in a stack collection. Using it:
Console.WriteLine(shoe.Count)
For n As Int32 = 1 To 3
Console.WriteLine("Picked #{0}", shoe.Pop)
Next
Console.WriteLine(shoe.Count)
When you Pop a value it is removed from the collection automatically. If you use a lot of values from the shoe, you will want to check the count to make sure it is not empty.
100
Picked #12
Picked #69
Picked #53
97
After drawing 3 values, the shoe has only 97 values remaining.
Random Notes
In all cases your Random generator should be a form level object which you create once. Never create them in a loop or you will likely get the same value over and over.
The OrderBy(Function(r) RNG.Next) method of randomizing is usually good enough for casual use, but it is inefficient. If you will be randomizing large sets and/or using it frequently you should consider using a proper shuffle such as the Fisher-Yates shuffle shown here.

Dice Roller Populate TextBox(s)

I am still learning basic programming, literally off Visual Basic 2012 v11.
Here is what I am stumped on:
I made a stupid-simple Table-Top Role-Playing Character Log application.
I made a simple dice roller/"random number" procedure and set it to fill a ListBox with each button click of "ROLL" until the max of 6 was reached. That worked fine.
However, I changed my app to link with a database to store simple character information for all of the people playing,etc. Which means I now have separate dataset TextBoxes for each click of "ROLL". Would someone please advise me on the best way to populate one TextBox per button click with a maximum of 6 clicks, please?
I was using a loop to fill the ListBox with exactly 6 entries, and started that line of thought for filling the TextBoxes, but my late-night tired brain cannot find a way to fill ONE box EACH TIME instead of all boxes every single time.
THANK YOU FOR YOUR HELP!
My Code:
Private Sub btnRoll_Click(sender As Object, e As EventArgs) Handles btnRoll.Click
'Roll a character stat up to 6 and add it to the lisbox
'D20 is standard die, but stats below 6 are forgiven for this campagin
Dim Dice As New Random
Dim DiceRoll As Integer = Dice.Next(6, 20)
Dim intCount As Integer = 0
Dim Stat As String = Convert.ToString(DiceRoll)
Do While intCount < 7
Loop
End Sub
I don't believe you've included enough information to give an informed answer.
From my understanding, you'd like to take the result of the roll, and input it into one of several textboxes (you haven't given a number of textboxes, but you'd like it done in less than 6 clicks).
Depending on what the different fields will be, you may want to include your calculations within the loop, along with this, to specify the output and then roll again X times within the loop:
Do While intcount < 7
Select Case intcount
Case 1
txtBox1 = stat
Case 2
txtBox2 = stat
Case 3
txtBox3 = stat
Case 4
txtBox4 = stat
Case 5
txtBox5 = stat
Case 6
txtBox6 = stat
Case Else
'Nothing if not specified with other arguments.
'Roll again
stat = Convert.ToString(Dice.Next(6,20))
Loop

Visual Basic- random number

I have some VB code that gives me a random number, 1 between 20 (X). However, within 20 attempts, I will get the same number twice. How can I get a sequence of random numbers without any of them repeating? I basically want 1-20 to show up up in a random order if I click a button 20 times.
Randomize()
' Gen random value
value = CInt(Int((X.Count * Rnd())))
If value = OldValue Then
Do While value = OldValue
value = CInt(Int((X.Count * Rnd())))
Loop
End If
For 1 to 20, use a data structure like a LinkedList which holds numbers 1 to 20. Choose an index from 1 to 20 at random, take the number at that index, then pop out the number in that location of the LinkedList. Each successive iteration will choose an index from 1 to 19, pop, then 1 to 18, pop, etc. until you are left with index 1 to 1 and the last item is the last random number. Sorry for no code but you should get it.
The concept is, you have to add the generated random number into a list, and before adding it into the list, make sure that the new number is not contains in it. Try this code,
Dim xGenerator As System.Random = New System.Random()
Dim xTemp As Integer = 0
Dim xRndNo As New List(Of Integer)
While Not xRndNo.Count = 20
xTemp = xGenerator.Next(1, 21)
If xRndNo.Contains(xTemp) Then
Continue While
Else
xRndNo.Add(xTemp)
End If
End While
[Note: Tested with IDE]
for that purpose, you need to store all previous generated number, not just one, as u did in OldValue named variable. so, store all previously generated numbers somewhere (list). and compare the newly generated number with all those in list, inside ur while loop, and keep generating numbers, while number is not equal to any of one in list..
Add the numbers to a list and then pick them in a random order, deleting them as they are picked.
Dim prng As New Random
Dim randno As New List(Of Integer)
Private Sub Button1_Click(sender As Object, _
e As EventArgs) Handles Button1.Click
If randno.Count = 0 Then
Debug.WriteLine("new")
randno = Enumerable.Range(1, 20).ToList 'add 1 to 20 to list
End If
Dim idx As Integer = prng.Next(0, randno.Count) 'pick a number
Debug.WriteLine(randno(idx)) 'show it
randno.RemoveAt(idx) 'remove it
End Sub