週ごとの日曜の日付を 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)、Craykon 繰り返す (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)、Craykon ("" + 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일의 요일}