random function for final project in tic tac toe - c#

I don't understand why the messagebox keeps displaying 0. For each sequence there is a direction. The purpose of the random function is to find the best point to start a new sequence. There seems to be a problem with my howfree function, I can't understand what the problem is, please help me.
public int howfree(int x, int y)
{
int freenum = 0;
int counter = 0;
foreach (GameForm.direction dirs in (GameForm.direction[]) Enum.GetValues(typeof(GameForm.direction)))
{
for (int j = 0; j < 5; j++)
{
y += Directions[(int)dirs, 0];
x += Directions[(int)dirs, 1];
if ( InBoard(y, x) && cells[y,x].cellType == Type.EMPTY)
{
counter++;
}
else
break;
}
if (counter == 5)
{
freenum++;
}
counter = 0;
}
return freenum;
}
///////////////////////////////////////////////////////////////////////////////
public Cell Randomize()
{
int row=0;
int col=0;
Random random = new Random();
int rand = 0;
//bool Found = false;
int max = 0;
int fff=0;
List<Cell> Options = new List<Cell>();
foreach (Cell CCC in cells)
{
fff=howfree(CCC.row,CCC.col);
if (fff > max)
max = fff;
}
foreach (Cell c in cells)
{
if (howfree(c.row, c.col) == max)
{
Options.Add(new Cell(c.row, c.col));
}
}
// while (!Found)
// {
rand = (int)random.NextDouble() * (Options.Count - 1);
//row = random.Next() * (Settings.Rows);
//col = random.Next() * (Settings.Cols);
MessageBox.Show(rand.ToString());
row = Options[rand].row;
col = Options[rand].col;
//}
return new Cell(row, col);
}

Why not use the overload that's designed for integers?
rand = random.Next(Options.Count);
From the MSDN documentation:
Returns a nonnegative random integer that is less than the specified maximum.

You're doing it wrong.
rand = (int)random.NextDouble() * (Options.Count - 1);
Random.NextDouble() will produce number between 0 and less than 1.0.
That means it can get up to 0.999 (You get my point) but will never be 1.
When you use explicit int cast on a fraction less bigger than 0 and less than 1 you will always get 0.
You should have done it like this:
rand = (int)(random.NextDouble() * (Options.Count - 1));
So now it will int cast after the count of options.

Related

C# user-input size of

I want to be able to create an array with random integers where the size of it is the user's choice and I can transfer the printed out array into a different textbox.
i tried
int listamount; //stores the number
if (int.TryParse(LStextbox.Text, out listamount) && LStextbox.Text.Length > 0)
{
//int.tryparse converts the string into a integer
//text.lentgh > 0 makes sure the box will not be left blank
}
else
{
}
int min = 0;
int max = 100; //i want to make the max an indefinite number, is that posible?
int num = listamount;
Random r = new Random();
int[] ar;
ar = new int[num];
for (i = 0; int =< num - 1; i++)
{
ar[i] = r.Next(min, max);
}
Ypu can use below approach:
You can achieve max int by using Int32.MaxValue statement.
By the way you have some mistakes with in the for loop, I have corrected them.
int listamount; //stores the number
if (int.TryParse(LStextbox.Text, out listamount) && LStextbox.Text.Length > 0)
{
//int.tryparse converts the string into a integer
//text.lentgh > 0 makes sure the box will not be left blank
}
else
{
}
int min = 0;
int max = Int32.MaxValue; //i want to make the max an indefinite number, is that posible?
int num = listamount;
Random r = new Random();
int[] ar;
ar = new int[num];
for (int i = 0; i <= num - 1; i++)
{
ar[i] = r.Next(min, max);
}
foreach(int y in ar)
Console.WriteLine(y);

How to generate a unique random number in a range without repeating a number in C# [duplicate]

