c#: Project Euler 8. Have some troubles in program - c#

I'm writing a program to solve problem 8 in project Euler, which finds the thirteen adjacent digits in the 1000-digit number that have the greatest product. Firstly, i determine that the 1000-digit number is a string. Then i create a split method that breaks up this string into smaller chars, and converts it to int number. (i use ulong type instead of int)
static ulong split(char input)
{
ulong number = ulong.Parse(Convert.ToString(input));
return number;
}
then i create a method that has ability to check whether what is the biggest product. convert it into int type, find the product of thirteen adjacent digits.
static ulong check(string string1)
{
ulong product = 1;
ulong max = 0;
ulong[] array = new ulong[50];
char[] h1 = string1.ToCharArray();
for (int i = 0; i < string1.Length; i++)
array[i] = split(h1[i]);
for (int i = 0; i < array.Length - 12; i++)
{
for (int j = 0; j < 13; j++)
{
product *= array[i + j]
if (product > max)
max = product;
}
product = 1;
}
return max;
In the main method. i write some code to input the 1000-digit number and write the answer.
string input = #"73167176531330624919225119674426574742355349194934
96983520312774506326239578318016984801869478851843
85861560789112949495459501737958331952853208805511
12540698747158523863050715693290963295227443043557
66896648950445244523161731856403098711121722383113
62229893423380308135336276614282806444486645238749
30358907296290491560440772390713810515859307960866
70172427121883998797908792274921901699720888093776
65727333001053367881220235421809751254540594752243
52584907711670556013604839586446706324415722155397
53697817977846174064955149290862569321978468622482
83972241375657056057490261407972968652414535100474
82166370484403199890008895243450658541227588666881
16427171479924442928230863465674813919123162824586
17866458359124566529476545682848912883142607690042
24219022671055626321111109370544217506941658960408
07198403850962455444362981230987879927244284909188
84580156166097919133875499200524063689912560717606
05886116467109405077541002256983155200055935729725
71636269561882670428252483600823257530420752963450";
input = input.Replace(" ", "");
input = input.Replace("/r/n", "");
Console.Write(check(input));
Console.ReadKey();
But the program has trouble in the split method. can you explain for me, please ? :(
here is all my program.
string input = #"73167176531330624919225119674426574742355349194934
96983520312774506326239578318016984801869478851843
85861560789112949495459501737958331952853208805511
12540698747158523863050715693290963295227443043557
66896648950445244523161731856403098711121722383113
62229893423380308135336276614282806444486645238749
30358907296290491560440772390713810515859307960866
70172427121883998797908792274921901699720888093776
65727333001053367881220235421809751254540594752243
52584907711670556013604839586446706324415722155397
53697817977846174064955149290862569321978468622482
83972241375657056057490261407972968652414535100474
82166370484403199890008895243450658541227588666881
16427171479924442928230863465674813919123162824586
17866458359124566529476545682848912883142607690042
24219022671055626321111109370544217506941658960408
07198403850962455444362981230987879927244284909188
84580156166097919133875499200524063689912560717606
05886116467109405077541002256983155200055935729725
71636269561882670428252483600823257530420752963450";
input = input.Replace(" ", "");
input = input.Replace("/r/n", "");
Console.Write(check(input));
Console.ReadKey();
}
static ulong split(char input)
{
ulong number = ulong.Parse(Convert.ToString(input));
return number;
}
static ulong check(string string1)
{
ulong product = 1;
ulong max = 0;
ulong[] array = new ulong[50];
char[] h1 = string1.ToCharArray();
for (int i = 0; i < string1.Length; i++)
array[i] = split(h1[i]);
Console.WriteLine();
for (int i = 0; i < array.Length - 12; i++)
{
for (int j = 0; j < 13; j++)
{
product *= array[i + j];
if (product > max)
{
max = product;
Console.Write(array[i + j] + " ");
}
}
product = 1;
}
return max;
}

Related

Calculation power of number in themselves with loops

I'm new to C# and I'm trying to calculate power of (1,3) to themselves with loops but this code just calculate their squares I appreciate if someone helps me.
for (int i = 1; i <= 3; i++)
{
tav =i*i;
Console.Write(tav);
}
for (int i = 1; i <= 3; i++)
{
int num = i;
int result = num;
for (int k = 2; k <= num; k++) { result *= num; }
Console.WriteLine("{0}^{0} = {1}", num, result);
}

how to generate auto ID in C#? A0000 to Z9999 and start over with A0000

private static string ancient;
public static string MtrclGENERERTOR()
{
char[] t = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".ToCharArray();
int i;
for (int j = 0; j < t.Length ; j++)
{
for (i = 0; i < 10000; i++)
{
sancient = t[j] + i.ToString().PadLeft(4, '0');
}
if(i == 9999)
{
j += 1;
}
}
if (sancient == "Z9999")
{
sancient = "A0000";
MtrclGENERERTOR();
}
return ancient;
}
*and it shows me one result which is Z9999, *
it works perfectly without being inside a method, but when I tried to complete my class with the method but it give all the object one value which is "Z9999"
Maybe it's easier to count from 10000 to 269999 and use the first digits (divide by 10000) as the index to get the letter
for(int x = 10000; x <= 26999; x++)
Console.WriteLine(t[x/10000] + (x%10000).ToString("0000"));

Find the largest palindrome made from the product of two 3-digit numbers C#

I tried to solve projecteuler 4th project with C# but I don't receive the correct answer, I get 90909. Can someone spot my mistake?
The problem goes like this:
A palindromic number reads the same both ways. The largest palindrome made from the product of two 2-digit numbers is 9009 = 91 × 99.
Find the largest palindrome made from the product of two 3-digit numbers.
namespace Largest_palindrome_product{
class Program
{
static void Main(string[] args)
{
string Reverse(string s)
{
char[] charArray = s.ToCharArray();
Array.Reverse(charArray);
return new string(charArray);
}
int result = 0;
string rev= "hello";
string palindrome = "hello";
string bingo = "hello";
int j = 1;
for (int i = 1; i< 1000; i++)
{
for (int y = 1; y< 1000; y++)
{
result = i * y;
bingo = result.ToString();
rev = Reverse(bingo);
j = int.Parse(bingo);
}
if (rev == bingo)
{
palindrome = bingo;
}
}
Console.Write(palindrome);
Console.Read();
}
}
}
I think what has caused so much confusion is the use of String this just complicates thing having to convert them back and forth.
Your program works fine (if the if is moved as per John's comment) if only you'd checked the new number was larger!
here is my take on it:
// stolen from https://www.geeksforgeeks.org/reverse-digits-integer-overflow-handled/
int Reverse(int num)
{
int rev_num = 0;
while (num > 0)
{
rev_num = rev_num * 10 + num % 10;
num = num / 10;
}
return rev_num;
}
int result = 0;
int palindrome = 0;
int j = 1;
for (int i = 999; i > 0; i--)
{
for (int y = 999; y > 0; y--)
{
result = i * y;
if (result == Reverse(result))
{
if (result > palindrome)
{
palindrome = result;
}
}
}
}
Console.Write(palindrome);
Console.Read();

C# : Find the largest palindromic number made from product of 3-digit numbers

I'm writing a program to find the largest palindromic number made from product of 3-digit numbers. Firstly,i Create a method which has ability to check if it is a palindromic number. Here is my code :
static int check(string input_number)
{
for (int i = 0; i < input_number.Length/2; i++)
if (input_number[i] != input_number[input_number.Length - i])
return 0;
return 1;
}
After that, it's my main code:
static void Main(string[] args)
{
int k = 0;
for (int i = 0; i < 999; i++)
for (int j = 0; j < 999; j++)
{
k = i * j;
if (check(k.ToString()) == 1)
Console.Write(k + " ");
}
}
But when it has a problem that the length of input_number is zero. So my code doesn't run right way. What can I do to solve the length of input_number?
You have a few bugs in your code:
1. 3-digit-numbers range from `100` to `999`, not from `0` to `998` as your loops currently do.
So your Main method should look like this:
static void Main(string[] args)
{
int k = 0;
for (int i = 100; i <= 999; i++)
for (int j = 100; j <= 999; j++)
{
k = i * j;
if (check(k.ToString()) == 1)
Console.Write(k + " ");
}
}
Now all pairs of three digit numbers are checked. But to improve performance you can let j start at i, because you already checked e.g. 213 * 416 and don't need to check 416 * 213 anymore:
for (int i = 100; i <= 999; i++)
for (int j = i; j <= 999; j++) // start at i
And since you want to find the largest, you may want to start at the other end:
for (int i = 999; i >= 100; i--)
for (int j = 999; j >= 100; j--)
But that still does not guarantee that the first result will be the largest. You need to collect the result and sort them. Here is my LINQ suggestion for your Main:
var results = from i in Enumerable.Range(100, 900)
from j in Enumerable.Range(i, 1000-i)
let k = i * j
where (check(k.ToString() == 1)
orderby k descending
select new {i, j, k};
var highestResult = results.FirstOrDefault();
if (highestResult == null)
Console.WriteLine("There are no palindromes!");
else
Console.WriteLine($"The highest palindrome is {highestResult.i} * {highestResult.j} = {highestResult.k}");
2. Your palindrome-check is broken
You compare the character at index i to input_number[input_number.Length - i], which will throw an IndexOutOfRangeException for i = 0. Strings are zero-based index, so index of the last character is Length-1. So change the line to
if (input_number[i] != input_number[input_number.Length - i - 1])
Finally, I suggest to make the check method of return type bool instead of int:
static bool check(string input_number)
{
for (int i = 0; i < input_number.Length/2; i++)
if (input_number[i] != input_number[input_number.Length - i - 1])
return false;
return true;
}
This seems more natural to me.
You can use method below. Because you are trying to find the largest number you start from 999 and head backwards, do multiplication and check if its palindrome.
private void FindProduct()
{
var numbers = new List<int>();
for (int i = 999; i > 99; i--)
{
for (int j = 999; j > 99; j--)
{
var product = i * j;
var productString = product.ToString();
var reversed = product.Reverse();
if (product == reversed)
{
numbers.Add(product);
}
}
}
Console.WriteLine(numbers.Max());
}

Reorder digits in integer using C#

I want to ask how I can reorder the digits in an Int32 so they result in the biggest possible number.
Here is an example which visualizes what I am trying to do:
2927466 -> 9766422
12492771 -> 97742211
I want to perform the ordering of the digits without using the System.Linq namespace and without converting the integer into a string value.
This is what I got so far:
public static int ReorderInt32Digits(int v)
{
int n = Math.Abs(v);
int l = ((int)Math.Log10(n > 0 ? n : 1)) + 1;
int[] d = new int[l];
for (int i = 0; i < l; i++)
{
d[(l - i) - 1] = n % 10;
n /= 10;
}
if (v < 0)
d[0] *= -1;
Array.Sort(d);
Array.Reverse(d);
int h = 0;
for (int i = 0; i < d.Length; i++)
{
int index = d.Length - i - 1;
h += ((int)Math.Pow(10, index)) * d[i];
}
return h;
}
This algorithm works flawlessly but I think it is not very efficient.
I would like to know if there is a way to do the same thing more efficiently and how I could improve my algorithm.
You can use this code:
var digit = 2927466;
String.Join("", digit.ToString().ToCharArray().OrderBy(x => x));
Or
var res = String.Join("", digit.ToString().ToCharArray().OrderByDescending(x => x) );
Not that my answer may or may not be more "efficient", but when I read your code you calculated how many digits there are in your number so you can determine how large to make your array, and then you calculated how to turn your array back into a sorted integer.
It would seem to me that you would want to write your own code that did the sorting part without using built in functionality, which is what my sample does. Plus, I've added the ability to sort in ascending or descending order, which is easy to add in your code too.
UPDATED
The original algorithm sorted the digits, now it sorts the digits so that the end result is the largest or smallest depending on the second parameter passed in. However, when dealing with a negative number the second parameter is treated as opposite.
using System;
public class Program
{
public static void Main()
{
int number1 = 2927466;
int number2 = 12492771;
int number3 = -39284925;
Console.WriteLine(OrderDigits(number1, false));
Console.WriteLine(OrderDigits(number2, true));
Console.WriteLine(OrderDigits(number3, false));
}
private static int OrderDigits(int number, bool asc)
{
// Extract each digit into an array
int[] digits = new int[(int)Math.Floor(Math.Log10(Math.Abs(number)) + 1)];
for (int i = 0; i < digits.Length; i++)
{
digits[i] = number % 10;
number /= 10;
}
// Order the digits
for (int i = 0; i < digits.Length; i++)
{
for (int j = i + 1; j < digits.Length; j++)
{
if ((!asc && digits[j] > digits[i]) ||
(asc && digits[j] < digits[i]))
{
int temp = digits[i];
digits[i] = digits[j];
digits[j] = temp;
}
}
}
// Turn the array of digits back into an integer
int result = 0;
for (int i = digits.Length - 1; i >= 0; i--)
{
result += digits[i] * (int)Math.Pow(10, digits.Length - 1 - i);
}
return result;
}
}
Results:
9766422
11224779
-22345899
See working example here... https://dotnetfiddle.net/RWA4XV
public static int ReorderInt32Digits(int v)
{
var nums = Math.Abs(v).ToString().ToCharArray();
Array.Sort(nums);
bool neg = (v < 0);
if(!neg)
{
Array.Reverse(nums);
}
return int.Parse(new string(nums)) * (neg ? -1 : 1);
}
This code fragment below extracts the digits from variable v. You can modify it to store the digits in an array and sort/reverse.
int v = 2345;
while (v > 0) {
int digit = v % 10;
v = v / 10;
Console.WriteLine(digit);
}
You can use similar logic to reconstruct the number from (sorted) digits: Multiply by 10 and add next digit.
I'm posting this second answer because I think I got the most efficient algorithm of all (thanks for the help Atul) :)
void Main()
{
Console.WriteLine (ReorderInt32Digits2(2927466));
Console.WriteLine (ReorderInt32Digits2(12492771));
Console.WriteLine (ReorderInt32Digits2(-1024));
}
public static int ReorderInt32Digits2(int v)
{
bool neg = (v < 0);
int mult = neg ? -1 : 1;
int result = 0;
var counts = GetDigitCounts(v);
for (int i = 0; i < 10; i++)
{
int idx = neg ? 9 - i : i;
for (int j = 0; j < counts[idx]; j++)
{
result += idx * mult;
mult *= 10;
}
}
return result;
}
// From Atul Sikaria's answer
public static int[] GetDigitCounts(int n)
{
int v = Math.Abs(n);
var result = new int[10];
while (v > 0) {
int digit = v % 10;
v = v / 10;
result[digit]++;
}
return result;
}

Categories