블로그 이미지
.
속눈썹맨

공지사항

최근에 올라온 글

최근에 달린 댓글

최근에 받은 트랙백

글 보관함

calendar

1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31

OCaml

2006. 3. 15. 11:53 | Posted by 속눈썹맨

. 설치
http://ropas.kaist.ac.kr/caml/ocaml
-> distribution
-> Native Win32 port based on the Microsoft toolchain (3.08.2)

http://caml.inria.fr/
-> Download
-> Binary distributions for Microsoft Windows
-> Self installer (3.09.0) for the port based on the Microsoft toolchain

Interpreter 사용에는 Visual C++이나 cygwin 등이 필요없고
compiler 사용시에만 필요하다.

Compiler를 쓰기 위해서는 module system을 이해해야 한다.

. ML
Segmentation fault가 없다.

. SML
http://www.smlnj.org/ (미국식) - 요즘 개발 잘 안됨

. Ocaml
Caml + OOP

. Ocaml 문법
;; : 프로그램의 끝
+. : float를 위한 add(strongly typed language라서 integer add와 다르다.)
. _ : int = 1
_ : 변수명 없음
int : type
1 : value
. tuple 만들기 (a,b,c,d)
. tuple 쪼개기 (pattern matching 이용)
. function type : (입력 변수1 타입 -> 입력 변수2 타입 -> ... -> 입력 변수n 타입 -> 출력변수 타입)
. :: : cons operator (int -> int list -> int list)
. @ : list comcatenation operator(int list -> int list -> int list)
. 둘 중 하나로 다른 것을 구현가능하다.
. match e with
| pattern1 -> e1
| pattern2 -> e2
e(expression)이 pattern 1을 만족하면 e1을 수행 아니면 아래를 비교
. program : data type + algorithm

. let
같은 변수명이나 함수명을 다시 정의하면 가장 최근에 정의한 것이
수행된다.

. type 정의
type abc = A|B|C
type pair = PAIR of int * int
. A,B,C,PAIR
data 모양의 이름, 첫 글자는 반드시 대문자이다.
data를 construction할 때 사용한다.
A,B,C처럼 of가 없으면 delimiter, seperator, maker 등으로 쓴다.
ex) let a = A;;

. type abc = A
type abcd = A
let value = A( )
가장 최근에 적은 A가 그 위의 것을 shadow한다.
따라서 value의 type은 abcd이다.

. match e with
| ListEnd ->
| ListNode(1, ListEnd) ->
| ListNode(1, ListNode(x,y)) ->
| ListNode(x, y) ->
| x : 아무거나(named)
| _ : 아무거나(unnamed)

. program의 모든 부분이 strongly typed
. add-one
. run_twice (int->int) -> int -> int
. n! = n * (n-1) if n > 1
= 1 otherwise
. Polymorphism
. List -> 'a | 'a List

. 예제 프로그램
type tree = Leaf | Node of tree * tree;;

type tree = Leaf of int | Node of int * tree * tree;;
(* sum(lt) 대신 sum lt라고 써도 된다. *)
let rec sum t = match t with
| Leaf(x) -> x
| Node(x, lt, rt) -> x + (sum lt) + (sum rt);;

let value t = match t with
| Leaf i -> i
| Node (i, lt, rt) -> i;;

(* depth first search *)
let rec dfs t = match t with
| Leaf i -> print_int i
| Node (i, lt, rt) -> dfs lt; dfs rt; print_int i; ;;

(* tree t에 k라는 원소가 있는 지 본다. *)
let rec mem k t = match t with
| Leaf i -> k = i
| Node (i, lt, rt) -> (k = i) or (mem k lt) or (mem k rt);;
(* k = i은 bool type *)
(* or은 앞 expression 틀렸을 때 수행됨 *)

let mytree = Node(1, Node(2, Leaf 100, Leaf 4), Leaf 5);;
sum mytree;; => 112

