Project euler 8: weird issue - c#

I've tried solving Project Euler Problem 8
I believe I have the right approach, but for some reason I get the exception ("An unhandled exception of type 'System.ArgumentOutOfRangeException' occurred in mscorlib.dll") in below code when i=494.
Line is 38 I believe.
PS. The length of the string is 1000 as shown by debugger too.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace euler8
{
class Program
{
static void Main(string[] args)
{
const String candidate = "73167176531330624919225119674426574742355349194934"+
"96983520312774506326239578318016984801869478851843"+
"85861560789112949495459501737958331952853208805511"+
"12540698747158523863050715693290963295227443043557"+
"66896648950445244523161731856403098711121722383113"+
"62229893423380308135336276614282806444486645238749"+
"30358907296290491560440772390713810515859307960866"+
"70172427121883998797908792274921901699720888093776"+
"65727333001053367881220235421809751254540594752243"+
"52584907711670556013604839586446706324415722155397"+
"53697817977846174064955149290862569321978468622482"+
"83972241375657056057490261407972968652414535100474"+
"82166370484403199890008895243450658541227588666881"+
"16427171479924442928230863465674813919123162824586"+
"17866458359124566529476545682848912883142607690042"+
"24219022671055626321111109370544217506941658960408"+
"07198403850962455444362981230987879927244284909188"+
"84580156166097919133875499200524063689912560717606"+
"05886116467109405077541002256983155200055935729725"+
"71636269561882670428252483600823257530420752963450";
long max = 0;
int length = candidate.Length;
for (int i = 0; i < length - 13; i++)
{
string substring = candidate.Substring(i, i + 13);
int [] x = new int [13];
for(int j = 0; j<13; j++)
x[j]= int.Parse(substring[j].ToString());
long product = 1;
for (int k = 0; k < 13; k++)
product = product * x[k];
if (product > max)
max = product;
}
Console.WriteLine(max.ToString());
}
}
}
Does anyone spot the issue?

It looks like this is stemming from a misunderstanding of how .SubString() works.
string substring = candidate.Substring(i, i + 13);
Most likely should be:
string substring = candidate.Substring(i, 13);
.SubString() is : .SubString(startPosition, length) So adding i + 13 doesn't net you the next 13 characters, but instead the next i + 13 characters from start position i.

String.Substring needs a starting position plus a length, not and end position.
So just use
string substring = candidate.Substring(i, 13);

Related

How to better cast a char to int keeping the number value and not the ASCII value? [duplicate]

