- ΠΠ°ΡΠΈΠ°Π½Ρ: 12, 19
- ΠΡΠ΅ΠΏΠΎΠ΄Π°Π²Π°ΡΠ΅Π»Ρ ΠΠ΅Π½ΡΠΊΠΎΠΉ ΠΠ»Π΅ΠΊΡΠ°Π½Π΄Ρ ΠΠ»Π°Π΄ΠΈΠΌΠΈΡΠΎΠ²ΠΈΡ
- ΠΡΠΏΠΎΠ»Π½ΠΈΠ»
ΠΠΎΡΠ»ΡΠΊΠΎΠ² ΠΠ°Π½ΠΈΠΈΠ» ΠΠ΅ΡΡΠΎΠ²ΠΈΡ
,367165
- ΠΠ’ΠΠ, Π‘Π°Π½ΠΊΡ-ΠΠ΅ΡΠ΅ΡΠ±ΡΡΠ³, 2024
ΠΠ°Π½Π½Π°Ρ Π»Π°Π±ΠΎΡΠ°ΡΠΎΡΠ½Π°Ρ ΡΠ°Π±ΠΎΡΠ° Π½Π°ΠΏΡΠ°Π²Π»Π΅Π½Π° Π½Π° ΠΏΡΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ ΡΠ°Π·Π»ΠΈΡΠ½ΡΡ ΠΏΠΎΠ΄Ρ ΠΎΠ΄ΠΎΠ² ΡΡΠ½ΠΊΡΠΈΠΎΠ½Π°Π»ΡΠ½ΠΎΠ³ΠΎ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠΈΡΠΎΠ²Π°Π½ΠΈΡ Π΄Π»Ρ ΡΠ΅ΡΠ΅Π½ΠΈΡ Π·Π°Π΄Π°Ρ ΠΈΠ· Project Euler. Π Π΅ΡΠ΅Π½Π½ΡΠ΅ Π·Π°Π΄Π°ΡΠΈ:
- ΠΠ°Π΄Π°ΡΠ° 12: ΠΠ°Ρ
ΠΎΠΆΠ΄Π΅Π½ΠΈΠ΅ ΠΏΠ΅ΡΠ²ΠΎΠ³ΠΎ ΡΡΠ΅ΡΠ³ΠΎΠ»ΡΠ½ΠΎΠ³ΠΎ ΡΠΈΡΠ»Π° Ρ Π±ΠΎΠ»Π΅Π΅ ΡΠ΅ΠΌ
N
Π΄Π΅Π»ΠΈΡΠ΅Π»ΡΠΌΠΈ. - ΠΠ°Π΄Π°ΡΠ° 19: ΠΠΎΠ΄ΡΡΠ΅Ρ ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²Π° Π²ΠΎΡΠΊΡΠ΅ΡΠ΅Π½ΠΈΠΉ, Π²ΡΠΏΠ°Π΄Π°ΡΡΠΈΡ Π½Π° ΠΏΠ΅ΡΠ²ΠΎΠ΅ ΡΠΈΡΠ»ΠΎ ΠΌΠ΅ΡΡΡΠ° Π·Π° ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½Π½ΡΠΉ ΠΏΠ΅ΡΠΈΠΎΠ΄.
- p12/ ΠΈ p19/ β Π΄ΠΈΡΠ΅ΠΊΡΠΎΡΠΈΠΈ Ρ ΡΠ΅ΡΠ΅Π½ΠΈΡΠΌΠΈ Π·Π°Π΄Π°Ρ 12 ΠΈ 19 ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²Π΅Π½Π½ΠΎ.
- lib/ β ΠΌΠΎΠ΄ΡΠ»ΠΈ ΠΈ ΡΠ°ΠΉΠ»Ρ Ρ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΡΠΌΠΈ ΡΠ°Π·Π»ΠΈΡΠ½ΡΡ ΠΏΠΎΠ΄Ρ ΠΎΠ΄ΠΎΠ²:
- test/ β ΡΠ΅ΡΡΡ Π΄Π»Ρ ΠΏΡΠΎΠ²Π΅ΡΠΊΠΈ ΡΠ΅ΡΠ΅Π½ΠΈΠΉ, Π½Π°ΠΏΠΈΡΠ°Π½Π½ΡΠ΅ Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ΠΌ
OUnit2
.*
* - ΡΠΎΠ»ΡΠΊΠΎ Π² p12, Π² p19 ΠΈΡΠΏΠ»ΡΠ·ΡΡΡΡΡ inline
ΡΠ΅ΡΡΡ.
ΠΠΈΠΆΠ΅ ΠΏΡΠΈΠ²Π΅Π΄Π΅Π½Ρ ΡΠ΅ΠΌΠ°ΡΠΈΡΠ΅ΡΠΊΠΈΠ΅ ΠΎΡΠΎΠ±Π΅Π½Π½ΠΎΡΡΠΈ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΠΉ (Π³Π΄Π΅ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½Π° ΡΠ΅ΠΊΡΡΡΠΈΡ, Ρ Π²ΠΎΡΡΠΎΠ²Π°Ρ ΡΠ΅ΠΊΡΡΡΠΈΡ, ΠΌΠΎΠ΄ΡΠ»ΡΠ½ΠΎΠ΅ ΡΠ΅ΡΠ΅Π½ΠΈΠ΅ ΠΈ ΠΏΡ.)
let count_factors n =
let rec aux i =
if i * i > n
then 0
else if n mod i = 0
then if i * i = n then 1 + aux (i + 1) else 2 + aux (i + 1)
else aux (i + 1)
in
if n <= 0 then 0 else aux 1
;;
let count_factors_tail n =
let rec aux i count =
if i * i > n
then count
else if n mod i = 0
then aux (i + 1) (count + if i * i = n then 1 else 2)
else aux (i + 1) count
in
if n <= 0 then 0 else aux 1 0
;;
let result =
List.filter (fun x -> count_factors_tail x > 500) triangular_numbers
|> List.fold_left
(fun acc x ->
match acc with
| Some _ -> acc
| None -> Some x)
None
;;
let triangular_numbers limit =
let generate_range n = List.init n (fun i -> i + 1) in
List.map (fun n -> n * (n + 1) / 2) (generate_range limit)
;;
let triangular_numbers =
Seq.unfold
(fun n ->
let t = n * (n + 1) / 2 in
Some (t, n + 1))
1
;;
let find_first_triangular_with_factors n =
Seq.find (fun x -> count_factors_tail x > n) triangular_numbers
;;
let count_divisors n =
let count = ref 0 in
let root = int_of_float (sqrt (float_of_int n)) in
for i = 1 to root do
if n mod i = 0 then if i = n / i then incr count else count := !count + 2
done;
!count
;;
let find_triangle_with_divisors limit =
let found = ref false in
let result = ref 0 in
let n = ref 1 in
while not !found do
let tri_num = triangle_number !n in
if count_divisors tri_num > limit
then (
result := tri_num;
found := true);
incr n
done;
!result
;;
def count_divisors(n):
sqrt_n = int(math.sqrt(n))
count = sum(2 for i in range(1, sqrt_n + 1) if n % i == 0)
if sqrt_n * sqrt_n == n:
count -= 1
return count
def first_triangle_number_with_divisors(limit):
n = 1
triangle = 1
while True:
divisors = count_divisors(triangle)
if divisors > limit:
return triangle
n += 1
triangle += n
ΠΠΈΠΆΠ΅ ΠΏΡΠΈΠ²Π΅Π΄Π΅Π½Ρ ΡΠ΅ΠΌΠ°ΡΠΈΡΠ΅ΡΠΊΠΈΠ΅ ΠΎΡΠΎΠ±Π΅Π½Π½ΠΎΡΡΠΈ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΠΉ (Π³Π΄Π΅ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½Π° ΡΠ΅ΠΊΡΡΡΠΈΡ, Ρ Π²ΠΎΡΡΠΎΠ²Π°Ρ ΡΠ΅ΠΊΡΡΡΠΈΡ, ΠΌΠΎΠ΄ΡΠ»ΡΠ½ΠΎΠ΅ ΡΠ΅ΡΠ΅Π½ΠΈΠ΅ ΠΈ ΠΏΡ.)
let rec count_sundays year month day_of_week =
if year > 2000
then 0
else (
let new_count = if day_of_week = 0 then 1 else 0 in
let days_this_month = days_in_month year month in
let next_day_of_week = (day_of_week + days_this_month) mod 7 in
if month == 12
then new_count + count_sundays (year + 1) 1 next_day_of_week
else new_count + count_sundays year (month + 1) next_day_of_week)
;;
let rec count_sundays year month day_of_week count =
if year > 2000
then count
else (
let new_count = if day_of_week = 0 then count + 1 else count in
let days_this_month = days_in_month year month in
let next_day_of_week = (day_of_week + days_this_month) mod 7 in
if month == 12
then count_sundays (year + 1) 1 next_day_of_week new_count
else count_sundays year (month + 1) next_day_of_week new_count)
;;
let count_sundays start_year end_year =
let years = List.init (end_year - start_year + 1) (fun i -> start_year + i) in
let aux year =
let months = List.init 12 (fun m -> m + 1) in
List.filter (fun month -> zellers_congruence year month 1 = 0) months |> List.length
in
List.fold_left (fun acc year -> acc + aux year) 0 years
;;
let count_sundays start_year end_year =
let years = List.init (end_year - start_year + 1) (fun i -> start_year + i) in
let aux year =
let months = List.init 12 (fun m -> m + 1) in
let map_filter month = if zellers_congruence year month 1 = 0 then 1 else 0 in
List.fold_left ( + ) 0 (List.map map_filter months)
in
List.fold_left (fun acc year -> acc + aux year) 0 years
;;
let count_sundays start_year end_year =
let count = ref 0 in
for year = start_year to end_year do
for month = 1 to 12 do
if zellers_congruence year month 1 = 0 then incr count
done
done;
!count
;;
for year in range(1901, 2001):
for month in range(1, 13):
first_day = datetime(year, month, 1)
if first_day.weekday() == 6:
sundays_count += 1
OCaml ΠΏΠΎΠΊΠ°Π·Π°Π»ΡΡ ΠΌΠ½Π΅ Π΄ΠΎΡΡΠ°ΡΠΎΡΠ½ΠΎ ΠΏΡΠΎΡΡΡΠΌ ΠΈ ΠΏΠΎΠ½ΡΡΠ½ΡΠΌ ΠΏΠΎ ΡΠΈΠ½ΡΠ°ΠΊΡΠΈΡΡ, ΠΎΠ΄Π½Π°ΠΊΠΎ, ΠΏΡΠΈ ΠΏΠΎΠΈΡΠΊΠ΅ ΡΡΠ°Π»ΠΊΠΈΠ²Π°Π»ΡΡ Ρ ΠΏΡΠΈΠΌΠ΅ΡΠ°ΠΌΠΈ Π½Π° Haskell ΠΈ Π½Π΅ ΠΏΠΎΠ½ΠΈΠΌΠ°Π», ΠΏΠΎΡΠ΅ΠΌΡ ΠΏΠ΅ΡΠ²ΡΠΉ ΡΠ°ΠΊ ΡΡΠ»ΠΎΠΆΠ½ΡΠ΅Ρ ΠΌΠ΅ΡΡΠ°ΠΌΠΈ.
Π― ΠΏΠΎΠ·Π½Π°ΠΊΠΎΠΌΠΈΠ»ΡΡ Ρ ΡΠ°ΠΊΠΈΠΌΠΈ ΡΡΠ½ΠΊΡΠΈΡΠΌΠΈ, ΠΊΠ°ΠΊ List.map
, List.filter
ΠΈ List.fold
, ΠΎΠ½ΠΈ ΡΠ΄Π΅Π»Π°Π»ΠΈ ΠΊΠΎΠ΄ Π±ΠΎΠ»Π΅Π΅ ΠΊΠΎΠΌΠΏΠ°ΠΊΡΠ½ΡΠΌ ΠΈ ΠΏΠΎΠ½ΡΡΠ½ΡΠΌ. ΠΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ ΡΡΠ½ΠΊΡΠΈΠΈ filter
Π΄Π»Ρ ΠΎΡΡΠ΅ΠΈΠ²Π°Π½ΠΈΡ Π½Π΅ΠΏΠΎΠ΄Ρ
ΠΎΠ΄ΡΡΠΈΡ
Π·Π½Π°ΡΠ΅Π½ΠΈΠΉ Π΄Π΅Π»Π°Π΅Ρ ΠΊΠΎΠ΄ Π±ΠΎΠ»Π΅Π΅ Π΄Π΅ΠΊΠ»Π°ΡΠ°ΡΠΈΠ²Π½ΡΠΌ.
Π’Π°ΠΊΠΆΠ΅ Ρ Π²ΠΎΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π»ΡΡ Π»Π΅Π½ΠΈΠ²ΡΠΌΠΈ ΠΊΠΎΠ»Π»Π΅ΠΊΡΠΈΡΠΌΠΈ (Seq
), Π΄Π»Ρ Π³Π΅Π½Π΅ΡΠ°ΡΠΈΠΈ Π±Π΅ΡΠΊΠΎΠ½Π΅ΡΠ½ΠΎΠ³ΠΎ ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²Π° ΡΡΠ΅ΡΠ³ΠΎΠ»ΡΠ½ΡΡ
ΡΠΈΡΠ΅Π», ΡΡΠΎ Π·Π° ΡΡΠ΅Ρ Π»Π΅Π½ΠΈ ΠΏΠΎΠ·Π²ΠΎΠ»ΠΈΠ»ΠΎ ΠΎΠ±ΡΠ°ΡΠΈΡΡΡΡ ΡΠΎΠ»ΡΠΊΠΎ ΠΊ Π½ΡΠΆΠ½ΠΎΠΌΡ ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²Ρ ΡΡΠ΅ΡΠ³ΠΎΠ»ΡΠ½ΡΡ
ΡΠΈΡΠ΅Π» ΠΈ Π½Π΅ Π½ΡΠΆΠ½ΠΎ Π±ΡΠ»ΠΎ ΠΏΡΠΈΠ΄ΡΠΌΡΠ²Π°ΡΡ, ΠΊΠ°ΠΊ ΡΠΎΠ·Π΄Π°Π²Π°ΡΡ ΡΠ»Π΅Π΄ΡΡΡΠ΅Π΅.
ΠΡΠΎΡΡΡ (p19) Π·Π°Π΄Π°ΡΡ ΠΏΠΎΠ»ΡΡΠΈΠ»ΠΎΡΡ ΡΠ΅ΡΠΈΡΡ Π±ΠΎΠ»Π΅Π΅ ΠΊΠ°ΡΠ΅ΡΡΠ²Π΅Π½Π½ΠΎ, Π½Π° ΠΌΠΎΠΉ Π²Π·Π³Π»ΡΠ΄, Π²Π΅ΡΠΎΡΡΠ½Π΅Π΅ Π²ΡΠ΅Π³ΠΎ Π±Π»Π°Π³ΠΎΠ΄Π°ΡΡ ΡΠΎΠΌΡ, ΡΡΠΎ ΡΠΆΠ΅ ΡΠ°Π·ΠΎΠ±ΡΠ°Π»ΡΡ Ρ ΡΠΈΠ½ΡΠ°ΠΊΡΠΈΡΠΎΠΌ ΠΈ ΠΏΠΎΠ΄Ρ ΠΎΠ΄Π°ΠΌ ΠΊ ΡΠ΅ΡΠ΅Π½ΠΈΡ Π·Π°Π΄Π°Ρ. Π’Π΅ΠΌ Π½Π΅ ΠΌΠ΅Π½Π΅Π΅, Π±ΡΠ»ΠΎ ΡΡΠΆΠ΅Π»ΠΎ ΠΏΡΠΈΠ΄ΡΠΌΡΠ²Π°ΡΡ ΡΠ°Π·Π»ΠΈΡΠ½ΡΠ΅ ΡΠΏΠΎΡΠΎΠ±Ρ ΡΠ΅ΡΠ΅Π½ΠΈΡ, ΠΏΠΎΡΠΊΠΎΠ»ΡΠΊΡ ΠΎΠ±ΡΡΠ½ΠΎ Π΄ΠΎΡΡΠ°ΡΠΎΡΠ½ΠΎ ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΡΠ΅ΡΠ΅Π½ΠΈΡ.
ΠΠ»Ρ Π·Π°ΠΏΡΡΠΊΠ° ΡΠ΅ΡΡΠΎΠ² Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ΠΌ OUnit2:
dune runtest
ΠΠ»Ρ ΡΠ±ΠΎΡΠΊΠΈ ΠΈ Π·Π°ΠΏΡΡΠΊΠ° ΠΏΡΠΎΠ΅ΠΊΡΠ° Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎ ΠΈΠΌΠ΅ΡΡ:
- OCaml >= 4.12.0
- Dune >= 2.0
- OUnit2
- ppx_inline_test