{ }codelper
reversing stringsP0316

A note cipher that reverses each half

Some friends use a cipher when they pass notes. Let L be the length of a word and let h be the quotient of L divided by 2. The first h letters of the word are written backwards, and the last h letters are also written backwards on their own. If L is odd, one letter is left in the very middle, and it stays where it is. For example, notebook becomes etonkoob, because note and book are each reversed. pencils becomes nepcsli, because pen and ils are each reversed and the middle c stays. So a word of length 3 or less does not change. The first line gives the number of words n, and each of the next n lines gives one word. For each word, print the ciphered string on its own line.

Input
1 ≤ n ≤ 100.
Each word has length 1 to 1,000 and consists only of English uppercase letters, lowercase letters and digits
Output
n lines, each the ciphered word
Example 1 · stdin
4
notebook
pencils
ab
x
stdout
etonkoob
nepcsli
ab
x
main.py
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

Reversing a piece of a string looks different in each language.
Python uses s[:h][::-1] (a new string read backwards), JS/TS strings have no reverse, so [...t].reverse().join(""), Java uses new StringBuilder(t).reverse().toString(), C# converts to char[] and calls Array.Reverse(a, start, count), C uses a loop that swaps two characters while walking from both ends to the middle, C++ uses std::reverse(s.begin(), s.begin() + h), and Craykon uses s.Substring(0, h).Reverse().
The Python, JS, Java and Craykon solutions build new reversed strings and join them; the C, C++ and C# (char array) solutions change the characters in place.
The two numbers that name a piece also mean different things.
Python s[a:b], JS slice(a, b), Java substring(a, b) and C++ std::reverse(first, last) take (start, end), and the end position is not included.
C# Array.Reverse(array, start, count) and Craykon Substring(start, count) take (start, count).
Six traps: (1) If the back half starts at position h, the middle letter is reversed too when the length is odd (pencils in the example becomes nepslic).
The back half starts at position (length − h).
(2) Python s[-h:] and JS s.slice(-h) mean "the last h characters", but when h is 0, -0 is 0, so you get the whole string (x in the example becomes xx).
(3) Python reversed(t) gives an iterator, not a string.
str(reversed(t)) is the text <reversed object at …>, so join it with "".join(reversed(t)).
(4) reverse() on a JS array does not return a new array; it reverses that array itself.
If you reverse an array and then slice it again, you are slicing the already reversed one.
(5) In C, if the swapping loop does not stop at the middle of the range and runs to its end, everything is swapped twice and comes back unchanged (notebook is printed as it was).
(6) Passing an end position where (start, count) is expected: C# Array.Reverse(a, length − h, length) runs past the array and stops with an ArgumentException, and Craykon s.Substring(h, length − h) raises no error and cuts the middle letter together with the whole back half (notebook becomes etonbookkoob).