This question already has answers here:
Random number generator with no duplicates
(12 answers)
Closed 2 years ago.
Hi everyone I am trying to generate 6 different numbers on the same line in c# but the problem that i face is some of the numbers are repeating on the same line.Here is my code to
var rand = new Random();
List<int> listNumbers = new List<int>();
int numbers = rand.Next(1,49);
for (int i= 0 ; i < 6 ;i++)
{
listNumbers.Add(numbers);
numbers = rand.Next(1,49);
}
somewhere my output is
17 23 23 31 33 48
Check each number that you generate against the previous numbers:
List<int> listNumbers = new List<int>();
int number;
for (int i = 0; i < 6; i++)
{
do {
number = rand.Next(1, 49);
} while (listNumbers.Contains(number));
listNumbers.Add(number);
}
Another approach is to create a list of possible numbers, and remove numbers that you pick from the list:
List<int> possible = Enumerable.Range(1, 48).ToList();
List<int> listNumbers = new List<int>();
for (int i = 0; i < 6; i++)
{
int index = rand.Next(0, possible.Count);
listNumbers.Add(possible[index]);
possible.RemoveAt(index);
}
listNumbers.AddRange(Enumerable.Range(1, 48)
.OrderBy(i => rand.Next())
.Take(6))
Create a HashSet and generate a unique random numbers
public List<int> GetRandomNumber(int from,int to,int numberOfElement)
{
var random = new Random();
HashSet<int> numbers = new HashSet<int>();
while (numbers.Count < numberOfElement)
{
numbers.Add(random.Next(from, to));
}
return numbers.ToList();
}
Make it a while loop and add the integers to a hashset. Stop the loop when you have six integers.
Instead of using a List, you should use an HashSet. The HashSet<> prohibites multiple identical values. And the Add method returns a bool that indicates if the element was added to the list, Please find the example code below.
public static IEnumerable<int> GetRandomNumbers(int count)
{
HashSet<int> randomNumbers = new HashSet<int>();
for (int i = 0; i < count; i++)
while (!randomNumbers.Add(random.Next()));
return randomNumbers;
}
I've switched your for loop with a do...while loop and set the stopping condition on the list count being smaller then 6.
This might not be the best solution but it's the closest to your original code.
List<int> listNumbers = new List<int>();
do
{
int numbers = rand.Next(1,49);
if(!listNumbers.Contains(number)) {
listNumbers.Add(numbers);
}
} while (listNumbers.Count < 6)
The best approach (CPU time-wise) for such tasks is creating an array of all possible numbers and taking 6 items from it while removing the item you just took from the array.
Example:
const int min = 1, max = 49;
List<int> listNumbers = new List<int>();
int[] numbers = new int[max - min + 1];
int i, len = max - min + 1, number;
for (i = min; i < max; i++) numbers[i - min] = i;
for (i = 0; i < 6; i++) {
number = rand.Next(0, len - 1);
listNumbers.Add(numbers[number]);
if (number != (len - 1)) numbers[number] = numbers[len - 1];
len--;
}
If you are not worried about the min, max, and range then you can use this.
var nexnumber = Guid.NewGuid().GetHashCode();
if (nexnumber < 0)
{
nexnumber *= -1;
}
What you do is to generate a random number each time in the loop. There is a chance of course that the next random number may be the same as the previous one. Just add one check that the current random number is not present in the sequence. You can use a while loop like: while (currentRandom not in listNumbers): generateNewRandomNumber
Paste the below in the class as a new method
public int randomNumber()
{
var random = new Random();
int randomNumber = random.Next(10000, 99999);
return randomNumber;
}
And use the below anywhere in the tests wherever required
var RandNum = randomNumber();
driver.FindElement(By.CssSelector("[class='test']")).SendKeys(**RandNum**);
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
int[] que = new int[6];
int x, y, z;
Random ran = new Random();
for ( x = 0; x < 6; x++)
{
que[x] = ran.Next(1,49);
for (y = x; y >= 0; y--)
{
if (x == y)
{
continue;
}
if (que[x] == que[y])
{
que[x] = ran.Next(1,49);
y = x;
}
}
}
listBox1.Items.Clear();
for (z = 0; z < 6; z++)
{
listBox1.Items.Add(que[z].ToString());
}
}
}

Arrange elements in a matrix of any size

