{ }codelper
逆順ループ累積64ビット整数P0173

カンマを打った入出金の帳簿

通帳の入出金の記録を読み、金額と残高を見やすく出力する。
一行目に取引の数 n と最初の残高 b が空白一つで区切って与えられる。
続く n 行に取引の金額 a が一行に一つずつ与えられる。
正の数は入金、負の数は出金、0 は金額のない取引である。
取引ごとに残高に a を足し、その取引の金額と足したあとの残高を空白一つで区切って一行に出力する。
数は、符号を取った数字を右端から三桁ごとにカンマ(,)で区切って書く。
先頭にはカンマを書かない(例:1234567 → 1,234,567、123 → 123)。
負の数は区切った数字の前に - を付ける。
金額が正なら区切った数字の前に + を付け、0 なら符号なしで 0 と書く。
残高が 0 以上なら符号を付けない。

入力
1 ≤ n ≤ 1000、−10^12 ≤ b ≤ 10^12、−10^9 ≤ a ≤ 10^9。
数はすべて整数
出力
n 行
例 1 · stdin
4 1500000
-250000
1234
0
-2000000
stdout
-250,000 1,250,000
+1,234 1,251,234
0 1,251,234
-2,000,000 -748,766
例 2 · stdin
2 -999
999
1000000000
stdout
+999 0
+1,000,000,000 1,000,000,000
main.py
入力(stdin)

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

$ 準備完了

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

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

カンマは右端から数えるので、最後の数字から前へ逆向きに回るループが自然です(for (i = len - 1; i >= 0; i--)、Python range(len(s) - 1, -1, -1)、Craykon 繰り返す (i = s.長さ - 1; i >= 0; i -= 1))。
左から三桁ずつ区切ると 1234 が "123,4" になります。
符号を取ってから区切ります。"-123456" をまるごと区切ると - も一桁と数えて "-,123,456" になります。
残高は 1 兆に 10 億を 1000 回足して 2 兆まで行きます。
int(約 21 億)では最初の残高すら入らないので、C・C++ は long long、Java・C# は long を使います。
Python の整数には大きさの限りがなく、JS・TS・Craykon の数は 2^53(約 9000 兆)まで整数が正確なのでそのまま動きます。
用意された書式もありますが言語ごとに違います。
Python f"{v:,}" は常にカンマです。
Java String.format("%,d", v) と C# v.ToString("N0") はコンピュータの地域設定に従うので、ドイツ語の設定なら 1.234 のように点が出ます。
JS・TS toLocaleString も地域設定に従うので "en-US" を渡します。
C・C++ には地域設定に関係なくカンマを打つ標準の書式がありません(C++20 の std::format("{:L}", v) も地域設定に従います)。
0 円の取引に + を付けるのもよくある間違いです。

