2010년 10월 29일 금요일

Euler Problem 11

문제는 다음과 같다.
In the 20×20 grid below, four numbers along a diagonal line have been marked in red.
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
The product of these numbers is 26 × 63 × 78 × 14 = 1788696.
What is the greatest product of four adjacent numbers in any direction (up, down, left, right, or diagonally) in the 20×20 grid?

일단, 위 그리드에 있는 숫자들을 2차원 배열에 넣는 작업을 수행할 필요가 있다. 그 다음에 각각의 숫자를 중심으로 가로줄, 세로줄, 왼쪽 대각선 줄, 오른족 대각선 줄에서 각각 4개씩의 연속된 숫자를 뽑아 곱셈을 해야 한다. 처음에 어떻게 해야 할지 막막했으나, 2차원 배열표를 그려놓고 가만히 생각하니 규칙성이 발견되었다. 그래서 이를 아래와 같이 구현하였다.

Option Explicit

Sub Euler11()
    Dim sDigit As String
    Dim Num(1 To 20, 1 To 20)
    Dim i, j, k, Greatest, Product
   
    sDigit = sDigit & "08 02 22 97 38 15 00 40 00 75 04 05 07 78 52 12 50 77 91 08"
    sDigit = sDigit & " 49 49 99 40 17 81 18 57 60 87 17 40 98 43 69 48 04 56 62 00"
    sDigit = sDigit & " 81 49 31 73 55 79 14 29 93 71 40 67 53 88 30 03 49 13 36 65"
    sDigit = sDigit & " 52 70 95 23 04 60 11 42 69 24 68 56 01 32 56 71 37 02 36 91"
    sDigit = sDigit & " 22 31 16 71 51 67 63 89 41 92 36 54 22 40 40 28 66 33 13 80"
    sDigit = sDigit & " 24 47 32 60 99 03 45 02 44 75 33 53 78 36 84 20 35 17 12 50"
    sDigit = sDigit & " 32 98 81 28 64 23 67 10 26 38 40 67 59 54 70 66 18 38 64 70"
    sDigit = sDigit & " 67 26 20 68 02 62 12 20 95 63 94 39 63 08 40 91 66 49 94 21"
    sDigit = sDigit & " 24 55 58 05 66 73 99 26 97 17 78 78 96 83 14 88 34 89 63 72"
    sDigit = sDigit & " 21 36 23 09 75 00 76 44 20 45 35 14 00 61 33 97 34 31 33 95"
    sDigit = sDigit & " 78 17 53 28 22 75 31 67 15 94 03 80 04 62 16 14 09 53 56 92"
    sDigit = sDigit & " 16 39 05 42 96 35 31 47 55 58 88 24 00 17 54 24 36 29 85 57"
    sDigit = sDigit & " 86 56 00 48 35 71 89 07 05 44 44 37 44 60 21 58 51 54 17 58"
    sDigit = sDigit & " 19 80 81 68 05 94 47 69 28 73 92 13 86 52 17 77 04 89 55 40"
    sDigit = sDigit & " 04 52 08 83 97 35 99 16 07 97 57 32 16 26 26 79 33 27 98 66"
    sDigit = sDigit & " 88 36 68 87 57 62 20 72 03 46 33 67 46 55 12 32 63 93 53 69"
    sDigit = sDigit & " 04 42 16 73 38 25 39 11 24 94 72 18 08 46 29 32 40 62 76 36"
    sDigit = sDigit & " 20 69 36 41 72 30 23 88 34 62 99 69 82 67 59 85 74 04 36 16"
    sDigit = sDigit & " 20 73 35 29 78 31 90 01 74 31 49 71 48 86 81 16 23 57 05 54"
    sDigit = sDigit & " 01 70 54 71 83 51 54 69 16 92 33 48 61 43 52 01 89 19 67 48"
    k = 1
    For i = 1 To 20
        For j = 1 To 20
            Num(i, j) = Mid(sDigit, k, 2)
            k = k + 3
        Next
    Next
   
    For i = 1 To 20
        For j = 1 To 20
            For k = 3 To 0 Step -1
                ' 세로줄 계산
                If (i - k) > 0 And (i - k + 3) < 21 Then
                    Product = Num(i - k, j) * Num(i - k + 1, j) * Num(i - k + 2, j) * Num(i - k + 3, j)
                    If Product > Greatest Then
                        Greatest = Product
                    End If
                End If
                ' 가로줄 계산
                If (j - k) > 0 And (j - k + 3) < 21 Then
                    Product = Num(i, j - k) * Num(i, j - k + 1) * Num(i, j - k + 2) * Num(i, j - k + 3)
                    If Product > Greatest Then
                        Greatest = Product
                    End If
                End If
                ' 왼쪽 대각선 계산
                If (i - k) > 0 And (i - k + 3) < 21 And (j - k) > 0 And (j - k + 3) < 21 Then
                    Product = Num(i - k, j - k) * Num(i - k + 1, j - k + 1) * Num(i - k + 2, j - k + 2) * Num(i - k + 3, j - k + 3)
                    If Product > Greatest Then
                        Greatest = Product
                    End If
                End If
                ' 오른쪽 대각선 계산
                If (i - k) > 0 And (i - k + 3) < 21 And (j + k) < 21 And (j + k - 3) > 0 Then
                    Product = Num(i - k, j + k) * Num(i - k + 1, j + k - 1) * Num(i - k + 2, j + k - 2) * Num(i - k + 3, j + k - 3)
                    If Product > Greatest Then
                        Greatest = Product
                    End If
                End If
            Next
        Next
    Next
    Debug.Print Greatest
End Sub
실행시간(초):  0.046875

댓글 없음:

댓글 쓰기

2.1 벡터(Vector)

  R의 자료구조 : 벡터, factor, 행렬, 배열, 데이터프레임, 리스트 벡터(Vector)는 동일한 형태(예, 숫자)의 데이터 구성인자가 1개 이상이면서 1차원으로 구성되어 있는 데이터 구조입니다. w <- c(1, 2, 3, 4, ...