{ }codelper
文字型P0226

座席コードから券の番号を求める

小さな劇場の座席は、列ごとに w 席ずつある。
1 階の列は前から A, B, …, Z で、その後ろに 2 階の列が前から a, b, …, z と続く。
座席コードは、列の文字一つとその列の席番号(1〜w の数字一つ)をつなげて書いたものである。
たとえば B3 は 1 階 B 列の 3 番席である。
券の番号は A1 が 1 番、A2 が 2 番で、一つの列が終わると次の列の 1 番席に続く。
Z 列の次は a 列である。
つまり列の文字が前から r 番目の列(A が 0 番目、Z が 25 番目、a が 26 番目、z が 51 番目)で席番号が s なら、券の番号は r × w + s である。
一行目に w と座席コードの数 n が空白一つで区切って与えられ、続く n 行に座席コードが一つずつ与えられる。
座席コードごとに券の番号を一行に一つずつ出力せよ。

入力
1 ≤ w ≤ 9、1 ≤ n ≤ 100。
座席コードは二文字で、一文字目は英大文字(A〜Z)か英小文字(a〜z)、二文字目は 1 以上 w 以下の数字
出力
n 行、各行は券の番号(整数)
例 1 · stdin
4 4
A1
B3
a2
Z4
stdout
1
7
106
104
main.py
入力(stdin)

実行すると、これらの行が順に input()・標準入力に渡されます(実行中に入力を求めません)。

$ 準備完了

コードを入力して解くにはパソコンで開いてください。モバイルでは問題と解答を見られます。

ほかの言語では?言語別の解答を見る · 8 言語の解答

