An old mechanical counter has n wheels in a row.
The i-th wheel from the left has positions 0 to b_i - 1 and now shows position d_i.
Turning the counter forward by one step increases the rightmost wheel by 1.
When a wheel goes one step past b_i - 1 it returns to 0, and the wheel to its left increases by 1.
When the leftmost wheel goes from b_1 - 1 back to 0, the whole counter has wrapped forward once.
Turning backward by one step works the other way: the rightmost wheel decreases by 1, and a wheel that goes one step below 0 becomes b_i - 1 while the wheel to its left decreases by 1.
When the leftmost wheel goes from 0 to b_1 - 1, the whole counter has wrapped backward once.
If t is positive, turn forward t steps; if t is negative, turn backward -t steps; if t is 0, do not turn.
The first line gives n, the second line b_1 … b_n, the third line d_1 … d_n, and the fourth line t.
Numbers on the same line are separated by single spaces.
On the first line, print the positions of the wheels after turning, from the left wheel, separated by single spaces.
On the second line, print how many times the whole counter wrapped. Print the count if it wrapped forward, the count with a minus sign if it wrapped backward, and 0 if it did not wrap.
First line: the positions of the n wheels; second line: the number of wraps (negative if backward)
Example 1 · stdin
3
24 60 60
23 59 50
15
stdout
0 0 5
1
Example 2 · stdin
2
7 3
0 1
-5
stdout
5 2
-1
main.py
Error List00F8 ↓ · ⇧F8 ↑
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
Starting from the rightmost wheel, split the incoming value s = d + (value passed in) into the position s mod b and the quotient passed to the left. Turning backward makes s negative, and that is where % and / differ between languages. Python's % and // are floor division, so the position is always 0 to b-1 and the quotient is rounded down (-4 // 3 == -2), which is exactly right. In C, C++, Java, C#, JS, TS and Craykon, % takes the sign of the dividend (-4 % 3 == -1), and integer / in C, C++, Java and C#, JS/TS Math.trunc(s / b) and Craykon Mathf.Quot truncate toward zero (-4 / 3 == -1), so the position goes negative and one borrow goes missing. In JS, TS and Craykon / keeps the fraction (-4 / 3 == -1.333…), so it cannot be used as the quotient directly. Fix the position with (s % b + b) % b and then get the quotient as (s - position) / b (it divides exactly), or in Java use Math.floorMod and Math.floorDiv. Fixing only the position and leaving the quotient as a truncating division is a common mistake too. The second trap is size. t goes up to 10^12, so C/C++ need long long and Java/C# need long; an int overflows. Numbers in JS, TS and Craykon are exact up to 2^53 (about 9×10^15), so t itself is fine. But if you turn the whole counter into one number, the product of the wheel sizes reaches 60^10 (about 6×10^17), past 2^53, and the low digits come out wrong. Passing the quotient wheel by wheel keeps every value near t in any language. Python int(s / b) also truncates toward zero after a float division, so it is the same trap.
Pythonmain.py · 14 lines
n = int(input())b = list(map(int, input().split()))d = list(map(int, input().split()))t = int(input())# 오른쪽 바퀴부터: 이 바퀴에 들어온 값 s를 칸(나머지)과 왼쪽으로 넘길 값(몫)으로 나눈다# Python의 %와 //는 내림 나눗셈이라 s가 음수여도 칸은 0 ~ b-1, 몫은 아래로 내린 값이다carry = tfor i in range(n - 1, -1, -1): s = d[i] + carry d[i] = s % b[i] carry = s // b[i]print(*d)print(carry) # 맨 왼쪽 바퀴에서도 넘친 값 = 계수기 전체가 넘어간 횟수
JavaScriptmain.js · 13 lines
const lines = require("fs").readFileSync(0, "utf8").split("\n");const n = Number(lines[0]);const b = lines[1].trim().split(/\s+/).map(Number);const d = lines[2].trim().split(/\s+/).map(Number);let carry = Number(lines[3]); // 10^12는 2^53 안이라 Number로 정확하다// JS의 %는 나누어지는 수의 부호를 따른다(-7 % 3 === -1) → b를 더해 다시 나눈다for (let i = n - 1; i >= 0; i--) { const s = d[i] + carry; d[i] = ((s % b[i]) + b[i]) % b[i]; carry = (s - d[i]) / b[i]; // s - 칸은 b로 딱 나누어떨어진다: 내림 몫}console.log(d.join(" ") + "\n" + carry);
TypeScriptmain.ts · 14 lines
import { readFileSync } from "node:fs";const lines: string[] = readFileSync(0, "utf8").split("\n");const n: number = Number(lines[0]);const b: number[] = lines[1].trim().split(/\s+/).map(Number);const d: number[] = lines[2].trim().split(/\s+/).map(Number);let carry: number = Number(lines[3]); // 10^12는 2^53 안이라 number로 정확하다// TS(JS)의 %는 나누어지는 수의 부호를 따른다(-7 % 3 === -1) → b를 더해 다시 나눈다for (let i = n - 1; i >= 0; i--) { const s: number = d[i] + carry; d[i] = ((s % b[i]) + b[i]) % b[i]; carry = (s - d[i]) / b[i]; // s - 칸은 b로 딱 나누어떨어진다: 내림 몫}console.log(d.join(" ") + "\n" + carry);
JavaMain.java · 24 lines
import java.util.Scanner;public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); int[] b = new int[n]; long[] d = new long[n]; for (int i = 0; i < n; i++) b[i] = sc.nextInt(); for (int i = 0; i < n; i++) d[i] = sc.nextLong(); long carry = sc.nextLong(); // 10^12: int로는 넘친다 // Java의 %와 /는 0 쪽으로 버린다(-7 % 3 == -1) → Math.floorMod·floorDiv는 내림으로 나눈다 for (int i = n - 1; i >= 0; i--) { long s = d[i] + carry; d[i] = Math.floorMod(s, (long) b[i]); carry = Math.floorDiv(s, (long) b[i]); } StringBuilder out = new StringBuilder(); for (int i = 0; i < n; i++) out.append(i > 0 ? " " : "").append(d[i]); out.append('\n').append(carry).append('\n'); System.out.print(out); }}
C#Main.cs · 23 lines
using System;using System.Linq;class Program{ static void Main() { int n = int.Parse(Console.ReadLine()); int[] b = Console.ReadLine().Split(' ', StringSplitOptions.RemoveEmptyEntries).Select(int.Parse).ToArray(); long[] d = Console.ReadLine().Split(' ', StringSplitOptions.RemoveEmptyEntries).Select(long.Parse).ToArray(); long carry = long.Parse(Console.ReadLine().Trim()); // 10^12: int로는 넘친다 // C#의 %는 나누어지는 수의 부호를 따른다(-7 % 3 == -1) → b를 더해 다시 나눈다 for (int i = n - 1; i >= 0; i--) { long s = d[i] + carry; d[i] = (s % b[i] + b[i]) % b[i]; carry = (s - d[i]) / b[i]; // s - 칸은 b로 딱 나누어떨어진다: 내림 몫 } Console.WriteLine(string.Join(" ", d)); Console.WriteLine(carry); }}
C++main.cpp · 21 lines
#include <iostream>#include <vector>int main() { int n; std::cin >> n; std::vector<long long> b(n), d(n); for (auto& x : b) std::cin >> x; for (auto& x : d) std::cin >> x; long long carry; // t는 10^12까지: int로는 넘친다 std::cin >> carry; // C++의 %는 0 쪽으로 버린 나눗셈의 나머지라 음수가 나올 수 있다 → b를 더해 다시 나눈다 for (int i = n - 1; i >= 0; i--) { long long s = d[i] + carry; d[i] = (s % b[i] + b[i]) % b[i]; carry = (s - d[i]) / b[i]; // s - 칸은 b로 딱 나누어떨어진다: 내림 몫 } for (int i = 0; i < n; i++) std::cout << (i ? " " : "") << d[i]; std::cout << '\n' << carry << '\n';}
Cmain.c · 20 lines
#include <stdio.h>int main(void) { int n, b[10]; long long d[10], carry; /* t는 10^12까지: int로는 넘친다 */ scanf("%d", &n); for (int i = 0; i < n; i++) scanf("%d", &b[i]); for (int i = 0; i < n; i++) scanf("%lld", &d[i]); scanf("%lld", &carry); /* C의 %는 0 쪽으로 버린 나눗셈의 나머지라 음수가 나올 수 있다 → b를 더해 다시 나눈다 */ for (int i = n - 1; i >= 0; i--) { long long s = d[i] + carry; d[i] = (s % b[i] + b[i]) % b[i]; carry = (s - d[i]) / b[i]; /* s - 칸은 b로 딱 나누어떨어진다: 내림 몫 */ } for (int i = 0; i < n; i++) printf(i ? " %lld" : "%lld", d[i]); printf("\n%lld\n", carry); return 0;}
Craykonmain.cray · 15 lines
n = Console.ReadLine().ToNumber();b = Console.ReadNumbers();d = Console.ReadNumbers();carry = Console.ReadLine().ToNumber(); // 10^12는 2^53 안이라 정확하다// 크레이콘의 %도 나누어지는 수의 부호를 따른다(-7 % 3 == -1) → b를 더해 다시 나눈다// 수학.몫은 0 쪽으로 버리니, 내림 몫은 (s - 칸) / b로 구한다(딱 나누어떨어진다)for (i = n - 1; i >= 0; i--){ s = d[i] + carry; d[i] = (s % b[i] + b[i]) % b[i]; carry = (s - d[i]) / b[i];}Console.WriteLine(d.Join(" "));Console.WriteLine(carry);