4
\$\begingroup\$

I was trying one of the problems found on HP Codewars 2007: (2)

Task Description: The CodeWars judges and scorekeepers need help printing the team names above each column on our score sheet. But we want them to look nice, so they need to be printed vertically. All we have to use is a list of team names. Please write us a program that will take a list of team names, and print them vertically.

Program Input Your program will prompt for a team name. Continue prompting for names until you receive “END”. Unlike the real CodeWars, this one will be limited to 16 teams maximum.

Program Output Your program will output to the screen each team’s name, in the order it was entered, arranged vertically such that it is read from top to bottom. There should be two spaces between each name as printed.

enter image description here

I attempted the problem and created the Java solution below:

import java.util.Scanner;
import java.util.ArrayList;

public class Prob02 {
    public static void main(String[] args) {
        Scanner stdin = new Scanner(System.in);

        ArrayList<String> teams = new ArrayList<>();
        ArrayList<Integer> log = new ArrayList<>();

        do{
            System.out.print("Enter team name: ");
            teams.add(stdin.nextLine());
            //System.out.println(); Optional for clearer display. But not required.
        } while (!"END".equals(teams.get((teams.size()-1)))); 
                    //while END is not equal to last element of teams

        teams.remove(teams.get((teams.size()-1)));



        //Find largest String length
        //set defaults - index is 0 and elementLength is first length
        int index = 0; 
        int elementLength = teams.get(0).length();

        //If the first one was indeed the longest one and the only one...
        log.add(index); 

        for(int i = 0; i < teams.size(); i++) {
            if ((teams.get(i)).length() > elementLength) {
                //overwrite index and elementLength if the new one is larger than the default
                index = i; 
                elementLength = (teams.get(i)).length();

                log.add(index); //now, we only need index (or team).
            }

            //repeat.
        }


        String longest = teams.get( log.get(log.size()-1) );

        int longestLengthOfTeam = longest.length();


        int letterYouArePrinting = 0;

        for(int i = 0; i < (longestLengthOfTeam); i++){

            for(int x = 0; x < teams.size(); x++) {
                String team = teams.get(x);
                String[] teamSplit = team.split("");
                //CONVERT !! !!! !!!!!
                ArrayList<String> teamTheNewOne = new ArrayList<>();
                for(int ttno=0; ttno < teamSplit.length; ttno++) {
                    teamTheNewOne.add(teamSplit[ttno]);
                }

                boolean inBoundChecker = (letterYouArePrinting >= teamTheNewOne.size());
                if (inBoundChecker == true) {
                    System.out.print("   "); //not a whole line! 3 Spaces, [1] + 2 req.
                    continue;
                }

                    //Print first letter of all teams
                    System.out.print(teamTheNewOne.get(letterYouArePrinting) + "  " /*Two spaces rule*/);

            }

            System.out.println();
            letterYouArePrinting++;
        //Now, print next letter
        }

    }
}

Is there a more efficient way to solve this problem?

P.S.: Problem can be found at http://www.hpcodewars.org/past/cw10/problems/Prob02%20--%20Vertical%20Printing.pdf .

\$\endgroup\$
3
\$\begingroup\$

Yes, I think there is more straightforward ways to implement this:

  1. Compute the length of the largest string.
  2. Create a 2D char[][] matrix with the amount of rows equal to the length of the largest string. The amount of "columns" depends how much space you want between two neighbour columns.
  3. Fill out the matrix with characters.
  4. Create a StringBuilder and fill it with the chars from the matrix.

All in all

I had this in mind:

private static final int DEFAULT_COLUMN_SPACING = 2;

public static String makeVerticalText(List<String> lines) {
    return makeVerticalText(lines, DEFAULT_COLUMN_SPACING);
}

public static String makeVerticalText(List<String> lines, 
                                      int columnSpacing) {
    if (lines.isEmpty()) {
        return "";
    }

    int maximumLength = lines.stream()
                             .max(Comparator.comparing(String::length))
                             .get()
                             .length();

    char[][] matrix = new char[maximumLength]
                              [(columnSpacing + 1) * lines.size()
                              - columnSpacing];
    int columnIndex = 0;

    for (String line : lines) {
        int rowIndex = 0;

        for (char c : line.toCharArray()) {
            matrix[rowIndex++][columnIndex] = c;
        }

        columnIndex += 1 + columnSpacing;
    }

    int numberOfColumns = matrix[0].length;
    StringBuilder sb = 
            new StringBuilder(maximumLength * (matrix[0].length + 1));

    for (int rowIndex = 0; rowIndex < maximumLength; ++rowIndex) {
        for (columnIndex = 0; columnIndex < numberOfColumns; ++columnIndex) {
            char currentChar = matrix[rowIndex][columnIndex];
            sb.append(currentChar == '\u0000' ? ' ' : currentChar);
        }

        if (rowIndex < maximumLength - 1) {
            sb.append('\n');
        }
    }

    return sb.toString();
}

Hope that helps.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.