(* map : ('a -> 'b) -> 'a list -> 'b list *)
let rec map f alist = match alist with
| [] -> []
| hd::tail -> (f hd)::(map f tail);;

(* alist에 el이라는 원소가 있는 지 본다. *)
let rec mem el alist = match alist with
| [] -> false
| hd::tail -> (hd = el) or (mem el tail);;

let rec gcd n m =
if n = 0
then m
else if n >= m
then gcd (n - m) m
else gcd m n;;

. Mutual recursive function
let rec f x = 블라 (g 블라) 블라
and g y = 블라 (f 블라) 블라

. Mutual recursive type(?)
type t1 = ... | C1 of ... * t2 * ... | ...
and t2 = ... | C2 of ... * t1 * ... | ...

. assignment statement(= side effect 생김)
let x = ref 0;
let _ = print_int !x;
let _ = x:=1;
let _ = print_int !x;

. head and tail
head::tail -> head === car, stack top
head::tail -> tail === cdr, stack pop

. Type
1. let rec gcd (n, m) = (int * int -> int) type
  => gcd (1,2) : OK
  => gcd 1 2 : error               

2. let rec gcd n m = (int -> int -> int) type
  => gcd (1, 2) : error
  => gcd 1 2 : OK

. Type
[] : list type - 같은 타입의 원소가 몇 개든 들어와도 됨. (다른 타입이 섞일 수 없음, 갯수가 맘대로)
() : tuple type - 원소의 갯수와 type이 정해짐. (다른 타입이 섞일 수 있음. 갯수가 고정)
list는 원소를 ;로 구분하고
tuple은 원소를 ,으로 구분해준다.
[1,2,3]은 [(1,2,3)]으로 해석함.

. Type
let rec eval t = match t with
| INT i -> i
| PLUS (ls, rs) -> (eval ls) + (eval rs)
| MINUS (ls, rs) -> (eval ls) - (eval rs)
| TIMES (ls, rs) -> (eval ls) * (eval rs);;
Characters 17-75:
Warning P: this pattern-matching is not exhaustive.
Here is an example of a value that is not matched:
INT _
  .................match t with

=> INT(i) -> i 로 적어야 됨. 괄호를 안치면 이런 에러가 남.

. Polymorphism
. 안전성(sound), 완전성(completeness)
. 안전성과 완전성은 둘 다 달성될 수 없다. trade-off 해야 한다.
. Polymorphism은 completeness를 위해 존재한다.
. completeness를 위해 soundness를 희생
let rec f x =
let _ = (f 1, f "")
in ();;
(ML의 type system이 허용하지 않음, LISP에서는 허용)
. ML => sound, LISP => complete

(* cmp 순으로된 두 list를 merge하기 *)
# let rec merge cmp l1 l2 = match (l1, l2) with
     | ([], lst) -> lst
     | (lst, []) -> lst
     | (h1 :: t1, h2 :: t2) ->
     match (cmp h1 h2, cmp h2 h1) with
     | (true, false) -> h1 :: (merge cmp t1 l2)
     | (false, true) -> h2 :: (merge cmp l1 t2)
     | _ -> h1 :: (merge cmp t1 t2);;
(* cmp match에서 h1 h2, h2 h1을 두개 비교하는 이유 *)
(* cmp에 등호가 들어갈 때나 아무튼 두 원소가 같은 경우 한 번만 적어주기 위함 *)

# let less x y = x < y;;
# merge less [1;3;5] [2;4;8];;

# merge less [1,3,5] [2,4,8];;

(* list의 구분자는 ;임 ,를 쓰면 안됨 *)
(* list를 2개의 list로 split 함 *)
let rec split list = match (list) with
                    | ([]) -> ([], [])
                    | ([x]) -> ([x], [])
                    | (x::y::tail) -> let (p, q) = (split tail) in (x::p, y::q) ;;

# split [1; 2; 3; 4; 5; 6; 7; 8;];;
- : int list * int list = ([1; 3; 5; 7], [2; 4; 6; 8])