This is more of a discussion than a question per se since I could solve this with code but I think there should be better ways of doing this.
I need to distribute elements in a matrix so that each quadrant of the matrix (which dimensions aren't necessarily divisible by 4) contains an equal (or as close to equal as possible) number of said elements but is located randomly within that quadrant.
The rest of the matrix needs to contain random elements of a different type.
For instance, distributing 10 elements (A) in a 9x6 matrix could look like this:
Which reveals the problem of what to do with the middle lines when a dimension is odd. It could be included on one quadrant or the other randomly (the fact that there are no As in the 3 middle columns is just chance)
I first thought of dealing with this with a recursive function that divides into quadrants and randomly places each element.
I'm halfway through coding this in C#, the idea being something like this (it doesn't work as of yet and some things are inefficient to try to make the code more readable):
private void PopulateQuadrants(ref Test5Target[,] matrix,
int xBeginQuadrant, int xEndQuadrant, int yBeginQuadrant, int yEndQuadrant, int targets)
{
if (targets == 0)
{
return;
}
else if (targets == 1)
{
Random rand = new Random();
matrix[rand.Next(xBeginQuadrant, xEndQuadrant), rand.Next(yBeginQuadrant, yEndQuadrant)]
= new Test5Target(ChosenTarget, UseAdvancedTargets);
for (int x = xBeginQuadrant; x < xEndQuadrant; x++)
{
for (int y = xBeginQuadrant; y < xEndQuadrant; y++)
{
if (matrix[x, y] == null)
{
int type = rand.Next(TargetCount);
while(type == ChosenTarget){
type = rand.Next(TargetCount);
}
matrix[x, y] = new Test5Target(rand.Next(TargetCount), UseAdvancedTargets);
}
}
}
return;
}
else
{
int[] TargetsPerQuadrant = { targets / 4, targets / 4, targets / 4, targets / 4 };
int RemaindingTargets = targets % 4;
Random rand = new Random();
while (RemaindingTargets > 0)
{ // Randomly select quadrants to allocate the Remainding targets (one may end up with 3 extra as it is now)
TargetsPerQuadrant[rand.Next(4)]++;
RemaindingTargets--;
}
PopulateQuadrants(ref matrix, xBeginQuadrant, xEndQuadrant / 2, yBeginQuadrant, yEndQuadrant / 2, TargetsPerQuadrant[0]);
PopulateQuadrants(ref matrix, xEndQuadrant / 2, xEndQuadrant, yBeginQuadrant, yEndQuadrant / 2, TargetsPerQuadrant[1]);
PopulateQuadrants(ref matrix, xBeginQuadrant, xEndQuadrant / 2, yBeginQuadrant, yEndQuadrant / 2, TargetsPerQuadrant[2]);
PopulateQuadrants(ref matrix, xEndQuadrant / 2, xEndQuadrant, yBeginQuadrant / 2, yEndQuadrant, TargetsPerQuadrant[3]);
}
}
Is there any mathematically correct or simple or something way of achieving this or should I keep going in this way.
I finally decided to just place a minimum of a fourth of all elements in each corner randomly and the remainder also randomly ignoring odd lengths or just letting it skew toward one side or the other.
private Element[,] GetCancellationTestMatrix(int rows, int columns, int targets, int types)
{
// Supposing the different types of elements are just ints and we want a concrete type
// for our targets which is contained in the variable "TargetType"
Element[,] Matrix = new int[rows, columns];
Random rand = new Random();
int currQuadRowBegin = 0;
int currQuadRowEnd = rows / 2;
int currQuadColBegin;
int currQuadColEnd;
int rowIndex;
int colIndex;
for (int i = 0; i < 2; i++)
{
currQuadColBegin = 0;
currQuadColEnd = columns / 2;
for (int j = 0; j < 2; j++)
{
for (int t = 0; t < targets / 4; t++)
{
rowIndex = rand.Next(currQuadRowBegin, currQuadRowEnd);
colIndex = rand.Next(currQuadColBegin, currQuadColEnd);
while (Matrix[rowIndex, colIndex] != null)
{
rowIndex = rand.Next(currQuadRowBegin, currQuadRowEnd);
colIndex = rand.Next(currQuadColBegin, currQuadColEnd);
}
Matrix[rowIndex, colIndex] = new Element(TargetType);
}
currQuadColBegin = currQuadColEnd++;
currQuadColEnd = columns - 1;
}
currQuadRowBegin = currQuadRowEnd++;
currQuadRowEnd = rows - 1;
}
// Some targets may be unarranged yet (up to three)
int remainding = targets % 4;
while (remainding > 0)
{
rowIndex = rand.Next(0, rows);
colIndex = rand.Next(0, columns);
while (Matrix[rowIndex, colIndex] != null)
{
rowIndex = rand.Next(0, rows);
colIndex = rand.Next(0, columns);
}
Matrix[rowIndex, colIndex] = new Element(TargetType);
remainding--;
}
// Fill the remainding elements of the target matrix with other targets
List<int> fakeTargets = new List<int>(rows * columns - targets);
// If we are placing 10 targets in a 9x6 matrix then we need to place an extra
// 9 * 6 - 10 = 34 targets and if we have, say, 4 types then we can divide that
// between 4-1 (for the target type)
int targetsOfEachType = (rows * columns - targets) / types-1;
for (int i = 0; i < types; i++)
{
if (i == TargetType) continue;
for (int j = 0; j < targetsOfEachType; j++)
{
fakeTargets.Add(i);
}
}
int tmp;
while (fakeTargets.Count < rows * columns - targets)
{
tmp = rand.Next(types);
while (tmp == TargetType)
{
tmp = rand.Next(types);
}
fakeTargets.Add(tmp);
}
Shuffle(fakeTargets); // Assume this method shuffles the list of fakeTargets
tmp = 0;
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < columns; j++)
{
if (Matrix[i, j] != null) continue;
Matrix[i, j] = new Element(fakeTargets[tmp++]);
}
}
return Matrix;
}
Of course, I'm not claiming this is a good solution, just one that works for me at least for now. I'll leave some time so that someone can post a better answer or some corrections over mine before I check this as the answer.

