My Code Always outputs a 0 I not know what is wrong - c#

I am trying to find the number of 3 digit numbers that has 2 numbers that are the factors of the third. So for example, 248 would be valid since 2 * 4 = 8 and 933 would also be valid since 3 * 3 = 9.
using System;
class Program
{
public static void Main (string[] args)
{
int Total = 0;
for (int i = 100; i < 1000; i++)
{
string I = Convert.ToString(i);
Console.WriteLine(I[2]+" "+I[1]+" "+I[0]+" "+I);
if (I[2] == I[1] * I[0] || I[1] == I[0] * I[2] || I[0] == I[2] * I[1])
{
Console.WriteLine("true");
Total++;
}
}
Console.WriteLine("the total is");
Console.WriteLine(Total);
}
}

When you access a string by index, you get a char and not an int. To get an int out of a char, you have to parse it back:
var a = int.Parse(I[0].ToString());
var b = int.Parse(I[1].ToString());
var c = int.Parse(I[2].ToString());
Then you can do your multiplication like a == b * c and so on

Related

How to perform addition of 2 very large (over 50 digits) binary string values in C#

I have been thinking of adding binary numbers where binary numbers are in a form of string and we add those two binary numbers to get a resultant binary number (in string).
So far I have been using this:
long first = Convert.ToInt64(a, 2);
long second = Convert.ToInt64(b, 2);
long addresult = first + second;
string result = Convert.ToString(addresult, 2);
return result;
Courtesy of Stackoverflow: Binary addition of 2 values represented as strings
But, now I want to add numbers which are far greater than the scope of a long data type.
For Example, a Binary value whose decimel result is a BigInteger, i.e., incredibly huge integers as shown below:
111101101000010111101000101010001010010010010110011010100001000010110110110000110001101 which equals to149014059082024308625334669
1111001101011000001011000111100011101011110100101010010001110101011101010100101000001101000010000110001110100010011101011111111110110101100101110001010101011110001010000010111110011011 which equals to23307765732196437339985049250988196614799400063289798555
At least I think it does.
Courtesy of Stackoverflow:
C# Convert large binary string to decimal system
BigInteger to Hex/Decimal/Octal/Binary strings?
I have used logic provided in above links which are more or less perfect.
But, is there a more compact way to add the given two binary strings?
Kindly let me know as this question is rattling in my mind for some time now.
You can exploit the same scheme you used before but with BigInteger:
using System.Linq;
using System.Numerics;
...
BigInteger first = a.Aggregate(BigInteger.Zero, (s, item) => s * 2 + item - '0');
BigInteger second = b.Aggregate(BigInteger.Zero, (s, item) => s * 2 + item - '0');
StringBuilder sb = new StringBuilder();
for (BigInteger addresult = first + second; addresult > 0; addresult /= 2)
sb.Append(addresult % 2);
if (sb.Length <= 0)
sb.Append('0');
string result = string.Concat(sb.ToString().Reverse());
This question was a nostalgic one - thanks. Note that my code is explanatory and inefficient with little to no validation, but it works for your example. You definitely do not want to use anything like this in a real world solution, this is just to illustrate binary addition in principle.
BinaryString#1
111101101000010111101000101010001010010010010110011010100001000010110110110000110001101
decimal:149014059082024308625334669
BinaryString#2
1111001101011000001011000111100011101011110100101010010001110101011101010100101000001101000010000110001110100010011101011111111110110101100101110001010101011110001010000010111110011011
decimal:23307765732196437339985049250988196614799400063289798555
Calculated Sum
1111001101011000001011000111100011101011110100101010010001110101011101010100101000001101000010001101111011100101011010100101010000000111111000100100101001100110100000111001000100101000
decimal:23307765732196437339985049251137210673881424371915133224
Check
23307765732196437339985049251137210673881424371915133224
decimal:23307765732196437339985049251137210673881424371915133224
Here's the code
using System;
using System.Linq;
using System.Numerics;
namespace ConsoleApp3
{
class Program
{
// return 0 for '0' and 1 for '1' (C# chars promotion to ints)
static int CharAsInt(char c) { return c - '0'; }
// and vice-versa
static char IntAsChar(int bit) { return (char)('0' + bit); }
static string BinaryStringAdd(string x, string y)
{
// get rid of spaces
x = x.Trim();
y = y.Trim();
// check if valid binaries
if (x.Any(c => c != '0' && c != '1') || y.Any(c => c != '0' && c != '1'))
throw new ArgumentException("binary representation may contain only '0' and '1'");
// align on right-most bit
if (x.Length < y.Length)
x = x.PadLeft(y.Length, '0');
else
y = y.PadLeft(x.Length, '0');
// NNB: the result may require one more bit than the longer of the two input strings (carry at the end), let's not forget this
var result = new char[x.Length];
// add from least significant to most significant (right to left)
var i = result.Length;
var carry = '0';
while (--i >= 0)
{
// to add x[i], y[i] and carry
// - if 2 or 3 bits are set then we carry '1' again (otherwise '0')
// - if the number of set bits is odd the sum bit is '1' otherwise '0'
var countSetBits = CharAsInt(x[i]) + CharAsInt(y[i]) + CharAsInt(carry);
carry = countSetBits > 1 ? '1' : '0';
result[i] = countSetBits == 1 || countSetBits == 3 ? '1' : '0';
}
// now to make this byte[] a string
var ret = new string(result);
// remember that final carry?
return carry == '1' ? carry + ret : ret;
}
static BigInteger BigIntegerFromBinaryString(string s)
{
var biRet = new BigInteger(0);
foreach (var t in s)
{
biRet = biRet << 1;
if (t == '1')
biRet += 1;
}
return biRet;
}
static void Main(string[] args)
{
var s1 = "111101101000010111101000101010001010010010010110011010100001000010110110110000110001101";
var s2 = "1111001101011000001011000111100011101011110100101010010001110101011101010100101000001101000010000110001110100010011101011111111110110101100101110001010101011110001010000010111110011011";
var sum = BinaryStringAdd(s1, s2);
var bi1 = BigIntegerFromBinaryString(s1);
var bi2 = BigIntegerFromBinaryString(s2);
var bi3 = bi1 + bi2;
Console.WriteLine($"BinaryString#1\n {s1}\n decimal:{bi1}");
Console.WriteLine($"BinaryString#2\n {s2}\n decimal:{bi2}");
Console.WriteLine($"Calculated Sum\n {sum}\n decimal:{BigIntegerFromBinaryString(sum)}");
Console.WriteLine($"Check\n {bi3}\n decimal:{bi3}");
Console.ReadKey();
}
}
}
I'll add an alternative solution alongside AlanK's just as an example of how you might go about this without converting the numbers to some form of integer before adding them.
static string BinaryStringAdd(string b1, string b2)
{
char[] c = new char[Math.Max(b1.Length, b2.Length) + 1];
int carry = 0;
for (int i = 1; i <= c.Length; i++)
{
int d1 = i <= b1.Length ? b1[^i] : 48;
int d2 = i <= b2.Length ? b2[^i] : 48;
int sum = carry + (d1-48) + (d2-48);
if (sum == 3)
{
sum = 1;
carry = 1;
}
else if (sum == 2)
{
sum = 0;
carry = 1;
}
else
{
carry = 0;
}
c[^i] = (char) (sum+48);
}
return c[0] == '0' ? String.Join("", c)[1..] : String.Join("", c);
}
Note that this solution is ~10% slower than Alan's solution (at least for this test case), and assumes the strings arrive to the method formatted correctly.