(* tail recursive를 이용한 split 구현 *)
(* 속도가 더 빠르다. split하면서 값의 순서가 뒤집혀서 나온다. *)
let split x =
  let rec loop(p, q, r) = match(p, q, r) with
       | (p, q, []) -> (p, q)
       | (p, q, [a]) -> (a::p, q)
       | (p, q, a::b::rest) -> loop(a::p, b::q, rest) in loop([], [], x);;

split([1;2;3;4;5;6;7;8;9;10]);;
- : int list * int list = ([9; 7; 5; 3; 1], [10; 8; 6; 4; 2])

let rec sort less list = match (list) with
   | [] -> [] (* 이것이 없으면 stack overflow가 일어남. *)
   | [a] -> [a] (* 이것이 없으면 stack overflow가 일어남. *)
   | list -> let rec merge (l1, l2) = match (l1, l2) with                    
       | ([], a) -> a                                                        
       | (a, []) -> a                                                        
       | (h1::t1, h2::t2) ->                                                 
           if (less h1 h2) then h1::merge(t1, l2)                            
                           else h2::merge(t2, l1)                            
       and split l = match (l) with                                          
           | [] -> ([], [])                                                  
           | [x] -> ([x], [])                                                
           | (x::y::tail) -> let (p, q) = split tail in (x::p, y::q) in
       let (p, q) = split(list)                                                  
       in merge((sort less p), (sort less q));;

sort less [];;
sort less [1];;
sort less [1;2];;
sort less [2;1];;
sort less [1;2;3];;
sort less [2;1;3];;
sort less [3;2;1];;
sort less [10;9;8;7;6;5;4;3;2;1];;
sort less [1;2;3;4;5;6;7;8;9;10];;

. ML에서 Ocaml로 포팅하기
  . ML은 fun을 쓰지만 Ocaml에서는 let으로 쓰고 fun을 생략
  . Recursive function의 경우 ML은 rec을 안 쓰지만 Ocaml에서는 rec를 쓴다.
  . ML은 그냥 |으로 구분하지만 Ocaml은 match를 쓴다.
  ML은 =을 쓸 때 Ocaml은 ->을 쓴다.
  . ML은 nil, Ocaml은 []

Haskell - a lazy functional programming language

2006. 3. 15. 01:58 | Posted by 속눈썹맨
. GHC (Haskell 구현 중 하나)
http://www.haskell.org/ghc/
-> Download
-> Windows용
-> Standalone과 Visual Haskell (Visual Studio용이 있음.)

. 시작 -> 프로그램 -> GHC -> 버젼 -> GHCi

. 종료
:quit

. 예제 프로그램

Drscheme

2006. 3. 15. 01:57 | Posted by 속눈썹맨
http://www.drscheme.org/
. DrScheme v301
plt-301-bin-i386-win32.exe를 실행
PLT Scheme이라고 깔림
. 실행
choose Language -> Professional Languages -> Standard(R5RS)

. 예제
(+ 1 2) => 3
(car (quote (A B))) => A
초등학교 선생님으로 있는 친구가 이런 문제를 냈다.
정육면체의 전개도는 11개.
그럼 직육면체는 전개도가 몇 개나 될까?

일단, 정육면체의 전개도는 다음과 같다.

*
****
*

*
****
*

*
****
*

*
****
*


*
****
*

*
****
*

**
***
*

*
*
****

**
**
**

*
*
**
*
*

*
*
***
*
-----------------
직육면체는 세 변이 모두 길이가 다르다고 하자.

그리고 좀 더 조건을 강하게 줘야 할 것 같다.
'세 변 중 어느 두 변도 한 변이 다른 변의 2,3,4,5배가 되지 않는 다.'
(이렇게 안하면 변의 길이에 따라서 경우의 수가 다를 것 같아서.)

