[๋ฌธ์ ์ค๋ช ]
๋ ์คํ ๋์ ์ด์ํ๋ ์ค์นดํผ๋ ์ฝ๋ก๋19๋ก ์ธํ ๋ถ๊ฒฝ๊ธฐ๋ฅผ ๊ทน๋ณตํ๊ณ ์ ๋ฉ๋ด๋ฅผ ์๋ก ๊ตฌ์ฑํ๋ ค๊ณ  ๊ณ ๋ฏผํ๊ณ  ์์ต๋๋ค.
๊ธฐ์กด์๋ ๋จํ์ผ๋ก๋ง ์ ๊ณตํ๋ ๋ฉ๋ด๋ฅผ ์กฐํฉํด์ ์ฝ์ค์๋ฆฌ ํํ๋ก ์ฌ๊ตฌ์ฑํด์ ์๋ก์ด ๋ฉ๋ด๋ฅผ ์ ๊ณตํ๊ธฐ๋ก ๊ฒฐ์ ํ์ต๋๋ค. ์ด๋ค ๋จํ๋ฉ๋ด๋ค์ ์กฐํฉํด์ ์ฝ์ค์๋ฆฌ ๋ฉ๋ด๋ก ๊ตฌ์ฑํ๋ฉด ์ข์ ์ง ๊ณ ๋ฏผํ๋ "์ค์นดํผ"๋ ์ด์ ์ ๊ฐ ์๋๋ค์ด ์ฃผ๋ฌธํ  ๋ ๊ฐ์ฅ ๋ง์ด ํจ๊ป ์ฃผ๋ฌธํ ๋จํ๋ฉ๋ด๋ค์ ์ฝ์ค์๋ฆฌ ๋ฉ๋ด๋ก ๊ตฌ์ฑํ๊ธฐ๋ก ํ์ต๋๋ค.
๋จ, ์ฝ์ค์๋ฆฌ ๋ฉ๋ด๋ ์ต์ 2๊ฐ์ง ์ด์์ ๋จํ๋ฉ๋ด๋ก ๊ตฌ์ฑํ๋ ค๊ณ  ํฉ๋๋ค. ๋ํ, ์ต์ 2๋ช
 ์ด์์ ์๋์ผ๋ก๋ถํฐ ์ฃผ๋ฌธ๋ ๋จํ๋ฉ๋ด ์กฐํฉ์ ๋ํด์๋ง ์ฝ์ค์๋ฆฌ ๋ฉ๋ด ํ๋ณด์ ํฌํจํ๊ธฐ๋ก ํ์ต๋๋ค.
