You control a TV with channels 1 to c using a remote.
At first the TV is off, the channel is 1, the volume is 10, mute is off, there is no previous channel, and no digits are stored.
Each key is one character, and the keys are given on one line in the order pressed.
While the TV is off, every key except P and ? is ignored.
While off, P turns the TV on, and ? prints OFF on one line.
When turned on, the channel, volume, mute and previous channel are as they were when it was turned off.
While on, a digit key 0–9 appends that digit to the stored digits. When the stored digits reach three digits, 'digit handling' happens at once.
While on, a key that is not a digit first does 'digit handling', then its own action.
'Digit handling' happens only when digits are stored: read the stored digits as a number (007 is 7) and clear them. If the number is from 1 to c, go to that channel. If it is out of range, go to no channel.
While on, each key does the following.
- #: does nothing (only digit handling).
- P: turns the TV off.
- U: goes to the next channel. After channel c comes channel 1.
- D: goes to the channel before. Before channel 1 comes channel c.
- B: goes to the previous channel. If there is no previous channel, nothing happens.
- +: raises the volume by 1 (never above 30) and turns mute off.
- -: lowers the volume by 1 (never below 0) and turns mute off.
- M: toggles mute.
- ?: prints CH channel MUTE if mute is on, otherwise CH channel VOL volume, on one line.
'Going to' a channel means: only if it differs from the current channel, remember the current channel as the previous channel and make that channel the current one. If it is the same as the current channel, nothing changes.
Digits left over after the last key are not handled.
The first line gives c, and the second line gives the keys without spaces.
Print one line for each ?.
Input
2 ≤ c ≤ 999. There are 1 to 10,000 keys, each one of 0–9, #, P, U, D, B, +, -, M, ?. There is at least one ?
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
This is a switch that picks a branch by one key. Choosing on one character: C/C++/Java/C#/JS/TS switch (k) { case 'U': … } (JS/TS use the string "U"), Python 3.10+ match k: case "U":, Craykon switch (k) { case "U": … break; }. Grouping cases that do the same thing, like the ten digits: C/C++/JS/TS/C# (empty cases only) case '0': case '1': …, Java arrow case '+', '-' ->, Python case "+" | "-":, Craykon case "0", "1", …:. Trap ① fall-through: C/C++/JS/TS and Java's old case: statement run on into the next case when break is missing. Forgetting break after U also runs D, and the channel comes back. C# makes this a compile error, and Java's arrow switch, Python match and Craykon switch do not fall through. Craykon's break leaves only the switch. ② D at channel 1: (ch - 2) % c + 1 gives channel 0 in C/C++/Java/C#/JS/TS/Craykon because % keeps the negative sign. Use (ch - 2 + c) % c + 1 or Java Math.floorMod (Python % is never negative). ③ Order of nested conditions: ask 'is it off?' before the switch, so the volume or channel never changes while off. ④ Every non-digit key handles the stored digits first (not only #). So 5U goes to 6, the channel after 5. ⑤ Going to the same channel does not overwrite the previous channel. ⑥ + and - turn mute off.
Pythonmain.py · 60 lines
c = int(input())keys = input().strip()power = Falsech, vol, muted = 1, 10, Falseprev = 0 # 바로 전 채널(0이면 아직 없음)buf = "" # 누른 숫자를 모아 둔 것out = []def go(to): """채널을 to로 바꾼다. 지금과 같으면 바꾼 것이 아니다.""" global ch, prev if to != ch: prev, ch = ch, todef commit(): global buf if buf: v = int(buf) # "007"은 7 buf = "" if 1 <= v <= c: go(v)for k in keys: if not power: # 꺼져 있으면 P와 ? 말고는 듣지 않는다 if k == "P": power = True elif k == "?": out.append("OFF") continue if k.isdigit(): buf += k if len(buf) == 3: commit() continue commit() # 숫자가 아닌 키는 모아 둔 숫자부터 처리한다 match k: case "#": pass case "P": power = False case "U": go(ch % c + 1) case "D": go((ch - 2) % c + 1) # Python의 %는 늘 0 이상이라 1번 → c번 case "B": if prev: go(prev) case "+" | "-": vol = min(30, vol + 1) if k == "+" else max(0, vol - 1) muted = False case "M": muted = not muted case "?": out.append(f"CH {ch} MUTE" if muted else f"CH {ch} VOL {vol}")print("\n".join(out))
JavaScriptmain.js · 62 lines
const [cLine, keysLine] = require("fs").readFileSync(0, "utf8").split("\n");const c = Number(cLine);const keys = keysLine.trim();let power = false;let ch = 1, vol = 10, muted = false;let prev = 0; // 바로 전 채널(0이면 아직 없음)let buf = ""; // 누른 숫자를 모아 둔 것const out = [];const go = (to) => { if (to !== ch) [prev, ch] = [ch, to]; // 지금과 같으면 바꾼 것이 아니다};const commit = () => { if (buf === "") return; const v = Number(buf); // "007"은 7 buf = ""; if (v >= 1 && v <= c) go(v);};for (const k of keys) { if (!power) { // 꺼져 있으면 P와 ? 말고는 듣지 않는다 if (k === "P") power = true; else if (k === "?") out.push("OFF"); continue; } if (k >= "0" && k <= "9") { buf += k; if (buf.length === 3) commit(); continue; } commit(); // 숫자가 아닌 키는 모아 둔 숫자부터 처리한다 switch (k) { case "#": break; case "P": power = false; break; case "U": go((ch % c) + 1); break; case "D": go(((ch - 2 + c) % c) + 1); // JS의 %는 음수를 남기니 c를 더해 둔다 break; case "B": if (prev !== 0) go(prev); break; case "+": case "-": // 두 경우가 같은 일을 하도록 일부러 이어 내려간다 vol = k === "+" ? Math.min(30, vol + 1) : Math.max(0, vol - 1); muted = false; break; case "M": muted = !muted; break; case "?": out.push(muted ? `CH ${ch} MUTE` : `CH ${ch} VOL ${vol}`); break; }}console.log(out.join("\n"));
TypeScriptmain.ts · 64 lines
import { readFileSync } from "node:fs";const [cLine, keysLine]: string[] = readFileSync(0, "utf8").split("\n");const c = Number(cLine);const keys = keysLine.trim();let power = false;let ch = 1, vol = 10, muted = false;let prev = 0; // 바로 전 채널(0이면 아직 없음)let buf = ""; // 누른 숫자를 모아 둔 것const out: string[] = [];const go = (to: number): void => { if (to !== ch) [prev, ch] = [ch, to]; // 지금과 같으면 바꾼 것이 아니다};const commit = (): void => { if (buf === "") return; const v = Number(buf); // "007"은 7 buf = ""; if (v >= 1 && v <= c) go(v);};for (const k of keys) { if (!power) { // 꺼져 있으면 P와 ? 말고는 듣지 않는다 if (k === "P") power = true; else if (k === "?") out.push("OFF"); continue; } if (k >= "0" && k <= "9") { buf += k; if (buf.length === 3) commit(); continue; } commit(); // 숫자가 아닌 키는 모아 둔 숫자부터 처리한다 switch (k) { case "#": break; case "P": power = false; break; case "U": go((ch % c) + 1); break; case "D": go(((ch - 2 + c) % c) + 1); // JS의 %는 음수를 남기니 c를 더해 둔다 break; case "B": if (prev !== 0) go(prev); break; case "+": case "-": // 두 경우가 같은 일을 하도록 일부러 이어 내려간다 vol = k === "+" ? Math.min(30, vol + 1) : Math.max(0, vol - 1); muted = false; break; case "M": muted = !muted; break; case "?": out.push(muted ? `CH ${ch} MUTE` : `CH ${ch} VOL ${vol}`); break; }}console.log(out.join("\n"));
JavaMain.java · 62 lines
import java.io.BufferedReader;import java.io.InputStreamReader;import java.io.IOException;public class Main { static int c, ch = 1, vol = 10, prev = 0; static boolean muted = false; static StringBuilder buf = new StringBuilder(); // 누른 숫자를 모아 둔 것 // 채널을 to로 바꾼다. 지금과 같으면 바꾼 것이 아니다 static void go(int to) { if (to != ch) { prev = ch; ch = to; } } static void commit() { if (buf.length() == 0) return; int v = Integer.parseInt(buf.toString()); // "007"은 7 buf.setLength(0); if (v >= 1 && v <= c) go(v); } public static void main(String[] args) throws IOException { BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); c = Integer.parseInt(in.readLine().trim()); String keys = in.readLine().trim(); boolean power = false; StringBuilder out = new StringBuilder(); for (char k : keys.toCharArray()) { if (!power) { // 꺼져 있으면 P와 ? 말고는 듣지 않는다 if (k == 'P') power = true; else if (k == '?') out.append("OFF\n"); continue; } if (Character.isDigit(k)) { buf.append(k); if (buf.length() == 3) commit(); continue; } commit(); // 숫자가 아닌 키는 모아 둔 숫자부터 처리한다 // 화살표 switch는 이어 내려가지 않아 break가 필요 없다 switch (k) { case '#' -> { } case 'P' -> power = false; case 'U' -> go(ch % c + 1); case 'D' -> go(Math.floorMod(ch - 2, c) + 1); // floorMod는 늘 0 이상 case 'B' -> { if (prev != 0) go(prev); } case '+', '-' -> { vol = k == '+' ? Math.min(30, vol + 1) : Math.max(0, vol - 1); muted = false; } case 'M' -> muted = !muted; case '?' -> out.append("CH ").append(ch).append(muted ? " MUTE" : " VOL " + vol).append('\n'); default -> { } } } System.out.print(out); }}
C#Main.cs · 82 lines
using System;using System.Text;class Program{ static int c, ch = 1, vol = 10, prev = 0; static bool muted = false; static string buf = ""; // 누른 숫자를 모아 둔 것 // 채널을 to로 바꾼다. 지금과 같으면 바꾼 것이 아니다 static void Go(int to) { if (to != ch) { prev = ch; ch = to; } } static void Commit() { if (buf == "") return; int v = int.Parse(buf); // "007"은 7 buf = ""; if (v >= 1 && v <= c) Go(v); } static void Main() { c = int.Parse(Console.ReadLine().Trim()); string keys = Console.ReadLine().Trim(); bool power = false; var sb = new StringBuilder(); foreach (char k in keys) { if (!power) { // 꺼져 있으면 P와 ? 말고는 듣지 않는다 if (k == 'P') power = true; else if (k == '?') sb.Append("OFF\n"); continue; } if (char.IsDigit(k)) { buf += k; if (buf.Length == 3) Commit(); continue; } Commit(); // 숫자가 아닌 키는 모아 둔 숫자부터 처리한다 // C#은 case 끝에 break가 없으면 컴파일 오류라서 이어 내려가는 실수가 없다 switch (k) { case '#': break; case 'P': power = false; break; case 'U': Go(ch % c + 1); break; case 'D': Go((ch - 2 + c) % c + 1); // C#의 %는 음수를 남기니 c를 더해 둔다 break; case 'B': if (prev != 0) Go(prev); break; case '+': case '-': // 빈 case는 다음 case와 묶을 수 있다 vol = k == '+' ? Math.Min(30, vol + 1) : Math.Max(0, vol - 1); muted = false; break; case 'M': muted = !muted; break; case '?': sb.Append(muted ? $"CH {ch} MUTE\n" : $"CH {ch} VOL {vol}\n"); break; } } Console.Write(sb); }}
C++main.cpp · 73 lines
#include <algorithm>#include <iostream>#include <string>int c, ch = 1, vol = 10, prev = 0;bool muted = false;std::string buf; // 누른 숫자를 모아 둔 것// 채널을 to로 바꾼다. 지금과 같으면 바꾼 것이 아니다void go(int to) { if (to != ch) { prev = ch; ch = to; }}void commit() { if (buf.empty()) return; int v = std::stoi(buf); // "007"은 7 buf.clear(); if (v >= 1 && v <= c) go(v);}int main() { std::string keys, out; std::cin >> c >> keys; bool power = false; for (char k : keys) { if (!power) { // 꺼져 있으면 P와 ? 말고는 듣지 않는다 if (k == 'P') power = true; else if (k == '?') out += "OFF\n"; continue; } if (k >= '0' && k <= '9') { buf += k; if (buf.size() == 3) commit(); continue; } commit(); // 숫자가 아닌 키는 모아 둔 숫자부터 처리한다 switch (k) { case '#': break; case 'P': power = false; break; case 'U': go(ch % c + 1); break; case 'D': go((ch - 2 + c) % c + 1); // C++의 %는 음수를 남기니 c를 더해 둔다 break; case 'B': if (prev) go(prev); break; case '+': vol = std::min(30, vol + 1); muted = false; break; case '-': vol = std::max(0, vol - 1); muted = false; break; case 'M': muted = !muted; break; case '?': out += "CH " + std::to_string(ch) + (muted ? " MUTE" : " VOL " + std::to_string(vol)) + "\n"; break; } } std::cout << out;}
Cmain.c · 81 lines
#include <stdio.h>#include <stdlib.h>static int c, ch = 1, vol = 10, muted = 0, prev = 0;static char buf[4];static int blen = 0;/* 채널을 to로 바꾼다. 지금과 같으면 바꾼 것이 아니다 */static void go(int to) { if (to != ch) { prev = ch; ch = to; }}static void commit(void) { if (blen == 0) return; buf[blen] = '\0'; int v = atoi(buf); /* "007"은 7 */ blen = 0; if (v >= 1 && v <= c) go(v);}static char keys[10002];int main(void) { int power = 0; scanf("%d %10001s", &c, keys); for (char *p = keys; *p; p++) { char k = *p; if (!power) { /* 꺼져 있으면 P와 ? 말고는 듣지 않는다 */ if (k == 'P') power = 1; else if (k == '?') puts("OFF"); continue; } switch (k) { /* 숫자 열 개는 case를 잇대어 써서 한 곳으로 모은다(일부러 이어 내려감) */ case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': buf[blen++] = k; if (blen == 3) commit(); continue; /* 아래의 commit을 건너뛰고 다음 키로 */ default: break; } commit(); /* 숫자가 아닌 키는 모아 둔 숫자부터 처리한다 */ switch (k) { case '#': break; case 'P': power = 0; break; case 'U': go(ch % c + 1); break; case 'D': go((ch - 2 + c) % c + 1); /* C의 %는 음수를 남기니 c를 더해 둔다 */ break; case 'B': if (prev) go(prev); break; case '+': vol = vol < 30 ? vol + 1 : 30; muted = 0; break; case '-': vol = vol > 0 ? vol - 1 : 0; muted = 0; break; case 'M': muted = !muted; break; case '?': if (muted) printf("CH %d MUTE\n", ch); else printf("CH %d VOL %d\n", ch, vol); break; } } return 0;}
Craykonmain.cray · 111 lines
c = Console.ReadLine().ToNumber();keys = Console.ReadLine().Trim();power = false;ch = 1;vol = 10;muted = false;prev = 0; // 바로 전 채널(0이면 아직 없음)buf = ""; // 누른 숫자를 모아 둔 것// 채널을 to로 바꾼다. 지금과 같으면 바꾼 것이 아니다가기(to){ if (to != ch) { prev = ch; ch = to; }}모은숫자처리(){ if (buf != "") { v = buf.ToNumber(); // "007"은 7 buf = ""; if (v >= 1 && v <= c) { 가기(v); } }}for (i = 0; i < keys.Length; i++){ k = keys[i]; if (!power) { // 꺼져 있으면 P와 ? 말고는 듣지 않는다 if (k == "P") { power = true; } else if (k == "?") { Console.WriteLine("OFF"); } continue; } switch (k) { case "0": case "1": case "2": case "3": case "4": case "5": case "6": case "7": case "8": case "9": buf = buf + k; if (buf.Length == 3) { 모은숫자처리(); } break; default: 모은숫자처리(); // 숫자가 아닌 키는 모아 둔 숫자부터 처리한다 switch (k) { case "P": power = false; break; case "U": 가기(ch % c + 1); break; case "D": 가기((ch - 2 + c) % c + 1); // %는 음수를 남기니 c를 더해 둔다 break; case "B": if (prev != 0) { 가기(prev); } break; case "+": vol = Mathf.Min(30, vol + 1); muted = false; break; case "-": vol = Mathf.Max(0, vol - 1); muted = false; break; case "M": muted = !muted; break; case "?": if (muted) { Console.WriteLine("CH " + ch + " MUTE"); } else { Console.WriteLine("CH " + ch + " VOL " + vol); } break; } break; }}