C# - Loop formatting [closed] - c#

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
Having a bit of trouble with an assignment of mine. It's supposed too prompt the user to enter a range (2 integers), then using the format below display the equations that are within the range.
Example:
Enter minimum integer: 3
Enter maximum integer: 7
All: 3 + 4 + 5 + 6 + 7 = 25
Even: 4 + 6 = 10
Odd: 3 + 5 + 7 = 15
Not asking for the entire solution, just a bit of the loop formatting issue. Any help would be appreciated.
Console.Write("Enter minimum integer: ");
string min = Console.ReadLine();
Console.Write("Enter maximum integer: ");
string max = Console.ReadLine();
int min32 = int.Parse(min);
int max32 = int.Parse(max);
for (int i = min32; i <= max32; i++)
Console.Write(i + " + ");

The simplest approach would be to start outputting the numbers in the console, always checking if this is the last number which will be outputed (if that's the case, don't print the + after the number.)
Console.Write("All: ");
int sum = 0;
for (int i = min32; i <= max32; i++)
{
if(i != max32) //Only add " + " after the number if this is not the end of the for loop
Console.Write(i + " + ");
else
Console.Write(i);
sum += i;
}
Console.WriteLine(" = " + sum);
//Outputs for min32 = 3 and max32 = 7:
//3 + 4 + 5 + 6 + 7 = 25
Bonus round: LINQ queries on an IEnumerable<int> returned from Enumerable.Range(), filtered using some Where statements and concatinated using a string.Join():
using System;
using System.Linq;
public class Program
{
public static void Main()
{
Console.Write("Min: ");
int min = int.Parse(Console.ReadLine());
Console.Write("Max: ");
int max = int.Parse(Console.ReadLine());
var sequence = Enumerable.Range(min, max - min + 1);
string all = "All: " + string.Join(" + ", sequence);
string even = "Even: " + string.Join(" + ", sequence.Where(a => a % 2 == 0));
string odd = "Odd: " + string.Join(" + ", sequence.Where(a => a % 2 == 1));
Console.WriteLine(all + " = " + sequence.Sum());
Console.WriteLine(even + " = " + sequence.Where(a => a % 2 == 0).Sum());
Console.WriteLine(odd + " = " + sequence.Where(a => a % 2 == 1).Sum());
}
}

Perhaps keep a string for each collection of numbers. When adding to a total, also append the number to the string. Another option might be string.Join() on a list of strings, using " + " as the separator.
Once the loop finishes, print the joined lists along with the appropriate sum.

Related

Have a number correspond to a position in a multi dimensional array (map 1D numeric values to 2D)

I would like the user to input a number 1-9 and have that number correspond to a position on a 3x3 2d array. And then change the value in that array to an "x".
int input = Convert.ToInt32(Console.ReadLine());
string[,] numbers = {
{ " ", " ", " " },
{ " ", " ", " " },
{ " ", " ", " " }
};
At first I decided to do this:
int x = input % 3 - 1;
int y = input / 3 - 1;
And then access the array at numbers[y, x] however this caused problems with the index being out of bounds.
You had a somewhat good intuition for subtracting 1, but you did it in a wrong way.
The correct would be:
int x = (input-1) % 3;
int y = (input-1) / 3;
Subtracting 1 from the input (in the range 1..9) will translate it to the range 0..8.
Then using / and % with 3, will get you the x,y coordinates, both in 0..2 range.

Difficulty understanding logic of the implemented algorithm - C#

