2022년은 돌이켜보면 참 많은 일을 했다고 생각되면서도, 이것밖에 하지 못했나?라는 아쉬움도 가득한 한 해였다.

 

 

군 복무 중일 때 일이었다.

개발자로의 진로를 고민하고 있던 나에게 주변인들은 소프트웨어 마에스트로를 추천해 주었고,

왜인지 모르게 "이건 죽어도  꼭 하고 싶다!"라는 생각이 들었다.

 

 

소프트웨어 마에스트로를 알아보면서 코딩 테스트라는 걸 처음 접하게 되었고,

주변에 PS를 하던 선임을 따라 온라인 저지 사이트 '백준'과 '구름 IDE'를 활용하여 싸지방에서 매일 같이 문제 풀이에만 전념했다.

2021년 Github Streaks
2022 Github Streak

 

Solved.ac에서 제공하는 온라인 저지 사이트 티어 플러그인 덕분에 마치 게임을 하듯이 나의 '티어'를 올리기 위해서, 나를 도와주는 선임을 따라잡고 싶어서(플레티넘 5) 정말 열심히 풀었다.오죽하면 연등이 끝나고 밤에 화장실 간다고 하고 나와서 문제를 적어놨던 종이와 펜을 들고 변기에 앉아서 연필로 문제를 풀고, 다음 날 연등 시간에 맞춰보기도 했었다.

 

 

 

골절로 인한 통깁스 (약 2달 - 3달)

군 전역을 한 뒤 등록금과 생활금을 벌기 위해 겨울에 주유소에서 알바를 했었는데, 불의의 사고로 오른손이 골절되었던 적도 있었다. 물론 개의치 않고 왼손만 사용해서 타자를 치고, 문제를 풀었다.

 

 

그렇게 solved.ac 티어 골드에서 소프트웨어 마에스트로 13기 코딩테스트를 치렀다.

1차, 2차 코딩테스트 모두 완벽한 All Solved는 아니었지만, 운 좋게도 합격 문자를 받았다.

 

코딩테스트에서는 응시 PC 웹캠을 켜서 부정행위를 방지하는 시스템이 있었는데, "나 팔도 부러졌지만 진짜 열심히 하고 있어요"를 혹시 심사위원 중 한 분이라도 좋게 봐주시지 않을까? 하는 생각에 정말 열심히 풀었던 게 지금 생각하면 웃음이 나온다.

 

 

그렇게 최종 면접에 진출하게 되어 부랴부랴 면접 준비를 하고, 포트폴리오를 작성했고 달달 외우기를 반복했다.

 

소프트웨어 마에스트로 13기 최종 면접

면접은 5:5로 진행되었고, 포트폴리오를 이용해 1분간 자기소개 후 심사위원님들의 질의응답을 통해 이루어졌다.

 

내 소개가 되어 자기소개를 마치고 질의응답을 받는데, 포트폴리오가 별 게 없었는지 처음엔 알고리즘 질문을 하시다가 후반부엔 인공지능, AI 기술 사용 경험, 프로젝트 경험을 질문하셨는데 처음 제출했던 자소서에 AI 관련 프로젝트를 해보고 싶다고 작성했기 때문인 것 같다.

물론 관련 경험도 기술도 전무한 나는 제대로 대답을 드리지 못하고 아쉬움만 가득한 채 면접장을 나와야 했다.

 

나의 자기소개 및 질의응답 순서는 제일 마지막이었고, 같이 들어온 나머지 네 분의 포트폴리오와 면접 과정을 지켜볼 수 있었다. 나는 최대한 내가 해왔던 일, 의지를 담아 피력해 갔다고 생각했는데, 그들의 면접 과정을 지켜보니 한 없이 초라해지고 머리가 멍해지는 기분이 들었다.

 

사실 소프트웨어 마에스트로는 초보 개발자들을 위한 AtoZ 교육 기관이 아니다. 의지도 물론 중요하지만 어느 정도의 실력과 경험이 있는 지원자들이 모여서 팀을 꾸리고 본 과정 6개월 동안 서비스를 만들어나가는 것이다. 의지와 코딩테스트는 충분히 어필했어도 나는 절대적으로 코딩 실력과 경험이 모자랐다.



 

아쉽고 분하지 않았다면 이는 분명 거짓말 일 것이다.

하지만 13기 탈락을 통해 '지금의 나'는 감사함을 느끼고 있다.

 

13기 소프트웨어 지원자들의 면접 과정을 지켜볼 수 있었고, 다른 지원자들과 함께 포트폴리오와 개발 지식을 공유할 시간을 가질 수 있었다. 이를 통해 내가 부족한 게 어떤 점이고, 앞으로 어떻게 헤쳐나가야 할지 어렴풋이 알 수 있었다.

그 당시의 코딩 실력으로 운 좋게 합격했다 하더라도 과연 내가 팀원들에게 자신감 있게 손을 내밀 수 있었을까?

 

 

실패와 절망에 주저앉아 아무것도 하지 않는 건 내 취미가 아니다.

불합격 문자를 받고 즉시 2022년을 성장의 시간으로 여기기로 했고, 다양한 활동을 계획하고 성장을 위해 노력했다.

 


