paiza レベルアップ問題集 標準入力その6「STEP: 3 1 行目で与えられる N 個の整数の入力」をPythonとGASの両方で解いたコードの紹介

この記事を読むことで、Pythonで標準入力とsplitなどのメソッドを複数用いて、リスト(配列)に数値を格納して、個数を除いたリスト内の数値をループの中で出力することが可能になります。

GASではスプレッドシートで値を取得して、二次元配列に格納して出力しています。

このコーナーでは、プログラミング学習コンテンツpaizaラーニングレベルアップ問題集を、PythonとGAS(Google Apps Script)の両方で同じ問題を解いたコードを公開している学習ログです。

Python・GASのどちらの言語のコードも可能な限り詳細に解説致します。
GASはスプレッドシートのエディタを使ってコードを書いております。

Pythonではpaizaに入会しなくても問題集を解きたい方向けにpaiza.ioを用いております。paiza.ioの使い方はこちらから。

(入会するか否かは問題集を解いて見てからの読者様のご判断にお任せ致します。
どちらの選択をされても記事を読めるようになっておりますので、ご安心なさって下さい。)


1 行目で与えられる N 個の整数の入力 (paizaランク D 相当)

問題:
1 行目で、整数 N と、続けて N 個の整数 a_1, … , a_N が半角スペース区切りで与えられます。
a_1, … , a_N を改行区切りで出力してください。

ではまず、Pythonで解いて行きます。


手順として、

1: 1行目の整数を標準入力で数値として取得する際標準入力と幾つかの関数を使って、数値の個数と出力する数値を全てリストarrayに格納する

2: リスト(添字0から始まる)の1番目の添字0の要素を数値の個数Nとする


3: リストの2番目の添字1の要素から最後の添字N-1の要素までをループで出力する

・シンプルなループ
・上記の内包表記

の3ステップで行います。

今回は入出力例1を用います。

入力例1
13 5085 2923 8669 3231 7032 73 2683 8317 5545 9774 7179 2646 2470

出力例1
5085
2923
8669
3231
7032
73
2683
8317
5545
9774
7179
2646
2470

まず、準備として、paiza.ioにこのように入力します。
(入力例1 をコピペしたのみ)

Web page header with a green 'Run (Ctrl-Enter)' button, Japanese title 'Pythonを学ぶ | プログラミング力診断', and a long number sequence in a text input.

この一番初めの13は、次の「5085」〜「2470」までの数値の個数13個を表しています。

まずはこの1行全てを標準入力で、いくつかの関数も使って数値として取得して、リストの形に変換してarrayに格納します。

このコード1行に複数の関数を使用しているので、今回の例に即して簡潔にお伝えします。

input … 標準入力で文字や数値を取得する

split … 指定の区切り文字で分割して取得する

int … 上記 inputで取得する対象が整数である


map … 関数をまとめて適用


list … リスト(配列)変換

上記の関数を用いてコードを掲載致します。

splitの区切り文字の指定は、問題文の通り半角スペースです。

関数が沢山に色々出て来てしまいましたので、まずは、標準入力で取得した数値がリスト(配列)形式でarrayに取得出来たことをprint文で出力して確認します。

#1行分をリストとして取得してarrayに格納
array=list(map(int,input().split(' ')))

#arrayにリストの形式で数値が格納されていることを確認
print(array)

この様にリストとして格納出来ました。

Tab bar with three tabs labeled 出力, 入力, コメント and a blue '0' badge; a line of numbers in brackets: [13, 5085, 2923, 8669, 3231, 7032, 73, 2683, 8317, 5545, 9774, 7179, 2646, 2470]

この先頭のarray[0]に当たる13を数値の個数Nとして取得と確認をします。

array=list(map(int,input().split(' ')))
print(array)

#数値の個数Nにarray[0]を代入する
N=array[0]

#Nに代入出来たことを確認する
print(N)
Row of numbers: 13, 5085, 2923, 8669, 3231, 7032, 73, 2683, 8317, 5545, 9774, 7179, 2646, 2470, with the first 13 outlined in a pink rounded rectangle.

N=13が正しく代入されたことが確認出来ました。
この状態で、配列の2番目のarray[1]=5085 〜 配列の末尾array[13]までループで出力します。

