Getting remainder of sequence but with exception on element with remainer zero - c#

Let say i have number 1 to 24, i want to get remainder of these from 12
so with mod 12 sequence would be 1 to 11 and additionally 0 (of 12 and 24) .
But i need this 0 to be always 12.
How to achieve such a thing in one liner(without additional variables or ifs).
Right now code is something like this:
for (int i = 1; i <= 24; i++)
{
Console.WriteLine(i % 12);
}

Oneline solution (with slight overhead though: i % 12 could be computed twice):
for (int i = 1; i <= 24; i++)
{
Console.WriteLine(i % 12 == 0 ? 12 : i % 12);
}
Pure arithmetic solution is
for (int i = 1; i <= 24; i++)
{
Console.WriteLine(12 - (12 - i % 12) % 12);
}

Another arithmetic options:
for (int i = 1; i <= 24; i++)
{
Console.WriteLine((i-1) % 12 + 1);
}
This simple makes sure the 'start' is moved one placed to the left (i-1) and corrects the outcome from 0 to 11 to 1 to 12 bij adding 1 to the result

Related

Generating a for while foreach algorithm in c# with a pyramidal structure

I have been trying to get this to work for 3 days, and I feel like I'm using the wrong approach, if anyone can correct me I will wax your car. Background, client asked to me make a simple pyramid algorithm. I want to select add everything to a list of objects and make everything on the left side true and everything on the right side false. Every other line reads the line 2 lines prior and adds multiple entries. The first time it adds a number like 1 it's one time, then it adds two 1's for each 1 until there is 4. So the first time it enters a 1 on line 1, then on line 3 it adds a 1 two times, then on line 5 it reads from line 3 and adds each of those 1's 2 times.
Here is a visual representation.
|1|
|2| |3|
|1|1| |4|5|
|2|2|3|3| |6|7|8|9|
|1|1|1|1|4|4|5|5| |10|11|12|13|14|15|16|17|
|2|2|2|2|3|3|3|3|6|6|7|7|8|8|9|9| |18|19|20|21|22|23|24|25|26|27|28|29|30|31|32|33
The order this list would be is:
1|2|3|1|1|4|5|2|2|3|3|6|7|8|9|1|1|1|1|4|4|5|5|10|11|12|13|14|15|16|17...
I keep getting close, but it fails to generate the correct output. `
for (int i = 1; i < 50; i = i * 2)
{
Response.Write(i.ToString() + " - ");
var previousLevel = (i / 2 / 2);
foreach (var oc in infoRows.Where(x => x.level == previousLevel))
{
for (int p = i; p > 0; p--)
{
Response.Write(oc.id + "*");
}
}
while (level <= i)
{
for (int r = 1; r <= i; r++)
{
InfoRow tempInforow = new InfoRow();
tempInforow.customerCode = GenerateCustomerNumber(position);
tempInforow.id = customerId;
tempInforow.sendtoidnumber = level.ToString();
tempInforow.status = 0; // GetStatus(position, totalCount);
tempInforow.position = position;
tempInforow.level = i;
infoRows.Add(tempInforow);
customerId++;
position++;
Response.Write(tempInforow.id + "-");
level++;
}
}
}
`
Essentially this generates the following:
1 - 1-
2 - 2-3-
4 - 1*1*1*1*4-5-6-7-
8 - 2*2*2*2*2*2*2*2*3*3*3*3*3*3*3*3*8-9-10-11-12-13-14-15-
16 - 4*4*4*4*4*4*4*4*4*4*4*4*4*4*4*4*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*6*6*6*6*6*6*6*6*6*6*6*6*6*6*6*6*7*7*7*7*7*7*7*7*7*7*7*7*7*7*7*7*16-17-18-19-20-21-22-23-24-25-26-27-28-29-30-31-
32 -
I've tried 30 different ways with switch statements, while statements, for and foreach statements, the closest I can get to this working is level 4.
Can someone suggest another way. Maybe a multidimensional array or idk what. Thank you.
Let's write the sequence down and have a look on what's going on:
# 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 ...
seq 1 2 3 1 1 4 5 2 2 3 3 6 7 8 9 1 1 1 1 4 4 5 5 10 ...
^ ^ ^ ^ ^ ^
| |
if # is power of 2 (e.g. 8 == 2**3)
we should copy and double # / 4 items (here 8 / 4 == 2 items)
starting from # / 4 item (here 8 / 4 == 2, starting from item #2)
Time to implement this algorithm
Code:
using System.Linq;
...
private static List<int> Pyramid(int size) {
if (size < 0)
throw new ArgumentOutOfRangeException(nameof(size));
if (size <= 3)
return Enumerable.Range(1, size).ToList();
List<int> result = new List<int>(size) { 1, 2, 3 };
for (int value = 4; result.Count < size; )
if (BitOperations.IsPow2(result.Count + 1)) {
int chunk = (result.Count + 1) / 4;
for (int i = 0; i < chunk && result.Count < size; ++i) {
result.Add(result[chunk - 1 + i]);
if (result.Count >= size)
return result;
result.Add(result[chunk - 1 + i]);
}
}
else
result.Add(value++);
return result;
}
Demo:
// First 31 items from the pyramid
Console.Write(string.Join("|", Pyramid(31)));
Output:
1|2|3|1|1|4|5|2|2|3|3|6|7|8|9|1|1|1|1|4|4|5|5|10|11|12|13|14|15|16|17

