paizaオンラインハッカソン7に参加してみた – メイド服(C++, Swift)

注意: この記事は1年以上前に掲載されたものです。情報が古い場合がありますのでお気を付け下さい。

paizaオンラインハッカソン7に参加してみた – 猫(C++, Swift)に続いて、今回はC++及びSwiftでメイド服にチャレンジしてみたい。

今回のお題の目的

今回のお題は特定の時間に起きることを前提に、残業した時間に応じて睡眠時間を増やした時に、何時に寝ればいいのかを出力するというのが目的になっている。

今回では以下が使えるかが重要になってくる。

  • 時間型を使うかどうか
  • フォーマット書式を使うかどうか

サンプルコード

C++

cf: https://github.com/saitomarch/POH7/blob/master/cpp/maid.cpp

#include <iostream>
#include <cstdio>

using namespace std;

string readline() {
    string str;
    getline(cin, str);
    return str;
}

int main(void){
    auto days = stoi(readline());
    for (auto day = 0; day < days; day++) {
        const auto overworks = stoi(readline());
        const auto hour = 60;
        const auto day = 24;
        const auto minSleeps = 6 * hour;
        const auto requireToSleeps = (minSleeps * hour) + (overworks / 3);
        const auto wakeUp = 7;

        const auto hours = ((day + wakeUp - ((requireToSleeps / hour) + ((requireToSleeps % hour) == 0 ? 0 : 1))) % day);
        const auto minutes = (requireToSleeps % hour) == 0 ? 0 : (hour - (requireToSleeps % hour));

        printf("%02d:%02d\n", hours, minutes);
    }
    return 0;
}

Swift

サンプル1

注: このコードはPOHの環境では動作に必要となるフレームワークが欠けているため動きません。

cf: https://github.com/saitomarch/POH7/blob/master/swift/maid.swift

import Foundation
let days = Int(readLine()!)!
for day in 0..<days {
    let overworks = Int(readLine()!)!
    let hour = 60
    let dayHours = 24
    let minSleeps = 6 * hour
    let requireToSleeps = minSleeps + (overworks / 3)
    let wakeup = 7

    let hours = (dayHours + wakeup - ((requireToSleeps / hour) + ((requireToSleeps % hour) == 0 ? 0 : 1))) % dayHours
    let minutes = (requireToSleeps % hour) == 0 ? 0 : (hour - (requireToSleeps % hour))

    print(String(format: "%02d:%02d", hours, minutes))
}

サンプル2

cf https://github.com/saitomarch/POH7/blob/master/swift/maid_poh.swift

func datetimeFormat(hour: Int, _ minute: Int) -> String {
    var hourString = String(hour)
    var minuteString = String(minute)

    while (hourString.characters.count < 2) {
        hourString = "0" + hourString
    }
    while (minuteString.characters.count < 2) {
        minuteString = "0" + minuteString
    }
    return "\(hourString):\(minuteString)"
}

let days = Int(readLine()!)!
for day in 0..<days {
    let overworks = Int(readLine()!)!
    let hour = 60
    let dayHours = 24
    let minSleeps = 6 * hour
    let requireToSleeps = minSleeps + (overworks / 3)
    let wakeup = 7

    let hours = (dayHours + wakeup - ((requireToSleeps / hour) + ((requireToSleeps % hour) == 0 ? 0 : 1))) % dayHours
    let minutes = (requireToSleeps % hour) == 0 ? 0 : (hour - (requireToSleeps % hour))

    print(datetimeFormat(hours, minutes))
}

解説

今回はまず日数を取得、それをループの回数にした。

その後、残業した時間が分で入力されるため、それに応じて睡眠に必要な時間を計算する。基本的には睡眠に必要な時間は以下のようになる。

睡眠に必要な時間=(6時間)+(残業した時間÷3)

その後、7時に起きるということを想定して、寝る時間を計算した上で出力する。なお、この際、日付が変わった後の時間にする場合は0にリセットするという制約があるため、その点は要注意である。

なお、今回では、出力の仕方が若干変わっている。C++ではprintfが使えるため問題ないのだが、SwiftではPOHの環境ではFoundation Frameworkが使えないため、Objective-Cでいう+[NSString stringWithFormat:]に相当する処理が使えないため、独自に関数を指定して定義を行った。なお、Mac環境ではC++のようにフォーマットを使った解法ができるのだが・・・。

最後に

今回は言語によって比較的簡単に解けるかどうかが変わってくるかもしれない、今回の場合はSwiftでは使えるはずの命令が使えないという制約があり、それをどうやって克服するかがネックになったが、それができれば基本的には問題を読めば難なくクリアできるだろう。

ぜひともチャレンジしてみると良いだろう。

タイトルとURLをコピーしました