Kattis run time error solving Jumbo Javelin with C# - c#

I am new to Kattis and trying solve the challenge Jumbo Javelin with C# but I get run time error even though I am exiting my program with 0.
Here is my code:
using System;
namespace JumboJavelin
{
class Program
{
static void Main(string[] args)
{
int l = int.Parse(Console.ReadLine());
int sum = 0;
int loss = 1;
for (int n = 0; n <= 100; n++)
{
sum += l;
if((n + 1) % 2 == 0 && !n.Equals(0))
{
sum -= ((n + 1) / 2)*loss;
}
try
{
l = int.Parse(Console.ReadLine());
}
catch (FormatException)
{
break;
}
}
Console.WriteLine(sum);
Environment.Exit(0);
}
}
}
Can someone please help me? I know my solution eventually outputs the wrong answer but right now I am trying to get rid of the run time error since it works perfectly fine on Visual Studio 2019.
All help is appreciated. Thanks

If you change the error your catch to Exception you will see that it is actually a wrong answer, so something goes wrong. You do exit your program with an exit code 0 at the bottom of your code, however, it throws an Exception somewhere else. Two things to consider:
First, the problem statement explains that as a first input, you get an integer N (this N indicates the amount of steel rods he has) and CAN BE between 1 and 100 (1 not inclusive hence, 1<N<=100). You now have a loop that always loops from 1 to 100. And the loop should loop from 1 up to and including whatever value N is. Try to see what you can do about that.
Second you read the input at the "tail" of the loop. This means that after the last cycle you do another read input. And that you do not read the first l. Try changing reading the input for l at the beginning of the loop. (and the first input you read in your Main, should not be for l (see point 1)).
See how far this gets you, is something is not clear please let me know.

As Kasper pointed out, n is dynamically provided on the first line; don't assume you have 100 lines to collect with for (int n = 0; n <= 100; n++).
There's no need to handle errors with the format; Kattis will always adhere to the format they specify. If something goes wrong parsing their input, there's no point trying to catch it; it's up to you to fix the misunderstanding. It's better to crash instead of catch so that you won't be fooled by Kattis telling you the failure was due to a wrong answer.
A simple approach is as follows:
Collect n from the first line of input; this is the preamble
Loop from 0 to n, collecting each line
Accumulate the values per line into a sum
Print sum - n + 1, the formula you can derive from their samples
using System;
class JumboJavelin
{
static void Main(string[] args)
{
int n = int.Parse(Console.ReadLine());
int sum = 0;
for (int i = 0; i < n; i++)
{
sum += int.Parse(Console.ReadLine());
}
Console.WriteLine(sum - n + 1);
}
}
You can use this pattern on other problems. You won't always aggregate one result after n lines of input though; sometimes the input is a single line or you have to print something per test case. Some problems require you to split and parse each line on a delimiter.
Regardless of the case, focus on gathering input cleanly as a separate step from solving the problem; only combine the two if you're confident you can do it without confusion or if your solution is exceeding the time limit and you're sure it's correct otherwise.

Related

What is stopping this program from having an output

