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 | ``` |