음, 그럼 후보군은 몇개나 될까?
일단 정육면체의 전개도를 이미 구했으니 그것을 이용해보자.
세 변 중 두 변을 고르는 경우의 수는 3가지.
가로로 놓을 지, 세로로 놓을 지에 따라 그것들이 다시 2가지.
즉, 6가지의 방법으로 11개의 전개도 각각에 직사각형을 assign 할 수 있다.
일단 각 전개도에서 한 면만 assign되면 다른 면들은 그 면에 dependent하게
결정된다. (아랫면, 옆면 등 이웃면의 길이가 fix되므로)

이제 우리는 3 x 2 x 11 = 66가지만 test해보면 된다.
사람이 해볼 수도 있겠으나 너무 귀찮으니 컴퓨터로 해보자.
66가지는 아주 쉽게 generate 할 수 있다.
(Graphic툴로 금방 그릴 수 있다.)

66개지만 서로 모두 비교할 필요는 없고 각자 6가지 중에 서로를 비교하면 된다.

비교도 컴퓨터로 하면 편할 듯.
회전과 flip이 가능한 모든 가짓수를 따져보면
0도 회전, 90도 회전, 180도 회전, 270도 회전 = 4가지
그대로 두기, 좌우 뒤집기, 위아래 뒤집기, 좌우위아래뒤집기 = 4가지
4 x 4 = 16가지.

6가지를 비교하려면 6C2 = 15가지 pair가 나옴.

(15번) x (16가지) x (16가지) x (11Group) = 42240번의 6 x 6 Matrix 비교가 필요하다.

그럼 이제 문제를 정리하고 짜야할 프로그램을 알아보면
1. 전개도 생성 프로그램(전개도가 없다면)
2. 전개도 비교 프로그램(전개도가 주어져 있다면)

일반적으로 확장해보면
정 n면체나 축구공 같은 도형에 대해서도 풀 수 있을 것 같다.
이 경우 자유도가 더 크다.

예를 들자 면이 육각형이라고 하면
0,60,120,180,240,300도의 회전 = 6가지
6개의 축을 이용한 뒤집기 = 6가지
사각형은 16가지였지만 6각형은 36가지다.
비교를 위해 도형을 align하는 방법도 좀 더 고민해야 할 것이다.
--------------------
유사한 문제
. 고등학교 화학 II - 유기화합물 가지 그리기, 광학이성질체, 기하 이성질체
. 단백질 folding
. 재료공학 - 고체 결정구조(Crystal)
. Graph Theory - connectivity, connected component
. 이산수학, 조합수학, 위상수학(?)
--------------------
@ 추천곡 '네모의 꿈' - 푸른하늘

function object (= functor )

2006. 3. 6. 01:05 | Posted by 속눈썹맨
C++에 도입된 기능이다.
특히 C++ STL에서 사용된다.
callback function의 용도로 많이 쓰인다.
pointer to function와 같은 기능을 갖지만 몇 가지 장점이 있다.

http://www.sgi.com/tech/stl/functors.html
http://gethelp.devx.com/techtips/cpp_pro/10min/10min0100.asp
http://en.wikipedia.org/wiki/Function_object
. 장점
. result를 global, local variable이 아닌 member function에 가지고 있으므로 안전하다. (여러곳에서 call하다가 결과가 사라지는 일이 없을 것이므로)
. compiler가 지원한다면 inline이 가능하다.
. 보통 생성자, 소멸자를 안 쓰므로 overhead가 없다.

. STL에서 사용되는 곳
#include // for greater<> and less<>
#include //for sort()
sort()
for_each()
greater()
less()

. 예제 코드
// vector V의 모든 값을 accumulate한다.
struct adder : public unary_function
{
adder() : sum(0) {}
double sum;
void operator()(double x) { sum += x; }
};

vector V;
...
adder result = for_each(V.begin(), V.end(), adder()); [3]
cout << "The sum is " << result.sum << endl;

. Languages
. Smalltalk : one of the first language to support functor
. C : function pointer
. C++ : overloads the function call operator by defining an operator() member function, class type functor, operator()
. Java : deriving from the interface, inheritance model of functor
. Python : __call__()
. Lisp
. ML : Mapping from module to module
. Prolog : function symbol

