Problem 18 » 履歴 » バージョン 5
Noppi, 2024/01/02 06:11
| 1 | 1 | Noppi | [ホーム](https://redmine.noppi.jp) - [[Wiki|Project Euler]] |
|---|---|---|---|
| 2 | # [[Problem 18]] |
||
| 3 | |||
| 4 | ## Maximum Path Sum I |
||
| 5 | By starting at the top of the triangle below and moving to adjacent numbers on the row below, the maximum total from top to bottom is $23$. |
||
| 6 | <div style="text-align:center"><span style="color:red">3</span><br /> |
||
| 7 | <span style="color:red">7</span> 4<br /> |
||
| 8 | 2 <span style="color:red">4</span> 6<br /> |
||
| 9 | 8 5 <span style="color:red">9</span> 3</div> |
||
| 10 | That is, $3 + 7 + 4 + 9 = 23$. |
||
| 11 | Find the maximum total from top to bottom of the triangle below: |
||
| 12 | <div style="text-align:center">75<br /> |
||
| 13 | 95 64<br /> |
||
| 14 | 17 47 82<br /> |
||
| 15 | 18 35 87 10<br /> |
||
| 16 | 20 04 82 47 65<br /> |
||
| 17 | 19 01 23 75 03 34<br /> |
||
| 18 | 88 02 77 73 07 63 67<br /> |
||
| 19 | 99 65 04 28 06 16 70 92<br /> |
||
| 20 | 41 41 26 56 83 40 80 70 33<br /> |
||
| 21 | 41 48 72 33 47 32 37 16 94 29<br /> |
||
| 22 | 53 71 44 65 25 43 91 52 97 51 14<br /> |
||
| 23 | 70 11 33 28 77 73 17 78 39 68 17 57<br /> |
||
| 24 | 91 71 52 38 17 14 91 43 58 50 27 29 48<br /> |
||
| 25 | 63 66 04 68 89 53 67 30 73 16 69 87 40 31<br /> |
||
| 26 | 04 62 98 27 23 09 70 98 73 93 38 53 60 04 23</div> |
||
| 27 | 3 | Noppi | |
| 28 | 1 | Noppi | **NOTE:** As there are only $16384$ routes, it is possible to solve this problem by trying every route. However, Problem 67, is the same challenge with a triangle containing one-hundred rows; it cannot be solved by brute force, and requires a clever method! ;o) |
| 29 | |||
| 30 | ## 数字の文字数 |
||
| 31 | 以下の三角形の頂点から下の行の隣接する数字を通って下まで移動するとき, その数値の和の最大値は23になる. |
||
| 32 | <div style="text-align:center"><span style="color:red">3</span><br /> |
||
| 33 | <span style="color:red">7</span> 4<br /> |
||
| 34 | 2 <span style="color:red">4</span> 6<br /> |
||
| 35 | 8 5 <span style="color:red">9</span> 3</div> |
||
| 36 | この例では 3 + 7 + 4 + 9 = 23. |
||
| 37 | 以下の三角形を頂点から下まで移動するとき, その最大の和を求めよ. |
||
| 38 | <div style="text-align:center">75<br /> |
||
| 39 | 95 64<br /> |
||
| 40 | 17 47 82<br /> |
||
| 41 | 18 35 87 10<br /> |
||
| 42 | 20 04 82 47 65<br /> |
||
| 43 | 19 01 23 75 03 34<br /> |
||
| 44 | 88 02 77 73 07 63 67<br /> |
||
| 45 | 99 65 04 28 06 16 70 92<br /> |
||
| 46 | 41 41 26 56 83 40 80 70 33<br /> |
||
| 47 | 41 48 72 33 47 32 37 16 94 29<br /> |
||
| 48 | 53 71 44 65 25 43 91 52 97 51 14<br /> |
||
| 49 | 70 11 33 28 77 73 17 78 39 68 17 57<br /> |
||
| 50 | 91 71 52 38 17 14 91 43 58 50 27 29 48<br /> |
||
| 51 | 63 66 04 68 89 53 67 30 73 16 69 87 40 31<br /> |
||
| 52 | 04 62 98 27 23 09 70 98 73 93 38 53 60 04 23</div> |
||
| 53 | 2 | Noppi | |
| 54 | **注:** ここではたかだか 16384 通りのルートしかないので, すべてのパターンを試すこともできる. Problem 67 は同じ問題だが100行あるので, 総当りでは解けない. もっと賢い方法が必要である. |
||
| 55 | 1 | Noppi | |
| 56 | ```scheme |
||
| 57 | 4 | Noppi | #!r6rs |
| 58 | #!chezscheme |
||
| 59 | |||
| 60 | (import (chezscheme)) |
||
| 61 | |||
| 62 | (define triangle |
||
| 63 | '#(#(75) |
||
| 64 | #(95 64) |
||
| 65 | #(17 47 82) |
||
| 66 | #(18 35 87 10) |
||
| 67 | #(20 04 82 47 65) |
||
| 68 | #(19 01 23 75 03 34) |
||
| 69 | #(88 02 77 73 07 63 67) |
||
| 70 | #(99 65 04 28 06 16 70 92) |
||
| 71 | #(41 41 26 56 83 40 80 70 33) |
||
| 72 | #(41 48 72 33 47 32 37 16 94 29) |
||
| 73 | #(53 71 44 65 25 43 91 52 97 51 14) |
||
| 74 | #(70 11 33 28 77 73 17 78 39 68 17 57) |
||
| 75 | #(91 71 52 38 17 14 91 43 58 50 27 29 48) |
||
| 76 | #(63 66 04 68 89 53 67 30 73 16 69 87 40 31) |
||
| 77 | #(04 62 98 27 23 09 70 98 73 93 38 53 60 04 23))) |
||
| 78 | |||
| 79 | (define (walkthrough triangle) |
||
| 80 | (let* ([triangle-length (vector-length triangle)] |
||
| 81 | 5 | Noppi | [initial-result (let ([last-vector (vector-ref triangle (sub1 triangle-length))]) |
| 82 | (map |
||
| 83 | (lambda (num) |
||
| 84 | `(,num ,num)) |
||
| 85 | (vector->list last-vector)))]) |
||
| 86 | 4 | Noppi | (if (= triangle-length 1) |
| 87 | 5 | Noppi | (cdar initial-result) |
| 88 | 4 | Noppi | (let loop1 ([current-index (- triangle-length 2)] |
| 89 | [result initial-result]) |
||
| 90 | 5 | Noppi | (let* ([current-vector (vector-ref triangle current-index)] |
| 91 | [initial-list (vector->list current-vector)]) |
||
| 92 | 1 | Noppi | (if (zero? current-index) |
| 93 | 5 | Noppi | (let* ([i-cell (car result)] |
| 94 | [j-cell (cadr result)] |
||
| 95 | 4 | Noppi | [i-value (car i-cell)] |
| 96 | [j-value (car j-cell)] |
||
| 97 | [i-tree (cdr i-cell)] |
||
| 98 | [j-tree (cdr j-cell)] |
||
| 99 | 5 | Noppi | [current-value (car initial-list)]) |
| 100 | 4 | Noppi | (if (<= j-value i-value) |
| 101 | (cons current-value i-tree) |
||
| 102 | (cons current-value j-tree))) |
||
| 103 | 5 | Noppi | (let loop2 ([rest-nums initial-list] |
| 104 | [rest-tree result] |
||
| 105 | [temp-tree '()]) |
||
| 106 | (if (null? rest-nums) |
||
| 107 | (loop1 (sub1 current-index) (reverse temp-tree)) |
||
| 108 | (let* ([i-cell (car rest-tree)] |
||
| 109 | [j-cell (cadr rest-tree)] |
||
| 110 | [i-value (car i-cell)] |
||
| 111 | [j-value (car j-cell)] |
||
| 112 | [i-tree (cdr i-cell)] |
||
| 113 | [j-tree (cdr j-cell)] |
||
| 114 | [current-value (car rest-nums)]) |
||
| 115 | (if (<= j-value i-value) |
||
| 116 | (loop2 (cdr rest-nums) |
||
| 117 | (cdr rest-tree) |
||
| 118 | (cons (cons (+ current-value i-value) (cons current-value i-tree)) |
||
| 119 | temp-tree)) |
||
| 120 | (loop2 (cdr rest-nums) |
||
| 121 | (cdr rest-tree) |
||
| 122 | (cons (cons (+ current-value j-value) (cons current-value j-tree)) |
||
| 123 | temp-tree)))))))))))) |
||
| 124 | 4 | Noppi | |
| 125 | (define answer-18 |
||
| 126 | (apply + (walkthrough triangle))) |
||
| 127 | |||
| 128 | (printf "18: ~D~%" answer-18) |
||
| 129 | 1 | Noppi | ``` |