알고리즘은 돌아오는거야...!
답:
vscode에서 풀이할 때는 잘 돌아갔는데 제출하면 오류가 난다!
IndexError: string index out of range
원인 찾아보자...
zfill을 5로 설정해서 생긴 문제
n으로 바꾸면 성공!!!
def solution(n, arr1, arr2):
array1 = []
array2 = []
for a in arr1:
a = format(a, 'b')
print(a)
if len(a) != n:
a = a.zfill(n) # 5 x n으로 지정
array1.append(a)
else:
array1.append(a)
for r in arr2:
r = format(r, 'b')
if len(r) != n:
r = r.zfill(n) # 5 x n으로 지정
array2.append(r)
else:
array2.append(r)
answer = []
for i in range(0,n):
answer_str = ''
for a in range(len(array1[i])):
if array1[i][a] == '0' and array2[i][a] == '0':
answer_str += " "
elif array1[i][a] == '1' or array2[i][a] == '1':
answer_str += '#'
answer.append(answer_str)
return answer
길고도 길다..ㅋㅋ
> 팀원들의 풀이
적어두고 분석해보자!
1)
def solution(n, arr1, arr2):
answer = []
for i in range(n):
array = bin(arr1[i] | arr2[i])
array = array[2:].zfill(n)
array = array.replace('1','#').replace('0',' ')
answer.append(array)
return answer
2)
def solution(n, arr1, arr2):
answer = []
for i, j in zip(arr1,arr2):
a = str(bin(i|j)[2:])
a = a.rjust(n,'0')
# rjust : 오른쪽 정렬해서 n보다 길이가 작으면 앞에는 0으로 채운다.
a = a.replace('1', '#')
a = a.replace('0', ' ')
answer.append(a)
return answer
- 해당 문제 풀이에 쓸만한 함수들 +a 공부하여 정리 -
bin() 바이너리 함수!
Convert an integer number to a binary string prefixed with “0b”.
int를 받아 '0b'를 붙인 이진수 문자열을 만들어준다.
>>> bin(3)
'0b11'
>>> bin(-10)
'-0b1010'
접두사 "0b"가 필요한 경우 다음 방법 중 하나를 사용할 수 있습니다
format()
f-string
#format()
>>> format(14, '#b'), format(14, 'b')
('0b1110', '1110')
#f-string
>>> f'{14:#b}', f'{14:b}'
('0b1110', '1110')
format(value, format_spec='')
2개의 인자를 받아 format_spec에 따라 값을 변환해준다.
기본 format_spec은 일반적으로 호출과 동일한 효과를 제공하는 빈 문자열 = str(value)
+++ python에서 2진수 8진수 16진수 다루기
bin() = 2진수
oct() = 8진수
hex() = 16진수
동일한 숫자값 42를 넘겨준 것이기 때문에 str(value)에 넣었을때 모두 '42'가 나온다!
>>> bin(0b101010)
'0b101010'
>>> oct(0b101010)
'0o52'
>>> hex(0b101010)
'0x2a'
>>> str(0b101010)
'42'
int()로 정수형으로 바꾸어줄 수 있음. 이때 인자는 첫번째에 진수값, 두번째는 base값을 넣어준다.
>>> int('0b101010', 2)
42
>>> int('0o52', 8)
42
>>> int('0x2a', 16)
42
#int의 두번째 인자는 default값이 10임!
>>> int('42', 10)
42
>>> int('42')
42
[참조] :
https://docs.python.org/3/library/functions.html?highlight=bin#bin +format()
formet_spec mini-language 심심할때 읽어보자!
https://docs.python.org/3/library/string.html#formatspec
> 문자열에 0을 추가하기
zfill() 문자열 메서드
: 원하는 문자열 길이를 지정하는 숫자를 매개변수로 사용하고, 문자열 왼쪽에 0을 추가해준다.
매개변수로 전달된 숫자가 원래 문자열 길이보다 작으면 변화X
A = '1'
B = '101101'
print(A.zfill(5)) # '00001' = 정수로 변환하면 1만 남음 주의
print(B.zfill(5)) # '101101' = 변화 없음
rjust() ljust() 문자열 메서드
: 필수 매개변수로 원하는 길이를 지정하는 숫자, 문자를 옵션 매개변수로 사용
rjust는 왼쪽, ljust는 오른쪽에 선택적 문자를 추가한다
문자를 지정하지 않으면 기본값은 공백 " "
A = '123'
B = 'HI'
print(A.rjust(5,"0")) # '00123'
print(B.ljust(5,"0")) # 'HI000'
format()
A = '1'
print('{:0>5}'.format(A))
이 방법은 Python 2~Python 3.5에서만 사용 = 내 python은 ver3.9 이상이어서 못쓰는 방법이었다. 왜 안되나 했네!
f-string으로 문자열 채우기
: 최신 버전에서 추가, 문자열의 빠른 형식지정을 제공해준다!
A = '1'
print(f'{A:0>5}') # '00001'
# 2023년1월30일 글
[참조] : https://www.delftstack.com/ko/howto/python/pad-string-with-zeros-in-python/
문제 분석 및 해석
> 문제
지도는 한 변의 길이가 n인 정사각형 배열.
각 칸은 공백 " ", 벽 "#" 두 종류
전체 지도는 두장의 지도를 겹쳐서 얻을 수 있다.
어느하나라도 벽이 있으면 벽("#") 둘다 공백이면 공백(" ")
= 1이 있으면 #
= 0이면 공백
암호화된 배열은 지도의 각 가로 줄에서 벽 부분을 1 공백을 0으로 했을때 얻어지는 이진수에 해당하는 값의 배열
> 입 출력 값
입력 : n 과 2개의 정수 배열 arr1, arr2가 들어온다.
출력 : '#', 공백으로 이주어진 배열
매개변수 값
n 5
arr1 [9, 20, 28, 18, 11]
arr2 [30, 1, 21, 17, 28]
출력 ["#####","# # #", "### #", "# ##", "#####"]
> 분석
1) 풀이에 필요한 함수 예상
bin() 바이너리 함수?
2) 내가 생각한 풀이
arr1, arr2를 이진수로 바꾸고
+추가+ 길이를 맞춰주기
바꾼 숫자에서 1이 있는 부분을 합치고 =>이 부분을 조금 더 자세하게 생각해야했다!
#, ' '으로 변환하여 출력
- 과정1 -
이진수를 만드는 bin()함수로 arr1, arr2 바꾸기
arr1 = [9, 20, 28, 18, 11]
def solution(n, arr1, arr2):
for a in arr1:
arr1 = bin(a)
print(arr1)
#arr1 변환 결과 값
0b1001
0b10100
0b11100
0b10010
0b1011
0b를 떼어내기 위해서 format()함수를 사용하고, zfill() 함수로 5자리를 맞추어 주었다
array1 = []
for a in arr1:
a = format(a, 'b')
if len(a) != n:
a = a.zfill(5)
array1.append(a)
else:
array1.append(a)
#결과 값
arr1 = ['01001', '10100', '11100', '10010', '01011']
잠시 int값으로도 넣어보았는데 열심히 넣어준 0이 싹 사라지는 것을 볼 수 있다!
for r in arr2:
r = format(r, 'b')
if len(r) != n:
r = r.zfill(5)
array2.append(int(r))
else:
array2.append(int(r))
# [11110, 1, 10101, 10001, 11100]
각각의 자리를 비교해 1과 0을 넣기위해 이차원배열에 각각의 문자열을 쪼개어 넣고, 비교하고자했는데
코드가 너무 복잡해지고, 어떤 값을 넣어 비교해야할지 헷갈리는 상태가 되었다.
과정2.
이 시점에서 막혔는데, 팀원과 문제점을 공유하고 방법을 추천받았다
문자열도 인덱스가 된다는 것을 재확인.
for문으로 문자열의 길이를 만큼의 index값을 받아오고, 각각의 자리를 비교하여 바꾸어주는 방법을 사용했다.
for i in range(0,n):
answer_str = '' # 문제점: 1초기화를 못하고 있고, 2공백이 안 넣어지고 있다
for a in range(len(array1[i])):
if array1[i][a] and array2[i][a] == 0:
answer_str += " "
elif array1[i][a] or array2[i][a] == 1:
answer_str += '#'
answer.append(answer_str)
# 값이...?
# ['#####', '##########', '###############', '####################', '#########################']
ㅋㅋㅋ 문자열 초기화를 위해 for문 바깥으로 answer_str을 빼줬다
answer_str = '' # 남은문제점 : 2공백이 안 넣어지고 있다
for i in range(0,n):
...
오류.. and 로 비교하기 위해 a and b를 사용하면 a, b에 모두 비교하는 내용을 적어주어야했다!
그러니까 array1[i][a]가 1이어서 계속 #이 들어가는 상태였던 것.
if array1[i][a] and array2[i][a] == 0:
answer_str += " "
...
# ['#####', '#####', '#####', '#####', '#####']
아래와 같이 각각의 값을 비교하여 변환하도록 변경!
if array1[i][a] == '0' and array2[i][a] == '0':
answer_str += " "
elif array1[i][a] == '1' or array2[i][a] == '1':
answer_str += '#'
느낀점:
혼자 해결하지 못한 것은 아쉽지만, 문제를 바라보는 시각에 대해 배웠다.
진짜로 혼자서만 해결하려고 했으면 더 많은 시간이 걸렸을 것 같다...ㅠㅠ
어떤 문제점이있는지 딱 잡아내는 시야와 정리하여 표현하는 부분을 배워야겠다는 생각이 들었다!
이렇게 좋은 페어프로그래밍!
동료가 있을때 함께하세요! 캬
다음에는 짧고 예쁜 코드로 보이는 동기들의 방법으로 풀어보고싶다..!
'알고리즘 풀이' 카테고리의 다른 글
[algorithm] 페어 - 백준:2563 색종이 (0) | 2023.05.02 |
---|---|
[algorithm] 페어 - 프로그래머스: 나머지가 1인 수, 없는 숫자 더하기 (0) | 2023.05.01 |
[algorithm] 페어 - 백준: 25304 영수증 (0) | 2023.04.27 |
[algorithm] 페어 - 프로그래머스: 영어가 싫어요 (0) | 2023.04.26 |
[algorithm] 페어 - 프로그래머스: 로그인 성공?, n의 배수 고르기 (0) | 2023.04.25 |