2020.코딩일지

[JS][코플릿]Immersive Toy Problem-21_inequalityNumber 본문

algorithm

[JS][코플릿]Immersive Toy Problem-21_inequalityNumber

개발하는라푼젤 2022. 9. 15. 16:44
728x90

 

문제

아래와 같은 과정을 거쳐 부등호 수(inequalityNumber)를 만들 수 있습니다.

  • 최대 9개의 부등호(<, >)가 주어집니다.
  • 부등호의 좌우에는 0부터 9사이의 숫자가 한 번씩만 들어가야 합니다.
  • 부등호를 만족하는 숫자의 조합을 차례대로 이어 붙여 만든 정수를 부등호 수라고 한다.

부등호 기호들을 입력받아 부등호를 만족하는 최대 부등호 수와 최소 부등호 수의 차이를 리턴해야 합니다.

입력

인자 1 : signs

  • string 타입의 공백을 사이에 둔 부등호 기호들
  • signs.length는 17 이하 (최대 9개의 부등호 기호)

출력

  • number 타입을 리턴해야 합니다.

주의사항

  • 첫 자리가 0인 경우도 부등호 수에 포함되어야 합니다.
  • 모든 입력에 답은 항상 존재합니다.

입출력 예시

let output = inequalityNumber('<');
console.log(output); // --> 88 (89 - 01)

output = inequalityNumber('< >');
console.log(output); // --> 876 (897 - 021)

output = inequalityNumber('> < >');
console.log(output); // --> 8,754 (9,786 - 1,032)

 

 

👻하

이건 킹규명님풀이없이는안된다안돼. 문제조차이해불가 ㅜㅜ

킹규명님의노션풀이

 

const inequalityNumber = function (signs) { // <

	// 재귀 함수
	// 부등호 숫자를 찾는 함수
  const aux = (idx, signs, nums, digits, isVisited) => {

		// 모든 부등호 좌우에 숫자를 넣어준 경우
    if (idx === signs.length) {
			// nums 배열의 join으로 string type으로 합친다.
			// parseInt로 string을 number로 변환 후 return 한다.
      return parseInt(nums.join(''));
    }

		// 부등호를 선택한다.
    const sign = signs[idx];

		// 반복문을 사용해 0 ~ 9까지 돌아보면서 알맞는 숫자를 찾는다.
    for (let i = 0; i < digits.length; i++) {

			// 부등호의 오른쪽에 들어갈 숫자를 선택한다.
      const right = digits[i];
			
			// 오른쪽에 들어갈 숫자가 이미 사용된 숫자라면
			// 현재 반복을 건너뛰고 다음 반복으로 넘어간다.
      if (isVisited[right]) continue;

      // 첫 번째 숫자가 아닌 경우
			// 첫 부등호 왼쪽을 제외한 위치는 해당 조건문으로 들어간다.
      if (idx >= 0) {

        // 해당 부등호의 왼쪽 숫자
				// 해당 부등호의 오른쪽 숫자와 비교하기 위해서 지정
				// 왼쪽 숫자는 오른쪽 숫자의 이전 index를 조회하면 찾을 수 있다.
        const left = nums[nums.length - 1];

				// 해당 부등호와 비교해 식이 틀리다면
				// 현재 반복을 건너뛰고 다음 반복으로 넘어간다.
				// 부등호와 틀리기 때문에 현재 right는 맞지 않는 숫자라는 뜻
        if (sign === '<' && left >= right) continue;
        if (sign === '>' && left <= right) continue;
      }

      // 조건을 만족하거나 첫번째 숫자인 경우
			// 사용한 숫자를 true 표시해 같은 숫자가 중복 사용되지 않게 한다.
      isVisited[right] = true;

			// 재귀를 실행
			// idx를 1올려 다음 부등호에 대한 숫자를 구한다.
			// nums.concat(right)를 통해 부등호 수를 완성해 간다.
      const target = aux(idx + 1, signs, nums.concat(right), digits, isVisited);

			// target은 재귀함수 이름이다.
			// 즉, 완성된 부등호 수를 가진다.
			// 완성된 부등호 수가 있다면 목표를 달성했으니 재귀를 종료한다.
      if (target !== undefined) {
        return target;
      }

      // 아직 부등호 수를 완성하지 못했다면
			// 사용했다고 표시한 것을 사용 전이라고 되돌려 준다.
      isVisited[right] = false;
    }

		// 모든 숫자를 탐색했지만 알맞는 숫자를 찾지 못했다면
		// undefined를 return 한다.
    return undefined;
  };

	// 부등호만 남기고 띄어쓰기는 제거한다.
  signs = signs.split(' ');

	// 탐색할 숫자
  const digits = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
 
  // min은 최소 부등호 수를 구함으로 digits 배열을 정방향으로 사용한다.
	// max는 최대 부등호 수를 구함으로 digits 배열을 역방향으로 사용한다.
	// idx에 들어가는 -1은 숫자 위치를 나타낸다.
	// 첫 숫자가 0이 아닌 -1인 이유는 if (idx >= 0) 조건을 통과하기 위해서이며
	// 첫 숫자는 아무 조건 필요 없이 들어갈 수 있는 위치이기 때문이다.
	// isVisited라는 매개변수에 들어가는 Array(10).fill(false)는
	// 숫자 사용 상태를 나타내며 사용한 숫자는 true로 check한다.
  const min = aux(-1, signs, [], digits, Array(10).fill(false));
  const max = aux(-1, signs, [], digits.reverse(), Array(10).fill(false));

	// 최대 부등호 수에 최소 부등호 수를 뺀 값을 return 한다.
  return max - min;
};

 

 

 

 

Comments