Factorial(s) of N numbers in for loop - c#

I am working on a problem from CodeChef where I need to calculate the factorial of n numbers.
The user inputs a number which determines how many ints to perform a factorial calculation on and then inputs the numbers to calculate.
My problem is with the multiplication itself. For example if I have an int == 5 then the result will be 20 (it will calculate n by the last factorial only, not by all of them)
Here is where the problem exists:
for(int x = 0; x < _numbersToProcess.Length; x++) {// Loop throuigh Array by index
for (int y = 1; y < _numbersToProcess[x]; y++) {// Y is equal to less than index x
_result[x] = _numbersToProcess[x] * y;// Multiply x by y then add to array
}
}
The outer loop defines how many calculations to perform.
The inner loop calulates the factorials by iterating through each index of _numberToProcess and multiplying it by every number less than the number to be calculated on.
The problem is that the factorial calculation overwrites itself,
for example:
factorial of 5 result: 20 but it should be 120 (it overwrites itself until it reaches the last multiplier)
So I tried the following:
_result[x] = _numbersToProcess[x] *= y;
This is obviously the same as _numbersToProcess[x] = _numbersToProcess[x] * y;
But this gives a completley different result:
If we again input 5 then this will result in the output of -1899959296.
I know I can easily copy and paste from other submissions but I want to know why my method does not result in the correct output.
Here is the method in its entirety:
int _numbers = int.Parse(Console.ReadLine());// Get number of ints to calculate
int[] _numbersToProcess = new int[_numbers];// Array of inputs
int[] _result = new int[_numbers];
int i = 0;
while(i < _numbersToProcess.Length) {
_numbersToProcess[i] = int.Parse(Console.ReadLine());
i++;
}
for(int x = 0; x < _numbersToProcess.Length; x++) {// Loop throuigh Array by index
for (int y = 1; y < _numbersToProcess[x]; y++) {// Y is equal to less than index x
_result[x] = _numbersToProcess[x] *= y;// Multiply x by y then add to array
}
}
for (int n = 0; n < _result.Length; n++) {// Y is equal to less than index x
Console.WriteLine(_result[n]);// Write to console
}
Console.ReadLine();

int _numbers = int.Parse(Console.ReadLine());// Get number of ints to calculate
int[] _numbersToProcess = new int[_numbers];// Array of inputs
int[] _result = new int[_numbers];
int i = 0;
while(i < _numbersToProcess.Length) {
_numbersToProcess[i] = int.Parse(Console.ReadLine());
i++;
}
for (int x = 0; x < _numbersToProcess.Length; x++)
{// Loop throuigh Array by index
int fact = 1;
for (int y = 1; y <= _numbersToProcess[x]; y++)
{// Y is equal to less than index x
fact = fact*y;
}
_result[x] = fact;
}
for (int n = 0; n < _result.Length; n++) {// Y is equal to less than index x
Console.WriteLine(_result[n]);// Write to console
}
Console.ReadLine();
Problem is with your inner for loop. here, you are always, overriding result array.
i.e for y=5;
inner for loop executes for 5 times.
iteration -1 :
y=1,
_numbersToProcess[5]=5
_result[x]=5
iteration -2 :
y=2,
_numbersToProcess[5]=10
_result[x]=10
iteration -3 :
y=3,
_numbersToProcess[5]=30
_result[x]=30
.
.
.
.
.
thus it goes for 12 iteration as your _numbertoprocess[5] is changing and stops once it reaches less than 0 i.e -1899959296.
iteration 12:
_numbertoprocess[5] = -1899959296.
i.e you are changing numbertoprocess everytime in your inner for loop.
you can verify it by adding
Console.WriteLine(y);
Console.WriteLine(_numbersToProcess[x]);
Console.WriteLine(_result[x]);
in your inner for loop.

for (int y = 1; y < _numbersToProcess[x]; y++) {// Y is equal to less than index x
_result[x] = _numbersToProcess[x] *= y;// Multiply x by y then add to array
}
In loop condition y < _numberToProcess[x];. It compare between y and _numberToProcess[x] array value
I think you should edit loop condition to y < x
Be lucky.

Here i'm using a recursive function factorial
/* Factorial function*/
int factorial (int n)
{
return (n*factorial(n-1))
}
int _numbers = int.Parse(Console.ReadLine());// Get number of ints to calculate
int[] _numbersToProcess = new int[_numbers];// Array of inputs
int[] _result = new int[_numbers];
int i = 0;
while(i < _numbersToProcess.Length) {
_numbersToProcess[i] = int.Parse(Console.ReadLine());
i++;
}
for(int x = 0; x < _numbersToProcess.Length; x++) {// Loop throuigh Array by index
_result[x] = factorial(_result[x])// Multiply x by y then add to array
}
}
for (int n = 0; n < _result.Length; n++) {// Y is equal to less than index x
Console.WriteLine(_result[n]);// Write to console
}
Console.ReadLine();

