プロジェクト

全般

プロフィール

Problem 19 » 履歴 » バージョン 2

Noppi, 2024/01/01 16:05

1 1 Noppi
[ホーム](https://redmine.noppi.jp) - [[Wiki|Project Euler]]
2
# [[Problem 19]]
3
4
## Counting Sundays
5
You are given the following information, but you may prefer to do some research for yourself.
6
7
* 1 Jan 1900 was a Monday.
8
* Thirty days has September, April, June and November.
9
All the rest have thirty-one,
10
Saving February alone,
11
Which has twenty-eight, rain or shine.
12
And on leap years, twenty-nine.
13
* A leap year occurs on any year evenly divisible by 4, but not on a century unless it is divisible by 400.
14
15
How many Sundays fell on the first of the month during the twentieth century (1 Jan 1901 to 31 Dec 2000)?
16
17
## 日曜日の数え上げ
18
次の情報が与えられている.
19
20
* 1900年1月1日は月曜日である.
21
* 9月, 4月, 6月, 11月は30日まであり, 2月を除く他の月は31日まである.
22
* 2月は28日まであるが, うるう年のときは29日である.
23
* うるう年は西暦が4で割り切れる年に起こる. しかし, 西暦が400で割り切れず100で割り切れる年はうるう年でない.
24
25
20世紀(1901年1月1日から2000年12月31日)中に月の初めが日曜日になるのは何回あるか?
26
27
```scheme
28 2 Noppi
#!r6rs
29
#!chezscheme
30
31
(import (chezscheme))
32
33
(define (leap-year? year)
34
  (cond
35
    [(and (not (zero? (mod year 400)))
36
          (zero? (mod year 100)))
37
     #f]
38
    [(zero? (mod year 4)) #t]
39
    [else #f]))
40
41
(define (days-count year month)
42
  (case month
43
    [(4 6 9 11) 30]
44
    [2
45
     (if (leap-year? year)
46
       29
47
       28)]
48
    [else 31]))
49
50
(define (month-calender year month start-dayweek)
51
  (let ([end (days-count year month)])
52
    (let loop ([i 1] [dayweek start-dayweek] [result '()])
53
      (if (< end i)
54
        (values (reverse result) (mod (add1 (cdr (car result))) 7))
55
        (loop (add1 i) (mod (add1 dayweek) 7)
56
              (cons `((,year ,month ,i) . ,(mod dayweek 7)) result))))))
57
58
(define (year-calender year start-dayweek)
59
  (let loop ([i 1] [dayweek start-dayweek] [result '()])
60
    (if (< 12 i)
61
      (values result dayweek)
62
      (let-values ([(lis next-dayweek) (month-calender year i dayweek)])
63
        (loop (add1 i) next-dayweek `(,@result ,@lis))))))
64
65
(define (pickup-dayweek calender dayweek)
66
  (filter
67
    (lambda (cell)
68
      (= (cdr cell) dayweek))
69
    calender))
70
71
(define (pickup-start-month calender)
72
  (filter
73
    (lambda (cell)
74
      (= (list-ref (car cell) 2) 1))
75
    calender))
76
77
(define calender-1900-2000
78
  (let loop ([year 1900] [dayweek 1] [result '()])
79
    (if (< 2000 year)
80
      result
81
      (let-values ([(lis next-dayweek) (year-calender year dayweek)])
82
        (loop (add1 year) next-dayweek `(,@result ,@lis))))))
83
84
(define calender-1901-2000
85
  (filter
86
    (lambda (cell)
87
      (<= 1901 (caar cell)))
88
    calender-1900-2000))
89
90
(define answer-19
91
  (length
92
    (pickup-dayweek
93
      (pickup-start-month calender-1901-2000)
94
      0)))
95
96
(printf "19: ~D~%" answer-19)
97 1 Noppi
```