I am finding it hard to understand the logic of the following algorithm that outputs 8,8. I would appreciate if you could provide some insight.
using System;
namespace Console_Example
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine(g(4) + g(5) + "," + g(6));
Console.ReadKey();
}
static int g(int k)
{
if ((k == 1) || (k == 2))
return 1;
else
return g(k - 1) + g(k - 2);
}
}
}
Just a recursive function. You have to follow all steps.
if k = 1:
return 1;
if k = 2:
return 1;
if k = 3:
return (g(2) + g(1)) result is: 1 + 1 = 2
if k = 4:
return (g(3) + g(2)) result is: (1 + 1) + 1 = 3
if k = 5:
return (g(4) + g(3)) result is: 5 + 3 = 5
if k = 6:
return (g(5) + g(4)) result is: 5 + 3 = 8
This looks very similar to the Fibonacci sequence (wikipedia), where each number is the sum of the two previous numbers.
Because it is a recursive function, look at the return g(k - 1) + g(k - 2); where it calls itself, you must follow all the recursion until it ends.
g(1): 1 -- Because the return 1;
g(2): 1 -- Because the return 1;
g(3): g(2) + g(1) = 1 + 1 = 2 -- Here starts the recursion
g(4): g(3) + g(2) = 2 + 1 = 3
g(5): g(4) + g(3) = 3 + 2 = 5
g(6): g(5) + g(4) = 5 + 3 = 8
So g(4) + g(5) +"," +g(6) would be:
3 + 5 , 8 = 8, 8
Pretty much the sum of the F4 F5 resulting in the F6 value.
A better implementation of the Fibonacci sequence would be
static int Fibonacci(int k)
{
if(k < 0)
throw new ArgumentException("Fibonnaci works with numbers >= 0");
if (k == 0 || k == 1)
return k;
else
return Fibonacci(k - 1) + Fibonacci(k - 2);
}

Read() only takes first input but no other input from other Console.Read()

