λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°

Algorithm

[Algorithm] N으둜 ν‘œν˜„

πŸ“‹ 문제

μ•„λž˜μ™€ 같이 5와 μ‚¬μΉ™μ—°μ‚°λ§ŒμœΌλ‘œ 12λ₯Ό ν‘œν˜„ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

12 = 5 + 5 + (5 / 5) + (5 / 5)
12 = 55 / 5 + 5 / 5
12 = (55 + 5) / 5

5λ₯Ό μ‚¬μš©ν•œ νšŸμˆ˜λŠ” κ°κ° 6,5,4 μž…λ‹ˆλ‹€. κ·Έλ¦¬κ³  μ΄μ€‘ κ°€μž₯ μž‘은 κ²½μš°λŠ” 4μž…λ‹ˆλ‹€.
이처럼 숫자 Nκ³Ό numberκ°€ μ£Όμ–΄μ§ˆ λ•Œ, Nκ³Ό μ‚¬μΉ™μ—°μ‚°λ§Œ μ‚¬μš©ν•΄μ„œ ν‘œν˜„ ν•  수 μžˆλŠ” 방법 쀑 N μ‚¬μš©νšŸμˆ˜μ˜ μ΅œμ†Ÿκ°’μ„ return ν•˜λ„λ‘ solution ν•¨μˆ˜λ₯Ό μž‘μ„±ν•˜μ„Έμš”.

μ œν•œμ‚¬ν•­

  • N은 1 이상 9 μ΄ν•˜μž…λ‹ˆλ‹€.
  • numberλŠ” 1 μ΄μƒ 32,000 μ΄ν•˜μž…λ‹ˆλ‹€.
  • μˆ˜μ‹μ—λŠ” κ΄„ν˜Έμ™€ μ‚¬μΉ™μ—°μ‚°λ§Œ κ°€λŠ₯ν•˜λ©° λ‚˜λˆ„κΈ° μ—°μ‚°μ—μ„œ λ‚˜λ¨Έμ§€λŠ” λ¬΄μ‹œν•©λ‹ˆλ‹€.
  • μ΅œμ†Ÿκ°’μ΄ 8보닀 ν¬λ©΄ -1을 return ν•©λ‹ˆλ‹€.

μž…μΆœλ ₯ μ˜ˆ

5 12 4
2 11 3

 

✏️ 풀이

μ „ν˜•μ μΈ DP문제라고 μƒκ°ν–ˆλ‹€. 

 

λ¨Όμ € λ°°μ—΄(canMakeNum)을 ν•˜λ‚˜ μ„ μ–Έν–ˆλ‹€. 이 배열이 μ˜λ―Έν•˜λŠ” 것은 μΈλ±μŠ€λŠ” μ‚¬μš©ν•˜λŠ” 숫자의 개수이고, 각 μš”μ†ŒλŠ” Set 자료ꡬ쑰둜 λ˜μ–΄ μžˆμ–΄ λ§Œλ“€ 수 μžˆλŠ” 수λ₯Ό μ˜λ―Έν•œλ‹€. 처음 μ΄ˆκΈ°ν™”ν•  λ•Œ 숫자λ₯Ό 이어뢙인 수(λ§Œμ•½ μˆ«μžκ°€ 1, μ‚¬μš©ν•œ κ°œμˆ˜κ°€ 2라면 11)λ₯Ό 할당해쀬닀. κΈΈμ΄λŠ” 9인데 μ‚¬μš©ν•œ μˆ«μžκ°€ 8개λ₯Ό λ„˜μ–΄κ°€λ©΄ -1을 λ¦¬ν„΄ν•˜λΌλŠ” 쑰건이 μžˆμ—ˆκΈ° λ•Œλ¬Έμ΄λ‹€.

 

1λΆ€ν„° 8κΉŒμ§€ λ°˜λ³΅λ¬Έμ„ μˆ˜ν–‰ν•œλ‹€. μ΄λŠ” μ‚¬μš©ν•œ 숫자의 개수λ₯Ό μ˜λ―Έν•˜κ³  λ‚΄ λ‘œμ§μ€ λ§Œλ“€ 수 μžˆλŠ” μˆ«μžλ“€μ„ λͺ¨λ‘ λ§Œλ“€μ–΄ Set에 λ„£μ–΄μ£Όκ³  κ·Έ μ•ˆμ— λͺ©ν‘œλ‘œ ν•˜λŠ” μˆ«μžκ°€ μžˆλŠ”μ§€ ν™•μΈν•œλ‹€. 이 λ•Œ 계산법은 λ‹€μŒκ³Ό κ°™λ‹€.

 

  • 2λΌλŠ” 숫자λ₯Ό 1번 μ‚¬μš©ν–ˆμ„ λ•Œ: {2}
  • 2λΌλŠ” 숫자λ₯Ό 2번 μ‚¬μš©ν–ˆμ„ λ•Œ: {22, 4(2+2), 0(2-2), 1(2/2), 4(2*2)} -> {22, 4, 0, 1}

