늘모자란

늘모자란


Intent setResult 관리

Android 2019/08/02 15:57
금번에 앱을 수정하는데 intent 전환시 반환되는 requestCode가 무슨짓을 해도 0이 나와서 삽질을 했다
아무래도 기본적인 이해가 없이 땜질만하다보니 (주로 퍼온코드들을 넣다보니) 이런일이 발생하게 된것 같은데...

대상이 되는 액티비티는 A, B, C 세개였는데

처음에는 A가 B를 불러주고, B가 C를 부르는 구도인데
B에서 C를 무슨수를 써도 C에서 받는 RequestCode가 0이었다. 이게 왜그럴까 하면서 많은 삽질을 했는데...

좀 파보니 A가 B를 이렇게 부르고 있었다

intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
...
startActivityForResult(intent, 0);


근데 이렇게 하면 A가 B를 부르고 다시 A에게 돌아간거나 다를바가 없었다.
호출되는 상황이 다르기때문에 B의 result를 그대로 써야하는데 이렇게 되면 0으로만 값이 반환되는것이었다

그래서 이런 상황에서는 B의 반환값을 그대로 사용하기 위해서 다음과 같이 써야한다.

A를 다음과 같이 고친다

intent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT);
...
startActivity(intent);



B는 하던데로 setResult에 값을 적고 반환한다.

setResult(Value, intent);


A는 B와 C사이의 커뮤니케이션에 아무 상관이 없는 친구이므로, 관심꺼라고 명시를 해줘야 제대로 전달된다.
사실, 이 디자인은 문제가 좀 있었는데 B가 A를 상속받고, 핸들러로 처리하면 될 문제였으나... A를 상속하지 않은채로 만들어진 쌩짜의 액티비티라 이런일이 생길수도 있던것 같다...
2019/08/02 15:57 2019/08/02 15:57

서론


글쓰기에 앞서서, 별로 권하고 싶진 않습니다.
좀 고행길이고, 저는 판교테크노밸리 기업은행에서 진행했는데 그 은행에서 2번째로 성공한 사람이랍디다.

우선, 집주인들이 왜 전세자금대출을 꺼려하는지 알 필요가 있습니다.

집주인들은 전세금을 받아서 대부분 다른곳에 투자합니다. 그리고 새로운 세입자가 오면 새 세입자에게 전세금을 받고, 투자했던곳에 입금 후 전세금을 빼서 이사가는 세입자에게 돌려주는 식이죠. 이 구간은 보통 유연하게 처리 됩니다. 뭐 하루 이따가 돈 줘라, 하루 이따가 돈 주겠다. 뭐 이런식으로 투자한 전세금의 로스가 생기지 않도록 처리한다는거죠

그런데 전세자금대출로 전세금을 내면 그렇지 않습니다.
딱 하루만 지나도 은행은 집주인에게 이자를 부과합니다. 빨리 돈 갚으라고요. 돈을 유연하게 운용할 수 없고 칼같이 은행에 입금해야합니다. 집주인들로서는 귀찮은 일이죠. 그래서 전세자금대출을 안해준다는 주인들은 이게 귀찮아서 안해준다고 합니다. 근데 여기까진 그냥 기본만 지키면 되는거라, 왠만하면 해줍니다. 

중소기업청년전세자금대출도 80%는 비슷합니다. 거의 필요한 서류가 없고 빨리빨리 진행되는 편입니다.
하지만 그게 궁금하진 않잖아요? 100% 대출은 왜 권하지 않느냐?

집주인의 의지와 상관없이 대출이 나오지 않기 때문입니다.
집주인들은 전세금 및 건물을 담보로해 대출을 받아 또 다른 투자를 합니다. 대부분의 건물은 융자가 걸려있습니다.
100%대출의 경우에선 진짜 작은 융자도 허락하질 않습니다. 그냥, 융자가 있다면 안된다고 보면 됩니다.
그리고 보증보험에 가입되고 이로 인해 내용증명이 발송됩니다. 사실 이건 발송된다고만 알려주면 되는 사항이고 집주인이 해야할 필요는 없습니다.

그럼, 시작해볼까요.

주제파악


너무 센 워딩인가 싶은데 3500 이상 연봉받는 사람은 이거 신청못합니다. 그리고 입사 1년이상안되면 포기하세요.
또, 회사가 너무 약해도 문제가 됩니다. 여기서 확인해보세요. http://nhuf.molit.go.kr/FP/FP05/FP0502/FP05020604.jsp
그리고, 은행에서 자기가 얼마까지 대출되는지도 파악해야합니다. 1억짜리 집구했는데 대출 1억 못준다고 하면 안되잖아요? 대강 연봉의 3배 정도까지 나온다고 보면 될 것 같습니다.

집구하기


가장 먼저 해야할 일은 집을 구하는것입니다. 너무 당연한 소리지만 위에 얘기한대로 융자가 없는 건물이어야 합니다.
다가구주택 및 아파트, 오피스텔의 경우에는 한명한명이 세대주이기때문에 별로 신경쓸 필욘없습니다. 그러나 단독주택같은 건물은 융자체크를 반드시 해야합니다.
100%를 받을시 최대 금액은 1억원입니다. 1억 이상의 집은 반전세 돌리면 해결됩니다. 그러니까 조건이 까다로운셈입니다. 간단히 정리해봅시다

- 좋은집을 구한다.
- 전세금을 확인한다.
- 집 크기를 확인한다. (85m^2 이상의 크기는 입주 불가)
- 융자가 없는 집인지 확인한다

여기서 융자가 없는 건물을 셀프로 확인하는 방법은, 건물 등기를 떼보면 됩니다. 융자가 있을떄는 '을구' 란에 기재되어 나옵니다. 뭐라도 하나 나오면 그 집은 그냥 포기하세요. 이사인만큼 이 과정이 가장 어렵고 치열합니다. 대부분 한개씩 하자가 있습니다. 심지어는 저는 계약날 전에 주인이 마음바꿔서 물러진적도 있습니다. 진-짜 힘듭니다. 된다고 하는 중개사들 찾기도 어렵고, 집주인도 찾기 어렵습니다. 100%는 정말 어렵습니다.