I made this code to brute force anagrams by printing all possible permutables of the characters in a string, however there is no output. I do not need simplifications as I am a student still learning the basics, I just need help getting it to work this way so I can better understand it.
using System;
using System.Collections.Generic;
namespace anagramSolver
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Enter anagram:");
string anagram = Console.ReadLine();
string temp = "";
List<string> storeStr = new List<string>(0);
List<int> storeInt = new List<int>(0);
//creates factorial number for anagram
int factorial = 1;
for (int i = anagram.Length; i > 0; i--)
{
factorial *= i;
}
while (storeStr.Count != factorial)
{
Random rnd = new Random();
while(temp.Length != anagram.Length)
{
int num = rnd.Next(anagram.Length - 1);
if (storeInt.Contains(num) == true)
{
}
else
{
storeInt.Add(num);
temp += anagram[num];
}
}
if (storeStr.Contains(temp) == true)
{
temp = "";
}
else
{
storeStr.Add(temp);
Console.WriteLine(temp, storeStr.Count);
temp = "";
}
}
}
}
}
edit: added temp reset after it is deemed contained by storeStr
Two main issues causing infinite loop:
1)
As per Random.Next documentation, the parameter is the "exclusive" upper bound. This means, if you want a random number between 0 and anagram.Length - 1 included, you should use rnd.Next(anagram.Length);.
With rnd.Next(anagram.Length - 1), you'll never hit anagram.Length - 1.
2)
Even if you solve 1, only the first main iteration goes well.
storeInt is never reset. Meaning, after the first main iteration, it will have already all the numbers in it.
So, during the second iteration, you will always hit the case if (storeInt.Contains(num) == true), which does nothing and the inner loop will go on forever.
Several issues here...
The expression rnd.Next(anagram.Length - 1) generates a value between 0 and anagram.Length - 2. For an input with two characters it will always return 0, so you'll never actually generate a full string. Remove the - 1 from it and you'll be fine.
Next, you're using a list to keep track of the character indices you've used already, but you never clear the list. You'll get one output (eventually, when the random number generator covers all the values) and then enter an infinite loop on the next generation pass. Clear storeInt after the generation loop to fix this.
While not a true infinite loop, creating a new instance of the random number generator each time will give you a lot of duplication. new Random() uses the current time as a seed value and you could potentially get through a ton of loops with each seed, generating exactly the same values until the time changes enough to change your random sequence. Create the random number generator once before you start your main loop.
And finally, your code doesn't handle repeated input letters. If the input is "aa" then there is only a single distinct output, but your code won't stop until it gets two. If the input was "aab" there are three distinct permutations ("aab", "aba", "baa") which is half of the expected results. You'll never reach your exit condition in this case. You could do it by keeping track of the indices you've used instead of the generated strings, it just makes it a bit more complex.
There are a few ways to generate permutations that are less error-prone. In general you should try to avoid "keep generating random garbage until I find the result I'm looking for" solutions. Think about how you personally would go about writing down the full list of permutations for 3, 4 or 5 inputs. What steps would you take? Think about how that would work in a computer program.
this loop
while(temp.Length != anagram.Length)
{
int num = rnd.Next(anagram.Length - 1);
if (storeInt.Contains(num) == true)
{
}
else
{
storeInt.Add(num);
temp += anagram[num];
}
}
gets stuck.
once the number is in storeInt you never change storeStr, yet thats what you are testing for loop exit

Computing the most frequent element

I have recently come across this line of code and what it does is that it goes through an array and returns the value that is seen most often. For example 1,1,2,1,3 so it will return 1 because it appears more than 2 and 3. What I am trying to do is understand how it works so what I did was I went through it with visual studio step by step but it is not ringing any bells.
Can anyone help me understand what is going on here? It would be a total plus if someone can tell me what does c do and what is the logic behind the arguments in the if statements.
int[] arr = a;
int c = 1, maxcount = 1, maxvalue = 0;
int result = 0;
for (int i = 0; i < arr.Length; i++)
{
maxvalue = arr[i];
for (int j = 0; j <arr.Length; j++)
{
if (maxvalue == arr[j] && j != i)
{
c++;
if (c > maxcount)
{
maxcount = c;
result = arr[i];
}
}
else
{
c=1;
}
}
}
return result;
EDIT: On closer examination, the code snippet has a nested loop and is conventionally counting the maximum seen element by simply keeping track of the maximum seen times and the element that was seen and keeping them in sync.
That looks like an implementation of the Boyer-Moore majority vote counting algorithm. They have a nice illustration here.
The logic is simple, and is to compute the majority in a single pass, taking O(n) time. Note that majority here means that more than 50% of the array must be filled with that element. If there is no majority element, you get an "incorrect" result.
Verifying if the element is actually forming a majority is done in a separate pass usually.
It is not computing the most frequent element - what it is computing is the longest run of elements.
Also, it is not doing it very efficiently, the inner loop only needs to compute upto i-1, not upto arr.Length.
c is keeping track of the current run length. The first "if" is to check if this is a "continouous run". The second "if" (after reaching the last element in the run) will check if this run is longer than any run you have seen so far.
In the above input sample, you are getting 1 as answer because it is the longest run. Try with an input where the element with the longest run is not the same as the most frequent element. (e.g., 2,1,1,1,3,2,3,2,3,2,3,2 - here 2 is the most frequent element, but 1,1,1 is the longest run).