์๋ฅผ ๋ค์ด, ์๋ 6๋ช
์ด ์ฃผ๋ฌธํ ๋จํ๋ฉ๋ด๋ค์ ์กฐํฉ์ด ๋ค์๊ณผ ๊ฐ๋ค๋ฉด,
(๊ฐ ์๋์ ๋จํ๋ฉ๋ด๋ฅผ 2๊ฐ ์ด์ ์ฃผ๋ฌธํด์ผ ํ๋ฉฐ, ๊ฐ ๋จํ๋ฉ๋ด๋ A ~ Z์ ์ํ๋ฒณ ๋๋ฌธ์๋ก ํ๊ธฐํฉ๋๋ค.)
์๋ ๋ฒํธ	์ฃผ๋ฌธํ ๋จํ๋ฉ๋ด ์กฐํฉ
1๋ฒ ์๋	A, B, C, F, G
2๋ฒ ์๋	A, C
3๋ฒ ์๋	C, D, E
4๋ฒ ์๋	A, C, D, E
5๋ฒ ์๋	B, C, F, G
6๋ฒ ์๋	A, C, D, E, H
๊ฐ์ฅ ๋ง์ด ํจ๊ป ์ฃผ๋ฌธ๋ ๋จํ๋ฉ๋ด ์กฐํฉ์ ๋ฐ๋ผ "์ค์นดํผ"๊ฐ ๋ง๋ค๊ฒ ๋  ์ฝ์ค์๋ฆฌ ๋ฉ๋ด ๊ตฌ์ฑ ํ๋ณด๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
์ฝ์ค ์ข
๋ฅ	๋ฉ๋ด ๊ตฌ์ฑ	์ค๋ช
์๋ฆฌ 2๊ฐ ์ฝ์ค	A, C	1๋ฒ, 2๋ฒ, 4๋ฒ, 6๋ฒ ์๋์ผ๋ก๋ถํฐ ์ด 4๋ฒ ์ฃผ๋ฌธ๋์ต๋๋ค.
์๋ฆฌ 3๊ฐ ์ฝ์ค	C, D, E	3๋ฒ, 4๋ฒ, 6๋ฒ ์๋์ผ๋ก๋ถํฐ ์ด 3๋ฒ ์ฃผ๋ฌธ๋์ต๋๋ค.
์๋ฆฌ 4๊ฐ ์ฝ์ค	B, C, F, G	1๋ฒ, 5๋ฒ ์๋์ผ๋ก๋ถํฐ ์ด 2๋ฒ ์ฃผ๋ฌธ๋์ต๋๋ค.
์๋ฆฌ 4๊ฐ ์ฝ์ค	A, C, D, E	4๋ฒ, 6๋ฒ ์๋์ผ๋ก๋ถํฐ ์ด 2๋ฒ ์ฃผ๋ฌธ๋์ต๋๋ค.
๊ฐ ์๋๋ค์ด ์ฃผ๋ฌธํ ๋จํ๋ฉ๋ด๋ค์ด ๋ฌธ์์ด ํ์์ผ๋ก ๋ด๊ธด ๋ฐฐ์ด orders, "์ค์นดํผ"๊ฐ ์ถ๊ฐํ๊ณ ์ถ์ดํ๋ ์ฝ์ค์๋ฆฌ๋ฅผ ๊ตฌ์ฑํ๋ ๋จํ๋ฉ๋ด๋ค์ ๊ฐฏ์๊ฐ ๋ด๊ธด ๋ฐฐ์ด course๊ฐ ๋งค๊ฐ๋ณ์๋ก ์ฃผ์ด์ง ๋, "์ค์นดํผ"๊ฐ ์๋ก ์ถ๊ฐํ๊ฒ ๋ ์ฝ์ค์๋ฆฌ์ ๋ฉ๋ด ๊ตฌ์ฑ์ ๋ฌธ์์ด ํํ๋ก ๋ฐฐ์ด์ ๋ด์ return ํ๋๋ก solution ํจ์๋ฅผ ์์ฑํด ์ฃผ์ธ์.
์กฐํฉ
์กฐํฉ์ ๋ชจ๋ ๊ฒฝ์ฐ์ ์๋ฅผ ์กฐํํ๋, ์ค๋ณต๋๋ ๊ฒฝ์ฐ์ ์๋ ์ ๊ฑฐํ๋ค
์๊ณ ๋ฆฌ์ฆ์ ๋ค์๊ณผ ๊ฐ์
function getCombination(arr,fixNum) {
  	// ์กฐํฉ์ ๋ด์ ๋ฐฐ์ด
	const results = []
    if(fixNum === 1) return arr.map(el => [el])
  	
  	arr.forEach((fixed,idx,origin) => {
    	const nextArr = origin.slice(idx+1)
        const combArr = getCombination(nextArr,fixNum-1)
        const fixAndCombArr = combArr.map(el => [fixed,...el])
        results.push(fixAndCombArr)
    })
  	return results
}
๋ชจ๋ ์กฐํฉ์ ์๊ฐ return๋๋ค.
์์ด
์์ด์ ๋ชจ๋ ๊ฒฝ์ฐ์ ์๋ฅผ ์กฐํํ๋, ์ค๋ณต๋๋ ๊ฒฝ์ฐ์ ์ ๋ํ ํฌํจํ๋ค.
์๊ณ ๋ฆฌ์ฆ์ ๋ค์๊ณผ ๊ฐ์
function getPermutation(arr,fixNum) {
  	// ์กฐํฉ์ ๋ด์ ๋ฐฐ์ด
	const results = []
    if(fixNum === 1) return arr.map(el => [el])
  	
  	arr.forEach((fixed,idx,origin) => {
      // ์กฐํฉ๊ณผ์ ์ฐจ์ด์ ์ ๋ค์ ์ธ์๋ก ๋๊ธธ ๋ฐฐ์ด์ ๊ธธ์ด
    	const nextArr = [...origin.slice(0,idx),...origin.slice(idx+1)]
        const perArr = getPermutation(nextArr,fixNum-1)
        const fixAndCombArr = perArr.map(el => [fixed,...el])
        results.push(fixAndCombArr)
    })
  	return results
}
๋ชจ๋ ์์ด์ ์๊ฐ return๋๋ค.

