C# Collatz - Does anyone know a fix? - c#

Hey does anyone have a fix for this? I don't know why i keep getting an error that the main-cs and compilation fails.
using System;
class MainClass {
public static void Main (string[] args) {
Console.WriteLine ("Length of Collatz Row");
int cn = Console.ReadLine();
CollatzListLength(cn);
}
public int CollatzListLength(n){
int number;
List<int> numbers = new List<int>();
while(n != 1){
if(n % 2 == 0){
number = n/2;
}
if(n%2 ==1){
number = n*3 + 1;
}
n = number;
numbers.Add(number);
}
return numbers.Count;
}

Console.ReadLine() returns a string, not an int.
CollatzListLength needs to be static and the parameter needs to be declared as int
n = number; doesn't work because number may never be assigned a value. Use else instead of if (n % 2 == 1) as it just checks the other possible condition anyway.
In total:
static void Main(string[] args)
{
Console.WriteLine("Length of Collatz Row");
if (int.TryParse(Console.ReadLine(), out int cn))
CollatzListLength(cn);
else
Console.WriteLine("Needs a number");
}
public static int CollatzListLength(int n)
{
int number;
List<int> numbers = new List<int>();
while (n != 1)
{
if (n % 2 == 0)
{
number = n / 2;
}
else
{
number = n * 3 + 1;
}
n = number;
numbers.Add(number);
}
return numbers.Count;
}
I haven't actually checked the sanity of the code though.

An alternative, repaired to compile without error messages:
using System;
using System.Collections.Generic;
class Program
{
public static void Main(string[] args)
{
Console.WriteLine("Length of Collatz Row");
int cn = int.Parse(Console.ReadLine());
int len = CollatzListLength(cn);
Console.WriteLine($"len {len}");
}
public static int CollatzListLength(int n)
{
int number = 0;
List<int> numbers = new List<int>();
while (n != 1)
{
if (n % 2 == 0)
{
number = n / 2;
}
if (n % 2 == 1)
{
number = n * 3 + 1;
}
n = number;
numbers.Add(number);
}
return numbers.Count;
}
}

Related

The code stops after one input

I have to create a program that breaks after the sum of the digits of a number is bigger than 20.(The code seems to break after one entry(i entered the number 5))This is my attempt:
class Program
{
static void Main(string[] args)
{
int sum = 0;
while (sum < 20)
{
string number = Console.In.ReadLine();
foreach (int num in number)
{
sum += num;
}
if (sum >= 20)
{
break;
}
sum = 0;
}
}
}
Your code makes no sense however the issue is the ascii value instead of int indicated below:
string numero = Console.In.ReadLine();
foreach (int num in numero) ----> This takes ascii value of the char NOT int value
Try this code out:
public static int CharToInt(char input)
{
int result = -1;
if (input >= 48 && input <= 57)
{
result = input - '0';
}
return result;
}
static void Main(string[] args)
{
int soma = 0;
while (soma < 20)
{
Console.WriteLine("Soma is:" + soma);
string numero = Console.In.ReadLine();
foreach (char num in numero)
{
int value = CharToInt(num);
soma += value;
}
}
Console.WriteLine("Final Soma is:" + soma);
}
You have to convert the string number to an integer first with Int.TryParse().
I'd go this way:
class Program
{
static void Main(string[] args)
{
int sum = 0;
string number = Console.In.ReadLine();
foreach (var num in number.Select(digit => int.Parse(digit.ToString())))
{
sum += num;
if (sum >= 20)
break;
}
Console.WriteLine("Sum :{0}",sum);
Console.ReadLine();
}
}

I need help implementing a for loop

I've been trying to implement this into a for loop. I wrote out a flow chart for this program. The program needs to repeat until n = 1. Ive included a link to my flow chart. If someone could help me out here that would be awesome.
using System;
namespace collatzconjecture
{
class MainClass
{
public static void Main(string[] args)
{
int n = Convert.ToInt32(Console.ReadLine());
if (n == 1)
{
Console.WriteLine("n = {0}", n);
}
else if (n % 2 == 0)
{
int a = n / 2;
Console.WriteLine("n = {0}", a);
}
else
{
int b = 3 * n + 1;
Console.WriteLine("n = {0}", b);
}
Console.ReadKey();
}
}
}
If you have to use for, put it straightforward, as it is described:
start with user input
break on n == 1
next step is either 3 * n + 1 or n / 2
something like this:
public static void Main(string[] args) {
for (int n = Convert.ToInt32(Console.ReadLine()); // start with user input
n > 1; // safier choice then n != 1
n = n % 2 == 0 ? n / 2 : 3 * n + 1) // next step either n/2 or 3*n + 1
Console.WriteLine(n);
Console.ReadKey();
}
However, if you can choose the implementation, I suggest extacting logic into a generator:
private static IEnumerable<int> Collatz(int n) {
while (n > 1) {
yield return n;
n = n % 2 == 0
? n / 2
: 3 * n + 1;
}
yield return n;
}
And UI
public static void Main(string[] args) {
int n = Convert.ToInt32(Console.ReadLine());
Console.Write(string.Join(Environment.NewLine, Collatz(n)));
}
What you really want is a while loop that continues until n is 1.
public static void Main(string[] args)
{
int n = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("n = {0}", n);
while(n != 1)
{
if (n % 2 == 0)
{
n = n / 2;
}
else
{
n = 3 * n + 1;
}
Console.WriteLine("n = {0}", a);
}
Console.ReadKey();
}

C# (find second largest number) How to split program in subprograms ?so I can reuse code later...?

I have this program that finds second largest number from users input, user needs to input atleast 2 numbers and maximum 10. I want to split program into subprograms(at least main and one function). And i cant get it to work :(
Org. code:
static void Main(string[] args)
{
int n = 1, max = 0, smax = 0, i = 0, ISsmaxrepeating = 0;
while (n != 0 && i < 10)
{
Console.WriteLine("Input number");
n = int.Parse(Console.ReadLine());
//I want this part to be in a function from here.
if (n > max)
{
smax = max;
max = n;
}
else if (n > smax)
{
smax = n;
}
//to here
if (n == smax)
{
ISsmaxrepeating = n; // checks if there are 2 numbers smax. Example: 2 1 1 it outputs error
}
i++;
}
if (smax != 0 && smax != ISsmaxrepeating)
{
Console.WriteLine("secondmax is {0}", smax);
}
else
{
Console.WriteLine("error");
}
Console.ReadLine();
So far I come up with this but it is not working :(
static int checking(int n, int max, int smax)
{
if (n > max)
{
smax = max;
max = n;
}
else if (n > smax)
{
smax = n;
}
return n;
}
static void Main(string[] args)
{
int n = 1, max = 0, smax = 0, i = 0, ISsmaxrepeating = 0, result = 0;
while (n != 0 && i < 10)
{
Console.WriteLine("Input number");
n = int.Parse(Console.ReadLine());
result = checking(n,max,smax);
if (n == smax)
{
ISsmaxrepeating = n; // checks if there are 2 numbers smax. Example: 2 1 1 it outputs error
}
i++;
}
if (smax != 0 && smax != ISsmaxrepeating)
{
Console.WriteLine("secondmax is {0}", smax);
}
else
{
Console.WriteLine("error");
}
Console.ReadLine();
}
You can output multiple variables from the function using ref keyword. However, it's better not to use a function for this kind of operation.
static void checking(int n, ref int max, ref int smax)
{
if (n > max)
{
smax = max;
max = n;
}
else if (n > smax)
{
smax = n;
}
}
Call the function inside Main
checking(n, ref max, ref smax);
Why dont.you use Math.max or Math.min? If.you want to find highest between 3 numbes, first do int halfmax=math.max(firstnum,secondnum)
then do int max = Math.max(halfmaz,thirdnum).

Number of zeroes at the end of factorial

I need to find the number of zeroes at the end of a factorial number. So here is my code, but it doesn't quite work :/
using System;
class Sum
{
static void Main(string[] args)
{
int n = int.Parse(Console.ReadLine());
long factoriel = 1;
for (int i = 1; i <= n; i++)
{
factoriel *= i;
}
Console.WriteLine(factoriel);
int timesZero = 0;
while(factoriel % 10 != 0)
{
timesZero++;
}
Console.WriteLine(timesZero);
}
}
I know I can use a for loop and divide by 5, but I don't want to. Where is the problem in my code and why isn't it working?
There's problem with your algorithm: integer overflow. Imagine, that you are given
n = 1000
and so n! = 4.0238...e2567; you should not compute n! but count its terms that are in form of (5**p)*m where p and m are some integers:
5 * m gives you one zero
25 * m gives you two zeros
625 * m gives you three zeros etc
The simplest code (which is slow on big n) is
static void Main(string[] args) {
...
int timesZero = 0;
for (int i = 5; i <= n; i += 5) {
int term = i;
while ((term % 5) == 0) {
timesZero += 1;
term /= 5;
}
}
...
}
Much faster implementation is
static void Main(string[] args) {
...
int timesZero = 0;
for (int power5 = 5; power5 <= n; power5 *= 5)
timesZero += n / power5;
...
}
Counting Trailing zeros in Factorial
static int countZerosInFactOf(int n)##
{
int result = 0;
int start = 1;
while (n >= start)
{
start *= 5;
result += (int)n/start;
}
return result;
}
Make sure to add inbuilt Reference System.Numeric
using System.Text;
using System.Threading.Tasks;
using System.Numeric
namespace TrailingZeroFromFact
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Enter a no");
int no = int.Parse(Console.ReadLine());
BigInterger fact = 1;
if (no > 0)
{
for (int i = 1; i <= no; i++)
{
fact = fact * i;
}
Console.WriteLine("{0}!={1}", no, fact);
string str = fact.ToString();
string[] ss = str.Split('0');
int count = 0;
for (int i = ss.Length - 1; i >= 0; i--)
{
if (ss[i] == "")
count = count + 1;
else
break;
}
Console.WriteLine("No of trailing zeroes are = {0}", count);
}
else
{
Console.WriteLine("Can't calculate factorial of negative no");
}
Console.ReadKey();
}
}
}
static void Main(string[] args)
{
Console.WriteLine("Enter the number:");
int n = int.Parse(Console.ReadLine());
int zero = 0;
long fac=1;
for (int i = 1; i <= n; i++)
{
fac *= i;
}
Console.WriteLine("Factorial is:" + fac);
ab:
if (fac % 10 == 0)
{
fac = fac / 10;
zero++;
goto ab;
}
else
{
Console.WriteLine("Zeros are:" + zero);
}
Console.ReadLine();
}
Your code seems fine, just a little correction in the while-condition:
public static int CalculateTrailingZeroes(BigInteger bigNum)
{
int zeroesCounter = 0;
while (bigNum % 10 == 0)
{
zeroesCounter++;
bigNum /=10;
}
return zeroesCounter;
}
That works, I just tested it.

n-th prime number problem, need to speed it up a bit

There is simple cipher that translates number to series of . ( )
In order to encrypt a number (0 .. 2147483647) to this representation, I (think I) need:
prime factorization
for given p (p is Prime), order sequence of p (ie. PrimeOrd(2) == 0, PrimeOrd(227) == 49)
Some examples
0 . 6 (()())
1 () 7 (...())
2 (()) 8 ((.()))
3 (.()) 9 (.(()))
4 ((())) 10 (().())
5 (..()) 11 (....())
227 (................................................())
2147483648 ((..........()))
My source code for the problem
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
static class P
{
static List<int> _list = new List<int>();
public static int Nth(int n)
{
if (_list.Count == 0 || _list.Count < n)
Primes().Take(n + 1);
return _list[n];
}
public static int PrimeOrd(int prime)
{
if (_list.Count == 0 || _list.Last() < prime)
Primes().First(p => p >= prime);
return (_list.Contains(prime)) ? _list.FindIndex(p => p == prime) : -1;
}
public static List<int> Factor(int N)
{
List<int> ret = new List<int>();
for (int i = 2; i ≤ N; i++)
while (N % i == 0)
{
N /= i;
ret.Add(i);
}
return ret;
}
public static IEnumerable<int> Primes()
{
_list = new List<int>();
_list.Add(2);
yield return 2;
Func<int, bool> IsPrime = n => _list.TakeWhile(p => p ≤ (int)Math.Sqrt(n)).FirstOrDefault(p => n % p == 0) == 0;
for (int i = 3; i < Int32.MaxValue; i += 2)
{
if (IsPrime(i))
{
_list.Add(i);
yield return i;
}
}
}
public static string Convert(int n)
{
if (n == 0) return ".";
if (n == 1) return "()";
StringBuilder sb = new StringBuilder();
var p = Factor(n);
var max = PrimeOrd(p.Last());
for (int i = 0; i ≤ max; i++)
{
var power = p.FindAll((x) => x == Nth(i)).Count;
sb.Append(Convert(power));
}
return "(" + sb.ToString() + ")";
}
}
class Program
{
static void Main(string[] args)
{
string line = Console.ReadLine();
try
{
int num = int.Parse(line);
Console.WriteLine("{0}: '{1}'", num, P.Convert(num));
}
catch
{
Console.WriteLine("You didn't entered number!");
}
}
}
The problem is SLOWNESS of procedure PrimeOrd. Do you know some FASTER solution for finding out order of prime in primes?
Heading
If You know how to speed-up finding order of prime number, please, suggest something. :-)
Thank You.
P.S. The biggest prime less than 2,147,483,648 is 2,147,483,647 and it's 105,097,565th prime. There is no need to expect bigger number than 2^31.
This is not something you should be doing at run-time. A better option is to pre-calculate all these primes and then put them in your program somehow (a static array, or a file to be read in). The slow code is then run as part of the development process (which is slow anyway :-), not at the point where you need your speed.
Then it's just a matter of a lookup of some sort rather than calculating them every time you need them.
Please see SO questions:
http://www.google.com/search?q=site%3Astackoverflow.com+prime+number&btnG=Search
Finding prime numbers with the Sieve of Eratosthenes (Originally: Is there a better way to prepare this array?)
Prime number calculation fun
How can I find prime numbers through bit operations in C++?
prime numbers c#
Finding composite numbers
Prime numbers program
If you need a list of known primes, have a look here
You should cache the primes to _list and then use it for both Factor and PrimeOrd. Additionally avoid operators LINQ operators like TakeWhile that create values that you throw away.
Here's an optimized version:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
static class P
{
private static List<int> _list = new List<int>();
public static int Nth(int n)
{
if (_list.Count == 0 || _list.Count <= n)
{
GenerateNextPrimes().First(p => _list.Count >= n);
}
return _list[n];
}
public static int PrimeOrd(int prime)
{
var primes = GrowPrimesTo(prime);
return primes.IndexOf(prime);
}
public static List<int> Factor(int N)
{
List<int> ret = new List<int>();
GrowPrimesTo(N);
for (int ixDivisor = 0; ixDivisor < _list.Count; ixDivisor++)
{
int currentDivisor = _list[ixDivisor];
while (N % currentDivisor == 0)
{
N /= currentDivisor;
ret.Add(currentDivisor);
}
if (N <= 1)
{
break;
}
}
return ret;
}
private static List<int> GrowPrimesTo(int max)
{
if (_list.LastOrDefault() >= max)
{
return _list;
}
GenerateNextPrimes().First(prime => prime >= max);
return _list;
}
private static IEnumerable<int> GenerateNextPrimes()
{
if (_list.Count == 0)
{
_list.Add(2);
yield return 2;
}
Func<int, bool> IsPrime =
n =>
{
// cache upperBound
int upperBound = (int)Math.Sqrt(n);
for (int ixPrime = 0; ixPrime < _list.Count; ixPrime++)
{
int currentDivisor = _list[ixPrime];
if (currentDivisor > upperBound)
{
return true;
}
if ((n % currentDivisor) == 0)
{
return false;
}
}
return true;
};
// Always start on next odd number
int startNum = _list.Count == 1 ? 3 : _list[_list.Count - 1] + 2;
for (int i = startNum; i < Int32.MaxValue; i += 2)
{
if (IsPrime(i))
{
_list.Add(i);
yield return i;
}
}
}
public static string Convert(int n)
{
if (n == 0) return ".";
if (n == 1) return "()";
StringBuilder sb = new StringBuilder();
var p = Factor(n);
var max = PrimeOrd(p.Last());
for (int i = 0; i <= max; i++)
{
var power = p.FindAll(x => x == Nth(i)).Count;
sb.Append(Convert(power));
}
return "(" + sb.ToString() + ")";
}
}
class Program
{
static void Main(string[] args)
{
string line = Console.ReadLine();
int num;
if(int.TryParse(line, out num))
{
Console.WriteLine("{0}: '{1}'", num, P.Convert(num));
}
else
{
Console.WriteLine("You didn't entered number!");
}
}
}

Categories

Resources