This question already has answers here:
Convert char to int in C#
(20 answers)
Closed 3 years ago.
I have just wrote a code(c#) for my sample exam in C# basics study.
Еven though I was able to write it correctly and receive all points, I am not quite satisfied with the way I have used to cast the char ASCII value to the desired int value.
I am asking for a better way to express the following code:
using System;
namespace MultiplyTable
{
class Program
{
static void Main(string[] args)
{
//Input:
string inputNumber = Console.ReadLine();
//Logic:
int firstNumber = 0;
int secondNumber = 0;
int thirdNumber = 0;
for (int i = 0; i < inputNumber.Length; i++)
{
firstNumber = inputNumber[0] - 48;
secondNumber = inputNumber[1] - 48;
thirdNumber = inputNumber[2] - 48;
}
for (int p = 1; p <= thirdNumber; p++)
{
for (int j = 1; j <= secondNumber; j++)
{
for (int k = 1; k <= firstNumber; k++)
{
Console.WriteLine($"{p} * {j} * {k} = {p * j * k};");
}
}
}
}
}
}
The input is an integer three-digit number in the range [111… 999].
I have used string instead of int, to quicker read and store all char values.
The issue here is that when I have the char let's say '3' I need to use the int value of '3' and not the ASCII Dec value of 51.
As I had a limited time to write this code I succeeded to resolve it by subtracting 48 as you can see in the code provided.
What is the correct/more advanced way to do this exercise ?
Thank you in advance!
Substracting foo's ASCII value from 0's ASCII value will give you number.
char foo = '2';
int bar = foo - '0';
Or you can just simply convert char to string and then convert to int:
int bar = int.Parse(foo.ToString());

Range of a string program [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
This is a program to get all the letters in a string in a specified range (in this case characters 3 through 7 of the word 'kangaroo').
Why am i getting an error at line arr[i] = x[start+i];?
I am not using Substring because my instructor wants us to figure out how to do it without it as an exercise.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MethodsPractice2
{
class Program
{
static char[] GetRangeOfCharacters(string word, int start, int end)
{
string x = word;
char[] arr = new char[end - start];
for (int i = 0; i < end; i++)
{
arr[i] = x[start + i];
}
return arr;
}
private static void Main(string[] args)
{
char[] endResult;
string word = "kangaroo";
int start = 3;
int end = 7;
endResult = GetRangeOfCharacters(word, start, end);
Console.WriteLine(endResult);
}
}
}
I'll explain the error you are getting,
You have said that you wish to start at character 3, and fill arr which is has 4 entries, with the characters that start at (3) + i
i can be any number less than 7.. 3 + 6 = 9; and Kangaroo has 8 letters in it... therefore you for loop at the minimum needs to go to
i < (end - start)
The other error could could get is i >= 4 in which case it would be trying to access arr[4] which is also out of range
0123456789
kangaroo
garo## /// what arr would be - # = error
garoo# // where i would get you - # = error
If you're looking for the easiest way to print part of the string, the easiest way, as mentioned in the comments, is with the String.Substring method.. To get characters #3-7 of the word kangaroo, you could use:
String.Substring(2,5);
The 2 is the starting index (it's 0-based, so 2 is the third character), and 5 is the length.
If you need the array of characters (as your return type indicates), you could try using the String.ToCharArray method, which functions the same way:
x.ToCharArray(2,5)
Because you take too many characters in the loop:
static char[] GetRangeOfCharacters(string word, int start, int end)
{
string x = word;
char[] arr = new char[end - start];
for (int i = 0; i < end; i++) // <--- here!!!
{
arr[i] = x[start + i];
}
return arr;
}
Correct would be
for (int i = 0; i < end - start; i++)
I would use this instead (skipped invalid argument check):
static char[] GetRangeOfCharacters(string word, int start, int end)
{
return word.Skip(start).Take(end - start).ToArray();
// or more efficient: word.Substring(start, end - start).ToCharArray();
}
end is 7 so you are looping from 0 to 7 and so going at subscripts 3 to 10
so
for (int i = 0; i < end; i++)
should be
for (int i = 0; i < (end - start); i++)
or perhaps even clearer
for (int i = 0; i < arr.Length; i++)
You're overflowing your array, arr[] by 1. Quanity (end-start) gives you one less than the size of your range.
You need to use quantity (end-start+1) to size your target array.
arr is an array with 4 slots (7 - 3).
But the code:
for (int i = 0; i < end; i++)
will loop 7 times (because end == 7), trying to write to a new position of arr on every iteration.
Q: How can you store 7 distinct values to an array with only 4 slots?
A: You can't!
(Your for-loop needs different constraints).
Well end is 7, start is 3. 3 + 6 is 9. Kangaroo is only of length 8 so you're gonna get an index out of range exception (looping while i < end, and adding i to start to get the index). As others have suggested you should use substring instead of your current method.
string subString;
if (end - start < 0)
subString = null; // error!
else
subString = myWord.SubString(start, end - start);
Might also want to check that start and end are both less than myWord.Length

Printing a sorted array

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace SkihopperOpgave
{
class Program
{
static void Main(string[] args)
{
string deltagerNavn = " ";
int hopLængde = 0;
string[] deltager = new string[5];
int[] hopLængder = new int[5];
string[] pladsNumre = new string[5] { "1. ", "2. ", "3. ", "4. ", "5. " };
for (int i = 0; i < deltager.Length; i++)
{
Console.Write("Indtast deltagernavn: ");
deltager[i] = Console.ReadLine();
Console.Write("Indtast hoplængde for deltager: ");
hopLængder[i] = Convert.ToInt32(Console.ReadLine());
for (int j = hopLængder.Length-1; j>0; j--) //Bubblesort
{
for (int k = 0; k < j; k++)
{
int b = hopLængder[k];
hopLængder[k] = hopLængder[k+1];
hopLængder[k+1] = b;
}
}
for (int s = 0; s < deltager.Length; s++)
{
Console.WriteLine(pladsNumre[s] + hopLængder[s] + deltager[s]);
}
}
}
}
}
I am trying to create a program that prints out a sorted list of Ski jumpers (deltagere), by sorting their jump distance (hoplængde). What happens is that the user first types in the name of the ski jumper, then the jump distance. The program should then print out a sorted list in this format: 1. 80 John (Newline) 2. 45 Mark... etc.
Each time a user types in a ski jumper, the list should be printed, with all the distances sorted in a descending order.
I've created an array for both names of the ski jumpers and their distances, but I am having trouble as to how I connect the first element in the int array with the first element in the string array and how to correctly sort this in each iteration.
I tried creating a bubblesort for the job, but I get wrong results.
Take a look at overloads of static method Array.Sort() - it can do what you want.
Also you should read about SortedList<> class - it is probably even better option for your task and use comments already posted (by Fischerman) to declare an entity class.
I think that's enough hints for a homework =)

using a char value to compare to a variable name in c#?

I am trying to solve one of the Euler Project problems using c# (problem 22). Though I have run into a problem. It's probably worth noting I am relatively new to programming, especially c#.
I need to come up with a word score for a set of strings that I have. This involves summing up the score of each letter in a a word, e.g. a=1, b=2, c=3 and so on. To do this I have assigned all 26 letters of the alphabet as variables with the relevant scores. I then want to compare each letter in the word with the relevant variables of the same name. However what I am left with is a char data type, what's the best way for me to compare the character to the relevant variable, and then use the variable value in my integer calculation. I have included the code I have so far below, with the problem occuring in the last 2 lines excluding braces. (I have had a quick look, and it appears this is not supported in c++, though i'm not sure about c#). Any help would be greatly appreciated.
string[] lines = File.ReadAllLines(#"C:\Users\john\Downloads\names.txt");
//Console.WriteLine(lines[1]);
char[] delimiterChars = { ',', '\t' };
string text = lines[0];
string[] names = text.Split(delimiterChars);
Console.WriteLine("{0} words in text:", names.Length);
Array.Sort(names);
int a = 1;
int b = 2;
int c = 3;
int d = 4;
int e = 5;
int f = 6;
int g = 7;
int h = 8;
int i = 9;
int j = 10;
int k = 11;
int l = 12;
int m = 13;
int n = 14;
int o = 15;
int p = 16;
int q = 17;
int r = 18;
int s = 19;
int t = 20;
int u = 21;
int v = 22;
int w = 23;
int x = 24;
int y = 25;
int z = 26;
int[] nameTotal;
for (int count = 0; count < names.Length; count++)
{
string name = names[count];
int total = 0;
for (int count2 = 0; count2 < name.Length; count2++)
{
nameTotal[count] = name.Substring(count2) + total;
total = total + nameTotal[count];
}
}
You can do this by taking advantage of the layout of the standard ASCII table.
In ASCII, the 'a' character has a decimal value of 97. Lower-case letters then continue up until 122.
Therefore, you can easily convert an 'a' char value to your required value by using:
char charToConvert = 'a';
int requiredValue = (int)charToConvert - 96;
If you want to calculate the sum of the letters in a name, you can also use Linq (just an example):
string name = "ABCD";
int sum = name.Select(letter => letter - 'A' + 1).Sum();
You can perform calculations with letters just like with integers in C#.
The Select method (which is an extension method from Linq) projects each letter of the string to it's corresponding value. These values are then summed by the extension method Sum().
Edit: As jlafay pointed out, you can omit the Select call and put the projection into the Sum method:
name.Sum(letter => letter - 'A' + 1)
And regarding your original question: You can't access the name of a local variable, even with reflection. That information is not included in the metadata of the compiled code.
Instead of assigning 26 variables for each letter, create an IDictionary<TKey, TValue> where the TKey is the character and the TValue is whatever value you assign. Then you can access the value by passing in the character much more easily.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace SO
{
static class Program
{
static void Main()
{
WebClient wc = new WebClient();
var text = wc.DownloadString("http://projecteuler.net/project/names.txt");
var names = Regex.Matches(text, "[A-Z]+").Cast<Match>()
.Select(x => x.Value)
.OrderBy(x => x)
.Select((name, inx) => new
{
Name = name,
Score = name.Sum(c => c - 'A' + 1) * (inx + 1)
});
foreach (var n in names)
{
Console.WriteLine("{0}: {1}", n.Name, n.Score);
}
}
}
}

Determine if all digits of the sum of n and swapped n are odd

I need to determine if all the digits of the sum of n numbers and swapped n are odd.
For example:
36 + 63 = 99 (9 and 9 are both odd)
409 + 904 = 1313 (1 and 3 are both odd)
Visual Studio builds my code and it runs, but it doesn't return an answer.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
long num = Convert.ToInt64(Console.Read());
long vol = voltea(num);
long sum = num + vol;
bool simp = simpares(sum);
if (simp == true)
Console.Write("Si");
else
Console.Write("No");
}
static private bool simpares(long x)
{
bool s = false;
long [] arreglo = new long [1000];
while ( x > 0)
{
arreglo [x % 10] ++;
x /=10;
}
for (long i=0 ; i <= arreglo.Length ; i++)
{
if (arreglo [i]%2 != 0)
s = true;
}
return s;
}
static private long voltea(long x)
{
long v = 0;
while (v > 0)
{
v = 10 * v + x % 10;
x /= 10;
}
return v;
}
}
}
I'm not sure what's wrong with your code, but I was thinking an easier way to accomplish this would be to use strings, rather than doing all the divisions and mods by 10.
Convert original number to string, reverse the string, then convert that back to a long
Add the original and reversed numbers
Convert the sum to a string
Loop over the result string and check to see if each digit is odd
It's not too clear what you mean by "Doesn't return an answer".
Add:
Console.ReadKey();
Console.ReadLine();
At the end of your Main function. I'd hazard a guess that you're not seeing an answer because the console is closing on you.
EDIT:
Found it:
for (long i=0 ; i <= arreglo.Length ; i++)
Index out of bounds. That should be:
for (long i=0 ; i < arreglo.Length ; i++)
i should be "Less than" arreglo, not "Less than or equal to"
EDIT2:
This is why your current code is broken. I'd highly recommend also looking at alternative methods of solving the problem. See Andy White's Answer.
It looks to me like you might have an infinite loop and a loop that never enters.
// because v = 0, the while will never execute
long v = 0;
while (v > 0)
{
v = 10 * v + x % 10;
x /= 10;
}

Categories