Can I find the number of digits of a BigInteger in C#?

I am solving this problem, in which they ask for the index of the first Fibonacci number of 1000 digits, and my first idea was something similar to:
BigInteger x = 1;
BigInteger y = 1;
BigInteger tmp = 0;
int currentIndex = 2;
while (x.NoOfDigits < 1000)
{
tmp = x + y;
y = x;
x = tmp;
currentIndex++;
}
return currentIndex;
However, as far as I can tell, there is no method for counting the number of digits of a BigInteger. Is this true? One way of circumventing it is to use the .ToString().Length method of a BigInteger, but I'm told that string processing is slow.
A BigInteger also has a .ToByteArray(), and I thought of converting a BigInteger to a byte array and checking the length of that array - but I don't think that this uniquely determines the number of digits in the BigInteger.
For what it's worth, I implemented another way of solving it, which is manually storing the Fibonacci numbers in array, and which stops as soon as the array is full, and I compared this to the .ToString-based method, which is about 2.5 times slower, but the first method takes 0.1 second, which also seems like a long time.
Edit: I've tested the two suggestions in the answers below (the one with BigInteger.Log and the one with MaxLimitMethod). I get the following run times:
Original method: 00:00:00.0961957
StringMethod: 00:00:00.1535350
BigIntegerLogMethod: 00:00:00.0387479
MaxLimitMethod: 00:00:00.0019509
Program
using System;
using System.Collections.Generic;
using System.Numerics;
using System.Diagnostics;
class Program
{
static void Main(string[] args)
{
Stopwatch clock = new Stopwatch();
clock.Start();
int index1 = Algorithms.IndexOfNDigits(1000);
clock.Stop();
var elapsedTime1 = clock.Elapsed;
Console.WriteLine(index1);
Console.WriteLine("Original method: {0}",elapsedTime1);
Console.ReadKey();
clock.Reset();
clock.Start();
int index2 = Algorithms.StringMethod(1000);
clock.Stop();
var elapsedTime2 = clock.Elapsed;
Console.WriteLine(index2);
Console.WriteLine("StringMethod: {0}", elapsedTime2);
Console.ReadKey();
clock.Reset();
clock.Start();
int index3 = Algorithms.BigIntegerLogMethod(1000);
clock.Stop();
var elapsedTime3 = clock.Elapsed;
Console.WriteLine(index3);
Console.WriteLine("BigIntegerLogMethod: {0}", elapsedTime3);
Console.ReadKey();
clock.Reset();
clock.Start();
int index4 = Algorithms.MaxLimitMethod(1000);
clock.Stop();
var elapsedTime4 = clock.Elapsed;
Console.WriteLine(index4);
Console.WriteLine("MaxLimitMethod: {0}", elapsedTime4);
Console.ReadKey();
}
}
static class Algorithms
{
//Find the index of the first Fibonacci number of n digits
public static int IndexOfNDigits(int n)
{
if (n == 1) return 1;
int[] firstNumber = new int[n];
int[] secondNumber = new int[n];
firstNumber[0] = 1;
secondNumber[0] = 1;
int currentIndex = 2;
while (firstNumber[n-1] == 0)
{
int carry = 0, singleSum = 0;
int[] tmp = new int[n]; //Placeholder for the sum
for (int i = 0; i<n; i++)
{
singleSum = firstNumber[i] + secondNumber[i];
if (singleSum >= 10) carry = 1;
else carry = 0;
tmp[i] += singleSum % 10;
if (tmp[i] >= 10)
{
tmp[i] = 0;
carry = 1;
}
int countCarries = 0;
while (carry == 1)
{
countCarries++;
if (tmp[i + countCarries] == 9)
{
tmp[i + countCarries] = 0;
tmp[i + countCarries + 1] += 1;
carry = 1;
}
else
{
tmp[i + countCarries] += 1;
carry = 0;
}
}
}
for (int i = 0; i < n; i++ )
{
secondNumber[i] = firstNumber[i];
firstNumber[i] = tmp[i];
}
currentIndex++;
}
return currentIndex;
}
public static int StringMethod(int n)
{
BigInteger x = 1;
BigInteger y = 1;
BigInteger tmp = 0;
int currentIndex = 2;
while (x.ToString().Length < n)
{
tmp = x + y;
y = x;
x = tmp;
currentIndex++;
}
return currentIndex;
}
public static int BigIntegerLogMethod(int n)
{
BigInteger x = 1;
BigInteger y = 1;
BigInteger tmp = 0;
int currentIndex = 2;
while (Math.Floor(BigInteger.Log10(x) + 1) < n)
{
tmp = x + y;
y = x;
x = tmp;
currentIndex++;
}
return currentIndex;
}
public static int MaxLimitMethod(int n)
{
BigInteger maxLimit = BigInteger.Pow(10, n - 1);
BigInteger x = 1;
BigInteger y = 1;
BigInteger tmp = 0;
int currentIndex = 2;
while (x.CompareTo(maxLimit) < 0)
{
tmp = x + y;
y = x;
x = tmp;
currentIndex++;
}
return currentIndex;
}
}
Provided that x > 0
int digits = (int)Math.Floor(BigInteger.Log10(x) + 1);
will get the number of digits.
Out of curiosity, I tested the
int digits = x.ToString().Length;
approach. For 100 000 000 iterations, it's 3 times slower than the Log10 solution.
Expanding on my comment--instead of testing based on number of digits, test based on exceeding a constant that has the upper limit of the problem:
public static int MaxLimitMethod(int n)
{
BigInteger maxLimit = BigInteger.Pow(10, n);
BigInteger x = 1;
BigInteger y = 1;
BigInteger tmp = 0;
int currentIndex = 2;
while (x.CompareTo(maxLimit) < 0)
{
tmp = x + y;
y = x;
x = tmp;
currentIndex++;
}
return currentIndex;
}
This should result in a significant performance increase.
UPDATE:
This is an even quicker method on .NET 5 (since GetBitLength() is required):
private static readonly double exponentConvert = Math.Log10(2);
private static readonly BigInteger _ten = 10;
public static int CountDigits(BigInteger value)
{
if (value.IsZero)
return 1;
value = BigInteger.Abs(value);
if (value.IsOne)
return 1;
long numBits = value.GetBitLength();
int base10Digits = (int)(numBits * exponentConvert).Dump();
var reference = BigInteger.Pow(_ten, base10Digits);
if (value >= reference)
base10Digits++;
return base10Digits;
}
The slowest part of this algorithm for large values is the BigInteger.Pow() operation. I have optimized the CountDigits() method in Singulink.Numerics.BigIntegerExtensions with a cache that holds powers of 10, so check that out if you are interested in the fastest possible implementation. It caches powers up to exponents of 1023 by default but if you want to trade memory usage for faster performance on even larger values you can increase the max cached exponent by calling BigIntegerPowCache.GetCache(10, maxSize) where maxSize = maxExponent + 1.
On an i7-3770 CPU, this library takes 350ms to get the digit count for 10 million BigInteger values (single-threaded) when the digit count <= the max cached exponent.
ORIGINAL ANSWER:
The accepted answer is unreliable, as indicated in the comments. This method works for all numbers:
private static int CountDigits(BigInteger value)
{
if (value.IsZero)
return 1;
value = BigInteger.Abs(value);
if (value.IsOne)
return 1;
int exp = (int)Math.Ceiling(BigInteger.Log10(value));
var test = BigInteger.Pow(10, exp);
return value >= test ? exp + 1 : exp;
}