그리고 입주날짜가 중요합니다. 대출 서류 검토 및 심사는 최대 3주정도가 소요됩니다. 역시 만족되지 않으면 안되겠죠.
집을 찾았다면 은행에가서 대출할건데 어쩌면 되냐고 물어보면 이것저것 따져주고, 양식 두개를 줍니다. 그건 아래단에서 작성합니다.

계약하기


집을 구하셨다면 대단한겁니다.
계약전에 등기등본을 들고 은행에 가면 대출이 나오겠네요 안나오겠네요 이런 소릴 해줍니다. '을구'에 뭐가 없으면 대부분 가능하지만, 은행에서는 국토부 시세 등을 따져보기 때문에 그냥 등기등본들고 은행가서 여기 진행해도 되냐고 물어보는게 가장 속편합니다.

집 주인과 계약을 하실 차례입니다. 계약은 일반적인 계약과는 다를게 없습니다만, '확인서'를 작성해야합니다.
그 건물에 누가 살고 있고, 전세금은 얼마, 월세는 얼마를 내며 살고 있는지 작성되어야 합니다. 이건 나중에 세입자 증명서를 제출해야할때 이름이 안맞으면 다시 써야할수도 있으니까 임대인에게 제대로 물어봐야합니다. (보통 역정냄)

중개사에서도 건물 시세 조사서를 작성해줘야합니다. 이건 대출할거다 하면 은행에서 양식을 주면서 써오라고 합니다. (계약전에 은행에 꼭 들릅시다)

이래저래 계약을 하되 반드시 다음 특약을 챙겨야합니다. 대출이 안나올수도 있기 때문입니다.
'은행대출이 불가능할시, 계약을 무효로 하고 전액 반환한다.' 와 같은 뉘앙스면 됩니다. 이거 못써주겠다고 하면 그냥 조용히 자리에서 일어나시면 됩니다. 보증금을 지불하고, 영수증을 꼭 챙깁시다.

계약을 완료했으면 확정일자를 신청합니다. 확정일자를 작성하지 않으면 애초에 신청을 못하고, 나중에 세입자 증명서를 뗄수가 없으니까 바로 합시다.
신청이 끝났다면 이제 문서와의 전쟁입니다.

대출 신청

드디어 대출신청란까지 왔습니다.
대출엔 다음과 같은 서류들이 필요했던것 같은데 누락이 된게 있을수도 있습니다.

- 재직 증명서 (회사에 요청)
- 근로소득원천징수영수증 (회사에 요청)
- 건강보험자격득실확인서
- 사업자등록증 (사본, 회사에 요청)
- 고용보험 피보험자격 이력 내역서
- 회사 주업종코드 확인 자료 (회사에 요청)
- 주민등록 등본, 초본, 가족관계증명서
- 집 등기 등본
- 분양계약서, 임대차 계약서 (사본X)
- 확정일자가 작성된 계약서 (이건 돌려받습니다)
- 확인서 (세들어 사는 사람의 전세금액 및 월세금액, 집주인)
- 세입자 확인서 (확정일자가 있지 않으면 발급안됨. 주민복지센터에서. 반드시 본인게 아니라 건물전체의 내역 필요.)
- 공인중개사 등록증
- 건물 주변 시세 조사서 (중개사에서 작성)

아 많다 증말 진짜
위에건 예외없이 다 필요하니 그냥 미리 준비들 합시다. 근데 너무 오래되면 못쓴다고 돌려보내니까 너무 빨리 뽑아두진 말고...
잔금일자를 확인후에 은행에 가면 무지막지한 대출 신청서에 계속 사인하고 날짜 적으라고 합니다. 시키는대로 하면 됩니다.. 
뭐 보증금은 어떻고 잔금은 어디로 들어가고 이런거는 굳이 알아가야할 필요가 없습니다. 그냥 은행에서 시키는대로 하면 다 됩니다.

기다림


기다리는 동안 은행에서 가끔 연락이 옵니다. 이 문서가 잘못됐는데, 특약에 사인해주셔야하는데 하면서 챙겨줍니다.
오랄떄 왠만하면 빨리빨리 다녀야합니다. 일정이 늦춰질 수 있거든요. 신청 후 임대인에게 내용증명 등기가 날아가는데 이것도 꼭 수령해야합니다.
제발 수령해달라고 합시다. 그러면 은행에서 그거 받았냐고 임대인에게 전화가 따로가고, 받았다하고 뭐 동의같은거 해주면 진짜 기다리기만 하면 됩니다. 골때리는게 별도의 승인 문자 이런게 없습니다. 어떻게 진행되는지도 모르겠고 그냥 기다려야되는데 저는 하도 답답해서 은행가서 어찌되고 있냐고 물어본적도 있어요..

이사


잔금일자가 되면 이사를 가면 됩니다. 아~ 이사 왔다~
끝이 아닙니다. 전화가 옵니다. 실사단이 파견됩니다. 약 5분정도 걸리는 시간인데 집 문사진이랑, 실제로 세입자가 떠나고 내가 들어간 집인지 등을 보고 갑니다. 근데 짤없이 평일만 된다고 합니다. 하...... 

전입신고도 해야합니다. 이사후 3일이내에 전입안하면 황입니다. 전입신고를 했다면 주소 변동이력이 작성된 등본을 뽑아다 은행에 제출하면, 모든 과정이 끝이 납니다.

결론


문서는 사실 얼마든 쓸수있습니다. 좀 귀찮으니까요.
그런데 100%로 되는 집을 구하는게 너무 힘듭니다. 중개사들 시선도 곱지도 않고요. 차타고 가다가 한두개만 보여주고 우린 그런거 없다하고 내려준 중개사도 있습니다 ㅋㅋ 
마음을 넉넉하게 가지시고, 천천히 알아보심을 권합니다. 그럼!
2019/03/25 10:04 2019/03/25 10:04
TL;DR
apktool로 디컴파일-컴파일 했을때 망하면 다음을 확인해보자
classpath 'com.android.tools.build:gradle:3.1.4' -> 3.1.4 이상부터 뭘 해도 안된다.


