Script / CSS

G1sUtil.js

G1sBlogger.js

G1sNavigationList.js

G1sCode

G1sTagList

2012년 2월 29일 수요일

[Project Euler] 17. 1부터 1000까지 영어로 썼을 때 사용된 글자의 개수는?

17. 1부터 1000까지 영어로 썼을 때 사용된 글자의 개수는?
1부터 5까지의 숫자를 영어로 쓰면 one, two, three, four, five 이고,
각 단어의 길이를 더하면 3 + 3 + 5 + 4 + 4 = 19 이므로 사용된 글자는 모두 19개입니다.

1부터 1,000까지 영어로 썼을 때는 모두 몇 개의 글자를 사용해야 할까요?

참고: 빈 칸이나 하이픈('-')은 셈에서 제외하며, 단어 사이의 and 는 셈에 넣습니다.
  예를 들어 342를 영어로 쓰면 three hundred and forty-two 가 되어서 23 글자,
  115 = one hundred and fifteen 의 경우에는 20 글자가 됩니다.
Click

이것도 일반화를 해볼려다가 여러가지 생각해야 할게 너무 많아 그냥 포기.
각각의 수가 얼마나 들어가는지를 암산하여 각 수의 영어 알파벳 숫자와 곱해주었습니다.
<script>
function p017(){
 var nums = {
  1: "one",
  2: "two",
  3: "three",
  4: "four",
  5: "five",
  6: "six",
  7: "seven",
  8: "eight",
  9: "nine",
  10: "ten",
  11: "eleven",
  12: "twelve",
  13: "thirteen",
  14: "fourteen",
  15: "fifteen",
  16: "sixteen",
  17: "seventeen",
  18: "eighteen",
  19: "nineteen",
  20: "twenty",
  30: "thirty",
  40: "forty",
  50: "fifty",
  60: "sixty",
  70: "seventy",
  80: "eighty",
  90: "ninety",
  100: "hundred",
  1000: "thousand"
 };
 
 var l = 0;//46684//17524
 var t = nums[100].length;
    
 //1의 자리 : 100당 9번씩 10번 + (100의자리) 100번 + (천의자리) 1만 1번.
 for (var i = 1; i < 10; i++) 
  l += nums[i].length * ((9 * 10) + 100 + ((i == 1) ? 1 : 0));
 //10~19 : 100당 1번씩 10번.
 for(var i=10; i<20; i++)
  l += nums[i].length * (1*10);
 //10의 자리 : 100당 10번씩 10번.
 for(var i=20; i<100; i+=10)
  l+= nums[i].length * (10*10);
 //100 : 100당 100씩 9번.
 l += nums[100].length * (100*9);
 //1000 : 1 번.
 l += nums[1000].length * 1;
 //and : 100당 99번씩 9번.
 l += "and".length * (99*9); 
 
 return l;
}
</script>

2012년 2월 24일 금요일

[Project Euler] 16. 2^(1000)의 각 자리수를 모두 더하면?

16. 2^(1000)의 각 자리수를 모두 더하면?
2^(15) = 32768 의 각 자리수를 더하면 3 + 2 + 7 + 6 + 8 = 26 입니다.

2^(1000)의 각 자리수를 모두 더하면 얼마입니까?
Click

2의 1000승이므로 역시나 너무 큰 값이 나오니 10의 자리씩 잘라서 계산.
다 구한 후 10으로 나눠가며 나머지값을 더해주었습니다.
<script>
function powLargeNum(n,k){
 var result = new Array();
 result[0] = 1;
 var cnt = 0;
 for(var i=0; i<k; i++){
  for(var j=cnt; j>=0; j--){
   result[j] = result[j] * n;
   if(result[j] / 10000000000 >= 1){
    if(result[j+1] == null){
     result[j+1] = parseInt(result[j]/ 10000000000);
     if(j == cnt) cnt++;
    }
    else
     result[j+1] += parseInt(result[j]/ 10000000000);
    result[j] = result[j] % 10000000000;
   }
  }
 }
 return result;
}

function sumDigitArray(n){
 var l = n.length;
 var sum = 0;
 for (var i = 0; i < l; i++) {
  temp = n[i];
  while (temp != 0) {
   sum += temp % 10;
   temp = parseInt(temp / 10);
  }
 }
 }
</script>

2012년 2월 23일 목요일

[Project Euler] 15. 20×20 격자의 좌상단에서 우하단으로 가는 경로의 수

15. 20×20 격자의 좌상단에서 우하단으로 가는 경로의 수
아래와 같은 2 × 2 격자의 왼쪽 위 모서리에서 출발하여 오른쪽 아래 모서리까지 도달하는 길은 모두 6가지가 있습니다 (거슬러 가지는 않기로 합니다).


그러면 20 × 20 격자에는 모두 몇 개의 경로가 있습니까?
Click 알고리즘을 배울때 비슷한 문제를 본 것 같긴 하지만.... 먼저 제가 푼 방식은 도착지부터 거꾸로 탐색하며 각각의 위치에서 갈 수 있는 수를 더해가는 식입니다. 도착지를 0,0으로 놓고, 0,j 와 i,0은 모두 1로 놓고, 1,1부터는 i-1,j와 i,j-1의 값을 더해가며 결과값을 얻었습니다.
그런데 풀고들어가서 댓글을 보니 순열공식으로 풀이가 가능하다는 군요...

식이 어떻게 유도가 되는지는 모르겠지만...

순열(順列, permutation)은 서로 다른 n 개의 원소 중에서 r 개()를 뽑아서 한 줄로 세우는 경우의 수이다.



nPr, 혹은 P(n,r) 라고 쓴다. 이 기호는 순열을 나타내는 permutation의 앞글자를 딴 것이다.

P(n,r)의 수는 다음과 같이 구할 수 있다.



이를 계승을 이용하면 다음과 같은 식으로 나타낼 수 있다.

위키백과 : 순열

그리고 이를 응용하면.... 간단한 코드가 나오는 군요.
<script>
function permutation(n, m){
 var mn = m+n;
 var result = 1;
 for(var i=0;i<n; i++){
  result *= (mn-i)/(m-i);
 }
 return result;
}
</script>

[Project Euler] 14. 백만 이하로 시작하는 우박수 중 가장 긴 과정을 거치는 것은?

14. 백만 이하로 시작하는 우박수 중 가장 긴 과정을 거치는 것은?
양의 정수 n에 대하여, 다음과 같은 계산 과정을 반복하기로 합니다.

n → n / 2 (n이 짝수일 때)
n → 3 n + 1 (n이 홀수일 때)

13에 대하여 위의 규칙을 적용해보면 아래처럼 10번의 과정을 통해 1이 됩니다.

13 → 40 → 20 → 10 → 5 → 16 → 8 → 4 → 2 → 1
아직 증명은 되지 않았지만, 이런 과정을 거치면 어떤 수로 시작해도 마지막에는 1로 끝나리라 생각됩니다.
(역주: 이것은 콜라츠 추측 Collatz Conjecture이라고 하며, 이런 수들을 우박수 hailstone sequence라 부르기도 합니다)

