1

Relatively new to Java, looking for a solution to a crucial part of a game I'm making for a class. The idea is to make a very simple stock market simulation game, but the problem is related to creating made-up company names. I have three arrays for the first, middle, and last names of companies. I'm trying to make some of these companies have one word names, others two, etc. So far I've used a random number generator and if/elif/else statement to simulate one, but I would like five of them and I would prefer a more efficient method of doing so. Here's the code:

import java.util.Random;
import java.io.*;
import java.util.*;

class Main {

    public static void main(String[] args) {
        // The code all goes in here

        String[] companyFirstNames = {"Alpine", "Bear", "Bull", "Cuckoo", "Delta", "Dragon", "Echo", "Fighter", "Giant", "H20", "Indo", "Jared", "Jason", "Kicker", "Lodge", "Little", "Manzo", "Mint", "Neighbour", "Nelson", "Ossuary", "Open", "Private", "Poor", "Quick", "Quiant", "Reach", "Rebel", "Space", "Spear", "Titus", "Trebble", "Underdog", "Upper", "Vital", "Vert", "White", "Whistle", "X's", "Yuri's", "Yogurt", "Zebra"};

        String[] companySecondNames = {" Science", " Technology", " Arts", " Research", " Laboratory", " Lodging", " Woodworking", " Fashion", " Oil", " Trading", "  Investing"};

        String[] companyLastNames = {" Limited", " Co.", " Corp.", " Corporation", " Ltd", " Institute", " Association", " Federation", " Firm"};
        //Three arrays of random company name "pieces"

        Random randomNamer = new Random();
        //Used for getting random names & ints

        int randomOne = randomNamer.nextInt(companyFirstNames.length);
        int randomTwo = randomNamer.nextInt(companySecondNames.length);
        int randomThree = randomNamer.nextInt(companyLastNames.length);
        //Three ints that are given random values associated to the arrays

        int numberOne = randomNamer.nextInt(100);
        //Getting a random 0-100 number

        String bigNameCompany = companyFirstNames[randomOne] + companySecondNames[randomTwo] + companyLastNames[randomThree]; 
        String midNameCompany = companyFirstNames[randomOne] + companyLastNames[randomThree];
        String smallNameCompany = companyFirstNames[randomOne];
        //The three types of company names possible to produce

        String companyOne;
        String companyTwo;
        String companyThree;
        String companyFour;
        String companyFive;
        //The five companies I want to name

        if (numberOne <= 45) {
            companyOne = bigNameCompany;
            //The first company name is random and big
        } else if (numberOne <= 85) {
            companyOne = midNameCompany;
            //Two word name
        } else {
            companyOne = smallNameCompany;
            //One word name
        }

        System.out.println(companyOne);
        //printing the name of the first company

        //Can i get a loop to do this more efficiently for 5 companies?

    }

}
Jon Bates
  • 3,055
  • 2
  • 30
  • 48
Jared
  • 13
  • 3

3 Answers3

0

I'd encourage you to play around with it. That's the fun of programming is solving little puzzles like this, and there are a bunch of ways to do something like this. Here is one to give you some ideas:

    Random randomNamer = new Random();
    String[] companyFirstNames = { "Alpine", "Bear", "Bull", "Cuckoo", "Delta", "Dragon", "Echo", "Fighter", "Giant", "H20", "Indo", "Jared", "Jason", "Kicker", "Lodge", "Little", "Manzo", "Mint", "Neighbour", "Nelson", "Ossuary", "Open", "Private", "Poor", "Quick", "Quiant", "Reach", "Rebel", "Space", "Spear", "Titus", "Trebble", "Underdog", "Upper", "Vital", "Vert", "White", "Whistle", "X's", "Yuri's", "Yogurt", "Zebra" };
    String[] companySecondNames = { " Science", " Technology", " Arts", " Research", " Laboratory", " Lodging", " Woodworking", " Fashion", " Oil", " Trading", "  Investing" };
    String[] companyLastNames = { " Limited", " Co.", " Corp.", " Corporation", " Ltd", " Institute", " Association", " Federation", " Firm" };

    for (int i = 0; i < 5; i++) {
        int chance = randomNamer.nextInt(100);
        int firstIdx = randomNamer.nextInt(companyFirstNames.length);
        int secondIdx = randomNamer.nextInt(companySecondNames.length);
        int lastIdx = randomNamer.nextInt(companyLastNames.length);

        String name = null;
        if (chance <= 45) {
            name = companyFirstNames[firstIdx] + companySecondNames[secondIdx] + companyLastNames[lastIdx];
        } else if (chance <= 85) {
            name = companyFirstNames[firstIdx] + companyLastNames[lastIdx];
        } else {
            name = companyFirstNames[firstIdx];
        }
        System.out.println(name);
    }