Voucher 제도

2006. 3. 1. 03:13 | Posted by 속눈썹맨
. Voucher
일종의 coupon처럼 특정한 물건만 살 수 있게 하는 ticket.
Marketing에서 유래되었다.
예) 도서 상품권, 문화 상품권, 백화점 상품권.

. Voucher 제도
정부에서 교육, 빈민층 구제를 위한 음식 교환권, 사회보장 등을 위해 발행.
사회보장에 시장원리를 적용하는 셈.

현금으로 지급하게 되면 utility function에 따라 소비자는 현명한 선택(정부가 원하는 선택)이 아닌 자신의 마음에 드는 선택을 할 수가 있다.
따라서 특정 상품을 구입하는 것을 강제하게 한다.
그리고 암시장이 생겨서 그것을 몰래 팔지 않도록 해야 한다.

. 여행 voucher 제도
중소기업에 다니는 250만원 이하의 월급 생활자가 국내 여행시 40%(15만원 이내)를 지원하는 제도
일종의 복지제도인데, 중소기업의 부족한 복지 수준을 정부가 보조해줌.
중소기업청 : http://www.smba.go.kr
한국관광협회중앙회 : http://www.KoreaTravel.or.kr

칼 아이칸, KT&G 주식 공개 매수

2006. 2. 24. 13:18 | Posted by 속눈썹맨
. 적대적 M&A에 약한 기업
뚜렷한 대주주가 없을 때
주가가 지나치게 쌀 때

. 공개매수
현재 주가의 30% 정도 높은 가격을 불러, 주식을 사모아서 M&A를 시도하는 것

. 2.23일 종가
칼 아이칸은 17% 높은 가격을 물렀음,
그런데 이미 주식이 12% 뛰어서 공개매수에 응해 주식을 팔 merit가 사라지고 있음.

. 시세 차익
공개매수를 선언하면 대부분 주식이 뛰기 마련인데, 그 때 오히려 모두 팔아버리면 큰 시세 차익을 남길 수 있다.

. 칼 아이칸
. 2005년 8월 타임워너(세계 최대 미디어그룹)를 공격

. 방어장치
. 독소조항(poison pill)

. 기업사냥꾼
. 장기적 성과를 희생해서 단기 성과를 내도록 압박함.
최대한 빠르게 자본을 회수하려고 하기 때문에 투자/개발 등에 인색해짐.
자사주 배입, 배당금 늘리기 등을 원함

. Bear's hug(곰의 포옹)
. 경영진에게 매수를 제의하고 공개매수도 시작.

. 담배금지법
. 금주법처럼 담배 금지법이 논의 되고 있음.
. 국내 흡연자 : 1,200만
. 고용인 : 20만

CG - Texture

2006. 2. 14. 18:27 | Posted by 속눈썹맨
Texture라는 것은 상당히 특이한 기법인 것 같다.
요즘 웹게시판이나 GUI에서 말하는 skin과 꽤 비슷하다.
일단 기하학적인 물체의 모양을 모두 그린 후 질감을 입히는 것이다.

음악으로 말하자면 midi와 비슷하다.
midi 방식은 거시적인 파장만 저장한 후 각 악기의 음을 녹음해서
음색을 입히는 방식이다. (악보 + 음색이라고 볼 수 있다.)

음색, texture 같은 기법들은 인간의 인식에 의해 사용되는 추상적인 모델을 이용한 손실 decomposition이라고 할 수 있겠다.

아무튼 상당히 훌륭한 생각이다. 일반적으로 같은 물체는 같은 질감을 가지니까.

. decal - 전사인쇄 방식
프라모델(plastic model)을 만들 때도 쓰인다. 판박이라고도 부른다.
일단 종이나 어떤 표현에 물감 등을 묻힌 후 그것을 입체 도형에 입히는 기법.

100분 토론 - 부동산 문제