그러면, 백만(1,000,000) 이하의 수로 시작했을 때 1까지 도달하는데 가장 긴 과정을 거치는 숫자는 얼마입니까?

참고: 계산 과정 도중에는 숫자가 백만을 넘어가도 괜찮습니다.
Click

다른 방법이 있을까 열심히 고민하다가 결국은 찾지 못하고 단순방식으로 결정하였습니다.
그나마 약간 이라도 시간효율을 줄이기 위해 이전 결과를 배열에 저장하여 콜라츠추측에 의해 수가 원래 수보다 작아지면 이전에 카운트한 수를 더해주는 방법을 택했습니다.
<script>
function p014_in(limit){
 var arr = new Array();
 arr[1] = 0;
 var max = 0;
 var seed = 0;
 for(var i=2; i<limit; i++){
  var cnt = 0;
  var temp = i;
  while(temp != 1){
   if(temp<i) break;
   else if(temp%2==0) temp /= 2;
   else temp = temp*3+1;
   cnt++;
  }
  arr[i] = cnt + arr[temp];
  if (max < arr[i]) {
   max = arr[i];
   seed = i;
  }
 } 
 result seed;
}
</script>

2012년 2월 22일 수요일

[Project Euler] 13. 50자리 숫자 100개를 더한 값의 첫 10자리 구하기

13. 50자리 숫자 100개를 더한 값의 첫 10자리 구하기
아래에 50자리 숫자가 100개 있습니다. 이것을 모두 더한 값의 첫 10자리는 얼마입니까?
Click

앞에 10자리수만 얻는 것이므로 앞에 몇자리만 잘라서 계산하거나 하는 방법으로도 가능할 것 같으나 모든 수를 더해서 결과를 얻도록 결정...

숫자가 너무 크므로 일단 string로 받아서 구분자로 각각의 수를 자른 뒤 각각의 수를 10의 자리씩 잘라서 배열에 저장하여 계산하였습니다.

2012년 2월 21일 화요일

[Project Euler] 12. 500개 이상의 약수를 갖는 가장 작은 삼각수는?

12. 500개 이상의 약수를 갖는 가장 작은 삼각수는?
1부터 n까지의 자연수를 차례로 더하여 구해진 값을 삼각수라고 합니다.
예를 들어 7번째 삼각수는 1 + 2 + 3 + 4 + 5 + 6 + 7 = 28이 됩니다.
이런 식으로 삼각수를 구해 나가면 다음과 같습니다.

1, 3, 6, 10, 15, 21, 28, 36, 45, 55, ...
이 삼각수들의 약수를 구해봅시다.

 1: 1
 3: 1, 3
 6: 1, 2, 3, 6
10: 1, 2, 5, 10
15: 1, 3, 5, 15
21: 1, 3, 7, 21
28: 1, 2, 4, 7, 14, 28
위에서 보듯이, 5개 이상의 약수를 갖는 첫번째 삼각수는 28입니다.

그러면 500개 이상의 약수를 갖는 가장 작은 삼각수는 얼마입니까?
Click

처음에는 일일이 하나씩 더해가며 구했으나.... 이게 비 효율적이라는 생각에 고민에 고민을 거듭해 코드는 복잡하지만 좀 더 효율적인 방법을 찾음.

우선 첫번째 방법은...
<script language="Javascript" type="text/javascript">
/** 약수의 갯수를 찾는다. **/
function countSubMultiples(n){
 //count 변수 초기화.
 var cnt = 0;
 
 /* i는 1부터 n을 나눠주며 나누어 떨어지는 수들을 찾아 cnt 변수를 증가.
  * 나누는 값과 결과값이 같을경우 1을.. 그렇지 않을 경우 2를 더해줌.
  */
 var i = 1;
 var str = ""
 while(1){
  if (i > n / i)
   return cnt;
  if (n % i == 0) {
   cnt += (i == n / i) ? 1 : 2;
   str += i + ", " +(n/i) + ", ";
  }
  i++;
 }
}

/** n값을 입력받아 약수의 수가 n보다 큰 삼각함수를 출력. **/
function p012(n){
 var i = 1;
 var tric=1;
 while(1){
  if(countSubMultiples(tric)>=n)
   break;  
  i++;
  tric += i;
 } 
 alert(tric); 
}
</script>
이렇게 하고나니 너무 비 효율적인것 같아 새로 방법을 찾던 중...
삼각 수는 결국 등차수열의 합들이므로....

F(n) = n(n+1)/2

라는 공식에서부터 고민을 시작하여 다른 방법을 찾아 내었습니다.

  1. F(n) = n(n+1)/2
  2. 즉. F(n)의 약수는... 1,F(n), (n 또는 n/2), ((n+1) 또는 (n+1)/2),
    그리고 (n 또는 n/2), ((n+1) 또는 (n+1)/2)의 약수들과 그 약수들의 곱.
    이 중... 1은 모든 수의 약수이므로 중복.. F(n)은 (n 또는 n/2) * ((n+1) 또는 (n+1)/2) 이므로 제외....
    그러므로 F(n)의 약수는 (n 또는 n/2), ((n+1) 또는 (n+1)/2)의 약수들의 곱
    # 이 후 (n 또는 n/2) = X, ((n+1) 또는 (n+1)/2) = Y로 표기.
  3. 서로 겹치지 않는 두 숫자군 M,L에서 양쪽에서 서로 하나씩의 수를 뽑아내 만들 수 있는 수의 수는 count(M) * count(L).
  4. 연속한 두 수의 서로 약수들은 겹치는 수가 없겠지?? 1을 제외한 그 어떤수가 자연수와의 곱에서 1차이나는 두 수를 만들 수 는 없으니....
  5. 4에 이어서... 연속한 두 수중 짝수를 2로 나눈 수의 약수들은 2로 나누기 전 약수로 이루어졌으므로 나누지 않은 다른 수와 1외에 약수가 겹치는 일은 없을 것....
  6. 1~5까지의 결론으로 F(n)의 약수들의 수 = [X의 약수의 수 - 1] * [Y의 약수의 수 - 1] + [X의 약수 수 - 1] + [Y의 약수 수 - 1] + 1
  7. x * y + x + y + 1 = xy + x + y + 1 = x(y+1) + y+1 = (x+1) * (y+1)
  8. 6,7번에 의해.. F(n)의 약수들의 수 = [X의 약수의 수] * [Y의 약수의 수]
  • 마찬가지로 어떤 수 T의 약수의 수는.. 곱해서 T가 나오는 두 수를 구해 위 8번 공식 대입.