Solving with only loop

The number 124 has the property that it is the smallest number whose first three multiples contain the digit 2. Observe that
124*1 = 124, 124*2 = 248, 124*3 = 372 and that 124, 248 and 372 each contain the digit 2. It is possible to generalize this property to be the smallest number whose first n multiples each contain the digit 2. Write a function named smallest(n) that returns the smallest number whose first n multiples contain the digit 2. Hint: use modulo base 10 arithmetic to examine digits.
Its signature is
int smallest(int n)
Examples
If n is return because
4 624 because the first four multiples of 624 are 624, 1248, 1872, 2496 and they all contain the
digit 2. Furthermore 624 is the smallest number whose first four multiples contain the digit 2.
5 624 because the first five multiples of 624 are 624, 1248, 1872, 2496, 3120. Note that 624 is also
the smallest number whose first 4 multiples contain the digit 2.
6 642 because the first five multiples of 642 are 642, 1284, 1926, 2568, 3210, 3852
7 4062 because the first five multiples of 4062 are 4062, 8124, 12186, 16248, 20310, 24372, 28434.
Note that it is okay for one of the multiples to contain the digit 2 more than once (e.g., 24372).
I tried to solve this by this way
//Its a incomplete code
public static int smallest(int n)
{
int i = 1;
for (; ; )
{
int temp = 0;
int myNum = 0;
for (int j = 1; j <= n; j++)
{
myNum = i * j;
//check for condition
}
//if condition ture break
}
}
But I am stick to the problem is I cannot create hard coded n times variable.. Can you help me proceed that?
You may assume that such a number is computable on a 32 bit machine, i.e, you do not have to detect integer overflow in your answer.
using System;
using System.Collections.Generic;
namespace firstconsoleproject
{
class MainClass
{
public static void Main (string[] args)
{
int first=4;
int c=0;
int ax;
int ai;
Console.WriteLine ("please enter n");
ax = Convert.ToInt32( Console.ReadLine());
for (int i=11 ; ax>0 ;)
{ if (first==1)
{
c = ax+1;
i++;
}
c--;
ai=i*c;
for (int ten=10 ; ; )
{
if(ai%ten==2)
{
first=0;
break;
}else if (ai==0)
{
first=1;
break;
}
ai/=10;
}
if (c==0){Console.WriteLine("number is "+i);break;}
}Console.ReadKey ();
}
}
}
// Function smallest n
public int smallest(int a)
{
int temp = 0, holder = 0, k = 0;
if (a <= 0) return 0;
else
{
for (int i = 100; i < Int16.MaxValue; i++)
{
int count = 0;
k = 0;
int[] array = new int[a];
for (int j = 1; j < 9; j++)
{
holder = i * j;
temp = holder;
while (temp > 0)
{
int rem = temp % 10;
if (rem == 2)
{
count++;
if (k < a)
{
array[k] = j;
k++;
break;
}
}
temp /= 10;
}
if (count == a)
{
int countTemp = 0;
for (int h = 0; h < a; h++)
{
if (h + 1 < a)
{
if (array[h + 1] == array[h] + 1 && array[0] == 1 && array[h] > 0)
{
countTemp++;
if (countTemp == a - 1)
return i;
}
}
}
}
}
}
}
return 0;
}
public static int smallest(int n)
{
int i = 1;
for (; ; )
{
int contain = 0;
int temp = 0;
int myNum = 0;
for (int j = 1; j <= n; j++)
{
myNum = i * j;
temp = myNum;
while (true)
{
if (temp % 10 == 2)
{
contain++;
break;
}
temp = temp / 10;
if (temp <= 0)
break;
}
}
if (contain == n)
break;
i++;
}
return i;
}

Categories

Resources