<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0"><channel><atom:link rel="hub" href="http://tumblr.superfeedr.com/" xmlns:atom="http://www.w3.org/2005/Atom"/><description>Programmer</description><title>HPI.cc</title><generator>Tumblr (3.0; @astralhpi)</generator><link>http://hpi.cc/</link><item><title>SICP 연습문제 1.22</title><description>&lt;p&gt;한동안 공부할 만한 멘탈 상태가 아니라서 쉬고 있었습니다. 이러면 안되겠다는 생각에 문제나 풀었습니다.&lt;/p&gt;
&lt;p&gt;이 연습 문제에 대해서는 문제와 답을 생략하고, 필요한 프로시저만 포스팅하도록 하겠습니다. 문제가 너무 길고, 공부한 내용을 실험으로 체크해보는 형태의 문제라 포스팅하기 난감하네요.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;(define (search-for-primes start end)&lt;/p&gt;
&lt;p&gt;  (define (check-and-next-iter cur)&lt;/p&gt;
&lt;p&gt;    (timed-prime-test cur)&lt;/p&gt;
&lt;p&gt;    (iter (+ cur 2)))&lt;/p&gt;
&lt;p&gt;  (define (iter cur)&lt;/p&gt;
&lt;p&gt;    (if (&amp;lt; cur end)&lt;/p&gt;
&lt;p&gt;        (check-and-next-iter cur)&lt;/p&gt;
&lt;p&gt;        0&lt;/p&gt;
&lt;p&gt;        )&lt;/p&gt;
&lt;p&gt;    )&lt;/p&gt;
&lt;p&gt;  (if (even? start)&lt;/p&gt;
&lt;p&gt;      (iter (+ start 1))&lt;/p&gt;
&lt;p&gt;      (iter start)))&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;#이 프로시저대로라면 2를 소수로 체크하지 않겠지만, 문제에 주어진 조건이 &amp;#8216;홀수&amp;#8217;를 차례로 찾아 소수인지 알아보는 프로시저를 짜라는 것이라 이렇게 짰습니다.&lt;/div&gt;</description><link>http://hpi.cc/post/20527221802</link><guid>http://hpi.cc/post/20527221802</guid><pubDate>Thu, 05 Apr 2012 23:40:00 +0900</pubDate><category>SICP</category><category>LISP</category><category>scheme</category><category>study</category><category>programming</category></item><item><title>SICP 연습문제 1.17, 1.18</title><description>&lt;p&gt;연습문제 1.17에 되도는 프로세스로 짜라는 말이 없어서 얼떨결에 반복 프로세스를 펼치는 프로시저를 짜버렸습니다. 그리고 1.18번 문제를 보니 1.17에서 짠 프로시저를 반복 프로세스로 고치라네요? 아이고, 귀찮으니 1.18번에 대한 해답만 포스팅 합니다.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;연습문제 1.17&lt;/p&gt;
&lt;p&gt; 이 절에서 나오는 거듭제곱 알고리즘은 여러번 곱셈을 거듭하여 값을 구한다는 단순한 생각에 뿌리를 둔다. 이와 비슷하게 곱셈도 덧셈을 거듭하는 것으로 나타낼 수 있다. 다음은 expt 프로시저처럼 (언어에서 덧셈만 있고 곱셈은 없다 치고) 덧셈으로 곱셈 프로시저를 짜본 것이다.&lt;/p&gt;

&lt;p&gt;(define (* a b)&lt;/p&gt;
&lt;p&gt;  (if (= b 0)&lt;/p&gt;
&lt;p&gt;      0&lt;/p&gt;
&lt;p&gt;      (+ a (* a (- b 1)))))&lt;/p&gt;

&lt;p&gt;이 알고리즘의 계산 단계는 b와 나란히 (즉, 선형 비례로)자란다. 이때 덧셈 말고도 정수값을 두배로 하거나 (짝수를) 반으로 나누느 프로시저 double과 halve가 이미 있었다고 치자. 이 프로시저를 써서, fast-expt처럼 계산 단계가 로그 비례로 자라나는 곱셈 프로시저를 짜보라.&lt;/p&gt;