상당히 복잡한 유추과정...  그리고 그만큼이나 복잡한 코드입니다.
<script language="Javascript" type="text/javascript">
function p012(n)
{
    //배열 선언.
    var arr = new Array();
 
    //약수의 수 계산.
    //F(n) 약수들의 수 = [X약수 수-1] * [Y약수 수-1] + [X약수 수-1] + [Y약수 수-1] + 1
    arr[1] = 1;
    var i=1;
    while(1){
 /* arr[i+1]를 채움.
  * 구하는 방식은 곱해서 i가 되는 두 수를 찾은 후 두 수의 약수값(arr)으로 구함. */
 var t= i+1;
 arr[t] = 2;  //arr[t] 초기화. i를 나눌 수 있는 수가 없으면 2로 설정되게함.
 for(var j=2; j<=t; j++){
  if(t%j == 0){
   if ((t / j) % j == 0) {
    /* t를 나누는 두 수 (t / j), j 가 약수관계일 경우
     * t 의 약수는.. (t/j) 값에다 (t/j)의 약수 중 j의 배수가
     * 아닌 수들의 수를 더하여 구함.
     */
    var temp = t/j;
    while(temp%j==0)
     temp /= j;
    arr[t] = arr[t / j] + arr[temp];
    break;
   }
   else {
    arr[t] = arr[j] * arr[parseInt(t / j)];
    break;
   }
  }
 }
 /* x,y를 구함. 
  * i 가 짝수일때와 i 가 홀 수 일때로 구분. */
 var x,y;
 if(i%2 == 0){
  x = arr[i/2];
  y = arr[i+1];
 }
 else{
  x = arr[i];
  y = arr[(i+1)/2];
 }
 //x*y가 v값보다 크면 원하는 값을 얻었으므로 i*(i+1)/2 리턴.
 if(x*y >= n)
  return (i*(i+1)/2);
 i++;
    }
}
</script>

2012년 2월 20일 월요일

[Project Euler] 11. 20×20 격자에서 연속된 네 숫자의 곱 중 최대값

11. 20×20 격자에서 연속된 네 숫자의 곱 중 최대값
아래와 같은 20×20 격자가 있습니다.

08 02 22 97 38 15 00 40 00 75 04 05 07 78 52 12 50 77 91 08
49 49 99 40 17 81 18 57 60 87 17 40 98 43 69 48 04 56 62 00
81 49 31 73 55 79 14 29 93 71 40 67 53 88 30 03 49 13 36 65
52 70 95 23 04 60 11 42 69 24 68 56 01 32 56 71 37 02 36 91
22 31 16 71 51 67 63 89 41 92 36 54 22 40 40 28 66 33 13 80
24 47 32 60 99 03 45 02 44 75 33 53 78 36 84 20 35 17 12 50
32 98 81 28 64 23 67 10 26 38 40 67 59 54 70 66 18 38 64 70
67 26 20 68 02 62 12 20 95 63 94 39 63 08 40 91 66 49 94 21
24 55 58 05 66 73 99 26 97 17 78 78 96 83 14 88 34 89 63 72
21 36 23 09 75 00 76 44 20 45 35 14 00 61 33 97 34 31 33 95
78 17 53 28 22 75 31 67 15 94 03 80 04 62 16 14 09 53 56 92
16 39 05 42 96 35 31 47 55 58 88 24 00 17 54 24 36 29 85 57
86 56 00 48 35 71 89 07 05 44 44 37 44 60 21 58 51 54 17 58
19 80 81 68 05 94 47 69 28 73 92 13 86 52 17 77 04 89 55 40
04 52 08 83 97 35 99 16 07 97 57 32 16 26 26 79 33 27 98 66
88 36 68 87 57 62 20 72 03 46 33 67 46 55 12 32 63 93 53 69
04 42 16 73 38 25 39 11 24 94 72 18 08 46 29 32 40 62 76 36
20 69 36 41 72 30 23 88 34 62 99 69 82 67 59 85 74 04 36 16
20 73 35 29 78 31 90 01 74 31 49 71 48 86 81 16 23 57 05 54
01 70 54 71 83 51 54 69 16 92 33 48 61 43 52 01 89 19 67 48

위에서 대각선 방향으로 연속된 붉은 숫자 네 개의 곱은 26 × 63 × 78 × 14 = 1788696 입니다.

그러면 수평, 수직, 또는 대각선 방향으로 연속된 숫자 네 개의 곱 중 최대값은 얼마입니까?

Click

string로 받은 문자를 정해진 크기에 따라 잘라서 배열에 넣고 배열을 돌며 문제 해결.
처음에 대각선을 할때 왜 우측으로 올라가는 대각선을 생각을 안했는지....
<script>
function multyplyAdjoinNumber(nums, x, y, k, dirX, dirY){
 var multyply = 1;
 for(var i=0; i<k; i++) {
  var temp = nums[x+i*dirX][y+i*dirY];
  multyply *= temp;  
 }
 return multyply;
}

function maxMultiplyAdjoinNumber(n, m, k, nums){
 //배열 선언. 배열의 크기는 n X m.
 var array = new Array();
 for(var i=0;i<m;i++)
 array[i] = new Array();
  
 //값을 배열에 넣으며 i,j가 k 보다 클때 이전에 입력 된 배열의 값들과 곱한 값을 구함.
 var max = 0;
 for(var i=0; i<n; i++) {
  for(var j=0; j<m; j++) {
  var temp = parseInt(nums.substr((i*n+j)*3,1))*10+ parseInt(nums.substr((i*n+j)*3+1,1));
  array[i][j] = temp;
  if (i >= k - 1 && j >= k - 1) {
   max = maxNumber(max, multyplyAdjoinNumber(array, i, j, k, -1, -1));
   max = maxNumber(max, multyplyAdjoinNumber(array, i-3, j, k, 1, -1));
  }
  if(i>=k-1)
   max = maxNumber(max,multyplyAdjoinNumber(array,i,j,k,-1,0));
  if(j>=k-1)
   max = maxNumber(max,multyplyAdjoinNumber(array,i,j,k,0,-1));
  }
 }
 return max;
}
</script>

2012년 2월 18일 토요일

[Project Euler] 10. 이백만 이하 소수의 합

10. 이백만 이하 소수의 합
10 이하의 소수를 모두 더하면 2 + 3 + 5 + 7 = 17 이 됩니다.
이백만(2,000,000) 이하 소수의 합은 얼마입니까?
Click

원래는 처음과 마찬가지로 소수를 배열에 저장해가며 해당 수로 나눠줘 소수를 판단 하였으나 이게 각 수마다 나눠줘야하므로 많은 시간이 걸리는데, 문제를 풀고나서 댓글에 나온 '에라토스테네스의 체'라는 알고리즘을 발견 하였네요.

우선은 처음 했던 코드입니다.
 
