본문 바로가기
회사를 추억하며 #1 이전 회사를 9년 가까이 다녔기에 여러 사람을 만났다. 그래서인지 많은 일이 있었다. 무엇보다 사람이 생각난다. 나는 늦게 합류했지만, 앞서 회사를 창업할 때 함께 한 이들. 대단한 사람들이었다. 이들에 대해 익명으로 써보고자 한다. 그런 거장들과 함께 일한 것으로도 사실 영광이다. 게다가 나의 장년 대부분을 장식한 추억이니까 ... 그 사람은 고기를 무척 좋아했다. 덩치도 매우 좋았다. 회사에는 항상 운동복 차림에 크로스백을 맸고 60인치에 달하는 4K 텔레비전을 모니터로 썼다. 그럼에도 아이러니하게도 글꼴 크기는 100 포인트가 넘었다. 조망이 전혀 안되는데도 코딩 솜씨는 그야말로 최고였다. 템플릿 라이브러리를 처음부터 혼자 짤 수 있었다. 믿을 수 없는 수준이었다. 컴파일러 레벨까지 완전히 알고 있.. 2020. 3. 3.
200224 최근에 그야말로 난리가 났다. 감염자가 생기면 회사가 휴업하게 되니 무조건 마스크를 쓰라고 공지가 왔다. 그런데 신종 플루나 메르스가 유행할 때는 어떻게 했었는지 기억이 안 난다. 분명 그 때도 회사를 다니고 일했었는데... 과거는 아름다워서 그런가. 동료에게도 물었는데 그도 잘 생각이 안 난다고 했다. 하긴 블랙 먼데이도 누군가에게는 끔찍한 과거지만, 또 어떤 이에게는 인생 전환의 기회가 되었다. 불운이 내게 닥치지 않는다면 이것도 그저 잊혀지리라. 문제는 마치 현재가 영원한 것처럼 보이는 것이지만... 그러나 공부를 하며 라디오를 들으니 세상 시름도 잊고 좋다. 나만 다른 세상에 사는 것처럼 말이다. 오늘은 유니티 튜토리얼을 좀더 했다. 간단히 속성을 다루거나 따라하는 건 지루했다. 코드로 진행하는 .. 2020. 2. 24.
django 과제 전환 배치 기간 동안 이것저것 공부를 해보았다. 한가지만 팔 것 그랬나 생각도 들지만... 암튼 그 중에 웹 백엔드 프로그래밍을 시도해봤다. 장고는 파이썬 기반이기에 무척 익숙하다. 물론 백엔드는 낯설지만. 그런데 너무 늦게 이걸 보았고, 지원한 다른 곳에서도 nodejs 기반의 코드 과제를 주었다. 게다가 아이는 입원... 다행히 부인님이 도와줘서 밤 늦게 집에 온 뒤 새벽까지 짰다. 다음 날 오전 중에 수정해서 제출했다. 역시 이런 쪽의 학습 없이 도전해서 그런지 탈락했다. 면접 제의는 없었으니까. 점수가 무척 낮은데 상위라서 조금 놀랐다. 아마 지원하고 완성하지 않은 이가 많았으리라 짐작한다. 조금 더 열심히 해봤으면 어땠을까. 뭐 이미 지난 일이고... 일단 너무 늦게 과제를 보았다. 무엇보다 내.. 2020. 2. 22.
200219 오늘은 엔씨소프트를 관두는 오랜 지인을 만나 식사를 했다. 그는 이야소프트 시절부터 알던 친구같은 동생이다. 그는 QA로 일하고 있었다. 성실하고 언변도 뛰어났다. 마침 회사에서 기획자 수업 과정을 외부에서 받을 수 있는 기회를 주었다. 그는 기획에 욕심이 있는 까닭에 하고 싶어했다. 그러나 정규직만 가능했다. 나는 꾀를 냈다. 내 명의로 신청하고 그가 가는 걸로... 수업이 끝난 후 회사에서 사실을 알아챘다. 그러나 그다지 문제되지 않고 넘어갔다. 어쨌든 난 가능하다면 돕고 싶었다. 그리고 그에게 기회가 왔다. 수업을 진행한 교수가 자리를 제의했다. 아마 거울전쟁이었나. 그런데 슈팅 게임이었다. 또 하나는 이야소프트의 던전 히어로 개발 쪽이었다. 고민하는 그에게 나는 MMORPG 쪽을 하길 권했다. 그.. 2020. 2. 19.
200218 번복을 걱정했던 팀내 다른 분이 마침내 자리를 옮기셨다. 나는 번복당하고 그 충격이 엄청났다... 왜 회사에 남아서 수모를 당해야할까. 게임, 비게임 모두 기회가 있었다. 그러나 그 후에는 운이 없었다. 다음 기회를 잡기 위해 2개월을 기다려야했다. 기분이 나아졌지만 그때는 세상에서 제일 못난 사람이 나였다. 그래도 다행이다. 그 분은 실력있고 성실한 분이다. 그 팀에서도 분명 잘해내실 것이다. 내가 옮긴 팀에서는 DirectX와 셰이더를 주로 다룬다. 그간 게임 엔진만 알면 된다고 등한시했던 것을 말이다. 전환배치 기간 동안 느낀 점이 있는데 무언가 알아가는 건 재밌다는 사실이다. 구글 퀵랩도 해보고 장고나 nodejs로 웹서버 프로그램도 짜봤다. 그런데 왜 게임은 안 만들었을까. 그런 준비가 안되어있.. 2020. 2. 18.
Valid Parentheses https://leetcode.com/problems/valid-parentheses/ 괄호가 잘 닫혔는지 검사하는 문제 class Solution: def isValid(self, s: str) -> bool: stack = [] pairs = { ')' : '(', ']' : '[', '}' : '{', } for ch in s: if ch in ( '(', '[', '{' ): stack.insert( 0, ch ) else: if not stack: return False else: openBracket = stack.pop( 0 ) if pairs[ ch ] != openBracket: return False return not stack 2020. 2. 12.
Min Stack https://leetcode.com/problems/min-stack/ 스택을 구현하는 문제. 쉽다. class MinStack: def __init__(self): """ initialize your data structure here. """ self.__min = float( 'inf' ) self.__stack = [] def push(self, x: int) -> None: self.__min = min( self.__min, x ) self.__stack.insert( 0, x ) def pop(self) -> None: stack = self.__stack value = stack[ 0 ] self.__stack = stack[ 1 : ] if value == self.__min: self.. 2020. 2. 12.
200211 잘한 일: 쌓인 책 정리 2020. 2. 12.
200210 어제는 치통으로 몹시 괴로웠다. 그덕인지 눈도 왜 이리 아픈지... 참을 수 없어 진통제를 사러갈 정도였다. 이 끔찍한 경험은 20대 초반에 해본 이후로 다시는 겪지 않으려 애썼다. 매년 치과에 가고 스케일링도 하고 의사 하라는대로 다하고 최근에는 치실도 매일 하는데 이런 일이 생겼다. 약을 먹고 괴로워하다 낮잠을 자고나니 조금 나아졌다. 진통제를 안 먹고 버티다가 통증이 와서 다시 먹었다. 취침 시간부터 다시 고통이 찾아왔다. 물을 머금으면 나아져서 계속 그랬다. 덕택에 잠을 잘 수 없었다. 엎어져서 신음하다 잠이 들었다. 아침에는 조금 나아졌다. 팀을 옮긴지 첫날부터 연차를 쓰게 생겼다. 몹시 공교롭지만 어쩔 수 없다. 오늘 잘한 일: 아이하고 게임을 만들기 위해 스크래치를 살펴보았다. 만들기 쉽지만.. 2020. 2. 12.
초보 게임 개발자들을 위한 원로개발자 톰의 충고 언제인지 모르겠다. 아마 내가 http://ehei.x-y.net이란 블로그를 운영하고 있었을 때일 것이다. 아마 20년 가까이 전인 것 같다... 그 때는 게임 개발을 하고 싶어 몸이 달아 있었고 영어 공부도 하고 싶었다. 어디선가 http://www.sloperama.com/ 라는 사이트를 추천받았고 글을 제법 좋다고 생각했었던 것 같다. 그래서 겁도 없이 번역을 해보았다... 그런데 이걸 인터넷에서 찾아낼 수 있었다. 내가 워드 파일로 만들었었나... 기억은 없는데 누군가 깔끔히 정리해주신 것 같다. 저자를 보니 강석규님이라고 나오는데 감사드린다. 사실 살면서 잃어버리는 것이 누구나 있을 것이다. 나만 해도 그렇다. 예전에 그렸던 그림들, 작성했던 글들(특히 게임스팟에 썼던 게임 리뷰 글)이 없어진.. 2020. 1. 15.
가정 속의 마르지 않는 금맥 책은 부동산 투자로 부를 축적한 사람이 썼다. 최초에는 집을 소유할 것을 주장한다. 그러다 집 안에도 자산이 있음을 논한다. 나만 해도 집에 필요없는 물품을 헐값에 팔아버리는 쪽이긴 하다. 저자는 거기서 더 나간다. 생활용품 같은 소비재도 일종의 자산이며 사람들은 그걸 주기적으로 산다고 한다. 따라서 그런 소비재를 파는 사업에 종사하면 부를 얻을 수 있다고 주장한다. 그래서 금맥이란 단어가 나왔다. 아마 그런 사람을 프로슈머라 하나보다. 책에서 몇 번이고 그 말이 나온다. 명시적으로 언급하지는 않았지만 내가 도매업자가 아니라면 다단계 외에는 없을 것이다. 책이 주장하는 바는 맞다. 허나 그런 사업을 하는 주식을 사는 편이 좋다고 생각한다. 플랫폼에 종속되어 사업을 한다면 수익성이 있을까 의심한다. 어디나.. 2019. 12. 10.
또 가족이 생긴 날 결혼을 약속한 후 어느 날. 나는 그녀에게 입양을 하고 싶다고 했다. 후원도 좋지만 가족으로 인생을 책임져주고 싶다고 했다. 그녀도 찬성했다. 그녀는 마음씨가 곱다. 10년 동안 보육원에서 봉사했고, 2년 간 장애우 시설에서도 도왔다. 누구에게 의지하지 않고 다른 사람 탓도 하지 않는다. 돈이 있으면 쓰고 없으면 안 쓴다. 그런 그녀이기에 말을 꺼냈던 것 같다. 나는 친자가 없어도 입양 만으로도 좋다고 했다. 웬걸. 그녀는 반드시 친자를 키워보고 입양해야 한다고 했다. 애를 키워보지 않으면 선입견에 빠질 것이라고 했다. 나는 나름 차별은 모르는 사람이라 생각해서 그렇지 않을거라고 했다. 그러나 이걸 내 고집대로 할 수는 없는 노릇. 세월이 흘러 아이를 낳아 키우고 입양을 할 수 있는 기회가 왔다. 우리 .. 2019. 12. 10.
Target Sum https://leetcode.com/problems/target-sum/ 주어진 값 S가 되도록 제시된 정수 집합으로 조합을 찾는 문제. 부호가 +,-가 될 수 있다. 어차피 모든 조합을 검사해야 하므로, 동적 프로그래밍 기법을 써서 반복 계산을 피해야 한다. import collections class Solution: def findTargetSumWays( self, nums, S: int ) -> int: if not nums: return 0 # key: remain nums, value: sum cases caches = collections.defaultdict( lambda : collections.defaultdict( int ) ) count, _ = self.__findTargetS.. 2019. 12. 4.
Clone Graph https://leetcode.com/problems/clone-graph/ 그래프를 복사하는 문제. 결국은 모든 노드를 방문하므로, 이미 가본 곳만 가지 않도록 주의한다. """ # Definition for a Node. class Node: def __init__(self, val, neighbors): self.val = val self.neighbors = neighbors """ class Solution: def cloneGraph(self, node: 'Node') -> 'Node': visited = {} return self.__cloneGraph( node, visited ) def __cloneGraph( self, node, visited ): if node.val in visit.. 2019. 11. 26.
Perfect Squares 어떤 정수가 주어졌을 때, 제곱이 되는 수로 어떤 합이 결정되는지 구하는 문제 https://leetcode.com/problems/perfect-squares/ import math class Solution: def numSquares(self, n: int) -> int: currentValues = { n } count = 0 while currentValues: nextValues = set() for currentValue in currentValues: for i in range( 1, int( math.sqrt( currentValue ) ) + 1 ): remainValue = currentValue - i * i if not remainValue: return count + 1 elif.. 2019. 11. 25.
Open the Lock 숫자 네 개가 달린 자물쇠를 특정 숫자로 만드는 문제. 각 숫자는 한번에 한 칸만 옮겨진다. 난점은 막다른 골목(deadend)의 존재. 깊이 우선 탐색으로 해결하면 된다. https://leetcode.com/problems/open-the-lock/ class Solution: def openLock( self, deadends, target: str ) -> int: deadends = set( deadends ) currentNumbers = { '0000' } count = 0 visitedNumbers = set() while currentNumbers: visitingNumbers = set() for currentNumber in currentNumbers - deadends: if tar.. 2019. 11. 4.
Number of Islands 행렬에 있는 1의 뭉치를 세는 문제. 너비 우선 탐색을 쓰면 쉽게 해결된다 https://leetcode.com/problems/number-of-islands/ class Solution: def numIslands(self, grid: List[List[str]]) -> int: visited = set() count = 0 rowCount = len( grid ) if not rowCount: return 0 columnCount = len( grid[ 0 ] ) if not columnCount: return 0 for row, rowList in enumerate( grid ): for column, v in enumerate( rowList ): if v == '1': if self.__pai.. 2019. 11. 4.
Design Circular Queue 마지막 원소를 구하면 다시 첫 원소를 탐색하는 링 버퍼를 구현하는 문제 https://leetcode.com/problems/design-circular-queue/ class MyCircularQueue: def __init__(self, k: int): """ Initialize your data structure here. Set the size of the queue to be k. """ self.__queue = [ None ] * k self.__queueSize = k self.__head = 0 self.__tail = -1 self.__count = 0 def enQueue(self, value: int) -> bool: """ Insert an element into the circu.. 2019. 11. 1.
Unique Binary Search Trees II 정수 n이 주어질 때 1~n까지의 수로 이진 트리를 구성할 경우의 수를 얻는다. 역시 동적 프로그래밍 기법으로 같은 해를 반복하지 않도록 해야 한다 https://leetcode.com/problems/unique-binary-search-trees-ii/ # Definition for a binary tree node. # class TreeNode: # def __init__(self, x): # self.val = x # self.left = None # self.right = None # Definition for a binary tree node. class TreeNode: def __init__( self, x ): self.val = x self.left = None self.right =.. 2019. 10. 25.
K-th Symbol in Grammar 0부터 시작한다. 다음 줄부터는 0은 01로 1은 10으로 바꿔나간다. 이 때 줄의 개수 N이 주어질 때, K번째 항목이 뭔지 알아맞춰야 한다. 인덱스가 1부터 시작하니 주의. 트리의 깊이에 따라 패턴이 발견된다. 즉 왼쪽 노드는 부모와 값이 같고 오른쪽 노드는 반전된다. 이 점을 이용한다. # https://leetcode.com/problems/k-th-symbol-in-grammar/discuss/113710/Python-simple-solution-to-understand-with # -explanations class Solution: def kthGrammar( self, N: int, K: int ) -> int: if N == 1: return 0 return self.__kthGramme.. 2019. 10. 24.
Merge Two Sorted Lists 두 개의 연결 리스트를 정렬해서 하나로 합치는 문제 https://leetcode.com/problems/merge-two-sorted-lists/ # Definition for singly-linked list. # class ListNode: # def __init__(self, x): # self.val = x # self.next = None class Solution: def mergeTwoLists( self, l1: ListNode, l2: ListNode ) -> ListNode: if l1 is None: return l2 elif l2 is None: return l1 else: if l1.val < l2.val: head = l1 l1 = l1.next else: head = l2 l.. 2019. 10. 24.
Pow(x, n) x의 n제곱을 구하는 코드를 작성하는 문제. 빌트인 라이브러리로 너무나 쉽게 풀리는 문제지만, 그건 문제의 취지에 어긋나니 직접 풀었다. 너무 방심하다가 시간 초과로 고생... 캐시 적중율을 높이기 위해 최대한 짝수로 제곱하도록 나누었다. https://leetcode.com/problems/powx-n/ class Solution: def myPow(self, x: float, n: int) -> float: if not x: return 0 if 0 > n: x = 1 / x return self.__myPow3( x, abs( n ), { 0 : 1, 1 : x } ) def __myPow3( self, x, n, cache ): if n in cache: return cache[ n ] else:.. 2019. 10. 24.
Maximum Depth of Binary Tree 2진 트리의 깊이를 재는 문제. 깊이 우선 탐색을 쓰면 간단히 풀린다 https://leetcode.com/problems/maximum-depth-of-binary-tree/ # Definition for a binary tree node. # class TreeNode: # def __init__(self, x): # self.val = x # self.left = None # self.right = None class Solution: def maxDepth(self, root: TreeNode) -> int: if root is None: return 0 else: return self.__maxDepth( root, 1 ) def __maxDepth(self, root, count) -> int.. 2019. 10. 24.
Climbing Stairs https://leetcode.com/problems/climbing-stairs/ Climbing Stairs - LeetCode Level up your coding skills and quickly land a job. This is the best place to expand your knowledge and get prepared for your next interview. leetcode.com 계단을 올라갈 때 하나 혹은 둘씩 올라간다고 할 때 경우의 수가 몇이나 되는지 헤아리는 문제. 필연적으로 말단으로 갈 수록 경우의 수가 겹친다. 따라서 동적 프로그래밍 기법으로 계산을 반복하지 않도록 해야 한다. class Solution: def climbStairs(self, n: int, cach.. 2019. 10. 24.
Fibonacci Number 제목이 곧 내용... https://leetcode.com/problems/fibonacci-number/ class Solution: def fib(self, N: int, cache = None) -> int: if N == 0: return 0 elif N == 1: return 1 else: if cache is None: cache = {} if N in cache: return cache[ N ] else: result = self.fib( N - 1, cache ) + self.fib( N - 2, cache ) cache[ N ] = result return result 2019. 10. 24.
Reverse Linked List 단방향 연결 리스트를 뒤집는 문제 https://leetcode.com/problems/reverse-linked-list/ # Definition for singly-linked list. # class ListNode: # def __init__(self, x): # self.val = x # self.next = None class Solution: def reverseList( self, head: ListNode ) -> ListNode: if head is None: return head else: reversedHead, _ = self.__reverseListIteratively( head ) head.next = None return reversedHead def __reverseList.. 2019. 10. 24.
Swap Nodes in Pairs https://leetcode.com/problems/swap-nodes-in-pairs/ 인접한 두 개의 노드를 서로 바꾸는 문제 # Definition for singly-linked list. # class ListNode: # def __init__(self, x): # self.val = x # self.next = None class Solution: def swapPairs(self, head: ListNode) -> ListNode: if head is None: return head nextHead = head.next if nextHead is None: return head nextNextHead = nextHead.next nextHead.next = head if nextNextH.. 2019. 10. 24.