2025. 3. 15. 13:55ㆍ프로그래머스/LV.2
문제링크: 모음사전
문제설명
사전에 알파벳 모음 'A', 'E', 'I', 'O', 'U'만을 사용하여 만들 수 있는, 길이 5 이하의 모든 단어가 수록되어 있습니다. 사전에서 첫 번째 단어는 "A"이고, 그다음은 "AA"이며, 마지막 단어는 "UUUUU"입니다.
단어 하나 word가 매개변수로 주어질 때, 이 단어가 사전에서 몇 번째 단어인지 return 하도록 solution 함수를 완성해주세요.
제한조건
- word의 길이는 1 이상 5 이하입니다.
- word는 알파벳 대문자 'A', 'E', 'I', 'O', 'U'로만 이루어져 있습니다.
문제풀이
permutation은 중복을 허용하지 않기 때문에 리스트에 각 문자를 5개씩 넣어줬다.
조합을 구해서 리스트에 추가하는 부분에서 append를 써서
TypeError: sequence item 0: expected str instance, tuple found
오류가 났었다.
♣ append()와 extend()의 차이점
🔹 append(): 리스트에 그 자체로 추가
- 리스트 안에 리스트가 들어감
- append()는 하나의 객체를 통째로 추가함.
🔹 extend(): 리스트를 개별 요소로 풀어서 추가
- 리스트 안에 리스트가 아니라, 개별 원소가 추가됨
- extend()는 반복 가능한(iterable) 객체를 풀어서 추가함.
🔹 append() vs extend() 차이점 요약
메서드 동작 방식 예제 결과
append(x) | 리스트에 그 자체로 추가 | lst.append([4, 5]) | [1, 2, 3, [4, 5]] |
extend(x) | 리스트를 개별 요소로 풀어서 추가 | lst.extend([4, 5]) | [1, 2, 3, 4, 5] |
🔥 문제에서 append()를 사용하면 안 되는 이유
per = []
for i in range(1, 6):
per.append(product(alpha, repeat=i)) # ❌ 잘못된 코드
🚨 이렇게 하면 per에 product()의 객체가 리스트로 들어감.
즉, per 안에는 [<itertools.product object at 0x...>] 같은 값이 들어가게 됨.
✔ 올바른 코드 (extend() 사용)
🎯 결론
- append() → 리스트 자체를 요소로 추가
- extend() → 리스트를 개별 요소로 풀어서 추가
- 순열이나 조합을 리스트에 추가할 때는 extend()를 써야 한다!
그리고 alpha=['A','E','I','O','U']*5 이렇게 리스트로 말고
alpha='AEIOU' * 5 문자열로 줘도 됨. => 반복 가능한 객체라
나의코드
from itertools import permutations
def solution(word):
answer = 0
alpha=['A','E','I','O','U']*5 # 중복 허용 조합을 만들기 위해
per=[] # 조합
# result=[] # 문자열
for i in range(1,6):
per.extend(permutations(alpha,i))
result=list(set(''.join(p) for p in per))
result.sort()
answer=result.index(word)
return answer+1 # 몇번째이기 때문에 인덱스 +1
참고하기
from itertools import product
def solution(word):
vowels = "AEIOU"
# 길이 1~5까지 가능한 모든 단어 생성
dictionary = []
for i in range(5):
for comb in product(vowels, repeat=i+1): # 길이가 i+1인 모든 조합 생성
dictionary.append("".join(comb))
# 사전순 정렬
dictionary.sort()
# 입력된 단어의 위치 반환 (0부터 시작하므로 +1)
return dictionary.index(word) + 1
product를 이용하여 푼 풀이
📌 itertools.product() 정리
🔹 역할:
- 주어진 문자열에서 **중복을 허용한 모든 순열(중복 순열, 데카르트 곱)**을 생성
🔹 사용법:
from itertools import product
vowels = "AEIOU"
list(product(vowels, repeat=2))
✅ 결과:
[('A', 'A'), ('A', 'E'), ('A', 'I'), ..., ('U', 'U')]
➡ "AA", "AE", "AI", ..., "UU" 형태로 변환 가능
🔹 코드에서의 역할:
for i in range(5):
for comb in product(vowels, repeat=i+1):
dictionary.append("".join(comb))
✔ 길이가 1~5인 모든 단어를 생성하여 리스트에 추가
✔ 사전순 정렬 후 인덱스로 단어 순서 찾기
🔹 비교:
함수 중복 허용 순서 고려 예제(AB, repeat=2) 결과product() | ✅ | ✅ | product("AB", repeat=2) | AA, AB, BA, BB |
permutations() | ❌ | ✅ | permutations("AB", 2) | AB, BA |
combinations() | ❌ | ❌ | combinations("AB", 2) | AB |
👉 product()는 중복 허용 & 순서 고려하는 "중복 순열" 생성 함수!
def solution(word):
answer = 0
for i, n in enumerate(word):
answer += (5 ** (5 - i) - 1) / (5 - 1) * "AEIOU".index(n) + 1
return answer
🛠 핵심 아이디어
- 각 자리에서 알파벳(A, E, I, O, U)이 가질 수 있는 조합 개수를 이용해 위치를 계산
- A, E, I, O, U는 각각 0, 1, 2, 3, 4의 인덱스를 가짐
- 이를 기반으로 자리값을 반영해 가중치를 계산
🔎 코드 분석
def solution(word):
answer = 0
for i, n in enumerate(word): # word의 각 문자에 대해 반복
answer += (5 ** (5 - i) - 1) / (5 - 1) * "AEIOU".index(n) + 1
return answer
📌 변수 정리
변수 설명word | 주어진 단어 |
i | 현재 문자(알파벳)의 위치 (0부터 시작) |
n | 현재 문자 (A, E, I, O, U 중 하나) |
"AEIOU".index(n) | 현재 문자가 A, E, I, O, U 중 몇 번째인지 (0~4) |
💡 숫자 계산 방식
주어진 단어가 몇 번째인지 구하는 방식은 각 자리값에 따른 가중치를 더하는 방식입니다.
1️⃣ (5⁵ - 1) / (5 - 1)
- 자리값에 따라 앞에 얼마나 많은 단어가 있는지 결정하는 등비수열 합 공식
- 5⁵ - 1 / 5 - 1 = 781
→ 예를 들어, 첫 번째 문자가 바뀔 때마다 781개씩 이동
2️⃣ 자리별 계산
- "AEIOU".index(n) : 현재 문자의 인덱스를 가져옴 (A = 0, E = 1, ...)
- 위치별 가중치 계산
- 첫 번째 자리 → 781 * 인덱스
- 두 번째 자리 → 156 * 인덱스
- 세 번째 자리 → 31 * 인덱스
- 네 번째 자리 → 6 * 인덱스
- 다섯 번째 자리 → 1 * 인덱스
3️⃣ +1 보정
- 모든 단어의 위치는 1부터 시작하므로, 각 자리에서 +1을 추가
✨ 예제 계산
🔹 word = "EIO"
문자 자리(i) "AEIOU".index(n) 가중치 계산 결과E | 0 | 1 | 781 * 1 + 1 | 782 |
I | 1 | 2 | 156 * 2 + 1 | 314 |
O | 2 | 3 | 31 * 3 + 1 | 94 |
합계 | 1190 |
🔹 따라서 "EIO"는 1190번째 단어임!
🎯 최종 요약
- 각 자리(A, E, I, O, U)에 따른 가중치(781, 156, 31, 6, 1)를 곱하여 계산
- "AEIOU".index(n)을 사용하여 알파벳의 위치를 찾음
- 각 자리의 값을 합산하여 최종 순서(answer)를 구함
- 최종 결과를 1부터 시작하는 순번으로 반환
def solution(word):
preset = dict()
preset['A'] = [1,1,1,1,1]
preset['E'] = [782,157,32,7,2]
preset['I'] = [1563,313,63,13,3]
preset['O'] = [2344,469,94,19,4]
preset['U'] = [3125,625,125,25,5]
######### 사전이므로 idx4부터 따라올라가면
########## preset 산출가능함
ans=0
for idx, key in enumerate(word):
ans+=preset[key][idx]
return ans
'프로그래머스 > LV.2' 카테고리의 다른 글
[프로그래머스][LV.2] 조이스틱 | python3 (0) | 2025.03.18 |
---|---|
[프로그래머스][LV.2] 전력망을 둘로 나누기 | python3 (0) | 2025.03.16 |
[프로그래머스][LV.2] 소수 찾기 | python3 (0) | 2025.03.14 |
[프로그래머스][LV.2] 카펫 | python3 (0) | 2025.03.14 |
[프로그래머스][LV.2] 더 맵게 | python3 (0) | 2025.03.12 |