#### /extra/project-euler/019/019.factor

http://github.com/abeaumont/factor
Unknown | 66 lines | 46 code | 20 blank | 0 comment | 0 complexity | d9f2f94c328ee3aa0daed3c546aefc07 MD5 | raw file
``` 1! Copyright (c) 2007 Samuel Tardieu, Aaron Schaefer.
3USING: calendar combinators kernel math math.ranges namespaces sequences
4    math.order project-euler.common ;
5IN: project-euler.019
6
7! http://projecteuler.net/index.php?section=problems&id=19
8
9! DESCRIPTION
10! -----------
11
12! You are given the following information, but you may prefer to do some
13! research for yourself.
14
15!     * 1 Jan 1900 was a Monday.
16!     * Thirty days has September, April, June and November.  All the rest have
17!       thirty-one, Saving February alone, Which has twenty-eight, rain or
18!       shine.  And on leap years, twenty-nine.
19!     * A leap year occurs on any year evenly divisible by 4, but not on a
20!       century unless it is divisible by 400.
21
22! How many Sundays fell on the first of the month during the twentieth century
23! (1 Jan 1901 to 31 Dec 2000)?
24
25
26! SOLUTION
27! --------
28
29! Use Zeller congruence, which is implemented in the "calendar" module
30! already, as "zeller-congruence ( year month day -- n )" where n is
31! the day of the week (Sunday is 0).
32
33: euler019 ( -- answer )
34    1901 2000 [a,b] [
35        12 [1,b] [ 1 zeller-congruence ] with map
36    ] map concat [ 0 = ] count ;
37
38! [ euler019 ] 100 ave-time
39! 1 ms ave run time - 0.51 SD (100 trials)
40
41
42! ALTERNATE SOLUTIONS
43! -------------------
44
45<PRIVATE
46
47: start-date ( -- timestamp )
48    1901 1 1 <date> ;
49
50: end-date ( -- timestamp )
51    2000 12 31 <date> ;
52
53: first-days ( end-date start-date -- days )
54    [ 2dup after=? ]
55    [ dup 1 months time+ swap day-of-week ]
56    produce 2nip ;
57
58PRIVATE>
59
60: euler019a ( -- answer )
61    end-date start-date first-days [ 0 = ] count ;
62
63! [ euler019a ] 100 ave-time
64! 17 ms ave run time - 2.13 SD (100 trials)
65
66SOLUTION: euler019
```