Home  >  Article  >  ProjectEuler Question 17: I changed this line of code and my answer changed drastically, even though I thought it should work

ProjectEuler Question 17: I changed this line of code and my answer changed drastically, even though I thought it should work

WBOY
WBOYforward
2024-02-13 20:51:08915browse

php editor Apple encountered an interesting situation in ProjectEuler issue 17. After he changed one line of code, he found that the answer changed dramatically, even though he thought the code should work fine. This question piqued his curiosity, and he began to explore the reasons and seek solutions. This story is full of challenges and thoughts, making people look forward to the editor’s answer.

Question content

I am working on project euler question 17. I should write a program to count the total number of characters in a written number 1-1000. You ignore spaces and hyphens. According to the problem description, hundreds of numbers include a "and" (three hundred and forty-two). My code works in most cases except for multiples of 100 (when it calculates the extra "sum"). For example, count 600 as "six hundred and." This caused my answer to deviate from 27 (3 out of 9 out of 100 digits). This is almost the correct solution:

string[] nums = {"",
                 "one",
                 "two",
                 "three",
                 "four",
                 "five",
                 "six",
                 "seven",
                 "eight",
                 "nine",
                 "ten",
                 "eleven",
                 "twelve",
                 "thirteen",
                 "fourteen",
                 "fifteen",
                 "sixteen",
                 "seventeen",
                 "eighteen",
                  "nineteen"};
string[] ten = {"",
                "",
                "twenty",
                "thirty",
                "forty",
                "fifty",
                "sixty",
                "seventy",
                "eighty",
                "ninety"};
int sum = 0;
map<integer, integer> ones = new hashmap<>();
map<integer, integer> teens = new hashmap<>();
map<integer, integer> tens = new hashmap<>();
for (int i = 0; i < 10; i++) {
    ones.put(i, nums[i].length());
}
for (int i = 10; i < nums.length; i++) {
    teens.put(i, nums[i].length());
}
for (int i = 0; i < ten.length; i++) {
    tens.put(i * 10, ten[i].length());
}
for (int i = 1; i < 1000; i++) {
    int num = 0;
    int n = i % 100;
    if (n > 19 || n < 10) {
        num += ones.get(n % 10);
        num += tens.get(n - n % 10);
    }
    else {
        num += teens.get(n);
    }
    num += i > 99 ? "hundredand".length() : 0;
    num += ones.get(i / 100);
    system.out.println(num + " " + i);
    sum += num;
}
sum += ("onethousand").length();
// actual is 21124
system.out.println(sum);

This results in an output of 21151, which is 27 different from the expected output of 21124. Variable num is used for debugging purposes.

I tried changing one of the lines of the loop and added an extra statement:

num += i>99 ? "hundred".length() : 0;
num += i%100==0 ? 3 : 0;

After running this updated version, the output is 18487. I'm not sure why this difference is so striking and would like to understand where this comes from. I first thought it was because of the ternary operator, since my knowledge of it is limited. Also, any suggestions to make the code more efficient are welcome. I'd like to enter sum-27 before printing, but I feel like that's a bit cheating :). Thanks!

Workaround

As others have said in comments to your question, your problem is how your code handles numbers that are multiples of 100. You always add hundred and never just hundredum>. In fact, you indicated yourself in your question:

In the code below, I'm using an explicit if statement - rather than the ternary operator - because I believe it makes the code easier to understand when reading. Please note that this is the only change I made to the code posted in your question.

import java.util.hashmap;
import java.util.map;

public class myclass {
    public static void main(string args[]) {
        string[] nums = {"",
                         "one",
                         "two",
                         "three",
                         "four",
                         "five",
                         "six",
                         "seven",
                         "eight",
                         "nine",
                         "ten",
                         "eleven",
                         "twelve",
                         "thirteen",
                         "fourteen",
                         "fifteen",
                         "sixteen",
                         "seventeen",
                         "eighteen",
                         "nineteen"};
        string[] ten = {"",
                        "",
                        "twenty",
                        "thirty",
                        "forty",
                        "fifty",
                        "sixty",
                        "seventy",
                        "eighty",
                        "ninety"};
        int sum = 0;
        map<integer, integer> ones = new hashmap<>();
        map<integer, integer> teens = new hashmap<>();
        map<integer, integer> tens = new hashmap<>();
        for (int i = 0; i < 10; i++) {
            ones.put(i, nums[i].length());
        }
        for (int i = 10; i < nums.length; i++) {
            teens.put(i, nums[i].length());
        }
        for (int i = 0; i < ten.length; i++) {
            tens.put(i * 10, ten[i].length());
        }
        for (int i = 1; i < 1000; i++) {
            int num = 0;
            int n = i % 100;
            if (n > 19 || n < 10) {
                num += ones.get(n % 10);
                num += tens.get(n - n % 10);
            }
            else {
                num += teens.get(n);
            }
            if (i > 99) {
                num += n == 0 ? "hundred".length() : "hundredand".length();
            }
            num += ones.get(i / 100);
            sum += num;
//            system.out.printf("%2d %3d %5d%n", num, i, sum);
        }
        sum += ("onethousand").length();
        // actual is 21124
        system.out.println(sum);
    }
}

When I run the above code, I get the following results:

21124

In the code of your question, you wrote (in the code comments) that this is the expected answer.

The above is the detailed content of ProjectEuler Question 17: I changed this line of code and my answer changed drastically, even though I thought it should work. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:stackoverflow.com. If there is any infringement, please contact admin@php.cn delete