Home » Java » java – Getting names from text file shifts names 1 place to the left (in array)-Exceptionshub

java – Getting names from text file shifts names 1 place to the left (in array)-Exceptionshub

Posted by: admin February 25, 2020 Leave a comment

Questions:

I was trying to solve problem 22 of Euler Project. Description of what I’m trying to solve is here:
https://projecteuler.net/problem=22

Where’s the problem?: I’ve got the names from the text file, put them on one string,
edited the string so that the names are separated by one space.
After getting those names on an array of Strings, I sort them. After finishing the program and getting the result wrong, I started testing different parts of the program and notice that the name “COLIN”, which by eulerproject page is said to be the 938th, is 937th on my array. I can’t seem to get why is it happening and how to fix this. Help would be much appreciated.

Here is the code:

package Project022;

import java.io.File;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;

public class NameScore {
    private long scoreSum;

    private LinkedList<String> allNames;

    private String[] sortedNames;
    private int[] nameScores;

    public NameScore(){
        scoreSum = 0;
        allNames = new LinkedList<>();
        getNames();
    }
    private void getNames(){
        List<String> content = null;
        File names;
        // read "names.txt" file and put all the names in one line(not effective when line
        // length surpasses String maximum character range(2^31 - 1) but is good enough for us
        // for now)
        try {
            names = new File("Project022\names.txt");
            content = Files.readAllLines(Paths.get(names.getPath()), StandardCharsets.US_ASCII);
        } catch (Exception e){
            System.out.println("something went wrong while getting the file");
        }
        assert content != null;

        //replace (",") with a space ( )
        String filtered = content.get(0).replaceAll("\",\"", " ");

        //then remove first and last (")
        filtered = filtered.substring(1, filtered.length() - 1);

        //declare "tempName" as a helper string
        StringBuilder tempName = new StringBuilder();

        //get every name and put it on the LinkedList
        for (int i = 0; i < filtered.length(); i++) {
            if (filtered.charAt(i) != ' '){
                tempName.append(filtered.charAt(i));
            } else {
                allNames.add(tempName.toString().trim());
                tempName = new StringBuilder();
            }
        }

        //now we use an pre defined array since it is faster.
        sortedNames = new String[allNames.size()];

        for (int i = 0; i < sortedNames.length; i++) {
            sortedNames[i] = allNames.get(i);
        }

        //make the new array worthy of its name
        Arrays.sort(sortedNames);

        System.out.println(sortedNames[937]);

        System.out.println(Arrays.asList(sortedNames) + "\n" + sortedNames.length);
    }

    public void calculate(){
        //we set the score for each name
        nameScores = new int[sortedNames.length];

        //
        for (int i = 0; i < nameScores.length; i++) {
            setScore(sortedNames[i], i + 1);
        }

        for (int i = 0; i < nameScores.length; i++) {
            scoreSum += nameScores[i];
        }
    }
    private void setScore(String name, int n) {
        int sc = 0;
        for (int i = 0; i < name.length(); i++) {
            sc += (int)name.toUpperCase().charAt(i) - 'A' + 1;
        }
        sc *= n;
        nameScores[n-1] = sc;
    }
    @Override
    public String toString(){ return "the score of all names is: " + scoreSum; }

    public static void main(String[] args) {
        NameScore name = new NameScore();
        name.calculate();
        System.out.println(name);
    }
}

What I’ve ruled out as a problem:

  1. the setScore() method which gives a score for every name, because I tested it with examples by hand and by program and got same results.

  2. the calculate() method, since what it does is gets the score for each name and adds to the total sum.

How to&Answers:

This works for me.

Path p = Paths.get("p022_names.txt");
try {
    List<String> lines = Files.readAllLines(p); // throws java.io.IOException
    System.out.println(lines.size()); // Only one line in file.

    // Remove all " (double quotes) characters.
    String tmp = lines.get(0).replaceAll("\"", "");

    String[] names = tmp.split(",");
    System.out.println(names.length);
    Arrays.sort(names);

    // Test against example given in problem description.
    System.out.println(names[937]); // Should be COLIN
    char[] lett = names[937].toCharArray();
    int sigma = 0;
    for (int k = 0; k < lett.length; k++) {
        sigma += lett[k] - 'A' + 1; // Since only uppercase letters in file.
    }
    int score = sigma * (937 + 1);
    System.out.println(score); // Should be 49714

    // Now obtain answer, i.e. the total of all the name scores in the file.
    int total = 0;
    for (int i = 0; i < names.length; i++) {
        char[] letters = names[i].toCharArray();
        int sum = 0;
        for (int j = 0; j < letters.length; j++) {
            sum += letters[j] - 'A' + 1;
        }
        total += sum * (i + 1);
    }
    System.out.println(total);
}
catch (IOException xIo) {
    xIo.printStackTrace();
}

