Looping - amount of years from months - c#

I have a int months (84 for example) and I need to work out how many years that equals so using 84 = 7 years
I need to loop through the initial number and see how many full years are in there and print the result
example:
int count = 84;
for (int i = 12; i <= count; i++)
{
years = i;
}
This doesn't work of course, it produces '84 years' where I should produce 7 years. I also need to get the remaining months after the year calculation so if the initial number was 85 for example it would result in 7 years 1 month.

Use standard mathematical operations instead of a loop:
int count = 84;
int years = count / 12;
int months = count % 12;
First one is division, second is modulus.
Because both count and 12 are integers count/12 returns an integer as well. So for 85 it will return 7, not 7.1.
Update
Loop version could look like that:
count = 84;
years = 0;
for (int i = 12; i <= count; i += 12)
{
years++;
}

Doing that with a loop would look like this:
int years = 0;
while (count >= 12) {
count -= 12;
years++;
}
However, you can do the same without looping:
int years = count / 12;
count %= 12;

Try this:
DateTime t = new DateTime();
t = t.AddMonths(84);
int year = t.Year; // year = 8
int month = t.Month; // month = 1

Surely you just need basic math operations:
int count = 84;
int years = (int)(count / 12);
int months = count % 12;

int years = count / 12;
int remainingMonths = count % 12;

thanks to everyone who gave a answer :D much appreciated
i got it working like this in the end
int employmentInMonthsAmount = this.MaxEmploymentHistoryInMonths;
var intcounter = 0;
int years = 0;
for (var i = 0; i < employmentInMonthsAmount; i++)
{
if (intcounter >= 12)
{
years++;
intcounter = 0;
}
intcounter++;
}
var monthsleft = intcounter;

Related

How to fix IndexOutOfRangeException [duplicate]

