『N個の値を入力するプログラム』が意外とめんどくさい

3 min read読了の目安(約2700字 6

いやもう,FizzBuzz問題の代わりに『コードが書けないプログラマ志願者を見分ける手法』にしてもいいほどに(それは言い過ぎ).

以前,『サンプルコードは入力と出力をセットにして作成してから実行を確かめる』といったことを述べている記事を書き,また,その趣旨に基づく『最初のサンプルプログラム』集みたいな記事も作成しました.これらを踏まえ,AtCoderあたりでは定番の,値入力部分のサンプルプログラムをいろんな言語で書き始めてみたのですが…いやあ,めんどくさい.入力スタイルに合わせるのはもちろん,言語固有の工夫が必要だったり,入力後の処理によってケースバイケースとなったり."Hello, World!"プログラムが出力だけのことはあるといいますか.

とりあえず,次の競プロ練習風問題に対応するプログラムを,いくつかのプログラミング言語で書いてみた結果を掲載.必要に応じて追加・修正していく予定.『この言語ならもっとスマートに書けるぜ!』的なツッコミ・議論歓迎.

  • N個の整数値を入力すると,カンマ+空白区切りで逆順に出力するプログラム
  • 個数Nおよび整数値は,いわゆる半角空白か改行で区切って入力
  • 出力時のカンマ+空白の空白も半角とし,最後の値は改行のみ

【入出力例】

入力例1
3
10 20 30
出力例1
30, 20, 10
入力例2
4 10 20
30 40
出力例2
40, 30, 20, 10

プログラム例

C言語 (GCC 8.3.0)

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
  int n, *a;

  scanf("%d", &n);
  a = (int *)malloc(sizeof(int) * n);
  for (int i = 0; i < n; i++) scanf("%d", &a[i]);
  for (int i = n; i > 1; i--) printf("%d, ", a[i - 1]);
  printf("%d\n", a[0]);

  free(a);

  return 0;
}

C++ (GCC 8.3.0)

#include <iostream>
#include <string>
using namespace std;

int main(void)
{
  int n;

  cin >> n;
  string a[n];
  for (int i = 0; i < n; i++) cin >> a[i];
  for (int i = n; i > 1; i--) cout << a[i - 1] << ", ";
  cout << a[0] << "\n";

  return 0;
}

Lua (Lua 5.3.3)

n = io.read("n")
a = {}
for i = 1, n do a[#a+1] = io.read("n") end
for i = n, 2, -1 do io.write(a[i], ", ") end
io.write(a[1], "\n")

Scheme (GNU Guile 3.0.4およびGauche 0.9.9)

(define (readn n)
  (if (= n 0) '()
      (let ((r (read)))
        (cons r (readn (- n 1))))))

(let ((a (readn (read))))
  (for-each
    (lambda (x) (display x) (display ", "))
    (reverse (cdr a)))
  (display (car a)) (newline))

Common Lisp (SBCL 1.4.16)

(let* ((n (read))
       (a (mapcar #'read
            (coerce
              (make-array n :initial-element nil)
              'list))))
  (mapc
    (lambda (x) (princ x) (princ ", "))
    (reverse (cdr a)))
  (princ (car a)))

Python (Python 3.8.5)

i = input()
while i == '': i = input()

a = i.split()
n = int(a.pop(0))

while len(a) < n:
    i = input()
    while i == '': i = input()
    a = a + i.split()

for v in a[1:n][::-1]:
    print(v, ", ", end="")
print(a[0])

備考

記事に関する補足

  • ちなみにこれ,『N個の(空白・改行区切りの)文字列』だともっとめんどくさい. もはや字句解析レベルの前処理が必要.空行で入力終わり,とするならsplit系でいけるのだけれども. Python版を見る限り,そこまでではなさそう.やっぱりめんどくさいけど.

更新履歴

  • 2020-11-16:Python版を追加
  • 2020-11-15:Scheme版を修正(Twitterコメントより)
  • 2020-11-14:初版公開