Pythonmain.py · 26 行
def group(v):    """0 이상인 v를 오른쪽부터 세 자리마다 쉼표로 끊는다."""    s = str(v)    out = ""    for i in range(len(s) - 1, -1, -1):  # 맨 오른쪽 숫자부터 거꾸로        out = s[i] + out        if (len(s) - i) % 3 == 0 and i > 0:  # 세 개를 붙였고 앞에 숫자가 더 있으면            out = "," + out    return out  def money(v, plus):    if v < 0:        return "-" + group(-v)  # 부호는 떼고 끊은 뒤 앞에 붙인다    if v > 0 and plus:        return "+" + group(v)    return group(v)  n, balance = map(int, input().split())lines = []for _ in range(n):    a = int(input())    balance += a  # 잔액에 차례로 쌓는다    lines.append(money(a, True) + " " + money(balance, False))print("\n".join(lines))
JavaScriptmain.js · 28 行
const nums = require("fs").readFileSync(0, "utf8").trim().split(/\s+/).map(Number);const n = nums[0];let balance = nums[1]; // 2조까지라 Number(2^53 미만)로 정확하다 // 0 이상인 v를 오른쪽부터 세 자리마다 쉼표로 끊는다function group(v) {  const s = String(v);  let out = "";  for (let i = s.length - 1; i >= 0; i--) {    out = s[i] + out;    if ((s.length - i) % 3 === 0 && i > 0) out = "," + out;  }  return out;} function money(v, plus) {  if (v < 0) return "-" + group(-v); // 부호는 떼고 끊은 뒤 앞에 붙인다  if (v > 0 && plus) return "+" + group(v);  return group(v);} const out = [];for (let k = 0; k < n; k++) {  const a = nums[2 + k];  balance += a;  out.push(money(a, true) + " " + money(balance, false));}console.log(out.join("\n"));
TypeScriptmain.ts · 29 行
import { readFileSync } from "node:fs";const nums: number[] = readFileSync(0, "utf8").trim().split(/\s+/).map(Number);const n: number = nums[0];let balance: number = nums[1]; // 2조까지라 number(2^53 미만)로 정확하다 // 0 이상인 v를 오른쪽부터 세 자리마다 쉼표로 끊는다function group(v: number): string {  const s: string = String(v);  let out = "";  for (let i = s.length - 1; i >= 0; i--) {    out = s[i] + out;    if ((s.length - i) % 3 === 0 && i > 0) out = "," + out;  }  return out;} function money(v: number, plus: boolean): string {  if (v < 0) return "-" + group(-v); // 부호는 떼고 끊은 뒤 앞에 붙인다  if (v > 0 && plus) return "+" + group(v);  return group(v);} const out: string[] = [];for (let k = 0; k < n; k++) {  const a: number = nums[2 + k];  balance += a;  out.push(money(a, true) + " " + money(balance, false));}console.log(out.join("\n"));
JavaMain.java · 36 行
import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader; public class Main {    // 0 이상인 v를 오른쪽부터 세 자리마다 쉼표로 끊는다    static String group(long v) {        String s = Long.toString(v);        StringBuilder out = new StringBuilder();        for (int i = s.length() - 1; i >= 0; i--) {            out.append(s.charAt(i));            if ((s.length() - i) % 3 == 0 && i > 0) out.append(',');        }        return out.reverse().toString(); // 거꾸로 붙였으니 마지막에 뒤집는다    }     static String money(long v, boolean plus) {        if (v < 0) return "-" + group(-v); // 부호는 떼고 끊은 뒤 앞에 붙인다        if (v > 0 && plus) return "+" + group(v);        return group(v);    }     public static void main(String[] args) throws IOException {        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));        String[] first = br.readLine().trim().split("\\s+");        int n = Integer.parseInt(first[0]);        long balance = Long.parseLong(first[1]); // 1조를 넘으니 int가 아니라 long        StringBuilder out = new StringBuilder();        for (int k = 0; k < n; k++) {            long a = Long.parseLong(br.readLine().trim());            balance += a;            out.append(money(a, true)).append(' ').append(money(balance, false)).append('\n');        }        System.out.print(out);    }}
C#Main.cs · 40 行
using System;using System.Text; class Program{    // 0 이상인 v를 오른쪽부터 세 자리마다 쉼표로 끊는다    static string Group(long v)    {        string s = v.ToString();        var out_ = new StringBuilder();        for (int i = s.Length - 1; i >= 0; i--)        {            out_.Insert(0, s[i]);            if ((s.Length - i) % 3 == 0 && i > 0) out_.Insert(0, ',');        }        return out_.ToString();    }     static string Money(long v, bool plus)    {        if (v < 0) return "-" + Group(-v); // 부호는 떼고 끊은 뒤 앞에 붙인다        if (v > 0 && plus) return "+" + Group(v);        return Group(v);    }     static void Main()    {        string[] first = Console.ReadLine().Split(' ', StringSplitOptions.RemoveEmptyEntries);        int n = int.Parse(first[0]);        long balance = long.Parse(first[1]); // 1조를 넘으니 int가 아니라 long        var sb = new StringBuilder();        for (int k = 0; k < n; k++)        {            long a = long.Parse(Console.ReadLine().Trim());            balance += a;            sb.Append(Money(a, true)).Append(' ').Append(Money(balance, false)).Append('\n');        }        Console.Write(sb);    }}
C++main.cpp · 30 行
#include <iostream>#include <string> // 0 이상인 v를 오른쪽부터 세 자리마다 쉼표로 끊는다std::string group(long long v) {    std::string s = std::to_string(v);    std::string out;    for (int i = static_cast<int>(s.size()) - 1; i >= 0; i--) {        out.insert(out.begin(), s[i]);        if ((static_cast<int>(s.size()) - i) % 3 == 0 && i > 0) out.insert(out.begin(), ',');    }    return out;} std::string money(long long v, bool plus) {    if (v < 0) return "-" + group(-v); // 부호는 떼고 끊은 뒤 앞에 붙인다    if (v > 0 && plus) return "+" + group(v);    return group(v);} int main() {    int n;    long long balance, a; // 1조를 넘으니 int가 아니라 long long    std::cin >> n >> balance;    for (int k = 0; k < n; k++) {        std::cin >> a;        balance += a;        std::cout << money(a, true) << ' ' << money(balance, false) << '\n';    }}
Cmain.c · 37 行
#include <stdio.h> /* 0 이상인 v를 오른쪽부터 세 자리마다 쉼표로 끊어 buf 안 어딘가에 쓰고, 그 시작을 돌려준다 */static char *group(long long v, char *buf, int size) {    char *p = buf + size - 1;    *p = '\0';    int count = 0;    do { /* 맨 오른쪽 숫자부터 거꾸로 채운다 */        if (count > 0 && count % 3 == 0) *--p = ',';        *--p = (char)('0' + v % 10);        v /= 10;        count++;    } while (v > 0);    return p;} static void money(long long v, int plus) {    char buf[40];    if (v < 0) printf("-%s", group(-v, buf, sizeof buf)); /* 부호는 떼고 끊은 뒤 앞에 붙인다 */    else if (v > 0 && plus) printf("+%s", group(v, buf, sizeof buf));    else printf("%s", group(v, buf, sizeof buf));} int main(void) {    int n;    long long balance, a; /* 1조를 넘으니 int가 아니라 long long */    scanf("%d %lld", &n, &balance);    for (int k = 0; k < n; k++) {        scanf("%lld", &a);        balance += a;        money(a, 1);        putchar(' ');        money(balance, 0);        putchar('\n');    }    return 0;}
Craykonmain.cray · 38 行
첫줄 = コンソール.数読み();n = 첫줄[0];잔액 = 첫줄[1]; // 2조까지라 크레이콘 수로 정확하다繰り返す (k = 0; k < n; k += 1){    a = コンソール.行読み().数に();    잔액 += a;    コンソール.書く(돈(a, 真) + " " + 돈(잔액, 偽));} // 0 이상인 v를 오른쪽부터 세 자리마다 쉼표로 끊는다끊기(v){    s = "" + v;    결과 = "";    繰り返す (i = s.長さ - 1; i >= 0; i -= 1)    {        결과 = s[i] + 결과;        もし ((s.長さ - i) % 3 == 0 && i > 0)        {            결과 = "," + 결과;        }    }    返す 결과;} 돈(v, 더하기표){    もし (v < 0)    {        返す "-" + 끊기(-v); // 부호는 떼고 끊은 뒤 앞에 붙인다    }    もし (v > 0 && 더하기표)    {        返す "+" + 끊기(v);    }    返す 끊기(v);}