{ }codelper
건너뛰며 반복삼항 연산자자리 맞추기P0126

여러 달 달력 찍기

달력 여러 달을 이어서 출력하는 프로그램을 만든다. 첫 줄에 달의 수 k와 첫째 달 1일의 요일 w가 주어진다. 요일은 0이 일요일, 1이 월요일, 2가 화요일, 3이 수요일, 4가 목요일, 5가 금요일, 6이 토요일이다. 둘째 줄에 달마다 날 수 k개가 차례로 주어진다. 다음 달의 1일은 앞 달 마지막 날의 다음 요일이다. 달마다 한 주를 한 줄에 출력하고, 한 줄은 일요일부터 토요일까지 일곱 칸이다. 첫 줄은 1일이 든 주, 마지막 줄은 마지막 날이 든 주다. 칸은 두 글자 너비이고, 날짜는 오른쪽에 맞춘다(한 자리 날짜는 앞에 빈칸 하나). 1일 앞의 칸은 빈칸 두 개로 채운다. 칸과 칸 사이에는 빈칸 하나를 둔다. 줄 끝의 빈칸은 채점하지 않으므로, 마지막 날 뒤의 칸은 찍어도 되고 안 찍어도 된다. 달과 달 사이에는 빈 줄 하나를 출력한다.

입력
1 ≤ k ≤ 12, 0 ≤ w ≤ 6, 날 수는 28 이상 31 이하
출력
달마다 4~6줄, 달 사이에 빈 줄 하나
예시 1 · stdin
2 3
30 31
stdout
          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

                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
main.py
입력(stdin)

실행하면 이 줄들이 차례로 input()·표준 입력으로 들어가요(실행 중에 묻지 않아요).

$ 준비됐어요

코드를 입력해 풀려면 PC에서 열어 주세요. 모바일에서는 문제와 풀이를 볼 수 있어요.

다른 언어로는?언어별 풀이 보기 · 8개 언어 풀이

주마다 일요일 날짜를 1 - w부터 7씩 건너뛰면(0 이하는 지난달 칸) 몇 줄인지 따로 셀 필요가 없어요.
7씩 건너뛰는 반복: Python range(1 - w, n + 1, 7)(끝 n + 1은 들어가지 않음), C 계열·JS·TS for (s = 1 - w; s <= n; s += 7), 크레이콘 반복 (s = 1 - w; s <= n; s += 7).
흔한 함정 셋: Python에서 끝을 n으로 쓰면 n일이 일요일인 마지막 주가 빠져요.
줄 수를 (w + n) / 7 + 1로 세면 토요일에 꽉 차게 끝나는 달에 빈 줄이 하나 더 생겨요.
다음 달 요일은 (w + n) % 7이에요(w + n - 1은 마지막 날의 요일).
칸 채우기는 삼항 연산자 한 줄이에요: Python f"{d:2d}" if 1 <= d <= n else " "(조건이 가운데), 나머지 조건 ? 값 : 값.
오른쪽 맞춤: Python f"{d:2d}", JS·TS String(d).padStart(2)(padEnd는 왼쪽 맞춤이라 틀려요), Java String.format("%2d", d), C# d.ToString().PadLeft(2), C printf("%2d"), C++ std::setw(2), 크레이콘 ("" + d).앞채우기(2).

