Ideal behavior for a constraint in online test c# - c#

I want to know how to proceed if a console input is not met in a online test.
Like - 0 > x > 10
Sample question -
Please take two inputs from user and return the sum of the both.
Constraint -
0 < a < 10
2 < b <= 15
Below are solutions I have tried with their success rate.
Case 1:
int a = Convert.ToInt32(Console.ReadLine());
while (a < 1 || a > 9)
a = Convert.ToInt32(Console.ReadLine());
int b = Convert.ToInt32(Console.ReadLine());
while (b < 3 || b > 15)
b = Convert.ToInt32(Console.ReadLine());
Success - 35 %
Case 2
int a = Convert.ToInt32(Console.ReadLine());
if(a < 1 || a > 9)
Environment.Exit(0);
int b = Convert.ToInt32(Console.ReadLine());
if(b < 3 || b > 15)
Environment.Exit(0);
Success - 35 %
Case 3:
try
{
int a = Convert.ToInt32(Console.ReadLine());
if (a < 1 || a > 9)
throw new ArgumentException();
int b = Convert.ToInt32(Console.ReadLine());
if (b < 3 || b > 15)
throw new ArgumentException();
return a + b;
}
catch(ArgumentException ex)
{
Console.WriteLine(ex);
}
Success - 0%
Case 4: Without Constraint
int a = Convert.ToInt32(Console.ReadLine());
int b = Convert.ToInt32(Console.ReadLine());
return a + b;
Success - 95%
So what am I missing to get 100%