자세히
내가 만든 앱을 디컴파일 및 컴파일 해야되는 계기가 생겼는데 (왜 이런 삽질을 하냐고 묻진 말자... 자본주의...)
갑자기 이런 에러가 나면서 재 컴파일이 되지 않았다.

Public symbol array/XXXXXX declared here is not defined.


이런게 막 수십줄이 뜨고 마지막에는 

brut.androidlib.AndrolibException 이 뜨면서 으마으마한것들이 잔뜩 나오며 실패했다.
minSDK 문제인지 targetSDK 문제인지 진짜 뭔 별 안해본게 없는데 커밋로그들을 쭉 둘러보면서 바뀐게 뭔가 하다가 설마 gradle 버전 문제인가 싶어서 기존에 쓰던 3.1.4로 낮춰서 빌드를 해 재컴파일 해보았더니 그냥 된다...

3.1.4에서 올린 이유는 이런 에러가 나왔기 때문인데
The rule `-keep public class *extends java.lang.annotation.Annotation {


gradle 버전을 올리니 더 뜨지 않아서 올렸던 기억이 있다. 그런데.. 이런 사태가 난 것이다.
좀 실험을 했는데 3.2.1 도 해보고, 3.3.1도 해봤는데 뭘 해도 안된다. 그냥 3.1.4만 된다. 혹은 그 아래버전도 되겠지만 그건 필요가 없으니..
어이가 없어서 남긴다. 여튼 겨우 한건 해결...
2019/02/27 11:31 2019/02/27 11:31

2018년

Gossip 2018/12/31 09:51
2018년은 참 다사다난해였고, 진행중이다.

흠..
2017년도에 블로깅은 꽤 열심히 했다. TIL (Today I Learn) 위주의 글들도 제법 작성했고 워게임을 풀이하는 바람에 꽤 많은 글을 작성한 해 였다. 방문자가 20명대에서 매일 40명대 찍히는거보면 헛짓거리는 아니었던 모양이다. 그래봐야 40명이긴하지만...
두번째로 일상이 챗바퀴..
자전거를 열심히 탔다. 인천에 경인항에도 갔다오기도 하고 꾸준히 탔으나 그외에는 기존의 나를 탈선시킬정도까지 어마어마한 취미는 없었다. 좋은 사람이 생긴거 정도는 ... 음...
세번째 건강은 꽤 호전이 있었다.
좀 많이 쳐줘서 2 3키로만 감량하면 20키로쯤 감량된거같다. 좀 어거지긴하지만 감량이 된건 된거고, 혈압도 훈련소안에서 제자리를 찾아왔기때문에 이대로 쭉 유지도 하고, 감량도 계속해볼 생각이다. 그래도 근력이 딸리는건 마찬가지라 운동도 필요하고...
2018년
훈련을 다녀오니 이제 다 끝난 느낌이다. 날 가로막는 모든 장애물이 사라진 느낌?
좀 더 적극적으로 공부를 해야겠다. 그리고 보안 공부를 소홀히 하지 않겠고.. 자격증을 취득해보는게 목표다. 자격증을 취득한다는 거도 의미가 있지만, 일단 목표가 있고 공부를 한다는 행위에 의미를 두기로 한다. 한자, 토익, 리눅스 마스터 등이 생각하고 있는 목표인데 잘 모르겠다.
그리고 알고리즘과 자료구조를 다시 공부할 생각이다.
결국 기초가 중요한건데 모래성을 계속 쌓아갈 순 없다. 워게임 대신 온라인 저지를 좀 풀어볼 생각이다.
두루뭉술한 목표가 되었지만 잘 실천한다면 도약을 위한 발판을 준비하는 한 해가 되지 않을까? 아듀 2017.


직무


훈련소에 다녀왔었다. 2018년이 껴있는 날은 8일정도밖에 안되지만 어쨌든 2018년엔 훈련소를 다녀왔다.
사람이 변했나? 그렇진 않다. 다짐같은건 정말 많이 했고 그렇기에 남긴글이긴한데, 사실은 하나도 이룬게 없다. 지금 보니 우습기만하다. 자격증? 한자? 토익?;;; 적어놓은것의 나열을 보면 정말 한심한 한해를 보낸것 같다.

그래도 여러 시도는 하려고 했다. 역시 이놈의 싴갤러스의 프레임을 벗어나지 못한...
첫번째로, 채팅이 SSL을 지원하지 않아 HTTPS 를 적용할 수 없었었다. 그래서 웹 푸시 역시 사용할 수 없었기 때문에, 채팅을 직접 개발했었다.
socket.io를 이용했고 서버는 노드. 간단한 채팅정도는 왔다갔다 쉽게 만들 수 있었지만 관리자 측면에서 생각해본적은 없었기 때문에 괜찮은 시간이었다. 그러나 완성되진 못했다.. 가능한 모든 가능성과 변수를 고려하고 프로젝트에 돌입해야겠다는 교훈을 얻었다. 그래도 주석이 잔뜩 남긴 소스들은 깃헙에 남게 되었으니까 완전 망한건 아닌것 같다.

두번째 역시 싴갤러스.
셀레늄을 이용한 프로젝트였고 토이 프로젝트인데 너무 프로젝트에 끌려다니는것 같아 인간다움을 추구해 진행된 프로젝트였다. 자동화 관련인데.. 
소스 자체는 2016년 10월에 작성했었는데 한가지 난관을 돌파하지 못하다가 4월쯤 겨우 적용할 수 있었다. 꾸준히 해왔던건 아니고, 자전거 타고 돌아오는길에 왠지 할 수 있을 것 같아서 피느에게 부탁해 프로그램하나 만들고, 적용했다. 현재까지도 잘 돌아가고 있고, 간간히 오작동하고는 있으나 계속 보강할 생각이다.

세번째는 서버. 하지만 역시 싴갤러스;;
docker 를 이용해 mysql replication 컨테이너를 만들고, 컨테이너 자체 백업을 적용했다. 그러니까 백업이 어떻게 보면 삼중화 된 것인데, 새벽경 정기 기 백업, repl, 그리고 컨테이너 커밋을 이용한 백업 체계를 만들(었)었다. 이미지가 크기때문에 당연히 몇개 저장하지 못했고, 결국 서버에 ssd를 하나 더 붙이는 대작업까지 수행했다. 이 작업은 훈련소에서 디비가 깨졌단 소리 듣고 혼자 빡쳐서 꼭 해야겠다고 생각했던건데, mysql 의 인덱스 크래시 문제는 해결이 안된다. 현재 이 백업 체계는 동작하지 않고 있고 -_- 조만간 다시 진행할 예정이다. 뭐가 문제인지 어느순간부터 컨테이너 커밋이 진행되지 않는데, 용량 문제인가 싶기도하다...

그외 여러가지 기능 업뎃을 진행했으나 기억에 남는것은..

1. 키트 데이터 통계를 낼 수 있는 득템전광판 제작
2. 네이드 퇴역
3. 앱 아이콘 변경
4. HTTPS 및 HTTP2 적용 (엄청 미루다가 드디어) , prefork 에서 event 기반으로 변경

이지만 뭐니뭐니해도 레이드, 지염도서관 리팩토링이 기억에 남는다.
내용은 따로 썼었으니 적진않겠지만 코드관리관점에서 가시적인 성과가 있어서 참 좋았다. 기분도 엄청 좋았고.


그외에 회사일은,
뛰어난 일을 한건 없고 잡기술들이 많이 늘었다. 잡지식도 많이 늘고, 애플에 버그리포트도 했다. 먹히진 않았다만.....
내년 싴갤러스는 할 수 있는 목표부터 적어야겠다. docker 안정화하고, 웹 푸시 적용하고, 장기적으로는 아파치를 nginx 로 변경하는게 목표이다


좋은 사람이 있었었다. 2017년 후반과 1월 초까지는. 그런데 4월까지 내내 힘들다가 4월말에 또 좋은 사람이 나타나 좋은 시간을 보내고 있다.
마냥 좋기만 한건 아니지만, 서로 맞춰가는 재미도 있는것 같고 또 한번도 생각해본적도 없던 결혼에 대한 인식도 바뀌었다. 그러나 대부분 즐겁고 행복한 느낌이다. 언제까지 이 감정이 지속될진 모르겠지만, 2019년에 끝나버릴지도 모르겠지만 적어도 2018년은 그렇게 보냈다. 2019년엔 다투지 않고 즐겁게 보냈으면 좋겠는데. 지금까진 그냥 바램.2019년을 돌아볼때 어떤 느낌일까 싶다. 내곁에 계속 남아 있어주려나. 아니면 2018년 초반처럼 아파한 시간을 보냈으려나.
그리고 이사하고 싶다. 이사가 될진 잘 모르겠다만..

공부

정말 열심히 살 생각이다. 11월까진 조용히 아무일도 없게 보내고 싶다. 그러나, 11월엔 이직을 목표로 하려고 한다.
몸이 편한건 사실이다. 일이 많지 않은것도 맞고. 그러나 뭔가 얻는 기분도 들지 않고 뭣보다 일이 재미가 없다. 힘들어도 부딪히면서 일궈내는 느낌이 너무 없어서 좀 더 높은곳을 향하는게 좋지 않나 싶다. 이직하지 않더라도 결국 나 스스로에겐 도움이 될테니까 말이다. 


역시 구체적인 목표는 없는 두루뭉술한 2018년 돌아보기와 2019년 목표였다.
사실, 2019년은 마지막 해라서 조용히만 보내자가 목표이다. 2019년의 나는 어떨까? 앞자리도 바뀌고, 정신적으로 더 성숙해질까? 스스로도 궁금하다.
2018/12/31 09:51 2018/12/31 09:51
W: An error occurred during the signature verification. The repository is not updated and the previous index files will be used. GPG error: http://dl.google.com stable Release: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY 1397BC53640DB551
W: Failed to fetch http://dl.google.com/linux/mod-pagespeed/deb/dists/stable/Release
W: Some index files failed to download. They have been ignored, or old ones used instead.


나는 pagespeed 를 아파치 모듈에 붙여서 사용하고 있다. 그런데 언제부터인지 계속해서 업데이트가 안되었다 (위 내용처럼)
오늘은 정말 거슬려서 구글링을 좀 해봤고 해당을 찾을 수 있었는데... 


apt 명령어 사용시 공개키를 이용하게 되는데 모종의 이유로 이 키가 삭제되거나 누락되면 자동으로 다시 받지 않는 모양이다
https://askubuntu.com/questions/766883/there-is-no-public-key-available-for-the-following-key-ids-1397bc53640db551

여기서 볼 수 있지만, 다음과 같은 명령어로 키를 내려받아주면 해결된다

sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys [KEY NUMBER]


2018/11/12 10:48 2018/11/12 10:48
There is no vulnerability.
Just find the rules.

nc wargame.kr 10034


배스킨 라아빈스 써리~원

배스킨 라빈스 게임은 어릴적 UN의 맴버중 하나가 나와서 필승법이 있다고 예능 인터뷰때 했다고 해서 사기게임이라고 뇌리에 깊게 박혀있다.
실제로, 1:1에서는 배스킨라빈스 게임은 실수하지 않는한 먼저 하는 사람이 무조건 이기는 방법이 있다.

1:1 베스킨 라빈스를 제시하라. 단 필승법을 아는지 대충 떠 봐야한다. (그건 알아서. 귀찮아) 
먼저 시작한다면, 처음에는 1, 2를 외쳐라. 그 다음에는 [4개-상대방이 말한 갯수]만큼씩 외쳐라.

두번째 시작한다면, 어떻게든 당신이 마지막으로 외치는것이 4의 배수보다 1개 많도록 29, 25, 21, 17, 13, 9, 5개가 남도록 한다.
즉 당신이 2, 6, 10, 14, 18, 22, 26으로 끝을 내게 외쳐야 한다.

그 다음에는 마찬가지로 [4-상대갯수]를 말하면 이긴다.
출처: http://yews.tistory.com/entry/베스킨-라빈스-31-11승리전략 [생각의 화장실]


예를 들면 이런식으로 많이 나와 있다. 이런건데, 요점은 반드시 내가 말해야 하는 수가 있다는 것이다.
이런 배경지식을 가지고 시작해보자

Welcome to STITCH's baskinrobbinsN game!
Your Purpose is to win Baskin Robbins31 game from AI. 

Rule)
As you already know, it seems like real Baskin Robbins31 game. But maximum number is not 31.

ex) N=101 , count 10
It situation, You can saying up to ten at a time of number. because count is 10.
if you speaking 101 faster than AI , you lose because N is 101

you will input smaller than count...
you will input the numbers in order.

----------------------------------
hint) 
N = 31, count = 3
input your name -> ab
Hi! ab
user first!
input your number -> 1 2 3
user say -> 1 2 3
computer say -> 4 5 6
input your number -> 7
user say -> 7
computer say -> 8 9 10
input your number -> 11 12 13
user say -> 11 12 13
computer say -> 14
input your number -> 15 16
user say -> 15 16
computer say -> 17 18
input your number -> 19 20 21
user say -> 19 20 21
computer say -> 22
input your number -> 23
user say -> 23
computer say -> 24 25 26
input your number -> 27 28
user say -> 27 28
computer say -> 29 30
AI win!
----------
------------------------

**** Timeout is 150sec... ****
**** Total 31 round... ****
Good luck~




N = 2166, count = 133

input your name -> Hi! fantazm
computer first!
computer say -> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
input your number -> 


문제가 예시와 함께 잔뜩나온다. 근데 기존에 알던 배스킨게임이 아니다. 최대 수와 부를 수 있는 수자가 랜덤으로 주어진다.
사실 이 글을 쓰기전에 살짝 해봤는데 컴퓨터를 이길 수가 없다. 생각을 다시 해보기로 했다.
읽고 나니 드는 생각이 있다.

나온 문제에서 보면, 내가 불러야될 숫자는 정해져있다. 컴퓨터 턴이 되어도 절대 끝낼 수 없는 수를 불러야한다. 그럼 컴퓨터는 2164까지밖에 부를수있고, 부르더라도 나는 2165를 말하고 승리한다.

http://lg-sl.net/product/scilab/sciencestorylist/ALMA/readSciencestoryList.mvc?sciencestoryListId=ALMA2018040003&subjectId=ALL

https://blog.naver.com/jong1003min/220348353765

https://namu.wiki/w/%EB%B0%B0%EC%8A%A4%ED%82%A8%EB%9D%BC%EB%B9%88%EC%8A%A4%2031(%EA%B2%8C%EC%9E%84)

참고한 링크들을 보자. 왜 하필이면 4일까? 4가 28을 부를 수 있는 배수의 마지노선이기 때문이다. 즉.. 워게임이지만 알고리즘에 가까운 코딩문제인것 같다.

핵심은, 나머지를 구한후 필승 수열을 구하는것이다.
r = (N - 1) % (count + 1)


그리고 목표 수치도 N이 아니라 N-1을 불러야는게 핵심이다. 때문에 내가 한개 더 많이 말해야한다. (베스킨라빈스게임에서도 3까지 부를 수 있지만 4로 맞춰 말하면 이긴다)
따라서 count + 1 을 해서, 필승 수열을 만든다

solns = []
while r < N:
    solns.append(r)
    r += (count + 1)


이제 여기에 등장하는 숫자까지 맞춰서 말하면 이긴다.
코드를 다 올리는건 좀 아닌것 같고 문제 풀면서 정말 X같았던 점들만 좀 적어본다.

1. 아무리해도 이길수가 없다. 컴퓨터가 먼저 시작을 하기 때문이다. 그리고 기가 막히게도 컴퓨터는 이 필승수열의 첫번째 수를 말한다.. 진짜 한참 삽질했는데
처음에 이름을 입력받는데... 이 입력을 짝수로 하면 내가 먼저 시작하고, 홀수로 하면 컴퓨터가 먼저 시작한다. 아........ 이건 처음 수열을 만들때 0으로 시작할 경우, 일부러 컴퓨터에게 턴을 주는식으로 구현하면 된다.
2. 소켓이 짤려서 온다. 숫자가 길어지고, 정확히 1460 자 이상이 되면 개행한다. computer say -> 로 파싱하고 있다가 의문의 payload wrong을 만날 수 있는데, 게임이 시작되었고, 개행이 된채 숫자만 던졌다면 해당 숫자를 마지막으로 다시 계산해야한다

요컨데 이런식으로 온다.

computer say -> 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 (개행)
(탭) 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652

별도의 처리가 없으면 이때 1632를 마지막 숫자로 읽어서 시간낭비를 하게 된다.
다음과 같이 정규식으로 처리해주면 된다.

 ext = re.findall(r"^\s+((?:\d+ )*\d+)$", line)
 if len(ext):
    response = re.findall(r"^\s+((?:\d+ )*\d+)$", line)[0].split(" ")
 


socket.recv 같이 너무 작으면 개행을 막 두번씩 하기도 하니, 애초에 넉넉하게 잡고 수신해주면 좋을 것 같다.
2018/11/07 09:09 2018/11/07 09:09
wargame.kr이 새단장을 해서 보니 문제가 꽤 추가 되어 있었다.
custom OS 빼곤 다 풀었었던거 같은데... 저 문제는 아직도 잘 모르겠고, 짬을 내서 풀어보기로 한다.

먼저 시도할 문제는 plz variable 이라는 문제.

Can you find the solution quickly in polynomials? 
nc wargame.kr 10004


nc는 netcat 의 줄임말로, 간단히 데이터를 읽고 쓰는 프로그램이라고 한다.
여러 문제를 눌러보니 이제 문제를 웹에서 푸는게 아니라 저 프로그램을 이용해야 되는거 같다.
그냥 telnet을 이용해도 되는거 같은데 일단 시킨대로 nc로 연결해보았다.
그러자 문제가 나왔다.

Please match the correct answer 30 times.

Submit format -> a,b,c,d,,,(Ascending order)
Timeout = 60sec
a,b,c,d,,, is natural number
a,b,c,d,,, is 100 <= <= 1000

1th...
b * a + f + e * d - c = 491787
a * b * c - d * e + f = 359074294
e - b + a * c - d - f = 677922
d + c + e + f + a + b = 3215
a * f - c + e + b + d = 162962
a * b + c + f - e - d = 368086
Answer -> 



예 잘봤습니다. 제 점수는요.
여러번 연결해보니 나오는 변수 만큼 문제가 출력되는거 같다. polynomials. 다항식, 연립방정식이다.
그전에 내가 알파고가 아니니까 60초만에 저 문제들을 풀어낼순 없다. 코드로 문제를 받는거부터 시작이다.
딴건 없고, 그냥 소켓 연결을 생각하고 코딩을 하면 되었다.

import socket

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_address = ('wargame.kr',10004)
sock.connect(server_address)

data = sock.recv(1024)
print data

sock.close()


데이터 전송은 sock.send로 하면 되는거 같다. 어쨌든 잘 연결이 되었다.
이제 문제를 풀어야하는데.. python 연립방정식 따위의 키워드로 검색을 하니 몇개 나왔다. sympy 나 numpy scipy 등을 이용하면 된다고 한다.
그중에 sympy 의 solve를 많이 쓰는거같은데, 이 문제에서는 답까지 주니까 nsolve를 사용하면 될것 같았다.

우선 nsolve 를 사용하기 위해서는 어떤 알파벳이 변수로 사용되고 있는지 Symbol을 선언해주어야 했다.
그리고 이건 식입니다. 하고 명세하기 위한 Eq도 필요했다.
우리는 그리고 nsolve를 사용하기로 ...

from sympy import Symbol, Eq, nsolve


그리고 식은 정직하게 주지만 다음 문제를 보지 못했기 때문에, 수학식임을 판단하기 위해서 다음과 같이 검사했다.
각 라인이 개행되있기때문에 라인별로 정규식으로 검사했다. 좀 과한거 같긴한데 아래같이 할 필욘없다.. 여튼 이렇게 식과 답을 분리해서 넣었다.

for line in data.split('\n'):
 if "Answer" not in line and "Submit format" not in line and re.match(r"[a-zA-Z]",line) != None and re.match(r"^(-?\d+)$",line) == None and re.search(r"[()\\*+-]", line) != None:
 eq.append(re.findall(r"(.+?) \=",line)[0].replace("\t"," "))
 answ.append(int(re.findall(r"\=\s(.+)",line)[0]))


사용되는 변수들은 중복을 제거해 Symbol 로 선언해주기 위해 다음과 같이 했다.

list(set(re.findall(r"[a-z]","".join(eq))))


이제 list 세개를 모두 확보했기때문에 nsovle에 넣고 돌림 되겠지 하고 돌렸는데 에러가 났다-_-
Eq로 list를 하나하나 해줘도 Symbol 이 변수명으로 선언되지 않으면 돌아가질 않았다. 즉 요렇게

a = Symbol('a')


허미.. 이게 몇개나 나올줄 알고 심볼을 선언해주나. exec를 쓰면 된다.

exec("{0} = Symbol('{1}')".format(name, str(name)))


이런 느낌으로 돌려주면 선언된다. Eq도 똑같이 해줬는데 그래도 안된다.
그래서 찾아보니, (e1,e2,e3,e4) / (x,y,z) 이런식으로 기재는 하는데 내가 만든 리스트는 ('e1','e2','e3') ('x','y','z') 처럼 문자열같이 되있었다.
하아.. eval 도 해주기로 했다.

for i,j,k in zip(exps, symbols,answ):
 epack = "{},{}".format(epack,i)
 spack = "{},{}".format(spack,j)
 apack = "{},{}".format(apack,k)

epack = "("+epack[1:]+")"
spack = "("+spack[1:]+")"
apack = "("+apack[1:]+")"


이후 nsolve에 eval(epack) 이런식으로 실행했다. 안된다.
코드상 문제는 없는거 같은데 단순히 값을 꾸겨넣는정도로는 안되나보다. matrix 가 0이니, divisionZero 에러니 뭐 별에 별 에러가 나와서 그냥 때려쳤다. solve도 써보고 뭐 다른 방법도 여러개 해봤는데 안됨.
그러다가 내가 못찾은 다른 solver가 있는건 아닐까 싶어 찾아보다가 z3라는 solver를 찾게 되었다.

z3는 리버싱때 많이 쓴다고 한다. 주소 계산같은데 활용되는거 같다. 어쨌든 z3라는 무기를 다시 확보했으니, 풀어보자.

먼저 Solver 라고 문제 풀이 머신을 하나 추가해줘야한다.

import z3 as z
s = z.Solver()


이런느낌이다. 그리고 조건들을 추가해줘야하는데, 수식에서 = 를 ==로 변환해서 넣어주어야 한다.
그리고 100보다 크고, 1000보다 작은 수이기때문에 조건을 입력해주어야한다. 아니면 시간이 너무 오래걸리거나 중간에 퍼지는 경우가 생긴다.
또한, 위에서 Symbol 을 선언해주었던것 처럼 eval 로 Int 임도 먼저 선언해주어야 한다. 그러면..

for i in variables:
 exec("{} = z.Int('{}')".format(i,i))
 s.add(eval("{} >= 100".format(eval(i))))
 s.add(eval("{} <= 1000".format(eval(i))))

이런 느낌이 된다. 그리고 수식을 = 를 변환해주어서 추가해준다.

for i in exps:
 s.add(eval(i.replace("=","==")))


이러고 문제 해결을 위해 다음과 같이 해준다.

s.check()
result = s.model()



여기서 내가 헷갈렸던건,
Submit format -> a,b,c,d,,,(Ascending order)
이부분인데, 아.. 나는 값을 정렬하라는줄 알았는데 그게 아니라 key 이름대로 정렬해서 출력하는것이다. 진짜 풀이에 문제가 있는줄 알고 한참헤맸다..
새로운 라이브러리를 알게 되니 뭔가 강력한 무기를 갖춘 느낌이다. 플래그를 보니 정답이었던것 같다.

2018/10/31 15:41 2018/10/31 15:41

레이드.

마비노기라는 게임에 레이드라는 단어가 이제 어울릴지 모르겠습니다.
유저 하나하나가 너무 강해지는 바람에 체력이 못따라가는 상황인 것 같더군요..



그럼에도 불구하고 싴갤러스에서는 유저분들의 제보를 이용해 보다 더 나은 레이드 환경을 만들려고 항상 노력하고 있습니다 (진짜)
오늘 이 글에서 다룰 이야기는 바로 그 레이드 개선에 관한 이야기입니다

구조적 문제를 안고 시작하다


처음 싴갤러스의 레이드를 다룰때는 네이드, 거대사자, 거대악어, 평원 드래곤 그리고 이프리트 5종만 다루었습니다.



아마 위 레이아웃은 본적도 없으신분들이 많을 것 같은데요.
이때는 웹, 즉 PHP를 막 배우고 있을때 만든 홈페이지라 레이드 별로 페이지를 전부 하나씩 생성했습니다.
그리고 DB에서 보스별로 불러와 처리했죠. 그러니까 즉, SQL 쿼리만 살짝 다른 페이지가 5종, 전체를 볼 수 있는 페이지까지 해서 6종이죠.
그리고 자바스크립트도 잘 할 줄 몰라서 하나의 페이지를 가지고 인자를 전달해 다른 결과를 보여준다는건 생각도 못했고, 무조건 페이지 이동이 필요했습니다


js를 좀 배우고 나서도 문제가 해결되진 않았습니다.
이미 나눠진 페이지를 굳이 합칠 필요가 없었기 때문입니다. 그리고 이땐 또 ajax와 REST개념을 잘못 이해하고 있어서 ajax로 데이터를 불러오는게 아니라 페이지 자체를 그대로 불러와 대상 dom 에 씌우는 식이었습니다. 그러니까, 불러오는 페이지에서 표까지 완전히 작성하는 구조였죠.

그렇게 많은 페이지들이 만들어진 상태에서 레이드가 계속 늘어났습니다. 레드 드래곤부터 시작해서, 시간이 고정이었던 사막 드래곤, 신규 레이드인 블랙, 화이트 드래곤부터 지금의 실반 드래곤, 모쿠르칼피까지. 첫 단추를 잘못꿴 상태였기때문에 똑같은 페이지를 계속 만들어낼 수 밖에 없었습니다. 잘못된건 아는데, 빠르게 결과물을 내야했기때문에 -당시에 레이드는 경쟁구도의 사이트가 있었습니다- 속도를 올릴 수 밖에 없었고, 나중을 기약하며 조악한 페이지들을 계속 늘려만 갔죠. 그 결과는...


(여기서 strings는 작업하려고 추가해놓은거고 실제론 없었음)

raid3.php 이라는 뷰 페이지에서 page를 include 해서 보여주는 식이었고, 각 페이지에서는 각 프로세스를 처리할 (레이드 마다 시간이 다르기때문에) 페이지에 1:1로 매칭이 됩니다. 초록색은 작업하려고 만든거라 상관없고... 그러니까, 거의 20여개에 달하는 페이지로 구성되어 있던거죠... 그리고 스크립트도 PHP 변수를 사용해 처리하기때문에 인라인 스크립트로 작성되어 있고, css도 인라인 css로 작성되어 있기때문에...

단 하나의 수정이 발생하면 최소 8개 페이지(레이드가 다르더라도 인터페이스는 공통된 경험을 줘야하니까)가 수정되어야했고, 좀 심하면 처리 페이지까지 수정해야했으니 1글자를 고치기 위해 20페이지가 수정되어야 하는 기염을 토하기도 했습니다.
구조적인 문제가 분명히 있었으나, 다들 잘 쓰고 있으니까요. 굳이 수정이 안되어도 문제가 없었습니다. 어차피 레이드는 완성형이라고 생각했고, 뭐 하나 추가되면 페이지 늘려야지, 이젠 도가 텄으니 빨리빨리 수정할 수 있다 이런식으로 애써 신경안쓰려고 하고 살았습니다..


곪은건 터지게 된다


신규 기능 요청이 들어왔습니다. 별건아니고, 전광판을 여러개 띄울 수 있게 해주세요.... 인데
모든 보스몬스터가 별도로 구분되어 있기때문에 현재의 구조로는 제공할 수가 없었습니다. 정확히는 가능은 하지만 불필요한 함수를 작성해야할 수도 있고, 뭣보다 중간에 수정이 일어나게 되면 모든 페이지에 같은 내용으로 또 작성... 아... 더 이상은 얘기하기 싫네요.

그래서 이왕 이렇게 된거 레이드 자체를 다시짜자고 결심하게 되었습니다.
단 한번의 수정으로 많은 경험을 선사해주자는거죠. 결론부터 작성해보자면 다음과 같이 변했습니다.
여기에 raid.js 라는 별도로 분리된 js 파일이 하나 더 있습니다. 뷰를 담당하는 파일이 하나 더 있고요.



먼저 페이지를 통일하는게 중요했습니다.
어차피 설명만 좀 다르고 마크업은 똑같기 때문에 (아주 약간만 다르던지) assets에 strings 를 추가해 파라미터별로 설명을 다르게 표시해주는것부터 시작했습니다. 같은 이름의 변수를 case마다 계속 작성해나가는게 유쾌한 경험은 아니었지만 필요한 작업이니까, 좋게 말하면 string을 분리한거고, 나쁘게 말하면 우겨넣은거죠. 그래도 다음과 같아졌습니다.



이제 이 수많은 print_보스들... 왜 이럴까 소스를보니 초반부는 다른데 후반부는 완전 같습니다.
이상하네 하고 보니까(내가 짠건데 이상하네라고...) 그냥 시간을 체크해서 레이드 시간인지 아니만 판단하는 부분만 다를뿐 모두 같더군요.
그리고 이상하게 뿔피리데이터를 이쪽에서 만들고 있었는데 검색 키워드만 조금씩 다르고 쿼리도 같고요. 자갈치 시장도 아니고 한번에 처리하려고 발악을 한 느낌이었습니다. (print_smd_data , print_smd_horn 이렇게 안하려고...?)

해야할건 명확했습니다. 각 보스별로 시간 체크 및 시간, 제보 정보를 합치고, 뿔피리 데이터를 분리해 처리하는 두개파일로 나누는거죠.
그리고 전광판을 여러개 띄웠을때도 같은 페이지로 온전히 동작해야하니까 범용성을 살짝 넣고.

그렇게 서버에서 주는 값들을 대강 명세하고, js 를 수정했습니다.
기존엔 js안에 서버 변수를 넣어서 그대로 작성한 케이스가 많았는데 이번엔 어떤 서버변수도 사용하면 안되었기때문에, url 을 이용해 구분했습니다. 그리고 대부분의 DOM을 dynamic 하게 만들어야했기때문에 js안에 html div를 많이 작성했습니다. 이게 맞는 방법인진 모르겠는데.. 맞겠죠?;

js를 작성하면서 느낀건데 multi line을 작성할때 쓰는 ` (back qoute)와 new URL, filter arrow 등은 IE에서 사용할 수가 없었어서 다 만들었다 생각했는데 대체하기 위해 다시 작업을 하고.... 뭐 그랬던거 같네요. 그리고 신규 관리자분이 들어왔는데... 시련이 시작되었습니다. css 지옥이었는데.. 봐주는 관리자 한명이 잠을 안자...




