Problem 32 » 履歴 » バージョン 1
Noppi, 2024/01/13 06:38
| 1 | 1 | Noppi | [ホーム](https://redmine.noppi.jp) - [[Wiki|Project Euler]] |
|---|---|---|---|
| 2 | # [[Problem 32]] |
||
| 3 | |||
| 4 | ## Pandigital Products |
||
| 5 | We shall say that an $n$-digit number is pandigital if it makes use of all the digits $1$ to $n$ exactly once; for example, the $5$-digit number, $15234$, is $1$ through $5$ pandigital. |
||
| 6 | |||
| 7 | The product $7254$ is unusual, as the identity, $39 \times 186 = 7254$, containing multiplicand, multiplier, and product is $1$ through $9$ pandigital. |
||
| 8 | |||
| 9 | Find the sum of all products whose multiplicand/multiplier/product identity can be written as a $1$ through $9$ pandigital. |
||
| 10 | |||
| 11 | HINT: Some products can be obtained in more than one way so be sure to only include it once in your sum. |
||
| 12 | |||
| 13 | ## パンデジタル積 |
||
| 14 | すべての桁に 1 から n が一度だけ使われている数をn桁の数がパンデジタル (pandigital) であるということにしよう: 例えば5桁の数 15234 は1から5のパンデジタルである. |
||
| 15 | |||
| 16 | 7254 は面白い性質を持っている. 39 × 186 = 7254 と書け, 掛けられる数, 掛ける数, 積が1から9のパンデジタルとなる. |
||
| 17 | |||
| 18 | 掛けられる数/掛ける数/積が1から9のパンデジタルとなるような積の総和を求めよ. |
||
| 19 | |||
| 20 | ヒント: いくつかの積は, 1通り以上の掛けられる数/掛ける数/積の組み合わせを持つが1回だけ数え上げよ. |
||
| 21 | |||
| 22 | ```scheme |
||
| 23 | (import (scheme base) |
||
| 24 | (gauche base) |
||
| 25 | (scheme sort)) |
||
| 26 | |||
| 27 | (define (my-permutation lis) |
||
| 28 | (let perm-sub ([rest lis] [sub '()] [result '()]) |
||
| 29 | (if (null? rest) |
||
| 30 | (cons (reverse sub) result) |
||
| 31 | (fold-right (^[n result] |
||
| 32 | (perm-sub (delete n rest) (cons n sub) result)) |
||
| 33 | result |
||
| 34 | rest)))) |
||
| 35 | |||
| 36 | (define (unique lis) |
||
| 37 | (let loop ([prev #f] [rest lis] [result '()]) |
||
| 38 | (cond |
||
| 39 | [(null? rest) (reverse result)] |
||
| 40 | [(and prev |
||
| 41 | (= prev (car rest))) |
||
| 42 | (loop prev (cdr rest) result)] |
||
| 43 | [else |
||
| 44 | (loop (car rest) |
||
| 45 | (cdr rest) |
||
| 46 | (cons (car rest) result))]))) |
||
| 47 | |||
| 48 | ; 有効な a * b = c のそれぞれの桁数は次の通り |
||
| 49 | ; (1 4 4) |
||
| 50 | ; (2 3 4) |
||
| 51 | ; (3 2 4) |
||
| 52 | ; (4 1 4) |
||
| 53 | ; ただし、a * b = b * a なので後半は必要ない |
||
| 54 | (define pandigital-num-triplets |
||
| 55 | (let ([perm-list (my-permutation (iota 9 1))]) |
||
| 56 | (let loop ([rest perm-list] [result '()]) |
||
| 57 | (if (null? rest) |
||
| 58 | result |
||
| 59 | (let* ([digital (car rest)] |
||
| 60 | [rest (cdr rest)] |
||
| 61 | [digital-vec (list->vector digital)] |
||
| 62 | [a1 (vector-ref digital-vec 0)] |
||
| 63 | [b1 (+ (* (vector-ref digital-vec 1) 1000) |
||
| 64 | (* (vector-ref digital-vec 2) 100) |
||
| 65 | (* (vector-ref digital-vec 3) 10) |
||
| 66 | (vector-ref digital-vec 4))] |
||
| 67 | [c (+ (* (vector-ref digital-vec 5) 1000) |
||
| 68 | (* (vector-ref digital-vec 6) 100) |
||
| 69 | (* (vector-ref digital-vec 7) 10) |
||
| 70 | (vector-ref digital-vec 8))] |
||
| 71 | [a2 (+ (* (vector-ref digital-vec 0) 10) |
||
| 72 | (vector-ref digital-vec 1))] |
||
| 73 | [b2 (+ (* (vector-ref digital-vec 2) 100) |
||
| 74 | (* (vector-ref digital-vec 3) 10) |
||
| 75 | (vector-ref digital-vec 4))] |
||
| 76 | [new-result result]) |
||
| 77 | (when (= (* a1 b1) c) |
||
| 78 | (set! new-result (cons `(,a1 ,b1 . ,c) new-result))) |
||
| 79 | (when (= (* a2 b2) c) |
||
| 80 | (set! new-result (cons `(,a2 ,b2 . ,c) new-result))) |
||
| 81 | (loop rest new-result)))))) |
||
| 82 | |||
| 83 | (define pandigital-nums |
||
| 84 | (unique |
||
| 85 | (list-sort < (map (cut cddr <>) |
||
| 86 | pandigital-num-triplets)))) |
||
| 87 | |||
| 88 | (define answer-32 |
||
| 89 | (apply + pandigital-nums)) |
||
| 90 | |||
| 91 | (format #t "32: ~d~%" answer-32) |
||
| 92 | ``` |