무선 충전 - SWEA

무선 충전 - SWEA

dx = [0, -1, 0, 1, 0]
dy = [0, 0, 1, 0, -1]

def power(u):
    p = [0] * A
    for i in range(A):
        if abs(u[0] - ap[i][1] + 1) + abs(u[1] - ap[i][0] + 1) <= ap[i][2]:
            p[i] = ap[i][3]
    return p

def calculate(p1, p2):
    ret = 0
    if A == 1: return max(p1[0], p2[0])
    for i in range(A):
        for j in range(A):
            if i != j:
                ret = max(p1[i] + p2[j], ret)
    return ret

T = int(input())

for test_case in range(1, T + 1):
    M, A = map(int, input().split())
    ma = list(map(int, input().split()))
    mb = list(map(int, input().split()))
    ap = [list(map(int, input().split())) for _ in range(A)]

    ua = [0, 0]
    ub = [9, 9]
    _sum = 0
    _sum += calculate(power(ua), power(ub))

    for i in range(M):
        ua[0] += dx[ma[i]]
        ua[1] += dy[ma[i]]
        ub[0] += dx[mb[i]]
        ub[1] += dy[mb[i]]
        _sum += calculate(power(ua), power(ub))

    print("#" + str(test_case) + " " + str(_sum))

'코딩테스트 > SWEA' 카테고리의 다른 글

[SWEA] 1244 최대상금 python  (0) 2020.07.17

배열 B의 값 - BOJ

배열 B의 값 - BOJ

문제 예시의 4X4 배열을 예시로 든다면
0, 1, 2, 3행에서 1,2 행을 바꿔도 최대값이 바뀌지 않을 것임.
따라서 (중간 행 중에서 최소값)과 (0행 or 마지막 행) 중에 행을 하나 교환하거나
열에서도 똑같은 작업을 해서 최대값을 구하면 된다.

def calculate(board):
    _sum = 0
    for i in range(N - 1):
        for j in range(M - 1):
            _sum += board[i][j] + board[i + 1][j] + board[i + 1][j + 1] + board[i][j + 1]
    return _sum

def newmap(x, y, rc): # rc -> r인지 c인지
    b = [[0] * M for _ in range(N)]
    for i in range(N):
        for j in range(M):
            b[i][j] = a[i][j]
    if rc:
        for c in range(M):
            b[x][c], b[y][c] = a[y][c], a[x][c]
    else:
        for r in range(N):
            b[r][x], b[r][y] = a[r][y], a[r][x]
    return b

N, M = map(int, input().split())
a = [list(map(int, input().split())) for _ in range(N)]
row = [0] * N
col = [0] * M
r_min = float('inf')
c_min = float('inf')
min_col, min_row = -1, -1

ret = calculate(a)

# 각 행열 합 계산
for i in range(N):
    for j in range(M):
        row[i] += a[i][j]
        col[j] += a[i][j]

# 최소 크기 행
for r in range(1, N - 1):
    tr = row[r] * 4
    tr -= 2 * (a[r][0] + a[r][M - 1])
    if r_min > tr:
        r_min = tr
        min_row = r

# 최소 크기 열
for c in range(1, M - 1):
    tc = col[c] * 4
    tc -= 2 * (a[0][c] + a[N - 1][c])
    if c_min > tc:
        c_min = tc
        min_col = c

if min_row > 0:
    new = newmap(0, min_row, 1)
    ret = max(ret, calculate(new))
    new = newmap(N - 1, min_row, 1)
    ret = max(ret, calculate(new))

if min_col > 0:
    new = newmap(0, min_col, 0)
    ret = max(ret, calculate(new))
    new = newmap(M - 1, min_col, 0)
    ret = max(ret, calculate(new))

print(ret)

'코딩테스트 > BOJ' 카테고리의 다른 글

[BOJ] 1806 부분합 (python)  (0) 2020.11.08
[BOJ] 17136 색종이 붙이기 (python)  (0) 2020.09.18
[BOJ] 16929 Two Dots (python)  (0) 2020.09.03
[BOJ] 10026 적록색약 (python)  (0) 2020.09.03
백준 #5052 전화번호목록 (Python)  (0) 2020.04.16

Two Dots - BOJ

Two Dots - BOJ