화면을 같이 보고 있는게 아니라서 캡쳐 후 보여주기를 계속 반복해야했고 결국 대화방 앨범이 이거 관련 내용으로 한페이지를 넘게 차지하게 되더군요. 개인적으로 디자인 작업은 안좋아하기때문에 아주 많이 힘든 시간이었습니다.... ㅠㅠ
신규 기능 추가를 마치고, 테스트 서버에서 기능이 실제 데이터 기반으로 잘 돌아가는걸 확인하고 기능을 릴리즈 했지만 IE 호환문제, 창이 자동으로 안뜬다던지, 채팅 제보 정규식에 문제가 있다던지 하는 소소하면서도 안되면 불편한 문제들이 계속 발견되면서, 한번에 완벽하긴 정말 어렵구나 하는 생각을 했습니다

돌아보며


금번 작업은 보기엔 별거 없습니다. 기능한개가 추가 되었고, 사이트 외형적으로도 거의 변한게 없습니다.




그러나,
5,000여 라인의 코드 삭제가 있었고, 2,200 여 라인의 코드 작성이 있었습니다.. 이 작업은 단 이틀만에 수행되었고요..
훨씬 많을줄 알았는데 이거밖에 안돼 같은 생각이 들지만, 범용성을 위한 코드 리팩토링은 싴갤러스를 운영하면서 처음인거같습니다.