Pythonmain.py · 8 lines
n = int(input())for _ in range(n):    s = input().strip()    h = len(s) // 2    # 앞쪽 h글자, 한가운데(길이가 홀수일 때만 한 글자), 뒤쪽 h글자    front, middle, back = s[:h], s[h:len(s) - h], s[len(s) - h:]    # [::-1]은 거꾸로 읽은 새 문자열을 만든다    print(front[::-1] + middle + back[::-1])
JavaScriptmain.js · 15 lines
const lines = require("fs").readFileSync(0, "utf8").split("\n");const n = Number(lines[0]);// 문자열에는 reverse가 없어서 글자 배열로 바꿔 뒤집고 다시 잇는다const reversed = (t) => [...t].reverse().join("");const out = [];for (let i = 1; i <= n; i++) {  const s = lines[i].trim();  const h = Math.floor(s.length / 2);  // 앞쪽 h글자, 한가운데(길이가 홀수일 때만 한 글자), 뒤쪽 h글자  const front = s.slice(0, h);  const middle = s.slice(h, s.length - h);  const back = s.slice(s.length - h);  out.push(reversed(front) + middle + reversed(back));}console.log(out.join("\n"));
TypeScriptmain.ts · 16 lines
import { readFileSync } from "node:fs";const lines: string[] = readFileSync(0, "utf8").split("\n");const n: number = Number(lines[0]);// 문자열에는 reverse가 없어서 글자 배열로 바꿔 뒤집고 다시 잇는다const reversed = (t: string): string => [...t].reverse().join("");const out: string[] = [];for (let i = 1; i <= n; i++) {  const s: string = lines[i].trim();  const h: number = Math.floor(s.length / 2);  // 앞쪽 h글자, 한가운데(길이가 홀수일 때만 한 글자), 뒤쪽 h글자  const front: string = s.slice(0, h);  const middle: string = s.slice(h, s.length - h);  const back: string = s.slice(s.length - h);  out.push(reversed(front) + middle + reversed(back));}console.log(out.join("\n"));
JavaMain.java · 27 lines
import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader; public class Main {    // String은 고칠 수 없어서 StringBuilder에 담아 뒤집는다    static String reversed(String t) {        return new StringBuilder(t).reverse().toString();    }     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 i = 0; i < n; i++) {            String s = in.readLine().trim();            int len = s.length();            int h = len / 2;            // substring(시작, 끝): 끝 자리는 들어가지 않는다            String front = s.substring(0, h);            String middle = s.substring(h, len - h);            String back = s.substring(len - h);            out.append(reversed(front)).append(middle).append(reversed(back)).append('\n');        }        System.out.print(out);    }}
C#Main.cs · 22 lines
using System;using System.Text; class Program{    static void Main()    {        int n = int.Parse(Console.ReadLine().Trim());        var sb = new StringBuilder();        for (int i = 0; i < n; i++)        {            // string은 고칠 수 없어서 char 배열로 바꿔 그 자리에서 뒤집는다            char[] a = Console.ReadLine().Trim().ToCharArray();            int h = a.Length / 2;            // Array.Reverse(배열, 시작, 개수): 셋째 값은 끝 자리가 아니라 개수다            Array.Reverse(a, 0, h);            Array.Reverse(a, a.Length - h, h);            sb.Append(new string(a)).Append('\n');        }        Console.Write(sb);    }}
C++main.cpp · 17 lines
#include <algorithm>#include <iostream>#include <string> int main() {    int n;    std::cin >> n;    for (int i = 0; i < n; i++) {        std::string s;        std::cin >> s;        auto h = s.size() / 2;        // std::reverse(시작, 끝): 끝은 들어가지 않는다. 그 자리에서 뒤집는다        std::reverse(s.begin(), s.begin() + h);        std::reverse(s.end() - h, s.end());        std::cout << s << '\n';    }}
Cmain.c · 28 lines
#include <stdio.h>#include <string.h> /* s[from] ~ s[to]를 그 자리에서 뒤집는다. 양 끝에서 가운데로 오며 맞바꾼다 */static void reverse_range(char *s, int from, int to) {    while (from < to) {        char tmp = s[from];        s[from] = s[to];        s[to] = tmp;        from++;        to--;    }} int main(void) {    int n;    static char s[1001];    scanf("%d", &n);    for (int i = 0; i < n; i++) {        scanf("%1000s", s);        int len = (int)strlen(s);        int h = len / 2;        reverse_range(s, 0, h - 1);         /* 앞쪽 h글자 */        reverse_range(s, len - h, len - 1); /* 뒤쪽 h글자 */        printf("%s\n", s);    }    return 0;}
Craykonmain.cray · 11 lines
n = Console.ReadLine().ToNumber();for (i = 0; i < n; i++){    s = Console.ReadLine().Trim();    h = Mathf.Quot(s.Length, 2);    // 부분문자열(시작, 개수): 둘째 값은 끝 자리가 아니라 글자 수다    앞쪽 = s.Substring(0, h);    가운데 = s.Substring(h, s.Length - 2 * h);    뒤쪽 = s.Substring(s.Length - h, h);    Console.WriteLine(앞쪽.Reverse() + 가운데 + 뒤쪽.Reverse());}