{ }codelper
比較論理演算子P0169

満年齢で決める入場料

遊園地が、客の満年齢で入場料を決める。
一行目に今日の日付、二行目に客の数 n、続く n 行に客ごとの生年月日が与えられる。
日付はすべて YYYY-MM-DD の形(月と日は二桁)で、生年月日は今日より後ではない。
満年齢は(今日の年 - 生まれた年)から、今年の誕生日がまだ来ていなければ 1 を引いたものである。
今年の誕生日がまだ来ていないとは、今日の月が生まれた月より前か、二つの月が同じで今日の日が生まれた日より前であることをいう。
この規則どおりにすると、2 月 29 日生まれの人は平年には 3 月 1 日に一つ年をとる。
入場料は、満年齢が 2 歳以下なら 0 ウォン、3〜12 歳なら 6,000 ウォン、13〜18 歳なら 9,000 ウォン、19〜64 歳なら 15,000 ウォン、65 歳以上なら 7,000 ウォンである。
ただし今日の月と日が生まれた日の月と日の両方と同じなら、つまり今日が誕生日なら、年齢に関係なく 0 ウォンである。
客ごとに一行に、満年齢と入場料を空白一つで区切って入力の順に出力せよ。
最後の行に入場料の合計を出力せよ。

入力
1900-01-01 ≤ 生年月日 ≤ 今日 ≤ 2100-12-31、1 ≤ n ≤ 1,000、日付はすべて暦にある日
出力
客ごとに一行(満年齢、入場料)、最後の行に入場料の合計
例 1 · stdin
2025-10-01
6
2015-09-30
2015-10-02
2007-10-01
2004-02-29
1960-12-31
2023-01-15
stdout
10 6000
9 6000
18 0
21 15000
64 15000
2 0
42000
例 2 · stdin
2023-02-28
3
2004-02-29
1958-02-28
2010-03-01
stdout
18 9000
65 0
12 6000
15000
main.py
入力(stdin)

実行すると、これらの行が順に input()・標準入力に渡されます(実行中に入力を求めません)。

$ 準備完了

コードを入力して解くにはパソコンで開いてください。モバイルでは問題と解答を見られます。

ほかの言語では?言語別の解答を見る · 8 言語の解答

「誕生日が過ぎたか」を聞く比較がこの問題のすべてです。
よくある間違いは、月と日を別々に聞く tm >= bm && td >= bd です。
5 月 3 日に 4 月 20 日生まれの人を見ると、月は過ぎているのに日(3 < 20)のせいでまだ誕生日前だと出ます。
正しい条件は「月が前か、月が同じで日が前」で、七つの言語は tm < bm || (tm == bm && td < bd)、Python は tm < bm or (tm == bm and td < bd) です(Craykon も ||・&& です)。
Python のタプル (tm, td) < (bm, bd) と C++ の std::tie(tm, td) < std::tie(bm, bd) は先頭の要素から順に比べるので、この条件を一度に書けます。
JS・TS の配列にはこのような比較はありません。
[tm, td] < [bm, bd] は二つの配列を文字列 "10,1" と "9,30" に変えて辞書順で比べるので、10 月 1 日が 9 月 30 日より前だと出ます(TS はこの式を止めません)。
Java・C# のタプルや配列にも < はないので、要素ごとに比べるか、月 × 100 + 日のような一つの数にして比べます。
日付の文字列 "MM-DD" どうしを比べても、月と日が二桁なので辞書順がそのまま日付の順になります。
Python・JS・TS・Craykon は <、Java は compareTo、C# は string.CompareOrdinal、C++ の std::string は < で比べられます。
しかし C で char 配列どうしを < で比べると、内容ではなくメモリのアドレスを比べるので、strcmp を使う必要があります。

