Problem 67 » 履歴 » バージョン 2
Noppi, 2024/01/30 00:01
| 1 | 1 | Noppi | [ホーム](https://redmine.noppi.jp) - [[Wiki|Project Euler]] |
|---|---|---|---|
| 2 | # [[Problem 67]] |
||
| 3 | |||
| 4 | ## Maximum Path Sum II |
||
| 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 | |||
| 7 | <p style="text-align:center"><span style="color:red"><b>3</b></span><br><span style="color:red"><b>7</b></span> 4<br> |
||
| 8 | 2 <span style="color:red"><b>4</b></span> 6<br> |
||
| 9 | 8 5 <span style="color:red"><b>9</b></span> 3</p> |
||
| 10 | |||
| 11 | That is, 3 + 7 + 4 + 9 = 23. |
||
| 12 | |||
| 13 | Find the maximum total from top to bottom in [triangle.txt](https://projecteuler.net/resources/documents/0067_triangle.txt) (right click and 'Save Link/Target As...'), a 15K text file containing a triangle with one-hundred rows. |
||
| 14 | |||
| 15 | <b>NOTE:</b> This is a much more difficult version of [[Problem 18]]. It is not possible to try every route to solve this problem, as there are 2<sup>99</sup> altogether! If you could check one trillion (10<sup>12</sup>) routes every second it would take over twenty billion years to check them all. There is an efficient algorithm to solve it. ;o) |
||
| 16 | |||
| 17 | ## 最大経路の和 その2 |
||
| 18 | 以下の三角形の頂点から下まで移動するとき, その数値の合計の最大値は23になる. |
||
| 19 | |||
| 20 | <p style="text-align:center"><span style="color:red"><b>3</b></span><br><span style="color:red"><b>7</b></span> 4<br> |
||
| 21 | 2 <span style="color:red"><b>4</b></span> 6<br> |
||
| 22 | 8 5 <span style="color:red"><b>9</b></span> 3</p> |
||
| 23 | |||
| 24 | この例では 3 + 7 + 4 + 9 = 23 |
||
| 25 | |||
| 26 | 100列の三角形を含んでいる15Kのテキストファイル [triangle.txt](https://projecteuler.net/resources/documents/0067_triangle.txt) (右クリックして, 『名前をつけてリンク先を保存』)の上から下まで最大合計を見つけよ. |
||
| 27 | |||
| 28 | 注:これは, [[Problem 18]]のずっと難しいバージョンです. |
||
| 29 | 全部で2<sup>99</sup> 通りの組み合わせがあるので, この問題を解決するためにすべてのルートをためすことは可能でありません! |
||
| 30 | あなたが毎秒1兆本の(10<sup>12</sup>)ルートをチェックすることができたとしても, 全てをチェックするために200億年以上かかるでしょう. |
||
| 31 | 解決するための効率的なアルゴリズムがあります. ;o) |
||
| 32 | |||
| 33 | ```scheme |
||
| 34 | 2 | Noppi | (import (scheme base) |
| 35 | (gauche base) |
||
| 36 | (scheme file)) |
||
| 37 | |||
| 38 | (define (read-triangle filename) |
||
| 39 | (read-from-string |
||
| 40 | (format "#(~a)" |
||
| 41 | (call-with-output-string |
||
| 42 | (^[string-port] |
||
| 43 | (call-with-input-file |
||
| 44 | filename |
||
| 45 | (^[file-port] |
||
| 46 | (let loop ([line (read-line file-port)]) |
||
| 47 | (unless (eof-object? line) |
||
| 48 | (format string-port "(~a)" line) |
||
| 49 | (loop (read-line file-port))))) |
||
| 50 | :element-type :character)))))) |
||
| 51 | |||
| 52 | (define (walkthrough triangle) |
||
| 53 | (assume (vector? triangle)) |
||
| 54 | (assume (positive? (vector-length triangle))) |
||
| 55 | (let* ([triangle-length (vector-length triangle)] |
||
| 56 | [initial-result (let ([last-vector (vector-ref triangle (- triangle-length 1))]) |
||
| 57 | (map (^n `(,n ,n)) |
||
| 58 | last-vector))]) |
||
| 59 | (let loop1 ([current-index (- triangle-length 2)] |
||
| 60 | [result initial-result]) |
||
| 61 | (if (negative? current-index) |
||
| 62 | (cdar result) |
||
| 63 | (let* ([current-vector (vector-ref triangle current-index)] |
||
| 64 | [initial-list current-vector]) |
||
| 65 | (let loop2 ([rest-nums initial-list] |
||
| 66 | [rest-tree result] |
||
| 67 | [temp-tree '()]) |
||
| 68 | (if (null? rest-nums) |
||
| 69 | (loop1 (- current-index 1) (reverse temp-tree)) |
||
| 70 | (let* ([i-cell (car rest-tree)] |
||
| 71 | [j-cell (cadr rest-tree)] |
||
| 72 | [i-value (car i-cell)] |
||
| 73 | [j-value (car j-cell)] |
||
| 74 | [i-tree (cdr i-cell)] |
||
| 75 | [j-tree (cdr j-cell)] |
||
| 76 | [current-value (car rest-nums)]) |
||
| 77 | (if (<= j-value i-value) |
||
| 78 | (loop2 (cdr rest-nums) |
||
| 79 | (cdr rest-tree) |
||
| 80 | (cons (cons (+ current-value i-value) (cons current-value i-tree)) |
||
| 81 | temp-tree)) |
||
| 82 | (loop2 (cdr rest-nums) |
||
| 83 | (cdr rest-tree) |
||
| 84 | (cons (cons (+ current-value j-value) (cons current-value j-tree)) |
||
| 85 | temp-tree))))))))))) |
||
| 86 | |||
| 87 | (define answer-67 |
||
| 88 | (apply + |
||
| 89 | (walkthrough (read-triangle "triangle.txt")))) |
||
| 90 | |||
| 91 | (format #t "67: ~d~%" answer-67) |
||
| 92 | 1 | Noppi | ``` |