import sysUNITS = "dhms" # 큰 단위부터SECONDS = [86400, 3600, 60, 1]LIMIT = [0, 23, 59, 59] # 첫 덩이가 아닐 때 넘으면 안 되는 값(d는 늘 첫 덩이라 쓰이지 않는다)def read_number(s, i): """i번 자리부터 숫자를 읽어 (값, 숫자가 끝난 다음 자리)를 함께 돌려준다.""" value = 0 while i < len(s) and "0" <= s[i] <= "9": value = value * 10 + int(s[i]) i += 1 return value, idef parse(s): """(True, 모두 몇 초) 또는 (False, 처음 틀린 자리)를 돌려준다.""" total = 0 last = -1 # 바로 앞 덩이의 단위 번호 i = 0 while i < len(s): start = i value, i = read_number(s, i) if i == start: # 숫자가 와야 할 자리 return False, start + 1 if i == len(s): # 단위 없이 끝났다 return False, i + 1 u = UNITS.find(s[i]) if u < 0 or u <= last: # 단위가 아니거나, 앞 단위보다 작지 않다 return False, i + 1 if last >= 0 and value > LIMIT[u]: return False, start + 1 # 틀린 곳은 수가 시작한 자리 total += value * SECONDS[u] last = u i += 1 return True, totaldef main(): lines = sys.stdin.read().split() n = int(lines[0]) out = [] for s in lines[1:1 + n]: ok, x = parse(s) out.append(("ok " if ok else "error ") + str(x)) print("\n".join(out))main()
JavaScriptmain.js · 44 行
const lines = require("fs").readFileSync(0, "utf8").trim().split(/\s+/);const UNITS = "dhms"; // 큰 단위부터const SECONDS = [86400, 3600, 60, 1];const LIMIT = [0, 23, 59, 59]; // 첫 덩이가 아닐 때 넘으면 안 되는 값// i번 자리부터 숫자를 읽어 [값, 숫자가 끝난 다음 자리]를 배열로 돌려준다function readNumber(s, i) { let value = 0; while (i < s.length && s[i] >= "0" && s[i] <= "9") { value = value * 10 + Number(s[i]); i++; } return [value, i];}// [true, 모두 몇 초] 또는 [false, 처음 틀린 자리]function parse(s) { let total = 0; let last = -1; // 바로 앞 덩이의 단위 번호 let i = 0; while (i < s.length) { const start = i; const [value, next] = readNumber(s, i); i = next; if (i === start) return [false, start + 1]; // 숫자가 와야 할 자리 if (i === s.length) return [false, i + 1]; // 단위 없이 끝났다 const u = UNITS.indexOf(s[i]); if (u < 0 || u <= last) return [false, i + 1]; if (last >= 0 && value > LIMIT[u]) return [false, start + 1]; // 수가 시작한 자리 total += value * SECONDS[u]; last = u; i++; } return [true, total];}const n = Number(lines[0]);const out = [];for (let k = 1; k <= n; k++) { const [ok, x] = parse(lines[k]); out.push((ok ? "ok " : "error ") + x);}console.log(out.join("\n"));
TypeScriptmain.ts · 45 行
import { readFileSync } from "node:fs";const lines: string[] = readFileSync(0, "utf8").trim().split(/\s+/);const UNITS = "dhms"; // 큰 단위부터const SECONDS: number[] = [86400, 3600, 60, 1];const LIMIT: number[] = [0, 23, 59, 59]; // 첫 덩이가 아닐 때 넘으면 안 되는 값// i번 자리부터 숫자를 읽어 [값, 숫자가 끝난 다음 자리]를 튜플로 돌려준다function readNumber(s: string, i: number): [number, number] { let value = 0; while (i < s.length && s[i] >= "0" && s[i] <= "9") { value = value * 10 + Number(s[i]); i++; } return [value, i];}// [true, 모두 몇 초] 또는 [false, 처음 틀린 자리]function parse(s: string): [boolean, number] { let total = 0; let last = -1; // 바로 앞 덩이의 단위 번호 let i = 0; while (i < s.length) { const start = i; const [value, next] = readNumber(s, i); i = next; if (i === start) return [false, start + 1]; // 숫자가 와야 할 자리 if (i === s.length) return [false, i + 1]; // 단위 없이 끝났다 const u = UNITS.indexOf(s[i]); if (u < 0 || u <= last) return [false, i + 1]; if (last >= 0 && value > LIMIT[u]) return [false, start + 1]; // 수가 시작한 자리 total += value * SECONDS[u]; last = u; i++; } return [true, total];}const n = Number(lines[0]);const out: string[] = [];for (let k = 1; k <= n; k++) { const [ok, x] = parse(lines[k]); out.push((ok ? "ok " : "error ") + x);}console.log(out.join("\n"));
JavaMain.java · 53 行
import java.io.*;public class Main { static final String UNITS = "dhms"; // 큰 단위부터 static final long[] SECONDS = {86400, 3600, 60, 1}; static final long[] LIMIT = {0, 23, 59, 59}; // 첫 덩이가 아닐 때 넘으면 안 되는 값 // Java 메서드는 값 하나만 돌려주니 record로 묶는다 record Num(long value, int next) {} record Result(boolean ok, long x) {} // i번 자리부터 숫자를 읽어 (값, 숫자가 끝난 다음 자리)를 돌려준다 static Num readNumber(String s, int i) { long value = 0; while (i < s.length() && Character.isDigit(s.charAt(i))) { value = value * 10 + (s.charAt(i) - '0'); i++; } return new Num(value, i); } // (true, 모두 몇 초) 또는 (false, 처음 틀린 자리) static Result parse(String s) { long total = 0; int last = -1; // 바로 앞 덩이의 단위 번호 int i = 0; while (i < s.length()) { int start = i; Num num = readNumber(s, i); i = num.next(); if (i == start) return new Result(false, start + 1); // 숫자가 와야 할 자리 if (i == s.length()) return new Result(false, i + 1); // 단위 없이 끝났다 int u = UNITS.indexOf(s.charAt(i)); if (u < 0 || u <= last) return new Result(false, i + 1); if (last >= 0 && num.value() > LIMIT[u]) return new Result(false, start + 1); // 수가 시작한 자리 total += num.value() * SECONDS[u]; last = u; i++; } return new Result(true, total); } public static void main(String[] args) throws IOException { BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); int n = Integer.parseInt(in.readLine().trim()); StringBuilder out = new StringBuilder(); for (int k = 0; k < n; k++) { Result r = parse(in.readLine().trim()); out.append(r.ok() ? "ok " : "error ").append(r.x()).append('\n'); } System.out.print(out); }}
C#Main.cs · 56 行
using System;using System.Text;class Program{ const string Units = "dhms"; // 큰 단위부터 static readonly long[] Seconds = { 86400, 3600, 60, 1 }; static readonly long[] Limit = { 0, 23, 59, 59 }; // 첫 덩이가 아닐 때 넘으면 안 되는 값 // i번 자리부터 숫자를 읽어 (값, 숫자가 끝난 다음 자리)를 튜플로 돌려준다 static (long value, int next) ReadNumber(string s, int i) { long value = 0; while (i < s.Length && s[i] >= '0' && s[i] <= '9') { value = value * 10 + (s[i] - '0'); i++; } return (value, i); } // (true, 모두 몇 초) 또는 (false, 처음 틀린 자리) static (bool ok, long x) Parse(string s) { long total = 0; int last = -1; // 바로 앞 덩이의 단위 번호 int i = 0; while (i < s.Length) { int start = i; long value; (value, i) = ReadNumber(s, i); if (i == start) return (false, start + 1); // 숫자가 와야 할 자리 if (i == s.Length) return (false, i + 1); // 단위 없이 끝났다 int u = Units.IndexOf(s[i]); if (u < 0 || u <= last) return (false, i + 1); if (last >= 0 && value > Limit[u]) return (false, start + 1); // 수가 시작한 자리 total += value * Seconds[u]; last = u; i++; } return (true, total); } static void Main() { int n = int.Parse(Console.ReadLine().Trim()); var sb = new StringBuilder(); for (int k = 0; k < n; k++) { var (ok, x) = Parse(Console.ReadLine().Trim()); sb.Append(ok ? "ok " : "error ").Append(x).Append('\n'); } Console.Write(sb); }}
C++main.cpp · 54 行
#include <iostream>#include <string>#include <utility>using namespace std;const string UNITS = "dhms"; // 큰 단위부터const long long SECONDS[] = {86400, 3600, 60, 1};const long long LIMIT[] = {0, 23, 59, 59}; // 첫 덩이가 아닐 때 넘으면 안 되는 값// i번 자리부터 숫자를 읽어 (값, 숫자가 끝난 다음 자리)를 pair로 돌려준다pair<long long, int> readNumber(const string& s, int i) { long long value = 0; while (i < (int)s.size() && s[i] >= '0' && s[i] <= '9') { value = value * 10 + (s[i] - '0'); i++; } return {value, i};}// (true, 모두 몇 초) 또는 (false, 처음 틀린 자리)pair<bool, long long> parse(const string& s) { int len = (int)s.size(); long long total = 0; int last = -1; // 바로 앞 덩이의 단위 번호 int i = 0; while (i < len) { int start = i; auto [value, next] = readNumber(s, i); // C++17 구조적 바인딩 i = next; if (i == start) return {false, start + 1}; // 숫자가 와야 할 자리 if (i == len) return {false, i + 1}; // 단위 없이 끝났다 int u = (int)UNITS.find(s[i]); // 없으면 npos → -1 if (u < 0 || u <= last) return {false, i + 1}; if (last >= 0 && value > LIMIT[u]) return {false, start + 1}; // 수가 시작한 자리 total += value * SECONDS[u]; last = u; i++; } return {true, total};}int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int n; cin >> n; string s; for (int k = 0; k < n; k++) { cin >> s; auto [ok, x] = parse(s); cout << (ok ? "ok " : "error ") << x << "\n"; } return 0;}
Cmain.c · 54 行
#include <stdio.h>#include <string.h>static const char UNITS[] = "dhms"; /* 큰 단위부터 */static const long long SECONDS[] = {86400, 3600, 60, 1};static const long long LIMIT[] = {0, 23, 59, 59}; /* 첫 덩이가 아닐 때 넘으면 안 되는 값 *//* i번 자리부터 숫자를 읽어 값을 돌려주고, 숫자가 끝난 다음 자리는 *next에 써 준다. C 함수는 값 하나만 돌려주니 둘째 값은 포인터로 내보낸다 */static long long read_number(const char *s, int i, int *next) { long long value = 0; while (s[i] >= '0' && s[i] <= '9') { value = value * 10 + (s[i] - '0'); i++; } *next = i; return value;}/* 맞으면 1을 돌려주고 *x에 모두 몇 초인지, 틀리면 0을 돌려주고 *x에 처음 틀린 자리 */static int parse(const char *s, long long *x) { int len = (int)strlen(s); long long total = 0; int last = -1; /* 바로 앞 덩이의 단위 번호 */ int i = 0; while (i < len) { int start = i; long long value = read_number(s, i, &i); if (i == start) { *x = start + 1; return 0; } /* 숫자가 와야 할 자리 */ if (i == len) { *x = i + 1; return 0; } /* 단위 없이 끝났다 */ const char *p = strchr(UNITS, s[i]); int u = p ? (int)(p - UNITS) : -1; if (u < 0 || u <= last) { *x = i + 1; return 0; } if (last >= 0 && value > LIMIT[u]) { *x = start + 1; return 0; } /* 수가 시작한 자리 */ total += value * SECONDS[u]; last = u; i++; } *x = total; return 1;}int main(void) { int n; char s[64]; if (scanf("%d", &n) != 1) return 0; for (int k = 0; k < n; k++) { long long x; if (scanf("%63s", s) != 1) return 0; if (parse(s, &x)) printf("ok %lld\n", x); else printf("error %lld\n", x); } return 0;}
Craykonmain.cray · 65 行
단위들 = "dhms"; // 큰 단위부터초 = [86400, 3600, 60, 1];한도 = [0, 23, 59, 59]; // 첫 덩이가 아닐 때 넘으면 안 되는 값// i번 자리부터 숫자를 읽어 [값, 숫자가 끝난 다음 자리]를 목록으로 돌려준다수읽기(s, i){ 값 = 0; 間 (i < s.長さ && s[i] >= "0" && s[i] <= "9") { 값 = 값 * 10 + s[i].数に(); i = i + 1; } 返す [값, i];}// [참, 모두 몇 초] 또는 [거짓, 처음 틀린 자리]풀기(s){ 합 = 0; 앞단위 = -1; // 바로 앞 덩이의 단위 번호 i = 0; 間 (i < s.長さ) { 시작 = i; r = 수읽기(s, i); 값 = r[0]; i = r[1]; もし (i == 시작) { 返す [偽, 시작 + 1]; // 숫자가 와야 할 자리 } もし (i == s.長さ) { 返す [偽, i + 1]; // 단위 없이 끝났다 } u = 단위들.位置検索(s[i]); もし (u < 0 || u <= 앞단위) { 返す [偽, i + 1]; } もし (앞단위 >= 0 && 값 > 한도[u]) { 返す [偽, 시작 + 1]; // 수가 시작한 자리 } 합 = 합 + 값 * 초[u]; 앞단위 = u; i = i + 1; } 返す [真, 합];}n = コンソール.行読み().数に();繰り返す (k = 0; k < n; k++){ r = 풀기(コンソール.行読み().空白除去()); もし (r[0]) { コンソール.書く("ok " + r[1]); } でなければ { コンソール.書く("error " + r[1]); }}