-
[내배캠, Lv1] 랜덤 닉네임 생성기알고리즘 문제/Java 2024. 6. 13. 21:06
문제
문제1 : 랜덤한 닉네임을 생성하는 자바/코틀린 코드를 작성해보세요.
- 사용자는 최소 27가지 이상의 닉네임 중 하나를 랜덤으로 출력 할 수 있습니다. (아래의 키워드를 사용해주세요!)
- 기철초풍, 멋있는, 재미있는
- 도전적인, 노란색의, 바보같은
- 돌고래, 개발자, 오랑우탄
문제 접근
문제를 풀기전 나는 다음과 같은 계획을 세웠다.
- 3가지 키워드를 각각 List에 삽입한다.
- Random 객체를 활용하여 0 ~ 2사이의 난수를 생성한다.
- 해당 난수에 해당하는 문자열을 연결하여 출력한다.
해당 계획대로 구현하기 위해 나는 다음과 같은 내용을 학습해야할 필요가 있었다.
- 문자열 출력
- Java의 List 객체 생성 및 초기화
- Random 객체 사용법
계획대로 구현한 코드
import java.util.Arrays; import java.util.List; import java.util.Random; import java.util.Scanner; public class App { static final int MAXIMUM_COUNT = 3; public static void main(String[] args) throws Exception { List<String> firstModifier = Arrays.asList(new String[]{"기절초풍 ", "멋있는 ", "재미있는 "}) ; List<String> secondModifier = Arrays.asList(new String[]{"도전적인 ", "노란색의 ", "바보같은 "}) ; List<String> nickName = Arrays.asList(new String[]{"돌고래", "개발자", "오랑우탄"}); Random rand = new Random(); int firstIndex = rand.nextInt(MAXIMUM_COUNT); int secondIndex = rand.nextInt(MAXIMUM_COUNT); int ninkNameIndex = rand.nextInt(MAXIMUM_COUNT); System.out.println(firstModifier.get(firstIndex) + secondModifier.get(secondIndex) + nickName.get(ninkNameIndex)); } }
그리고 설레이는 마음을 안고 돌려본 결과는 다음과 같았다
재미있고, 도전적이라는 키워드는 마음에 들지만 오랑우탄이라는 마지막 문구가 너무 마음에 들지 않았고
해당 문구만 바꾸고 싶다는 생각을 하던 중 한가지 방법이 떠올랐다.
[ 전략적 팀 전투에 존재하는 시스템인 '증강체와 재설정(리롤)' ] 전략적 팀 전투에 존재하는 '리롤'이라는 아이디어를 사용하면 '내가 원하는 별명을 얻을 수 있겠다.' 라는 생각이 들었다.
그와 동시에 낮은 확률로 '당첨'을 제공한다면 돌릴 때 마다, 소소한 재미 또 한 제공할 수 있으리라 생각이 들었고,
낮은 확률로 당첨되는 "코딩을 잘하는 ", "논리적인 ", "코린이" 라는 키워드를 추가 하기로 했다.
해당 기능을 추가하는 과정에서 2가지 문제를 추가적으로 해결해야할 필요가 있었다.
- 사용자의 input을 어떻게 받을 것인가
- 확률을 어떻게 구현할 것인가
해결 방법
사용자의 input 처리
GUI를 사용할 수 없기에 cin, scanf처럼 사용자로 부터 문자를 입력 받아, 해당 입력에 대한 결과를 보여주는 것이
현재 내가 사용할 수 있는 최선의 방법이라 생각이 들었다.
개인적으로는 민망하지만 이 부분에서 제일 오래 해맸는데, System.Out.println을 자세히 알기 전
ln을 in으로 착각하여 해당 함수를 통해, 입력받은 값을 가져오는 것인 줄 알았다.
결과는 당연하게도 input값을 받는 command변수의 숫자인 0으로 터미널은 도배가 되어 있었고,
그 후, 검색을 통해 scanner라는 객체를 통해 데이터를 입력 받을 수 있다는 것을 확인하고 수정하였다.
확률 구현
Random과 구간을 잘 활용하면 확률 기능을 추가 할 수 있을 것이라 생각이 들었다.
별도의 dice라는 함수를 만들어, 전체 아이템 수, 당첨 아이템 수, 각 당첨 확률을 받게 만들었고,
각 당첨 확률을 0 ~ 100사이의 구간으로 변경,
random을 사용해 얻은 난수가 해당 구간에 존재 한다면 해당 구간에 해당하는 결과를 반환,
random을 통해 얻은 난수가 아이템 당첨 구간에 존재하지 않는다면
기존과 동일하게 0 ~ 기존 아이템 수( 전체 아이템 수 - 당첨 아이템 수 ) 중 무작위 숫자를 반환하게 구현하였다.
예시) 당첨1 = 20%, 당첨 2 = 40%, random 결과 값 = 40
당첨1 ( 0 ~ 19 ) 당첨2 ( 20 ~ 59 ) 당첨 ! 꽝 ( 60 ~ 99 ) 최종 코드
더보기import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Random; import java.util.Scanner; public class App { static final int MAXIMUM_COUNT = 4; // 전체 항목 당첨 개수 각 확률 random 객체 public static int dice(int totalCount, int winningCount, int[] rate, Random engine) { int normalCount = totalCount - winningCount; // 일반 닉네임 개수 = 전체 개수 - 당첨 개수 // 당첨이 존재할 경우 if(winningCount > 0) { // 0 ~ 99사이의 난수 생성 int randNum = engine.nextInt(100); int accumulate = 0; // 당첨 항목 별로 구간을 생성하여 난수가 해당 범위에 존재할 경우 당첨! for(int i = 0; i < rate.length; ++i) { accumulate += rate[i]; if(randNum < accumulate) { return normalCount + i; } } } return engine.nextInt(normalCount); } public static void main(String[] args) throws Exception { List<String> firstModifier = Arrays.asList(new String[]{"기절초풍 ", "멋있는 ", "재미있는 ", "코딩을 잘하는 "}) ; List<String> secondModifier = Arrays.asList(new String[]{"도전적인 ", "노란색의 ", "바보같은 ", "논리적인 "}) ; List<String> nickName = Arrays.asList(new String[]{"돌고래", "개발자", "오랑우탄", "코린이"}); Random rand = new Random(); Scanner sc = new Scanner(System.in); int reroll = 3; // 첫 무작위 닉네임 결과 int firstIndex = dice(MAXIMUM_COUNT, 1, new int[]{ 1 }, rand); int secondIndex = dice(MAXIMUM_COUNT, 1, new int[]{ 10 }, rand); int ninkNameIndex = dice(MAXIMUM_COUNT, 1, new int[]{ 20 }, rand); // while(reroll > 0) { System.out.println(firstModifier.get(firstIndex) + secondModifier.get(secondIndex) + nickName.get(ninkNameIndex)); System.out.println(String.format("남은 재설정 횟수 : %d", reroll)); System.out.println("1. 재설정 2. 확정"); int command = sc.nextInt(); if(command == 1) { System.out.println("1. 1번만 변환 2. 2번만 변환 3. 3번만 변환 4. 전체 변환 그외. 취소"); int nextCommand = sc.nextInt(); switch(nextCommand) { case 1: firstIndex = dice(MAXIMUM_COUNT, 1, new int[]{ 1 }, rand); --reroll; break; case 2: secondIndex = dice(MAXIMUM_COUNT, 1, new int[]{ 10 }, rand); --reroll; break; case 3: ninkNameIndex = dice(MAXIMUM_COUNT, 1, new int[]{ 20 }, rand); --reroll; break; case 4: firstIndex = dice(MAXIMUM_COUNT, 1, new int[]{ 1 }, rand); secondIndex = dice(MAXIMUM_COUNT, 1, new int[]{ 10 }, rand); ninkNameIndex = dice(MAXIMUM_COUNT, 1, new int[]{ 20 }, rand); reroll -= 3; break; } } else if(command == 2) { break; } else { System.out.println("숫자를 다시 한 번 확인해 주세요."); } } System.out.println("\n최종 닉네임 : " + firstModifier.get(firstIndex) + secondModifier.get(secondIndex) + nickName.get(ninkNameIndex)); } }
결과
[ 1번, 2번, 3번 키워드를 순서대로 바꾼 결과 ] '알고리즘 문제 > Java' 카테고리의 다른 글
[프로그래머스, Lv1] 명예의 전당(1) (1) 2024.07.24 [프로그래머스, Lv1] K번째 수 (0) 2024.07.23 [프로그래머스, Lv1] 문자열 다루기 기초 (0) 2024.07.18 [내배캠, Lv3] 단어 맞추기 게임 (0) 2024.06.19 [내배캠, Lv2] 자판기 (0) 2024.06.14 - 사용자는 최소 27가지 이상의 닉네임 중 하나를 랜덤으로 출력 할 수 있습니다. (아래의 키워드를 사용해주세요!)