#include <stdio.h>
int main()
{
int c, n, fact = 1;
printf("Enter a number to calculate it's factorial\n");
scanf("%d", &n);
for (c = 1; c <= n; c++)
fact = fact * c;
printf("Factorial of %d = %d\n", n, fact);
return 0;
}

Check this out maybe it will help...
#include <stdio.h>
#include <stdlib.h>
long f(int n) {
if (n==0) return 1;
else return n * f(n-1);
}
int main(int argc, char *argv[]) {
long *factorials;
int *inputs;
int n;
printf("Enter number n = ");
scanf("%d", &n);
factorials = (long *) malloc(n*sizeof(long));
inputs = (int *) malloc(n*sizeof(int));
for (int i = 0; i < n; i++) {
long k;
printf("Enter %d number = ", i + 1);
scanf("%ld", &k);
inputs[i] = k;
factorials[i] = f(k);
}
for (int i = 0; i < n; i++) {
printf("Factorial for %d = %ld\n", inputs[i], factorials[i]);
}
return 0;
}

Related

Factorials of Big numbers without BigInteger (C#)

Is there an algorithm for calculating a factorial without using System.Numerics library? We receive an int number and we need to return factorial of this number as string(if n = 30, we should return "265252859812191058636308480000000", if n = 70, we should return "11978571669969891796072783721689098736458938142546425857555362864628009582789845319680000000000000000" ect. Numbers are very big)
I tried to find out, did anyone already write an article about that, but I didn't find anything.
It suffices to implement multiplication of a large number as a string by a small integer.
Illustration: 12! = 11! x 12 is obtained by multiplying every digit by 12 and summing (with shifts):
39916800
36
108
108
12
72
96
0
0
---------
479001600
A lazy solution. It is possible to evaluate the factorial with just BigNum addition, replacing the multiplications by successive additions. (For n!, we will perform 1+2+3+...n-1 additions. This is acceptable for moderate n.)
The computation uses two pre-allocated string (arrays of char), which are initially filled with null bytes (Writeline skips them). When adding from right to left, we stop when we meet a null.
int n = 20;
// Factorial and temporary string; 100! fits in 158 digits
const int N = 158;
char[] f = new char[N], t = new char[N];
f[N - 1] = '1'; // 1!
// Product up to n by successive additions
for (int i = 2; i <= n; i++)
{
// t= f
f.CopyTo(t, 0);
for (int j = 0; j < i - 1; j++)
{
// f+= t, repeated i-1 times
int c = 0; // Carry
for (int k = N - 1; k >= 0; k--)
{
if (t[k] == 0 && c == 0) break; // Significant part exhausted
int d = Math.Max(0, t[k] - '0') + Math.Max(0, f[k] - '0') + c;
c= d / 10; d = d % 10; f[k] = (char)(d + '0'); // Next carry/digit
}
}
Console.WriteLine(f);
}
Output:
2
6
24
120
720
5040
40320
362880
3628800
39916800
479001600
6227020800
87178291200
1307674368000
20922789888000
355687428096000
6402373705728000
121645100408832000
2432902008176640000
static string FindFactorial(int n)
{
int[] result = new int[500000];
result[0] = 1;
int resultSize = 1;
for (int x = 2; x <= n; x++)
resultSize = Multiply(x, result, resultSize);
string factorial = "";
for (int i = resultSize - 1; i >= 0; i--)
factorial += result[i].ToString();
return factorial;
}
static int Multiply(int x, int[] result, int resultSize)
{
int carry = 0;
for (int i = 0; i < resultSize; i++)
{
int product = result[i] * x + carry;
result[i] = product % 10;
carry = product / 10;
}
while (carry != 0)
{
result[resultSize] = carry % 10;
carry /= 10;
resultSize++;
}
return resultSize;
}
This will work

C# foreach loop take values from outer loop to inner loop

I have the below code.
int[] a = new int[] { 8, 9 };
for(int i=0;i<n;i++)
{
print i;
int z;
//during first iteration
z=8;
during second iteration
z=9;
}
Output should be something like this.
during first iteration i=0 and z=8
during second iteration i=1 and z=9
array a contains 2 elements. N and number of elements in array a will be always same. next my for loop will execute. during first iteration want z value should be 8(first element of array ) and second iteration my z value should be 9. I want to map 1st element of integer array to first iteration of for loop and so on.
try
for (int i = 0; i < a.Length; i++) // or i < n if you want
{
print i;
int z = a[i]; // this line will get value from a one by one, 0, 1, 2, 3 and so on...
}
Edit 1 -
After seeing the comments on the other answer, the array 'a' turns out is a dynamic array which have size n (which is 2)
the revised edition:
int n = 2;
int[] a = new int[n];
string input = null;
for (int i = 0; i < a.Length; i++) // or i < n if you want
{
print i;
input = Console.ReadLine();
try {
a[i] = int.Parse(input);
Console.WriteLine(string.Format(
"You have inputted {0} for the {1} element",
input, i
));
} catch { Console.WriteLine("Non integer input"); i -= 1; }
}
you can try this
int [] a = {8,9};
for(int i=0; i< a.Length; i++)
{
int z = a[i]; //for taking value from array at the specific ith position
Console.WriteLine("i: " + i + " z:" + z);
}
try this
List<int> a = new List<int>();
int n = 2; // you can change it according to your need
for (int i = 0; i < n; i++)
{
string str = Console.ReadLine(); // make sure you enter an integer and conver it
int z = int.Parse(str);
a.Add(z);
}
foreach (int k in a)
{
Console.WriteLine(k);
}

C# outside the bounds of the array

I am getting the error " Index was outside the bounds of the array". This code that I typed from my text book. Cant seem to find anything wrong with it.
class Program
{
static void Main()
{
int[] scores = new int[8];
int x;
string inputString;
for (x = 0; x < scores.Length; ++x)
{
Write("Enter your score on test {0} ", x + 1);
inputString = ReadLine();
scores[x] = Convert.ToInt32(inputString);
}
WriteLine("\n----------------------------");
WriteLine("Scores in original order: ");
for(x = 0; x < scores.Length; ++x)
Write("{0, 6}", scores[x]);
WriteLine("\n----------------------------");
Array.Sort(scores);
WriteLine("Scores in sorted order: ");
for(x = 0; x < scores.Length; ++x)
Write("{0, 6}", scores[x]);
WriteLine("\n----------------------------");
Array.Reverse(scores);
WriteLine("Scores in reverse order: ");
for(x = 0; x < scores.Length; ++x) ;
Write("{0, 6}", scores[x]);
}
}
}
You have an extra semicolon
for (x = 0; x < scores.Length; ++x) ;
Console.Write("{0, 6}", scores[x]);
The for loop runs, doing nothing except increment x to the final value of 8. Then the next line runs with x still having the value from before, which happens to be 8.
To fix it, remove the extra ;.

