Created
November 5, 2019 08:54
-
-
Save gouf/35dfe2c4f84e0576b8e7327445b9c575 to your computer and use it in GitHub Desktop.
Paiza 練習問題 : [翌営業日 - その1](https://paiza.jp/works/mondai/dateset/working_day_1?language_uid=ruby)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require File.join(__dir__, 'lib', 'workdays') | |
# eg. 10 1 FRI | |
# => 10月4日 | |
workday = WorkDay.new(*gets.chomp.split) | |
month, day = workday.next_workday | |
puts "#{month}月#{day}日" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# frozen_string_literal: true | |
# 月, 日, 曜日から「翌営業日」を算出 | |
class WorkDay | |
WEEK = %w[SUN MON TUE WED THU FRI SAT] | |
WORK_DAY = %w[MON TUE WED THU FRI] | |
NON_WORK_DAY = %w[SUN SAT] | |
SHORT_MONTH = [2, 4, 6, 9, 11] # 30日終わりの月 (厳格さは求めないので2月も同じ扱いにする) | |
LONG_MONTH = [1, 3, 5, 7, 8, 10, 12] # 31日終わりの月 | |
private_constant :WEEK, :SHORT_MONTH, :LONG_MONTH, :WORK_DAY, :NON_WORK_DAY | |
def initialize(month, day, week) | |
@month = month.to_i | |
@day = day.to_i | |
@wday_index = WEEK.index(week) # WEEK 定数を modulo(WEEK.size) で参照するカウンタ | |
# 外部からの入力によって設定する値が決まるので インスタンス変数として定義 | |
@last_day_of_month = | |
if SHORT_MONTH.include?(@month) | |
30 | |
elsif LONG_MONTH.include?(@month) | |
31 | |
end | |
end | |
def next_workday | |
# 2月28日の次の日は必ず 3月1日扱いにする | |
if february_28? | |
@month = 3 | |
@day = 1 | |
@wday_index += 1 | |
return find_workday! | |
end | |
@day += 1 | |
@wday_index += 1 | |
find_workday! | |
end | |
private | |
def february_28? | |
[@month, @day].eql?([2, 28]) | |
end | |
def non_workday? | |
NON_WORK_DAY.include?(wday_index_as_string) | |
end | |
def workday? | |
WORK_DAY.include?(wday_index_as_string) | |
end | |
def wday_index_as_string | |
WEEK.at(@wday_index.modulo(WEEK.size)) | |
end | |
# 「日」加算時、「3月32日」のような値になってないか検査 | |
def day_out_of_bounce? | |
@day > @last_day_of_month | |
end | |
# 「12月32日」のような値になっていれば「1月1日」と翌月に変換する | |
def adjust_day_month_bounce! | |
return [@month, @day] unless day_out_of_bounce? | |
@month += 1 | |
@day = 1 | |
if @month > 12 | |
@month = 1 | |
end | |
[@month, @day] | |
end | |
# 月日 (@month, @day) が営業日になるまで日を進めて探す | |
def find_workday! | |
adjust_day_month_bounce! | |
loop do | |
break adjust_day_month_bounce! if workday? | |
@wday_index += 1 | |
@day += 1 | |
adjust_day_month_bounce! | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# frozen_string_literal: true | |
describe WorkDay do | |
context '#next_workday' do | |
subject { WorkDay.new(month, day, week).next_workday } | |
shared_examples 'next_workday' do | |
it { is_expected.to eq expected } | |
end | |
context '2月28日(水)' do | |
it_behaves_like 'next_workday' do | |
let(:month) { 2 } | |
let(:day) { 28 } | |
let(:week) { 'WED' } | |
let(:expected) { [3, 1] } | |
end | |
end | |
context '2月28日(金)' do | |
it_behaves_like 'next_workday' do | |
let(:month) { 2 } | |
let(:day) { 28 } | |
let(:week) { 'FRI' } | |
let(:expected) { [3, 3] } | |
end | |
end | |
context '2月28日(土)' do | |
it_behaves_like 'next_workday' do | |
let(:month) { 2 } | |
let(:day) { 28 } | |
let(:week) { 'SAT' } | |
let(:expected) { [3, 2] } | |
end | |
end | |
context '3月4日(金)' do | |
it_behaves_like 'next_workday' do | |
let(:month) { 3 } | |
let(:day) { 4 } | |
let(:week) { 'FRI' } | |
let(:expected) { [3, 7] } | |
end | |
end | |
context '3月31日(金)' do | |
it_behaves_like 'next_workday' do | |
let(:month) { 3 } | |
let(:day) { 31 } | |
let(:week) { 'FRI' } | |
let(:expected) { [4, 3] } | |
end | |
end | |
context '7月7日(土)' do | |
it_behaves_like 'next_workday' do | |
let(:month) { 7 } | |
let(:day) { 7 } | |
let(:week) { 'SAT' } | |
let(:expected) { [7, 9] } | |
end | |
end | |
context '8月9日(日)' do | |
it_behaves_like 'next_workday' do | |
let(:month) { 8 } | |
let(:day) { 9 } | |
let(:week) { 'SUN' } | |
let(:expected) { [8, 10] } | |
end | |
end | |
context '12月31日(土)' do | |
it_behaves_like 'next_workday' do | |
let(:month) { 12 } | |
let(:day) { 31 } | |
let(:week) { 'SAT' } | |
let(:expected) { [1, 2] } | |
end | |
end | |
context '12月31日(日)' do | |
it_behaves_like 'next_workday' do | |
let(:month) { 12 } | |
let(:day) { 31 } | |
let(:week) { 'SUN' } | |
let(:expected) { [1, 1] } | |
end | |
end | |
context '12月31日(月)' do | |
it_behaves_like 'next_workday' do | |
let(:month) { 12 } | |
let(:day) { 31 } | |
let(:week) { 'MON' } | |
let(:expected) { [1, 1] } | |
end | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment