# you can write to stdout for debugging purposes, e.g.
# print("this is a debug message")
def solution(N, M):
# write your code in Python 3.6
chocolates = [0]*N
_current = 0
while chocolates[_current] != 1:
chocolates[_current] = 1
_current = (_current+M)%N
return sum(chocolates)
pass
배열을 활용해서 정직하게 문제 그대로 풀려고 하였는데요,
이렇게 풀게 되면 정확도는 맞출 수 있었는지는 모르겠지만,
시간효율에 대해서는 Timeout으로 점수를 얻지 못했습니다..ㅠ!
이 문제는 산수로 풀 수 있는 문제입니다.
특별히 Codility에서는 이 문제를 유클리드 알고리즘으로 접근하도록
분류를 해놓았는데요,
아래는 제가 문제를 정확하게 다시 읽고 몇번의 시도 끝에 풀게 된 코드입니다.
# you can write to stdout for debugging purposes, e.g.
# print("this is a debug message")
def solution(N, M):
# write your code in Python 3.6
from math import gcd
return N//gcd(M,N)
pass
2줄이면 끝나는 문제이지요..?
때로는 생각나는 대로 무작정 덤비는 것보다,
산수와, 수식 등을 적용할 수 있는지 한번 더 고민해본 후에 문제를 풀어나가는 것도 좋은 방법일 것 같습니다.
# you can write to stdout for debugging purposes, e.g.
# print("this is a debug message")
def solution(N, P, Q):
# write your code in Python 3.6
result = []
for a,b in zip(P,Q):
if b <= N:
c = b
else:
c = N
result.append(len(get_prime(N,a,c)))
#print(result)
return result
pass
def get_prime(num,a,b):
arr = []
if num <= 1:
return arr
arr2 = []
for i in range(2,num+1):
flag = True
for j in range(len(arr)):
if i%arr[j] == 0:
flag = False
break
if flag:
if a <= i**2 and i**2 <= b:
arr2.append(i*i)
arr2.extend([k*i for k in arr if a <= k*i and k*i <= b])
arr.append(i)
return arr2
구글링을 통해서 해답을 알게 되었다.
해답은 인덱스를 사용하여 계산을 하는 것이다.
# you can write to stdout for debugging purposes, e.g.
# print("this is a debug message")
import math
def solution(N, P, Q):
# write your code in Python 3.6
# N+1의 개수를 가진 빈 배열을 만들어준다.
arr = [0]*(N+1)
semi_cnt = [0]*(N+1)
each_sum = 0
#1~N 까지의 범위의 수를 소수와 소수의 배수로 구분함
i = 2
while i <= math.sqrt(N):
if arr[i] == 0:
j = i*i
while j <= N:
arr[j] = i
j += i
i += 1
#print(arr)
# 인덱스를 통해서 문제를 풀어준다.(소수일때, 나누고 나눈 값이 다시 소수라면 +1)
for i in range(1,N+1):
if arr[i] != 0:
j = i//arr[i]
if arr[j] == 0:
each_sum += 1
semi_cnt[i] = each_sum
#rint(semi_cnt)
result = []
# 범위에 따라 소수의 개수를 차감하여 값을 배열에 넣어준다.
for i,j in zip(P,Q):
result.append(semi_cnt[j]-semi_cnt[i-1])
#print(result)
return result
pass
A non-empty array A consisting of N integers is given.
Apeakis an array element which is larger than its neighbors. More precisely, it is an index P such that 0 < P < N − 1, A[P − 1] < A[P] and A[P] > A[P + 1].
We want to divide this array into blocks containing the same number of elements. More precisely, we want to choose a number K that will yield the following blocks:
A[0], A[1], ..., A[K − 1],
A[K], A[K + 1], ..., A[2K − 1], ...
A[N − K], A[N − K + 1], ..., A[N − 1].
What's more, every block should contain at least one peak. Notice that extreme elements of the blocks (for example A[K − 1] or A[K]) can also be peaks, but only if they have both neighbors (including one in an adjacent blocks).
The goal is to find the maximum number of blocks into which the array A can be divided.
Array A can be divided into blocks as follows:
one block (1, 2, 3, 4, 3, 4, 1, 2, 3, 4, 6, 2). This block contains three peaks.
two blocks (1, 2, 3, 4, 3, 4) and (1, 2, 3, 4, 6, 2). Every block has a peak.
three blocks (1, 2, 3, 4), (3, 4, 1, 2), (3, 4, 6, 2). Every block has a peak. Notice in particular that the first block (1, 2, 3, 4) has a peak at A[3], because A[2] < A[3] > A[4], even though A[4] is in the adjacent block.
However, array A cannot be divided into four blocks, (1, 2, 3), (4, 3, 4), (1, 2, 3) and (4, 6, 2), because the (1, 2, 3) blocks do not contain a peak. Notice in particular that the (4, 3, 4) block contains two peaks: A[3] and A[5].
The maximum number of blocks that array A can be divided into is three.
Write a function:
class Solution { public int solution(int[] A); }
that, given a non-empty array A consisting of N integers, returns the maximum number of blocks into which A can be divided.
If A cannot be divided into some number of blocks, the function should return 0.
Write anefficientalgorithm for the following assumptions:
N is an integer within the range [1..100,000];
each element of array A is an integer within the range [0..1,000,000,000].
Copyright 2009–2020 by Codility Limited. All Rights Reserved. Unauthorized copying, publication or disclosure prohibited.
Peaks 문제는 봉우리를 최소 1개씩 포함하고 있는 Block의 개수를 구하는 문제이다.
최대 블록의 개수를 Return 해주면 되는데,
그 방법을 구체적으로 어떻게 짜야되는지 다양하게 시도하다가
결국 답지를 보고 풀었다.ㅜㅜ!!
그래도 이 방법 잘 알아두어야겠다.
정답 코드
# you can write to stdout for debugging purposes, e.g.
# print("this is a debug message")
def solution(A):
# write your code in Python 3.6
peaks = []
for i in range(1, len(A)-1):
if A[i] > A[i-1] and A[i] > A[i+1]:
peaks.append(i)
for i in range(len(peaks),0,-1):
if len(A) % i == 0:
block_size = len(A)//i
block = [False]*i
block_cnt = 0
for j in range(len(peaks)):
idx = peaks[j] // block_size
if block[idx] == False:
block[idx] = True
block_cnt += 1
if block_cnt == i:
return block_cnt
return 0
pass
그 원인을 살펴보니 큰 수에 대해서는 for문에서 i 가 일일히 +1씩 되면서 진행되는 부분이
성능이 좋지 않음을 알 수 있었다.(Timeout Error 발생ㅜㅜ)
그래서 for i in range(2,int(i/2)): 처럼 나누기 2를 해보기도 하고 그랬는데,
역시나 마찬가지였다.
# you can write to stdout for debugging purposes, e.g.
# print("this is a debug message")
def solution(N):
# write your code in Python 3.6
check = N
max_perimeter = 2*(1+(N))
for i in range(1,N+1):
# 반복되는 값이 가장 최근의 몫의 값보다 커지면 그만
if i >= check:
break
# 0으로 나눠지면 약수
if N%i == 0:
max_perimeter = min(max_perimeter,2*(i+(N/i)))
check = N/i
return int(max_perimeter)
pass
잠깐 들었던 생각이
이전에 풀었던 Codility 문제 중에 CounterFactors라는 문제에서도 약수를 구하는 문제였는데,
# you can write to stdout for debugging purposes, e.g.
# print("this is a debug message")
def solution(N):
# write your code in Python 3.6
max_perimeter = 2*(1+(N))
number_iter = 1
while number_iter*number_iter < N:
# 약수이면
if N/number_iter%1 == 0:
max_perimeter = min(max_perimeter,2*(number_iter+(N/number_iter)))
number_iter += 1
if number_iter*number_iter == N:
max_perimeter = min(max_perimeter,4*number_iter)
return int(max_perimeter)
pass
# you can write to stdout for debugging purposes, e.g.
# print("this is a debug message")
def solution(A):
# write your code in Python 3.6
#print(A)
if len(A) <= 2:
return 0
pre_peak_idx = 0
current_peak_num = 0
result_peak_num = 0
peak_idx_arr = []
for i in range(1,len(A)-1):
#print(peak_idx_arr)
# 만약 피크라면
if A[i-1] < A[i] and A[i+1] < A[i]:
# 최초 피크라면
if current_peak_num == 0:
current_peak_num += 1
peak_idx_arr.append(i)
# 피크가 2개 이상이라면
else:
# 조건에 부합하는지
peak_idx_arr.append(i)
for j in range(len(peak_idx_arr)-1,0,-1):
if abs(peak_idx_arr[j]-peak_idx_arr[j-1]) < (current_peak_num+1):
del peak_idx_arr[j-1]
break
if len(peak_idx_arr) == current_peak_num:
continue
else:
current_peak_num += 1
#print(peak_idx_arr)
return len(peak_idx_arr)
pass
다시 풀어봐야겠다..!! 화이팅!
다시 풀어보았다
정확도: 66% (peak의 개수가 많아지는 상태에서는 다수의 Timeout 에러 발생)
- 코드 -
# you can write to stdout for debugging purposes, e.g.
# print("this is a debug message")
def solution(A):
# write your code in Python 3.6
if len(A) < 2:
return 0
peak_arr = []
for i in range(1,len(A)-1):
# 피크라면
if A[i-1] < A[i] and A[i+1] < A[i]:
peak_arr.append(i)
#print(peak_arr)
length_peak_arr = len(peak_arr)
if len(peak_arr) == 0:
return 0
for j in range(len(peak_arr),0,-1):
current_index = 0
num_of_peak = 1
for i in range(1,len(peak_arr)):
if abs(peak_arr[i] - peak_arr[current_index]) < j:
continue
else:
num_of_peak += 1
current_index = i
if num_of_peak == j:
return j
return num_of_peak
pass
이중 for문은 역시 안좋다
대충 감을 잡은 거 같다.
다시 풀어봐야겠다!!
임시 저장 코드
# you can write to stdout for debugging purposes, e.g.
# print("this is a debug message")
def solution(A):
# write your code in Python 3.6
if len(A) < 2:
return 0
num_peaks = 0
peak_arr = []
for i in range(1, len(A)-1):
# 피크인 경우
if A[i-1] < A[i] and A[i+1] < A[i]:
peak_arr.append(i)
print(peak_arr)
if len(peak_arr) == 0:
return 0
if len(peak_arr) == 1:
return 1
peak_cnt_ = 1
peak_num_ = 1
for j in range(len(peak_arr),1,-1):
for i in range(len(peak_arr)):
if peak_arr[i] >= peak_j*j:
peak_num_ += 1
peak_cnt_ += 1
if peak_arr[i] >= peak_arr[0]+j*peak_cnt_:
peak_num_ += 1
peak_cnt_ += 1
if peak_num_ == j:
return peak_num_
pass
7월6일 재도전
# you can write to stdout for debugging purposes, e.g.
# print("this is a debug message")
def solution(A):
# write your code in Python 3.6
if len(A) <= 2:
return 0
peaks = []
for i in range(1,len(A)-1):
if A[i-1] < A[i] and A[i+1] < A[i]:
peaks.append(i+1)
if len(peaks) == 1:
return 1
if len(peaks) == 0:
return 0
num = len(peaks)
try:
for i in range(1,num):
j = 1
if len(peaks) < i+1:
break
while j < i+1:
if peaks[j] >= peaks[j-1]+(i+1):
j += 1
else:
del peaks[j]
except:
return len(peaks)
return len(peaks)
# you can write to stdout for debugging purposes, e.g.
# print("this is a debug message")
def solution(A):
# write your code in Python 3.6
peak_arr = []
for i in range(1,len(A)-1):
if A[i] > A[i-1] and A[i] > A[i+1]:
peak_arr.append(i)
print(peak_arr)
result_peak_num = 0
if len(peak_arr) == 1:
return 1
else:
start_peak_num = 1
while start_peak_num < len(peak_arr):
# 몇개의 봉우리를 찾아야하는지
start_peak_num += 1
# 기본 1로 시작함(이미 하나 찾은거로 가정)
current_peak_num = 1
s = peak_arr[0]
# 1개 찾고, 2개 찾고 ..
for i in range(1,len(peak_arr)):
e = peak_arr[i]
if abs(e-s) >= start_peak_num:
# 여기가 다시 시작이 된다
s = e
current_peak_num += 1
if current_peak_num == start_peak_num:
result_peak_num = max(result_peak_num,start_peak_num)
#print(result_peak_num)
return result_peak_num
pass
==============아래는 성공한 코드 =============
8월 21일 코드
드디어 풀었다!!
물론 구글링을 조금 하긴 했지만,
어느정도 혼자 힘으로 풀 수 있었다.
# you can write to stdout for debugging purposes, e.g.
# print("this is a debug message")
def solution(A):
# write your code in Python 3.6
# peak가 있는 인덱스만 모아놓은 리스트 초기화
peak_arr_list = []
# peak가 있는 인덱스만 모아놓은 리스트 값 채워넣기
for i in range(1,len(A)-1):
if A[i] > A[i-1] and A[i] > A[i+1]:
peak_arr_list.append(i)
# 만약 peak가 0개라면 return 0
if len(peak_arr_list) == 0:
return 0
# 만약 peak가 1개라면 return 1
if len(peak_arr_list) == 1:
return 1
# peak_arr_list 출력 테스트
#print(peak_arr_list)
# peak_arr 라는 리스트 초기화
peak_arr = [0]*len(A)
peak_arr[0] = -1
peak_arr[-1] = -1
peak_idx = -1
# peak_arr 값 채워넣기
for i in range(len(A)-2,0,-1):
if A[i] > A[i-1] and A[i] > A[i+1]:
peak_idx = i
peak_arr[i] = peak_idx
# peak_arr 출력 테스트
#print(peak_arr)
max_num_flag = -1
# 1에서 len(A)까지 반복 -> 최대 peak 개수는 len(A)가 될 수 있음
for i in range(1,len(peak_arr_list)+1):
# index는 매 loop마다 1값으로 초기화
index = 1
# num_flag는 매 loop마다 peak 조건을 만족하면 +1씩 해줌
num_flag = 0
# num_flag가 loop보다 작으면 반복 -> 같아지면 해당 num_flag는 가능한 개수이다.
while num_flag < i:
try:
if peak_arr[index] != -1:
num_flag += 1
index = peak_arr[index] + i
else:
return max_num_flag
except:
return max_num_flag
# 만약 이전 loop의 peak 개수보다 크면 max_num_flag 초기화
max_num_flag = max(num_flag,max_num_flag)
# for 끝나면 가장 최대 peak 개수를 의미하는 max_num_flag 반환
return max_num_flag
pass
# you can write to stdout for debugging purposes, e.g.
# print("this is a debug message")
def solution(N):
# write your code in Python 3.6
if N == 1:
return 1
cnt = 0
for i in range(int(N/2)):
# 약수이면
i = i+1
if N/i%1 == 0:
if N//i < i:
break
if N//i == i:
cnt += 1
else:
cnt += 2
return cnt
pass
누군가의 코드
시간복잡도: O(sqrt(N))
# you can write to stdout for debugging purposes, e.g.
# print("this is a debug message")
def solution(N):
# write your code in Python 3.6
number_iter = 1
factor_cnt = 0
while number_iter*number_iter < N:
# 약수이면
if N/number_iter%1 == 0:
factor_cnt += 2
number_iter += 1
if number_iter*number_iter == N:
factor_cnt += 1
return factor_cnt
pass