그리고 에라토스테네스의 체 알고리즘은....
위키백과 : 에라토스테네스의 체
  1. 2부터 소수를 구하고자 하는 구간의 모든 수를 나열한다. 그림에서 회색 사각형으로 두른 수들이 여기에 해당한다.
  2. 2는 소수이므로 오른쪽에 2를 쓴다. (빨간색)
  3. 자기 자신을 제외한 2의 배수를 모두 지운다.
  4. 남아있는 수 가운데 3은 소수이므로 오른쪽에 3을 쓴다. (초록색)
  5. 자기 자신을 제외한 3의 배수를 모두 지운다.
  6. 남아있는 수 가운데 5는 소수이므로 오른쪽에 5를 쓴다. (파란색)
  7. 자기 자신을 제외한 5의 배수를 모두 지운다.
  8. 위의 과정을 반복하면 구하는 구간의 모든 소수가 남는다.
생각하면 쉬운 방식이었는데....
아무튼 이를 보고 약간 변형해서 구현.
<script>
function sumEratos(max)
{
 // 만일 n이 1보다 작거나 같으면 함수 종료
 if(max<=1) return 0;

 /* 2부터 n까지 n-1개를 저장할 수 있는 배열 할당
  * 배열 참조 번호와 소수와 일치하도록 배열의 크기는
  * n+1 길이만큼 할당(인덱스 번호 0과 1은 사용하지 않음)       */
 var PrimeArray = new Array();

 /* 배열초기화
  * 처음엔 모두 소수로 보고 true값을 줌  */
 for(var i=1; i<max/2; i++) PrimeArray[i]=true;

 /* 더한 값을 저장할 변수. */
 var sum = 2;

 /* 에라토스테네스의 체에 맞게 소수를 구함
  * 만일, PrimeArray[i]가 true이면 i 이후의 i 배수는
  * 약수로 i를 가지고 있는 것이 되므로 i 이후의 i 배수에 대해
  * false값을 준다.
  * PrimeArray[i]가 false이면 i는 이미 소수가 아니므로 i의 배수 역시
  * 소수가 아니게 된다. 그러므로 검사할 필요도 없다.  
  *
  * 짝수는 2 밖에 없으므로 2를 제외한 홀 수만 계산한다.
  * 2*i+1 값이 실제의 값이 됨..
  * */
 for(var i=1; i<max/2; i++){
  if(PrimeArray[i]){
   var p = 2*i+1;
   sum += p;
   for(var j=3; j*p<max; j+=2)PrimeArray[(j*p-1)/2]=false;
  }
 } 
 return sum;
}
</script>

[Project Euler] 9. a + b + c = 1000 이 되는 피타고라스 수

9. a + b + c = 1000 이 되는 피타고라스 수
세 자연수 a, b, c 가 피타고라스 정리 a² + b² = c² 를 만족하면 피타고라스 수라고 부릅니다 (여기서 a < b < c ).
예를 들면 32 + 42 = 9 + 16 = 25 = 52이므로 3, 4, 5는 피타고라스 수입니다.
a + b + c = 1000 인 피타고라스 수 a, b, c는 한 가지 뿐입니다. 이 때, a × b × c 는 얼마입니까?
Click

상당히 많은 고민을 하였습니다.
그냥 생각하면 미지수가 a,b,c 3개이기 때문에 이중 loop로 푸는게 단순하고...
실제 그렇게 푼 분들도 많은 것 같지만....
변수를 하나 줄여 1개의 loop로 해결.
a + b + c = n 에서.
b + c = n - a
b = (n - a) - c
n-a -> t로 놓으면... -> b = t - c

피타고라스 정리에 넣으면..

a ²  + b ²  = c ²  는
a ²  + (t-c) ²  = c²
a ²  + t ²  - 2*t + c ²  = c²
a ²  + t ²  = 2*t*c
( a ²  + t ² ) / (2*t) = c 

여기서 t = n-a 이므로...
주어진 n에서 a만 알면, c와 b를 구할 수 있다.
라는 과정을 거쳤습니다.
그리고 이걸 코드로 옮기면...
<script>
function p009(n){
    var a, b, c; 
    for(var i=1; i<n; i++) {
        a = i;
        var t = n-i;
        c = parseInt((a*a + t*t) / (2*t));
        b = n - a - c;  
        if(a*a + b*b == c*c)
            break;  
    }
    return a*b*c;
}
</script>
간단하게 정리.

2012년 2월 16일 목요일

[Project Euler] 8. 1000자리 숫자 안에서 이어지는 5자리 숫자의 곱 중 최대값은?

8. 1000자리 숫자 안에서 이어지는 5자리 숫자의 곱 중 최대값은?
다음은 연속된 1000자리 숫자입니다 (읽기 좋게 50자리씩 잘라놓음).

73167176531330624919225119674426574742355349194934
96983520312774506326239578318016984801869478851843
85861560789112949495459501737958331952853208805511
12540698747158523863050715693290963295227443043557
66896648950445244523161731856403098711121722383113
62229893423380308135336276614282806444486645238749
30358907296290491560440772390713810515859307960866
70172427121883998797908792274921901699720888093776
65727333001053367881220235421809751254540594752243
52584907711670556013604839586446706324415722155397
53697817977846174064955149290862569321978468622482
83972241375657056057490261407972968652414535100474
82166370484403199890008895243450658541227588666881
16427171479924442928230863465674813919123162824586
17866458359124566529476545682848912883142607690042
24219022671055626321111109370544217506941658960408
07198403850962455444362981230987879927244284909188
84580156166097919133875499200524063689912560717606
05886116467109405077541002256983155200055935729725
71636269561882670428252483600823257530420752963450

여기서 붉게 표시된 71112의 경우 7, 1, 1, 1, 2 각 숫자를 모두 곱하면 14가 됩니다.

이런 식으로 맨 처음 (7 × 3 × 1 × 6 × 7 = 882) 부터 맨 끝 (6 × 3 × 4 × 5 × 0 = 0) 까지 5자리 숫자들의 곱을 구할 수 있습니다.
이렇게 구할 수 있는 5자리 숫자의 곱 중에서 가장 큰 값은 얼마입니까?
Click

수학이라기보다는 큰수를 어떻게 다룰 것인지를 보는 문제이군요.
간단하게 string객체로 받아서 각 지점을 수로 변환하여 구현했습니다.
<script>
function p008(n){
    var max = 0; 
    for(var i=0; i<str.length-4; i++){
        var temp = 1;
        for(var j=0; j<5; j++)
            temp *= parseInt(str.charAt(i+j));
        if(temp > max)
            max = temp;
    }  
    alert(max);
}
</script>

2012년 2월 15일 수요일

[Project Euler] 7. 10001번째의 소수?

7. 10001번째의 소수?
소수를 크기 순으로 나열하면 2, 3, 5, 7, 11, 13, ... 과 같이 됩니다.
이 때 10,001번째의 소수를 구하세요.
Click

배열에 지금까지의 소수를 넣고 해당 소수들로 나누어떨어지는지로 판단.
<script>
function p007_in(n){
 if(n<=2){
  alert(n);
  return;
 }

 var cnt = 1;

 var prime = new Array();
 prime[0] = 2;
 var t = 3;
 while(cnt<n){
  var check = true;
  for(var i=0; i<cnt; i++){
   if(prime[i]>t/prime[i-1])
    break;
   else if(t%prime[i] == 0){
    check = false;
    break;
   }
  }
  if(check)
   prime[cnt++] = t;
  t += 2;
 }
  
 alert(prime[n-1]);
}
</script>

