Foreach doubles or triples itself - c#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace lotto
{
class Program
{
static void Main(string[] args)
{
char k = 'l';
while (!(k == 'k'))
{
Random rnd = new Random();
int[] tablica = new int[6];
for (int i = 0; i < 6; i++)
{
tablica[i] = 0;
}
for (int i = 0, z; i < 6; i++)
{
{
z = rnd.Next(1, 49);
while (tablica.Contains(z))
{
z = rnd.Next(1, 49);
}
tablica[i] = z;
}
}
Array.Sort(tablica);
foreach (int q in tablica)
{
Console.Write(q);
Console.Write(", ");
}
k = Convert.ToChar(Console.Read()) ;
Console.WriteLine("\n\n\n");
}
}
}
}
It works alright. When I use the step by step clickage (F10 in visual studio), it runs fine. But when I run it normally, then after the
k=Convert.ToChar(Console.Read());
when I supply 'k', the program stops, as intended.
when I supply nothing, it does the
foreach (int q in tablica)
{
Console.Write(q);
Console.Write(", ");
}
k = Convert.ToChar(Console.Read()) ;
Console.WriteLine("\n\n\n");
two times, and when I supply anything other than 'k' it does it three times. What.The.Hell.

Console.Read reads a single character at a time from the input stream (doc). When you press enter you are supplying two characters: \r then \n, so there are two characters to read before pausing for further user input.
I'm confused how it ran fine when you used F10 as I did this to see what was looping, I just so happened to use Enter when supplying "nothing" and saw the characters pop through.

Did you try capturing the input from Console.Read() and see what it is giving you? It might be something to do with a control character being read in, and it not being able to convert to char properly.
Also, completely aside, I would recommend reformatting your code (you have superfluous "{}" in there in the second for loop). Also, it is always good practice to give meaningful names to your variables. i, j, k, etc. have no inherent meaning. It will just be easier to refactor/maintaining your code in the future.
I didn't take a real close look at the rest of your code, but I'm guessing there are shorter/simpler ways to do a lot of it. This many for/foreach/while loop in one method has a code smell.

By using Console.Read(), you are actually getting your input plus "\r\n",so when you use ENTER you just get "\r\n"(2 chars), when you input a char"m", your input is "m\r\n"(3 chars), that's the reason why there is a "one" difference.
Besides, why use int i = 0, z;? the , z does not mean anything here for this is C++ usage.

Related

C# Get NZEC error parsing input on HackerEarth

I want to learn C# so I started to use hackerearth and solve problems from their website but I got into some kind of problem. So I have the following code
using System;
namespace ConsoleApp6
{
class Program
{
static void Main(string[] args)
{
long N, i, answer = 1;
do
{
N = Convert.ToInt32(Console.ReadLine());
} while (N < 1 && N > 1000);
long[] A = new long[N];
for (i = 0; i < N; i++)
{
do
{
A[i] = Convert.ToInt32(Console.ReadLine());
} while (A[i] < 1 && A[i] > 1000);
}
for(i = 0; i < N; i++)
{
answer = (answer * A[i]) % (1000000007);
}
Console.WriteLine(answer);
}
}
}
When I compile it I get the correct answer and everything it's fine but when I submit it to hackerearth compiler it gives me the NZEC error. I thought I'm missing something since I just started C# some days ago so I wrote it again but in C++ and it gave me the maximum score on the website. I know that there might be some problems in my variable declarations since I didn't understand exactly how to read numbers and I hope you can help me solve this problem. Thank you!
Assuming you are stuck on the Find Product problem, as you've suspected, the input of the data is one line for N, and then one line for ALL N numbers that you need to multiply, separated by a space. You can parse the line of numbers quickly with LINQ (I would suggest you get stuck into LINQ as quickly as possible - this will get you away from the C++ imperative mindset).
How about:
using System;
using System.Linq;
using System.Collections.Generic;
using System.Diagnostics;
namespace ConsoleApp6
{
class Program
{
static void Main(string[] args)
{
var N = Convert.ToInt32(Console.ReadLine()); // Less than 2^31 integers to be read
var A = Console.ReadLine() // Read the line of space delimited numbers
.Split(' ') // Split out by the separator
.Select(n => Convert.ToInt64(n)) // Parse each number to long
.ToArray(); // Convert to a materialized array
Debug.Assert(A.Length == N, "Site lied to us about N numbers");
long answer = 1; // or var answer = 1L;
for(var i = 0; i < N; i++)
{
answer = (answer * A[i]) % (1000000007);
}
Console.WriteLine(answer);
}
}
}
Some notes:
The do..while has no effect - they will always exit after one pass - this because a value cannot be < 1 and > 1000 simultaneously
Note that Convert.ToInt32 parses a 32 bit int. You've defined a long (which is ALWAYS 64 bit in C#, unlike C++), so this should be Convert.ToInt64
The problem does however constrain A[i] under 10 ^ 3, so A[] can be int[], although the product could be larger, so long or even System.Numerics.BigInteger can be used for the product.
NZEC is a site specific error - it means the app crashed with a non zero process ecit code. The site also prints the actual error and stack trace further down the page.
Since you say you want to learn C# (and not just convert C code to C#), you can also LINQify the final for loop which calculates the answer from the array using .Aggregate. Aggregate supports both a seeded overload (i.e. a left fold, as it allows the return type to differ), and an unseeded overload (i.e. reduce where the return type must be the same as the input enumerable). In your case, you don't actually need to seed the answer with 1L since it can be seeded with A[0] and the next multiplication will be with A[1] since any number multiplied by 1 will be number.
var answer = A.Aggregate((subtotal, next) => (subtotal * next) % (1000000007));