Output obtained when running above code is as follows.

1
5163
COLIN
49714
871198282

Answer:

I didn’t want to make too many changes to your code, so just removed your replacement of "," and instead just removed all ". Then I added ALONSO in the end after the loop.

I figure if we’re all in consensus about the total score of all the names, then we’re doing it right 🙂

It prints:

 -- Where's ALONSO ?
sortedNames[145] = ALONA
sortedNames[146] = ALONSO
sortedNames[147] = ALONZO

 -- Where's COLIN ?
sortedNames[936] = COLETTE
sortedNames[937] = COLIN
sortedNames[938] = COLLEEN

 -- Where's MARY ?
sortedNames[3361] = MARX
sortedNames[3362] = MARY
sortedNames[3363] = MARYA

 -- sortedNames.length = 5163

the score of all names is: 871198282

I also called it Project022:

import java.io.File;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;

//public class NameScore {
public class Project022 {
    private long scoreSum;

    private LinkedList<String> allNames;

    private String[] sortedNames;
    private int[] nameScores;

    public Project022(){
        scoreSum = 0;
        allNames = new LinkedList<>();
        getNames();
    }
    private void getNames(){
        List<String> content = null;
        File names;
        // read "names.txt" file and put all the names in one line(not effective when line
        // length surpasses String maximum character range(2^31 - 1) but is good enough for us
        // for now)
        try {
//            names = new File("Project022\names.txt");
            names = new File("resource\p022_names.txt");
            content = Files.readAllLines(Paths.get(names.getPath()), StandardCharsets.US_ASCII);
        } catch (Exception e){
            System.out.println("something went wrong while getting the file");
        }
        assert content != null;

        //replace (",") with a space ( )
//        String filtered = content.get(0).replaceAll("\",\"", " ");
        String filtered = content.get(0).replaceAll("\"", "");

//        //then remove first and last (")
//        filtered = filtered.substring(1, filtered.length() - 1);

        //declare "tempName" as a helper string
        StringBuilder tempName = new StringBuilder();

        //get every name and put it on the LinkedList
        for (int i = 0; i < filtered.length(); i++) {
//            if (filtered.charAt(i) != ' '){
            if (filtered.charAt(i) != ','){
                tempName.append(filtered.charAt(i));
            } else {
                allNames.add(tempName.toString().trim());
                tempName = new StringBuilder();
            }
        }
        allNames.add(tempName.toString().trim());  // added to include ALONSO

        //now we use an pre defined array since it is faster.
        sortedNames = new String[allNames.size()];

        for (int i = 0; i < sortedNames.length; i++) {
            sortedNames[i] = allNames.get(i);
        }

        //make the new array worthy of its name
        Arrays.sort(sortedNames);

        System.out.println("\n -- Where's ALONSO ?");
        for (int i = 145; i < 148; i++) {
          // sortedNames[0] = AARON
          System.out.println("sortedNames[" + i + "] = " + sortedNames[i]);
        }

        System.out.println("\n -- Where's COLIN ?");
        for (int i = 936; i < 939; i++) {
          // sortedNames[0] = AARON
          System.out.println("sortedNames[" + i + "] = " + sortedNames[i]);
        }

        System.out.println("\n -- Where's MARY ?");
        for (int i = 3361; i < 3364; i++) {
          // sortedNames[0] = AARON
          System.out.println("sortedNames[" + i + "] = " + sortedNames[i]);
        }

        System.out.println("\n -- sortedNames.length = " + sortedNames.length + "\n");

//        System.out.println(Arrays.asList(sortedNames) + "\n" + sortedNames.length);
    }

    public void calculate(){
        //we set the score for each name
        nameScores = new int[sortedNames.length];

        //
        for (int i = 0; i < nameScores.length; i++) {
            setScore(sortedNames[i], i + 1);
        }

        for (int i = 0; i < nameScores.length; i++) {
            scoreSum += nameScores[i];
        }
    }
    private void setScore(String name, int n) {
        int sc = 0;
        for (int i = 0; i < name.length(); i++) {
            sc += (int)name.toUpperCase().charAt(i) - 'A' + 1;
        }
        sc *= n;
        nameScores[n-1] = sc;
    }
    @Override
    public String toString(){ return "the score of all names is: " + scoreSum; }

    public static void main(String[] args) {
        Project022 name = new Project022();
        name.calculate();
        System.out.println(name);
    }
}