その際、ループの開始条件の指定では、

for i in range(1,N+1):

と記述します。

これは、ループの添字(インデックス)のiが、i=1,2, … 13の要素を取得する際、rangeの終わりの値はその数未満、つまり12になってしまうので、Nに1を足す必要があります。

この説明が分かり辛いかもしれませんので、まずはN+1の「+1を省いて」出力致します。

array=list(map(int,input().split(' ')))
#確認用の為、コメントアウト
#print(array)

N=array[0]

#確認用の為、コメントアウト
#print(N)

#ループをi=1からNと指定して出力
for i in range(1,N):
    print(array[i])

このコードの出力結果ですが、array[12]の「2646」までしか出力されておらず、最後のarray[13]の「2470」が抜けた結果になっています。

Vertical list of numbers (5085, 2923, 8669, 3231, 7032, 73, 2683, 8317, 5545, 9774, 7179, 2646) with a pink rounded input field at the bottom.

これで視覚的にrange(1,N)だと、Nが13だから13未満の12までしかループが回らないことが確認出来ましたので、この部分をrange(1,N+1)に修正したコードと実行結果を掲載致します。

(確認用に出力したコメントアウトした分は削除しました。)

array=list(map(int,input().split(' ')))
N=array[0]

#ループをi=1からN+1と指定して出力
for i in range(1,N+1):
    print(array[i])
Vertical column of numbers: 5085, 2923, 8669, 3231, 7032, 73, 2683, 8317, 5545, 9774, 7179, 2646, and 2470, with the final 2470 highlighted in a pink box.


更にコード短くする方法として、内包表記を用います。

[出力結果のprint文 for から「:」の直前まで]

今回の例ですと、

[print(array[i]) for range(1,N+1)]

とループが1行のコードで出力可能になります。

array=list(map(int,input().split(' ')))
N=array[0]

#ループを内包表記で出力
[print(array[i]) for i in range(1,N+1)]   

これでループの部分が1行とスッキリした記述になりました。

Pythonは以上です。
次は、GASで解いて行きます。


今度は、同じ問題をGASで解いてみます。
まず、スプレッドシートにこの様に配置しました。

Spreadsheet with an input row showing a long space-separated number sequence under the header 入力 (A), and a yellow-highlighted output column labeled 出力 on the right.

緑のセルA2(2,1)の数値を取得し、最初の数値13を数値の個数として定数Nに代入して、2番目の数値から最後までをC2(2,3)から始まる黄色いセルに出力します。

その際、この黄色いセルの範囲には、二次元配列として取得した整数が格納された配列を出力します。

※スプレッドシートに表示する場合は、二次元配列としての配列に追加をして作成します※

手順はこのようになります。

1: SpreadSheetAppから階層を辿って現在のシートにアクセスする

2: 緑色のセルA2(2,1)の数値を個数13個と、その後の13個分の数値をsplitメソッドを用いて配列としてarrayに取得する


3: 取得した配列arrayをログ出力する


4: 配列の先頭の添字0の要素array[0]をNに代入してN=13になることを確認する


5: 空の配列array2を宣言して、arrayの2番目array[1]から最後の要素array[13]を二次元配列array2に格納する


6: スプレッドシートに出力前にarray2が二次元配列として数値を格納出来たことをログ出力して確認する


7: 二次元配列array2をスプレッドシートのC2(2,3)から始まる黄色いセルに出力する


手順1: SpreadSheetAppから階層を辿って現在のシートにアクセスする

const ss = SpreadsheetApp.getActiveSheet();

ここで定数ssにSpreadsheetAppから階層を辿ってアクティブシートにアクセスしています。

コードを関数「standardInput3」に書いて行きます。

Standard Inputで標準入力の意味です。

function standardInput3() {

  //SpreadSheetAppから階層を辿って現在のシートにアクセスする
  const ss=SpreadsheetApp.getActiveSheet();

}


手順2:緑色のセルA2(2,1)の数値を個数13個と、その後の13個分の数値をsplitメソッドを用いて配列としてarrayに取得する

splitの区切り文字の指定は、問題文の通り半角スペースです。

array=ss.getRange(2,1).getValue().split(‘ ‘);