Adding numbers from 1 to N in C#

I'm writing code in C# and trying to add all of the numbers between the number 1 and N, N being the number that is inputted in a textbox. I'm doing this, at least trying to do this, by putting it into a while loop.
I have added all the numbers between 2 textboxes before but for some reason I'm driving myself crazy and can't figure this out. I'm a beginning programmer so please be gentle.
Any help would be greatly appreciated.
Edit:
One of the six thousand things I've tried. I think this has me in an infinite loop?
private void btnAddAll_Click(object sender, EventArgs e)
{
int n;
int count = 0;
int answer = 0;
n = int.Parse(txtNum.Text);
count = n;
while (count >= 1)
{
answer = answer + count;
count++;
}
lstShow.Items.Add("Sum = " + answer);
lstShow.Text = answer.ToString();
}
Why not use Gauss formula. (N*(N+1))/2
private void btnAddAll_Click(object sender, EventArgs e)
{
int n, answer;
n = int.Parse(txtNum.Text);
answer = (n*(n+1))/2;
lstShow.Items.Add("Sum = " + answer);
lstShow.Text = answer.ToString();
}
If you change the ++ to a -- it should work as you want it to.
int n;
int count = 0;
int answer = 0;
n = 3;
count = n;
while (count >= 1)
{
answer = answer + count;
count--; // here was the error
}
Console.WriteLine (answer);
Output: 6
Also, just for a point of additional interest you can use That uses Enumerable.Range and Enumerable.Sum instead of the while loop (probably goes beyond what is expected for a homework but it's useful to know what's out there).
answer = Enumerable.Range(1, n).Sum();
Your edit: you should decrement count..
Another edit, it appears I need to explain more:
By decrement I mean --. The post or pre decrement operator decreases the value by 1.
If count keeps increasing by 1, count >=1 will never be met. You need to reduce count to 1.. hence count--;
Also I suggest you use TryParse(string,out int) ; or at least wrap the Parse call in a try catch block.
Here is a pointer in pseudocode:
GetInput From User
TryParse Input
If Between 1 and N
Declare sum = 1;
for i to N-1
sum+=i;
/* if you don't want to use the for loop
while i < N
sum+=i;
inc i; */
Print sum
Debugging is an important skill for any programmer. There are some good tools in Visual Studio to help with debugging.
A good way to debug your code when you are stuck is to use 'breakpoints' and step through the code.
Select the line you want your code to stop at (e.g. n = int.Parse(txtNum.Text);) and press F9 - this will add a breakpoint at this line.
Now, when you run your programme, it will stop at the breakpoint. If you press F11, you can 'step' through the code one line at a time. You can hold your mouse over a variable to see its value while you are doing this.
You will quickly find the problem in your code if you do this.

Calculate how many ways you can add three numbers so that they equal 1000

