2018년 2월 8일 목요일

[python][hackerrank] Jumping on the Clouds: Revisited

아직은 역시 웜업 단계인가 보다.
쉽다.
n, k = tuple(map(int, input().strip().split(' ')))
c = tuple(map(int, input().strip().split(' ')))

result = 100
tmp = 0

while True:
    tmp = (tmp + k) % n
    result -= (1 + c[tmp]*2)
    if tmp == 0:
        break
    
print(result)

2018년 2월 6일 화요일

[python][hackerrank] Sequence Equation

처음에는 리스트로 그냥 뿌려서 하면 되는 건가 했는데
해(OUTPUT)를 가지고 반대로 x값(INPUT)을 구하는 것이었다.
값이 없는 경우가 있다면 그것들을 어떻게 해야 하는지 설명이 필요한데 그에 대한 설명이 없어서
그런경우는 없다는 가정하에 문제를 풀었다.

그래서 미리 p(p(y))를 풀어서 key값에 넣고 그 안에 x(INPUT)값을 value로 넣었다.

n =  int(input())
n_list = list(map(int, input().strip().split(' ')))
p = { n_list[n_list[x-1]-1]:x for x in n_list}

for i in range(1, n+1):
    print(p[i])

[python][hackerrank] Circular Array Rotation

n은 배열 값의 수
k는 right-circular-rotation의 횟수
q는 질의 회수
m은 실제 배열의 값

from collections import deque

n, k, q = map(int, input().strip().split(' '))
m = deque(map(int, input().strip().split(' ')))  # integers
m.rotate(k)  # wow...

for m_i in range(q):
    print(m[int(input())])  # don't need strip(). int() will do this.

혹은 다른 방법을 사용해보자.

n, k, q = map(int, input().strip().split(' '))
m = list(map(int, input().strip().split(' ')))

k %= n; tmp = m[-k:]; del m[-k:]; m[0:0] = tmp

for m_i in range(q):
    print(m[int(input())])  # don't need strip(). int() will do this.

[clojure][designpattern] 프로토타입 패턴

프로토타입은 원형틀이라고도 볼 수 있다.
기본적으로 만들어진 틀을 사용하는 것이다.
내용에서는 회원등록양식을 사용했는데 그 틀에 대한 기본틀을 프로토타입이라 하자. 여기서는 몸무게를 적지 않으면 60킬로를 기본값으로 넣는다고 한다.
그리고 중요한 것은 clone()메소드인데 왜 중요하냐면 기존에 만들어진 틀을 아주 쉽게 복사할 수 있는 것이다.

public class RegistrationForm implements Cloneable {
  private String name = "Zed";
  private String email = "zzzed@gmail.com";
  private Date dateOfBirth = new Date(1990, 1, 28);
  private int weight = 60;
  private Gender gender = Gender.MALE;
  private Status status = Status.SINGLE;
  private List children = Arrays.asList(new Child(Gender.FEMALE));
  private double monthSalary = 1000;
  private List favouriteBrands = Arrays.asList("Adidas", "GAP");

  @Override
  protected RegistrationForm clone() throws CloneNotSupportedException {
    RegistrationFrom prototyped = new RegistrationForm();
    prototyped.name = name;
    prototyped.email = email;
    prototyped.dateOfBirth = (Date)dateOfBirth.clone();
    prototyped.weight = weight;
    prototyped.gender = gender
    prototyped.status = status;

    List childrenCopy = new ArrayList();
    for (Child c : children) {
      childrenCopy.add(c.clone());
    }
    prototyped.children = childrenCopy;
    prototyped.monthsCopy = monthSalary;

    List brandsCopy = new ArrayList();
    for (String s : favoriteBrands) {
      brandsCopy.add(s);
    }
    prototyped.favouriteBrands = brandsCopy;
    
    return prototyped;
  }
}
사용자를 만들 때마다, clone()을 호출해서 기본값으로 쓴다.
왜 clone()을 사용해야 하나? 바로 자바가 나를 죽어라 헷갈리게 한 내용인 카피 문제이다.
이것 때문에 나는 getter를 만들때도 그것이 객체라면 복사를 한다. (혹시 몰라서...)


