Hackerrank – Popis problému
Celý popis zadania sa nacháza – Hackerrank.
Riešenie
Zo zadaného dátumu som si zistil, kedy je najbližšia nedeľa. Potom som zvyšoval dni o 7, aby som dostal nasledujúcu nedeľu. Tu si treba dať pozor na prípady, keď vyjde napr. nedeľa na 25. v mesiaci (napr. marec). Ďalšia by vyšla 32., čo samozrejme nie je platný dátum. Tento dátum je nutné preložiť na najnižší možný dátum nedele nasledujúceho mesiaca (v našom príklade by to bolo 1. apríla). A takto pokračujem až, kým neprekročím horné ohraničenie dátumu
Všetky riešenia sú dostupné aj na mojom GitHub profile.
Ruby
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 |
require 'date' def create_next_start_month(year, month, day) if day != 1 day = 1 if month == 12 month = 1 year += 1 else month += 1 end end return Date.new(year, month, day) end def valid_date?(year, month, day) return false if month > 12 max_days = month_days(year, month) return false if day > max_days return true end def month_days(year, month) case month when 1, 3, 5, 7, 8, 10, 12 return 31 when 4, 6, 9, 11 return 30 else if is_leap(year) return 29 else return 28 end end end def is_leap(year) return year % 400 == 0 if year % 100 == 0 return year % 4 == 0 end def create_valid_date(year, month, day) new_day = nil new_month = nil new_year = year if month > 12 new_month = month - 12 new_year += 1 else new_month = month end max_days = month_days(new_year, new_month) new_day = day if(max_days < new_day) new_day = new_day - max_days new_month = new_month + 1 end if(new_month > 12) new_month = new_month - 12 new_year += 1 end return new_year, new_month, new_day end def count_sundays(date_from, date_to) n = 1 sundays = 0 temp_date = Date.new(date_from.year, date_from.mon, date_from.day) while (temp_date <=> date_to) <= 0 sundays += 1 if temp_date.wday == 0 temp_date = date_from >> n n += 1 end return sundays end gets.chomp.to_i.times do (year, month, day) = gets.chomp.split.map{ |e| e.to_i } if valid_date?(year, month, day) date_from = create_next_start_month(year, month, day) else (year, month, day) = create_valid_date(year, month, day) date_from = create_next_start_month(year, month, day) end (year, month, day) = gets.chomp.split.map{ |e| e.to_i } if valid_date?(year, month, day) date_to = Date.new(year, month, day) else (year, month, day) = create_valid_date(year, month, day) date_to = Date.new(year, month, day) end puts count_sundays(date_from, date_to) end |