[Project Euler] 6. 1부터 100까지 "제곱의 합"과 "합의 제곱"의 차는?

6. 1부터 100까지 "제곱의 합"과 "합의 제곱"의 차는?
1부터 10까지 자연수를 각각 제곱해 더하면 다음과 같습니다 (제곱의 합). 
1² + 2² + ... + 10² = 385 
1부터 10을 먼저 더한 다음에 그 결과를 제곱하면 다음과 같습니다 (합의 제곱).
(1 + 2 + ... + 10)² = 552 = 3025 
따라서 1부터 10까지 자연수에 대해 "제곱의 합"과 "합의 제곱"의 차는 3025 - 385 = 2640 이 됩니다.
그러면 1부터 100까지 자연수에 대해 "제곱의 합"과 "합의 제곱"의 차는 얼마입니까?
Click

등차수열의 합의 제곱과 등비수열 중 제곱의 합을 구하는 공식입니다.
등비수열공식도 있지만 제곱을 위한 간단한 공식이 있으니 이를 이용합니다.

등차수열의 합.
(등비수열)제곱의 합
출처 : 수학이 알고싶은 중고대딩들을 위한 수학 노트

위에 두 공식을 이용해 구현.
<script>
function sigma_ak(n1, n2, a){
 return parseInt((n2-n1 + 1) * ((n2+n1) / 2.0) * a);
}
function sigma_k2(n){
 return parseInt(n * (n+1) * (2*n+1) /6 +0.5);
}
function p006(n){
 var r1 = sigma_ak(1,n,1);
 var r2 = sigma_k2(n); 
 alert(r1 * r1 - r2);
}
</script>

2012년 2월 14일 화요일

[Project Euler] 5. 1 ~ 20 사이의 어떤 수로도 나누어 떨어지는 가장 작은 수

5. 1 ~ 20 사이의 어떤 수로도 나누어 떨어지는 가장 작은 수
1 ~ 10 사이의 어떤 수로도 나누어 떨어지는 가장 작은 수는 2520입니다.
그러면 1 ~ 20 사이의 어떤 수로도 나누어 떨어지는 가장 작은 수는 얼마입니까?
Click
1~20까지 최소공배수를 구하는 문제이죠.
유클리드 알고리즘을 이용해 두 수의 최소 공배수를 구하고 그 수와 다른 수의 최소 공배수를 구하는 방식으로 구했습니다.
유클리드 알고리즘은...
1. 입력으로 두 수 m,n(m>n)이 들어온다. 2. n가 0이라면, m를 출력하고 알고리즘을 종료한다. 3. n가 m를 나누어 떨어지면, n을 출력하고 알고리즘을 종료한다. 4. 그렇지 않으면, m를 n로 나눈 나머지를 새롭게 m에 대입하고, m과 n을 바꾸고 3으로 돌아온다.
위와 같구요. 이를 이용해서...
<script>
/** 유클리드 알고리즘을 통해 최대 공약수와 최소 공배수를 구함. **/
function euclid(a,b){
 if (b == 0) return a;
 return euclid(b, a % b);
}
/* 최대 공약수 */
function gcd(a,b){
 return euclid(Math.max(a,b),Math.min(a,b));
}
/* 최소 공배수 */
function lcm(a,b){
 return (a*b) / gcd(a, b);
}
/* 1~n까지의 최소 공배수 */
function getNumsLcm(n){
 var temp = 2;
 for(var i=3; i<=n; i++)
  temp = lcm(temp,i);
 return temp;
}
</script>
위와 같이 구현합니다.

[Project Euler] 4. 세자리 수를 곱해 만들 수 있는 가장 큰 대칭수

4. 세자리 수를 곱해 만들 수 있는 가장 큰 대칭수

앞에서부터 읽을 때나 뒤에서부터 읽을 때나 모양이 같은 수를 대칭수(palindrome)라고 부릅니다.
두 자리 수를 곱해 만들 수 있는 대칭수 중 가장 큰 수는 9009 (= 91 × 99) 입니다.
세 자리 수를 곱해 만들 수 있는 가장 큰 대칭수는 얼마입니까?
Click
이번에도 단순 반복 알고리즘.
조금 신경을 썼다면 limit값부터 내려오면서 계산.
max값보다 작아지면 break를 하도록 하여 loop를 덜 돌도록 하였으나 이것도 얼마나 성과가 있을지.....
<script>
/** 대칭수 판단. **/
function isPalindrome(n){
 var temp = 0;
 var i;
 for(i=n; i>temp; i=parseInt(i/10)){
  temp = temp*10 + i%10; }
 if(temp == i) return true;
 else false;
}
/** limit값부터 내려오며 max 대칭수 구함. **/
function p004(n){
 var t=n; var max = 0; 
 while(1){
  if(t*t < max) break;  
  for(var i=t; i>0; i--){
   var temp = t*i;
   if(temp < max) break;
   if(isPalindrome(temp)){ max = temp; break; }
  }
  t--;  
 }
 return max;
}
</script>

2012년 2월 13일 월요일

[Project Euler] 3. 가장 큰 소인수 구하기

3. 가장 큰 소인수 구하기

어떤 수를 소수의 곱으로만 나타내는 것을 소인수분해라 하고, 이 소수들을 그 수의 소인수라고 합니다.
예를 들면 13195의 소인수는 5, 7, 13, 29 입니다.
600851475143의 소인수 중에서 가장 큰 수를 구하세요.

Click

이것도 간단하게....
i를 2부터 나눠떨어지면 계속 나눠주고, 아니면 i증가해주며 간단한 코드로 작성.
<script>
function getMaxPrimeFactor(n){
 var temp = n; 
 for(var i=2; i<temp; i++){
  while (temp % i == 0) temp /= i;  
  if(temp==1) { temp=i; break; }
 }
 return temp;
}
</script>
좀더 복잡하게 해주면 2는 따로 예외처리하여 2로 먼저 다 나눠준다음에
i를 3부터 2씩 증가시키며 하면 loop를 반으로 줄일수도.... 있겠지만 그럴 필요성은 크게 느끼지 않군요.

2012년 2월 12일 일요일

[Project Euler] 2. 피보나치 수열에서 4백만 이하이면서 짝수인 항의 합

2. 피보나치 수열에서 4백만 이하이면서 짝수인 항의 합

피보나치 수열의 각 항은 바로 앞의 항 두 개를 더한 것이 됩니다. 1과 2로 시작하는 경우 이 수열은 아래와 같습니다.
1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...
짝수이면서 4백만 이하인 모든 항을 더하면 얼마가 됩니까?
Click

