-
#AIL_24.01.12 // Programmers_푸드 파이트 대회AIL( Algorithm I Learned) 2024. 1. 13. 22:20
## AIL_ 푸드 파이트 대회
*** 문제 설명
수웅이는 매달 주어진 음식을 빨리 먹는 푸드 파이트 대회를 개최합니다. 이 대회에서 선수들은 1대 1로 대결하며, 매 대결마다 음식의 종류와 양이 바뀝니다. 대결은 준비된 음식들을 일렬로 배치한 뒤, 한 선수는 제일 왼쪽에 있는 음식부터 오른쪽으로, 다른 선수는 제일 오른쪽에 있는 음식부터 왼쪽으로 순서대로 먹는 방식으로 진행됩니다. 중앙에는 물을 배치하고, 물을 먼저 먹는 선수가 승리하게 됩니다.
이때, 대회의 공정성을 위해 두 선수가 먹는 음식의 종류와 양이 같아야 하며, 음식을 먹는 순서도 같아야 합니다. 또한, 이번 대회부터는 칼로리가 낮은 음식을 먼저 먹을 수 있게 배치하여 선수들이 음식을 더 잘 먹을 수 있게 하려고 합니다. 이번 대회를 위해 수웅이는 음식을 주문했는데, 대회의 조건을 고려하지 않고 음식을 주문하여 몇 개의 음식은 대회에 사용하지 못하게 되었습니다.
예를 들어, 3가지의 음식이 준비되어 있으며, 칼로리가 적은 순서대로 1번 음식을 3개, 2번 음식을 4개, 3번 음식을 6개 준비했으며, 물을 편의상 0번 음식이라고 칭한다면, 두 선수는 1번 음식 1개, 2번 음식 2개, 3번 음식 3개씩을 먹게 되므로 음식의 배치는 "1223330333221"이 됩니다. 따라서 1번 음식 1개는 대회에 사용하지 못합니다.
수웅이가 준비한 음식의 양을 칼로리가 적은 순서대로 나타내는 정수 배열 food가 주어졌을 때, 대회를 위한 음식의 배치를 나타내는 문자열을 return 하는 solution 함수를 완성해주세요.
*** 제한사항
2 ≤ food의 길이 ≤ 9
1 ≤ food의 각 원소 ≤ 1,000
food에는 칼로리가 적은 순서대로 음식의 양이 담겨 있습니다.
food[i]는 i번 음식의 수입니다.
food[0]은 수웅이가 준비한 물의 양이며, 항상 1입니다.
정답의 길이가 3 이상인 경우만 입력으로 주어집니다.
*** 입출력 예
food result [1, 3, 4, 6] "122333033221" [1, 7, 1, 2] "111303111"
*** 입출력 예 설명
입출력 예 #1
문제 예시와 같습니다.
입출력 예 #2
두 선수는 1번 음식 3개, 3번 음식 1개를 먹게 되므로 음식의 배치는 "111303111"입니다.
## solution.JavaScript
1. 문제의 접근 방식
주어진 문제는 두 선수가 먹는 음식의 양과 순서를 조절하여 대회의 규칙에 맞게 음식을 배치하는 것입니다. 대회 규칙은 다음과 같습니다:
- 음식의 양과 순서가 같아야 함.
- 칼로리가 적은 음식을 먼저 먹을 수 있게 배치.
이를 해결하기 위한 접근 방법은 다음과 같습니다:
- 먼저, 주어진 음식의 양을 칼로리가 적은 순서대로 정렬합니다.
- 두 선수가 번갈아가며 음식을 먹을 때, 각 선수가 먹을 음식의 순서를 결정합니다.
- 각 선수가 먹을 음식의 순서를 정하면서 대회를 위한 음식의 배치를 구합니다.
- 대회의 규칙에 따라 칼로리가 적은 음식을 먼저 먹을 수 있도록 배치합니다.
- 양쪽에서 같은 순서로 음식을 먹어야 하므로, 대회의 중앙에는 물을 넣어 대칭적인 배치를 만듭니다.
2. 문제풀이
function solution(food) { let answer = ""; for (let i = 1; i < food.length; i++) { answer += String(i).repeat(~~(food[i] / 2)); } return answer + "0" + [...answer].reverse().join(""); } /* 테스트 1 입력값 〉 [1, 3, 4, 6] 기댓값 〉 "1223330333221" 실행 결과 〉 테스트를 통과하였습니다. 테스트 2 입력값 〉 [1, 7, 1, 2] 기댓값 〉 "111303111" 실행 결과 〉 테스트를 통과하였습니다. */
1) let answer = "";: 결과 문자열을 저장할 변수 answer를 초기화합니다.
2) for (let i = 1; i < food.length; i++) {: 주어진 food 배열의 두 번째 원소부터 시작하여 반복문을 실행합니다.
3) answer += String(i).repeat(~~(food[i] / 2));: 현재의 i 값에 대해, 해당 인덱스의 food 배열 값을 2로 나눈 몫 만큼 i를 반복하여 answer에 추가합니다. (~~ 연산자는 소수점 이하를 버리는 역할을 합니다.)
4) return answer + "0" + [...answer].reverse().join("");: 위의 반복이 끝난 후, answer에 문자열 "0"을 추가하고, answer를 배열로 변환하여 뒤집고, 다시 문자열로 합쳐서 최종 결과를 반환합니다.
3. 다른사람의 문제풀이 및 접근방식 분석
function solution(food) { let player1 = []; let player2 = []; let repeat = 0; for (let i = 1; i <= food.length; i++) { if (food[i] > 1) { repeat = Math.floor(food[i] / 2); for (let j = 0; j < repeat; j++) player1.push(i) for (let k = 0; k < repeat; k++) player2.unshift(i) } } player1.push(0); player1 = player1.concat(player2); return player1.join(""); } /* 테스트 1 입력값 〉 [1, 3, 4, 6] 기댓값 〉 "1223330333221" 실행 결과 〉 테스트를 통과하였습니다. 테스트 2 입력값 〉 [1, 7, 1, 2] 기댓값 〉 "111303111" 실행 결과 〉 테스트를 통과하였습니다. */
1) let player1 = [];: 첫 번째 선수가 먹을 음식을 저장할 배열을 초기화합니다.
2) let player2 = [];: 두 번째 선수가 먹을 음식을 저장할 배열을 초기화합니다.
3) let repeat = 0;: 반복 횟수를 저장할 변수를 초기화합니다.
4) for (let i = 1; i <= food.length; i++) {: 주어진 food 배열을 순회합니다. 여기서 배열의 첫 번째 인덱스(물의 양)는 무시하고 1부터 시작합니다.
5) if (food[i] > 1) {: 현재 음식의 양이 1보다 큰 경우에만 아래의 코드 블록을 실행합니다. (물은 1이므로 1인 경우는 제외)
6) repeat = Math.floor(food[i] / 2);: 현재 음식을 반으로 나눈 몫을 계산하여 repeat 변수에 저장합니다.
7) for (let j = 0; j < repeat; j++) player1.push(i): 첫 번째 선수가 먹을 음식을 repeat 만큼 배열에 추가합니다.
8) for (let k = 0; k < repeat; k++) player2.unshift(i): 두 번째 선수가 먹을 음식을 repeat 만큼 배열의 처음에 추가합니다.
9) player1.push(0);: 물의 양을 나타내는 0을 player1 배열에 추가합니다.
10) player1 = player1.concat(player2);: 첫 번째 선수의 음식 배열에 두 번째 선수의 음식 배열을 연결합니다.
11) return player1.join("");: 배열을 문자열로 변환하여 결과를 반환합니다.
'AIL( Algorithm I Learned)' 카테고리의 다른 글
#AIL_24.01.11 // Programmers_문자열 내 마음대로 정렬하기 (2) 2024.01.11 #AIL_24.01.09 // Programmers_가장 가까운 같은 글자 (1) 2024.01.09 #AIL_24.01.08 // Programmers_두 개 뽑아서 더하기 (0) 2024.01.08 #AIL_24.01.04 // Programmers_같은 숫자는 싫어 (0) 2024.01.04 #AIL_24.01.03 // Programmers_크기가 작은 부분 문자열 (0) 2024.01.03