The first line gives the number of exception words k, and the second line gives the k exception words separated by single spaces (an empty line if k is 0).
The third line gives the number of titles n, followed by n English titles, one per line.
Rewrite each title in title case and print them one per line.
A title line is split into words by spaces. Spaces at the start and end of the line are dropped, and any number of spaces between words becomes one.
If a word ends with :, a subtitle starts after it. The : is part of that word, so "of:" does not equal the exception word "of".
For each word, first turn all English uppercase letters into lowercase.
If the word equals one of the exception words and is not the first word, not the last word, and not the word right after a word ending with : (the first word of a subtitle), leave it all lowercase.
Every other word gets only its first character in uppercase. If the first character is a digit, leave it as it is.
A character after ' or - does not start a new word, so it stays lowercase ("don't" → "Don't", "e-mail" → "E-mail", "3D" → "3d").
Print the rewritten words joined by single spaces.
Input
0 ≤ k ≤ 16; the exception words are distinct and have 1 to 10 lowercase English letters. 1 ≤ n ≤ 100. Each title line has length 1 to 200, consists only of English uppercase and lowercase letters, digits, ', -, : and spaces, and has at least one word. Every word starts with an English letter or a digit, and : can appear only at the very end of a word
Output
the n rewritten titles, one per line
Example 1 · stdin
5
a of the and in
4
the lord OF the rings
war and peace
don't look 3d e-mail
the
stdout
The Lord of the Rings
War and Peace
Don't Look 3d E-mail
The
Example 2 · stdin
2
of the
3
OF THE
THE END OF THE WORLD
the hobbit: the desolation of smaug
stdout
Of The
The End of the World
The Hobbit: The Desolation of Smaug
main.py
Error List00F8 ↓ · ⇧F8 ↑
Input (stdin)
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
There are five traps. First, Python str.title() treats everything right after a non-letter as a new word and produces "Don'T", "E-Mail" and "3D". Change only the first character of each word, as in low[0].upper() + low[1:] (capitalize() does this too). Changing case is JS/TS toUpperCase/toLowerCase, Java toUpperCase(Locale.ROOT), C# ToUpperInvariant/char.ToUpperInvariant, C/C++ toupper/tolower per character, Craykon ToUpper()/ToLower(). Second, ask whether a word is an exception only after lowercasing it, so that "OF" is caught too. Third, the last word is exempt as well as the first: "OF THE" becomes "Of The". Fourth, the first word of a subtitle after : is exempt too: the second "the" in "the hobbit: the desolation" becomes "The". Ask whether the previous word ends with : using Python endswith(":"), JS/TS/Java endsWith(":"), C# EndsWith(':'), C w[strlen(w) - 1] == ':', C++ w.back() == ':', Craykon EndsWith(":"). Fifth, trimming and splitting. Python split() with no argument, C# Split(' ', StringSplitOptions.RemoveEmptyEntries), C strtok, C++ >> and Craykon Split() with no separator skip all spaces at both ends and between words. split(" ") in JS/TS/Java leaves empty strings between two spaces and at the front, so trim() first and split by the regex / +/ or " +". Joining is Python " ".join(out), JS/TS out.join(" "), Java String.join(" ", words), C# string.Join(" ", words), Craykon out.Join(" "); C and C++ print a space before every word except the first.
Pythonmain.py · 14 lines
k = int(input())small = set(input().split())n = int(input())for _ in range(n): words = input().split() # 인자 없는 split()은 앞뒤·여러 칸 공백을 모두 없앤다 out = [] for i, w in enumerate(words): low = w.lower() # 첫 낱말, 마지막 낱말, : 뒤의 부제 첫 낱말은 예외 낱말이어도 대문자로 시작한다 if 0 < i < len(words) - 1 and not words[i - 1].endswith(":") and low in small: out.append(low) else: out.append(low[0].upper() + low[1:]) # title()은 ' 와 - 뒤도 대문자로 만든다 print(" ".join(out))
JavaScriptmain.js · 17 lines
const lines = require("fs").readFileSync(0, "utf8").split("\n");const k = Number(lines[0]);const small = new Set(lines[1].split(" ").filter((w) => w !== ""));const n = Number(lines[2]);const out = [];for (const line of lines.slice(3, 3 + n)) { // trim 뒤에 공백 덩어리로 나눈다: split(" ")은 빈 칸마다 빈 문자열을 남긴다 const words = line.trim().split(/ +/); const fixed = words.map((w, i) => { const low = w.toLowerCase(); // 첫 낱말, 마지막 낱말, : 뒤의 부제 첫 낱말은 예외 낱말이어도 대문자로 시작한다 if (i > 0 && i < words.length - 1 && !words[i - 1].endsWith(":") && small.has(low)) return low; return low[0].toUpperCase() + low.slice(1); }); out.push(fixed.join(" "));}console.log(out.join("\n"));
TypeScriptmain.ts · 18 lines
import { readFileSync } from "node:fs";const lines: string[] = readFileSync(0, "utf8").split("\n");const k: number = Number(lines[0]);const small = new Set<string>(lines[1].split(" ").filter((w) => w !== ""));const n: number = Number(lines[2]);const out: string[] = [];for (const line of lines.slice(3, 3 + n)) { // trim 뒤에 공백 덩어리로 나눈다: split(" ")은 빈 칸마다 빈 문자열을 남긴다 const words: string[] = line.trim().split(/ +/); const fixed: string[] = words.map((w: string, i: number): string => { const low: string = w.toLowerCase(); // 첫 낱말, 마지막 낱말, : 뒤의 부제 첫 낱말은 예외 낱말이어도 대문자로 시작한다 if (i > 0 && i < words.length - 1 && !words[i - 1].endsWith(":") && small.has(low)) return low; return low[0].toUpperCase() + low.slice(1); }); out.push(fixed.join(" "));}console.log(out.join("\n"));
JavaMain.java · 30 lines
import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.util.Arrays;import java.util.HashSet;import java.util.Locale;import java.util.Set;public class Main { public static void main(String[] args) throws IOException { BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); in.readLine(); Set<String> small = new HashSet<>(Arrays.asList(in.readLine().trim().split(" "))); int n = Integer.parseInt(in.readLine().trim()); StringBuilder out = new StringBuilder(); for (int t = 0; t < n; t++) { // trim 뒤 정규식 " +"로 나눈다: split(" ")은 빈칸 두 개 사이에 빈 문자열을 남긴다 String[] words = in.readLine().trim().split(" +"); for (int i = 0; i < words.length; i++) { String low = words[i].toLowerCase(Locale.ROOT); // 첫 낱말, 마지막 낱말, : 뒤의 부제 첫 낱말은 예외 낱말이어도 대문자로 시작한다 boolean inner = i > 0 && i < words.length - 1 && !words[i - 1].endsWith(":"); if (inner && small.contains(low)) words[i] = low; else words[i] = low.substring(0, 1).toUpperCase(Locale.ROOT) + low.substring(1); } out.append(String.join(" ", words)).append('\n'); } System.out.print(out); }}
C#Main.cs · 26 lines
using System;using System.Collections.Generic;class Program{ static void Main() { Console.ReadLine(); var small = new HashSet<string>(Console.ReadLine().Split(' ', StringSplitOptions.RemoveEmptyEntries)); int n = int.Parse(Console.ReadLine()); for (int t = 0; t < n; t++) { // RemoveEmptyEntries가 앞뒤·여러 칸 공백에서 생기는 빈 조각을 버린다 string[] words = Console.ReadLine().Split(' ', StringSplitOptions.RemoveEmptyEntries); for (int i = 0; i < words.Length; i++) { string low = words[i].ToLowerInvariant(); // 첫 낱말, 마지막 낱말, : 뒤의 부제 첫 낱말은 예외 낱말이어도 대문자로 시작한다 bool inner = i > 0 && i < words.Length - 1 && !words[i - 1].EndsWith(':'); if (inner && small.Contains(low)) words[i] = low; else words[i] = char.ToUpperInvariant(low[0]) + low.Substring(1); } Console.WriteLine(string.Join(" ", words)); } }}
C++main.cpp · 35 lines
#include <cctype>#include <iostream>#include <sstream>#include <string>#include <unordered_set>#include <vector>int main() { int k, n; std::cin >> k; std::unordered_set<std::string> small; for (int i = 0; i < k; i++) { std::string w; std::cin >> w; small.insert(w); } std::cin >> n; std::string line; std::getline(std::cin, line); // n 뒤의 줄 끝 for (int t = 0; t < n && std::getline(std::cin, line); t++) { // >> 는 앞뒤·여러 칸 빈칸을 건너뛰고 낱말만 읽는다 std::istringstream ss(line); std::vector<std::string> words; for (std::string w; ss >> w;) words.push_back(w); for (size_t i = 0; i < words.size(); i++) { std::string& w = words[i]; for (char& c : w) c = (char)std::tolower((unsigned char)c); // 첫 낱말, 마지막 낱말, : 뒤의 부제 첫 낱말은 예외 낱말이어도 대문자로 시작한다 bool inner = i > 0 && i + 1 < words.size() && words[i - 1].back() != ':'; if (!(inner && small.count(w))) w[0] = (char)std::toupper((unsigned char)w[0]); std::cout << (i ? " " : "") << w; } std::cout << '\n'; }}
Cmain.c · 39 lines
#include <stdio.h>#include <string.h>#include <ctype.h>static char small[20][16];static int k;static int isSmall(const char *w) { for (int i = 0; i < k; i++) if (strcmp(small[i], w) == 0) return 1; return 0;}int main(void) { int n; char line[256]; scanf("%d", &k); for (int i = 0; i < k; i++) scanf("%15s", small[i]); scanf("%d", &n); fgets(line, sizeof line, stdin); /* n 뒤의 줄 끝 */ for (int t = 0; t < n; t++) { if (!fgets(line, sizeof line, stdin)) break; line[strcspn(line, "\n")] = '\0'; /* strtok은 앞뒤·여러 칸 빈칸을 건너뛰고 낱말만 준다 */ char *words[128]; int m = 0; for (char *w = strtok(line, " "); w; w = strtok(NULL, " ")) words[m++] = w; for (int i = 0; i < m; i++) { for (char *p = words[i]; *p; p++) *p = (char)tolower((unsigned char)*p); /* 첫 낱말, 마지막 낱말, : 뒤의 부제 첫 낱말은 예외 낱말이어도 대문자로 시작한다 */ int inner = i > 0 && i < m - 1 && words[i - 1][strlen(words[i - 1]) - 1] != ':'; if (!(inner && isSmall(words[i]))) words[i][0] = (char)toupper((unsigned char)words[i][0]); printf(i == 0 ? "%s" : " %s", words[i]); } putchar('\n'); } return 0;}
Craykonmain.cray · 27 lines
k = Console.ReadLine().ToNumber();small = Dict();foreach (w in Console.ReadLine().Split()){ small[w] = true;}n = Console.ReadLine().ToNumber();for (t = 0; t < n; t++){ // 기준 없는 나누기()는 앞뒤·여러 칸 빈칸을 모두 건너뛴다 words = Console.ReadLine().Trim().Split(); out = []; for (i = 0; i < words.Count; i++) { low = words[i].ToLower(); // 첫 낱말, 마지막 낱말, : 뒤의 부제 첫 낱말은 예외 낱말이어도 대문자로 시작한다 if (i > 0 && i < words.Count - 1 && !words[i - 1].EndsWith(":") && small.Contains(low)) { out.Add(low); } else { out.Add(low[0].ToUpper() + low.Substring(1)); } } Console.WriteLine(out.Join(" "));}