crig
  • 859
  • 6
  • 19
  • Thank you for this! I gave the thing a couple tries but was pretty limited by my current java knowledge. I'm going to peek at this while I rework my code and figure out how to get five individual strings (for the 5 companies) from this that I can use in later code. – Jared Sep 16 '21 at 22:44
0

You can create a simple method for that (and you don't need white spaces in your name Strings):

private final String[] companyFirstNames = {"Alpine", "Bear", "Bull", "Cuckoo", "Delta", "Dragon", "Echo", "Fighter", "Giant", "H20", "Indo", "Jared", "Jason", "Kicker", "Lodge", "Little", "Manzo", "Mint", "Neighbour", "Nelson", "Ossuary", "Open", "Private", "Poor", "Quick", "Quiant", "Reach", "Rebel", "Space", "Spear", "Titus", "Trebble", "Underdog", "Upper", "Vital", "Vert", "White", "Whistle", "X's", "Yuri's", "Yogurt", "Zebra"};

private final String[] companySecondNames = {"Science", "Technology", "Arts", "Research", "Laboratory", "Lodging", "Woodworking", "Fashion", "Oil", "Trading", "Investing"};

private final String[] companyLastNames = {"Limited", "Co.", "Corp.", "Corporation", "Ltd", "Institute", "Association", "Federation", "Firm"};

private final Random randomNamer = new Random();

private String generateRandomName() {

    StringBuilder sb = new StringBuilder();
    
    int size = random.nextInt(100);
    int first = random.nextInt(companyFirstNames.length);

    sb.append(companyFirstNames[first]);
    
    if (size <= 85) {
        int second = random.nextInt(companySecondNames.length);
        sb.append(' ').append(companySecondNames[second]);
    }
    if (size <= 45) {
        int last = random.nextInt(companyLastNames.length);
        sb.append(' ').append(companyLastNames[last]);
    }
    return sb.toString();
}

Then you can do:

private List<String> generateNames(int numberOfNames) {
    return IntStream.range(0, numberOfNames).mapToObj(i -> 
            generateRandomName()).collect(Collectors.toList());
}

Calling the last method will allow you to create as many names as you want:

List<String> names = generateNames(5)

System.out.println(names);

Output:

[White Trading Firm, Open Research, Indo Oil, Fighter Technology, Cuckoo Oil Corporation]
Oboe
  • 2,643
  • 2
  • 9
  • 17
  • I never thought about making my own method, that's another for me to check out. Also, what does .append() do? I've never seen that before. – Jared Sep 16 '21 at 23:11
  • This is a better option that what I posted below.. – crig Sep 17 '21 at 15:30
  • A StringBuilder/StringBuffer is a more efficient way to concatenate Strings (sometimes) than using the + operator. In practice, in most cases the compiler ends up optimizing the + concatenation to be the same as using a StringBuilder, but there are some cases where it cannot. – crig Sep 17 '21 at 15:31
  • @Jared take a look at [`StringBuilder`](https://docs.oracle.com/en/java/javase/16/docs/api/java.base/java/lang/StringBuilder.html). – Oboe Sep 17 '21 at 15:32
  • @crig I think is very similar, the main difference is `StringBuilder` – Oboe Sep 17 '21 at 15:34
0

Your solution would probably work, but you could reuse your Random to decide whether a company name should have one, two or three words to make it more compact. This example would always generate a company with at least one name, while there's an equal probability for second and third:

final Random rnd = new Random();
final String[] companies = new String[5];

for(int i = 0; i < companies.length; i++) {
  final int idx = rnd.nextInt(100);
  companies[i] = companyFirstNames[idx%companyFirstNames.length] 
  + (rnd.nextBoolean() ? companySecondNames[idx%companySecondNames.length] : "")
  + (rnd.nextBoolean() ? companyLastNames[idx%companyLastNames.length] : "");
}

You can use something like rnd.nextInt(2) == 0 or rnd.nextInt(3) == 0 to play with the odds of a longer company name instead of nextBoolean().

Edit

Something that may be worth thinking about is uniqueness - is it a problem if you happen to generate the same company name more than once? Depending on your strategy you could keep track of either the number or name you generate (probably in a Set), and regenerate if it already exists.

PPartisan
  • 8,173
  • 4
  • 29
  • 48
  • Ok I think I get the jist of it, but I'm not entirely sure how the math within the companies[i] part works; specifically the companyFirstNames[idx...]. Why is there a modulus being used with idx and the companyFirstnames.length? Also thanks for reminding me about possible company names being the same, I didn't catch that. – Jared Sep 16 '21 at 22:59
  • It's a common technique used with array indexes to ensure a number is always within the array bounds. If you imagine a few scenarios you'll see how it works: if idx is 20 and array length 10, then 20%10 is 0. If idx is 21, 21%10 is 1. If idx is 5, 5%10 is 5. And so on. It just means you can reuse the same index for all the arrays. – PPartisan Sep 16 '21 at 23:20