본문 바로가기
알고리즘 문제 풀이/Programmers

[9회차]

by 중앙백 2021. 12. 13.

Programmers Level.2 N개의 최소공배수

import math

def solution(arr):
    answer = 1
    for ar in arr:
        answer = answer * ar // math.gcd(answer,ar)
    return answer

 

 

Programmers Level.2 뉴스 클러스터링

def solution(str1, str2):
    answer = 0
    str1 = str1.upper()
    str2 = str2.upper()
    list1 = {}
    list2 = {}
    h = ''
    for i in range(len(str1)):
        if h == '':
            h = str1[i]
        else:
            h = h[-1] + str1[i]
            if h.isalpha():
                if h not in list1:
                    list1[h] = 1
                else:
                    list1[h] += 1
    h = ''
    for i in range(len(str2)):
        if h == '':
            h = str2[i]
        else:
            h = h[-1] + str2[i]
            if h.isalpha():
                if h not in list2:
                    list2[h] = 1
                else:
                    list2[h] += 1
    uni_dicts = {}
    for i in list1:
        if i in list2:
            uni_dicts[i] = min(list1[i],list2[i])
    if list1 == {} and list2 == {}:
        return 65536
    answer = int(sum(uni_dicts.values())/(sum(list1.values())+sum(list2.values())-sum(uni_dicts.values())) * 65536)
    return answer

 - 내가 푼 풀이는 복잡하다는 생각이 들었다. 공부를 위해 다른 사람의 풀이를 공부했다. 아래는 그 풀이 중 하나이다.

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)

 - 정규식과 집합을 활용한 풀이다. 좋은 공부가 됐다.

 

 

Programmers Level.2 튜플

import re
from collections import Counter


def solution(s):
    numbers = re.findall(r'\d+', s)
    a = Counter(numbers)
    a = sorted(a.items(),key=lambda x:x[1], reverse=True)
    answer = []
    for i in a:
        answer.append(int(i[0]))
    return answer

 - 정규식과 카운터 모듈을 이용해보려고 구글에서 검색해가며 풀었다. 다른 사람은 더 짧게 프로그래밍 했길래 참고 삼아 아래에 적어본다.

def solution(s):

    s = Counter(re.findall('\d+', s))
    return list(map(int, [k for k, v in sorted(s.items(), key=lambda x: x[1], reverse=True)]))

import re
from collections import Counter

 

 

Programmers Level.2 구명보트

def solution(people, limit):
    answer = 0
    people = sorted(people)
    while people:
        person = people.pop()
        if len(people) > 0 and person + people[0] <= limit:
            people.pop(0)
        answer += 1
    return answer

 - 효율성 테스트 1에서 실패. 다른 효율성 테스트 문항에서도 시간이 수십 ms밖에 안되는데 왜 실패하는걸까..

 - pop(0)이 비효율적이라는 이야기를 들은 적이 있어서 deque를 사용해 구현했더니 정답.

from collections import deque

def solution(people, limit):
    answer = 0
    people = deque(sorted(people))
    while people:
        person = people.pop()
        if len(people) > 0 and person + people[0] <= limit:
            people.popleft()
        answer += 1
    return answer

 

 

 

Programmers Level.2 교점에 별 만들기

from itertools import combinations


def find_gyo(line1, line2):
    a, b, c = line1
    d, e, f = line2
    if a*e - d*b == 0:
        return
    x = -(e*c-b*f)/(a*e-d*b)
    y = -(-d*c+a*f)/(a*e-d*b)
    if x.is_integer() & y.is_integer():
        return [int(x), int(y)]


def solution(line):
    dot_list = []
    answer = []
    for i, j in combinations(line, 2):
        if find_gyo(i,j) and find_gyo(i, j) not in dot_list:
            dot_list.append(find_gyo(i,j))
    minx = min(dot_list, key=lambda x: x[0])[0]
    miny = min(dot_list, key=lambda x: x[1])[1]
    maxx = max(dot_list, key=lambda x:x[0])[0]
    maxy = max(dot_list, key=lambda x:x[1])[1]
    graph = [['.'] * (maxx - minx + 1) for _ in range(maxy - miny + 1)]
    for dot in dot_list:
        graph[maxy - dot[1]][dot[0] - minx] = '*'
    for gra in graph:
        answer.append(''.join(gra))
    return answer

 - 연립 방정식을 풀어서 정수해를 구하는데 까지는 쉬웠다.

 - y축 방향으로는 역순으로 점을 찍어야 한다는 것을 알아채지 못해서 시간이 걸렸다.

 

 

 

Programmers Level.2 숫자의 표현

def solution(n):
    answer = 0
    lists = [(i + 1)*i//2 for i in range(0, n + 1)]
    a = 0
    b = 1
    while b <= n:
        if lists[b] - lists[a] == n:
            answer += 1
            b += 1
            a += 1
        elif lists[b] - lists[a] < n:
            b += 1
        else:
            a += 1
    return answer

 

 

Programmers Level.2 주식가격

def solution(prices):
    answer = [0] * len(prices)
    for i in range(len(prices)):
        j = i + 1
        while j < len(prices):
            if prices[i] <= prices[j]:
                j += 1
            else:
                j += 1
                break
        answer[i] = j - i - 1
    return answer

 

 

Programmers Level.2 이진 변환 반복하기

def trans_bin(x, zero, cnt):
    y = ''
    for i in x:
        if i == '0':
            zero += 1
        else:
            y += i
    cnt += 1
    return bin(len(y))[2:], zero, cnt


def solution(s):
    answer = []
    zero = 0
    cnt = 0
    while s != '1':
        s, zero, cnt = trans_bin(s, zero, cnt)
    return [cnt, zero]

 

 

Programmers Level.2 다음 큰 숫자

def solution(n):
    n = bin(n)[2:]
    pos = 0
    one_cnt = 0
    if n[-1] == '0': # 0으로 시작했을 때
        for i in range(len(n)-1,-1,-1):
            if n[i] == '0' and one_cnt > 0:
                pos = i + 1 # 1이 나온다면 1이 끝나는 위치 기록
                break
            if n[i] == '1':
                one_cnt += 1 # 1 개수 세기
    if n[-1] == '1':
        for i in range(len(n)-1,-1,-1):
            if n[i] == '0':
                pos = i + 1 # 오른쪽 부터 살펴봤을 때 마지막 1 위치 기록
                break
            one_cnt += 1 # 1 개수 세기
    if pos == 0:
        answer = '1' + '0'* (len(n) + 1- one_cnt) + '1'*(one_cnt - 1)
    else:
        answer = n[:pos-1] + '10' + '0'*(len(n)-pos-one_cnt) + '1'*(one_cnt-1)
    answer = int(answer, 2)
    return answer

 

 - 음... 나는 문자열에서 0개수 1개수를 직접 세고 다음 큰 숫자를 직접 만들어냈는데... 훨씬 간단한 풀이가 있더라

def solution(n):
    num1 = bin(n).count('1')
    while True:
        n = n + 1
        if num1 == bin(n).count('1'):
            break
    return n

 - 왜 이런 생각을 못했을까... 아직 내 실력이 부족하다는 뜻이겠지.

'알고리즘 문제 풀이 > Programmers' 카테고리의 다른 글

[11회차]  (0) 2021.12.15
[10회차]  (0) 2021.12.14
[8회차]  (0) 2021.12.12
[7회차]  (0) 2021.12.10
[6회차]  (0) 2021.12.09

댓글