Clojure

(def registration-prototype
  {:name "Zed"
   :email "zzzed@gmail.com"
   :date-of-birth "1970-01-01"
   :weight 60
   :gender :male
   :status :single
   :children [{:gender :female}]
   :month-solary 1000
   :brands ["Adidas" "GAP"]})

;;return new object
(assoc registration-prototype
  :name "WHO"
  :email "EMAIL@DOTCOM"
  :weight 52
  :gender :female
  :month-salary 0)
clojure는 기본적으로 불변객체이기 때문에 clone은 필요없다.
그렇다면 항상 다 모든것을 final로 만들어 복사하면 느려지지 않을까?
느리긴 한데... 아주 느리지는 않다는 것이 클로저들의 주장인 것같다.

[python][hackerrank] Save the Prisoner!

#!/bin/python3
def saveThePrisoner(n, m, s):
    res = (m + s - 1) % n
    if res == 0:
        res = n
    return res

t = int(input().strip())
for _ in range(t):
    n, m, s = [int(x) for x in input().strip().split(' ')]
    result = saveThePrisoner(n, m, s)
    print(result)

[python][hackerrank] Viral Advertising

좀 더 단순하게 풀 수는 없었을까?
날짜가 지나갈 때마다 생존하는 녀석들을 따로 기억해야했고
그거와 별개로 내가 뱉어내야할 결과값을 따로 담아야했다.
def viral_ad(n):
    tmp = 2
    res = 2
    while n > 1:
        tmp = (tmp * 3) // 2
        res += tmp
        n -= 1
    return res

n = int(input().strip())
result = viral_ad(n)
print(result)

2018년 2월 3일 토요일

[python][hackerrank] Beautiful Days at the Movies

일반적인 방법
i,j,k = [int(x) for x in input().strip().split(' ')]
cnt = 0
for n in range(i,j):
    diff = abs(n - int(str(n)[::-1])) % k
    if diff == 0:
        cnt += 1
print(cnt)

조금더 일반적인(?) 방법
def bueatiful_days2():
    i,j,k = [int(x) for x in input().strip().split(' ')]
    res = sum(1 for x in range(i,j) if abs(int(str(x)[::-1])-x) % k == 0)
    print(res)

[python][hackerrank] Utopian Tree

법칙을 찾는데 오래 걸렸다. easy인데 푸는데 너무 시간이 걸렸다. 리듀스 같은걸 쓰려고 고집해서 그런것 같기도 하다.
n res
0 1 = 1
1 1*2 = 2
2 1*2 + 1 = 3
3 (1*2 + 1) * 2 = 6
4 (1*2 + 1) * 2 + 1 = 7
5 14
6 15
7 30
8 31
even
2 3 2*1 + 1 -> 11
4 7 2*2 + 2*1 + 1 -> 111
6 15 2*2*2 + 2*2 + 2*1 + 1 -> 1111
8 31 2^4 2^3 2^2 2^1 +2^0 -> 11111
from functools import reduce

t = int(input().strip())