일 λ•Œ 숫자λ₯Ό 3번 μ‚¬μš©ν•΄μ„œ λ§Œλ“€ 수 μžˆλŠ” μˆ«μžλŠ” 1번 μ‚¬μš©ν–ˆμ„ λ•Œμ™€ 2번 μ‚¬μš©ν–ˆμ„ λ•Œμ˜ μš”μ†Œλ“€μ„ μ„œλ‘œ 사칙연산해주면 λœλ‹€.

 

  • 222
  • 22+2, 22-2, 22/2, 22*2
  • 4+2, 4-2, 4/2, 4*2
  • 0+2, 0-2, 0/2, 2*2
  • 1+2, 1-2, 1/2, 1*2

μˆœμ„œλŒ€λ‘œ λ‚˜μ—΄ν•˜λ©΄ {222, 24, 20, 11, 44, 6, 2, 2, 8, 2, -2, 0, 4, 3, -1, 0.5, 2} κ°€ λ˜λŠ”λ° μ—¬κΈ°μ„œ 쀑볡을 μ œκ±°ν•˜κ³ , λ‚˜λˆ—μ…ˆμ˜ λͺ«λ§Œ μ‚¬μš©ν•˜λ©΄ {222, 24, 20, 11, 44, 6, 2, 8, -2, 0, 3}κ°€ λœλ‹€.  

 

이 λ•Œ μ£Όμ˜ν•΄μ•Ό ν•˜λŠ” 것은 μœ„μ˜ 계산듀은 (2번 μ‚¬μš©ν–ˆμ„ λ•Œμ˜ 숫자) 사칙연산 (1번 μ‚¬μš©ν–ˆμ„ λ•Œμ˜ 숫자)둜 2번 μ‚¬μš©ν–ˆμ„ λ•Œμ˜ μˆ«μžλ“€μ΄ μ•žμ— λ‚˜μ˜€λŠ”λ° λ‚˜λˆ—μ…ˆμ΄λ‚˜ λΊ„μ…ˆμ€ 숫자의 영ν–₯을 λ°›κΈ° λ•Œλ¬Έμ— λ°˜λŒ€μ˜ 과정을 μ§„ν–‰ν•΄μ€˜μ•Ό ν•œλ‹€. ν˜„μž¬μ˜ μ˜ˆμ‹œμ—μ„œλŠ” μ˜ˆμ™Έκ°€ μ—†μœΌλ‚˜, λ‹€λ₯Έ μˆ˜μ—μ„œλŠ” λ‹€λ₯Ό 수 μžˆλ‹€.

 

  • 2+22, 2-22, 2/22, 2*22
  • 2+4, 2-4, 2/4, 2*4
  • 2+0, 2-0, 2/0, 2*0
  • 2+1, 2-1, 2/1, 2*2

λ§Œμ•½ 4번 μ‚¬μš©ν•œ 숫자λ₯Ό κ³„μ‚°ν•˜κΈ° μœ„ν•΄μ„œλŠ” λ‹€μŒκ³Ό 같은 과정을 κ±°μΉœλ‹€.

  • (1번 μ‚¬μš©ν•œ 숫자) 사칙연산 (3번 μ‚¬μš©ν•œ 숫자)
  • (2번 μ‚¬μš©ν•œ 숫자) 사칙연산 (2번 μ‚¬μš©ν•œ 숫자)
  • (3번 μ‚¬μš©ν•œ 숫자) 사칙연산 (1번 μ‚¬μš©ν•œ 숫자)

λ‚˜λŠ” μ΄λ•Œ 경우의 수λ₯Ό μ‘°κΈˆμ΄λΌλ„ 쀄이기 μœ„ν•΄ μŒμˆ˜λŠ” ν¬ν•¨ν•˜μ§€ μ•Šμ•˜λ‹€.

 

κ³„μ‚°λ˜μ–΄ λ§Œλ“€ 수 μžˆλŠ” 숫자λ₯Ό 담은 Set μžλ£Œκ΅¬μ‘°κ°€ μ™„μ„±λ˜λ©΄ λͺ©ν‘œλ‘œ ν•œ μˆ«μžκ°€ μžˆλŠ”μ§€ ν™•μΈν•˜κ³  μžˆλ‹€λ©΄ answerλ₯Ό μ‚¬μš©ν•œ 숫자둜 ν• λ‹Ήν•˜κ³  break μ‹œμΌœμ€¬λ‹€.

⌨️ μ½”λ“œ

function solution(N, number) {
  var answer = -1;
  if (N === number) return 1;
  const canMakeNum = [...Array(9)].map((_, i) => new Set([parseInt(String(N).repeat(i))]));

  for (let i = 1; i < 9; i++) {
    for (let j = 1; j < i + 1; j++) {
      for (const num1 of canMakeNum[j]) {
        for (const num2 of canMakeNum[i - j]) {
          canMakeNum[i].add(num1 + num2);
          canMakeNum[i].add(num1 * num2);
          if (num2) canMakeNum[i].add(Math.floor(num1 / num2));
          if (num1 - num2 > 0) canMakeNum[i].add(num1 - num2);
        }
      }
    }

    if (canMakeNum[i].has(number)) {
      answer = i;
      break;
    }
  }

  return answer;
}