코드자체가 대단한것도 아니고 난이도가 있는 코드도 아니지만, 짧은 시간내에 끝내려고 일정을 빡빡하게 잡았고, 오히려 시간이 타이트했기때문에 한줄한줄 쓸모없이 작성하지 말자 이렇게 임했던 느낌입니다. 유저 수요도 고려하고, 중간에 기획을 바꾸기도 하면서..
개인적인 성취를 이룬 느낌이 더 강한 업데이트였습니다. 구조 통일도 했으니 앞으로 레이드쪽에 더 많은 기능 추가가 있을....수도 있겠죠?

다음엔 더 재밌는 글로 찾아뵙겠습니다~
2018/09/17 09:43 2018/09/17 09:43

앱 업데이트는 매번 참 두근거리는 일입니다. 
검수를 받기때문에 웹 처럼 빠르게 업데이트가 불가능하고(상대적으로), 기기의 이상 유무, 앱 설치와 제거 여부등 보고 있자면 흥미로운 통계가 많기 때문입니다.

사실, 싴갤러스는 모바일 레이아웃을 지원하기때문에 네이티브로 앱을 구성할 필요가 없고, 굳이 쓴다면 푸시 기능때문에 앱을 존속시키고 있는 것인데요. 그래서 그런가 많은 공수를 들이고 있지 않은것도 사실입니다. 그래도 이번에는 아이콘 그림도 많이 교체했고, 자주 볼 수 없는 화면에 신경도 (...) 썼습니다. 예를 들면 서버를 선택하는 화면에서 UI의 색이 바뀐다던지하는...