C# Resorting an array in a unique way

I am wanting to create multiple arrays of ints(in C#). However they all must have a unique number in the index, which no other array has that number in that index. So let me try show you what I mean:
int[] ints_array = new int[30];
for (int i = 0; i < ints_array.Count(); i++)
ints_array[i] = i;
//create a int array with 30 elems with each value increment by 1
List<int[]> arrayList = new List<int[]>();
for(int i = 0; i < ints_array.Count(); i++)
arrayList.Add(ints_array[i]. //somehow sort the array here randomly so it will be unique
So I am trying to get the arrayList have 30 int[] arrays and each is sorted so no array has the same int in the same index as another.
Example:
arrayList[0] = {5,2,3,4,1,6,7,8,20,21... etc }
arrayList[1] = {1,0,5,2,9,10,29,15,29... etc }
arrayList[2] = {0,28,4,7,29,23,22,17... etc }
So would this possible to sort the array in this unique kind of way? If you need anymore information just ask and ill fill you in :)
Wouldn't it be easier to create the arrays iteratively using an offset pattern?
What I mean is that if you created the first array using 1-30 where 1 is at index 0, the next array could repeat this using 2-30 where 2 is at index 0 and then wrap back to 1 and start counting forward again as soon as you go past 30. It would be an easy and repeatable way to make sure no array shared the same value/index pair.
You can do it like that:
List<int[]> arrayList = new List<int[]>();
Random rnd = new Random();
for (int i = 0; i < ints_array.Length; i++)
{
ints_array = ints_array.OrderBy(x => rnd.Next()).ToArray();
var isDuplicate = arrayList.Any(x => x.SequenceEqual(ints_array));
if (isDuplicate)
{
while (arrayList.Any(x => x.SequenceEqual(ints_array)))
{
ints_array = ints_array.OrderBy(x => rnd.Next()).ToArray();
}
}
arrayList.Add(ints_array);
}
I think, this wouldn't be so efficient for bigger numbers than 30.But in this case it shouldn't be a problem, in my machine it takes 7 milliseconds.
Jesse's idea would be best unless you needed a pure random pattern. In that case I would recommend generating a random number, checking all your previous arrays, and then placing it in an array if it did not match any other arrays current index. Otherwise, generate a new random number until you find a fresh one. Put that into a loop until all your arrays are filled.
Use a matrix (2D-array). It is easier to handle than a list of arrays. Create a random number generator. Make sure to initialize it only once, otherwise random number generator may create bad random numbers, if created in too short time intervals, since the slow PC-clock might not have ticked in between. (The actual time is used as seed value).
private static Random random = new Random();
Create two helper arrays with shuffeled indexes for rows and columns:
const int N = 30;
int[] col = CreateUniqueShuffledValues(N);
int[] row = CreateUniqueShuffledValues(N);
Then create and initialize the matrix by using the shuffeled row and column indexes:
// Create matrix
int[,] matrix = new int[N, N];
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
matrix[row[i], col[j]] = (i + j) % N;
}
}
The code uses these two helper methods:
private static int[] CreateUniqueShuffledValues(int n)
{
// Create and initialize array with indexes.
int[] array = new int[n];
for (int i = 0; i < n; i++) {
array[i] = i;
}
// Shuffel array using one variant of Fisher–Yates shuffle
// http://en.wikipedia.org/wiki/Fisher-Yates_shuffle#The_modern_algorithm
for (int i = 0; i < n; i++) {
int j = random.Next(i, n);
Swap(array, i, j);
}
return array;
}
private static void Swap(int[] array, int i, int j)
{
int temp = array[i];
array[i] = array[j];
array[j] = temp;
}
int size = 10;
// generate table (no duplicates in rows, no duplicates in columns)
// 0 1 2
// 1 2 0
// 2 0 1
int[,] table = new int[size, size];
for (int y = 0; y < size; y++)
for (int x = 0; x < size; x++)
table[y, x] = (y + x) % size;
// shuffle rows
Random rnd = new Random();
for (int i = 0; i < size; i++)
{
int y1 = rnd.Next(0, size);
int y2 = rnd.Next(0, size);
for (int x = 0; x < size; x++)
{
int tmp = table[y1, x];
table[y1, x] = table[y2, x];
table[y2, x] = tmp;
}
}
// shuffle columns
for (int i = 0; i < size; i++)
{
int x1 = rnd.Next(0, size);
int x2 = rnd.Next(0, size);
for (int y = 0; y < size; y++)
{
int tmp = table[y, x1];
table[y, x1] = table[y, x2];
table[y, x2] = tmp;
}
}
// sample output
for (int y = 0; y < size; y++)
{
for (int x = 0; x < size; x++)
Console.Write("{0} ", table[y, x]);
Console.WriteLine();
}