dx = [0, 0, -1, 1]
dy = [-1, 1, 0, 0]

def dfs(x, y, cnt):
    global tx, ty, flag
    if flag: return
    for i in range(4):
        nx = x + dx[i]
        ny = y + dy[i]
        if nx < 0 or ny < 0 or nx >= N or ny >= M or a[nx][ny] != a[tx][ty]: # 범위 벗어나지 않고, 색깔이 같을 때만 하도록
            continue
        if not visit[nx][ny]:
            visit[nx][ny] = True # 방문처리 했다가
            dfs(nx, ny, cnt + 1)
            visit[nx][ny] = False # 안한 걸로
        else:
            if cnt >= 4 and tx == nx and ty == ny: # 4번 이상이고 위치가 같을 때 -> 사이클
                flag = True
                return

N, M = map(int, input().split())
a = [list(input()) for _ in range(N)]
visit = [[False] * M for _ in range(N)]
flag = False

for i in range(N):
    for j in range(M):
        if not visit[i][j]:
            tx, ty = i, j
            visit[i][j] = True
            dfs(i, j, 1)
        if flag:
            print("Yes")
            exit(0)

print("No")

적록색약 - BOJ

적록색약 - BOJ

from collections import deque
from copy import deepcopy

dx = [1, -1, 0, 0]
dy = [0, 0, -1, 1]

def a_bfs(i, j):
    cnt = 0
    q1 = deque()
    q1.append((i, j))
    a_visit[i][j] = True
    while q1:
        x, y = q1.popleft()
        for k in range(4):
            nx = x + dx[k]
            ny = y + dy[k]
            if nx < 0 or ny < 0 or nx >= N  or ny >= N or a_visit[nx][ny]:
                continue
            if a[nx][ny] == a[i][j]:
                a_visit[nx][ny] = True
                q1.append((nx, ny))


def b_bfs(i, j):
    cnt = 0
    q2 = deque()
    q2.append((i, j))
    b_visit[i][j] = True
    while q2:
        x, y = q2.popleft()
        for k in range(4):
            nx = x + dx[k]
            ny = y + dy[k]
            if nx < 0 or ny < 0 or nx >= N or ny >= N or b_visit[nx][ny]:
                continue
            if b[nx][ny] == b[i][j]:
                b_visit[nx][ny] = True
                q2.append((nx, ny))


N = int(input())
a = [list(input()) for _ in range(N)]
b = deepcopy(a)
for i in range(N):
    for j in range(N):
        if b[i][j] == 'G':
            b[i][j] = 'R'

a_visit = [[False] * N for _ in range(N)]
b_visit = [[False] * N for _ in range(N)]

a_cnt = 0
b_cnt = 0

for i in range(N):
    for j in range(N):
        if not a_visit[i][j]:
            a_bfs(i, j)
            a_cnt += 1
        if not b_visit[i][j]:
            b_bfs(i, j)
            b_cnt += 1

print(a_cnt, b_cnt)

'코딩테스트 > BOJ' 카테고리의 다른 글

[BOJ] 16971 배열 B의 값 (python)  (0) 2020.09.04
[BOJ] 16929 Two Dots (python)  (0) 2020.09.03
백준 #5052 전화번호목록 (Python)  (0) 2020.04.16
백준 #13549 숨바꼭질3 (Python)  (0) 2020.04.12
백준 #9251 LCS [Python]  (0) 2020.03.27

 

프로그라피라는 개발 모임에 있을 때 다양한 스타트업에서 근무하는 사람들을 많이 만날 수 있었고, 자연스럽게 Project Managing과 관련된 용어들을 많이 접하게 되었다. 그중에서도 몇몇 용어는 추후에도 프로젝트를 진행함에 있어서 도움이 될 것 같은 용어와 방법론들이라 공유를 해볼까 한다.

 

KPT

애자일에서는 회고라는 말이 자주 쓰인다. 소프트웨어공학 수업을 들을 때도 그런 것을 느꼈고, 이번에 개편된 기사 공부를 할 때에도, 또한 동아리에서 프로젝트를 진행할 때에도 자주 접했던 단어이다. 실제로 협업 프로젝트를 하면서 이전에 진행된 사항에 대한 follow-up이 제대로 숙지되지 않는다면, 다음 단계로 넘어갈 때 삐걱대기 십상이다. 회고에서는 KPT라는 방식을 자주 사용한다고 한다. 각 약자의 의미는 다음과 같다.

 

