프로그래머스 파이썬 기초 트레이닝 :: 조건에 맞게 수열 변환하기 2 (저장용 배열)
문제 설명
프로그래머스 URL
https://school.programmers.co.kr/learn/courses/30/lessons/181881
프로그래머스 코딩 카테고리
코딩 기초 트레이닝
Day 15 리스트(배열), 문자열 - 조건에 맞게 수열 변환하기 2
Lv.0
문제 내용
정수 배열 arr가 주어집니다. arr의 각 원소에 대해 값이 50보다 크거나 같은 짝수라면 2로 나누고, 50보다 작은 홀수라면 2를 곱하고 다시 1을 더합니다.
이러한 작업을 x번 반복한 결과인 배열을 arr(x)라고 표현했을 때, arr(x) = arr(x + 1)인 x가 항상 존재합니다. 이러한 x 중 가장 작은 값을 return 하는 solution 함수를 완성해 주세요.
단, 두 배열에 대한 "="는 두 배열의 크기가 서로 같으며, 같은 인덱스의 원소가 각각 서로 같음을 의미합니다.
arr result
[1, 2, 3, 100, 99, 98] 5
-----------------------------------
2차원 배열 활용
내가 푼 코드
def solution(arr):
check = 1
tmp = [arr.copy()]
while True :
for i, v in enumerate(arr) :
if v > 50 and v % 2 == 0 :
arr[i] = v // 2
elif v < 50 and v % 2 :
arr[i] = (v * 2)+1
tmp.append(arr.copy())
if tmp[check] == tmp[check-1] :
break
check += 1
return check -1
1. 2차원 배열에 값 저장
tmp 라는 임시 배열(2차원)에 값을 저장할때 ,
tmp = [ arr ] 로 선언하면, arr 객체 자체를 넣는거기 때문에 while, for문에서 변경되면 tmp에서도 변경이 된다.
따라서, tmp = [ arr.copy() ]로 선언하고, while문에서도 tmp.append(arr.copy())로 해야 arr의 복사본이 저장이된다.
arr와 값은 같지만 주소값은 다른 녀석이 저장이 되는 것이다.
2. 2차원 배열의 마지막 arr랑 현재 arr 비교
최종적으로 tmp 2차원 배열에 저장되는 값은 아래와 같다.
[[1, 2, 3, 100, 99, 98], [3, 2, 7, 50, 99, 49], [7, 2, 15, 50, 99, 99], [15, 2, 31, 50, 99, 99],
[31, 2, 63, 50, 99, 99], [63, 2, 63, 50, 99, 99], [63, 2, 63, 50, 99, 99]]
마지막에 저장된 tmp[6] 이랑 바로 이전에 넣은 tmp[5] arr 값이랑 비교해서
똑같으면 while 문을 빠져나오고, tmp 인덱스를 위해 사용한 check 변수를 리턴한다.
-----------------------------------
나는 이렇게 전과정을 저장하는 이차원 배열을 만들어서 풀었지만,
임시 배열(1차원) 하나를 사용해서 문제를 풀 수 있다.
1차원 배열을 사용하더라도 다양한 방식이 있어서, 정리해봄
1차원 배열
while - break
def solution(arr):
answer = 0
old = arr
while(True):
new = []
for i in old:
if i>=50 and i%2 == 0: i = i/2
elif i<50 and i%2 == 1: i = i*2 + 1
new.append(int(i))
if old == new:
break
else:
old = new
answer += 1
return answer
old, new, arr 배열로 총 3개가 나온다.
old는 원본 arr 배열을 복사해서 시작한다.
조건에 맞춰서 값을 바꾼 새로운 배열은 new 에 저장을 해서
old == new 배열이 서로 같은지 확인한 뒤에, 같으면 break 로 while문을 빠져나온다.
다르면, old = new 로 바껴진 배열 값을 가진다 .
while - return
def solution(arr):
answer = 0
while True:
arr_trans = []
for i in arr:
if i >= 50 and i % 2 == 0:
arr_trans.append(i//2)
elif i < 50 and i % 2 == 1:
arr_trans.append(i*2 + 1)
arr_trans.append(i)
if arr == arr_trans:
return answer
answer += 1
arr = arr_trans
이 코드는 arr 원본 배열과 arr_trans 배열 두개를 사용한다.
변화시킨 arr 값을 arr_trans 에 저장하고, arr == arr_trans 같은지 비교한다.
같다면, break문이 아니라 return을 바로 줘서 while문을 빠져나온다.
다르다면, arr = arr_trans 한 뒤에 arr_trans 해서 새로운 값을 넣을 준비를 한다.
배열 없이, flag 변수
def solution(arr):
answer = 0
while True :
flag = False
for i, num in enumerate(arr) :
if num >= 50 and num % 2 == 0 :
arr[i] = num // 2
flag = True
elif num < 50 and num % 2 == 1 :
arr[i] = num * 2 + 1
flag = True
if flag :
answer += 1
else :
break
return answer
while 문을 멈추는 기능을 하는 flag 변수를 사용하는 코드이다.
배열을 추가로 사용하지 않는 이유는 배열의 값이 이전과 같다는 건 요소 값들이 변하지 않는다는 말과 같다.
for 문 안에있는 if 문들이 실행이되면, 값이 변하는 거니까 이전 배열과 다르다는걸 뜻하는데 if, elif문 둘다 안거치고 지나가면 이전 배열과 같으니까 flag 값이 False로 유지가 된다.
flag 값이 false 일때 while문 break가 실행되서 반복에서 빠져나오게 된다.
댓글
댓글 쓰기