def solution(board, moves):
answer = 0
stack, new_b = [], []
y:int = len(board)
for i in range(y):
new_b.append([b[i] for b in board if b[i]])
for move in moves:
if new_b[move-1]:
toy = new_b[move-1].pop(0)
if stack and toy == stack[-1]:
stack.pop()
answer += 2
else:
stack.append(toy)
return answer
바구니에 인형을 담는 다는 것에서
스택
을 이용해야겠다고 생각했다. 처음에는 이중for
문을 사용해서 풀었는데 시간 초과가 나서 코드를 수정했다.board
에 들어있는 값중 인형이 들어 있지 않는0
값은 제외하고 리스트를 행 기준에서 열 기준으로 바꿨다. 그래서 속도가 조금 빨라졌다.
def solution(board, moves):
basket = []
result = 0
for move in moves:
for i in range(0, len(board)):
dolls = board[i]
if dolls[move-1] == 0:
pass
else:
basket.append(dolls[move-1])
dolls[move-1] = 0
if len(basket) > 1 and basket[-2] == basket[-1]:
basket.pop()
basket.pop()
result += 2
break
else:
break
return result
이 코드는 알고리즘을 공부하기 전, 옛날에 풀었던 코드다. 확실히 이때에 비해 코드가 간결해졌다.
import re
def dot(new_id:str):
if new_id and new_id[0] == '.':
new_id = new_id[1:]
if new_id and new_id[-1] == '.':
new_id = new_id[:-1]
return new_id
def solution(new_id):
new_id = re.sub('[^a-z0-9-_.]','', new_id.lower()) # 1 & 2
while '..' in new_id: # 3
new_id = new_id.replace('..','.')
new_id = dot(new_id) # 4
if not new_id: # 5
new_id = 'a'
if len(new_id) >= 16: # 6
new_id = new_id[:15]
new_id = dot(new_id)
while len(new_id) < 3: # 7
new_id += new_id[-1]
return new_id
while
문을 사용하여..
을 줄이는 건 좋았는데 나머지 코드들은 뭔가 마음에 들지 않았다.
def solution(participant:list, completion:list) -> str:
participant.sort()
completion.sort()
for i in range(len(completion)):
if participant[i] != completion[i]:
return participant[i]
return participant[-1]
정렬을 한 상태에서
participant
와completion
을 비교하여 다르면participant
값을 리턴한다. 만약 다른 값이 없다면,participant
의 마지막 값이 정답이다.
def solution(answers):
solv = [0,0,0]
f, s, t = list(range(1,6))*2000, [2,1,2,3,2,4,2,5]*(10000//8+1), [3,3,1,1,2,2,4,4,5,5]*1000
tmp = list(zip(f,s,t))
for i,v in enumerate(answers):
for j,w in enumerate(tmp[i]):
if w == v:
solv[j] += 1
answer = [i+1 for i,v in enumerate(solv) if v == max(solv)]
return answer
f
,s
,t
를 순환을 돌리고 싶은데 방법이 생각안나 최대범위인10000
개로 만들었다. 그 뒤로zip
을 통해 문제 1번의 세명의 정답 순으로 만들어 비교했다.
def solution(answers):
solv = [0,0,0]
f, s, t = list(range(1,6)), [2,1,2,3,2,4,2,5], [3,3,1,1,2,2,4,4,5,5]
for i,v in enumerate(answers):
if v == f[i%len(f)]:
solv[0] += 1
if v == s[i%len(s)]:
solv[1] += 1
if v == t[i%len(t)]:
solv[2] += 1
answer = [i+1 for i,v in enumerate(solv) if v == max(solv)]
return answer
다른 사람들의 풀이를 보니 이렇게 패턴의 수를 나눠 나머지 값으로 순환을 시키면 된다. 왜 이 생각을 못 했을까...?😅
from itertools import cycle
def solution(answers):
solv = [0,0,0]
f, s, t = cycle(range(1,6)), cycle([2,1,2,3,2,4,2,5]), cycle([3,3,1,1,2,2,4,4,5,5])
for i,v in enumerate(answers):
if v == next(f):
solv[0] += 1
if v == next(s):
solv[1] += 1
if v == next(t):
solv[2] += 1
answer = [i+1 for i,v in enumerate(solv) if v == max(solv)]
return answer
cycle
을 사용하면iterable
한 객체를 더 쉽게 순환시킬 수 있다.itertools
가iterable
객체에 엄청나게 다양한 기능을 제공한다는 것을 새삼 다시 한번 느꼈다.
참고로itertools
모듈은 리턴값은 항상iterable
객체라는 것을 기억하자.
Reference
def solution(n, lost, reserve):
real_lost = set(lost) - set(reserve)
real_reserve = set(reserve) - set(lost)
answer = n-len(real_lost)
for i in sorted(real_lost):
if i+1 in real_reserve:
real_reserve.remove(i+1)
answer += 1
elif i-1 in real_reserve:
real_reserve.remove(i-1)
answer += 1
return answer
문제 조건에
여벌을 가져왔지만, 도난당한 친구는 체육복을 빌려줄 수 없다
부분을 구현하기 위해lost
와reserve
의 교집합을set
을 이용해 모두 빼주었다.
그리고for
문을 사용하기 전에real_lost
를 정렬해주어 앞에서 부터 순서대로 비교하도록 구현했다.
def solution(n, lost, reserve):
real_lost = [l for l in lost if l not in reserve]
real_reserve = [r for r in reserve if r not in lost]
answer = n-len(real_lost)
for i in sorted(real_lost):
if i+1 in real_reserve:
real_reserve.remove(i+1)
answer += 1
elif i-1 in real_reserve:
real_reserve.remove(i-1)
answer += 1
return answer
앞서
set
을 이용한 코드를 위처럼 컴프리헨션으로도 구현할 수 있다.
def solution(array, commands):
return [ sorted(array[i-1:j])[k-1] for i, j, k in commands ]
파이썬의 강점 덕분이겠지만, 너무나도 쉬운 문제.
def solution(a, b):
days = ['THU', 'FRI', 'SAT', 'SUN', 'MON', 'TUE', 'WED']
month_day = [0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
return days[(sum(month_day[:a])+b)%7]
백준에서 똑같은 문제를 풀었던 기억이 난다. 그때 당시에는 꽤 시간을 들여 고민했었는데, 이제는 바로 코드로 구현할 수 있다. 공부를 내가 열심히 했긴 했구나 싶다.
def solution(s):
return s[len(s)//2] if len(s)%2 else s[len(s)//2-1:len(s)//2+1]
def solution(arr):
answer = [-1]
for i in arr:
if answer and answer[-1] != i:
answer.append(i)
return answer[1:]
리스트가 비어있으면
answer[-1]
에서 오류가 난다. 이를 방지하기 위해 쓰레기 값인-1
를 넣었다.
def solution(arr):
answer = []
for i in arr:
if answer[-1:] != [i]:
answer.append(i)
return answer
answer[-1]
은 빈 리스트일 때 오류를 발생하지만,answer[-1:]
는 오류를 발생안한다!
def solution(n):
s = ''
def base(n):
if not n:return
a,b = divmod(n,3)
base(a)
nonlocal s
s = str(b) + s
base(n)
return int(s,3)
힘수를 사용하면 깔끔한 코드가 될 줄 알고 작성했는데 조잡해졌다.
def solution(n):
s = ''
while n:
s += str(n%3)
n //= 3
return int(s,3)
생각해보면 어차피 3진법을
3진법 n
을 구하는 것이 아니라 바로앞뒤 반전된 3진법 n
을 구하면 되는 것이다. 코드가 훨씬 간결해졌다.
def solution(absolutes, signs):
return sum([a if s else -a for a,s in zip(absolutes, signs)])
for
, if
, else
이 세가지를 모두 한 줄 코딩을 하려면 if~else
문을 for
문 앞에 작성해야한다.
def solution(a, b):
return sum([a*b for a,b in zip(a,b)])
고등학교 졸업하고 오랜만에 보는 내적...뭔가 반가웠다!
def solution(lottos, win_nums):
hits, zn = len([i for i in win_nums if i in lottos]), lottos.count(0)
return [7 - zn-hits if hits+zn else 6, 7-hits if hits else 6]
import itertools
def solution(numbers):
return sorted(list(set([a+b for a, b in itertools.combinations(numbers,2)])))
def solution(d, budget):
answer, m = 0, 0
d.sort()
for i in d:
if m + i <= budget:
m += i
answer += 1
return answer
import itertools
def solution(nums):
dp = [False] * 3000
for i in range(2,3000):
for j in range(2*i,3000,i):
dp[j] = True
return len([dp[sum(i)] for i in itertools.combinations(nums,3) if not dp[sum(i)]])
에라토스테네스의 체로 구현.
def solution(arr, divisor):
answer = [i for i in arr if not i%divisor]
return [[-1] if not answer else sorted(answer)][0]
def solution(arr, divisor):
return sorted([i for i in arr if not i%divisor]) or [-1]
or
을 이용하면 더욱더 간략하게 표현할 수 있다.print(10 or 11) # 둘 다 True이므로 앞에있는 10 출력 print([] or 11) # 11만 True이므로 11 출력
def solution(nums):
if len(set(nums)) <= len(nums)//2:
return len(set(nums))
return len(nums)//2
def solution(nums):
return min(len(set(nums),len(nums)//2)
나름 심플하게 풀었다고 생각했는데, 다른 사람들의 코드를 참고하니 위와 같이 한 줄로 작성이 가능하다.
def solution(a, b):
return sum(range(a,b+1) if a < b else range(b,a+1))
def solution(strings, n):
return sorted(sorted(strings), key = lambda x: x[n])
def solution(s):
return s.lower().count('p') == s.lower().count('y')
def solution(s):
return ''.join(sorted(s, reverse=True))
def solution(s):
return (len(s) == 4 or len(s) == 6) and s.isnumeric()
def solution(seoul):
return f"김서방은 {seoul.index('Kim')}에 있다"
def solution(n):
check = [False,False] + [True]*(n-1)
for i in range(2, n+1):
if check[i]:
for j in range(2*i, n+1, i):
check[j] = False
return check.count(1)
import itertools
def solution(n):
answer = itertools.cycle('수박')
return ''.join([next(answer) for _ in range(n)])
cycle
로 돌려서 수박을 출력한다. 그때 그때 값을 만들기 때문에 메모리 효율도 좋다.
def solution(s):
return int(s)
import string
def solution(s, n):
answer = ''
alpha = string.ascii_lowercase
for i in s:
small_i = i.lower()
if i != ' ':
if i.isupper():
answer += alpha[(alpha.index(small_i)+n)%len(alpha)].upper()
else:
answer += alpha[(alpha.index(small_i)+n)%len(alpha)]
else:
answer += ' '
return answer
def solution(n):
return sum([i for i in range(1, n+1) if not n%i])
def solution(s):
answer = []
s = s.lower().split(' ')
for i in s:
tmp = ''
for j,v in enumerate(i):
if (j+1)%2:
tmp += v.upper()
else:
tmp += v
answer.append(tmp)
return ' '.join(answer)
split()
으로 하면 공백을 원소로 취급안한다.split(' ')
로 해줘야 공백을 원소로 취급해준다.
def solution(n):
return sum(list(map(int, str(n))))
def solution(n):
return list(map(int, str(n)))[::-1]
def solution(n):
return int(''.join(sorted(list(str(n)), reverse=True)))
def solution(n):
if n**0.5 == int(n**0.5):
return (n**0.5+1)**2
return -1
루트(제곱근)을 구할 때
**0.5
를 하면 됨!
def solution(arr):
arr.remove(min(arr))
if not arr:
return [-1]
return arr
def solution(num):
if (num+1)%2:
return "Even"
return "Odd"
def solution(numbers, hand):
answer = ''
r, l = [3,6,9], [1,4,7]
cr, cl = 10, 12
for i,v in enumerate(numbers):
if v in r:
answer += "R"
cr = v
elif v in l:
answer += "L"
cl = v
else:
if v == 0:
v = 11
if abs(cr - v)//3+abs(cr - v)%3 < abs(cl - v)//3+abs(cl - v)%3:
answer += "R"
cr = v
elif abs(cr - v)//3+abs(cr - v)%3 > abs(cl - v)//3+abs(cl - v)%3:
answer += "L"
cl = v
else:
answer += hand[0].upper()
if hand[0].upper() == 'L':
cl = v
else:
cr = v
return answer
알고리즘을 공부하기 전, 이 문제를 2시간 동안 봤는데 결국 못 풀었다. 이제는 쉽게 느껴지니 뿌듯하다.
def solution(n, m):
lcm = n*m
while m:
n,m = m,n%m
return n, lcm//n
최대공약수
def gcd(x,y): while y: x,y = y, x%y return x
최소공배수
def lcm(x,y): return x*y//gcd(x,y)
def solution(num):
cnt = 0
while num != 1:
if cnt == 500:
return -1
if num%2:
num = num*3+1
cnt += 1
else:
num //= 2
cnt += 1
return cnt
def solution(arr):
return sum(arr)/len(arr)
def solution(x):
return not x % sum(map(int, str(x)))
def solution(phone_number):
return '*'*(len(phone_number)-4)+phone_number[-4:]
def solution(arr1, arr2):
if len(arr1) == len(arr2) and len(arr1[0]) == len(arr2[0]):
return [list(map(sum, zip(arr1[i],arr2[i]))) for i in range(len(arr1))]
def solution(x, n):
return [x*i for i in range(1,n+1)]
a, b = map(int, input().strip().split(' '))
print(('*'*a+'\n')*b)
def solution(n, arr1, arr2):
bmap = [list(format(arr1[i] | arr2[i], 'b').zfill(n)) for i in range(n)]
return [''.join(list(map(lambda x: ' ' if x == '0' else '#', j))) for j in bmap]
비트연산
비트 연산을 하려면 십진수를 이진수로 바꿔서 진행해야 하는 줄 알았는데 십진수 그대로도 비트연산이 된다! 예를 들면 아래와 같다.>> bin(0b1101 & 0b1001) # 비트 AND '0b1001' >> 13 & 9 # 비트 AND 9 >> bin(0b1101 | 0b1001) # 비트 OR '0b1101' >> 13 | 9 # 비트 OR 13 >> bin(0b1101 ^ 0b1001) # 비트 XOR '0b100' >> 13 ^ 9 # 비트 XOR 4 >> bin(~0b1101) # 비트 NOT '-0b1110' >> ~13 # 비트 NOT -14