Trying to remove the last "and" at the end of my output list

For my C# programming homework, we had to write a program that allows the user to input an integer and use a loop to print out the factors of that integer.
I got the program to output the integers.
The problem is, for example, when I enter in the integer "24", I want the output to be
1 and 2 and 3 and 4 and 6 and 8 and 12 and 24
but the output that comes out is
1 and 2 and 3 and 4 and 6 and 8 and 12 and 24 and
I don't want the extra "and" at the end of my Factors List
Here is what my code looks like:
using System;
namespace ConsoleApp3
{
class Program
{
static void Main(string[] args)
{
int a, b;
Console.WriteLine("Please enter your integer: ");
a = int.Parse(Console.ReadLine());
for (b = 1; b <= a; b++)
{
if (a % b == 0)
{
Console.Write(b + " ");
}
}
Console.ReadLine();
}
}
}
EDIT: The output has to be formatted as
1 and 2 and 3 and 4 and 6 and 8 and 12 and 24
or else I won't get credit for the assignment
You can enumerate factors, and then Join them with " and "
private static IEnumerable<int> Factors(int value) {
// Simplest, not that efficient
for (int i = 1; i <= value; ++i)
if (value % i == 0)
yield return i;
}
...
Console.Write(string.Join(" and ", Factors(24)));
Or you can add " and " before, not after printing factors (i)
int value = 24;
bool firstTime = true;
// Simplest, not that efficient
for (int i = 1; i <= value; ++i) {
if (value % i == 0) {
// print "and" before printing i
if (!firstTime)
Console.Write(" and ");
firstTime = false;
Console.Write(i);
}
}
How about adding the numbers to a List and printing after the loop:
int a, b;
a = int.Parse(Console.ReadLine());
var result = new List<int>();
for (b = 1; b <= a; b++)
{
if (a % b == 0)
{
result.Add(b);
}
}
Console.Write(string.Join(" and ", result));
static void Main(string[] args)
{
//get input from user
Console.WriteLine("Please enter your integer: ");
int a = int.Parse(Console.ReadLine());
//enumerate factors
var factors = Enumerable.Range(1, a)
.Where(i => a % i == 0).ToArray();
//join for nicely printed output
Console.Write(string.Join(" and ", factors));
Console.ReadLine();
}
I would recommend you to create a string and output that string becouse it allows you to do more things with it, then do something like this:
int a, b;
string x="";
Console.WriteLine("Please enter your integer: ");
a = int.Parse(Console.ReadLine());
for (b = 1; b <= a; b++)
{
if (a % b == 0)
{
x=x + b.toString() +" and";
}
}
if you know that always will be an "and" at the end you can simply do this
string x = x.Substring(0, x.Length - 3);
and then
Console.Write(x);
Console.ReadLine();