기본 웹에서 지원하는 아래로 끌어서 새로고침하는 기능도 넣어보았습니다. 이젠 당연하게 여겨지는 기능이고..
또, 안드로이드에서 갑자기 네트워크 문제가 발생했을경우 에러 다이얼로그 폭탄이 나오는 문제들도 수정했고, 캐시가 계속 쌓여서 앱이 비대해지지 않도록 신경도 써봤습니다.

그외에도 뭐 ... 다 말하지 못하는 사소한 것들도 참 많습니다만 어쨌든, 싴갤러스 1.13 앱을 즐겨주세요!
2018/09/11 09:14 2018/09/11 09:14
삼성 덱스에서 앱을 시동하면, 모바일 기기 기준으로 실행된다.
그런데 아시다시피 DEX의 화면은 엄청나게 광활한데 앱 화면은 작디 작고 늘어나지도 않는다. 조금 더 크게 사용하고 싶을 수도 있다는 것이다.

이때 사용하는것이 Nougat 에서 추가된 멀티 윈도우 기능이다. 나보다 더 자세히 쓰여있는 삼성의 가이드 링크를 첨부하지만 그거도 눌러보기 싫은 사람들을 위해서 쓰자면

Manifest의 Application 부분에 다음을 추가한다.

android:resizeableActivity="true"


이때 구글의 문서를 보면 오타가 기재되있기도 한데, resiz e able 이다. resiz a ble 아니다. e를 뺴먹지 말자.
그리고 gradle의 complile sdk 옵션을 24 이상으로 설정해야한다. Nougat에서 추가된 기능이기 때문이다.
초기 실행되는 레이아웃 사이즈도 조절할 수 있어 보이는데, 그거까지 바라는 사람은 없을거같다. 여튼, 다원화시대니까,,,,

2018/08/31 13:18 2018/08/31 13:18