Print ASCII of a triangle shape with variable input

Struggling with the print. I know it should be two for loops to print out the repeated letters, however, having problems to indent the lines. it should be a simple console C# program to print out the shape like below with a input 3.
XXXXX
XXX
X
With input 4 it should be like
XXXXXXX
XXXXX
XXX
X
Here is my code. Two for loops get the letters correctly but the lines all lined up at the left, not center.
static void Main(string[] args)
{
string num = Console.ReadLine().Trim();
int n = Convert.ToInt32(num);
int k=1;
for(int i = n; i>=1; i--)
{
Console.WriteLine("\n");
Console.WriteLine("".PadLeft(n));
for (int j = (2*i-1); j>=1;j--)
{
Console.Write("0");
}
}
Console.Read();
}
The statement:
Console.WriteLine("".PadLeft(n));
is the right idea but it's not quite there.
In your case, n is the number of lines you wish to print and is invariant. The number of spaces you need at the start of each line should begin at zero and increase by one for each line.
In any case, printing any number of spaces followed by newline (because it's WriteLine) is not what you want, you should be using Write instead.
So the code between int n = Convert.ToInt32(num); and Console.Read(); would be better off as something like:
for (int lineNum = 0; lineNum < n; lineNum++) {
int spaceCount = lineNum;
int xCount = (n - lineNum) * 2 - 1;
Console.Write("".PadLeft(spaceCount));
Console.WriteLine("".PadLeft(xCount, 'X'));
}
You'll notice some other changes there. First, I've used more meaningful variable names, something I'm a bit of a stickler for - using i is okay in certain circumstances but I often find it's more readable to use descriptive names.
I've also used PadLeft to do the X string as well, so as to remove the need for an inner loop.

checking if user input is equal to a randomly generated list of integers

I have a problem that I cannot seem to figure out.
I want to make a program that generates two random integers that are between 1 and 10 and then asks the user for input. The user must enter the same integers that were given by the program.
I know it probably sounds very simple, but I cant get my head around it. Help would be absolutely great.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Prototyping3
{
class Program
{
static void Main(string[] args)
{
Random random = new Random();
List<int> selection = new List<int>();
selection.Add(random.Next(0, 9));
selection.Add(random.Next(0, 9));
foreach (int s in selection)
{
Console.Write(s);
}
Console.WriteLine("...");
string input = Console.ReadLine();
int converted = Convert.ToInt32(input);
for (int i = 0; i < selection.Count(); i++)
{
if (converted == selection[i])
{
Console.WriteLine("correct");
}
else
{
Console.WriteLine("wrong");
}
}
}
}
}
This is my existing code. The program gives two integers, but when I enter them it just tells me that I'm wrong. When I enter one of the numbers it says im correct and wrong. I dont know what the problem is. Again, help would be greatly appreciated.
Seems like if you entered the right first number, it would tell you correct. But since you never re-enter a second number and store it in converted, the second number will be wrong (unless the two numbers are the same. You should ask for user input again, or just take both numbers in at once.
It's looping so when you input a number it loops on the next selection collection which has 2. Assuming order of doesn't matter. If it does then just do a for loop and check both collection's index if they are equal.
List<int> userInput = new List<int>();
for (int i = 0; i < selection.Count(); i++)
{
var int32 = Convert.ToInt32(Console.ReadLine());
userInput.Add(int32);
}
Console.WriteLine(userInput.Intersect(selection).Count() == selection.Count ? "correct" : "wrong");

whats wrong in this logic of finding longest common child of string

i came up with this logic to find longest common child of two strings of equal length but it runs successfuly only on simple outputs and fails others,pls guide me what i am doing wrong here.
String a, b;
int sum = 0;
int[] ar,br;
ar = new int[26];
br = new int[26];
a = Console.ReadLine();
b = Console.ReadLine();
for (int i = 0; i < a.Length; i++)
{
ar[(a[i] - 65)]++;
br[(b[i] - 65)]++;
}
for(int i =0;i<ar.Length;i++)
{
if (ar[i] <= br[i]) { sum += ar[i]; }
else sum += br[i];
}
Console.Write(sum);
Console.ReadLine();
output:
AA
BB
0 correct.
HARRRY
SALLY
2 correct
for both above input it runs but when i submit for evaluation it fails on their test cases.i cant access their testacase on which my logic fails.i wanna know where does my logic fails.
Your second loop is all wrong. It is simply finding the count of characters that occur in both the array and the count is only updated with the the no. of the common characters contained in the string containing the least no. of these common characters.
refer this link for the correct implementation.
http://en.wikibooks.org/wiki/Algorithm_Implementation/Strings/Longest_common_substring#Retrieve_the_Longest_Substring
Also convert your input to uppercase characters using String.ToUpper before you use the input string.

C#: How to use arrays, chars and strings? Clear up needed

I am new to programming and I have a project in my Algorithm class. What we have to do is decide on a problem and solve it. We haven't learnt much more than string, char and WriteLine. We did add a couple of things as you will see soon!
I decided that what I want to solve this: The user inserts a word, no matter how long and the program will automatically make the first letter a capital letter. So far this is what I have:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
start:
Console.WriteLine("Please enter a word below:");
Console.WriteLine("");
string str = Console.ReadLine();
char char1;
if (str[0] >= 97)
{
char1 = (char)(str[0] - 32);
}
else
{
char1 = (char)(str[0] + 32);
}
char char2 = (char)(str[1]);
char char3 = (char)(str[2]);
char char4 = (char)(str[3]);
char char5 = (char)(str[4]);
Console.WriteLine("");
Console.Write(char1);
Console.Write(char2);
Console.Write(char3);
Console.Write(char4);
Console.WriteLine(char5);
goto start;
}
}
}
The problem with that code is that any word with less than 5 letters will make the program crash. Anything with more than 5 letters will just be cut at the fifth letter... I was told that using arrays should solve this problem. Seeing as I am a total newbie at this, I would need this to be broken down and be as simply told as possible!
Any help getting this to work would be very appreciated.
Thanks :)
Console.WriteLine("Enter a word:");
string str = Console.ReadLine();
Console.WriteLine(str[0].ToString().ToUpper() + str.Substring(1));
This will work.
Or... if you need to go through the entire string and find the first actual alphabetical character, you can do the following:
Console.WriteLine("Please enter a word:");
string s = Console.ReadLine();
bool found = false;
char[] chars = new char[s.Length];
for (int i = 0; i < s.Length; i++)
{
if (Char.IsLetter(s[i]) && !found)
{
chars[i] = s[i].ToString().ToUpper()[0];
found = true;
}
else
{
chars[i] = s[i];
}
}
s = new String(chars);
Console.WriteLine(s);
Use a for loop like this after writing char1 to the Console:
if (str.Length > 1)
{
for (int i = 1; i < str.Length; i++)// Start at 1 to skip char1
{
Console.Write(str[i]);
}
}
There are some methods you can call on string that will be helpful:
Substring
ToUpper
In fact, you don't need to worry about characters; this problem can be solved using only strings.
Also take care to check that your code handles the case where the string is empty (using an if statement), which will happen if the user just presses Enter without typing anything.
You're taking an algorithms class and they make you choose a problem to solve? Sounds dangerous for someone learning.
Console.WriteLine("Please enter a word below:");
Console.WriteLine("");
string inputString = Console.ReadLine(); // try to use meaningful variable names
// shorthand for the if ... else block:
// type variableName = (true/false condition) ? "is true" : "is false";
char firstChar = inputString[0] >= 97 ? (char)(inputString[0] - 32) : (char)(inputString[0] + 32);
Console.WriteLine("");
Console.Write(firstChar);
for (int i = 1; i < inputString.Length; i++) // skip firstChar
{
Console.Write(inputString[i]);
}
As others have mentioned, you need to use a loop for this if you want anything resembling a general solution.
Also, you'll want to avoid using goto statements. There are many reasons, one being that they (in my opinion) make code difficult to read and maintain.
Additionally, if your code had worked as written, it would never end. Your program, as written would execute, then begin again, never stopping. If you want this sort of behavior, then you should wrap your code in an infinite loop which exits upon some condition. This might look something like:
bool keepRunning = true;
while(keepRunning){
//code here
Console.Write("go again? (y/n) ");
keepRunning = (string)(Console.ReadLine()).equals("y") ? false : true;
}
On that last statement, I forget if you need to cast the output of ReadLine to a string before calling the .equals method... I don't have my IDE up. i think you get the idea.
edit: I saw another response that was just posed about using the .ToUpper method. I thought of this but assumed maybe you needed to use the char type.

Categories