{ }codelper
stepping loopsternary operatorpaddingP0126

Multi-month calendar

Write a program that prints several months of a calendar one after another. The first line gives the number of months k and the weekday w of day 1 of the first month. Weekdays are 0 for Sunday, 1 for Monday, 2 for Tuesday, 3 for Wednesday, 4 for Thursday, 5 for Friday and 6 for Saturday. The second line gives the number of days of each month, k numbers in order. Day 1 of the next month falls on the weekday after the last day of the previous month. For each month print one week per line, and a line has seven cells from Sunday to Saturday. The first line is the week containing day 1, and the last line is the week containing the last day. A cell is two characters wide, and the date is right-aligned (a one-digit date gets one space in front). Cells before day 1 are filled with two spaces. Put one space between cells. Trailing spaces are not judged, so you may print the cells after the last day or leave them out. Print one blank line between months.

Input
1 ≤ k ≤ 12, 0 ≤ w ≤ 6, each month has 28 to 31 days
Output
4–6 lines per month, one blank line between months
Example 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
Input (stdin)

When you run, these lines are fed to input()/stdin in order (the program doesn't stop to ask).

$ Ready

Open this on a computer to write and run code. On mobile you can read the problem and the solutions.

In other languagesShow solutions by language · 8 languages

If you step the Sunday date of each week from 1 - w by 7 (0 or less means a cell of the previous month), you never need to count the rows separately.
Stepping by 7: Python range(1 - w, n + 1, 7) (the end n + 1 is excluded), C family, JS and TS for (s = 1 - w; s <= n; s += 7), Craykon for (s = 1 - w; s <= n; s += 7).
Three common traps: in Python, ending the range at n drops the last week when day n is a Sunday.
Counting rows as (w + n) / 7 + 1 adds an extra empty line for a month that ends exactly on Saturday.
The next month's weekday is (w + n) % 7 (w + n - 1 is the weekday of the last day).
Filling a cell is one ternary: Python f"{d:2d}" if 1 <= d <= n else " " (condition in the middle), the rest cond ? a : b.
Right-aligning: Python f"{d:2d}", JS/TS String(d).padStart(2) (padEnd left-aligns, which is wrong), Java String.format("%2d", d), C# d.ToString().PadLeft(2), C printf("%2d"), C++ std::setw(2), Craykon ("" + d).PadLeft(2).

Pythonmain.py · 12 lines
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 lines
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 lines
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 lines
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 lines
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 lines
#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 lines
#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 lines
kw = Console.ReadNumbers();k = kw[0];w = kw[1];lengths = Console.ReadNumbers();for (m = 0; m < k; m++){    n = lengths[m];    if (m > 0)    {        Console.WriteLine("");    }    // 한 주의 일요일 날짜: 1 - w부터 7씩 건너뛴다(0 이하면 지난달 칸)    for (start = 1 - w; start <= n; start += 7)    {        cells = [];        for (d = start; d < start + 7; d++)        {            cells.Add(d >= 1 && d <= n ? ("" + d).PadLeft(2) : "  ");        }        Console.WriteLine(cells.Join(" "));    }    w = (w + n) % 7; // 다음 달 1일의 요일}