n*n의 2차원 벽면에 기둥과 보를 설치하려고 한다.
설치
기둥
: 바닥 위/ 보의 한쪽 끝/ 다른 기둥 위
보
: 한쪽끝이 기둥위/ 양쪽 끝이 다른 보
삭제
: 삭제 뒤에도 규칙 만족할때
IN
OUT
#기둥과 보
def establish(build_frame, wall):
print("buil")
if build_frame[2] == 0:
#기둥
if build_frame[1] == 0 or wall[build_frame[1]][build_frame[0]-1] == 2 or wall[build_frame[1]-1][build_frame[0]] == 1:
#바닥 위
wall[build_frame[1]][build_frame[0]] = 1
elif wall[build_frame[1]][build_frame[0]] == 2:
#보의 한쪽 끝
wall[build_frame[1]][build_frame[0]] = 3
else:
#보
if wall[build_frame[1]-1][build_frame[0]] == 1 or wall[build_frame[1]-1][build_frame[0]+1] == 1 or (wall[build_frame[1]][build_frame[0]-1] == 2 and wall[build_frame[1]][build_frame[0]+1] == 2):
#양쪽끝이 다른 보
wall[build_frame[1]][build_frame[0]] = 2
def delete(build_frame, wall):
prev = wall[build_frame[1]][build_frame[0]]
#일단 지우고
if wall[build_frame[1]][build_frame[0]] == 3:
wall[build_frame[1]][build_frame[0]] = 3 - wall[build_frame[1]][build_frame[0]]
else: wall[build_frame[1]][build_frame[0]] = 0
possible = 0
#모든 벽이 조건 만족하는지 찾기
for i in range(len(wall)):
for j in range(len(wall)):
if wall[i][j] == 1:
#기둥 조건 만족?
if i == 0 or wall[i][j-1] != 1 or wall[i-1][j] != 2:
continue
else:
wall[build_frame[1]][build_frame[0]] = prev
return
elif wall[i][j] == 2:
#보 조건 만족?
if wall[i-1][j] !=2 or wall[i-1][j+1] !=2 or (wall[i][j-1] !=1 and wall[i][j+1] !=1):
continue
else:
wall[build_frame[1]][build_frame[0]] = prev
return
elif wall[i][j] == 3:
if i == 0 or wall[i][j-1] != 1 or wall[i-1][j] != 2 or wall[i-1][j] !=2 or wall[i-1][j+1] !=2 or (wall[i][j-1] !=1 and wall[i][j+1] !=1):
continue
else:
wall[build_frame[1]][build_frame[0]] = prev
return
def solution(n, build_frame):
answer = []
#기둥:1, 보:2, 둘다:3
wall = [[0]*(n+1) for _ in range(n+1)]
for i in range(len(build_frame)):
if build_frame[i][3] == 0:
delete(build_frame[i], wall)
else:
establish(build_frame[i], wall)
print(i, ": ", build_frame[i])
for j in range(len(wall)-1, -1, -1):
print(wall[j])
print("\n")
for i in range(len(wall)):
for j in range(len(wall)):
if wall[i][j] == 1:
tmp = [j, i, 0]
answer.append(tmp)
elif wall[i][j] == 2:
tmp = [j, i, 1]
answer.append(tmp)
elif wall[i][j] == 3:
tmp = [j, i, 0]
answer.append(tmp)
tmp = [j, i, 1]
answer.append(tmp)
answer.sort(key= lambda x:(x[0], x[1], x[2]))
return answer
print(solution(5, [[0,0,0,1],[2,0,0,1],[4,0,0,1],[0,1,1,1],[1,1,1,1],[2,1,1,1],[3,1,1,1],[2,0,0,0],[1,1,1,0],[2,2,0,1]]))
벽 사이즈만큼 리스트를 할당해 각 명령어마다 설치/삭제가 가능한지 판별하고 가능할때 해당 좌표에 비었을때 0, 기둥의 경우 1, 보는 2, 둘다 있을때는 3으로 바꾸어줬다.
둘다 있을때 3이 뭔가 문제가 나는것 같다. 파이썬 쓰면서 파이썬 활용 못하고 걍 갖다 하나하나 구현해버린듯 ㅋ.ㅋ
설치와 삭제 함수를 만들어 각 명령어 실행시 규칙에 맞는지 판별하였다.
설치는 맞게 되었는데, 삭제에서 모든 케이스를 분류하지 못해 오류가 났다 ,,,, 전체를 검사하는 방법으로 바꿨는데 마찬가지로 되지 않았다 ,,,,
def possible(answer):
for x,y,a in answer:
if a == 0:
#기둥이면
if y==0 or [x-1, y, 1] in answer or [x, y, 1] in answer or [x, y-1, 0] in answer:
continue
return False
elif a == 1:
#보이면
if [x, y-1, 0] in answer or [x+1, y-1, 0] in answer or ([x-1, y, 1] in answer and [x+1, y, 1] in answer):
continue
return False
return True
def solution(n, build_frame):
answer = []
for i in build_frame:
x, y, a, b = i
if b == 0:
answer.remove([x, y, a])
if not possible(answer):
answer.append([x, y, a])
if b == 1:
answer.append([x, y, a])
if not possible(answer):
answer.remove([x, y, a])
return sorted(answer)
이렇게 간단하게 끝내다니 ,,, 눈물이 날라하네 ,,
각 명령어마다 일단 설치/삭제하고 가능한지를 possible() 함수로 판단한다.
나처럼 따로 벽에 대한 배열을 두는 것이 아닌 answer에 설치된 구조물에 대한 좌표만 넣어놓고 in으로 판단한다. 똑똑한 파이썬,,
내일 다시 풀어보기 흑흑
리스트의 정렬 여러 조건으로
answer.sort(key = lambda x : (x[0], x[1], x[2])