How can I check if a number is a multiple of 50 in C# [duplicate]

This question already has answers here:
C# How to determine if a number is a multiple of another?
(8 answers)
Closed 3 years ago.
I have a loop like this:
for (int i = 0; i < scrapedWikiWords.Capacity; i++)
{
// code
Console.WriteLine(i);
}
How can I make it so the Console will only print numbers for when i = 0, 50, 100, 150 etc.
Use the modulus operator (%) operator:
for (int i = 0; i <= 200; i++)
{
if (i % 50 == 0)
Console.WriteLine(i);
}
You could simply increase i by 50 instead of by 1, for example like this:
for (int i = 0; i < scrapedWikiWords.Capacity; i += 50) { }
for (int i = 0; i < scrapedWikiWords.Capacity; i++)
{
processWikiWord(....);
if (i % 50 == 0)
{ // Update the user after 50, 100, 150, 200... words.
// (Updating after every single word would be way too much output!)
Console.WriteLine(i);
}
}
The Modulo operator returns the remainder of division.
For example:
20 / 3 == 6 with a remainder of 2;
20 % 3 == 2 (the remainder part)
The consequence is that any number Modulo N always results in a value between 0 and N-1.
Doing Modulo 50 means you will always get a result between 0 and 49.
The result will be 0 when the values of i are 50, 100, 150, 200, 250,...
The rest of the time the value will be somewhere between 1 and 49, and the if-statement will be skipped.

How to do the loop and solve the following

I'm supposed to code a program that writes out a division just like in school.
Example:
13:3=4.333333333333
13
1
10
10
10....
So my approach was:
Solve the division then get the solution in a List.
Then question if the first number (in this case 1) is divisible by 3.
If not put it down and add the second number and so on...
I managed to do this the first time. It's sloppy but works. The problem is that it only works with numbers that when divided get to have a decimal in it.
Exapmle:
123:13
This is the first code:
do
{
for (int number = 1; number <= divNum; number++)
if (number % divisor == 0) countH++;
for (int i = 0; i < count; i++)
Console.Write(" ");
if ((c = divNum % divisor ) < divisor )
{
Console.WriteLine(" " + ((divNum- (countH * divisor ))) * 10);
}
else Console.WriteLine(" " + (divNum- (countH * divisor )));
c = divNum % divisor ;
if (c < divisor )
{
divNum = c * 10;
}
count++; countH = 0;
} while ((divNum >= divisor ) && (count < x));
Any ideas or help? Sorry if this is a bad question.
************ added
Try of a better explanation:
1 cant be divided by 13, so it goes down, we get the 2 down and try 12 divided by 13, still nothing so we get the 3 down and try 123:13, 13 goes 9 times in 123 so we have 123-9*13 = 6 the six goes down we write 9 in the result. We try 6:13 not going so we drop a 0 next to 6. Next we try 60:13, 13 goes 4 times so 60-4*13 = 8, we get the 8 down. And so on..
123:13=9.46153....
123
60
80
20
70
50
....
Something like this should work. Not the fastest solution most likely, but should do the job.
var number = 123;
var b = 12;
int quotient;
double remainder = number;
var x = 10;
do
{
quotient = (int)Math.Floor(remainder / b);
remainder = remainder - (quotient * b);
for (int i = 0; i < count; i++)
Console.Write(" ");
remainder *= 10;
Console.WriteLine(" " + remainder);
count++;
} while ((remainder > 0) && (count < x));

How use bitmask operator