How to separate not separated input C#

The program must sum the even and odd numbers and then multiply them.
The problem comes when I enter the numbers like this 12345.
The array takes the number like 1 element but in order to make my code work it must separate the input when I put it like this 12345.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Lab_Methods
{
class Program
{
static void Main(string[] args)
{
int[] number = Console.ReadLine().Split(' ').Select(int.Parse).ToArray();
int even = 0;
int odd = 0;
for (int i = 0; i < number.Length; i++)
{
if (number[i] % 2 == 0)
{
even = even + number[i];
}
else
{
odd = odd + number[i];
}
}
Console.WriteLine(even * odd);
}
}
}
If you want to split on ' ' (space), your input should use delimiter: "1 2 3 4 5"
// Separated input like "1 2 3 45 6 789"
// we don't have to materialize into array
// let's be nice: allow tabulation as well as space,
// tolerate leading/trailing and double spaces: " 1 2 3 "
var numbers = Console
.ReadLine()
.Split(new char[] { ' ', '\t'}, StringSplitOptions.RemoveEmptyEntries) // let's be nice
.Select(item => int.Parse(item));
int even = 0;
int odd = 0;
foreach (var number in numbers) {
if (number % 2 != 0)
odd += number;
else
even += number;
}
Console.WriteLine(even * odd);
If you want to enumerate digits within single number (e.g. within "12345")
// Single number input like "12345678"
var numbers = Console
.ReadLine()
.Where(c => c >= '0' && c <= '9') // characters in '0'..'9' range
.Select(c => c - '0'); // corresponding ints
// Then as usual
int even = 0;
int odd = 0;
foreach (var number in numbers) {
if (number % 2 != 0)
odd += number;
else
even += number;
}
Console.WriteLine(even * odd);
This way you will be able to input numbers from 0 to 9 without having to care about the way they are written:
class Program
{
static void Main(string[] args)
{
int[] numbers = Console.ReadLine().Select(x => {
if(int.TryParse(x.ToString(), out int result))
{
return result;
}
else
{
return -1;
}
}).Where(x => x != -1).ToArray();
int even = 0;
int odd = 0;
for (int i = 0; i < numbers.Length; i++)
{
if (numbers[i] % 2 == 0)
{
even = even + numbers[i];
}
else
{
odd = odd + numbers[i];
}
}
Console.WriteLine(even * odd);
}
}
Input:
12345
Output:
54
Input:
1 2 3 4 5
Output:
54
Input:
1,2,3,4,5
Output:
54
Input:
,1.2 34|5
Output:
54

