paiza レベルアップ問題集 「FINAL問題 数列同士の引き算」をPythonとGASで解いてみた

このコーナーでは、学習コンテンツpaizaラーニングレベルアップ問題集をPythonとGASの両方で解いて全コードの解説をしています。
PythonとGASの両方のコードを用いて、全コード及び部分的にも可能な限り詳細に記載いたしました。

GASはスプレッドシートを使っています。
GASはGoogle Apps Scriptと言って、JavaScriptの文法をベースにしているので、JavaScriptの学習中の方にもお役立て出来るかも知れません。

サイトマップはこちらから

paizaレベルアップ問題集でPythonとGASを解いて見たに戻る
メインメニューに戻る
Python自作サンプル
GASサンプル
基本情報技術者試験

paizaでの解答はPythonで行いましたが、この記事ではPythonのコードと共に、同じ問題を現在学習中のGASだったらどう解くのか、スプレッドシートでバインドして作ってみました。

数列同士の引き算 Python3編

具体例として出力例1の、N=5 リスト「1,2,3,4,5」からリスト「5,4,3,2,1」で考えてみます。

入力例1
5
1 2 3 4 5
5 4 3 2 1

出力例1
-4
-2
0
2
4

ではまず、Pythonで解いてみます。

今回は、paiza.ioを使って解きます。paiza.ioの使い方はこちらから。

<<Pythonでの解き方>>

下準備として、paiza.ioにこの様に入力します。

手順として、

1.標準入力でリストの長さNを読み込む
2.標準入力でリストとしてリストarrayを読み込む
3.標準入力でリストarrayから減算するarray2を読み込む
4.リストarrayからarray2を減算した答えを格納する空のリスト、array_ansを定義する
5.ループで減算処理と減算結果の格納を同時に行う
6.答えが格納されたarray_ansをループで出力する

コードを見てみましょう。

手順1では、

N=int(input())

で、標準入力でリストの個数Nを読み込めます。

手順2では、

array=list(map(int,input().rstrip().split(‘ ‘)))

で、リストとして複数の数を標準入力で読み込んでいます。
listを使ってリストとしています。
mapで複数の数を読み込めます。
intで整数として読み込んでいます。
rstripで改行による影響を受けない様にして、split(‘ ‘)でスペース区切りの数値を読み込みます。

手順3では、

array2=list(map(int,input().rstrip().split(‘ ‘)))

で、arrayから減算するarray2をリストとして読み込みます。

手順4では、array[i]からarray2[I]の減算結果を格納するリストarray_ansを定義しています。

array_ans=[]

手順5ではループで減算処理と減算結果の格納を同時に行っています。
内包表記を使いました。

内包表記の書式は、

[結果 for いつものfor文]

です。
今回の内包表記のコードは、

[array_ans.append(array[i]-array2[i]) for i in range(N)]

です。

これを通常表記で書くと、

#ループで減算処理と減算結果の格納を同時に行う
for i in range(N):
    array_ans.append(array[i]-array2[i])

に、なります。

手順6では、内包表記を使ってリストarray_ansをループで出力しています。

[print(num) for num in array_ans]

これを通常のループで書くとこうなります。

#答えが格納されたarray_ansをループで出力する
for num in array_ans:
    print(num)

ここまでのコードはこの様になります。

#リストの長さNを取り込む
N=int(input())

#リストarrayを取り込む
array=list(map(int,input().rstrip().split(' ')))

#リストarray2を取り込む
array2=list(map(int,input().rstrip().split(' ')))

#リストarrayからarray2を減算した答えを格納する空のリスト、array_ansを定義する
array_ans=[]

#ループで減算処理と減算結果の格納を同時に行う
[array_ans.append(array[i]-array2[i]) for i in range(N)]
    
#答えが格納されたarray_ansをループで出力する
[print(num) for num in array_ans]

paiza.ioの出力結果です。

<<GASでの解き方>>

では、同じ問題をGASで解いてみます。

まず、スプレッドシートにこの様に配置しました。

緑のセルにN=配列の要素数、薄い灰色の所に配列array、濃い灰色の所に配列array2、減算結果array_ansを黄色の所に求めます。

※スプレッドシートに表示する場合は、ループを使って一次元配列ではなく、二次元配列としてからの配列に追加をして作成します※

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

1:スプレッドシートからアクティブシートをアクセスする
2:緑のセルから配列の長さNに出力する数値(この問題の場合は「5」)を取得する。
3:薄い灰色のセルから(この問題の場合は「1,2,3,4,5」)を読み込み、配列arrayとする
4:濃い灰色のセルから(この問題の場合は「5,4,3,2,1」)を読み込み、配列array2とする
5:N及び配列arrayとarray2をログ出力して正しく読み込めたことを確認する
6:減算結果を格納する配列array_ansを定義する
7:減算結果を格納したarray_ansをスプレッドシートに格納出来るようにする二次元配列array_printを定義する
8:ループでi=0からi<Nまでの間、array[0][i]-array2[0][i]の各要素の減算結果をarray_ansに追加する
9:計算結果が入ったarray_ansをスプレッドシートに出力できるように二次元配列として格納するためにarray_printに追加する
10:ログで配列array_ansとarray_printを確認する
11:スプレッドシートの黄色い所のB4である(5,2)から1行N列分にarrayを出力する

手順1: SpreadsheetAppから階層を辿ってアクティブシートをアクセスする

const ss=SpreadsheetApp.getActiveSheet();

