https://school.programmers.co.kr/learn/courses/30/lessons/17677
2018 KAKAO BLIND RECRUITMENT
from collections import Counter
def solution(str1, str2):
s1 = [ str1.lower()[i:i+2] for i in range(len(str1)-1) ]
s2 = [ str2.lower()[i:i+2] for i in range(len(str2)-1) ]
s1_clear = [s for s in s1 if s.isalpha()]
s2_clear = [s for s in s2 if s.isalpha()]
union = 0
intersection = 0
c1 = Counter(s1_clear)
c2 = Counter(s2_clear)
for s in set(s1_clear + s2_clear):
try: # s가 둘 다 있으면
union += max(c1[s], c2[s])
intersection += min(c1[s], c2[s])
except: # s가 한 쪽이라도 없으면
if s in c1:
union += c1[s]
else:
union += c2[s]
try:
return int(intersection/union*65536)
except:
return 65536
- List Comprehension으로 2글자씩 자른 소문자를 s1, s2에 저장
- s1과 s2에서
isalpha()
를 이용해서 영어인 것만 s1_clear, s2_clear에 저장- s1_clear와 s2_clear의 Counter 객체 저장 (각 문자와 그 문자의 빈도가 저장)
- 두 Counter 객체를 합친 것의 집합을 반복문을 돌림
- 둘 다 있으면 try 동작, 한 쪽만 있으면 except 동작
- 만약 0으로 나누는 상황이 나오면 except의 return 동작
차근차근해보니까 풀렸다.
처음에 정규표현식으로 시도했는데 isalpha()
를 사용해도 간단할 것 같았음
타인 코드
import re
import math
def solution(str1, str2):
str1 = [str1[i:i+2].lower() for i in range(0, len(str1)-1) if not re.findall('[^a-zA-Z]+', str1[i:i+2])]
str2 = [str2[i:i+2].lower() for i in range(0, len(str2)-1) if not re.findall('[^a-zA-Z]+', str2[i:i+2])]
gyo = set(str1) & set(str2)
hap = set(str1) | set(str2)
if len(hap) == 0 :
return 65536
gyo_sum = sum([min(str1.count(gg), str2.count(gg)) for gg in gyo])
hap_sum = sum([max(str1.count(hh), str2.count(hh)) for hh in hap])
return math.floor((gyo_sum/hap_sum)*65536)
set()끼리 %, |
를 사용한 아이디어가 신선했다.
이렇게 하니까 count() 함수로 쉽게 계산이 되네
하나 알아간다!