Pythonmain.py · 31 行
def parse(s):    y, m, d = map(int, s.split("-"))    return y, m, d  def price(age):    if age <= 2:        return 0    elif age <= 12:        return 6000    elif age <= 18:        return 9000    elif age <= 64:        return 15000    else:        return 7000  ty, tm, td = parse(input().strip())n = int(input())total = 0for _ in range(n):    by, bm, bd = parse(input().strip())    age = ty - by    # 튜플은 앞 칸부터 차례로 비교한다: 월이 같을 때만 일을 본다    if (tm, td) < (bm, bd):        age -= 1    fee = 0 if (tm, td) == (bm, bd) else price(age)  # 생일 당일은 무료    print(age, fee)    total += feeprint(total)
JavaScriptmain.js · 24 行
const lines = require("fs").readFileSync(0, "utf8").split("\n");const parse = (s) => s.trim().split("-").map(Number);const price = (age) => {  if (age <= 2) return 0;  else if (age <= 12) return 6000;  else if (age <= 18) return 9000;  else if (age <= 64) return 15000;  else return 7000;};const [ty, tm, td] = parse(lines[0]);const n = Number(lines[1]);const out = [];let total = 0;for (let i = 0; i < n; i++) {  const [by, bm, bd] = parse(lines[2 + i]);  // 배열끼리 <로 비교하면 문자열 "10,1" < "9,30"으로 비교된다 → 칸마다 직접 비교한다  const beforeBirthday = tm < bm || (tm === bm && td < bd);  const age = ty - by - (beforeBirthday ? 1 : 0);  const fee = tm === bm && td === bd ? 0 : price(age); // 생일 당일은 무료  out.push(`${age} ${fee}`);  total += fee;}out.push(String(total));console.log(out.join("\n"));
TypeScriptmain.ts · 25 行
import { readFileSync } from "node:fs";const lines: string[] = readFileSync(0, "utf8").split("\n");const parse = (s: string): number[] => s.trim().split("-").map(Number);const price = (age: number): number => {  if (age <= 2) return 0;  else if (age <= 12) return 6000;  else if (age <= 18) return 9000;  else if (age <= 64) return 15000;  else return 7000;};const [ty, tm, td] = parse(lines[0]);const n = Number(lines[1]);const out: string[] = [];let total = 0;for (let i = 0; i < n; i++) {  const [by, bm, bd] = parse(lines[2 + i]);  // 배열끼리 <로 비교하면 문자열 "10,1" < "9,30"으로 비교된다 → 칸마다 직접 비교한다  const beforeBirthday = tm < bm || (tm === bm && td < bd);  const age = ty - by - (beforeBirthday ? 1 : 0);  const fee = tm === bm && td === bd ? 0 : price(age); // 생일 당일은 무료  out.push(`${age} ${fee}`);  total += fee;}out.push(String(total));console.log(out.join("\n"));
JavaMain.java · 36 行
import java.io.BufferedReader;import java.io.InputStreamReader; public class Main {    static int[] parse(String s) {        String[] p = s.trim().split("-");        return new int[] {Integer.parseInt(p[0]), Integer.parseInt(p[1]), Integer.parseInt(p[2])};    }     static int price(int age) {        if (age <= 2) return 0;        else if (age <= 12) return 6000;        else if (age <= 18) return 9000;        else if (age <= 64) return 15000;        else return 7000;    }     public static void main(String[] args) throws Exception {        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));        int[] t = parse(in.readLine());        int n = Integer.parseInt(in.readLine().trim());        StringBuilder out = new StringBuilder();        long total = 0;        for (int i = 0; i < n; i++) {            int[] b = parse(in.readLine());            // 월이 앞서거나, 월이 같고 일이 앞서면 아직 생일 전이다            boolean beforeBirthday = t[1] < b[1] || (t[1] == b[1] && t[2] < b[2]);            int age = t[0] - b[0] - (beforeBirthday ? 1 : 0);            int fee = (t[1] == b[1] && t[2] == b[2]) ? 0 : price(age); // 생일 당일은 무료            out.append(age).append(' ').append(fee).append('\n');            total += fee;        }        out.append(total).append('\n');        System.out.print(out);    }}
C#Main.cs · 35 行
using System;using System.Linq;using System.Text; class Program{    static int Price(int age)    {        if (age <= 2) return 0;        else if (age <= 12) return 6000;        else if (age <= 18) return 9000;        else if (age <= 64) return 15000;        else return 7000;    }     static void Main()    {        int[] t = Console.ReadLine().Trim().Split('-').Select(int.Parse).ToArray();        int n = int.Parse(Console.ReadLine());        var sb = new StringBuilder();        long total = 0;        for (int i = 0; i < n; i++)        {            int[] b = Console.ReadLine().Trim().Split('-').Select(int.Parse).ToArray();            // 튜플은 앞 칸부터 비교하지만 C#의 튜플에는 <가 없다 → 칸마다 직접 비교한다            bool beforeBirthday = t[1] < b[1] || (t[1] == b[1] && t[2] < b[2]);            int age = t[0] - b[0] - (beforeBirthday ? 1 : 0);            int fee = (t[1] == b[1] && t[2] == b[2]) ? 0 : Price(age); // 생일 당일은 무료            sb.Append(age).Append(' ').Append(fee).Append('\n');            total += fee;        }        sb.Append(total).Append('\n');        Console.Write(sb);    }}
C++main.cpp · 29 行
#include <iostream>#include <string>#include <tuple> int price(int age) {    if (age <= 2) return 0;    else if (age <= 12) return 6000;    else if (age <= 18) return 9000;    else if (age <= 64) return 15000;    else return 7000;} int main() {    char dash;    int ty, tm, td, n;    std::cin >> ty >> dash >> tm >> dash >> td >> n;    long long total = 0;    for (int i = 0; i < n; i++) {        int by, bm, bd;        std::cin >> by >> dash >> bm >> dash >> bd;        // std::tie로 묶으면 튜플처럼 앞 칸부터 차례로 비교한다        bool beforeBirthday = std::tie(tm, td) < std::tie(bm, bd);        int age = ty - by - (beforeBirthday ? 1 : 0);        int fee = (tm == bm && td == bd) ? 0 : price(age); // 생일 당일은 무료        std::cout << age << ' ' << fee << '\n';        total += fee;    }    std::cout << total << '\n';}
Cmain.c · 28 行
#include <stdio.h> int price(int age) {    if (age <= 2) return 0;    else if (age <= 12) return 6000;    else if (age <= 18) return 9000;    else if (age <= 64) return 15000;    else return 7000;} int main(void) {    int ty, tm, td, n;    scanf("%d-%d-%d", &ty, &tm, &td);    scanf("%d", &n);    long total = 0;    for (int i = 0; i < n; i++) {        int by, bm, bd;        scanf("%d-%d-%d", &by, &bm, &bd);        /* 월이 앞서거나, 월이 같고 일이 앞서면 아직 생일 전이다 */        int before_birthday = tm < bm || (tm == bm && td < bd);        int age = ty - by - (before_birthday ? 1 : 0);        int fee = (tm == bm && td == bd) ? 0 : price(age); /* 생일 당일은 무료 */        printf("%d %d\n", age, fee);        total += fee;    }    printf("%ld\n", total);    return 0;}
Craykonmain.cray · 48 行
날짜(줄){    칸 = 줄.空白除去().分ける("-");    返す [칸[0].数に(), 칸[1].数に(), 칸[2].数に()];} 요금(age){    もし (age <= 2)    {        返す 0;    }    でなければ もし (age <= 12)    {        返す 6000;    }    でなければ もし (age <= 18)    {        返す 9000;    }    でなければ もし (age <= 64)    {        返す 15000;    }    返す 7000;} t = 날짜(コンソール.行読み());n = コンソール.行読み().数に();total = 0;繰り返す (i = 0; i < n; i++){    b = 날짜(コンソール.行読み());    age = t[0] - b[0];    // 월이 앞서거나, 월이 같고 일이 앞서면 아직 생일 전이다    もし (t[1] < b[1] || t[1] == b[1] && t[2] < b[2])    {        age -= 1;    }    fee = 요금(age);    もし (t[1] == b[1] && t[2] == b[2])    {        fee = 0; // 생일 당일은 무료    }    コンソール.書く(age + " " + fee);    total += fee;}コンソール.書く(total);