๋ฌธ์ ํ์ด
function getCombinations(arr,select) {
    let results = []
    if(select === 1) return arr.map(a => [a])
    
    arr.forEach((item,idx,origin) => {
        const outFix = origin.slice(idx+1)
        const combArr = getCombinations(outFix,select-1)
        const attach = combArr.map(el => [item,...el].join(""))
        results.push(...attach)
    })
    return results
}
function solution(orders, course) {
    // ์ ๋ต ๋ฐฐ์ด ์์ฑ
    const result = []
    // ๊ฐ๋ฅํ ๋ชจ๋  ๋ฉ๋ด๋ฅผ ๋ด์ ๋ฐฐ์ด ์์ฑ
    const allFoods = []
    // ๊ฐ ๋ฉ๋ด ๋ณ ํธ์ถ ํ์๋ฅผ ๋ด์ ๊ฐ์ฒด ์์ฑ
    const callFoods = {}
    // ๊ฐ ๋ฉ๋ด ์ซ์ ๋ณ ์ต๋๊ฐ
    let maxOrder = Array(course.length).fill(0)
    orders.forEach(a => {
        // a ๋ฅผ ์ค๋ฆ์ฐจ์ ๋ฌธ์์ด๋ก ๋ณ๊ฒฝ
        a = a.split('').sort()
        // ์ด๋ฒ ์ค๋์ ์์ ๋ฆฌ์คํธ๋ฅผ ๋ด์
        const nowFoods = []
        for(let i = a.length ; i > 1 ; i --) {
            getCombinations(a,i).map(el => {
                nowFoods.push(el)
            })
        }
        console.log(nowFoods)
        // ์ด๋ฒ ์ค๋์ ์ค๋ณต์ ์ ๊ฑฐํ๊ณ  ์ ์ฒด ์์ ๋ฆฌ์คํธ์ ํธ์
        nowFoods.filter((b,i) => nowFoods.indexOf(b) === i).forEach(c => allFoods.push(c))
    })
    // ๊ฐ ๋ฉ๋ด ๋ณ ํธ์ถ ํ์ ์ด๊ธฐํ
    allFoods.forEach(a => {
        callFoods[a] = 0
    })
    // ํธ์ถ ํ์ ์นด์ดํธ
    allFoods.forEach(a => {
        callFoods[a]++
    })
    // ๊ฐ ๋ฉ๋ด ์ซ์ ๋ณ ์ต๋ ๊ฐ ๊ตฌํ๊ธฐ
    for(const [key,val] of Object.entries(callFoods)) {
        val > maxOrder[course.indexOf(key.length)] ? maxOrder[course.indexOf(key.length)] = val : null 
    }
    // ๋๋ช
 ์ด์์ด ์ฃผ๋ฌธํ์ผ๋ฉฐ ์ฃผ๋ฌธ ์ฝ์ค์ ๊ธธ์ด๊ฐ course ๋ฐฐ์ด์ ์๋ orders ๋ฐฐ์ด์ key
    for(const [key,val] of Object.entries(callFoods)) {
        if(val >= 2 && course.includes(key.length) && val === maxOrder[course.indexOf(key.length)]) {
            result.push(key)
        }
    }
    return result.sort()
}