I'm learning bit mask. And found and example but couldn't make it work.
I'm trying to calculate all sum combination from one array.
The result should be
0 - 1 - 2 - 3 - 3 - 4 - 5 - 6
My problem is with (i & mask) should only result in {0,1} and isn't.
Instead is producing.
0 - 1 - 4 - 5 - 12 - 13 - 16 - 17
int[] elem = new int[] { 1, 2, 3 };
double maxElem = Math.Pow(2, elem.Length);
for (int i = 0; i < maxElem; first++)
{
int mask = 1, sum = 0;
for (int run = 0; run < elem.Length; run++)
{
sum += elem[run] * (i & mask);
mask <<= 1;
}
Debug.Write(sum + " - ");
}
(i & mask) should only result in {0,1} and isn't
(i & mask) should return a result in {0,1} only when mask is 1 - that is, on the initial iteration. However, as soon as mask gets shifted by mask <<= 1 operation, the result of the next operation will be in {0,2}. As the mask gets shifted, possible results will become {0,4}, {0,8}, {0,16} and so on, because the only bit set to 1 in the mask would be moving to the left.
The reason why << operator doubles the number is the same as the reason why writing a zero after a decimal number has the effect of multiplying the number by ten: appending a zero to a number of any base is the same as multiplying that number by the value of base.
Ok, I solve it creating an IF.
int[] elem = new int[] { 1, 2, 3 };
double maxElem = Math.Pow(2, elem.Length);
for (int i = 0; i < maxElem; first++)
{
for (int run = 0; run < elem.Length; run++)
{
int mask = 1, sum = 0;
if ((i & mask) > 0) // ADD THIS LINE
{
sum += elem[run];
}
mask <<= 1;
}
}

Result not matching. Floating point error?

I am trying to rewrite the R function acf that computes Auto-Correlation into C#:
class AC
{
static void Main(string[] args)
{
double[] y = new double[] { 772.9, 909.4, 1080.3, 1276.2, 1380.6, 1354.8, 1096.9, 1066.7, 1108.7, 1109, 1203.7, 1328.2, 1380, 1435.3, 1416.2, 1494.9, 1525.6, 1551.1, 1539.2, 1629.1, 1665.3, 1708.7, 1799.4, 1873.3, 1973.3, 2087.6, 2208.3, 2271.4, 2365.6, 2423.3, 2416.2, 2484.8, 2608.5, 2744.1, 2729.3, 2695, 2826.7, 2958.6, 3115.2, 3192.4, 3187.1, 3248.8, 3166, 3279.1, 3489.9, 3585.2, 3676.5 };
Console.WriteLine(String.Join("\n", acf(y, 17)));
Console.Read();
}
public static double[] acf(double[] series, int maxlag)
{
List<double> acf_values = new List<double>();
float flen = (float)series.Length;
float xbar = ((float)series.Sum()) / flen;
int N = series.Length;
double variance = 0.0;
for (int j = 0; j < N; j++)
{
variance += (series[j] - xbar)*(series[j] - xbar);
}
variance = variance / N;
for (int lag = 0; lag < maxlag + 1; lag++)
{
if (lag == 0)
{
acf_values.Add(1.0);
continue;
}
double autocv = 0.0;
for (int k = 0; k < N - lag; k++)
{
autocv += (series[k] - xbar) * (series[lag + k] - xbar);
}
autocv = autocv / (N - lag);
acf_values.Add(autocv / variance);
}
return acf_values.ToArray();
}
}
I have two problems with this code:
For large arrays (length = 25000), this code takes about 1-2 seconds whereas R's acf function returns in less than 200 ms.
The output does not match R's output exactly.
Any suggestions on where I messed up or any optimizations to the code?
C# R
1 1 1
2 0.945805846 0.925682317
3 0.89060465 0.85270658
4 0.840762283 0.787096604
5 0.806487301 0.737850083
6 0.780259665 0.697253317
7 0.7433111 0.648420319
8 0.690344341 0.587527097
9 0.625632533 0.519141887
10 0.556860982 0.450228026
11 0.488922355 0.38489632
12 0.425406196 0.325843042
13 0.367735169 0.273845337
14 0.299647764 0.216766466
15 0.22344712 0.156888402
16 0.14575994 0.099240809
17 0.072389526 0.047746281
18 -0.003238526 -0.002067146
You might try changing this line:
autocv = autocv / (N - lag);
to this:
autocv = autocv / N;
Either of these is an acceptable divisor for the expected value, and R is clearly using the second one.
To see this without having access to a C# compiler, we can read in the table that you have, and adjust the values by dividing each value in the C# column by N/(N - lag), and see that they agree with the values from R.
N is 47 here, and lag ranges from 0 to 17, so N - lag is 47:30.
After copying the table above into my local clipboard:
cr <- read.table(file='clipboard', comment='', check.names=FALSE)
cr$adj <- cr[[1]]/47*(47:30)
max(abs(cr$R - cr$adj))
## [1] 2.2766e-09
A much closer approximation.
You might do better if you define flen and xbar as type double as floats do not have 9 decimal digits of precision.
The reason that R is so much faster is that acf is implemented as native and non-managed code (either C or FORTRAN).

Categories

Resources