K = Keep, 좋았던 점, 유지해야 할 점

P = Problem, 나빴던 점, 문제점

T = Try, 개선해야 할 점, 도전해야 할 점

 

팀 멤버 각자의 관점에서 KPT를 작성하고 공유하면서, 좀 더 프로젝트에 대해 팀원 각자가 가지고 있는 생각을 자세히 알 수 있고, 현재의 문제점에 대해 이 KPT에 대한 피드백을 서로 공유하며 해결점에 도달할 수 있을 것이라 생각된다. 

 

Try가 Problem을 해결하기 위한 단서로서 회고에 있어서 가장 중요한 부분이라 느껴지는데, '~한 것을 조심하자'보다는 구체적인 Action(방법, 프로세스, tool) 이 드러나는 것으로 선정하는 것이 좋다.

 

OKR

OKR은 Obejectives & Key Result 의 약자이다. 구글이 사용하는 목표 관리 방법론이라고 잘 알려져 있는데, MBO(Management by Objective)에서의 KPI가 Top-Down 방식의 목표 관리 방식이며, 성과관리 시스템과의 직접적인 연계라는 단점을 가지고 있는데, 이 KPI의 개선을 위해 만들어진 방법론이 바로 OKR이라고 한다. 방법론을 살펴보면 다른 것보다도 직원들, 팀원들의 동기 부여에 목적이 있는 것으로 생각된다.

 

Objectives는 현재 목표보다도 상위 단계로 '추구하고자 하는 이상', '도전적인 목표' 정도로 번역하면 맞을 것 같다. 다시 말해 쉽게 성취할 수 없는 목표여야 하며, 그만큼 구체적으로 서술되어야 한다.

 

Key Result는 Objectives에서 설정한 목표가 달성되었는지를 판단할 수 있는 단서라고 보면 된다. 한 Objective 당 3개 정도의 Key Result가 나올 수 있고, 후에 Objectives의 성취도를 판단할 때에 이 Key Result가 어느 정도 완성되었는지를 판단하면 된다. 무조건적으로 정량적으로 평가되어야 하는 것은 아니지만, 측정 가능한 수치로 설정하는 것이 좋다.

 

Objectives의 60~70% 정도의 성취도도 충분히 높은 성취로 볼 수 있다. OKR은 일반적으로 한 분기의 사이클로 이루어지는데, 한 분기 안에서 도전적인 목표를 성취하기는 쉽지 않은 일이기 때문이다. 

 

팀적으로 OKR이 설정되었다면, 그에 부합하는 개인의 OKR도 설정되어야 한다. 또한 OKR을 달성할 수 있을 것인가라는 확신(자신감 점수)을 초기에 10점 만점에 5점으로 설정해놓고, 주마다 진행되는 Key Result 리뷰에서 해당 자신감 점수를 작성하게 하고 점수에 대한 피드백을 팀원간에 공유한다. 만약 이 자신감 점수가 너무 낮다면, 왜 잘 안되고 있는가에 대해 의논을 해보야할 시점일 것이다.

 


프로젝트를 한참 진행하는 플레이어의 입장에서 있을 때는 이러한 툴과 방법론의 중요성을 잘 몰랐다. 기획-개발-배포의 단계로 하나의 서비스를 개발해오면서 당연히 삐걱대는 요소들이 존재하였고, 그것은 결과적으로 팀에 마이너스로 다가왔다. 수많은 스타트업의 무수한 팀들이 겪었던 문제 해결과 고민의 끝에 나온 방법론이 이러한 것이고 "그러한 것들"이라고 치부했던 것들의 중요성을 이제는 체감할 수 있다.

 

Reference

안드로이드 액티비티 생명주기

이번에 Django rest api 서버 포지션으로 안드로이드와 협업하는 경험이 있었다.

안드로이드 어플을 개발함에 있어서 안드로이드 컴포넌트 중 하나인 액티비티 생명주기에 대해 깊은 이해가 필요한 것을 보고 정리하게 되었다.

액티비티 생명주기

