Write a program that fills a 15-byte array with positive double-digit random numbers. in each number, the sum of the two digits is equal to 9.
Here's what I've done so far:
int one = 0;
int two = 0;
int[] arr = new int[15];
Random rnd = new Random();
for (int i = 0; i < arr.Length; i++)
{
arr[i] = rnd.Next(10, 99);
one = arr[0] % 10;
two = arr[0] / 10;
if (arr[i] % 2 == 0 && one + two == 9)
Console.WriteLine(arr[i]);
}
The problem with your solution is that rnd.Next(10, 99) will not always produce number with the properties that you want. you should write a code that always works.
We know that sum of digits of a number should be 9. if we assume our two-digit number to be a*10+b where a and b are digits and a + b = 9, we can randomly generate a from 1 to 9.
Then we can calculate other digit b = 9 - a.
therefor our final result would be a*10 + 9 - a which will be simplified to a*9 + 9 where a is random number from 1 to 9, here are two examples.
a=7 then 7 * 9 + 9 = 72, 7 + 2 = 9
a=3 then 3 * 9 + 9 = 36, 3 + 6 = 9
note that a is in this range 1 <= a < 9
Related
Got stuck on quite simple problem in my code. I need to count what I would call a nested sums of an array. Let's take as an example the array:
[1,2,2,3,6]
I want to sum them as:
0 + 1 = 1
1 + 2 = 3
1 + 2 + 2 = 5
1 + 2 + 2 + 3 = 8
1 + 2 + 2 + 3 + 6 = 14
sum = 1 + 3 + 5 + 8 + 14 = 31
Edit:
I tried to do it with stack, but it failed
int sums = 0;
Stack<int> sum = new Stack<int>();
for (int i = 0; i < queries.Length; i++)
{
sum.Push(queries[i]);
}
for (int i = 0; sum.Count != 0; i++)
{
if(i != 0)
{
sums += sum.Pop();
}
}
You can run this task in a single loop considering when you have an array of size 5, the first element is repeating 5 times, second element repeating 4 times and etc.
int[] arr = { 1, 2, 2, 3, 6 };
int mysum = 0;
for (int i = 0; i < arr.Length; i++)
mysum += (arr.Length - i) * arr[i];
Console.WriteLine(mysum);
Output:
31
Explanation:
1 = 1
1 + 2 = 3
1 + 2 + 2 = 5
1 + 2 + 2 + 3 = 8
1 + 2 + 2 + 3 + 6 = 14
========================
5*1 + 4*2 + 3*2 + 2*3 + 1*6 = 31
You can do this much more efficiently and more easily, by multiplying each value by its reversed index + 1
For example, using LINQ
int[] arr = { 1, 2, 2, 3, 6 };
var result = arr.Reverse().Select((val, i) => val * (i + 1)).Sum();
Note that .Reverse on an array (or other Collection<T>) does not actually move any items, it just reads them backwards. So this is therefore an O(n) operation, as opposed to your original solution which is O(n2 / 2)
dotnetfiddle
You can also do this procedurally, this is almost the same as #aminrd's answer.
int[] arr = { 1, 2, 2, 3, 6 };
var result = 0;
for (var i = arr.Length - 1; i >= 0; i--)
result += arr[i] * (i + 1);
Take advantage of Linq! .Sum() will add up everything in your collection. You run that twice, once per each slice, and once per each subtotal.
var input = new [] { 1, 2, 2, 3, 6 };
var totalSum = Enumerable.Range(1, input.Length).Sum(len => input[0..len].Sum());
// totalSum is 31
Enumerable.Range gets you a collection of numbers between (and including) 1 and 5 - the possible lengths of each slice of your sub arrays. You then use the range operator [0..#] to get increasingly larger slices.
Yes, this is not as clever as aminrd's solution - it's doing all the computations manually and you're performing many slices.
This question already has answers here:
Linq query to get all numbers (positive and negative) up to N that sum up to number K
(5 answers)
Listing all permutations of a string/integer
(28 answers)
Closed 1 year ago.
Given input: N = 6, X = 3
The output should be:
1 + 2 + 3 - 4 - 5 + 6 = 3
1 + 2 - 3 + 4 + 5 - 6 = 3
1 - 2 - 3 - 4 + 5 + 6 = 3
So far I could manage this:
//returns a string of numbers from 1 to N
static string Numbers(int maxNumber) => maxNumber > 1 ? Numbers(maxNumber - One) + maxNumber :"1";
and a function that generates all possible combinations for +- but the problem is that I want to combine the +- resulted string with numbers from 1 to N:
static void Permute(char[] arry, int i, int n)
{
int j;
if (i == n)
Console.WriteLine(arry);
else
{
for (j = i; j <= n; j++)
{
Swap(ref arry[i], ref arry[j]);
Permute(arry, i + 1, n);
Swap(ref arry[i], ref arry[j]); //backtrack
}
}
}
static void Swap(ref char a, ref char b)
{
char tmp;
tmp = a;
a = b;
b = tmp;
}
This looks like a very different form of "permute". For N integers, you have D=N-1 decisions to make, each of which can be either a + or a -. Two options is: "binary", so, if this is me, I would compute (2^D)-1 (which gives us the upper bound), then do a for loop from zero to that number (inclusive), and do the math: each binary digit is a decision point, and we could say 0===- and 1===+; see what the result is: if it is the number you wanted: log it.
For N=6 we have D=5, and 32 attempts to do; 0 thru 31:
int N = 6, X = 3;
// how many decisions is that?
var decisions = N - 1;
// treat each -/+ as one of "decisions" binary digits
var binaryUpperLimit = (1 << decisions) - 1;
for (int i = 0; i <= binaryUpperLimit; i++)
{
// compute the sum
int sum = 1; // the 1 is a permenant fixture, it seems
// determine each decision using binary arithmetic
for (int place = 0; place < decisions; place++)
{
int digit = place + 2;
if ((i & (1 << place)) == 0)
{
sum -= digit;
}
else
{
sum += digit;
}
}
// is that what we wanted?
if (sum == X)
{
// we have a "hit"; repeat the above to output this
Console.Write("1");
for (int place = 0; place < decisions; place++)
{
if ((i & (1 << place)) == 0)
{
Console.Write(" - ");
}
else
{
Console.Write(" + ");
}
int digit = place + 2;
Console.Write(digit);
}
Console.Write(" = ");
Console.WriteLine(sum);
}
}
(if the initial 1 can be negative, you'll need to adjust to add an extra decision, start the sum at zero, and make digit be +1 instead of +2)
How to count each number that gets generated randomly using array in C#?
Output will be as below:
2
3
5
3
5
Number 1 : 0
Number 2 : 1
Number 3 : 2
Number 4 : 0
Number 5 : 2
I did come out with random numbers but then I'm stuck to figure out how to count each number.
int[] randNum;
randNum = new int[5];
Random randNum2 = new Random();
for (int i = 0; i < randNum.Length; i++)
{
randNum[i] = randNum2.Next(0, 9);
Console.Writeline(randNum[i]);
}
Console.WriteLine();
Usually, we use Dictionary for such problems:
// We build dictionary:
Dictionary<int, int> counts = new Dictionary<int, int>();
// 1000 random numbers
for (int i = 0; i < 1000; ++i) {
int random = randNum2.Next(0, 9);
if (counts.TryGetValue(random, out int count))
counts[random] = count + 1;
else
counts.Add(random, 1);
}
// Then query the dictionary, e.g.
// How many times 4 appeared?
int result = counts.TryGetValue(4, out int value) ? value : 0;
However, if numbers are of a small range (say, 0..8, not -1000000..1000000000) we can use arrays:
int numbersToGenerate = 5;
int max = 9;
int[] counts = new int[max];
for (int i = 0; i < numbersToGenerate; ++i) {
int random = randNum2.Next(0, max);
counts[random] += 1;
}
// Output:
for (int i = 0; i < counts.Length; ++i)
Console.WriteLine($"Number {i} : {counts[i]}");
If i understood you correctly you want an extra array with the counting output of the other array.
Then i think this is a simple solution:
int[] arrResult = new int[9];
foreach(int number in randNum){
if(arrResult[number] == null){
arrResult[number] = 0;
}
arrResult[number] = arrResult[number] + 1;
}
if as i am reading in your code the numbers are from 0 to 8 so 9 numbers, this will output an Array where if the random numbers for example are 0 1 0 2 3 1 0
arrResult[0] == 3
arrResult[1] == 2
arrResult[3] == 1
there probably is a more efficent way with linq and different uses but this should be a solution which would work for your problem
I was able to get my array to sort to the right but, struggling
to get the left rotation to work for example [1, 2, 3, 4, 5, 6, 7, 8] if
rotated to the left 4 spaces [4, 5, 6, 7, 8, 1, 2, 3] I feel like it's super simple and just a small change to my current right rotation but, I'm stumped.
if (direction == "right")
{
{
//make spaces<nums.Length
if (spaces > newArray.Length)
{
while (spaces - newArray.Length >= 0)
{
spaces = spaces - newArray.Length;
}
}
if (spaces == 0)
{
}
else
{
int[] temp = new int[spaces];
//move to a temp array
for (var i = temp.Length - 1; i >= 0; i--)
{
temp[i] = newArray[newArray.Length - spaces + i];
}
//push to the end
for (var j = newArray.Length - spaces - 1; j >= 0; j- -)
{
newArray[j + spaces] = newArray[j];
}
//put the ones in temp array back to the top
for (var s = 0; s < temp.Length; s++)
{
newArray[s] = temp[s];
}
}
}
}
Wel, if you want it simple, try Linq and modulo arithmetics:
int[] array = new int[] { 1, 2, 3, 4, 5, 6, 7, 8 };
int shift = 4;
int[] result = Enumerable
.Range(0, array.Length)
.Select(i => array[(i + shift % array.Length + array.Length) % array.Length])
.ToArray();
Same modulo arithmetics and no Linq
int shift = 4;
int[] result = new int[array.Length];
for (int i = 0; i < result.Length; ++i)
result[i] = array[(i + shift % array.Length + array.Length) % array.Length];
If you want to rotate to right, assign negative values to shift.
Edit: what's going under the hood, modulo arithmetics explained. Our task is when we are given i (index of result) to compute index of the initial array:
array = {1 2 3 4 5 6 7 8}
result = {5 6 7 8 1 2 3 4}
as we can see,
index = i + shift
when shift is small enough (5 is taken from 0 + 4 == 4th index). However we can't exceed arrays length but should subtract it (i.e. restart from 0)
7 + 4 == 11 -> 11 - 8 == 3
I.e.
index = i + shift
index >= array.Length
? index - array.Length // index is too large, restart from 0
: index; // index is small enough
This operation is equal to remainder %:
index = (i + shift) % array.Length
It's good enough, but we still have 2 specific issues with .Net:
i + shift can result in integer oveflow (when, say shift = int.MaxValue)
.Net can well return negative remainder (if shift < 0)
That's why shift % array.Length to meet the first issue and + array.Length for the second. Finally
(i + shift % array.Length + array.Length) % array.Length
I am working on a Visa credit card generator and I'm not seeing the problem with the following:
My code seems to work for 16 digit card numbers, however, it doesn't seem to work for 13 digit cards, as the generated card numbers are invalid on both online testers and on my app.
Code:
var randomNum = new Random();
int [] lengths = new int[] { 13, 16 };
int length = lengths[randomNum.Next(lengths.Length)];
int [] str;
int [] reversed;
var lastDigit = 0;
var sum = 0;
if (length == 16)
{
str = new int[16];
reversed = new int[15];
}
else
{
str = new int[13];
reversed = new int[12];
}
Random rnd = new Random();
while (pos < length - 1)
{
str[pos++] = rnd.Next(0, 9);
}
for (int i = 0; i < str.Length - 1; i++)
{
reversed[i] = str[str.Length - i - 2];
}
for (pos = 0; pos < length - 1; pos++)
{
if (pos % 2 == 0 && length == 16)
{
reversed[pos] *= 2;
if (reversed[pos] > 9)
reversed[pos] = reversed[pos] - 9;
}
else if (pos % 2 == 1 && length == 13)
{
reversed[pos] *= 2;
if (reversed[pos] > 9)
reversed[pos] = reversed[pos] - 9;
}
sum += reversed[pos];
}
lastDigit = (10 - (sum % 10)) % 10;
str[length - 1] = lastDigit;
I apologize for copying the whole code, but I thought it would make things more understandable.
The algorithm I followed from http://www.freeformatter.com/credit-card-number-generator-validator.html:
Drop the last digit from the number. The last digit is what we want to check against
Reverse the numbers
Multiply the digits in odd positions (1, 3, 5, etc.) by 2 and
subtract 9 to all any result higher than 9
Add all the
numbers together
The check digit (the last number of the card) is the amount that you
would need to add to get a multiple of 10 (Modulo 10)
Sample card numbers generated by my code:
16 digit: 4145422641287432 - Valid
13 digit: 4354735186403 - Invalid
(The sum before adding the check
digit was 47 meaning 3 would be the check digit resulting in the whole sum being 50 => 50%10=0)
What exactly am I doing wrong here?