2006. 2. 10. 01:46 | Posted by 속눈썹맨
. 양도소득세
현재 양도소득세가 너무 올라서 다주택자가 집을 내놓지 않음.

. 문제
강남에 집을 사려면 평균 40년 이상 돈을 모아야함.
전국적으로 99%, 서울은 90% 이상이 집을 가질 수 있지만 실제로 서울 사는 사람의 40%는 집이 없음.

. 근본적 원인 - 토지의 불로소득(지대)
건물에 대한 금액은 별로 되지 않음.
예를 들어 강남의 10평대 아파트의 경우 재건축시만 의미가 있지, 그 집들은 너무 낡아서 실질적으로 가치가 거의 없음.
국가가 토지를 보유, 임대하고 건물만 분양 - 홍준표 의원 등의 주장, 일본, 유럽에서 일부 시행 중, 아파트의 가격이 정말로 떨어지는 것은 아님, 하지만 소비자가 적은 돈으로 집을 마련할 수 있음.
우리나라는 땅값이 너무 비쌈.

현재는 건물과 땅 모두를 임대하는 임대 아파트가 있음.

. 홍준표 의원의 주장
토공 등은 땅 장사를 해서는 안된다.(투기로 3조를 남겼음.)
정부기관은 이익을 남겨서는 안된다.

. 토공의 해결책
장기 계획을 세우거나 계획이 세워지기 전에 땅값이 쌀 때 미리 토지를 매입해둔다.

. 부동산 정책의 종류
공급 위주의 정책
수요 위주의 정책

. 개발이익 환수제
개인의 노력없이 앉아서 국가의 정책에 의해 이익이 난 것은 국가가 회수에서 공적으로 쓴다.
한나라당(홍준표) - 반대, 1가구 1주택에 가난한 강남 주민에게도 이익을 환수하는 것은 안 좋다.
재건축에서는 기술적 문제가 있어서 아직 시행되지 못하고 있다.
개발이익을 계산하기 힘들다. 늦게 계산하면 이미 올라버리고, 집값이 떨어지면 걷은 세금은 다시 돌려줘야 할까?
결국 재건축을 해야 주택공급이 확대 되지만 이익 환수를 제대로 하지 못하고 재건축을 하면 투기가 일어난다.

. 재개발 - 도시 계획부터 다시함. 상하수도, 도로도 다시 만듬, 주택 -> 아파트, 강북
. 재건축 - 집만 다시 지음. 아파트 -> 아파트, 강남

HDTV (high-definition television)

2006. 2. 10. 00:19 | Posted by 속눈썹맨
해상도 : 아날로그 2배
비율 : 5:3.3 (기존 아날로그 4:3)

준비물 : PC + HDTV용 TV수신카드 + UHF안테나(기존 TV안테나와 다름)
. HDTV용 TV수신카드
외장형이 좋음.
케이블 TV에서도 HDTV를 송출하는 채널도 있음.
대부분 기존 TV주파수와 겸용임.
날씨의 영향을 아날로그보다 좀 더 받음.
수신율이 떨어지면 아날로그는 잡음이 끼지만 HDTV의 경우는 아예 수신이 안될 수 있음.
내장형보다 외장형이 하드웨어 충돌이 적음.
저가형은 소프트웨어로 디코딩을 하므로 CPU resource를 많이 잡아먹음.
Pentium 4이상, Graphic card가 좋으면 유리
가격 - USB 2.0 이용 - 13~15만원대
브랜드 - 시그마컴, 디비코, AMT

. UHF 안테나
실내용, 실외용이 있음. 실외용이 더 좋음.
하지만 KAIST 기숙사는 실내용을 써야할 것임.
가격 - 실내용 6만원 대
실외용 - 2~4만원 대

. 송신소
. 대전
식장산 - CH14(KBS1), CH16(KBS2), CH18(EBS), CH17(MBC), CH15(SBS - TJB)
계룡산 - CH26(KBS1), CH32(KBS2), CH38(EBS)