간단하게 갑니다. 그냥 단순 반복 알고리즘.
아무리 생각해도 4백만 이하 짝수의 피보나치수를 구하는 공식은 안보이는 군요.
라고 하지만 딱 생각해도 공식이 없을 것 같은 문제입니다.
<script>
function p002(max){ 
 var n = new Array(); 
 n[0] = 1;
 n[1] = 2;
 
 var i = 2;
 var sum = 0;
 
 while(1){
  var temp = (i+1)%2;
  if(n[temp]>max)  break;
   
  if(n[temp]%2 == 0) sum += n[temp];
  
  n[i%2] += n[temp];
  
  i++;
 }
 
 return sum;
}
</script>
역시나 일반화를 위해 max값을 받으면 짝수 값을 return 하게...

2012년 2월 11일 토요일

[Project Euler] 1. 1000보다 작은 자연수 중에서 3 또는 5의 배수를 모두 더하면?

1. 1000보다 작은 자연수 중에서 3 또는 5의 배수를 모두 더하면?

10보다 작은 자연수 중에서 3 또는 5의 배수는 3, 5, 6, 9 이고, 이것을 모두 더하면 23입니다.
1000보다 작은 자연수 중에서 3 또는 5의 배수를 모두 더하면 얼마일까요?
Click

첫문제는 역시 간단하게....

놀라운건 이 문제를 풀고 들어갔더니 대부분의 분들이 1~1000까지 for문을 돌며 3의 배수 또는 5의 배수이면 sum값에 더해주면서 푸는 방식을 택했다는 것.

그런 방식은 가장 단순하고 확실하겠지만.... 효율면에서 좋은거라고 보기 힘들죠.
그것 보다는 이같은 경우 등차수열의 합을 구하는 공식을 적용하면 쉽게 결과가 나오는 문제.

위키백과 : 등차수열

결론적으로 등차수열의 합의 원리는 {an}의 중앙값 x {an}의 항의 개수로 정리 할 수 있다.(단, {an}은 유한수열)

그리고 여기서 고려할게 3과 5 두 수의 최소공배수인 15의 합또한 빼줘야 한다는 것.

위에 등차수열의 합 공식을 ∑을 이용해 나타내고, 최대치 max/a(a=3,5,15) 의 값을 각각 n₁,n₂,n₃로 놓으면, 결국 공식은...

result = 3∑n₁+ 5∑n₂- 15∑n₃

이렇게 풀기는 너무 간단하니까 이 함수를 일반화를 하여, a,b값과 max값을 입력받으면 그에 해당하는 배수의 합을 구하는 함수를 만들면
<script>
/** 유클리드 알고리즘을 통해 최대 공약수와 최소 공배수를 구함. **/
function euclid(a,b){
 if (b == 0) return a;
 return euclid(b, a % b);
}

/* 최대 공약수 */
function gcd(a,b){
 return euclid(Math.max(a,b),Math.min(a,b));
}

/* 최소 공배수 */
function lcm(a,b){
 return (a*b) / gcd(a, b);
}

/** 등차 수열의 합. **/
function sigma_ak(n1, n2, a){
 return parseInt((n2-n1 + 1) * ((n2+n1) / 2.0) * a);
}

/** max 보다 작은 n의 배수들의 합. **/
function sumMultiples(n, max){
 var cnt = parseInt(max / n);
 return sigma_ak(0, cnt, n);
}

/** max 보다 작은 n1,n2의 배수들의 합. **/
function sum2Multiples(n1, n2, max){
 var sum1 = sumMultiples(n1, max);
 var sum2 = sumMultiples(n2, max);
 var sumLcn = sumMultiples(lcm(n1,n2), max);
 
 return sum1 + sum2 - sumLcn;
}
</script>
코드가 좀 긴가요?
함수로 쪼개넣고 깔끔하게 보이기 위해 그런 듯 보이지만 합쳐놓고 보면 그렇게 길지도 않죠.

효율은 0부터 max까지 a,b의 배수를 더하는 것과는 비교도 되지 않는

최대 공약수를 구하는 법은 유클리드 안고리즘을 이용했습니다.

하루 하나씩 Project Euler

Project Euler

수학적인 문제들을 컴퓨터 프로그래밍으로 하나씩 해결해가는 퀴즈 풀이 사이트.


구글+ 의 소식을 통해 우연히 알게 된 사이트로 두뇌회전좀 시켜볼까 라는 생각에 건드리기 시작한 문제들.

하루에 한문제씩.
될 수 있으면 생각나는 최적의 방법으로 해결하기위해 많은 고민을 하며 풀어나가 볼까 합니다.

사용 언어는 간단하게 javascript.
간단한 함수들만 이용할테니 어떤 언어든 상관없겠지만 이왕 하는김에 결과를 블로그에 올려볼까 합니다.
그래서 javascript를 사용. 블로그에서 작동하는 것을 확인 할 수 있도록 할 생각입니다.

그럼 제 수학지식과 알고리즘에 +가 되기를 바라며....

[Blogger] Layout 를 만져보자.

전에 한 포스트에서 Blogger의 Layout를 수정하는 것을 썼었던 적이 있었는데요. 
Blogger의 관리 화면이 새로운 디자인으로 바낀 겸 따로 궁금해 하시는 분이 있으실까봐 따로 정리해 보았습니다.

레이아웃을 수정하는데는 2가지 방법이 있는데요.
첫번째가 Blogger에서 제공하는 템플렛레이아웃 툴에서 수정하는 것이고...
두번째로 직접 HTML 편집을 통해 수정하는 것입니다. 

첫번째 방법은 모두 알고 계실테니 간단히 넘어가면서 여기서는 HTML 편집을 통해 간단하게 Blogger 레이아웃 툴에서 제공하지 않는 위치에 가젯을 위치시키는 것을 보겠습니다.

간단한 예로 제 Post 위에 위치한 Posts List 가젯를 보시면 되겠네요.
저 위치는 원래 Layout에서는 제공하지 않는 위치죠...


1. Blogger에서 제공하는 기본 툴을 이용한 편집.

1.1 템플렛.



템플렛 화면을 보시면 그림처럼 맞춤 설정이 있구요.. 보시면..


템플릿에 동적뷰와 옆으로 Blogger에서 제공하는 기본 디자인들이 보입니다.
동적뷰는 동적으로 움직이는 깔끔한 디자인들로 이것은 레이아웃이나 너비등은 조정할 수가 없이 배경 색이나 글의 색만 수정 할 수 있게 되어있구요.
저희가 볼 것은 그 옆에 기본 디자인들 입니다.
원하는 것을 선택하시구요..


다음 배경은 기본으로 제공하는 것 외에 자유롭게 꾸미고 싶으실 경우 배경 이미지와 기본 색상 테마를 선택 하실 수가 있습니다.

너비 조정은 그야말로 너비를 조정하는 곳이고...


레이아웃을 보시면 기본적으로 제공하는 레이아웃을 보실 수 있습니다.