Pythonmain.py · 12 줄
k, w = map(int, input().split())lengths = list(map(int, input().split()))months = []for n in lengths:    lines = []    # 한 주의 일요일 날짜: 1 - w부터 7씩 건너뛴다(0 이하면 지난달 칸)    for start in range(1 - w, n + 1, 7):        cells = [f"{d:2d}" if 1 <= d <= n else "  " for d in range(start, start + 7)]        lines.append(" ".join(cells).rstrip())    months.append("\n".join(lines))    w = (w + n) % 7  # 다음 달 1일의 요일print("\n\n".join(months))
JavaScriptmain.js · 15 줄
const [, first, ...lengths] = require("fs").readFileSync(0, "utf8").trim().split(/\s+/).map(Number);let w = first;const months = [];for (const n of lengths) {  const lines = [];  // 한 주의 일요일 날짜: 1 - w부터 7씩 건너뛴다(0 이하면 지난달 칸)  for (let start = 1 - w; start <= n; start += 7) {    const cells = [];    for (let d = start; d < start + 7; d++) cells.push(d >= 1 && d <= n ? String(d).padStart(2) : "  ");    lines.push(cells.join(" ").trimEnd());  }  months.push(lines.join("\n"));  w = (w + n) % 7; // 다음 달 1일의 요일}console.log(months.join("\n\n"));
TypeScriptmain.ts · 16 줄
import { readFileSync } from "node:fs";const [, first, ...lengths]: number[] = readFileSync(0, "utf8").trim().split(/\s+/).map(Number);let w: number = first;const months: string[] = [];for (const n of lengths) {  const lines: string[] = [];  // 한 주의 일요일 날짜: 1 - w부터 7씩 건너뛴다(0 이하면 지난달 칸)  for (let start = 1 - w; start <= n; start += 7) {    const cells: string[] = [];    for (let d = start; d < start + 7; d++) cells.push(d >= 1 && d <= n ? String(d).padStart(2) : "  ");    lines.push(cells.join(" ").trimEnd());  }  months.push(lines.join("\n"));  w = (w + n) % 7; // 다음 달 1일의 요일}console.log(months.join("\n\n"));
JavaMain.java · 25 줄
import java.util.Scanner; public class Main {    public static void main(String[] args) {        Scanner sc = new Scanner(System.in);        int k = sc.nextInt();        int w = sc.nextInt();        StringBuilder out = new StringBuilder();        for (int m = 0; m < k; m++) {            int n = sc.nextInt();            if (m > 0) out.append('\n');            // 한 주의 일요일 날짜: 1 - w부터 7씩 건너뛴다(0 이하면 지난달 칸)            for (int start = 1 - w; start <= n; start += 7) {                StringBuilder line = new StringBuilder();                for (int d = start; d < start + 7; d++) {                    if (d > start) line.append(' ');                    line.append(d >= 1 && d <= n ? String.format("%2d", d) : "  ");                }                out.append(line.toString().stripTrailing()).append('\n');            }            w = (w + n) % 7; // 다음 달 1일의 요일        }        System.out.print(out);    }}
C#Main.cs · 30 줄
using System;using System.Collections.Generic;using System.Text; class Program{    static void Main()    {        string[] first = Console.ReadLine().Split(' ', StringSplitOptions.RemoveEmptyEntries);        int w = int.Parse(first[1]);        string[] lengths = Console.ReadLine().Split(' ', StringSplitOptions.RemoveEmptyEntries);        var months = new List<string>();        foreach (string s in lengths)        {            int n = int.Parse(s);            var lines = new List<string>();            // 한 주의 일요일 날짜: 1 - w부터 7씩 건너뛴다(0 이하면 지난달 칸)            for (int start = 1 - w; start <= n; start += 7)            {                var cells = new List<string>();                for (int d = start; d < start + 7; d++)                    cells.Add(d >= 1 && d <= n ? d.ToString().PadLeft(2) : "  ");                lines.Add(string.Join(" ", cells).TrimEnd());            }            months.Add(string.Join("\n", lines));            w = (w + n) % 7; // 다음 달 1일의 요일        }        Console.WriteLine(string.Join("\n\n", months));    }}
C++main.cpp · 23 줄
#include <iomanip>#include <iostream>#include <string> int main() {    int k, w;    std::cin >> k >> w;    for (int m = 0; m < k; m++) {        int n;        std::cin >> n;        if (m > 0) std::cout << '\n';        // 한 주의 일요일 날짜: 1 - w부터 7씩 건너뛴다(0 이하면 지난달 칸)        for (int start = 1 - w; start <= n; start += 7) {            for (int d = start; d < start + 7 && d <= n; d++) {                if (d > start) std::cout << ' ';                if (d >= 1) std::cout << std::setw(2) << d;                else std::cout << "  ";            }            std::cout << '\n';        }        w = (w + n) % 7; // 다음 달 1일의 요일    }}
Cmain.c · 23 줄
#include <stdio.h> int main(void) {    int k, w;    scanf("%d %d", &k, &w);    for (int m = 0; m < k; m++) {        int n;        scanf("%d", &n);        if (m > 0) putchar('\n');        // 한 주의 일요일 날짜: 1 - w부터 7씩 건너뛴다(0 이하면 지난달 칸)        for (int start = 1 - w; start <= n; start += 7) {            // 마지막 날 뒤 칸은 줄 끝 빈칸이라 찍지 않는다            for (int d = start; d < start + 7 && d <= n; d++) {                if (d > start) putchar(' ');                if (d >= 1) printf("%2d", d);                else printf("  ");            }            putchar('\n');        }        w = (w + n) % 7; // 다음 달 1일의 요일    }    return 0;}
Craykonmain.cray · 23 줄
kw = 콘솔.수들읽기();k = kw[0];w = kw[1];lengths = 콘솔.수들읽기();반복 (m = 0; m < k; m++){    n = lengths[m];    만약 (m > 0)    {        콘솔.쓰기("");    }    // 한 주의 일요일 날짜: 1 - w부터 7씩 건너뛴다(0 이하면 지난달 칸)    반복 (start = 1 - w; start <= n; start += 7)    {        cells = [];        반복 (d = start; d < start + 7; d++)        {            cells.넣기(d >= 1 && d <= n ? ("" + d).앞채우기(2) : "  ");        }        콘솔.쓰기(cells.잇기(" "));    }    w = (w + n) % 7; // 다음 달 1일의 요일}