1

I am having trouble with Project Euler's Problem 22

Using names.txt (right click and 'Save Link/Target As...'), a 46K text file containing over five-thousand first names, begin by sorting it into alphabetical order. Then working out the alphabetical value for each name, multiply this value by its alphabetical position in the list to obtain a name score.

For example, when the list is sorted into alphabetical order, COLIN, which is worth 3 + 15 + 12 + 9 + 14 = 53, is the 938th name in the list. So, COLIN would obtain a score of 938 × 53 = 49714. What is the total of all the name scores in the file?

So far this is the first Euler problem I haven't been able to solve on my own, and I don't get what I'm doing wrong here. I'm coming up short by 1532 with this solution.

This is my code:

using (WebClient client = new WebClient())
{
    try
    {
        tempString = client
            .DownloadString("http://projecteuler.net/project/resources/p022_names.txt")
            .Replace("\"", "");
    }
    catch (Exception)
    {
        MessageBox.Show("Error, check your internet connection!");
    }
}

string[] names = tempString.Split(',');
Array.Sort(names);
int total = 0;
for (int i = 0; i < names.Length; i++)
{
    int namescore = 0;
    foreach (char c in names[i]) { namescore += (int)c - 64; }

    total += namescore * (i + 1);
}

return total.ToString();

I think it might be a C# specific bug or quirk ?

Community
  • 1
  • 1
r.delic
  • 795
  • 7
  • 18
  • 1
    You don't need to download the file from the Net as part of the task so you can (and probably should) drop that part of code. – ivan_pozdeev Feb 08 '15 at 11:23
  • I don't need to but I like it this way, it's simple, portable and doesn't interfere with the solution of the problem. – r.delic Feb 08 '15 at 11:27
  • What if you do `string[] names = tempString.ToUpperCase().Split(',');`? Could it be that their file has some lowercase chars by mistake? – SimpleVar Feb 08 '15 at 11:37
  • 1
    @YoryeNathan If you look at the file you'll see that all names are already upper case. – BartoszKP Feb 08 '15 at 11:37
  • The solution seems correct, so possibly a mistake in their expected result. OP should ask himself whether he really cares about that, or maybe he's just solving the problems to learn and practice - in which case, ignoring one possibly-failed problem is no big deal at all. – SimpleVar Feb 08 '15 at 11:40
  • Why would it be a C# bug? Which piece of your code acts "wrong"? – BartoszKP Feb 08 '15 at 11:57
  • @YoryeNathan Project Euler is a fairly large and active community, if it was a mistake on their part, someone would have corrected it by now. If the program logic is correct, then it must be a C# specific bug or quirk I think? – r.delic Feb 08 '15 at 11:59
  • 1
    I copy/pasted your code, signed up, entered the answer and it said "correct" - So this seems to be a layer-8-error :-) – dognose Feb 08 '15 at 12:00
  • @dognose how is that possible? What solution did you get? 871196750 or 871198282 ? – r.delic Feb 08 '15 at 12:04
  • @dognose uh, I keep getting 871196750 with the same exact code :/ – r.delic Feb 08 '15 at 12:08
  • @infamous see ivans post. You would need to compare some numbers to figure out where the error happens. – dognose Feb 08 '15 at 12:21

2 Answers2

1

As you noted, you cannot set the CurrentCulture, therefore set DefaultThreadCurrentCulture.

When I use

CultureInfo.DefaultThreadCurrentCulture = CultureInfo.GetCultureInfo("hr-HR");

before any action, I get the same result you have. So, obviously, you should use

CultureInfo.DefaultThreadCurrentCulture = CultureInfo.GetCultureInfo("en-US");

to achieve the expected output (other than mentioned in the comments it's not enough to do this in the ToString() method, cause it also affects sorting).

BartoszKP
  • 34,786
  • 15
  • 102
  • 130
dognose
  • 20,360
  • 9
  • 61
  • 107
0

Okay, let's check step by step an try to find inconsistencies. I have the correct answer.

Initial data:

names.Length == 5163
names.Count(w=>!Regex.IsMatch(w,"^[A-Z]+$")) == 0
names.Sum(w=>w.Length) == 30959

Partial sums (after N elements):

500: 7139561
2500: 187773540
5000: 811204450

UPDATE:

I have one idea: Sort is locale-specific! Try Sort(StringComparison.Ordinal).

UPDATE2:

To switch culture, set thread culture or AppDomain culture to, say, CultureInfo("en-US").

Community
  • 1
  • 1
ivan_pozdeev
  • 33,874
  • 19
  • 107
  • 152
  • 2
    to join this train: Add `System.IO.File.AppendAllText("debug_out.txt", i + " '" + names[i] +"' --> " +total.ToString() + System.Environment.NewLine);` in the for loop. Heres the output of mine :-) http://pastebin.com/ixBRsXqU - Same numbers as ivan. – dognose Feb 08 '15 at 12:17
  • The first 3 are correct. Partial sums: 500: 7137837 2500: 187771816 5000: 811202918 (using: for (int i = 0; i < N; i++) ) – r.delic Feb 08 '15 at 12:22
  • hmm if the first 3 are correct - that's pretty strange. Please add the code from my comment and compare line by line (where does the error appear first? ) – dognose Feb 08 '15 at 12:26
  • 1
    http://pastebin.com/5kqMft99 ( 238 'ANJA' --> 1445501 ) ! = ( 238 'ANN' --> 1446218 ) I get it now, it's counting 'nj' as a single letter as per the croatian alphabet on my system, how do I switch that to english ? – r.delic Feb 08 '15 at 12:34
  • see ivans edit: try `StringComparision.Ordinal`. But maybe the array is already broken after reading it from the website. Then, use `.ToString(CultureInfo.InvariantCulture)` when reading the file. – dognose Feb 08 '15 at 12:37
  • 1
    Error: Property or indexer 'System.Globalization.CultureInfo.CurrentCulture' cannot be assigned to -- it is read only – r.delic Feb 08 '15 at 12:45
  • 1
    @infamous My bad, there's a different property for setting that. – ivan_pozdeev Feb 08 '15 at 12:50