&lt;p&gt;연습문제 1.18&lt;/p&gt;
&lt;p&gt;연습문제 1.16과 1.17에서 얻은 결과를 바탕으로 덧셈, 두 배 값, 반값을 구하는 프로시저를 써서, 계산 단계가 로그 비례로 자라나는 반복 프로세스를 펼치도록, 곱셈 프로시저를 짜보자.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;해답은 1.16번 문제와 유사합니다.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;(define (mul a b)&lt;/p&gt;
&lt;p&gt;  (define (mul-iter result a b)&lt;/p&gt;
&lt;p&gt;    (cond ((= b 0) result)&lt;/p&gt;
&lt;p&gt;          ((even? b) (mul-iter result (double a) (halve b)))&lt;/p&gt;
&lt;p&gt;          (else (mul-iter (+ result a) a (- b 1)))))&lt;/p&gt;
&lt;p&gt;  (mul-iter 0 a b))&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;너무 성의가 없네요.&lt;/p&gt;</description><link>http://hpi.cc/post/20164211361</link><guid>http://hpi.cc/post/20164211361</guid><pubDate>Fri, 30 Mar 2012 18:32:57 +0900</pubDate></item><item><title>안드로이드 때문에 삶이 고달픕니다.</title><description>&lt;p&gt; 이제까지 안드로이드용 앱 개발을 하면서 수많은 멘탈붕괴를 겪었습니다. 근본적인 해결을 하지 못한 기기별 사운드 싱크 문제라던가, WebView에서 loadURL에 get인자를 넣으면 페이지 로드에 실패하는 문제라던가, 특정 HTML 페이지에서 text form을 탭하면 렌더링이 엉망이 되었다가 refresh 하고 나면 text form을 탭해도 렌더링이 문제가 발생하지 않는다든가&amp;#8230;. &lt;/p&gt;
&lt;p&gt; 언급하자면 한도 끝도 없습니다. 파편화 때문에 OS와 SDK의 버그에 대해서 업데이트를 기대할 수 없음에도 불구하고, 안드로이드 앱을 개발해야 하는 상황이 이런 문제들을 어떻게든 땜질해야 하게 만들었죠. &lt;/p&gt;
&lt;p&gt; 오늘도 어김없이 안드로이드는 저의 멘탈을 흔들어 놓았습니다. 상황이 복잡해서 설명하긴 좀 어렵지만, 요약하자면 scrollView에 listView가 있을 때, listView의 adapter의 notifyDataSetChanged 메소드를 호출하면 scrollView에 있는 다른 애니메이션의 listener가 불리지 않는 문제였습니다. 다른 재현을 위한 구체적인 조건이 있는지는 자세히 체크해보지 않아 모르겠습니다. &lt;/p&gt;
&lt;p&gt; 물론, 플랫폼을 의심하는 것보다 짜여진 코드를 의심하는 것이 맞습니다. 하지만 결국 플랫폼의 문제로 밝혀진 적이 한두 번이 아니다보니 어쩔 수 없이 플랫폼을 의심하게 되더군요.&lt;/p&gt;
&lt;p&gt; 안드로이드 앱 개발을 시작하기 전에는 딱히 안드로이드를 싫어하는 것은 아니었고, 구글을 좋아했기 때문에 오히려 호감이 있었습니다. 그리고 안드로이드 앱 개발을 시작한 뒤, 나름 안드로이드 개발 환경을 나쁘지 않게 여기던 적도 있었습니다. 하지만 이젠 아닙니다. 파편화, 버그 많은 OS와 SDK, 힙이 협소하게 제한된 VM등등 이젠 지긋지긋합니다. 물론, 잘 짜면 이런 점을 어느 정도 피할 수 있을지도 모르죠. 그럼에도 OS 업데이트가 힘듦에도 불구하고 버그가 많은 것과 파편화는 답이 없습니다.&lt;/p&gt;