2022년 한 해간.. 

 

수상 경력

- 2022 SCH AI/SW Festival - AI 영상처리 기반 뇌졸중 전조증상 자가진단 서비스 대상 수상

- LINC 3.0 산학연협력융합교육 경진대회 현장실습 부문 - 대상 수상

- 2022 캡스톤디자인 및 AI 해커톤 최우수상 수상

- LINC 3.0 산학연협력융합교육 경진대회 학술제 부문 - 우수상 수상

 

인턴 경력

- 2022 하계학기 개발자 여름 인턴 - 자동화 프로그램 개발자

- 2022 동계학기 개발자 국가근로장학생 - Python Flask AI 영상/이미지 처리 및 백앤드 서버 개발자

- 2022 카카오 Tech 채용연계형 인턴십 - DPE 서류 1차 합격

 

순천향대학교 SW 프런티어 활동

- 2022 순천향대학교 SW프런티어 1기 수료

- 2022 순천향대학교 BLEP 프로젝트 - 백앤드 Spring 서버 개발

 

SW 중심대학 활동

- 2022 순천향대학교 TOPCIT 모의고사 및 17, 18회 정기 평가 우수학생 선발

- 2022 SW 오픈소스 동아리 디오니소스 - 팀 리더

- 2022 TOPCIT 18회 정기 평가 총점 507점

 

대외활동

- 2023 순천향대학교 멋쟁이사자처럼 11기 운영진 선발

- 2022 공개개발자대회 - Java Spring 백앤드 개발자 참가

 

자격증

- 정보처리산업기사 합격

 

PS

- 백준 Solved.ac 플레티넘 5


 

 

[아산뉴스] 순천향대, '2022 캡스톤 디자인 및 AI 해커톤 경진대회' 두각

‘2022 캡스톤 디자인 및 AI 해커톤 경진대회’ 참가자들이 기념촬영을 갖고 있다.<사진=대학제공>     © 아산뉴스- 순천향대-성균관대-호서대-제주대 4개 대학 공동으로 팀 구성-  

www.asannews.co.kr

 

 

화려하고 다양하진 않지만, 할 수 있었던 모든 일들에 최선을 다해 열심히 했다고 자부할 수 있겠다.

팔이 부러져 타자 한 번 칠 때마다 피멍이 들던 수술 직후 병실 내에서도,

여름 인턴 기회를 놓치기 싫어서 서울에 다 쓰러져 가는 1평짜리 고시원에서 머물 때도,

며칠 밤을 새워가며 프로젝트를 하고, 대회에 나가 작품을 출전할 때도,

포기하지 않을 수 있었던 건 내가 걷는 길의 끝에 언젠가 더 많은 사람들이 손을 내밀어주고, 내가 어려움에 손 내밀며 함께 나아갈 수 있을 거라는 확신이 있었기 때문이었다.

모쪼록 아직도 부족한 게 많고 나아가야 할 길은 멀기만 하지만, 나는 어김없이 또 일어나서 나아갈 것이다.

나는 더 성장하고 싶고, 더 나아가고 싶다. 느리던 빠르던 상관없이 결국엔 나아가고 있다는 게 중요하다.

지금 이 글을 읽는 여러분도 언젠가 뒤를 돌아봤을 때 생각보다 더 많이 왔다고 느낄 수 있는, 그런 한 해가 되었으면 좋겠다.

https://www.acmicpc.net/problem/16953

 

16953번: A → B

첫째 줄에 A, B (1 ≤ A < B ≤ 109)가 주어진다.

www.acmicpc.net

 

"""
a - > b
1. 곱하기 2
2. 1을 수의 가장 오른쪽에 추가

"""
a, b = map(int, input().split())
count = 1

def go(a, b, count):
    if a == b:
        print(count)
        exit()
    if a > b:
        return
    go(a * 2, b, count + 1)
    go(int(str(a) + "1"), b, count + 1)


go(a, b, count)
print(-1)

 

재귀 함수를 이용하여 푼 문제

재귀의 조건을 살펴보자

1. A와 B가 같은 값이면 재귀 종료

2. A가 B보다 커지면 재귀 종료

3. 1-2에 해당하지 않는 경우 매 순간 a에 대해 곱하기 2, 1을 추가 해주면 됨

 

백준 알고리즘 No.1248번 맞춰봐 문제

def check(index):
    s = 0
    for i in range(index, -1, -1):
        s += ans[i]
        if sign[i][index] == 0:
            if s != 0:
                return False
        elif sign[i][index] < 0:
            if s >= 0:
                return False
        elif sign[i][index] > 0:
            if s <= 0:
                return False
    return True

def go(index):
    if index == n:
        return True
    if sign[index][index] == 0:
        ans[index] = 0
        return check(index) and go(index + 1)

    for i in range(1, 11):
        ans[index] = i * sign[index][index]
        if check(index) and go(index + 1):
            return True
    return False