文字一つを数に変える方法は言語ごとに違います。
C・C++・Java・C# の char は文字コードを持つ整数なので、row - 'A' がそのまま列の順番で、seat - '0' が席番号です。
ところが - '0' を忘れて seat をそのまま計算に使うと、エラーなしに文字コードが入ります('3' は 51)。
Python・JS・TS・Craykon には文字型がなく一文字の文字列だけなので、コードを取り出します:Python ord(c)、JS・TS c.charCodeAt(0)、Craykon 文字.コード(c)。
Python の ord("3") も 3 ではなく 51 です(数字一つなら int("3") でも済みます)。
JS では code[1] が文字列 "3" なので、r * w + code[1] が足し算ではなく連結になり "43" のような答えになります。
Craykon でも数 + 文字列は連結なので r * w + code[1] は "43" になります。
文字.コード で数にしてから計算します。
二つ目の落とし穴は 2 階です。
文字コードでは Z(90)と a(97)の間に別の文字が 6 個あるので、すべての列の文字から 'A' を引くと a が 26 ではなく 32 番目の列になります。
先に大文字かどうかを見分け('A' <= row <= 'Z'、Java Character.isUpperCase、C# char.IsUpper)、小文字は 26 + (row - 'a') と数えます。
列を 0 から数えることも忘れずに。
A を 1 番目の列と数えると A1 が w + 1 になります。

Pythonmain.py · 11 行
w, n = map(int, input().split())for _ in range(n):    code = input().strip()    row, seat = code[0], code[1]    # 글자는 ord로 코드를 얻어 뺀다. 1층 A~Z는 0~25째 줄, 2층 a~z는 26~51째 줄    if "A" <= row <= "Z":        r = ord(row) - ord("A")    else:        r = 26 + ord(row) - ord("a")    s = ord(seat) - ord("0")        # int(seat)와 같다. ord(seat)만 쓰면 49~57이다    print(r * w + s)
JavaScriptmain.js · 14 行
const lines = require("fs").readFileSync(0, "utf8").split("\n");const [w, n] = lines[0].trim().split(/\s+/).map(Number);const A = "A".charCodeAt(0), Z = "Z".charCodeAt(0), a = "a".charCodeAt(0), ZERO = "0".charCodeAt(0);const out = [];for (let i = 1; i <= n; i++) {  const code = lines[i].trim();  const row = code.charCodeAt(0);  // 1층 A~Z는 0~25째 줄, 2층 a~z는 26~51째 줄  const r = row <= Z ? row - A : 26 + row - a;  // code[1]은 문자열 "7"이다. 수에 + 하면 이어 붙여지니 코드로 바꿔 뺀다  const s = code.charCodeAt(1) - ZERO;  out.push(r * w + s);}console.log(out.join("\n"));
TypeScriptmain.ts · 12 行
import { readFileSync } from "node:fs";const lines: string[] = readFileSync(0, "utf8").split("\n");const [w, n]: number[] = lines[0].trim().split(/\s+/).map(Number);const out: number[] = [];for (let i = 1; i <= n; i++) {  const code: string = lines[i].trim();  const row: number = code.charCodeAt(0);  const r: number = row <= "Z".charCodeAt(0) ? row - "A".charCodeAt(0) : 26 + row - "a".charCodeAt(0);  const s: number = code.charCodeAt(1) - "0".charCodeAt(0);  out.push(r * w + s);}console.log(out.join("\n"));
JavaMain.java · 23 行
import java.io.BufferedReader;import java.io.InputStreamReader;import java.util.StringTokenizer; public class Main {    public static void main(String[] args) throws Exception {        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));        StringTokenizer st = new StringTokenizer(br.readLine());        int w = Integer.parseInt(st.nextToken());        int n = Integer.parseInt(st.nextToken());        StringBuilder out = new StringBuilder();        for (int i = 0; i < n; i++) {            String code = br.readLine().trim();            char row = code.charAt(0);            char seat = code.charAt(1);            // char끼리 빼면 int다. 1층 A~Z는 0~25째 줄, 2층 a~z는 26~51째 줄            int r = Character.isUpperCase(row) ? row - 'A' : 26 + (row - 'a');            int s = seat - '0'; // seat를 그대로 계산에 쓰면 글자 코드(49~57)가 들어간다            out.append(r * w + s).append('\n');        }        System.out.print(out);    }}
C#Main.cs · 24 行
using System;using System.Text; class Program{    static void Main()    {        string[] first = Console.ReadLine().Split(' ', StringSplitOptions.RemoveEmptyEntries);        int w = int.Parse(first[0]);        int n = int.Parse(first[1]);        var sb = new StringBuilder();        for (int i = 0; i < n; i++)        {            string code = Console.ReadLine().Trim();            char row = code[0];            char seat = code[1];            // char끼리 빼면 int다. 1층 A~Z는 0~25째 줄, 2층 a~z는 26~51째 줄            int r = char.IsUpper(row) ? row - 'A' : 26 + (row - 'a');            int s = seat - '0'; // char.GetNumericValue(seat)도 되지만 double을 돌려준다            sb.Append(r * w + s).Append('\n');        }        Console.Write(sb);    }}
C++main.cpp · 17 行
#include <iostream>#include <string> int main() {    std::ios::sync_with_stdio(false);    int w, n;    std::cin >> w >> n;    for (int i = 0; i < n; i++) {        std::string code;        std::cin >> code;        char row = code[0], seat = code[1];        // 1층 A~Z는 0~25째 줄, 2층 a~z는 26~51째 줄        int r = (row >= 'A' && row <= 'Z') ? row - 'A' : 26 + (row - 'a');        int s = seat - '0';        std::cout << r * w + s << '\n';    }}
Cmain.c · 16 行
#include <stdio.h> int main(void) {    int w, n;    scanf("%d %d", &w, &n);    for (int i = 0; i < n; i++) {        char code[8];        scanf("%7s", code);        char row = code[0], seat = code[1];        /* char는 작은 정수라 바로 뺄 수 있다. 1층 A~Z는 0~25째 줄, 2층 a~z는 26~51째 줄 */        int r = (row >= 'A' && row <= 'Z') ? row - 'A' : 26 + (row - 'a');        int s = seat - '0'; /* seat만 쓰면 '7'의 코드 55가 들어간다 */        printf("%d\n", r * w + s);    }    return 0;}
Craykonmain.cray · 21 行
first = コンソール.行読み().空白除去().分ける(" ");w = first[0].数に();n = first[1].数に();繰り返す (i = 0; i < n; i++){    code = コンソール.行読み().空白除去();    // 크레이콘에는 글자 타입이 없다. 한 글자 문자열을 글자.코드로 수로 바꿔 뺀다    row = 文字.コード(code[0]);    seat = 文字.コード(code[1]);    r = 0;    もし (row <= 文字.コード("Z"))    {        r = row - 文字.コード("A");    }    でなければ    {        r = 26 + row - 文字.コード("a");    }    s = seat - 文字.コード("0");    コンソール.書く(r * w + s);}