How to Save a Multidimensional Array Index?

Basically my first task was to save the position of the '0' in an integer. Real simple with a standard array. This code loops through an array (Size: 8) until it locates the 0, then save that as the position. See code below:
p.s: n is a reference to an array saved somewhere else.
int position = 0;
this.nodesExpanded++;
// Loop through the array to get the position of where '0' is
for (int i = 0; i < n.getPuzzle().length; i++){
if (n.getPuzzle()[i] == 0){
position = i;
break;
}
}
My ultimate task was to make this possible for a multidimensional array (Size: [3, 3]). So here's what I've created thus far:
for (int x = 0; x < 3; x++)
{
for (int y = 0; y < 3; y++)
{
if (n.getPuzzle()[x,y] == 0)
{
**position = ;**
break;
}
}//end y loop
}//end x loop
So how do I go about saving an array reference to a location to a value?
'position' will need to be something other than int I'm guessing..
If you need more clarification be sure to comment, sorry in advance & thank you!
You can use a Tuple to store that position. Or you can create your own data structure.
Example: at the end you can see how to access tuple items.
var positions = new List<Tuple<int, int>>();
for (int x = 0; x < 3; x++)
{
for (int y = 0; y < 3; y++)
{
if (n.getPuzzle()[x,y] == 0)
{
positions.Add(new Tuple<int, int>(x,y));
break;
}
}//end y loop
}//end x loop
if(positions.Any())
{
var xpos = positions[0].Item1;
var ypos = positions[0].Item2;
}
I find a natural way to store a multidimensional array index is to use a single dimensional array whose size is the number of dimensions.
So if you have a object[,,] A and index int[] i you would index into A with the expression A[i[0],i[1],i[2]].
It works the same way as your one-dimensional array, but you have two position values to keep. I've used ints for the example, but you may want to use a custom structure or Tuple (as AD.Net) said.
int xpos = -1;
int ypos = -1;
for (int x = 0; x < 3; x++)
{
for (int y = 0; y < 3; y++)
{
if (n.getPuzzle()[x,y] == 0)
{
xpos = x;
ypos = y;
break;
}
}//end y loop
}//end x loop
if (!(xpos > -1 && ypos > -1)) ; // 0 was not found

Categories