手順2:緑のセルから配列の長さNに出力する数値(この問題の場合は「5」)を取得する。

let N=ss.getRange(1,2).getValue();

手順3:薄い灰色のセルから(この問題の場合は「1,2,3,4,5」)を読み込み、配列arrayとする

let array=ss.getRange(2,2,1,N).getValues();

手順4:濃い灰色のセルから(この問題の場合は「5,4,3,2,1」)を読み込み、配列array2とする

let array=ss.getRange(2,2,1,N).getValues();

手順5:N及び配列arrayとarray2をログ出力して正しく読み込めたことを確認する

console.log(N);
console.log(array);
console.log(array2);

ログの実行結果です。

手順6:減算結果を格納する配列array_ansを定義する

let array_ans=[];

手順7:減算結果を二次元配列としてスプレッドシートに出力する用の配列array_printを定義する

let array_print=[];

手順8:ループでarray_ansに減算結果を格納する

//ループでarray_ansに減算結果を格納する
  for(let i=0;i<N;i++){
    array_ans.push(array[0][i]-array2[0][i]);
  }

array[0][i]-array2[0][i]となっているのは、スプレッドシートから取得した配列arrayは1行5列の二次元配列なのでこの様にコードを書いて計算しています。

手順9:減算結果を格納したarray_ansをスプレッドシートに二次元配列として出力出来る様に配列array_printに追加する

array_print.push(array_ans);

手順10:array_ansの計算結果及びarray_printに二次元配列として格納できたことをログで確認する

console.log(array_ans);
console.log(array_print);

最後のarray_printが、「1行5列の二次元配列」として格納されています。
この「1行5列だからこそ!」今回の場合では、スプレッドシートの黄色いセル、横方向1行分に格納出来るのです。これは後で出てくるので、今はこの「1行5列」という所を頭の片隅において下さい。

手順11:スプレッドシートの黄色いセルに出力用のarray_ans_printを格納する

ss.getRange(5,2,1,N).setValues(array_print);

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

GASでの全コードはこちらになります。

function loop11(){

  //SpreadsheetAppから階層を辿ってアクティブシートをアクセスする
  const ss=SpreadsheetApp.getActiveSheet();

  //配列の長さNを取得する
  let N=ss.getRange(1,2).getValue();

  //arrayを配列として取得する
  let array=ss.getRange(2,2,1,N).getValues();

  //減算用のarray2を配列として取得する
  let array2=ss.getRange(3,2,1,N).getValues();

  //N,array,array2が取得できたことをログで確認する
  console.log(N);
  console.log(array);
  console.log(array2);

  //減算結果を格納する空の配列array_ansを定義する
  let array_ans=[];

  //減算結果を二次元配列としてスプレッドシートに出力する用の配列array_printを定義する
  let array_print=[];

  //ループでarray_ansに減算結果を格納する
  for(let i=0;i<N;i++){
    array_ans.push(array[0][i]-array2[0][i]);
  }


  //格納した減算結果をスプレッドシートに二次元配列として出力用の配列array_printに追加する
  array_print.push(array_ans);

  //array_ansの計算結果及びarray_printに二次元配列として格納できたことをログで確認する
  console.log(array_ans);
  console.log(array_print);

  //スプレッドシートの黄色いセルに出力用のarray_ans_printを格納する
  ss.getRange(5,2,1,N).setValues(array_print);

}

宜しかったらコピペしてアレンジして見て下さい。

ちなみにarray_printを使わず、25行目をこのように書いて、計算結果array_ansを出力すると、([array[0][i]-arrray2[0][i]])と[]で括っています。)

array_ans.push([array[0][i]-array2[0][i]]);

このように、5行1列になってしまっているので、横方向の1行5列には格納できません。
下のエラー文をざっくり訳すと、

「行数が違っているよ。スプレッドシートの黄色い所は1行分なのに、5行ぶち込もうとしているから、スプレッドシートに出力できないよ」

Exception: The number of rows in the data does not match the number of rows in the range. The data has 5 but the range has 1.

ということになってしまいましたので、縦方向、横方向を確認してからスプレッドシートに格納することがGASでスプレッドシートを扱う上で、1番大事〜〜♪なんですね。

お疲れ様でした。

ブレイクタイムフォトはこちらになります。

目白庭園。
池袋から一駅

■ 参考文献の紹介■

じっくり丁寧にPythonを学びたい方向け。
まずはpaizaラーニングなどの学習コンテンツで学んで、基礎をマスターしたら、この本でじっくりと初級から中級レベルを目指せます。

初めてGASを学ぶ方向け。
スプレッドシートの基本的な使い方からGASのベースとなるJavaScriptの基礎文法、GASでの初歩的なプログラミングを学べます。

GASに少し慣れて来たら、基礎固めとリファレンスとしてこの本でじっくり学べます。

サイトマップはこちらから

paizaレベルアップ問題集でPythonとGASを解いて見たに戻る
メインメニューに戻る
Python自作サンプル
GASサンプル
基本情報技術者試験

←前の問題                        次の問題 →

投稿者: nekosiestr

プログラミング学習中の発達障害者です。宜しくお願いします。 趣味で写真を撮っています。 プログラミングは、GAS/HTML/CSS/JavaScript/jQuery/PHP、 発達障害は、自閉症スペクトラムASD/ADHD、 写真は、以前はコンパクトデジカメ、現在は、OLYMPUSミラーレス一眼を使っています。