Trying to find the 10001st prime number, c#

I am trying to "Find the 10001st prime number" as part of the Project Euler challenges and i have no idea why my code doesn't work. When I tested my isPrime() function, it succeeded in finding whether a number was prime, but my program returns 10200 as the 10001st prime. Why is this?
Here is My Code:
using System;
using System.Collections.Generic;
namespace Challenge_7
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Solution to Project Euler");
Console.WriteLine("Challenge 7 - Find the 10001st prime");
Console.WriteLine("\nProject Start:");
List<int> primes = new List<int>();
int number = 1;
while (primes.Count != 10001)
{
if (isPrime(number))
{
primes.Add(number);
Console.WriteLine(number);
}
number++;
}
Console.WriteLine("The 10001st prime is: {0}", primes[10000]);
Console.ReadLine();
}
private static bool isPrime(int n)
{
bool prime = true;
for (int i = 1; i <= Math.Ceiling(Math.Sqrt(n)); i++)
{
for (int j = 1; j <= Math.Ceiling(Math.Sqrt(n)); j++)
{
if (i * j == n)
{
prime = false;
}
}
}
return prime;
}
}
}
Here's a hint::
Imagine a number that is the product of 3 primes.
Lets say 3, 5, and 7 (or) 105;
sqrt(105) == 10.2 so ceiling is 11
There aren't two numbers less than 11 that multiply to 105.
So your algorithm would falsely return true!
Try Again! :-D
The problem is in you loops. Math.Ceiling(Math.Sqrt(10200)) is 101 and you need to check 102 * 100 = 10200 but your loops never reaches 102 and returns 10200 as prime!
You can use the code below for isPrime. It is exists in this link and I changed to C# for you:
private static bool isPrime(int n)
{
if (n <= 1)
return false;
else if (n <= 3)
return true;
else if (n % 2 == 0 || n % 3 == 0)
return false;
int i = 5;
while (i * i <= n)
{
if (n % i == 0 || n % (i + 2) == 0)
return false;
i += 6;
}
return true;
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace nthPrimeNumber
{
class Program
{
static void Main(string[] args)
{
ulong starting_number = 1;
ulong last_number = 200000; //only this value needs adjustment
ulong nth_primenumber = 0;
ulong a;
ulong b;
ulong c;
for (a = starting_number; a <= last_number; a++)
{
b = Convert.ToUInt64(Math.Ceiling(Math.Sqrt(a)));
for (c = 2; c <= b; c++)
{
if (a == 1 || (a % c == 0 && c != b))
{
break;
}
else
{
if (c == b)
{
nth_primenumber = nth_primenumber + 1;
break;
}
}
}
if (nth_primenumber == 10001)
{
break;
}
}
Console.WriteLine(nth_primenumber + "st" + "prime number is " + a);
Console.ReadKey();
}
}
}
The program above generates prime numbers between 1 and 200000. The program counts the generated prime numbers and checks if the generated prime numbers are already 10001. The program prints the 10001st prime number. If the program doesn't show 10001st (or shows below 10001) in the console, it is because the value of the last_number is small -- then try to adjust the value of the last_number (make it bigger). In this program, I have already adjusted the value of the last_number and will print the 10001st prime number.

An algorithm for a number divisible to n

At first user gives a number (n) to program, for example 5.
the program must find the smallest number that can be divided to n (5).
and this number can only consist of digits 0 and 9 not any other digits.
for example if user gives 5 to program.
numbers that can be divided to 5 are:
5, 10, 15, 20, 25, 30, ..., 85, 90, 95, ...
but 90 here is the smallest number that can be divided to 5 and also consist of digits (0 , 9). so answer for 5 must be 90.
and answer for 9 is 9, because it can be divided to 9 and consist of digit (9).
my code
string a = txtNumber.Text;
Int64 x = Convert.ToInt64(a);
Int64 i ,j=1,y=x;
bool t = false;
for (i = x + 1; t == false; i++)
{
if (i % 9 == 0 && i % 10 == 0 && i % x == 0)
{
j = i;
for (; (i /= 10) != 0; )
{
i /= 10;
if (i == 0)
t = true;
continue;
}
}
}
lblAnswer.Text = Convert.ToString(j);
If you're happy to go purely functional then this works:
Func<IEnumerable<long>> generate = () =>
{
Func<long, IEnumerable<long>> extend =
x => new [] { x * 10, x * 10 + 9 };
Func<IEnumerable<long>, IEnumerable<long>> generate2 = null;
generate2 = ns =>
{
var clean = ns.Where(n => n > 0).ToArray();
return clean.Any()
? clean.Concat(generate2(clean.SelectMany(extend)))
: Enumerable.Empty<long>();
};
return generate2(new[] { 9L, });
};
Func<long, long?> f = n =>
generate()
.Where(x => x % n == 0L)
.Cast<long?>()
.FirstOrDefault();
So rather than iterate through all possible values and test for 0 & 9 and divisibility, this just generates only numbers with 0 & 9 and then only tests for visibility. It is much faster this way.
I can call it like this:
var result = f(5L); // 90L
result = f(23L); //990909L
result = f(123L); //99999L
result = f(12321L); //90900999009L
result = f(123212L); //99909990090000900L
result = f(117238L); //990990990099990990L
result = f(1172438L); //null == No answer
These results are super fast. f(117238L) returns a result on my computer in 138ms.
You can try this way :
string a = txtNumber.Text;
Int64 x = Convert.ToInt64(a);
int counter;
for (counter = 1; !isValid(x * counter); counter++)
{
}
lblAnswer.Text = Convert.ToString(counter*x);
code above works by searching multiple of x incrementally until result that satisfy criteria : "consist of only 0 and or 9 digits" found. By searching only multiple of x, it is guaranteed to be divisible by x. So the rest is checking validity of result candidate, in this case using following isValid() function :
private static bool isValid(int number)
{
var lastDigit = number%10;
//last digit is invalid, return false
if (lastDigit != 0 & lastDigit != 9) return false;
//last digit is valid, but there is other digit(s)
if(number/10 >= 1)
{
//check validity of digit(s) before the last
return isValid(number/10);
}
//last digit is valid, and there is no other digit. return true
return true;
}
About strange empty for loop in snippet above, it is just syntactic sugar, to make the code a bit shorter. It is equal to following while loop :
counter = 1;
while(!isValid(input*counter))
{
counter++;
}
Use this simple code
int inputNumber = 5/*Or every other number, you can get this number from input.*/;
int result=1;
for (int i = 1; !IsOk(result,inputNumber); i++)
{
result = i*inputNumber;
}
Print(result);
IsOk method is here:
bool IsOk(int result, int inputNumber)
{
if(result%inputNumber!=0)
return false;
if(result.ToString().Replace("9",string.Empty).Replace("0",string.Empty).Length!=0)
return false;
return true;
}
My first solution has very bad performance, because of converting a number to string and looking for characters '9' and '0'.
New solution:
My new solution has very good performance and is a technical approach since of using Breadth-first search(BFS).
Algorithm of this solution:
For every input number, test 9, if it is answer print it, else add 2 child numbers (90 & 99) to queue, and continue till finding answer.
int inputNumber = 5;/*Or every other number, you can get this number from input.*/
long result;
var q = new Queue<long>();
q.Enqueue(9);
while (true)
{
result = q.Dequeue();
if (result%inputNumber == 0)
{
Print(result);
break;
}
q.Enqueue(result*10);
q.Enqueue(result*10 + 9);
}
Trace of number creation:
9
90,99
900,909,990,999
9000,9009,9090,9099,9900,9909,9990,9999
.
.
.
I wrote this code for console, and i used goto command however it is not prefered but i could not write it with only for.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace main
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Enter your number");
Int64 x = Convert.ToInt64(Console.ReadLine());
Int64 y, j, i, k, z = x;
x = x + 5;
loop:
x++;
for (i = 0, y = x; y != 0; i++)
y /= 10;
for (j = x, k = i; k != 0; j /= 10, k--)
{
if (j % 10 != 9)
if (j % 10 != 0)
goto loop;
}
if (x % z != 0)
goto loop;
Console.WriteLine("answer:{0}",x);
Console.ReadKey();
}
}
}

Categories

Resources