제가 선택한 레이아웃을 보시면... 상단 page를 위한 레이아웃과 Post가 들어가는 좌측 레이아웃, 그리고 그외 가젯이 들어가는 우측 레이아웃만 존재하고 Post 위에 Posts List 가젯이 들어갈 공간은 없다는 것을 아실 수 있습니다.

원하시는 본문, 바닥글 레이아웃을 선택하시면 되겠습니다.


마지막 고급은 세부적으로 글꼴이나 색, 바탕색 등을 설정할 수 있고... CSS를 추가하여 직접 설정을 할 수도 있습니다.

이상으로 원하는 템플릿을 선택하셨다면... 적용을 한 뒤 레이아웃으로 이동해 원하시는 가젯을 추가하여 원하는 위치에 넣으시면 됩니다.

1.2 레이아웃


이글을 작성하는 현재 제 레이아웃이구요.

가젯추가를 통해 원하시는 Blogger에서 제공하는 가젯을 추가해 주시면 되겠습니다.

이외에 외부에서 제공하는 가젯을 이용하기 위해서는..

HTML/JavaScript 가젯을 추가하신 후 코드를 입력해 주시면 됩니다.


이상 여기까지가 기본적인 첫번째 방법을 통한 방법이구요.
이미지가 들어가니 스크롤이 길어졌네요.



그럼 여기에 두번째 방법으로 제 Posts List를 위치하는 것을 예를 들어 설명하겠습니다.

2. HTML 편집을 통한 레이아웃 편집.


템플렛에서 맞춤설정 옆에 HTML 편집을 클릭합니다.


경고 화면이 뜨네요. 저야 물론 고급 사용자가 아니지만.... 간단한 것만 수정하는 것이니 일단 계속을 눌러 봅니다.


코드가 길고 복잡하네요.
잘 못 수정하면 블로그의 레이아웃들이 엉망이 될 수 있으니 따로 txt 파일에 코드를 복사해 두신 후 수정에 들어가 주세요.


자. 레이아웃에서 추가한 가젯들의 위치를 조정해 볼려면 우선 가젯을 찾아야 겠죠?
편집화면 가장 밑으로 내려보시면 보시다시피 <b:section-contents> 태그와 <b:widget> 태그들이 보이실 겁니다.

<b:widget> 태그가 각 가젯을 나타내고.. 이 가젯들을 <b:section-contents> 태그가 감싸고 있는 형태이죠.

그럼 원하시는 가젯를 찾아야 할 텐데요. 이것은 가젯의 id를 통해서 찾을 수 있습니다.

원하시는 가젯이 정확히 어떤것인지 모르실 경우에는 레이아웃화면에서 원하는 가젯의 편집창을 클릭하여 좌우로 늘리면 가장 끝에 보이실 겁니다.


제 Posts List 가젯의 id는 HTML4이군요.
위에 가젯 리스트에 HTML4라는 id의 가젯은 보이시지 않으시죠?

네... 여기는 템플렛 레이아웃에서 고른 레이아웃들 중에 sidebar-right-1, footer-1, footer-2-2 위치만 보이는 군요.

다른 레이아웃들은 위쪽 HTML 코드속에 숨어 있죠.
이것들을 찾는 방법은 'ctrl+F' 키를 통해 찾으시면 되겠죠?

우선 'ctrl+F'를 통해 이동을 원하시는 가젯의 id를 찾습니다. 저 같은 경우 'HTML4'군요.
찾았습니다.

다음으로 기존 layout에서 원하는 section에 가젯을 추가하실 경우 section의 id를 찾아서 해당 위치에 가젯 코드를 이동 시키면 되구요..
새로운 위치에 section을 만들어서 가젯을 추가하셔도 됩니다.

저는 'Post' 위에 'Posts List'를 넣을 것 이므로.... section을 새로 만들 필요는 없이... id가 'main'인 section을 찾아보겠습니다. id='main'을 입력하면은


위와같이 중간에 있는 section을 찾을 수 있습니다. 해당 section의 'Blog1'이라는 id를 가진 가젯 위쪽에 'HTML4'를 위치 시키면 끝.
템플릿 저장을 누르시고 바뀐 레이아웃을 확인하시면 됩니다.

잘못 된 부분이 있으면 저장해 뒀던 파일을 가지고 다시 복구 하시구요.

[Blogspot] Label을 이용한 글목록(Posts List) 구현.

2012년도에 이글을 포스팅하고 지금까지 참 많은 분들이 찾아와 주셨네요.
그동안 소스를 수정한다고 마음만 먹고 실천을 못했었는데 이제야 수정해서 적용을 했습니다.
이 포스트에 있는 버전은 최대 150개까지의 포스트만 볼 수 있는 제한이 있으니 아래 링크의 글목록 기능을 적용하시길 원하시는 분은 아래 링크의 버전을 사용하여 주시기 바랍니다.

[Blogspot] 글목록(Posts List v2) with Angular.js



Blogspot에서 글 목록을 보여주는 기능을 제대로 제공해 주지 않아 고민을 하다 없으면 차라리 만들어보자는 생각아래 여러 시도끝에 드디어 Blogspot의 글목록을 제가 원하는데로 만든 것 같네요.

카테고리는 구글의 Label를 통해 어느정도 분류가 가능하지만 이것을 제대로 보여주기 위해서는 해당 카테고리의 글 목록을 보여주는 기능이 필요했었지요.

아래 내용은 제가 직접 구현한 이 포스트 위에 보이시는 Post List를 구현하는 방법입니다.