I am following instructions in a C# Tutorial video that is great. I am building a file with the notes and code from the video.
I reviewed similar questions but they do not solve this problem.
Here is a copy of the CS file:
static void Main(string[] args)
{
// Single line comments
/* test multi-line comments
* asldkjasldkjaskd
* asldkjasldkja
* alsdkjalksdj
* */
Console.WriteLine("Hello world!");
Console.Write("What is your name? ");
string name = Console.ReadLine();
Console.WriteLine("Hello " + name);
bool canVote = true;
char grade = 'A';
// Integer with a max number of 2,147,483,647
int maxInt = int.MaxValue;
//Long with max value of 9,223,372,036,854,775,807
long maxLong = long.MaxValue;
// Decimal has a max value of 79,228,162,514,264,337,593,543,950,335
// If you need something bigger, look up BigInteger
decimal maxDecimal = decimal.MaxValue;
// A float is a 32 bit number with a max value of 3.402823E+38 with 7 decimal positions
float maxFloat = float.MaxValue;
// A double is a 32 bit number with a max value of 1.797693134E+308 with 15 decimal positions
double maxDouble = double.MaxValue;
Console.WriteLine("Max Int : " + maxInt);
Console.WriteLine("Max Long : " + maxLong);
Console.WriteLine("Max Decimal : " + maxDecimal);
Console.WriteLine("Max Float : " + maxFloat);
Console.WriteLine("Max Double : " + maxDouble);
var anotherName = "Tom";
// anotherName = 2; Cannot implicitly convert a gype 'int' to a 'string'
Console.WriteLine("anotherName is a {0}", anotherName.GetTypeCode());
// Math
Console.WriteLine("5 + 3 = " + (5 + 3));
Console.WriteLine("5 - 3 = " + (5 - 3));
Console.WriteLine("5 * 3 = " + (5 * 3));
Console.WriteLine("5 / 3 = " + (5 / 3));
Console.WriteLine("5.2 % 3 = " + (5.2 % 3));
int i = 0;
Console.WriteLine("i++ = " + (i++));
Console.WriteLine("++i = " + (++i));
Console.WriteLine("i-- = " + (i--));
Console.WriteLine("--i = " + (--i));
Console.WriteLine("i +- 3 = " + (i +- 3));
Console.WriteLine("i -= 2 = " + (i -= 2));
Console.WriteLine("i *= 2 = " + (i *= 2));
Console.WriteLine("i /= 2 = " + (i /= 2));
Console.WriteLine("i %= 2 = " + (i %= 2));
// casting
// if no magnitude is lost, casting will happen automatically. But otherwise, you set it up as follows
double pi = 3.14;
int intPi = (int)pi;
Console.WriteLine("intPi = " + intPi);
// Math functions
// Acos, Asin, Atan, Atan2, Cos, Cosh, Exp, Log, Sin, Sinh, Tan, Tanh
double number1 = 10.5;
double number2 = 15;
Console.WriteLine("number1 is " + number1);
Console.WriteLine("number2 is " + number2);
Console.WriteLine("Math.Abs(number1) " + (Math.Abs(number1)));
Console.WriteLine("Math.Ceiling(number2) " + (Math.Ceiling(number1)));
Console.WriteLine("Math.Floor(number1) " + (Math.Floor(number1)));
Console.WriteLine("Math.Max(number1,number2) " + (Math.Max(number1,number2)));
Console.WriteLine("Math.Min(number1,number2) " + (Math.Min(number1,number2)));
Console.WriteLine("Math.Pow(number1, 2) " + (Math.Pow(number1, 2)));
Console.WriteLine("Math.Round(number1) " + (Math.Round(number1)));
Console.WriteLine("Math.Sqrt(number1) " + (Math.Sqrt(number1)));
// random numbers
Random rand = new Random();
Console.WriteLine("Random number between 1 and 10 is " + rand.Next(1, 11));
// Relational operators : > < >= <= == !=
// Logical operators : && || ^ !
// note: ^ is the exclusive or
Console.WriteLine("What is your child's age? (enter 0 - 18)");
int age = Console.Read();
if ((age >= 5) && (age <= 7))
{
Console.WriteLine("Go to Elementary School");
} else if ((age > 7) && (age <= 13))
{
Console.WriteLine("Go to middle school");
} else if ((age < 5) || (age > 13))
{
Console.WriteLine("Your child does not meet our age requirements.");
} else
{
Console.WriteLine("Go to high school");
}
Console.WriteLine("What is your age? ");
int workingAge = Console.Read();
if ((workingAge < 14) || (workingAge > 67))
{
Console.WriteLine("You shouldn't work.");
}
}
The program ignores the input from the following:
Console.WriteLine("What is your age? ");
int workingAge = Console.Read();
The output is:
What is your age?
You shouldn't work.
So, the program is not stopping for my input, but rather seems to process its conditions based on the previous integer input value of 2 or 5.
Other articles talked about doing the following which I tried with no avail:
Console.WriteLine("What is your age? ");
int workingAge = Convert.ToInt32(Console.Read());
And
Console.WriteLine("What is your age? ");
int workingAge = int32.Parse(Console.Read());
The second one produced an error in Visual Studio The name 'int32' does not exist in the current context
I updated the script to use int.Parse(Console.ReadLine()), and it worked on Visual Studio 2007, but I ran this on Visual Studio 2015 Community Edition and it is doing the same exact thing as if the changes had no effect:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace HelloWorld
{
class Program
{
static void Main(string[] args)
{
// Single line comments
/* test multi-line comments
* asldkjasldkjaskd
* asldkjasldkja
* alsdkjalksdj
* */
Console.WriteLine("Hello world!");
Console.Write("What is your name? ");
string name = Console.ReadLine();
Console.WriteLine("Hello " + name);
bool canVote = true;
char grade = 'A';
// Integer with a max number of 2,147,483,647
int maxInt = int.MaxValue;
//Long with max value of 9,223,372,036,854,775,807
long maxLong = long.MaxValue;
// Decimal has a max value of 79,228,162,514,264,337,593,543,950,335
// If you need something bigger, look up BigInteger
decimal maxDecimal = decimal.MaxValue;
// A float is a 32 bit number with a max value of 3.402823E+38 with 7 decimal positions
float maxFloat = float.MaxValue;
// A double is a 32 bit number with a max value of 1.797693134E+308 with 15 decimal positions
double maxDouble = double.MaxValue;
Console.WriteLine("Max Int : " + maxInt);
Console.WriteLine("Max Long : " + maxLong);
Console.WriteLine("Max Decimal : " + maxDecimal);
Console.WriteLine("Max Float : " + maxFloat);
Console.WriteLine("Max Double : " + maxDouble);
var anotherName = "Tom";
// anotherName = 2; Cannot implicitly convert a gype 'int' to a 'string'
Console.WriteLine("anotherName is a {0}", anotherName.GetTypeCode());
// Math
Console.WriteLine("5 + 3 = " + (5 + 3));
Console.WriteLine("5 - 3 = " + (5 - 3));
Console.WriteLine("5 * 3 = " + (5 * 3));
Console.WriteLine("5 / 3 = " + (5 / 3));
Console.WriteLine("5.2 % 3 = " + (5.2 % 3));
int i = 0;
Console.WriteLine("i++ = " + (i++));
Console.WriteLine("++i = " + (++i));
Console.WriteLine("i-- = " + (i--));
Console.WriteLine("--i = " + (--i));
Console.WriteLine("i +- 3 = " + (i + -3));
Console.WriteLine("i -= 2 = " + (i -= 2));
Console.WriteLine("i *= 2 = " + (i *= 2));
Console.WriteLine("i /= 2 = " + (i /= 2));
Console.WriteLine("i %= 2 = " + (i %= 2));
// casting
// if no magnitude is lost, casting will happen automatically. But otherwise, you set it up as follows
double pi = 3.14;
int intPi = (int)pi;
Console.WriteLine("intPi = " + intPi);
// Math functions
// Acos, Asin, Atan, Atan2, Cos, Cosh, Exp, Log, Sin, Sinh, Tan, Tanh
double number1 = 10.5;
double number2 = 15;
Console.WriteLine("number1 is " + number1);
Console.WriteLine("number2 is " + number2);
Console.WriteLine("Math.Abs(number1) " + (Math.Abs(number1)));
Console.WriteLine("Math.Ceiling(number2) " + (Math.Ceiling(number1)));
Console.WriteLine("Math.Floor(number1) " + (Math.Floor(number1)));
Console.WriteLine("Math.Max(number1,number2) " + (Math.Max(number1, number2)));
Console.WriteLine("Math.Min(number1,number2) " + (Math.Min(number1, number2)));
Console.WriteLine("Math.Pow(number1, 2) " + (Math.Pow(number1, 2)));
Console.WriteLine("Math.Round(number1) " + (Math.Round(number1)));
Console.WriteLine("Math.Sqrt(number1) " + (Math.Sqrt(number1)));
// random numbers
Random rand = new Random();
Console.WriteLine("Random number between 1 and 10 is " + rand.Next(1, 11));
// Relational operators : > < >= <= == !=
// Logical operators : && || ^ !
// note: ^ is the exclusive or
Console.WriteLine("What is your child's age? (enter 0 - 18)");
int age = int.Parse(Console.ReadLine());
if ((age >= 5) && (age <= 7))
{
Console.WriteLine("Go to Elementary School");
}
else if ((age > 7) && (age <= 13))
{
Console.WriteLine("Go to middle school");
}
else if ((age < 4) || (age > 18))
{
Console.WriteLine("Your child does not meet our age requirements.");
}
else
{
Console.WriteLine("Go to high school");
}
Console.WriteLine("What is your age? ");
int workingAge = int.Parse(Console.ReadLine());
if ((workingAge < 14) || (workingAge > 67))
{
Console.WriteLine("You shouldn't work.");
}
else
{
Console.WriteLine("Work harder and smarter to get ahead.");
}
}
}
}
Please help.
.Read() reads only a single character. You probably want .ReadLine() instead, which reads all the characters up to Enter, and returns a string.
int workingAge = int.Parse(Console.ReadLine());
Expanding off of #recursive you can use int32.TryParse() to check if a valid number was supplied.
bool valid = false;
int workingAge;
while (!valid)
{
valid = int32.TryParse(Console.ReadLine(), out workingAge);
if (!valid)
Console.WriteLine("Supplied number was invalid");
}
// Rest of code
Edit: I think this can be simplified even further by doing the following:
int workingAge;
while (!int32.TryParse(Console.ReadLine(), out workingAge))
{
Console.WriteLine("Supplied number was invalid");
}
// Rest of code
I will add to recursive's solution and explain what is happening.
since you are using Console.Read() in two different areas -
and since Console.Read() reads one key input (i.e '1') -
you are probably entering two different digits in the first occurance which causes the first .Read() to only read the first digit, and "passes" the second digit to the second .Read()
as was said before me, changing the .Read() to .ReadLine() will solve your issue.