I need to create a program that calculates how many ways you can add three numbers so that they equal 1000.
I think this code should work, but it doesn't write out anything. What am I doing wrong? Any tips or solution?
using System;
namespace ConsoleApp02
{
class Program
{
public static void Main(string[] args)
{
for(int a = 0; a < 1000; a++)
{
for(int b = 0; b < 1000; b++)
{
for(int c = 0; c < 1000; c++)
{
for(int puls = a + b + c; puls < 1000; puls++)
{
if(puls == 1000)
{
Console.WriteLine("{0} + {1} + {2} = 1000", a, b, c);
}
}
}
}
}
Console.ReadKey(true);
}
}
}
Your innermost loop (iterating the puls variable) doesn't really make any sense, and because of the condition on it (puls < 1000) Console.WriteLine never runs.
Perhaps you should test whether A + B + C is 1000, instead.
Also, you'll find that you might be missing a couple particular combinations of numbers because of the bounds on your loops (depending on the problem statement.)
On a separate note, this particular implementation, while it'll work (with the modifications suggested by the other answers), is quite a performance hit, as the complexity of your algorithm is O(n^3). In other words, you are going through the innermost check one bilion times.
Here's a hint how you can optimize it to at least O(n^2) or just one milion iterations: for each pair of a and b generated by the two outer for loops, there's only one value for c that will result in 1000.
Question doesn't specify that negative numbers are not allowed. Answer is infinite.
You don't need the inner loop.
if (a+b+c == 1000)
write
In your final inner loop, "int puls = a + b + c; puls < 1000; puls++" you're ensuring that puls never = 1000, if puls is not less than 1000, it kicks out of the loop. That is why you are getting no values. But rethink your logic some as well.
If you get this assignment as a computer science student, you'd probably want to solve this using Dynamic Programming.
Once the inner most loop gets to 1000, it breaks out of the for loop and never even checks if it is 1000 in the 'if' statement.
That code will return no answer.
The interior for loop adds a + b + c and puts the result into puls. However, you stop the loop before puls can get to 1000, and then test inside the for statement to see if puls equals 1000. So, you won't get an answer.
Just test puls against 1000 in the inner loop. Why?
You can replace your innermost for loop with just a test for if (a+b+c == 1000) {...}.
Then you can add optimizations like - once a sum has been found with a combination, there is no need to continue with the inner loop.
The code does not cover the following cases
1000 + 0 + 0
0 + 10000 + 0
0 + 0 + 10000
The inner most loop should be an if rather for.
You don't need {} if there is only one statement in the loop or if clause.
EDIT:
Removed code answers
Try this:
{
for(a=0;a<=500;a++)
{
for (b=a;b<=500;b++)
{
c=1000-(a+b);
count

C# loop - break vs. continue

In a C# (feel free to answer for other languages) loop, what's the difference between break and continue as a means to leave the structure of the loop, and go to the next iteration?
Example:
foreach (DataRow row in myTable.Rows)
{
if (someConditionEvalsToTrue)
{
break; //what's the difference between this and continue ?
//continue;
}
}
break will exit the loop completely, continue will just skip the current iteration.
For example:
for (int i = 0; i < 10; i++) {
if (i == 0) {
break;
}
DoSomeThingWith(i);
}
The break will cause the loop to exit on the first iteration - DoSomeThingWith will never be executed. This here:
for (int i = 0; i < 10; i++) {
if(i == 0) {
continue;
}
DoSomeThingWith(i);
}
Will not execute DoSomeThingWith for i = 0, but the loop will continue and DoSomeThingWith will be executed for i = 1 to i = 9.
A really easy way to understand this is to place the word "loop" after each of the keywords. The terms now make sense if they are just read like everyday phrases.
break loop - looping is broken and stops.
continue loop - loop continues to execute with the next iteration.
break causes the program counter to jump out of the scope of the innermost loop
for(i = 0; i < 10; i++)
{
if(i == 2)
break;
}
Works like this
for(i = 0; i < 10; i++)
{
if(i == 2)
goto BREAK;
}
BREAK:;
continue jumps to the end of the loop. In a for loop, continue jumps to the increment expression.
for(i = 0; i < 10; i++)
{
if(i == 2)
continue;
printf("%d", i);
}
Works like this
for(i = 0; i < 10; i++)
{
if(i == 2)
goto CONTINUE;
printf("%d", i);
CONTINUE:;
}
When to use break vs continue?
Break - We're leaving the loop forever and breaking up forever. Good bye.
Continue - means that you're gonna give today a rest and sort it all out tomorrow (i.e. skip the current iteration)!
(Corny stories ¯¯\(ツ)/¯¯ and pics but hopefully helps you remember.
Grip Alert: No idea why those words are being used. If you want to skip the iteration, why not use the word skip instead of continue? This entire Stack overflow question and 1000s of developers would not be confused if the proper name was given.)
break would stop the foreach loop completely, continue would skip to the next DataRow.
There are more than a few people who don't like break and continue. The latest complaint I saw about them was in JavaScript: The Good Parts by Douglas Crockford. But I find that sometimes using one of them really simplifies things, especially if your language doesn't include a do-while or do-until style of loop.
I tend to use break in loops that are searching a list for something. Once found, there's no point in continuing, so you might as well quit.
I use continue when doing something with most elements of a list, but still want to skip over a few.
The break statement also comes in handy when polling for a valid response from somebody or something. Instead of:
Ask a question
While the answer is invalid:
Ask the question
You could eliminate some duplication and use:
While True:
Ask a question
If the answer is valid:
break
The do-until loop that I mentioned before is the more elegant solution for that particular problem:
Do:
Ask a question
Until the answer is valid
No duplication, and no break needed either.
All have given a very good explanation. I am still posting my answer just to give an example if that can help.
// break statement
for (int i = 0; i < 5; i++) {
if (i == 3) {
break; // It will force to come out from the loop
}
lblDisplay.Text = lblDisplay.Text + i + "[Printed] ";
}
Here is the output:
0[Printed] 1[Printed] 2[Printed]
So 3[Printed] & 4[Printed] will not be displayed as there is break when i == 3
//continue statement
for (int i = 0; i < 5; i++) {
if (i == 3) {
continue; // It will take the control to start point of loop
}
lblDisplay.Text = lblDisplay.Text + i + "[Printed] ";
}
Here is the output:
0[Printed] 1[Printed] 2[Printed] 4[Printed]
So 3[Printed] will not be displayed as there is continue when i == 3
Break
Break forces a loop to exit immediately.
Continue
This does the opposite of break. Instead of terminating the loop, it immediately loops again, skipping the rest of the code.
Simple answer:
Break exits the loop immediately.
Continue starts processing the next item. (If there are any, by jumping to the evaluating line of the for/while)
By example
foreach(var i in Enumerable.Range(1,3))
{
Console.WriteLine(i);
}
Prints 1, 2, 3 (on separate lines).
Add a break condition at i = 2
foreach(var i in Enumerable.Range(1,3))
{
if (i == 2)
break;
Console.WriteLine(i);
}
Now the loop prints 1 and stops.
Replace the break with a continue.
foreach(var i in Enumerable.Range(1,3))
{
if (i == 2)
continue;
Console.WriteLine(i);
}
Now to loop prints 1 and 3 (skipping 2).
Thus, break stops the loop, whereas continue skips to the next iteration.
Ruby unfortunately is a bit different.
PS: My memory is a bit hazy on this so apologies if I'm wrong
instead of break/continue, it has break/next, which behave the same in terms of loops
Loops (like everything else) are expressions, and "return" the last thing that they did. Most of the time, getting the return value from a loop is pointless, so everyone just does this
a = 5
while a < 10
a + 1
end
You can however do this
a = 5
b = while a < 10
a + 1
end # b is now 10
HOWEVER, a lot of ruby code 'emulates' a loop by using a block.
The canonical example is
10.times do |x|
puts x
end
As it is much more common for people to want to do things with the result of a block, this is where it gets messy.
break/next mean different things in the context of a block.
break will jump out of the code that called the block
next will skip the rest of the code in the block, and 'return' what you specify to the caller of the block. This doesn't make any sense without examples.
def timesten
10.times{ |t| puts yield t }
end
timesten do |x|
x * 2
end
# will print
2
4
6
8 ... and so on
timesten do |x|
break
x * 2
end
# won't print anything. The break jumps out of the timesten function entirely, and the call to `puts` inside it gets skipped
timesten do |x|
break 5
x * 2
end
# This is the same as above. it's "returning" 5, but nobody is catching it. If you did a = timesten... then a would get assigned to 5
timesten do |x|
next 5
x * 2
end
# this would print
5
5
5 ... and so on, because 'next 5' skips the 'x * 2' and 'returns' 5.
So yeah. Ruby is awesome, but it has some awful corner-cases. This is the second worst one I've seen in my years of using it :-)
Please let me state the obvious: note that adding neither break nor continue, will resume your program; i.e. I trapped for a certain error, then after logging it, I wanted to resume processing, and there were more code tasks in between the next row, so I just let it fall through.
To break completely out of a foreach loop, break is used;
To go to the next iteration in the loop, continue is used;
Break is useful if you’re looping through a collection of Objects (like Rows in a Datatable) and you are searching for a particular match, when you find that match, there’s no need to continue through the remaining rows, so you want to break out.
Continue is useful when you have accomplished what you need to in side a loop iteration. You’ll normally have continue after an if.
if you don't want to use break you just increase value of I in such a way that it make iteration condition false and loop will not execute on next iteration.
for(int i = 0; i < list.Count; i++){
if(i == 5)
i = list.Count; //it will make "i<list.Count" false and loop will exit
}
Since the example written here are pretty simple for understanding the concept I think it's also a good idea to look at the more practical version of the continue statement being used.
For example:
we ask the user to enter 5 unique numbers if the number is already entered we give them an error and we continue our program.
static void Main(string[] args)
{
var numbers = new List<int>();
while (numbers.Count < 5)
{
Console.WriteLine("Enter 5 uniqe numbers:");
var number = Convert.ToInt32(Console.ReadLine());
if (numbers.Contains(number))
{
Console.WriteLine("You have already entered" + number);
continue;
}
numbers.Add(number);
}
numbers.Sort();
foreach(var number in numbers)
{
Console.WriteLine(number);
}
}
lets say the users input were 1,2,2,2,3,4,5.the result printed would be:
1,2,3,4,5
Why? because every time user entered a number that was already on the list, our program ignored it and didn't add what's already on the list to it.
Now if we try the same code but without continue statement and let's say with the same input from the user which was 1,2,2,2,3,4,5.
the output would be :
1,2,2,2,3,4
Why? because there was no continue statement to let our program know it should ignore the already entered number.
Now for the Break statement, again I think its the best to show by example. For example:
Here we want our program to continuously ask the user to enter a number. We want the loop to terminate when the user types “ok" and at the end Calculate the sum of all the previously entered numbers and display it on the console.
This is how the break statement is used in this example:
{
var sum = 0;
while (true)
{
Console.Write("Enter a number (or 'ok' to exit): ");
var input = Console.ReadLine();
if (input.ToLower() == "ok")
break;
sum += Convert.ToInt32(input);
}
Console.WriteLine("Sum of all numbers is: " + sum);
}
The program will ask the user to enter a number till the user types "OK" and only after that, the result would be shown. Why?
because break statement finished or stops the ongoing process when it has reached the condition needed.
if there was no break statement there, the program would keep running and nothing would happen when the user typed "ok".
I recommend copying this code and trying to remove or add these statements and see the changes yourself.
As for other languages:
'VB
For i=0 To 10
If i=5 then Exit For '= break in C#;
'Do Something for i<5
next
For i=0 To 10
If i=5 then Continue For '= continue in C#
'Do Something for i<>5...
Next

Categories

Resources