
๋ฌธ์  ์ค๋ช
๊ฐ๋ฐํ ๋ด์์ ์ด๋ฒคํธ ๊ฐ๋ฐ์ ๋ด๋นํ๊ณ  ์๋ "๋ฌด์ง"๋ ์ต๊ทผ ์งํ๋ ์นด์นด์ค์ด๋ชจํฐ์ฝ ์ด๋ฒคํธ์ ๋น์ ์์ ์ธ ๋ฐฉ๋ฒ์ผ๋ก ๋น์ฒจ์ ์๋ํ ์๋ชจ์๋ค์ ๋ฐ๊ฒฌํ์์ต๋๋ค. ์ด๋ฐ ์๋ชจ์๋ค์ ๋ฐ๋ก ๋ชจ์ ๋ถ๋ ์ฌ์ฉ์๋ผ๋ ์ด๋ฆ์ผ๋ก ๋ชฉ๋ก์ ๋ง๋ค์ด์ ๋น์ฒจ ์ฒ๋ฆฌ ์ ์ ์ธํ๋๋ก ์ด๋ฒคํธ ๋น์ฒจ์ ๋ด๋น์์ธ "ํ๋ก๋" ์๊ฒ ์ ๋ฌํ๋ ค๊ณ  ํฉ๋๋ค. ์ด ๋ ๊ฐ์ธ์ ๋ณด ๋ณดํธ์ ์ํด ์ฌ์ฉ์ ์์ด๋ ์ค ์ผ๋ถ ๋ฌธ์๋ฅผ '' ๋ฌธ์๋ก ๊ฐ๋ ค์ ์ ๋ฌํ์ต๋๋ค. ๊ฐ๋ฆฌ๊ณ ์ ํ๋ ๋ฌธ์ ํ๋์ '' ๋ฌธ์ ํ๋๋ฅผ ์ฌ์ฉํ์๊ณ  ์์ด๋ ๋น ์ต์ ํ๋ ์ด์์ '*' ๋ฌธ์๋ฅผ ์ฌ์ฉํ์์ต๋๋ค.
"๋ฌด์ง"์ "ํ๋ก๋"๋ ๋ถ๋ ์ฌ์ฉ์ ๋ชฉ๋ก์ ๋งคํ๋ ์๋ชจ์ ์์ด๋๋ฅผ ์ ์ฌ ์์ด๋ ๋ผ๊ณ  ๋ถ๋ฅด๊ธฐ๋ก ํ์์ต๋๋ค.
์๋ฅผ ๋ค์ด, ์ด๋ฒคํธ์ ์๋ชจํ ์ ์ฒด ์ฌ์ฉ์ ์์ด๋ ๋ชฉ๋ก์ด ๋ค์๊ณผ ๊ฐ๋ค๋ฉด
| ์๋ชจ์ ์์ด๋ | 
|---|
| frodo | 
| fradi | 
| crodo | 
| abc123 | 
| frodoc | 
๋ค์๊ณผ ๊ฐ์ด ๋ถ๋ ์ฌ์ฉ์ ์์ด๋ ๋ชฉ๋ก์ด ์ ๋ฌ๋ ๊ฒฝ์ฐ,
| ๋ถ๋ ์ฌ์ฉ์ | 
|---|
| fr*d* | 
| abc1** | 
๋ถ๋ ์ฌ์ฉ์์ ๋งคํ๋์ด ๋น์ฒจ์์ ์ ์ธ๋์ด์ผ ์ผ ํ ์ ์ฌ ์์ด๋ ๋ชฉ๋ก์ ๋ค์๊ณผ ๊ฐ์ด ๋ ๊ฐ์ง ๊ฒฝ์ฐ๊ฐ ์์ ์ ์์ต๋๋ค.
| ์ ์ฌ ์์ด๋ | 
|---|
| frodo | 
| abc123 | 
| ์ ์ฌ ์์ด๋ | 
|---|
| frodo | 
| abc123 | 
์ด๋ฒคํธ ์๋ชจ์ ์์ด๋ ๋ชฉ๋ก์ด ๋ด๊ธด ๋ฐฐ์ด user_id์ ๋ถ๋ ์ฌ์ฉ์ ์์ด๋ ๋ชฉ๋ก์ด ๋ด๊ธด ๋ฐฐ์ด banned_id๊ฐ ๋งค๊ฐ๋ณ์๋ก ์ฃผ์ด์ง ๋, ๋น์ฒจ์์ ์ ์ธ๋์ด์ผ ํ ์ ์ฌ ์์ด๋ ๋ชฉ๋ก์ ๋ช๊ฐ์ง ๊ฒฝ์ฐ์ ์๊ฐ ๊ฐ๋ฅํ ์ง return ํ๋๋ก solution ํจ์๋ฅผ ์์ฑํด์ฃผ์ธ์.
| user_id | banned_id | result | 
|---|---|---|
| ["frodo", "fradi", "crodo", "abc123", "frodoc"] | ["frd", "abc1**"] | 2 | 
| ["frodo", "fradi", "crodo", "abc123", "frodoc"] | ["rodo", "rodo", "**"] | 2 | 
| ["frodo", "fradi", "crodo", "abc123", "frodoc"] | ["frd", "*rodo", "**", "**"] | 3 | 
์ ์ถ๋ ฅ ์์ ๋ํ ์ค๋ช
์ ์ถ๋ ฅ ์ #1
๋ฌธ์  ์ค๋ช ๊ณผ ๊ฐ์ต๋๋ค.
์ ์ถ๋ ฅ ์ #2
๋ค์๊ณผ ๊ฐ์ด ๋ ๊ฐ์ง ๊ฒฝ์ฐ๊ฐ ์์ต๋๋ค.
| ์ ์ฌ ์์ด๋ | 
|---|
| frodo | 
| crodo | 
| abc123 | 
| ์ ์ฌ ์์ด๋ | 
|---|
| frodo | 
| crodo | 
| abc123 | 
์ ์ถ๋ ฅ ์ #3
๋ค์๊ณผ ๊ฐ์ด ์ธ ๊ฐ์ง ๊ฒฝ์ฐ๊ฐ ์์ต๋๋ค.
| ์ ์ฌ ์์ด๋ | 
|---|
| frodo | 
| crodo | 
| abc123 | 
| frodoc | 
| ์ ์ฌ ์์ด๋ | 
|---|
| fradi | 
| crodo | 
| abc123 | 
| frodoc | 
| ์ ์ฌ ์์ด๋ | 
|---|
| fradi | 
| frodo | 
| abc123 | 
| frodoc | 
๋์ ํ์ด
function solution(user_id, banned_id) {
    // ๋ฐฐ์ด์ ๊ฐ ์์ ๋ณ ๋ฐด ๋นํ  ์ ์๋ ์ด์ฉ์
    const can = banned_id.map(banned => user_id.filter((user) => {
        if(banned.length !== user.length) return false
        
        for(let i = 0 ; i < banned_id.length ; i++) {
            if(banned[i] !== '*' && banned[i] !== user[i]) return false
        }
        return true
    }))
    
    // ์ ๋ต ๋ฆฌ์คํธ
    const ansList = {}
    
    const dfs = (idx = 0, already = []) => {
        // ๊ฒฝ์ฐ์ ์ ์์ ๊ฐ์์ก๋ค๋ฉด
        if(idx === can.length) {
            // ๋ฐฐ์ด์ ์ ๋ ฌํ๊ณ  key์ ๋ง๋ ๊ฐ์ true๋ก ์ ์ธ
            already.sort()
            ansList[already.join('')] = true
            return 
        }
        
        // ์์ง ๋ฐฉ๋ฌธํ์ง ์์๋ค๋ฉด ๋ฐฉ๋ฌธํ ๋ฐฐ์ด์ ์ฝ์
ํ๊ณ  ์ธ๋ฑ์ค๋ฅผ 1 ๋์
        can[idx].forEach(item => {
            if(!already.includes(item)) {
                dfs(idx+1, [...already, item])
            }
        })
    }
    dfs()
    // ์ ๋ฆฌ๋ ์ค๋ธ์ ํธ์ ํค ๊ฐ์ ๊ณ ์ ํ๋ฏ๋ก ๊ณ ์  ๊ฐ์ ๊ธธ์ด๋ฅผ return 
    return Object.keys(ansList).length
}