Converting C# to idiomatic R

Originally, I was using a short C# program I wrote to average some numbers. But now I want to do more extensive analysis so I converted my C# code to R. However, I really don't think that I am doing it the proper way in R or taking advantage of the language. I wrote the R in the exact same way I did the C#.
I have a CSV with two columns. The first column identifies the row's type (one of three values: C, E, or P) and the second column has a number. I want to average the numbers grouped on the type (C, E, or P).
My question is, what is the idiomatic way of doing this in R?
C# code:
string path = "data.csv";
string[] lines = File.ReadAllLines(path);
int cntC = 0; int cntE = 0; int cntP = 0; //counts
double totC = 0; double totE = 0; double totP = 0; //totals
foreach (string line in lines)
{
String[] cells = line.Split(',');
if (cells[1] == "NA") continue; //skip missing data
if (cells[0] == "C")
{
totC += Convert.ToDouble(cells[1]);
cntC++;
}
else if (cells[0] == "E")
{
totE += Convert.ToDouble(cells[1]);
cntE++;
}
else if (cells[0] == "P")
{
totP += Convert.ToDouble(cells[1]);
cntP++;
}
}
Console.WriteLine("C found " + cntC + " times with a total of " + totC + " and an average of " + totC / cntC);
Console.WriteLine("E found " + cntE + " times with a total of " + totE + " and an average of " + totE / cntE);
Console.WriteLine("P found " + cntP + " times with a total of " + totP + " and an average of " + totP / cntP);
R code:
dat = read.csv("data.csv", header = TRUE)
cntC = 0; cntE = 0; cntP = 0 # counts
totC = 0; totE = 0; totP = 0 # totals
for(i in 1:nrow(dat))
{
if(is.na(dat[i,2])) # missing data
next
if(dat[i,1] == "C"){
totC = totC + dat[i,2]
cntC = cntC + 1
}
if(dat[i,1] == "E"){
totE = totE + dat[i,2]
cntE = cntE + 1
}
if(dat[i,1] == "P"){
totP = totP + dat[i,2]
cntP = cntP + 1
}
}
sprintf("C found %d times with a total of %f and an average of %f", cntC, totC, (totC / cntC))
sprintf("E found %d times with a total of %f and an average of %f", cntE, totE, (totE / cntE))
sprintf("P found %d times with a total of %f and an average of %f", cntP, totP, (totP / cntP))
I would use the data.table package since it has group by functionality built in.
library(data.table)
dat <- data.table(dat)
dat[, mean(COL_NAME_TO_TAKE_MEAN_OF), by=COL_NAME_TO_GROUP_BY]
# no quotes for the column names
If you would like to take the mean (or perform other function) on multiple columns, still by group, use:
dat[, lapply(.SD, mean), by=COL_NAME_TO_GROUP_BY]
Alternatively, if you want to use Base R, you could use something like
by(dat, dat[, 1], lapply, mean)
# to convert the results to a data.frame, use
do.call(rbind, by(dat, dat[, 1], lapply, mean) )
I would do something like this :
dat = dat[complete.cases(dat),] ## The R way to remove missing data
dat[,2] <- as.numeric(dat[,2]) ## convert to numeric as you do in c#
by(dat[,2],dat[,1],mean) ## compute the mean by group
Of course to aggregate your result in a data.frame you can use the the classic , But I don't think is necessary here since it a list of 3 variables:
do.call(rbind,result)
EDIT1
Another option here is to use the elegant ave :
ave(dat[,2],dat[,1])
But the result is different here. In the sense you will get a vector of the same length as your original data.
EDIT2 To include more results you can elaborate your anonymous function:
by(dat[,2],dat[,1],function(x) c(min(x),max(x),mean(x),sd(x)))
Or returns data.frame more suitable to rbind call and with columns names:
by(dat[,2],dat[,1],function(x)
data.frame(min=min(x),max=max(x),mean=mean(x),sd=sd(x)))
Or use the elegant built-in function ( you can define your's also) summary:
by(dat[,2],dat[,1],summary)
One way:
library(plyr)
ddply(dat, .(columnOneName), summarize, Average = mean(columnTwoName))

C# ++ unary operator increment issue

Question regarding the C# ++ (right placed) operator.
As the left placed ++ operator, for example, ++var, (say holding an int value of 1) will increment by 1 before any other computation takes place (example value of 1 will become 2 after expression is executed and result displayed).
Can anyone explain the difference between the left placed operator and the right placed operator? (var++) as it does not seem to increment even after the expression is executed as it is supposed to do. Here is some sample code:
int var1, var2 = 5, var3 = 6;
var1 = var2++ * --var3;
Console.WriteLine(" {0} ", var1);
Console.ReadKey();
This is just 5 x 5 due to the decrement of var3 but without the decrement it is 5 x 6 and var2++ appears to have no effect other than the value of 5 it carries. If anyone can shed light on this topic I would be grateful. Thanks.
***Issue solved. A lot of great answers and input guys, was hard trying to decide what answer to accept but you are all winners here! Thanks again for the help! =)
int var1, var2 = 5, var3 = 6;
var1 = var2++ * --var3;
Console.WriteLine(" {0} ", var1);
Console.WriteLine(" {0} ", var2);
Console.ReadKey();
Output:
25
6
So var2 is incremented as expected.
++x (prefix increment) increments the value before the expression is evaluated. Thus it first increments the value and then returns it.
x++ (postfix increment) increments the value after the expression is evaluated. Thus, it returns the unchanged value, and only after that, x is incremented.
After the line var1 = var2++ * --var3;, var2 is actually 6, because it was incremented after its value was evaluated.
So your code:
var1 = var2++ * --var3;
does something like this:
int oldVar2 = var2;
var2 = var2 + 1;
var3 = var3 - 1;
var1 = oldVar2 * var3;
In C# the only difference between left-placed operator and right-placed operator is the actual returned value after computation.
In case of left-hand operator, returned new, or incremented value.
In case of right-hand operator, returned value is the "old" one, even if the real value was incremented.
But important to know that in both cases the sequence of operations executed is exactly the same.
The var2 value is incremented after evaluation for the multiplication; the var3 value is decremented before evaluation for the multiplication; it can be roughly conceptualised as:
var tmp = var2; // 5
var2 = var2 + 1; // 5 + 1 = 6
var3 = var3 - 1; // 6 - 1 = 5;
var1 = tmp * var3; // 5 * 5 = 25;
So the 25 is correct. If you inspect var2 you will find that it has incremented as expected.
However! If a complex calculation involving ++foo and bar-- gets confusing, then simply don't do it inline; break the computation down into simpler pieces, and execute that. The compiler won't judge you.
Here is some sample class leveraging concept of PreFix and PostFix increment operators. The code is written with comments making the output more clearer.
public class Test
{
public Test()
{ }
public static void Main(string[] args)
{
int i = 0;
Console.WriteLine("\n" + "Displaying Initial i = " + i + "\n"); // Prints 0 i.e. Initial value of i
Console.WriteLine("\n" + "Displaying PostFix i++ = " + i++ + "\n"); // Prints 0. Then value of i becomes 1.
Console.WriteLine("\n" + "Displaying Post-incremented i = " + i + "\n"); // Prints 1 i.e. Value of i after Post-increment
Console.WriteLine("\n" + "Displaying PreFix ++i = " + ++i + "\n"); // Prints 2. Then value of i incremented to 2
Console.WriteLine("\n" + "Displaying Pre-incremented i = " + i + "\n"); // Prints 2 i.e. Value of i after Pre-increment
Console.WriteLine("\n" + "---------------------------------------------" + "\n");
int j = 0;
Console.WriteLine("\n" + "Displaying Initial j = " + j + "\n"); // Prints 0 i.e. Initial value of j
Console.WriteLine("\n" + "Displaying PreFix ++j = " + ++j + "\n"); // Prints 1. Then value of j incremented to 1.
Console.WriteLine("\n" + "Displaying Pre-incremented j = " + j + "\n"); // Prints 1 i.e. Value of j after Pre-increment
Console.WriteLine("\n" + "Displaying PostFix j++ = " + j++ + "\n"); // Prints 1. Then value of j incremented to 2.
Console.WriteLine("\n" + "Displaying Post-incremented j = " + j + "\n"); // Prints 2 i.e. Value of j after Post-increment
Console.ReadLine();
}
}

Categories