When typing English on a keyboard, each letter is typed with a fixed hand.
The left-hand letters are the 15 letters q w e r t a s d f g z x c v b, and the right-hand letters are the 11 letters y u i o p h j k l n m.
An uppercase letter is typed with the same hand as its lowercase letter.
Characters that are not English letters (digits, spaces, punctuation) belong to neither hand.
One line of text is given.
A one-hand stretch is a part of the text made of one or more English letters in a row, with no other character between them, that all belong to the same hand.
Print three lines.
On the first line, print the length of the longest one-hand stretch.
On the second line, print that stretch exactly as it appears in the input (keeping its case). If several stretches are the longest, print the leftmost one.
If there is no English letter at all, print 0 on the first line and "-" on the second line.
On the third line, print the number of places where two adjacent characters are both English letters and belong to different hands.
If even one other character sits between two English letters, those two are not adjacent.
Input
One line of length 1 to 100,000. It uses only keyboard characters from space (code 32) to ~ (code 126). The line may have spaces at its start or end.
Output
Three lines: the length of the longest one-hand stretch, the stretch (- if none), the number of hand changes
Example 1 · stdin
Hello, minimum stewardess!
stdout
10
stewardess
2
Example 2 · stdin
Ab yo QAh
stdout
2
Ab
1
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
Walk the text one character at a time, carrying only "the hand of the previous character" and "the length of the stretch ending at this character". Getting one character: Python, JS, TS, C# and Craykon s[i], Java s.charAt(i), C/C++ s[i] (a single char in C; a string of length 1 or a char elsewhere). To ignore case, convert with Python ch.lower(), JS/TS toLowerCase(), Java Character.toLowerCase, C# char.ToLowerInvariant, C/C++ tolower or Craykon .ToLower(), then look it up in the hand table. Looking up differs too: Python c in LEFT, JS/TS LEFT.includes(c), Java/C# LEFT.indexOf(c) >= 0 (C# IndexOf), C strchr, C++ find != npos, Craykon LEFT.Contains(c). C's strchr also finds the terminating '\0', so strchr(LEFT, '\0') is true as well. The C solution first asks isalpha whether the character is an English letter and only then looks it up. The first trap is the end of the line. Comparing with the best only when a stretch breaks misses the last stretch running to the end of the line. Comparing at every character avoids this. Second, ties go to the leftmost one, so compare with > (>= keeps the rightmost). Third, when the hand changes, the new stretch starts at that character, so its length is 1, not 0. Fourth, treating every non-letter as "right hand if not left hand" puts digits and spaces into stretches, and comparing hand changes with "the last letter seen" counts across spaces. Read the line as it is without trimming spaces at its ends (C fgets also keeps the newline, so remove only that).
Pythonmain.py · 34 lines
LEFT = set("qwertasdfgzxcvb")RIGHT = set("yuiophjklnm")def hand(ch): """영어 글자면 "L"·"R", 아니면 None. 대문자는 소문자로 바꿔 찾는다.""" c = ch.lower() if c in LEFT: return "L" if c in RIGHT: return "R" return Nones = input()best_len, best_start = 0, -1run = 0 # 지금 글자에서 끝나는 한 손 덩이의 길이switches = 0prev = None # 바로 앞 글자의 손(글자가 아니면 None)for i, ch in enumerate(s): h = hand(ch) if h is None: run = 0 elif h == prev: run += 1 else: if prev is not None: switches += 1 # 바로 붙은 두 글자의 손이 다르다 run = 1 # 새 덩이는 이 글자부터 # 글자마다 견주면 줄 끝에서 끝나는 덩이도 놓치지 않는다. >라서 같으면 왼쪽 것이 남는다 if run > best_len: best_len, best_start = run, i - run + 1 prev = hprint(best_len)print(s[best_start:best_start + best_len] if best_len else "-")print(switches)
JavaScriptmain.js · 21 lines
const s = require("fs").readFileSync(0, "utf8").split("\n")[0].replace(/\r$/, "");const LEFT = "qwertasdfgzxcvb", RIGHT = "yuiophjklnm";// 영어 글자면 "L"·"R", 아니면 null. 대문자는 소문자로 바꿔 찾는다// (includes는 부분 문자열을 찾으니 빈칸·기호 한 글자도 들어갈 수 없게 글자 하나만 넘긴다)const hand = (ch) => { const c = ch.toLowerCase(); return LEFT.includes(c) ? "L" : RIGHT.includes(c) ? "R" : null;};let bestLen = 0, bestStart = -1, run = 0, switches = 0, prev = null;for (let i = 0; i < s.length; i++) { const h = hand(s[i]); if (h === null) run = 0; else if (h === prev) run++; else { if (prev !== null) switches++; run = 1; } if (run > bestLen) { bestLen = run; bestStart = i - run + 1; } // 같으면 왼쪽 것 prev = h;}console.log(`${bestLen}\n${bestLen ? s.slice(bestStart, bestStart + bestLen) : "-"}\n${switches}`);
TypeScriptmain.ts · 23 lines
import { readFileSync } from "node:fs";const s: string = readFileSync(0, "utf8").split("\n")[0].replace(/\r$/, "");const LEFT = "qwertasdfgzxcvb", RIGHT = "yuiophjklnm";type Hand = "L" | "R" | null;// 영어 글자면 "L"·"R", 아니면 null. 대문자는 소문자로 바꿔 찾는다const hand = (ch: string): Hand => { const c = ch.toLowerCase(); return LEFT.includes(c) ? "L" : RIGHT.includes(c) ? "R" : null;};let bestLen = 0, bestStart = -1, run = 0, switches = 0;let prev: Hand = null;for (let i = 0; i < s.length; i++) { const h: Hand = hand(s[i]); if (h === null) run = 0; else if (h === prev) run++; else { if (prev !== null) switches++; run = 1; } if (run > bestLen) { bestLen = run; bestStart = i - run + 1; } // 같으면 왼쪽 것 prev = h;}console.log(`${bestLen}\n${bestLen ? s.slice(bestStart, bestStart + bestLen) : "-"}\n${switches}`);
JavaMain.java · 35 lines
import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;public class Main { static final String LEFT = "qwertasdfgzxcvb", RIGHT = "yuiophjklnm"; // 영어 글자면 'L'·'R', 아니면 0. 대문자는 소문자로 바꿔 찾는다 static char hand(char ch) { char c = Character.toLowerCase(ch); if (LEFT.indexOf(c) >= 0) return 'L'; if (RIGHT.indexOf(c) >= 0) return 'R'; return 0; } public static void main(String[] args) throws IOException { String s = new BufferedReader(new InputStreamReader(System.in)).readLine(); int bestLen = 0, bestStart = -1, run = 0, switches = 0; char prev = 0; for (int i = 0; i < s.length(); i++) { char h = hand(s.charAt(i)); if (h == 0) run = 0; else if (h == prev) run++; else { if (prev != 0) switches++; run = 1; } if (run > bestLen) { bestLen = run; bestStart = i - run + 1; } // 같으면 왼쪽 것 prev = h; } System.out.println(bestLen); System.out.println(bestLen > 0 ? s.substring(bestStart, bestStart + bestLen) : "-"); System.out.println(switches); }}
C#Main.cs · 38 lines
using System;class Program{ const string Left = "qwertasdfgzxcvb", Right = "yuiophjklnm"; // 영어 글자면 'L'·'R', 아니면 '\0'. 대문자는 소문자로 바꿔 찾는다 static char Hand(char ch) { char c = char.ToLowerInvariant(ch); if (Left.IndexOf(c) >= 0) return 'L'; if (Right.IndexOf(c) >= 0) return 'R'; return '\0'; } static void Main() { string s = Console.ReadLine(); int bestLen = 0, bestStart = -1, run = 0, switches = 0; char prev = '\0'; for (int i = 0; i < s.Length; i++) { char h = Hand(s[i]); if (h == '\0') run = 0; else if (h == prev) run++; else { if (prev != '\0') switches++; run = 1; } if (run > bestLen) { bestLen = run; bestStart = i - run + 1; } // 같으면 왼쪽 것 prev = h; } Console.WriteLine(bestLen); Console.WriteLine(bestLen > 0 ? s.Substring(bestStart, bestLen) : "-"); Console.WriteLine(switches); }}
C++main.cpp · 33 lines
#include <cctype>#include <iostream>#include <string>const std::string LEFT = "qwertasdfgzxcvb", RIGHT = "yuiophjklnm";// 영어 글자면 'L'·'R', 아니면 0. 대문자는 소문자로 바꿔 찾는다char hand(char ch) { char c = (char)std::tolower((unsigned char)ch); if (LEFT.find(c) != std::string::npos) return 'L'; if (RIGHT.find(c) != std::string::npos) return 'R'; return 0;}int main() { std::string s; std::getline(std::cin, s); if (!s.empty() && s.back() == '\r') s.pop_back(); int bestLen = 0, bestStart = -1, run = 0, switches = 0; char prev = 0; for (int i = 0; i < (int)s.size(); i++) { char h = hand(s[i]); if (h == 0) run = 0; else if (h == prev) run++; else { if (prev != 0) switches++; run = 1; } if (run > bestLen) { bestLen = run; bestStart = i - run + 1; } // 같으면 왼쪽 것 prev = h; } std::cout << bestLen << '\n' << (bestLen > 0 ? s.substr(bestStart, bestLen) : "-") << '\n' << switches << '\n';}
Cmain.c · 35 lines
#include <ctype.h>#include <stdio.h>#include <string.h>static char line[100005];/* 영어 글자면 'L'·'R', 아니면 0. strchr는 끝의 '\0'도 찾으니 글자인지 먼저 본다 */static char hand(char ch) { if (!isalpha((unsigned char)ch)) return 0; char c = (char)tolower((unsigned char)ch); return strchr("qwertasdfgzxcvb", c) ? 'L' : 'R';}int main(void) { if (!fgets(line, sizeof line, stdin)) return 0; line[strcspn(line, "\r\n")] = '\0'; /* fgets는 줄바꿈까지 담는다 */ int best_len = 0, best_start = -1, run = 0, switches = 0; char prev = 0; for (int i = 0; line[i]; i++) { char h = hand(line[i]); if (h == 0) run = 0; else if (h == prev) run++; else { if (prev != 0) switches++; run = 1; } if (run > best_len) { best_len = run; best_start = i - run + 1; } /* 같으면 왼쪽 것 */ prev = h; } printf("%d\n", best_len); if (best_len > 0) printf("%.*s\n", best_len, line + best_start); else puts("-"); printf("%d\n", switches); return 0;}
Craykonmain.cray · 62 lines
LEFT = "qwertasdfgzxcvb";RIGHT = "yuiophjklnm";// 영어 글자면 "L"·"R", 아니면 "". 대문자는 소문자로 바꿔 찾는다// (있나는 부분 문자열을 찾으니 늘 한 글자만 넘긴다)손(ch){ c = ch.ToLower(); if (LEFT.Contains(c)) { return "L"; } if (RIGHT.Contains(c)) { return "R"; } return "";}s = Console.ReadLine();bestLen = 0;bestStart = -1;run = 0; // 지금 글자에서 끝나는 한 손 덩이의 길이switches = 0;prev = ""; // 바로 앞 글자의 손("": 글자가 아님)for (i = 0; i < s.Length; i++){ h = 손(s[i]); if (h == "") { run = 0; } else if (h == prev) { run++; } else { if (prev != "") { switches++; } run = 1; } // 글자마다 견주면 줄 끝에서 끝나는 덩이도 놓치지 않는다. >라서 같으면 왼쪽 것 if (run > bestLen) { bestLen = run; bestStart = i - run + 1; } prev = h;}Console.WriteLine(bestLen);if (bestLen > 0){ Console.WriteLine(s.Substring(bestStart, bestLen));}else{ Console.WriteLine("-");}Console.WriteLine(switches);