def get_len_divisor(n):
divisorsList = []
for i in range(1, int(n**(1/2)) + 1):
if (n % i == 0):
divisorsList.append(i)
if ((i**2) != n) :
divisorsList.append(n // i)
return len(divisorsList)
def solution(number, limit, power):
answer = 0
counts = []
for i in range(1, number + 1):
counts.append(get_len_divisor(i))
for i, c in enumerate(counts):
if c > limit:
counts[i] = power
else:
pass
return sum(counts)
def solution(cards1, cards2, goal):
answer = "Yes"
for g in goal:
if len(cards1) > 0 and g == cards1[0]:
cards1.pop(0)
elif len(cards2) > 0 and g == cards2[0]:
cards2.pop(0)
else:
answer = "No"
break
return answer
1. 입력과 목표의 관계 파악
cards1과 cards2는 각 단어가 순서대로 배열되어 있습니다.
goal을 순서대로 탐색하면서, 해당 단어가 cards1 또는 cards2의 맨 앞에 있는지 확인해야 합니다.
2. 구현 로직
goal 배열을 순회
goal의 각 단어를 하나씩 확인합니다.
현재 단어(current_word)를 가져옵니다.
cards1과 cards2의 첫 번째 단어 비교
cards1의 맨 앞 단어가 current_word와 같다면:
cards1의 첫 번째 단어를 제거합니다.
cards2의 맨 앞 단어가 current_word와 같다면:
cards2의 첫 번째 단어를 제거합니다.
둘 다 아니면:
goal을 만들 수 없으므로 "No"를 반환합니다.
모든 단어를 확인
goal 배열을 끝까지 순회했다면 "Yes"를 반환합니다.
3. 힌트: 카드 제거
cards1과 cards2에서 맨 앞의 단어를 확인하고 제거하는 동작이 필요합니다.
이를 위해 리스트의 첫 번째 요소를 읽고 제거하는 방식을 사용합니다.
4. 조건별 흐름 정리
단어 탐색:
current_word가 cards1[0]과 같으면:
cards1의 첫 번째 단어를 제거합니다.
아니고 current_word가 cards2[0]과 같으면:
cards2의 첫 번째 단어를 제거합니다.
둘 다 아니면:
"No"를 반환합니다.
반복 종료:
goal의 모든 단어를 처리했다면:
"Yes"를 반환합니다.
5. 반복문으로 처리
goal 배열을 하나씩 확인하고 처리합니다.
카드 뭉치의 맨 앞 단어와 비교하며, 일치하면 제거하고 다음 단어로 이동합니다.
6. 예제 분석
예제 1:
cards1: ["i", "drink", "water"]
cards2: ["want", "to"]
goal: ["i", "want", "to", "drink", "water"]
goal[0] = "i" → cards1에서 제거.
goal[1] = "want" → cards2에서 제거.
goal[2] = "to" → cards2에서 제거.
goal[3] = "drink" → cards1에서 제거.
goal[4] = "water" → cards1에서 제거.
모두 처리 → "Yes".
7. 구현 시 유의할 점
cards1과 cards2는 비어있을 수도 있으니 비교 전에 확인하세요.
goal을 모두 처리하면 "Yes"를 반환하세요.
*
```
if len(cards1) == 0 or len(cards2) == 0: continue
```
현재 코드에서 발생하는 문제는 cards1이나 cards2 중 하나가 비어있을 때 goal의 단어를 건너뛰는 것입니다. 이로 인해 원하는 로직이 제대로 실행되지 않습니다. 이 문제를 해결하기 위해 아래 내용을 고려해 보세요:
1. 조건 순서의 문제
if len(cards1) == 0 or len(cards2) == 0: 부분이 모든 경우를 건너뛰게 만듭니다.
사실 cards1 또는 cards2가 비어 있어도, 남은 단어들이 여전히 다른 리스트에 있는지 확인해야 합니다.
이 조건을 각 리스트가 비어 있는 경우에도 처리하도록 수정해야 합니다.
2. 리스트가 비어 있을 때 조건 추가
cards1 또는 cards2가 비어 있을 수 있습니다. 따라서 각각의 조건을 따로 처리해야 합니다.
예를 들어:
cards1이 비어 있는 경우: cards2[0]만 비교.
cards2가 비어 있는 경우: cards1[0]만 비교.
3. 수정할 조건의 흐름
goal의 현재 단어(g)가 cards1[0]과 같다면:
cards1의 첫 번째 단어를 제거합니다.
goal의 현재 단어가 cards2[0]과 같다면:
cards2의 첫 번째 단어를 제거합니다.
두 리스트가 모두 비어 있을 경우를 따로 건너뛰지는 않도록 해야 합니다.
4. 중요한 점
cards1.remove(g) 대신 pop(0)을 사용하세요.
remove는 리스트에서 해당 값을 찾아 제거하는 데 시간 복잡도가 O(n)이라 비효율적입니다.
pop(0)은 첫 번째 값을 제거하므로 문제의 요구사항에 맞고, 논리적으로도 더 깔끔합니다.
cards1이나 cards2가 비어 있는 경우에도 오류가 나지 않도록 각각의 조건을 개별적으로 처리해야 합니다.
지금 코드에서 발생하는 문제는 answer의 값을 "No"로 설정한 뒤에도 반복문이 계속 진행되고, 마지막에 answer = "Yes"로 덮어쓰여지는 데에 있습니다. 이로 인해 원하는 조건이 충족되지 않았음에도 불구하고 "Yes"가 반환됩니다.
문제의 원인
else 블록에서 answer = "No"로 설정했지만, continue를 사용하면서도 루프가 끝날 때 마지막에 answer = "Yes"가 실행됩니다.
반복문이 끝날 때까지 모든 조건을 만족했는지 확인하지 않고, 무조건 "Yes"로 설정하기 때문에 잘못된 결과가 나옵니다.
해결 방법
반복문을 즉시 종료
goal 배열을 처리하다가 조건을 만족하지 않는 경우, 더 이상 확인할 필요가 없으므로 즉시 "No"를 반환해야 합니다.
continue가 아닌, return "No"를 사용하면 문제를 해결할 수 있습니다.
answer 변수를 제거
불필요하게 answer를 계속 업데이트할 필요가 없습니다.
조건이 만족되지 않는 경우 바로 "No"를 반환하고, 반복문을 끝까지 수행했다면 "Yes"를 반환하면 됩니다.
def solution(dartResult):
answer = 0
temp = []
opts = []
cnt = 0 # 현재 몇 번째 점수인지 추적
# Step 1: 문자열 파싱
for i in dartResult:
if i.isalpha():
a = dartResult[:((dartResult.index(i)) + 1)]
temp.append(a)
dartResult = dartResult.replace(a, '', 1) # 첫 번째 등장만 제거
cnt += 1
elif i in '#*':
dartResult = dartResult.replace(i, '', 1) # 첫 번째 등장만 제거
opts.append((i, cnt - 1)) # 옵션과 대상 점수의 인덱스를 저장
# Step 2: 점수 계산
calcul = []
for value in temp:
if len(value) > 1:
nums, bonus = int(value[:-1]), value[-1]
if bonus == 'S':
nums = nums ** 1
elif bonus == 'D':
nums = nums ** 2
elif bonus == 'T':
nums = nums ** 3
calcul.append(nums)
# Step 3: 옵션 처리
for opt, idx in opts:
if opt == '*':
calcul[idx] *= 2
if idx > 0: # 이전 점수도 2배
calcul[idx - 1] *= 2
elif opt == '#':
calcul[idx] *= -1
# Step 4: 최종 합산
answer = sum(calcul)
return answer
세상에 나쁜 코드는 없다....
< 다른 풀이 법>
def solution(dartResult):
import re
# Step 1: 정규식으로 점수|보너스|[옵션] 패턴을 추출
pattern = r"(\d+)([SDT])([*#]?)"
matches = re.findall(pattern, dartResult)
# Step 2: 계산 로직 구현
scores = []
for i, (num, bonus, option) in enumerate(matches):
# 점수 계산
num = int(num)
if bonus == 'S':
num **= 1
elif bonus == 'D':
num **= 2
elif bonus == 'T':
num **= 3
# 옵션 처리
if option == '*':
num *= 2
if i > 0: # 이전 점수가 있다면 그것도 2배
scores[i-1] *= 2
elif option == '#':
num *= -1
scores.append(num)
# 총점 계산
return sum(scores)
정규식 패턴 설명
pattern = r"(\d+)([SDT])([*#]?)"
\d+:
\d는 숫자(0~9)를 의미합니다.
+는 숫자가 1개 이상 연속으로 나타날 수 있음을 의미합니다.
예: "10", "5", "1" 등 숫자로 된 점수를 추출합니다.
([SDT]):
대괄호 [ ] 안에 S, D, T를 넣어 S, D, T 중 하나를 찾습니다.
각 문자는 Single(S), Double(D), Triple(T)을 의미하며, 점수를 몇 제곱할지 결정합니다.
괄호 ( )는 이 부분을 그룹화하여 나중에 결과로 추출하게 합니다.
([*#]?):
대괄호 [ ] 안에 *, #를 넣어 이들 중 하나를 찾습니다.
?는 해당 부분이 0개 또는 1개 있을 수 있음을 의미합니다.
즉, 옵션이 없을 수도 있고, *나 # 중 하나가 있을 수도 있습니다.
괄호 ( )는 이 부분을 그룹화하여 나중에 결과로 추출하게 합니다.
re.findall 설명
python
코드 복사
matches = re.findall(pattern, dartResult)
re.findall 함수는 주어진 정규식 pattern을 문자열 dartResult에 적용하여, 모든 일치하는 부분을 리스트로 반환합니다.
def solution(keymaps, targets):
answer = []
keyboard = {}
for keymap in keymaps:
for i, value in enumerate(keymap):
if value not in keyboard:
keyboard[value] = i + 1
else:
keyboard[value] = min(keyboard[value], i + 1)
for target in targets:
ans = 0
for t in target:
if t in keyboard:
ans += keyboard[t]
else:
ans = -1
answer.append(ans)
return answer
테스트 케이스 14번 부터 틀렸다.
여러 반례를 추가해 보다 아래 케이스에서 오류가 나는 것 발견
["ABCE"], ["ABDE"], [-1]
["BC"], ["AC", "BC"], [-1, 3]
키보드에 없는 알파벳이 나오면 그대로 종료해야하는데 계속 값을 더해주고 있었다.
아래는 수정 코드
def solution(keymaps, targets):
answer = []
keyboard = {}
for keymap in keymaps:
for i, value in enumerate(keymap):
if value not in keyboard:
keyboard[value] = i + 1
else:
keyboard[value] = min(keyboard[value], i + 1)
for target in targets:
ans = 0
for t in target:
if t in keyboard:
ans += keyboard[t]
else:
ans = -1
break
answer.append(ans)
return answer
문자별 최소 키 입력 횟수 저장:
먼저 keymap을 순회하면서 각 문자가 등장할 때 필요한 키 입력 횟수를 계산해 저장해.
이 정보를 딕셔너리에 저장하면 매번 계산하지 않아도 되고 빠르게 조회할 수 있어.
여러 개의 keymap 처리:
같은 문자가 여러 keymap에 존재할 경우, 가장 적은 입력 횟수를 저장해야 해.
예를 들어, 'A'가 첫 번째 keymap에서 1번, 두 번째 keymap에서 3번에 등장한다면, 1을 저장해야 해.
문자열 작성 가능 여부 판단:
targets의 각 문자열에 대해, 해당 문자를 키보드에서 찾을 수 없으면 바로 -1을 결과로 저장해야 해.