function standardInput3() {
  
  const ss=SpreadsheetApp.getActiveSheet();

  //緑のセルA2の数値の個数と数値をsplitメソッドを用いて配列として取得
  const array=ss.getRange(2,1).getValue().split(' ');

}


手順3:取得した配列arrayをログ出力する

console.log(array);

コードと実行結果です。

function standardInput3() {
  
  const ss=SpreadsheetApp.getActiveSheet();
  const array=ss.getRange(2,1).getValue().split(' ');

  //取得した配列arrayをログ出力する
  console.log(array);

}
Vertical list of numbers in single quotes: '13', '5085', '2923', '8669', '3231', '7032', '73', '2683', '8317', '5545', '9774', '7179', '2646', '2470'.


手順4:配列の先頭の添字0の要素array[0]をNに代入してN=13になることを確認する

const N=array[0];

function standardInput3() {
  
  const ss=SpreadsheetApp.getActiveSheet();
  const array=ss.getRange(2,1).getValue().split(' ');
  console.log(array);

  //配列の先頭の添字0の要素数array[0]をNに代入する
  const N=array[0];

  //Nをログ出力で確認する
  console.log(N);

}

実行結果のログです。

Interface showing a vertical list of numbers in quotes, with the first item '13' highlighted; top label reads 実行開始 (Start execution) and bottom shows 実行完了 (Execution complete).


手順5:空の配列array2を宣言して、arrayの2番目array[1]から最後の要素array[13]を二次元配列array2に格納する

空の配列array2にpushメソッドを使ってarray[1]からarray[13]までを二次元配列になるようループで格納します。

ループの中で、array[i]の値が1から13まで変わるので変数としてletで宣言しています。
また、二次元配列になる様に、[array[i]]と配列array全体を[ ]で括っています。

function standardInput3() {
  
  const ss=SpreadsheetApp.getActiveSheet();
  const array=ss.getRange(2,1).getValue().split(' ');
  console.log(array);

  const N=array[0];
  console.log(N);

  //スプレッドシート出力用の空の配列array2を宣言
  const array2=[];

  //配列arrayの2番目から最後の要素を二次元配列になるようにarray2に格納する
  for(let i=1;i<=N;i++){
    array2.push([array[i]]);
  }

}


手順6:スプレッドシートに出力前にarray2が二次元配列として数値を格納出来たことをログ出力して確認する

console.log(array2);

コードと実行結果のログです。

Row of arrays with numbers in quotes, resembling a data column; two empty entries highlighted in pink/red.

無事に二次元配列として格納されたことが確認出来ました。


手順7:二次元配列array2をスプレッドシートのC2(2,3)から始まる黄色いセルに出力する

ss.getRange(2,3,N).setValues(array2);

C2が(2,3)で、N行出力するのでgetRangeに(2,3,N)と指定します。
また1列の(2,3,N,1)の1は省略可能です。

また、配列の数値は複数ですので、setValuesとsを付けて複数形にします。

実行後のスプレッドシートです。

Spreadsheet with a green input row of numbers under 入力 and a yellow 出力 column listing 1–12 outputs corresponding to each input row.

GASは以上です。

※ この記事の作成に参考になったサイトです ※
ありがとうございます。

Python mapの使い方


お疲れ様でした。ブレイクタイムPhotoは、

Aerial night view of a harbor city with a brightly lit rainbow Ferris wheel near the water’s edge.

横浜みなとみらい、ランドマークタワーの夜景と観覧車です。

←前の問題へ          次の問題へ→

ご精読有難うございました。

■ GASの入門書の紹介です ■

詳解! Google Apps Script完全入門 [第3版]
単行本
Kindle版(電子書籍)

■ 関連記事 ■

paizaレベルアップ問題集「標準入力6」へ戻る
paizaレベルアップ問題集_PythonとGASのコード紹介トップページへ

写真クリエイターとしての活動
自己紹介

投稿者アバター
nekosiestr
いつもブログをご覧頂きまして、誠に有難うございます。 Excelやデータベース、プログラミングを学習する傍ら、趣味で写真を撮影してPhotoshopで編集しております。

投稿者: nekosiestr

いつもブログをご覧頂きまして、誠に有難うございます。