실험실 장비가 측정값을 한 줄에 한 번씩 적어 둔 기록이 입력이 끝날 때까지 주어진다.
줄 수도, 한 줄에 든 수의 개수도 미리 알려 주지 않는다.
한 줄에서 '#'이 처음 나오는 곳부터 그 줄의 끝까지는 주석이고, 주석 속에 적힌 수는 세지 않는다.
주석을 뺀 나머지에는 정수가 0개 이상 있다.
정수와 정수 사이에는 빈칸, 탭, 쉼표가 하나 이상 섞여 있고, 줄의 맨 앞과 맨 뒤에도 이 글자들이 있을 수 있다.
쉼표가 겹쳐 있어도 그 사이에 값이 있다는 뜻은 아니다.
정수는 10진수이고, 맨 앞에 부호 '+'나 '-'가 붙을 수 있으며, 0으로 시작할 수도 있다.
그래서 007은 7이고 -012는 −12이며 +5는 5다.
정수가 하나라도 있는 줄만 기록이다.
빈 줄, 빈칸·탭·쉼표만 있는 줄, 주석만 있는 줄은 기록이 아니므로 건너뛰고, 그 뒤에도 기록이 더 있을 수 있다.
기록마다 입력에 나온 차례대로 한 줄에, 그 줄의 정수 개수와 합을 빈칸 하나로 띄워 출력하라.
마지막 줄에는 기록의 수, 모든 기록의 정수 개수를 더한 값, 모든 정수의 합을 빈칸 하나씩 띄워 출력하라.
기록이 하나도 없으면 "0 0 0" 한 줄만 출력한다.
입력
입력은 1~1,000줄이고, 한 줄은 줄 바꿈을 빼고 200글자 이하다. 정수는 부호를 뺀 숫자가 1~12개이고 값은 −100,000,000,000 이상 100,000,000,000 이하다. 부호는 정수 하나에 많아야 하나이고 그 정수의 맨 앞에만 나오며, 부호와 숫자 사이에는 아무 글자도 없다. 마지막 줄을 포함한 모든 줄은 줄 바꿈으로 끝난다. 주석이 아닌 곳에는 숫자, '+', '-', 빈칸, 탭, 쉼표만 나오고, 주석에는 출력 가능한 ASCII 글자가 나온다
출력
기록마다 "개수 합" 한 줄, 마지막 줄에 "기록 수 전체 개수 전체 합". 수는 쉼표 없이 숫자만 쓴다
예시 1 · stdin
# run 7 (2 sensors)
12, 007 +5
-3,,4 # 99 is ignored
100000000000 100000000000,
,,
08 010
stdout
3 24
2 1
2 200000000000
2 18
4 9 200000000043
main.py
오류 목록00F8 ↓ · ⇧F8 ↑
입력(stdin)
실행하면 이 줄들이 차례로 input()·표준 입력으로 들어가요(실행 중에 묻지 않아요).
$ 준비됐어요
코드를 입력해 풀려면 PC에서 열어 주세요. 모바일에서는 문제와 풀이를 볼 수 있어요.
다른 언어로는?언어별 풀이 보기 · 8개 언어 풀이
줄마다 수가 몇 개인지 모르기 때문에 줄의 끝이 어디인지를 알아야 하는 문제예요. C scanf("%lld"), C++ std::cin >> x, Java Scanner.nextLong()은 빈칸과 줄 바꿈을 똑같이 건너뛰어서 줄의 끝을 알 수 없어요(쉼표와 주석에서도 막혀요). 그래서 먼저 한 줄을 읽고(Python for line in sys.stdin, Java readLine(), C# Console.ReadLine(), C fgets, C++ getline, 크레이콘 콘솔.줄읽기(), JS·TS는 한꺼번에 읽어 split("\n")), 그 줄을 조각으로 나눠요. 나누는 도구마다 빈 조각을 다루는 법이 달라요. Python split()과 크레이콘 나누기()는 인자가 없으면 빈칸·탭 덩이를 한 번에 건너뛰므로 쉼표만 빈칸으로 바꿔 주면 돼요(replace(",", " "), 바꾸기(",", " ")). C strtok(line, " \t,\r\n")과 Java StringTokenizer(data, " \t,")도 빈 조각을 만들지 않고, C#은 Split(seps, StringSplitOptions.RemoveEmptyEntries)라고 적어 줘야 해요. C++는 쉼표를 빈칸으로 바꾼 뒤 std::istringstream에서 >>로 읽어요. 함정 하나: JS·TS split(/[ \t,]+/)는 줄의 맨 앞·맨 뒤 구분 글자 옆에 빈 문자열 ""을 남기고, Number("")는 오류 없이 0이에요. 거르지 않으면 예시 셋째 줄이 2 1이 아니라 4 1이 되고 빈 줄도 1 0으로 나와요. filter((t) => t !== "")로 걸러요. 함정 둘: Java split("[ \t,]+")는 맨 뒤의 빈 문자열만 버리고 맨 앞의 것은 남겨서, 예시 셋째 줄에서 Long.parseLong("")이 NumberFormatException으로 멈춰요. 함정 셋: C strtoll(tok, NULL, 0)처럼 진법에 0을 주면 0으로 시작하는 수를 8진수로 읽어요. 예시 마지막 줄의 010이 8이 되고 08은 0에서 멈춰서 2 18이 2 8이 돼요. 진법에 10을 줘요. Python int, JS·TS Number, Java Long.parseLong, C# long.Parse, C++ >>, 크레이콘 수로변환()은 007과 +5를 10진수 7과 5로 읽어요. 함정 넷: 주석을 잘라 내지 않고 줄 전체에서 수를 찾으면(Python re.findall) 예시 첫 줄의 7과 2, 셋째 줄의 99까지 세요. 함정 다섯: 합이 21억을 넘어요. C·C++ long long, Java·C# long으로 모아요. Java에서 int sum에 sum += Long.parseLong(t)를 쓰면 컴파일 오류 없이 int로 잘려서 예시 넷째 기록의 합 200000000000이 -1863462912가 돼요. Python은 크기 제한이 없고, JS·TS·크레이콘의 수는 2^53까지 정확해서 이 문제의 가장 큰 전체 합 1.5 × 10^15도 그대로 돼요. 함정 여섯: 수가 없는 줄을 건너뛰지 않으면 0 0이 출력되고 기록 수가 늘어요. 함정 일곱: 빈 줄은 입력의 끝이 아니에요. 빈 줄에서 멈추면 예시의 뒤쪽 두 기록을 놓쳐요. 입력의 끝은 Java·C# null, C fgets의 NULL, C++ getline의 거짓, 크레이콘 빈값으로 알아요.
Pythonmain.py · 16 줄
import sysrows = count_all = total = 0out = []for line in sys.stdin: # 입력이 끝날 때까지 한 줄씩 data = line.split("#")[0] # '#'부터는 주석 # 쉼표를 빈칸으로 바꾸면 split()이 빈칸·탭·쉼표 덩이를 한 번에 건너뛴다 nums = [int(t) for t in data.replace(",", " ").split()] if not nums: # 수가 없는 줄은 기록이 아니다 continue rows += 1 count_all += len(nums) total += sum(nums) out.append(f"{len(nums)} {sum(nums)}")out.append(f"{rows} {count_all} {total}")print("\n".join(out))
JavaScriptmain.js · 19 줄
const lines = require("fs").readFileSync(0, "utf8").split("\n");let rows = 0;let countAll = 0;let total = 0;const out = [];for (const line of lines) { const data = line.split("#")[0]; // '#'부터는 주석 // 나눈 뒤 빈 조각 ""을 꼭 걸러 낸다. Number("")는 오류 없이 0이다 const nums = data.split(/[ \t,]+/).filter((t) => t !== "").map(Number); if (nums.length === 0) continue; // 수가 없는 줄은 기록이 아니다 let sum = 0; for (const x of nums) sum += x; rows++; countAll += nums.length; total += sum; out.push(`${nums.length} ${sum}`);}out.push(`${rows} ${countAll} ${total}`);console.log(out.join("\n"));
TypeScriptmain.ts · 20 줄
import { readFileSync } from "node:fs";const lines: string[] = readFileSync(0, "utf8").split("\n");let rows = 0;let countAll = 0;let total = 0;const out: string[] = [];for (const line of lines) { const data: string = line.split("#")[0]; // '#'부터는 주석 // 나눈 뒤 빈 조각 ""을 꼭 걸러 낸다. Number("")는 오류 없이 0이다 const nums: number[] = data.split(/[ \t,]+/).filter((t) => t !== "").map(Number); if (nums.length === 0) continue; // 수가 없는 줄은 기록이 아니다 let sum = 0; for (const x of nums) sum += x; rows++; countAll += nums.length; total += sum; out.push(`${nums.length} ${sum}`);}out.push(`${rows} ${countAll} ${total}`);console.log(out.join("\n"));
JavaMain.java · 33 줄
import java.io.BufferedReader;import java.io.InputStreamReader;import java.util.StringTokenizer;public class Main { public static void main(String[] args) throws Exception { BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); int rows = 0; int countAll = 0; long total = 0; StringBuilder out = new StringBuilder(); String line; while ((line = in.readLine()) != null) { // 입력이 끝나면 null int hash = line.indexOf('#'); String data = hash >= 0 ? line.substring(0, hash) : line; // '#'부터는 주석 // StringTokenizer는 구분 글자가 겹치거나 맨 앞에 있어도 빈 조각을 만들지 않는다 StringTokenizer st = new StringTokenizer(data, " \t,"); int count = 0; long sum = 0; while (st.hasMoreTokens()) { sum += Long.parseLong(st.nextToken()); count++; } if (count == 0) continue; // 수가 없는 줄은 기록이 아니다 rows++; countAll += count; total += sum; out.append(count).append(' ').append(sum).append('\n'); } out.append(rows).append(' ').append(countAll).append(' ').append(total).append('\n'); System.out.print(out); }}
C#Main.cs · 29 줄
using System;using System.Text;class Program{ static void Main() { int rows = 0, countAll = 0; long total = 0; var sb = new StringBuilder(); char[] seps = { ' ', '\t', ',' }; string line; while ((line = Console.ReadLine()) != null) // 입력이 끝나면 null { string data = line.Split('#')[0]; // '#'부터는 주석 // RemoveEmptyEntries가 없으면 구분 글자가 겹친 곳마다 빈 문자열이 생긴다 string[] parts = data.Split(seps, StringSplitOptions.RemoveEmptyEntries); if (parts.Length == 0) continue; // 수가 없는 줄은 기록이 아니다 long sum = 0; foreach (string t in parts) sum += long.Parse(t); rows++; countAll += parts.Length; total += sum; sb.Append(parts.Length).Append(' ').Append(sum).Append('\n'); } sb.Append(rows).Append(' ').Append(countAll).Append(' ').Append(total).Append('\n'); Console.Write(sb); }}
C++main.cpp · 30 줄
#include <algorithm>#include <iostream>#include <sstream>#include <string>using namespace std;int main() { int rows = 0, countAll = 0; long long total = 0; string line; // cin >> x 는 줄 바꿈도 건너뛰어서 줄의 끝을 알 수 없다. getline으로 한 줄씩 읽는다 while (getline(cin, line)) { line = line.substr(0, line.find('#')); // '#'부터는 주석(없으면 npos라 줄 전체) replace(line.begin(), line.end(), ',', ' '); istringstream in(line); int count = 0; long long sum = 0, x; while (in >> x) { // 빈칸·탭 덩이를 건너뛰며 수를 하나씩 읽는다 sum += x; count++; } if (count == 0) continue; // 수가 없는 줄은 기록이 아니다 rows++; countAll += count; total += sum; cout << count << ' ' << sum << '\n'; } cout << rows << ' ' << countAll << ' ' << total << '\n'; return 0;}
Cmain.c · 27 줄
#include <stdio.h>#include <stdlib.h>#include <string.h>int main(void) { char line[256]; int rows = 0, count_all = 0; long long total = 0; /* scanf("%lld")는 줄 바꿈도 건너뛰어서 줄의 끝을 알 수 없다. 한 줄씩 읽어서 나눈다 */ while (fgets(line, sizeof line, stdin)) { char *hash = strchr(line, '#'); /* '#'부터는 주석 */ if (hash) *hash = '\0'; int count = 0; long long sum = 0; for (char *tok = strtok(line, " \t,\r\n"); tok; tok = strtok(NULL, " \t,\r\n")) { sum += strtoll(tok, NULL, 10); /* 꼭 10진법으로: 0을 주면 010을 8진수로 읽는다 */ count++; } if (count == 0) continue; /* 수가 없는 줄은 기록이 아니다 */ rows++; count_all += count; total += sum; printf("%d %lld\n", count, sum); } printf("%d %d %lld\n", rows, count_all, total); return 0;}
Craykonmain.cray · 28 줄
rows = 0;countAll = 0;total = 0;동안 (참){ line = 콘솔.줄읽기(); 만약 (line == 빈값) { 그만; } data = line.나누기("#")[0]; // '#'부터는 주석 // 쉼표를 빈칸으로 바꾸면 나누기()가 빈칸·탭·쉼표 덩이를 한 번에 건너뛴다 parts = data.바꾸기(",", " ").나누기(); 만약 (parts.개수 == 0) { 건너뛰기; } sum = 0; 각각 (t 에서 parts) { sum += t.수로변환(); } rows += 1; countAll += parts.개수; total += sum; 콘솔.쓰기(parts.개수 + " " + sum);}콘솔.쓰기(rows + " " + countAll + " " + total);