for _ in range(t):
    n = int(input().strip())
    print(reduce(lambda a,b: a+b, (map(lambda x: pow(2,x), range(((n+1)//2)+1)))) - n%2)

좀더설명하자면
n은
2일때 11
4일때 111
6일때 1111
8일때 11111
각각 1의 갯수만큼 이진수가 필요하다.
ex) n = 4
111 -> range(((4+1)// 2)+1) -> range(2+1) -> 1 2 3
저절로 1 2 3 이라고 나와주니 더 고맙다. 바로 pow를 이용해서 값을 구하자
[pow(2,1), pow(2,2), pow(2,3)]
그리고 다 더한다. reduce로
reduce(lambda a,b: a+b, [pow(2,1), pow(2,2), pow(2,3)])
그리고 even odd에 따른 차이를 뒤에 붙여준다.
 - n%2


[python][hackerrank] Designer PDF Viewer

#!/bin/python3
import string
from functools import reduce

h = {key: int(value) for key, value in zip(string.ascii_lowercase, input().strip().split(' '))}
word = input().strip()

height = reduce(max, map(lambda x: h[x], word))


print(len(word)*height)

참고자료: 딕셔너리로 한꺼번에 가져오기 위한 자료.
https://stackoverflow.com/questions/16060899/alphabet-range-python

[python][hackerrank] The Hurdle Race

이렇게 풀었다.
https://www.hackerrank.com/challenges/the-hurdle-race/problem
#!/bin/python3

n, k = [int(x) for x in input().strip().split(' ')]
height = [int(x) for x in input().strip().split(' ')]


print((lambda x: x if x > 0 else 0)(max(height)-k))
음... 나쁘지 않은듯. 결국 인풋을 받는 내용을 빼고는 한줄로 끝낸 거니까... 근대 이게 효율적인건가?

2018년 1월 26일 금요일

[clojure] 클로저로 mx-record 구하기 (mx-record in clojure)

예전에 MX-RECORD 받아와야 할 때, 자바로 된 것을 클로저로 바꾸면 어떨까 해서 한 번 짜봤던 것이 있다.

시작은 이렇게 하자. nslookup 을 사용할 것이다.
(use '[clojure.java.shell :only [sh]])

(sh "notepad" "a.txt")
(sh "notepad" "/a.txt")
(sh "pwd")
(sh "nslookup")
(sh "nslookup" "-query=mx" "google.com")

뭔가 보이는 것 같다.
(defn find-mx [hostname]
  (letfn [(nslookup [hostname] (sh "nslookup" "-query=mx" hostname))]
    (nslookup hostname)))

(find-mx "google.com")
자세히 보아하니 뭔가 엄청 나오는 거 같다.
좀 더 정리해보자. 보아하니 내가 찾으려는 내용에는 mail이라는 거와 exchanger라는게 붙어 있는 것 같다.
일단 해보자.
(defn find-mx [hostname]
  (letfn [(nslookup [hostname] (sh "nslookup" "-query=mx" hostname))]
    (remove nil? (map #(re-matches #"(.+)mail\sexchanger(.+)" %) 
                       (clojure.string/split (second (second (nslookup hostname))) #"\r\n")))))

(find-mx "google.com")

(["google.com\tMX preference = 10, mail exchanger = aspmx.l.google.com" "google.com\tMX
preference =
10, " " = aspmx.l.google.com"] ["google.com\tMX preference = 30, mail exchanger = alt2.aspmx.l.goog
le.com" "google.com\tMX preference = 30, " " = alt2.aspmx.l.google.com"] ["google.com\tMX
preference
= 20, mail exchanger = alt1.aspmx.l.google.com" "google.com\tMX preference = 20, " " =
alt1.aspmx.l
.google.com"] ["google.com\tMX preference = 50, mail exchanger = alt4.aspmx.l.google.com"
"google.co
m\tMX preference = 50, " " = alt4.aspmx.l.google.com"] ["google.com\tMX preference = 40, mail exchan
ger = alt3.aspmx.l.google.com" "google.com\tMX preference = 40, " " =
alt3.aspmx.l.google.com"])

나온 거 같다. 다른 테스트도 해보자.
user=> (count (find-mx "google.com"))
5
user=> (count (find-mx "google33.com"))
0
user=> (count (find-mx "naver.com"))
3

MX레코드가 있는지 없는지만 확인하고 싶다면
(count (find-mx hostname)) 0)
  true
  false)

(mx-exist? "google.com")
true
(mx-exist? "google3134.com")
false

2018년 1월 25일 목요일

[clojure] 리습-1 너 누구냐

클로저는 리습-1이란다. (그렇단다.)

리습-1

함수나 값 바인딩에 있어서 이름을 같은 방식으로 해석.

리습-2

심벌이 함수 호출 위치에 있는지 인지 위치에 있는지 등의 맥락에 따라 다르게 해석 (다른 곳에서 알아보니 함수이름이 저장되는 곳이랑 변수이름이 저장되는 곳이 다를 수도 있다네... 그러니 같은 변수이름 함수이름이 똑같아도 된다는 말인 것 같다.)

리습-1의 단점은 이름에 의존하기에 어쩌다 그 이름을 겹치게 사용하면 문제가 생길 수 있다는 것이다. (음... 다른 리습을 사용안해봐서 잘 모르겠다)
이런걸 포기하고 바인딩에 대한 단순성을 가지기 위해 리습-1을 사용하는 듯 하다.

어쨋든

클로저는 리습-1의 해석방식을 적용하여 명확한 구현과 심벌을 조회할 때 혼란에 빠지지않고 로직에 집중하라는 말씀이시다. (사실 잘모름...)
클로저의 단순성이 무엇인가
(defn best [f xs]
  (reduce #(if (f % %2) % %2) xs))
(best > [1 2 3 4 5 6])
6
위 best함수는 > 함수를 받아 몸체 안에서 f로 호출한다. (이렇게 함수, 값이 이름바인딩으로 아주 일괄적)
이게 뭐? 라고 생각한하면

리습-2(커먼리습)은 명시적으로 함수를 호출해주는 다른 함수 (funcall 이라고 하네?)의 도움이 필요하다. 마찬가지로 어떤 함수를 넘기려면 다음과 같이 함수 객체임을 표시하는 태그를 사용해야함.

;; 이거 클로저아님 커먼리습 코드임 실행안되니까 따라치지 말길.
(defun best (f xs)
  (reduce #'(lambda (l r)
             (if (funcall f l r) l r))
         xs))

(best #'>' '(1 2 3 4 5 6))
뭐 이상해 보이는건 내가 커먼리습을 몰라서 그런거지 절대 클로저가 좋아서 그런건 아닌듯. 그냥 차이를 알고 있자.


2018년 1월 23일 화요일

[Udacity] Robotics nanodegree term 1 후기

엄청 빡셌다.

유다시티 로보틱스 강의는 전체적으로 수학적 지식을 많이 요한다.
유다시티 강의의 특징은 제대로 가르쳐준다는 것이다. vagrant, docker 필요한 것은 다 써서 환경을 만들어주고
우리는 필요한 것만 배우면 된다. (설치가 안되요... 이런 걱정을 하지말아도 된다. 알아서 vm을 넘겨준다.)

혹여 안되는 것이 있어도, 1:1 채팅으로 많은 것을 해결 할 수 있다. 그것이 수학이던 프로그래밍이던... (대신 영어로)

디테일한 부분은 설명을 안하고 넘어가기도 한다. 관련 내용은 링크를 막 뿌리는데 그거로 공부하라는 것 같다.

그리고 slack을 이용할 수 있는데 난 잘 이용하지 않았다. 왜냐하면 1:1 채팅으로 스크린샷 등 보내주면서 물어보기 때문에 여기서 안되면
슬랙이 무슨 소용인가 싶었다.

프로젝트가 재미있는데 프로젝트를 하는 것보다, 프로젝트를 어떻게 풀었는지 적는 것이 너무 힘들었다.

프로젝트 1 : 저절로 길을 따라 가는 로봇 (https://github.com/ssisksl77/Udacity-RoboND-Rover-Project)
가장 재미 있었다. 파이썬으로 좌표를 따서 맵에 붙이고 좌표를 변경하고 하는 것이 아주 흥미로웠다. 이 프로젝트까지는 무료이기 때문에 한번 들어보는 것도 괜찮겠다.

프로젝트 2 : 로봇팔 (깃허브링크 없음)
꽤나 힘들었다. 푸는 것이야, 구글을 보고 이곳저곳 보고 해서 풀었지만. 완.벽.한. 개념이해가 없었다.
유다시티는 이것을 그냥 놔두지 않는다. 결국 6관절 로봇팔을 손으로 그려서 여기는 sin세타 저기는 코사인 뭐 그런걸 다 적어서 어떻게 저 각도를 구할 수 있었는지 주말내내 그려서 찾아냈다.

프로젝트 3 : 물체 인식 로봇 (깃허브 https://github.com/ssisksl77/RoboND-Perception-Project)
여기부터 머신러닝을 공부하기 시작했다. SVM 이란걸 만들어서 물체들을 인식할 녀석들의 형태 같은 것들을 저장한다. 여기부터 아... 머신러닝이 이런거구나... 라는 느낌을 받았다.
filtering RANSAC Exercise: https://www.youtube.com/watch?v=vt0QpQmOjto
Cluster Visualization : https://www.youtube.com/watch?v=xcQ5ySgGAMM
Object Recognition : https://www.youtube.com/watch?v=bwYcwcsnXbU
Train SVM: https://www.youtube.com/watch?v=GXwLPqTjkZ8 also contained in this repository

프로젝트 4 : 딥러닝 사람인식하는 쿼드로터 (https://github.com/ssisksl77/RoboND-DeepLearning-Project)
애뮬레이터로 드론이 나온다. 특정 인간을 찾아서 그 사람만을 따라가는 것이다. 이 내용은 딥러닝을 지식이 다분이 필요한데... 정말 힘들었다.
딥러닝을 어느정도 이해하고(이제 다 까먹은듯..) 풀 때는 재미있었다.
AWS에 들어가서 GPU연산용 EC2를 켜고 주피터 노트북으로 딥러닝 연산을 이것저것 바꿔보면서 해보면서 느낀 점은... 프로그래밍이 정말 필요없겠네... 이런느낌이었다.
다 풀고나서 끝이 아니다.
이게 뭔지 어떻게 풀었는지 설명하라는 것은 정말 답이 없었다.(한 6번 퇴짜 맞은듯 하다). 해당 깃허브에 가면 어떻게 문제를 풀었는지 볼 수 있는데... 하... 머리를 쥐어짰다. 정말...
하지만 그 사람을 따라다니는 것을 보면 흐믓하기도 했다.
Follow Me: https://www.youtube.com/watch?v=QYENm4WjB8k

하지만 term2는 안듣기로 했다. 왜냐하면 TX2를 구매해서 조립하고 그걸 가지고 뭔갈 하는 건가본데...
일단 TX2가 한국으로는 할인이 안된다. 물어봤더니 그래서 2학기 자체가 할인되니 그건 좋지? (뭐래...)
둘째, python 에서 C++로 변경해서 코딩해야 한다. 커리큘럼이 똑같은데 이 말은 비슷한 내용을 C++로만 바꾸고 실습해보는 수업일 수 있다는 점.
셋째, 쉬고싶어서. 일을하면서 다른 공부를 하는 건 재미있었는데, 이렇게 프로젝트를 3주에 하나씩 끝내지 않으면 돈이 날아간다는 생각하니 엄청힘들었다.
넷째, 이제 다른 것도 공부해야지. 머신러닝도 제대로 좀 알아야 할 거 같고, 파이썬, 클로저, 자바도 좀 더 제대로 만지고 싶다.


일단 Udacity는 가격의 값어치를 하는 곳은 분명하다. 하지만 그 만큼 많은 공부를 해야 한다. 유다시티의 nanodegree의 강의 내용은 꽤나 짧다.
우리가 기대해야 할 것은 프로젝트다. 프로젝트를 진행할 때, 함수를 만드는 방식, 클래스를 이용하는 방식, 등등을 꼬집어 준다.
그리고 정말로 이해를 했는지 끝까지 물고늘어진다.(로보틱스과정만 그런걸지도...)

프로젝트의 실력있는 분이 옆에서 도와주는 것처럼 하기 위해 많은 노력을 한다. 그 점을 높이산다. 좀 아쉬운 점은 한국에 있기 때문에 오프라인 이벤트들을 참여할 수 없었다.
그리고 많이 비싸다. 값어치를 하지만 많이 비싸다는 것을 유념하자. 하지만 머신러닝을 공부할 때 질좋은 교육을 배우고 싶다면 유다시티를 추천한다.