n = int(input())
s = input()
sign = [[0] * n for _ in range(n)]
ans = [0] * n
cnt = 0
for i in range(n):
    for j in range(i, n):
        if s[cnt] == '0':
            sign[i][j] = 0
        elif s[cnt] == '+':
            sign[i][j] = 1
        else:
            sign[i][j] = -1
        cnt += 1
go(0)
print(' '.join(map(str, ans)))
"""
-10 ~ 10 까지 N개의 정수로 이루어진 수열 A (N <= 10)
S[i][j] = A[i] ~ A[j] 까지의 합,
S[i][j]가 0보다 크면 +, 작으면 -, 같으면 0을 출력
S가 주어졌을 때, 가능한 A를 찾는 문제

각 자리마다 21가지의 수를 구해 넣어주저야 함
O(21^10)은 너무 큰 수로 BRUTE FORCE로는 해결이 어려움


----시간초과를 해결 할 방법 첫번째----
s[i][i] = A[i]의 부호
s[i][i] > 0 1~ 10
        = 0 0
        < 0 -10 ~ -1
로 경우의 수를 10^10로 줄일 수 있다.
하지만 10^10은 100억으로 시간초과.

----두번째----
i번째의 수를 정하면 S[j][i]의 부호를 모두 검사할 수 있다.
"""

 

  • 정보·통신 생성 시스템에서, 문제의 해답을 구하기 위한 추론 제어 방식의 하나. 규칙을 적용하여 얻은 결과가 틀리면  규칙을 적용한 다음부터 현재까지의 결과를 무시하고 처음으로 돌아가서 다른 규칙을 선택하여 다시 시도한다.

-표준 국어 대사전에서 발췌-

 

 

일반적으로 재귀함수에서 더 이상의 호출이 의미 없을 때, 중간에 재귀함수를 중단시키는 알고리즘을 의미한다.

백준 14889번, 15661번 스타트 링크 문제를 통해 백트래킹에 대해 알아보자.

 

 

1 ~ N까지의 번호 중 2개의 팀을 각 N/2명으로 나누어야 한다.

2. 이때 S[I][J] = i번 사람과 j번 사람이 같은 팀일 때 팀에 더해지는 능력치이다.

3. 팀의 능력치 : 팀에 속한 모든 s[i][j]쌍의 합이다.

4. 문제 요구 사항 : 두 팀의 능력치를 구하고 차이의 최소를 구하라

 

해당 문제를 요구 사항에 맞게 코딩하면

 

def go(index, first, second):
    if index == n:
        if len(first) != n // 2:
            return -1
        if len(second) != n // 2:
            return -1
        t1 = 0
        t2 = 0
        for i in range(n // 2):
            for j in range(n // 2):
                if i == j:
                    continue
                t1 += s[first[i]][first[j]]
                t2 += s[second[i]][second[j]]
        diff = abs(t1 - t2)
        return diff
    ans = -1

    t1 = go(index + 1, first + [index], second)
    if ans == -1 or (t1 != -1 and ans > t1):
        ans = t1
    t2 = go(index + 1, first, second + [index])
    if ans == -1 or (t2 != -1 and ans > t2):
        ans = t2
    return ans


n = int(input())
s = [list(map(int, input().split())) for _ in range(n)]
print(go(0, [], []))

이런 코드가 나오게 된다.

 

index : 사람을 어떤 팀에 넣을지 (스타트 팀, 링크 팀)

first : 1번 팀, second : 2번 팀

index == n 일 경우 함수 종료

first나 second의 팀 수가 n//2를 넘어가게 되면(딱 절반이어야 하는데 넘어갈 때)  -1 반환

 

하지만 index == n 일때 

first나 second가 n//2가 아님을 검사하게 되면

결국 index는 n 만큼의 재귀를 실행하게 된다. 

만약 first나 second가 (n이 8일 때) 5를 넘었을 때 바로 종료한다면 더 시간을 단축할수 있을 것이다.

 

이때를 위해 백트래킹 방법이 사용된다.

재귀 중간에, 특정 상황(의미 없는 재귀가 반복된다고 판단)에서 재귀를 종료시키는 구문을 넣어준다.

 

def go(index, first, second):
    if index == n:
        if len(first) != n // 2:
            return -1
        if len(second) != n // 2:
            return -1
        t1 = 0
        t2 = 0
        for i in range(n // 2):
            for j in range(n // 2):
                if i == j:
                    continue
                t1 += s[first[i]][first[j]]
                t2 += s[second[i]][second[j]]
        diff = abs(t1 - t2)
        return diff
    ans = -1
    if len(first) > n // 2:
        return -1
    if len(second) > n // 2:
        return -1

    t1 = go(index + 1, first + [index], second)
    if ans == -1 or (t1 != -1 and ans > t1):
        ans = t1
    t2 = go(index + 1, first, second + [index])
    if ans == -1 or (t2 != -1 and ans > t2):
        ans = t2
    return ans


n = int(input())
s = [list(map(int, input().split())) for _ in range(n)]
print(go(0, [], []))

 

따라서 중간에

if len(first) > n // 2:
    return -1
if len(second) > n // 2:
    return -1

 

를 넘어줌으로써, 시간을 절약시킬 수 있다.

+ Recent posts