This question already has answers here:
What is an IndexOutOfRangeException / ArgumentOutOfRangeException and how do I fix it?
(5 answers)
Closed 4 years ago.
I'm writing a Assignment for school (we are sepose to make one for the rest of the class) and I have run in to a problem. I'm having IndexOutOfRangeException errors when running the program and I can't figure out why I'm getting it.
Random rnd = new Random();
string strNumDice = tbxNumDice.Text;
int[] numDice = new int[int.Parse(strNumDice)];
int numSides = int.Parse(tbxNumSides.Text);
int trgNumber = int.Parse(tbxTarget.Text);
int sum = 0;
//int numTries = 0;
int var2 = 0;
if (int.Parse(strNumDice) * (numSides) >= trgNumber)
{
while (var2 != trgNumber)
{
tbxResult.AppendText("\n");
sum = 0;
foreach (int numberOfDice in numDice)
{
numDice[numberOfDice] = rnd.Next(1, numSides+1);
tbxResult.AppendText(numDice[numberOfDice].ToString() + " ");
sum += numDice[numberOfDice];
//numTries++;
}
tbxResult.AppendText("\n");
tbxResult.AppendText("The new sum is" + sum.ToString());
var2 = sum;
}
}
If I decide to roll 6 d6's and wan't a target sum of 36 it will continue to do so until it gets to 36.
The mistake is here:
foreach (int numberOfDice in numDice)
{
numDice[numberOfDice] = rnd.Next(1, numSides+1);
This is how javascript does foreach loops: you get the indexes of your array. C# gives you the values of the actual elements, rather than the indexes. As you will be modifying actual array elements, you want a for loop, rather than a foreach loop, like this:
for(int i = 0; i<numDice.Length; i++)
{
numDice[i] = rnd.Next(1, numSides+1);

New Year Chaos HackerRank Practise Problem - C# solution optimization [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
static void minimumBribes(int[] q)
{
Int32 TotalCount = 0;
bool blnSuccess = true;
Int32[] size = Ordering(q);
for (int intI = 0; intI < q.Length; intI++)
{
Int32 Tempvariable = 0;
Int32 TooChaotic = 0;
Int32 index = Index(size,q[intI]);
do
{
if (q[intI] != size[intI])
{
Tempvariable = size[index];
size[index] = size[index - 1];
size[index - 1] = Tempvariable;
index = index - 1;
TooChaotic = TooChaotic + 1;
if (TooChaotic > 2)
{
break;
}
TotalCount = TotalCount + 1;
}
} while (q[intI] != size[intI]);
if (TooChaotic > 2)
{
Console.WriteLine("Too chaotic");
blnSuccess = false;
break;
}
}
if (blnSuccess)
{
Console.WriteLine(TotalCount);
}
}
static int[] Ordering(int[] z)
{
int[] r = new int[z.Length];
r = z.OrderBy(x => x).ToArray();
return r;
}
static int Index(int[] z,int integer)
{
for (int intI = 0; intI < z.Length; intI++)
{
if(z[intI]== integer)
{
return intI;
}
}
return 0;
}
This code is working fine, but its runtime is too long.
I'm getting "Terminated due to timeout" in HackerRank. However, the solution is working fine on the local computer but it's taking more time.
Problem Link:https://www.hackerrank.com/challenges/new-year-chaos/problem.
Sample Input
2 (the number of test cases)
5 (number of people in the queue)
2 1 5 3 4 (n space-separated integers describing the final state of the queue)
5 (number of people in the queue)
2 5 1 3 4 (n space-separated integers describing the final state of the queue).
It must print an integer representing the minimum number of bribes necessary, or Too chaotic if the line configuration is not possible.
Output
3
Too chaotic
Question:
How do I reduce its runtime? Presently, I am using an array.
I've solved it a few weeks ago, this is my solution to the problem (100%)
static void minimumBribes(int[] q) {
int bribe = 0;
bool chaotic = false;
int n = q.Length;
for(int i = 0; i < n; i++)
{
if(q[i]-(i+1) > 2)
{
chaotic = true;
break;
}
for (int j = Math.Max(0, q[i]-2); j < i; j++)
if (q[j] > q[i])
bribe++;
}
if(chaotic)
Console.WriteLine("Too chaotic");
else
Console.WriteLine(bribe);
}
You don't need any other methods than the one provided by the challenge

Convert 1000 months in 83 years and 4 months

I try to make something and its work, but when I try to make a date under 1 month its crash. Can someone help me? The code is like this:
int page = int.Parse(Console.ReadLine());
int campingDays = int.Parse(Console.ReadLine());
int pagesPerDay = int.Parse(Console.ReadLine());
int months = page / ((30 - campingDays) * pagesPerDay);
int years = months / 12;
int remainingMonths = months % 12;
Console.WriteLine("{0} years {1} months", years, remainingMonths);
That's how i solve the "0 years 1 months" problem. There you go!
int readedPages = (30 - campingDays) * regularDays;
if ((campingDays == 30) || (regularDays == 0))
{
Console.WriteLine("never");
}
else
{
double readDuration = Math.Ceiling(bookPages / (double)readedPages);
double years = (int)(readDuration / 12);
double remainingMonths =(readDuration % 12);
Console.WriteLine("{0} years {1} months", years, remainingMonths);
}
Michal Ciechan is correct. (Just read your answer closely)
suggestion:
int _campingDaysAdj = 30 - campingDays;
if(_campingDaysAdj > 0 && pagesPerDay > 0)
{
int months = page / ((30 - campingDays) * pagesPerDay);
int years = months / 12;
int remainingMonths = months % 12;
Console.WriteLine("{0} years {1} months", years, remainingMonths);
}
else
{
//throw an exception or an error message etc.
}
You would get divide by zero error whenever
campingDays is 30 because of (30 - campingDays)
pagesPerDay is - 0
The problematic line:
int months = page / ((30 - campingDays) * pagesPerDay);
You may want 2 if statements to handle those cases.

How to compute the average for every n number in a list [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
Having a List of numbers, I want to take every n(e.g. 5 , 10 , etc.) element, compute their average and put the average in a new list. As an example lets assume we have the following list:
1 , 2 , 3 , 4 , 5 , 6 , 7 , 8
Now we compute the average every 2 elements and we will get the following list as output:
1.5 , 3.5 , 5.5 , 7.5
How can I do that?
You could use a for-loop and Enumerable.Average:
var averages = new List<double>();
for (int i = 0; i < ints.Length; i += 2)
{
int thisInt = ints[i];
int nextInt = i == ints.Length - 1 ? thisInt : ints[i + 1];
averages.Add(new[] { thisInt, nextInt }.Average());
}
Here's a dynamic approach that works with any length:
int take = 2;
for (int i = 0; i < ints.Length; i += take)
{
if(i + take >= ints.Length)
take = ints.Length - i;
int[] subArray = new int[take];
Array.Copy(ints, i, subArray, 0, take);
averages.Add(subArray.Average());
}
This problem is just testing your use of iteration and the modulus operator. Modulus gives you the remainder of division, you can use it to check whether or not the current number should be included in the average as you iterate the array. Here is a sample method;
public float nthsAverage(int n, int[] numbers)
{
// quick check to avoid a divide by 0 error
if (numbers.Length == 0)
return 0;
int sum = 0;
int count = 0;
for (int i = 0; i < numbers.Length; i++)
{
// might want i+1 here instead to compensate for array being 0 indexed, ie 9th number is at the 8th index
if (i % n == 0)
{
sum = sum + numbers[i];
count++;
}
}
return (float)sum / count;
}
public List<double> Average(List<double> number, int nElement)
{
var currentElement = 0;
var currentSum = 0.0;
var newList = new List<double>();
foreach (var item in number)
{
currentSum += item;
currentElement++;
if(currentElement == nElement)
{
newList.Add(currentSum / nElement);
currentElement = 0;
currentSum = 0.0;
}
}
// Maybe the array element count is not the same to the asked, so average the last sum. You can remove this condition if you want
if(currentElement > 0)
{
newList.Add(currentSum / currentElement);
}
return newList;
}

previous, current and next 3 quarters?

I am trying to get previous, current and next 3 quarters base on current quarter and year.
Example : Current Quarter = 3 & Year = 2014
I want Output,
Q2-2014
Q3-2014
Q4-2014
Q1-2015
Q2-2015
I am trying as under but output is NOT correct and also how to club previous quarter?
static void Main(string[] args)
{
int generateQuater = 5;
int currentQuater = 3;
int currentYear = DateTime.Now.Year;
List<string> lstQuaterYear = new List<string>();
for (int i = generateQuater; i > 0; i--)
{
lstQuaterYear.Add(string.Format("Q{0}-{1}", currentQuater, currentYear));
if (--currentQuater == 0)
{
currentQuater = 4;
currentYear++;
}
}
Console.ReadLine();
}
Change your loop as follows:
for (int i = 0; i < generateQuater; i++)
{
if(currentQuater%5 ==0)
{
currentQuater = 1;
currentYear++;
}
lstQuaterYear.Add(string.Format("Q{0}-{1}", currentQuater%5, currentYear));
currentQuater++;
}
Modulo 5 will return values in the range [0,4]. Quarter 0 can be interpreted as quarter 1 of the next year. Therefore, we handle that case by setting currentQuater to 1 and incrementing currentYear. This will go through the 4 quarters of each year, and on the 5th one, it will move to next year and restart counting from 1.
Demo
Finally this code with help of Tieson.
Question : Any other/linq approach for subjected problem also welcome.
int generateQuater = 4;
int currentQuater = 3;
int currentYear = DateTime.Now.Year;
List<string> lstQuaterYear = new List<string>();
//previous Quater
lstQuaterYear.Add(String.Format("Q{0}-{1}", (currentQuater - 1) + (((1) / 4) * 4), currentYear - ((1) / 4)));
for (int i = 0; i < generateQuater; i++)
{
if (currentQuater % 5 == 0)
{
currentQuater = 1;
currentYear++;
}
//current and next 3 Quater
lstQuaterYear.Add(string.Format("Q{0}-{1}", currentQuater % 5, currentYear));
currentQuater++;
}

Categories

Resources