수명주기 콜백 메서드

onCreate()

  • 액티비티가 생성될 때 호출되면 사용자 인터페이스 초기화에 사용됨.
  • 필수적으로 구현해야 함.
  • 데이터를 목록에 바인딩하고, 액티비티를 ViewModel과 연결하고, 일부 클래스 범위 변수를 인스턴스화할 수 있음.
  • 이후 시스템이 연달아 onStart()와 onResume() 메서드를 호출

onStart()

  • 액티비티가 사용자에게 보여지기 바로 직전에 호출됨.
  • 앱은 액티비티를 포그라운드에 보내 상호작용할 수 있도록 준비
  • 앱이 UI를 관리하는 코드를 초기화
  • onStart() 메서드는 매우 빠르게 완료되고, 이후 onResume() 메서드를 호출함

onResume()

  • 액티비티가 사용자와 상호작용하기 바로 전에 호출됨.
  • 전화, 다른 액티비티으로 이동, 기기 화면이 꺼지는 등의 이벤트가 발생하여 앱에서 포커스가 떠날 때까지 onResume() 상태에 머무름.
  • 방해되는 이벤트 발생시 시스템이 onPause() 콜백을 호출
  • 액티비티가 일시중지됨 상태에서 재개됨 상태로 돌아오면 시스템이 onResume() 메서드를 다시 한번 호출함. 따라서 onResume()을 구현하여 onPause() 중에 해제하는 구성요소를 초기화하고, 액티비티가 재개될 때마다 필요한 다른 초기화 작업도 수행해야 함.

onPause()

  • 다른 액티비티가 보여질 때 호출됨. 데이터 저장, 스레드 중지 등 처리할 때 쓰이는 메소드
  • 사용자가 액티비티에서 떠나는 첫 신호로 시스템은 onPause() 메서드를 호출. 액티비티가 포그라운드에 있지 않다는 것을 나타냄.
  • 구성요소가 포그라운드에 있지 않을 때 실행할 필요가 없는 기능을 모두 정지할 수 있음.
  • opPause()는 아주 잠깐 실행되므로 저장 작업을 실행하기에는 시간이 부족할 수 있음. 따라서 onPause()를 사용하여 애플리케이션 또는 사용자 데이터를 저장하거나, 네트워크 호출을 하거나, 데이터베이스 트랜잭션을 실행하면 안 됨. 부하가 큰 종료 작업은 onStop() 상태일 때 실행해야 함.

onStop()

  • 액티비티가 더 이상 사용자에게 보여지지 않을 때 호출됨.
  • 새로 시작된 액티비티가 화면 전체를 차지할 경우에 적용.
  • 구성요소가 화면에 보이지 않을 때 실행할 필요가 없는 기능을 모두 정지할 수 있음.
  • 앱이 사용자에게 보이지 않는 동안 앱은 필요하지 않은 리소스를 해제하거나 조정해야 함.
  • 멀티 윈도우 모드를 더욱 잘 지원하기 위해 UI 관련 리소스와 작업을 완전히 해제하거나 조정할 때 onPause() 대신 onStop()을 사용하는 것이 좋음.
  • onStop()을 사용하여 CPU를 비교적 많이 사용하는 종료 작업을 실행해야 함. 예를 들어 정보를 데이터베이스에 저장할 적절한 시기를 찾지 못했다면 onStop() 상태일 때 저장할 수 있음.
  • 액티비티가 중단됨 상태에 들어가면 액티비티 객체는 메모리 안에 머무르게 된다.
  • 액티비티가 다시 시작되면 시스템은 onRestart()를 호출. 액티비티가 실행을 종료하면 시스템은 onDestroy()를 호출.

onRestart()

  • 액티비티가 멈추었다가 다시 시작되기 바로 전에 호출됨.

onDestroy()

  • 액티비티가 소멸될 때 호출됨. finish() 메소드가 호출되거나 시스템이 메모리 확보를 위해 액티비티를 제거할 때 호출됨.
  • 구성 변경으로 인해 onDestory()가 호출되는 경우 시스템이 즉시 새 활동 인스턴스를 생성한 다음, 새로운 구성에서 그 새로운 이스턴스에 관해 onCreate()를 호출

Reference

+ Recent posts