&lt;p&gt;#추가 &lt;/p&gt;
&lt;p&gt; 위에 scrollView 관련 문제는 listView의 adapter에서 notifyDataSetChanged를 호출했을 때 scrollView가 강제로 listView가 보이도록 이동하는 것과 관련이 있는 것 같습니다. 특정 디바이스의 SDK 구현에 있는 문제인지, 특정 OS 버전의 문제인지는 모르겠네요. 시간이 부족합니다.&lt;/p&gt;</description><link>http://hpi.cc/post/20160386729</link><guid>http://hpi.cc/post/20160386729</guid><pubDate>Fri, 30 Mar 2012 15:04:00 +0900</pubDate><category>안드로이드</category><category>멘탈붕괴</category><category>으아아악</category></item><item><title>SICP 연습문제 1.16</title><description>&lt;p&gt;1.13~1.15는 단답형 문제라 포스팅하지 않겠습니다.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;fast-expt처럼 계산 시간이 로그 비례로 늘어나게끔 계속 제곱하는 방법을 쓰되, 반복 프로세스를 펼처내는 거듭제곱 프로시저를 짜보자.&lt;/p&gt;
&lt;p&gt;(귀띔: (b^(n/2))^2 = (b^2)^(n/2)이라는 점을 생각하여 지수 n, 밑수 b, 새  변수 a를 변수로 삼아 상태 바꾸는 귀칙을 정의하되, ab^n 값이 언제나 같도록  하라. 프로세스가 막 돌아갈 때 a는 1이고, 프로세스가 끝났을 때 a에 결과 값이 들어 있다. 대체로 상태가 바뀌어도 변하지 않는 값, 곧 변하지 않는 양을 찾아 정하는 것이, 반복 알고리즘을 설계할 때 아주 도움이 되는 방법이다.)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;이 문제에 대한 저의 풀이는 다음과 같습니다.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;(define (even? x)&lt;/p&gt;
&lt;p&gt;  (= (remainder x 2) 0))&lt;/p&gt;
&lt;p&gt;(define (fast-expt x n)&lt;/p&gt;
&lt;p&gt;  (define (fast-expt-iter a b n)&lt;/p&gt;
&lt;p&gt;    (cond &lt;/p&gt;
&lt;p&gt;      ((= n 0) a)&lt;/p&gt;
&lt;p&gt;      ((even? n) (fast-expt-iter a (square b) (/ n 2)))&lt;/p&gt;
&lt;p&gt;      (else (fast-expt-iter (* a b) b (- n 1)))))&lt;/p&gt;
&lt;p&gt;  (fast-expt-iter 1 x n))&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div&gt;핵심 아이디어는 어떤 인자를 두느냐에 있는 것 같습니다. &lt;/div&gt;
&lt;div&gt;상세한 내용은 문제에 힌트로 잘 나와있습니다.&lt;/div&gt;
&lt;div&gt;점점 풀이가 성의가 없어지는 기분이긴 하지만, 문제에 포함된 귀띔이 자세해서 괜찮다고 자기 합리화 해봅니다.&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;아래는 덤으로 짠, 테스트용 코드입니다.&lt;/div&gt;
&lt;blockquote&gt;
&lt;div&gt;
&lt;div&gt;(define (slow-expt x n)&lt;/div&gt;
&lt;div&gt;  (if (= n 1)&lt;/div&gt;
&lt;div&gt;      x&lt;/div&gt;
&lt;div&gt;      (* x (slow-expt x (- n 1)))))&lt;/div&gt;
&lt;div&gt;(define (test-expt x n)&lt;/div&gt;
&lt;div&gt;  (= (fast-expt x n) (slow-expt x n)))&lt;/div&gt;
&lt;/div&gt;
&lt;/blockquote&gt;</description><link>http://hpi.cc/post/20157518922</link><guid>http://hpi.cc/post/20157518922</guid><pubDate>Fri, 30 Mar 2012 13:34:00 +0900</pubDate><category>SICP</category><category>Scheme</category><category>LISP</category><category>Programming</category><category>Study</category></item><item><title>SICP 연습문제 1.12</title><description>&lt;blockquote&gt;
&lt;p&gt;연습문제 1.12&lt;/p&gt;
&lt;p&gt;다음 같은 꼴로 수를 모아 놓는 것을 파스칼의 세모꼴이라 한다.&lt;/p&gt;
&lt;p&gt;    1&lt;/p&gt;
&lt;p&gt;   1&amp;#160;1&lt;/p&gt;
&lt;p&gt;  1&amp;#160;2 1&lt;/p&gt;
&lt;p&gt; 1&amp;#160;3 3&amp;#160;1&lt;/p&gt;
&lt;p&gt;1&amp;#160;4 6&amp;#160;4 1&lt;/p&gt;
&lt;p&gt;&amp;#8230;&amp;#8230;..&lt;/p&gt;
&lt;p&gt;세모에서 왼쪽과 오른쪽 끝에는 모두 1이 있고, 세모 속에 있는 수는 바로 위에 있는 두 수를 더한 값이다. 파스칼의 세모꼴 수를 만드는 프로시저를 짜되, 되도는 프로세스가 나오도록 하라.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;몇 번째 줄인지를 x, 몇 번째 숫자인지를 y로 나타내면 다음과 같은 함수로 나타낼 수 있습니다.&lt;/p&gt;
&lt;p&gt;f(x,y) = f(x-1, y) + f(x-1, y-1) &lt;/p&gt;
&lt;p&gt;그럼 프로시저를 짜는 것은 해당 함수를 그대로 코드로 옮기면 되죠.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;(define (pascals-triangle x y)&lt;/p&gt;
&lt;p&gt;  (cond &lt;/p&gt;
&lt;p&gt;    ((and (= x 1) (= y 1)) 1)&lt;/p&gt;
&lt;p&gt;    ((= x 1) 0)&lt;/p&gt;
&lt;p&gt;    (else (+ (pascals-triangle (- x 1) (- y 1))&lt;/p&gt;
&lt;p&gt;             (pascals-triangle (- x 1) y)))))&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;부실하게라도 테스트 해보면, 원하는 값이 나오는 것을 확인할 수 있습니다.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;(pascals-triangle 3  2)&lt;/p&gt;
&lt;p&gt;2&lt;/p&gt;
&lt;p&gt;(pascals-triangle 5&amp;#160;3)&lt;/p&gt;
&lt;p&gt;6&lt;/p&gt;

&lt;/blockquote&gt;
&lt;p&gt;*연습문제 1.13은 고등학교 떄 질리도록 한 증명이라 하기 싫어서 안합니다.&lt;/p&gt;</description><link>http://hpi.cc/post/20118115154</link><guid>http://hpi.cc/post/20118115154</guid><pubDate>Fri, 30 Mar 2012 00:31:00 +0900</pubDate><category>SICP</category><category>LISP</category><category>Programming</category><category>Study</category></item><item><title>SICP 연습문제 1.11</title><description>&lt;blockquote&gt;
&lt;p&gt;연습문제 1.11&lt;/p&gt;
&lt;p&gt;n&amp;lt;3일 때 f(n)=n 이고, n&amp;gt;=3일 때 f(n)=f(n-1)+2f(n-2)+3f(n-3)으로 정의한 함수 f가 있다. f의 프로시저를 되도는 프로세스가 나오도록 짜라. 아울러, 반복 프로세스를 만들어내느 프로시저도 만들어 보라.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;되도는 프로세스가 나오도록 짜는건 정말 쉽습니다. 그냥 정의대로 작성하면 되니까요.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;(define (recursive-f n)&lt;/p&gt;
&lt;p&gt;  (if (&amp;lt; n 3)&lt;/p&gt;
&lt;p&gt;      n&lt;/p&gt;
&lt;p&gt;      (+ (recursive-f (- n 1))&lt;/p&gt;
&lt;p&gt;         (* 2 (recursive-f (- n 2)))&lt;/p&gt;
&lt;p&gt;         (* 3 (recursive-f (- n 3))))))&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;하지만, 반복 프로세스가 나오도록 짜는건 좀 귀찮습니다. 그래도 되도는 프로세스가 top-down 식으로 계산하는 것과 달리, 반복 프로세스는 bottom-up으로 계산하도록 짜면 된다는 사실을 깨달으면 별로 어렵진 않습니다.&lt;/p&gt;
&lt;p&gt;일단, f(n) 을 계산하기 위해 필요한 수치는 f(n-1), f(n-2), f(n-3) 3가지 입니다. 그리고, 얼마나 반복을 해야하는 지 카운트 하기 위해 count 인자가 하나 더 필요하겠죠. 따라서 f 의 반복 함수는 다음과 같은 형태로 정의 했습니다. &lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;(f-iter a b c count)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;a는 f(n-1), b는 f(n-2), c는 f(n-2) 를 나타냅니다. &lt;/p&gt;
&lt;p&gt;구현은 다음과 같습니다.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;(define (f-iter a b c count)&lt;/p&gt;
&lt;p&gt;  (if (= count 0)&lt;/p&gt;
&lt;p&gt;      a&lt;/p&gt;
&lt;p&gt;      (f-iter&lt;/p&gt;
&lt;p&gt;       (+ a &lt;/p&gt;
&lt;p&gt;          (* 2&amp;#160;b)&lt;/p&gt;
&lt;p&gt;          (* 3 c))&lt;/p&gt;
&lt;p&gt;       a&lt;/p&gt;
&lt;p&gt;       b&lt;/p&gt;
&lt;p&gt;       (- count 1))))&lt;/p&gt;
&lt;p&gt;(define (f n)&lt;/p&gt;
&lt;p&gt;  (if (&amp;lt; n 3)&lt;/p&gt;
&lt;p&gt;      n&lt;/p&gt;
&lt;p&gt;      (f-iter 2&amp;#160;1 0 (- n 2))))&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;짜고 나니까 이게 정확한 코드인 지 걱정이 되더군요. 되도는 프로세스가 나오는 쪽은 정의를 그대로 코드로 옮겨놓은거라 별로 걱정이 없습니다. 그래서 되도는 프로세스를 이용해 테스트를 하는 코드도 구현하였습니다.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;(define (test-f n)&lt;/p&gt;
&lt;p&gt;  (if (= n 0)&lt;/p&gt;
&lt;p&gt;      True&lt;/p&gt;
&lt;p&gt;      (and (= (f n) (recursive-f n)) (test-f (- n 1)))))&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;해당 테스트를 실행해본 결과, f(20)까지는 같은 값을 리턴하는 것을 확인하였습니다.&lt;/p&gt;</description><link>http://hpi.cc/post/20117549225</link><guid>http://hpi.cc/post/20117549225</guid><pubDate>Fri, 30 Mar 2012 00:12:00 +0900</pubDate><category>SICP</category><category>Programming</category><category>LISP</category><category>Scheme</category></item><item><title>SICP 연습문제 1.9</title><description>&lt;blockquote&gt;
&lt;p&gt;연습문제 1.9&lt;/p&gt;
&lt;p&gt;다음 두 프로시저는 모두 0보다 큰 정수 두 개를 더하는 일을 하는데, 인자에 1을 더하는 inc 프로시저와 인자에서 1을 빼는 dec 프로시저를 가져다 쓴다.&lt;/p&gt;
&lt;p&gt;(define (+ a b)&lt;/p&gt;
&lt;p&gt;  (if (= a 0)&lt;/p&gt;
&lt;p&gt;      b&lt;/p&gt;
&lt;p&gt;      (inc (+ (dec a) b))))&lt;/p&gt;
&lt;p&gt;(define (+ a b)&lt;/p&gt;
&lt;p&gt;  (if (= a 0)&lt;/p&gt;
&lt;p&gt;      b&lt;/p&gt;
&lt;p&gt;      (+ (dec a) (inc b))))&lt;/p&gt;
&lt;p&gt;맞바꿈 계산법에 따라 두 프로시저가 (+ 4&amp;#160;5)를 계산하는 프로세스를 밝혀라. 이 프로세스는 반복(iteration)하는가? 아니면 되도는(recursion)가?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;좋은 문제이지만 맞바꿈 계산법을 굳이 하고 싶지는 않군요. 그건 너무 고달프고 귀찮으니까요. 하지만, 반복하는 프로세스인지, 되도는 프로세스인지 판단하는 것은 맞바꿈 계산법을 하지 않더라도 알 수 있습니다. 반복 함수에서 이전 함수로 돌아갈 필요가 있는지, 없는지만 파악하면 되는 문제니까요.&lt;/p&gt;
&lt;p&gt;결론부터 말해서, 전자는 되도는 함수입니다. + 함수에서 다음 +함수를 호출한다면, 그 처리가 끝난 뒤 다시 원래 함수에서 inc 처리를 해줘야하니까요. 즉, 이전 함수로 돌아올 필요가 있습니다.&lt;/p&gt;
&lt;p&gt;하지만, 후자는 반복하는 함수입니다. + 함수에서 다음 +함수를 호출하고 나면, 그 함수의 리턴 값이 이전 +함수의 리턴 값이기도 하니까요. 이전 함수로 되돌아올 필요가 없습니다.&lt;/p&gt;

&lt;p&gt;* 연습문제 1.10 은 단순히 답을 나열하는 형식이 될 것 같아서 생략합니다.&lt;/p&gt;</description><link>http://hpi.cc/post/20116358089</link><guid>http://hpi.cc/post/20116358089</guid><pubDate>Thu, 29 Mar 2012 23:27:00 +0900</pubDate><category>SICP</category><category>Scheme</category><category>LISP</category><category>Programming</category><category>Study</category></item><item><title>SICP 연습문제 1.8</title><description>&lt;p&gt;정주행을 다시 시작한 뒤, 이미 풀었던 문제는 난이도가 그다지 높지 않아 정리하지 않고 넘어가도록 하겠습니다. 그래서 연습문제 1.8부터 시작합니다.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;연습문제 1.8 &lt;/p&gt;
&lt;p&gt;세제곱근을 구하는 뉴튼 법은, x의 세제곱근에 가까운 값을 y라고할 때 다음 식에 따라 y보다 더 가까운 값을 계산하는 것이다.&lt;/p&gt;
&lt;p&gt;((x/y^2)+2y)/3&lt;/p&gt;
&lt;p&gt;제곱근 프로시저처럼, 이 식을 써서 세제곱근 프로시저를 짜보자.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;포스팅하지는 않았지만, SICP에서 이 문제가 나오기 직전에 뉴튼 법으로 제곱근 찾는 연습이 있었기 때문에 쉽게 풀 수 있었습니다.&lt;/p&gt;
&lt;p&gt;일단 기본적인 반복 구조를 잡습니다.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;(define (cube-root-iter guess pre-guess x)&lt;/p&gt;
&lt;p&gt;  (if (good-enough? guess pre-guess)&lt;/p&gt;
&lt;p&gt;      guess&lt;/p&gt;
&lt;p&gt;      (cube-root-iter (improve-cube-root guess x)&lt;/p&gt;
&lt;p&gt;                      guess&lt;/p&gt;
&lt;p&gt;                      x)))&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;그냥 충분히 근사한 값이 나왔다면 값을 리턴하고, 아니라면 반복하는 구조입니다.&lt;/p&gt;
&lt;p&gt;그리고 구현이 안된 함수를 구현해 줍니다. 첫번째로 문제에서 제시된 공식을 함수로 만듭니다.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;(define (improve-cube-root guess x)&lt;/p&gt;
&lt;p&gt;  (/ (+ (/ x (square guess)) &lt;/p&gt;
&lt;p&gt;        (* 2.0 guess)) &lt;/p&gt;
&lt;p&gt;     3.0))&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;그 다음은 충분히 근사값인지 체크하는 good-enough? 함수를 작성합니다.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;(define (good-enough? guess pre-guess)&lt;/p&gt;
&lt;p&gt;  (or (&amp;lt; (abs (- (/ guess pre-guess) 1.0)) ignorable-rate-of-change)&lt;/p&gt;
&lt;p&gt;      (= guess pre-guess))) &lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;해당 함수는 여러가지 구현이 있을 수 있습니다.&lt;/p&gt;
&lt;p&gt;제 구현에 대해 간단하게 설명하자면, 이전 근사값에서 현재 근사값으로의 변화율을 계산하여 무시할만한 변화율이라면, 충분한 근사값이라고 판단하는 함수입니다. 따라서, x 값을 받지 않습니다.&lt;/p&gt;
&lt;p&gt;그리고 ignorable-rate-of-change 값과 cube-root-iter를 래핑해주는 cube-root 함수를 작성합니다.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;(define ignorable-rate-of-change 0.001)&lt;/p&gt;
&lt;p&gt;(define (cube-root x) &lt;/p&gt;
&lt;p&gt;  (cube-root-iter x 1.0 x))&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;결국 작성된 코드는 다음과 같습니다.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;(define ignorable-rate-of-change 0.001)&lt;/p&gt;
&lt;p&gt;(define (cube-root x) &lt;/p&gt;
&lt;p&gt;  (cube-root-iter x 1.0 x))&lt;/p&gt;
&lt;p&gt;(define (cube-root-iter guess pre-guess x)&lt;/p&gt;
&lt;p&gt;  (if (good-enough? guess pre-guess)&lt;/p&gt;
&lt;p&gt;      guess&lt;/p&gt;
&lt;p&gt;      (cube-root-iter (improve-cube-root guess x)&lt;/p&gt;
&lt;p&gt;                      guess&lt;/p&gt;
&lt;p&gt;                      x)))&lt;/p&gt;
&lt;p&gt;(define (good-enough? guess pre-guess)&lt;/p&gt;
&lt;p&gt;  (or (&amp;lt; (abs (- (/ guess pre-guess) 1.0)) ignorable-rate-of-change)&lt;/p&gt;
&lt;p&gt;      (= guess pre-guess))) &lt;/p&gt;
&lt;p&gt;(define (improve-cube-root guess x)&lt;/p&gt;
&lt;p&gt;  (/ (+ (/ x (square guess)) &lt;/p&gt;
&lt;p&gt;        (* 2.0 guess)) &lt;/p&gt;
&lt;p&gt;     3.0))&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div&gt;역시 LISP은 가독성이 좋지 않군요. &lt;/div&gt;
&lt;div&gt;이제 문제를 풀었으니 제대로 풀었는 지 확인해봐야겠습니다.&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;div&gt; (cube-root 8)&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;2.000000001071189&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt; (cube-root 27)&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;3.0000000017936714&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt; (cube-root 0.027)&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;0.30000000000341215&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt; (cube-root 125)&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;5.00000185586853&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt; (cube-root 0.125)&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;0.5000000000095152&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt; (cube-root 0.000125)&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;0.050000006799256806&lt;/div&gt;
&lt;/blockquote&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;테스트가 빈약하긴하지만, 대충 적당한 근사값을 얻을 수 있네요.&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;</description><link>http://hpi.cc/post/20115776026</link><guid>http://hpi.cc/post/20115776026</guid><pubDate>Thu, 29 Mar 2012 23:03:00 +0900</pubDate><category>LISP</category><category>Scheme</category><category>SICP</category></item><item><title>컴퓨터 프로그램의 구조와 해석(SICP)의 연습 문제를 풀어보며 포스팅을 해보려 합니다. 재작년 쯤에는 SICP를 틈틈이 공부했었지만, 어쩌다보니 흐지부지 되어 지금까지 버려놓고...</title><description>&lt;p&gt;&lt;strong&gt;컴퓨터 프로그램의 구조와 해석(SICP)&lt;/strong&gt;의 연습 문제를 풀어보며 포스팅을 해보려 합니다. 재작년 쯤에는 SICP를 틈틈이 공부했었지만, 어쩌다보니 흐지부지 되어 지금까지 버려놓고 있었습니다. -_-&lt;/p&gt;
&lt;p&gt;프로그래머로서 당연히 알아야할 기초 지식을 공부하고, 함수형 프로그래밍을 연습해 볼 수 있는 좋은 책인데 제 자신의 게으름과 나태함에 때문에 여기까지 왔군요.&lt;/p&gt;
&lt;p&gt;반성해야겠네요.&lt;/p&gt;
&lt;p&gt;아무래도 Scheme에는 익숙하지 않다보니 뻘스러운 행위를 많이 할지도 모르겠습니다. 만약 보시는 분이 계시다면, 그럴때는 &amp;#8216;에혀, 그냥 그렇게 살아라.&amp;#8217; 하지 마시고 가차없는 지적과 갈굼 부탁드리겠습니다. &lt;/p&gt;</description><link>http://hpi.cc/post/20110845207</link><guid>http://hpi.cc/post/20110845207</guid><pubDate>Thu, 29 Mar 2012 18:50:00 +0900</pubDate><category>SICP</category><category>Programming</category><category>LISP</category><category>Scheme</category><category>Study</category></item></channel></rss>