You would need to do a validation of some sort. Don't use an "Environment.Exit" because a while loop doesn't work like that. A while loop will continue until it returns "False" for example see the code below to validate digit input in the console.
while(!int.TryParse(someString, out int someInt))
{
Console.WriteLine("Your variable someString contains something other than numbers.");
}
Your code might look something like this.0 > x > 10
while(x < 0 || x > 10)
{
Console.WriteLine("Do this code.");
}
Constraints:
0 < a < 10
2 < b <= 15
Code:
int a;
int b; //Declare these outside the loop.
while(!(a > 0 && a < 10 && b > 2 && b <=15))
{
Console.WriteLine("Please Input a valid number for A.");
a = Console.ReadLine();
Console.WriteLine("Please Input a valid number for B.";
b = Console.ReadLine();
}
int sum = a + b;
Console.WriteLine($"The sum is {sum}.");

Related

Hollow Square Inside Hollow Square C#

Hello is it possible to create this kind of patter using console c#?
Input 1: 5
Input 2 :3
Expected Output:
*****
* * *
*** *
* *
*****
Here the top-left of the 5x5 box overlaps with the top-left of the 3x3 box.
I already tried to recreate this patter but i ended up with just whole square with cross inside
Example of my code below:
int num1,num2, i, j;
Console.WriteLine("Input 1");
num1 = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("Input 2");
num2 = Convert.ToInt32(Console.ReadLine());
for(i = 0;i < num1;i++)
{
for(j = 0;j < num1;j++)
{
if(i == 0 || i == num1 - 1)
{
Console.Write(" * ");
}
else if(j == 0 || j == num1 - 1)
{
Console.Write(" * ");
}else if (j == num2 -1 || i == num2 -1){
Console.Write(" * ");
}
else
{
Console.Write(" "); // space is printed ..
}
}
Console.WriteLine("");
}
Console.ReadLine();
Input 1: 5
Input 2: 3
Output:
*****
* * *
*****
* * *
*****
The reason you're seeing the output you are is that you are also considering values beyond the edges of box 2 as being within the box (along edge lines).
That is to say that your intention is to draw the black lines and the blue lines, but you're continuing the vertical line down (red) and the horizontal line across (red). In these situations, you need to restrict the line vertically or horizontally to ensure you don't extend it too far.
I would create two flags for each of the boxes:
bool borderOfOuterBox =
i == 0 // top
|| j == 0 // left side
|| i == (num1 - 1) // bottom
|| j == (num1 - 1); // right side
bool borderOfInnerBox =
i == 0 // top
|| j == 0 // left side
|| (i == (num2 - 1) && j < num2) // bottom (note j is within the bounds of num2)
|| (j == (num2 - 1) && i < num2); // right side (not i is within the bounds of num2)
Then the whole check for writing becomes this:
bool borderOfOuterBox = i == 0 || j == 0 || i == (num1 - 1) || j == (num1 - 1);
bool borderOfInnerBox = i == 0 || j == 0 || (i == (num2 - 1) && j < num2) || (j == (num2 - 1) && i < num2);
if (borderOfOuterBox || borderOfInnerBox)
{
Console.Write(" * ");
}
else
{
Console.Write(" "); // space is printed ..
}

I can't get numbers to be output the way I want in C#

I want to input a number between 1-100 and the console should write all numbers from input number to 101. If I input a number that is between 1-100 the program should close. I am having trouble getting the program to close when I input 0 or 101. It either freezes or includes 0 if I input 0 and just writes 101 if 101 is input. When the numbers are output there is no space between them.
static void Main(string[] args)
{
Console.WriteLine("Input a number between 1-100");
Console.Write("");
string number = Console.ReadLine();
int x = Convert.ToInt32(number);
do
{
if (x > 0 || x < 101) //I tried switching out || for &&
{
Console.Write(x++);
}
} while (x != 102);
}
You can do this using a for loop with a predefined value.
for (int x = Convert.ToInt32(number); x < 102; x++)
{
Console.WriteLine(x);
}
if (x > 0 || x < 101)
this is true for pretty much every number. You want to change || to &&
Console.Write(x++);
Change this to WriteLine or add an extra space at the end of x++ to get your space between them.
while (x != 102);
this only checks a single value. if you typed in, for example, 103, you would get an infinity loop. try < 102
One way is to use the current value of x as loop-condition
Console.WriteLine("Input a number between 1-100");
int x = Convert.ToInt32(Console.ReadLine());
while (x > 0 && x < 101)
{
Console.WriteLine(x++);
}
I think it's better to use a "for" loop:
Console.WriteLine("Input a number between 1-100");
Console.Write("");
string number = Console.ReadLine();
int x = Convert.ToInt32(number);
if( x > 0 && x < 101 )
{
for( int i = x; i <=101; i++ )
{
Console.Write(i);
}
}
Or if you want to use "do-while" loop, change your code like this:
static void Main( string[ ] args )
{
Console.WriteLine("Input a number between 1-100");
Console.Write("");
string number = Console.ReadLine();
int x = Convert.ToInt32(number);
do
{
if (x > 0 && x <= 101)
{
Console.WriteLine(x++);
}
else
{
Environment.Exit( 0 ); // when insert 0 or 101
}
} while (x < 102);
Console.ReadKey( ); // when write all numbers, wait for a key to close program
}
This code also handles if user tries to give input that isn't a digit.
int x;
// read input until user inputs a digit instead of string or etc.
do
{
Console.WriteLine("Input a number between 1-100");
}
while (!Int32.TryParse(Console.ReadLine(), out x));
// exit from program if x isn't between 1 and 100
if (x < 1 || x > 100)
return;
// else count from given number to 101
for(int i = x; i < 101; ++i)
{
Console.WriteLine(i);
}

Return value only of last iteration

I am trying to calculate the Greatest Common Divisor using a while loop. I am therefore looking for the greatest number (i.e. the last value of the loop). How do I get rid of the preceding numbers?
Example:
The greatest common divisor of 84 and 18 is 6. However, my code gives me the numbers 2, 3, and 6. What do I need to change to get only the last number?
using System;
namespace CalculateGCD
{
class Program
{
static void Main(string[] args)
{
int a = int.Parse(Console.ReadLine());
int b = int.Parse(Console.ReadLine());
int i = 1;
while (i <= Math.Min(a, b))
{
i++;
if (a % i == 0 && b % i == 0)
{
Console.WriteLine("GCD:{0}", i);
}
}
}
}
}
Define a variable called max then print the max out of the while loop like this:
int max = 0;
while (i <= Math.Min(a, b))
{
i++;
if (a % i == 0 && b % i == 0)
{
max = i;
}
}
Console.WriteLine("GCD:{0}", max);
Also if you are using C# 6 you could simplify your Console.WriteLine by using string interpolation like this:
Console.WriteLine($"GCD:{max}");
There is a simple solution which will calculate GCD
static int GCD(int a, int b) {
return b == 0 ? a : GCD(b, a % b);
}
and you can use it like below
using System;
namespace CalculateGCD
{
public class Program
{
public static void Main(string[] args)
{
int a = int.Parse(Console.ReadLine());
int b = int.Parse(Console.ReadLine());
Console.WriteLine(GCD(a,b));
}
static int GCD(int a, int b)
{
return b == 0 ? a : GCD(b, a % b);
}
}
}
You can invert the loop, insted of going from 1 to the Min between a and b, search from the Min to 1.
int i = Math.Min(a, b);
while (i > 0)
{
i--;
if (a % i == 0 && b % i == 0)
{
Console.WriteLine("GCD:{0}", i);
break;
}
}
simply reverse the enumeration sequence will do
int a = int.Parse(Console.ReadLine());
int b = int.Parse(Console.ReadLine());
int i = Math.Min(a ,b);
while (i > 1)
{
if (a % i == 0 && b % i == 0)
{
Console.WriteLine("GCD:{0}", i);
break;//greatest will be the first
}
i--;
}
int gcd;
while (i <= Math.Min(a, b))
{
i++;
if (a % i == 0 && b % i == 0)
{
gcd=i;
}
}
Console.WriteLine("GCD:{0}",gcd);
Save greatest common divisor in a variable.

C# How to correct wrong input within an array

So I need to do a array loop with students for class. The input has to be between 0-100 otherwise it doesn't accept the input from the user.
Console.WriteLine("How many students?");
int num1 = Keyboard.ReadInt();
int[] array = new int[num1];
Console.WriteLine("Give the student grades: ");
for (int i = 0; i < array.Length; i++)
{
int wrong;
wrong = Keyboard.ReadInt();
if (wrong > 0 && wrong <= 100)
{
array[i] = wrong;
}
else
{
while (wrong < 0 && wrong >= 100)
{
Console.WriteLine("Wrong input:");
wrong = Keyboard.ReadInt();
}
}
I think you just need to change && to ||:
while (wrong < 0 || wrong >= 100) ...
A number cannot be lower than zero and greater than 99 at the same time.
Your wrong variable can't be less then 0 and and bigger than 100 at the same time.
You should say: if wrong is less than 0 OR bigger than 100
That's why you need to use || instead of &&
Change your code like this :
while (wrong < 0 || wrong >= 100)
{
Console.WriteLine("Wrong input:");
wrong = Keyboard.ReadInt();
}
or you could change while to if here:
if (wrong < 0 || wrong >= 100)
{
Console.WriteLine("Wrong input:");
wrong = Keyboard.ReadInt();
}
or you could remove the whole block and use it in else statement in these two ways:
if (wrong > 0 && wrong <= 100)
{
array[i] = wrong;
}
else if(wrong < 0 || wrong >= 100)
{
Console.WriteLine("Wrong input:");
wrong = Keyboard.ReadInt();
}
or
if (wrong > 0 && wrong <= 100)
{
array[i] = wrong;
}
else
{
Console.WriteLine("Wrong input:");
wrong = Keyboard.ReadInt();
}

A recursion related issue in c#

This is the background to this question:
Background
Take any integer n greater than 1 and apply the following algorithm
If n is odd then n = n × 3 + 1 else n = n / 2
If n is equal to 1 then stop, otherwise go to step 1
The following demonstrates what happens when using a starting n of 6
6 - 3 - 10 - 5 - 16 - 8 - 4 - 2 - 1
After 8 generations of the algorithm we get to 1.
It is conjectured that for every number greater than 1 the repeated application of this algorithm will
eventually get to 1.
The question is how can I find a number that takes exactly 500 generations to reduce to 1?
The code below is my version but appearntly got some wrong logic. Could you help me correct this? Thanks in advance.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Sequence1
{
class Program
{
static void Main(string[] args)
{
int start = 1;
int flag = 0;
int value;
while(true){
int temp = (start - 1) / 3;
string sta = temp.ToString();
if (Int32.TryParse(sta, out value) )
{
if (((start - 1) / 3) % 2 == 1)
{
start = (start - 1) / 3;
flag++;
if (flag == 500)
{
break;
}
}
else
{
start = start * 2;
flag++;
if (flag == 500)
{
break;
}
}
}
else
{
start = start * 2;
flag++;
if (flag == 500)
{
break;
}
}
}
Console.WriteLine("result is {0}", start);
Console.ReadLine();
}
}
}
Since your question's title is "A recursion related issue", I will give you a recursive solution.
int Process(int input, int maxRecursionDepth)
{
// condition to break recursion
if (maxRecursionDepth == 0 || input == 1)
return input;
if (input % 2 == 1) // odd case
return Process(input * 3 + 1, maxRecursionDepth - 1);
else // even case
return Process(input / 2, maxRecursionDepth - 1);
}
Now to find all number in a specified range, that return 1 after exactly 500 recursions:
int startRange = 1, endRange = 1000;
int maxDepth = 500;
List<int> resultList = new List<int>();
for (int i = startRange; i <= endRange; i++)
{
if (Process(i, maxDepth) == 1)
resultList.Add(i);
}
Your problem is a part of Collatz conjecture (about recursively defined function) which has not been solved yet:
http://en.wikipedia.org/wiki/Collatz_conjecture
so I think brute force is a good way out:
public static int GetMinNumber(int generations) {
if (generations < 0)
throw new ArgumentOutOfRangeException("generations");
// Memoization will be quite good here
// but since it takes about 1 second (on my computer) to solve the problem
// and it's a throwaway code (all you need is a number "1979515")
// I haven't done the memoization
for (int result = 1; ; ++result) {
int n = result;
int itterations = 0;
while (n != 1) {
n = (n % 2) == 0 ? n / 2 : 3 * n + 1;
itterations += 1;
if (itterations > generations)
break;
}
if (itterations == generations)
return result;
}
}
...
int test1 = GetMinNumber(8); // <- 6
int test2 = GetMinNumber(500); // <- 1979515
Observing the problem,
13 → 40 → 20 → 10 → 5 → 16 → 8 → 4 → 2 → 1
In the third iteration we hit the number 10, which is smaller than 13
So instead of calculating the sequence count every time we can use a cache.
static int GetMinCollatz(int maxChain)
{
const long number = 1000000;
int minNumber = 0;
// Temporary values
int tempCount = 0;
long temp = 0;
// Cache
int[] sequenceCache = new int[number + 1];
// Fill the array with -1
for (int index = 0; index < sequenceCache.Length; index++)
{
sequenceCache[index] = -1;
}
sequenceCache[1] = 1;
for (int index = 2; index <= number; index++)
{
tempCount = 0;
temp = index;
// If the number is repeated then we can find
// sequence count from cache
while (temp != 1 && temp >= index)
{
if (temp % 2 == 0)
temp = temp / 2;
else
temp = temp * 3 + 1;
tempCount++;
}
sequenceCache[index] = tempCount + sequenceCache[temp];
if (sequenceCache[index] == maxChain)
{
minNumber = index;
}
}
return minNumber;
}
For more details refer project euler and this.
A recursive solution
private void ReduceTo1(int input, ref int totalCount)
{
totalCount++;
if (input % 2 == 0)
{
input = input / 2;
}
else
{
input = input * 3 + 1;
}
if (input != 1)
ReduceTo1(input, ref totalCount);
}
to test
int desireValue = 0;
for (int i = 1; i < 100000; i++)
{
int totalCount = 0;
ReduceTo1(i, ref totalCount);
if (totalCount >= 500)
{
desireValue = i;
break;
}
}

Categories