プロジェクト

全般

プロフィール

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