import sysfrom enum import Enumclass State(Enum): CREATED = 1 PAID = 2 SHIPPED = 3 DELIVERED = 4 CANCELLED = 5 REFUNDED = 6 RETURNED = 7# 상태 기계: (지금 상태, 사건) → 다음 상태. 표에 없는 짝은 거절NEXT = { (State.CREATED, "pay"): State.PAID, (State.CREATED, "cancel"): State.CANCELLED, (State.PAID, "ship"): State.SHIPPED, (State.PAID, "cancel"): State.REFUNDED, (State.SHIPPED, "deliver"): State.DELIVERED, (State.DELIVERED, "return"): State.RETURNED,}data = sys.stdin.read().split()n, q = int(data[0]), int(data[1])orders = [State.CREATED] * nrejected = 0for i in range(q): k, event = int(data[2 + 2 * i]) - 1, data[3 + 2 * i] nxt = NEXT.get((orders[k], event)) if nxt is None: rejected += 1 else: orders[k] = nxtprint("\n".join(s.name for s in orders)) # print(s)는 "State.PAID"를 찍는다print(rejected)
TypeScriptmain.ts · 43 行
import { readFileSync } from "node:fs";enum State { CREATED, PAID, SHIPPED, DELIVERED, CANCELLED, REFUNDED, RETURNED,}// 상태 기계: 받을 수 없는 사건이면 nullfunction next(s: State, event: string): State | null { switch (s) { case State.CREATED: return event === "pay" ? State.PAID : event === "cancel" ? State.CANCELLED : null; case State.PAID: return event === "ship" ? State.SHIPPED : event === "cancel" ? State.REFUNDED : null; case State.SHIPPED: return event === "deliver" ? State.DELIVERED : null; case State.DELIVERED: return event === "return" ? State.RETURNED : null; default: return null; // CANCELLED·REFUNDED·RETURNED는 끝 상태 }}const words: string[] = readFileSync(0, "utf8").trim().split(/\s+/);const n = Number(words[0]);const q = Number(words[1]);const orders: State[] = new Array<State>(n).fill(State.CREATED);let rejected = 0;for (let i = 0; i < q; i++) { const k = Number(words[2 + 2 * i]) - 1; const ns = next(orders[k], words[3 + 2 * i]); if (ns === null) rejected++; else orders[k] = ns;}// 숫자 enum의 값은 0, 1, 2…: 이름은 역방향 표 State[s]로 꺼낸다console.log(orders.map((s) => State[s]).join("\n"));console.log(rejected);
JavaMain.java · 37 行
import java.io.*;import java.util.*;public class Main { enum State { CREATED, PAID, SHIPPED, DELIVERED, CANCELLED, REFUNDED, RETURNED } // 상태 기계: 받을 수 없는 사건이면 null static State next(State s, String event) { return switch (s) { case CREATED -> event.equals("pay") ? State.PAID : event.equals("cancel") ? State.CANCELLED : null; case PAID -> event.equals("ship") ? State.SHIPPED : event.equals("cancel") ? State.REFUNDED : null; case SHIPPED -> event.equals("deliver") ? State.DELIVERED : null; case DELIVERED -> event.equals("return") ? State.RETURNED : null; case CANCELLED, REFUNDED, RETURNED -> null; // 끝 상태 }; } public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); StringTokenizer st = new StringTokenizer(br.readLine()); int n = Integer.parseInt(st.nextToken()), q = Integer.parseInt(st.nextToken()); State[] orders = new State[n]; Arrays.fill(orders, State.CREATED); int rejected = 0; for (int i = 0; i < q; i++) { st = new StringTokenizer(br.readLine()); int k = Integer.parseInt(st.nextToken()) - 1; State ns = next(orders[k], st.nextToken()); if (ns == null) rejected++; else orders[k] = ns; } StringBuilder sb = new StringBuilder(); for (State s : orders) sb.append(s).append('\n'); // enum의 toString()은 이름 sb.append(rejected).append('\n'); System.out.print(sb); }}
C#Main.cs · 40 行
using System;using System.Linq;using System.Text;enum State { Created, Paid, Shipped, Delivered, Cancelled, Refunded, Returned }class Program{ // 상태 기계: (상태, 사건) 튜플 패턴. 받을 수 없는 사건이면 null static State? Next(State s, string ev) => (s, ev) switch { (State.Created, "pay") => State.Paid, (State.Created, "cancel") => State.Cancelled, (State.Paid, "ship") => State.Shipped, (State.Paid, "cancel") => State.Refunded, (State.Shipped, "deliver") => State.Delivered, (State.Delivered, "return") => State.Returned, _ => null, }; static void Main() { var first = Console.ReadLine()!.Split(' '); int n = int.Parse(first[0]), q = int.Parse(first[1]); var orders = Enumerable.Repeat(State.Created, n).ToArray(); int rejected = 0; for (int i = 0; i < q; i++) { var p = Console.ReadLine()!.Split(' '); int k = int.Parse(p[0]) - 1; State? ns = Next(orders[k], p[1]); if (ns is State s) orders[k] = s; else rejected++; } var sb = new StringBuilder(); foreach (var s in orders) sb.Append(s.ToString().ToUpperInvariant()).Append('\n'); // ToString()은 "Paid" sb.Append(rejected).Append('\n'); Console.Write(sb); }}
C++main.cpp · 60 行
#include <iostream>#include <optional>#include <string>#include <vector>enum class State { Created, Paid, Shipped, Delivered, Cancelled, Refunded, Returned };// enum class도 이름을 모른다: switch로 이름표를 만든다const char *name(State s) { switch (s) { case State::Created: return "CREATED"; case State::Paid: return "PAID"; case State::Shipped: return "SHIPPED"; case State::Delivered: return "DELIVERED"; case State::Cancelled: return "CANCELLED"; case State::Refunded: return "REFUNDED"; case State::Returned: return "RETURNED"; } return "?";}// 상태 기계: 받을 수 없는 사건이면 빈 optionalstd::optional<State> next(State s, const std::string &ev) { switch (s) { case State::Created: if (ev == "pay") return State::Paid; if (ev == "cancel") return State::Cancelled; break; case State::Paid: if (ev == "ship") return State::Shipped; if (ev == "cancel") return State::Refunded; break; case State::Shipped: if (ev == "deliver") return State::Delivered; break; case State::Delivered: if (ev == "return") return State::Returned; break; default: break; // 끝 상태 } return std::nullopt;}int main() { std::ios::sync_with_stdio(false); int n, q; std::cin >> n >> q; std::vector<State> orders(n, State::Created); int rejected = 0; for (int i = 0; i < q; i++) { int k; std::string ev; std::cin >> k >> ev; if (auto ns = next(orders[k - 1], ev)) orders[k - 1] = *ns; else rejected++; } for (State s : orders) std::cout << name(s) << '\n'; std::cout << rejected << '\n';}
Cmain.c · 46 行
#include <stdio.h>#include <string.h>enum State { CREATED, PAID, SHIPPED, DELIVERED, CANCELLED, REFUNDED, RETURNED };/* C 열거형은 이름 붙은 int일 뿐이라 이름표를 따로 둔다(차례가 enum과 같아야 한다) */static const char *NAME[] = { "CREATED", "PAID", "SHIPPED", "DELIVERED", "CANCELLED", "REFUNDED", "RETURNED" };/* 다음 상태를 *s에 쓰고 1, 받을 수 없는 사건이면 0 */int step(enum State *s, const char *ev) { switch (*s) { case CREATED: if (strcmp(ev, "pay") == 0) { *s = PAID; return 1; } if (strcmp(ev, "cancel") == 0) { *s = CANCELLED; return 1; } break; /* break가 없으면 아래 case로 흘러내린다 */ case PAID: if (strcmp(ev, "ship") == 0) { *s = SHIPPED; return 1; } if (strcmp(ev, "cancel") == 0) { *s = REFUNDED; return 1; } break; case SHIPPED: if (strcmp(ev, "deliver") == 0) { *s = DELIVERED; return 1; } break; case DELIVERED: if (strcmp(ev, "return") == 0) { *s = RETURNED; return 1; } break; default: /* 끝 상태 */ break; } return 0;}int main(void) { static enum State orders[1000]; int n, q, rejected = 0; scanf("%d %d", &n, &q); for (int i = 0; i < n; i++) orders[i] = CREATED; for (int i = 0; i < q; i++) { int k; char ev[16]; scanf("%d %15s", &k, ev); if (!step(&orders[k - 1], ev)) rejected++; } for (int i = 0; i < n; i++) puts(NAME[orders[i]]); printf("%d\n", rejected); return 0;}