일단 코드먼저 보겠습니다.
<div>
<div id="posts" style="padding: 10px;">
</div>
<div align="center" id="posts-pgno" style="cursor: pointer;">
</div>
</div>
<script language="Javascript" type="text/javascript">
 /** url의 Parameter를 얻는 Class. **/
    var request = { 
  parameter: function(name) {
   return this.parameters()[name];
  },
  
  parameters: function() {
   var result = {};
   var url = window.location.href;
   var parameters = url.slice(url.indexOf('?') + 1).split('&');
    
   for(var i = 0;  i < parameters.length; i++) {
    var parameter = parameters[i].split('=');
    result[parameter[0]] = parameter[1];
   }
   return result;
  }
 }
 
 /** Page의 정보를 저장. **/
 var page = {
  //초기화.
  init: function(home,max){
   page.home = home;
   page.max = max;
   page.label = '';
   page.no = 1;
  },   
   
  //url의 parameter에서 pgno 값을 읽어 옮.
  setPage: function(){
   var url = window.location.href;
 
   var pl = url.lastIndexOf("/label/");
   var pq = url.lastIndexOf("?");
   
   if(pl != -1)
    page.label = url.substr(pl+7,((pq!=-1)?pq:url.length)-(pl+7));
   
   if(url.indexOf("pgno") != -1)
    page.no = request.parameter("pgno");
    
  }
  
 }
 /** feed를 parsing 하여 결과 뿌려 줌. **/
 var obj = {
  init: function () {
   obj.obj = document.getElementById('posts');
   obj.pgno = document.getElementById('posts-pgno');
  },
  
  // 검색을 요청하는 함수 
  pingSearch: function () {
   //변수 선언.
   obj.s = document.createElement('script');
   obj.s.type = 'text/javascript';
   obj.s.charset = 'utf-8';
   
   //feed callback 함수를 이용 json 객체 구한 후 pongSearch 함수호출. 
   if(page.label == '')
    obj.s.src = '' + page.home + 
     '/feeds/posts/summary/?max-results='+(page.no*page.max)
     +'&alt=json-in-script&callback=obj.pongSearch';
   else
    obj.s.src = '' + page.home + '/feeds/posts/summary/-/'
     +page.label+'?max-results='+(page.no*page.max)
     +'&alt=json-in-script&callback=obj.pongSearch';
    
   //append.
   document.getElementsByTagName('head')[0].appendChild(obj.s);
  },
   
  // 검색 결과를 뿌리는 함수 
  pongSearch: function (z) {
   obj.obj.innerHTML = '';
   
   /* 글 목록을 뿌려 줌. */
   for (var i = (page.no-1)*page.max; i < page.no*page.max; i++) {
    //예외처리.
    if(i >= z.feed.openSearch$totalResults.$t)
     break;
    
    //변수선언.
    var li = document.createElement("li");
    var a = document.createElement('a');
    
    //link로 사용할 base url.
    var url = page.home + '/search';
    if(page.label != '')
     url += '/label/' + page.label;
    
    //최종 link를 url 입력.
    if (i == 0) 
     a.href = url + '?max-results=1';
    else {
     var pub=obj.changeTime(z.feed.entry[i-1].published.$t);
     a.href = url + '?updated-max=' + pub 
     + '&max-results=1&pgno='+page.no;
    }
    a.innerHTML = obj.escapeHtml(z.feed.entry[i].title.$t);
     
    //append
    li.appendChild(a);
    obj.obj.appendChild(li);
   }
    
   /* page 뿌려줌. */
   obj.pongPgno(z);
  },
  
  // page를 뿌려주는 함수.
  pongPgno: function(z){
   obj.pgno.innerHTML = '';
   var before = document.createElement('a');
   var next = document.createElement('a');
   
   var ten = parseInt((page.no-1)/10);
   var total = z.feed.openSearch$totalResults.$t;

   /* before page */
   before.innerHTML = ' << ';   
   if(ten>0)
    obj.onMouseDown(before, ten*10);
   obj.pgno.appendChild(before);
   
   /* page number */
   for(var i=ten*10; i< (ten+1)*10; i++){
    if(i >= total/page.max)
     break;
    var a = document.createElement('a');
    obj.onMouseDown(a,i+1);
    
    a.innerHTML = ' ' + (i+1) + ' ';
    
    if(i+1 == page.no)
     a.style.color = 'yellow';     
    obj.pgno.appendChild(a);
   }
    
   /* next page */
   next.innerHTML = ' >> ';
   if(ten< parseInt(total/page.max/10))
    obj.onMouseDown(next, (ten+1)*10+1);
   obj.pgno.appendChild(next);
  },
   
  //mouse click event.
  onMouseDown: function(a, i){
   a.onmousedown = function(){
    page.no = i;
    obj.pingSearch();
   }
  },

  //Time 에러 수정.
  changeTime: function(str){
   var s = str.lastIndexOf('.')-1;
   var e = str.lastIndexOf('+')+1;
   
   var str2 = str.substr(0,s) + '%2B' + str.substr(e,100);
   
   return str2;
  },
  
  // HTML태그 안 먹게 하는 함수
  escapeHtml: function (str) {
   str = str.replace(/&/g, "&");
   str = str.replace(/</g, "<");
   str = str.replace(/>/g, ">");
   return str;
  }
 };

 page.init('http://creatorhong.blogspot.com', 5);
 page.setPage();
 obj.init(); 
 obj.pingSearch();
</script>
길군요...

그래도 그냥 복사 붙여넣기만 하면 되니...

바꾸실 곳은 아래쪽에 page.init('http://creatorhong.blogspot.com', 5);! 각각 블로그의 url 주소와 한 list안에 보여지는 최대 post 수를 입력하면 됩니다. 이때 url 주소 끝에 '/' 가 들어가면 안되구요.

최대 post수를 넘어가는 것은 번호를 넘겨가며 볼 수 있으니 적당한 수를 입력하시면 됩니다. 저 같은경우 5개로 지정하였습니다.

그리고... 앞쪽에 있는 <div> 태그내부에 style를 추가하시거나 css로 꾸미시는 것은 자유!.

이제 끝. 수정할 부분을 수정 하신 후 Blogger에서 제공하는 HTML/javascript 가젯에 코드를 붙여 넣기만 하면 됩니다.

HTML/javascript 가젯 추가하는 것을 모르시는 분이나 저처럼 Post 위쪽에 Posts List를 위치시키는 것이 궁금하신 분들은 링크 의 Post를 참고하시기 바랍니다.

아래는 구현 내용 설명....

전에 구현했던 코드 에서는 url의 label 부분을 읽어서 전체 feed에서 동일한 label를 찾아 순서대로 출력하는 방식이었는데요.
이때 url 인코딩을 제대로 처리 안하고 한 덕분에 여러가지 문제가 있었죠.

그래서 이번에는 url의 Label 를 읽는 것은 같으나 읽은 Label를 가지고 Label 마다 고유의 feed를 불러서 출력해주게 수정하였습니다. 그리고 각 List의 post link 를 post 고유 link가 아닌 Label에서의 순서를 통한 link로 입력하여 post를 눌러도 url 에 Label 이 남도록 수정 하였습니다.

더해서 접었다 펼 수 있게 했던 이전 코드와는 달리 정해진 수 만큼의 List을 항상 띄우고 아래 List Page Number 를 이용해 다음 List로 넘길 수 있도록 수정 하였습니다.

현재 Post Title만을 출력 되도록 하였는데... 혹시라도 label 이나 post 등록 날짜 등을 출력 하고 싶으시면 obj.pongSearch 부분을 수정하시면 됩니다.

이제보니 시간 설정을 표준시간대비 '-'인 곳의 대한 처리를 하지 않았군요. 알려주신 Samuel 님께 감사드립니다.
코드는 댓글에도 있지만.... 표준 시간대비 '-'이신 분들은 위에 코드 중 change:Time 부분을  아래 코드로 바꿔서 사용해 주시면 됩니다.
changeTime: function(str){
    var s = str.lastIndexOf('.')-1;
    var e = str.lastIndexOf('+')+1;

    if(e<1){
        e = str.lastIndexOf('-')+1;
        var str2 = str.substr(0,s) + '-' + str.substr(e,100);
    }
    else{
        var str2 = str.substr(0,s) + '%2B' + str.substr(e,100);
    }
    return str2;
},