paiza レベルアップ問題集 「FINAL問題 数列の中に何個ある?」をPythonとGASで解いてみた

この記事を読むことで、PythonでのIF文・Forループの基本的な書き方と、ループ内の変数の値がどの様に変化しているのかを逐一確認出来るトレースのコードの書き方、リスト内の指定の数を数えるcount関数の使い方を学べます。

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

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

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

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

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

数列の中に何個ある? (paizaランク D 相当)

問題:
長さ N の数列 a (a_1, a_2, …, a_N) が与えられます。
この数列の中に 1 が何個あるか出力してください。

この記事では、入力例3でNにリスト長さが「6」、リストに「8 1 3 8 1 3」が与えられたという条件で解いて行きます。

入力例3
6
8 1 3 8 1 3

出力例3
2

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

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

<<Pythonでの解き方>>

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

手順として、
1:標準入力でNを取得
2:標準入力でリストを取得
3:変数ansに配列の中に「1」が出現した回数を0で初期化する
4:ループで配列の中にある「1」を見つけたらansにインクリメント(出現回数 ans+=1)する
5:最終的な「1」の出現回数を出力する。

手順3ですが、配列の中の「1」の出現数を数えるので、最初の出現回数は0回です。
ansという変数に出現回数を格納しているので、まずansを0で初期化します。
ループで配列を探索して「1」が見つかったら、ansをインクリメントします。

では、コードを見て行きます。
リストの要素とその中身をトレースしたコードと実行結果です。


#リストの長さNを取得
N=int(input())


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


#「1」の出現回数ansを0で初期化する
ans=0


#ループでリストを探索して「1」を見つけたらansをインクリメントする
for num in array:
    print('分岐前:現在の「1」の数は【'+str(ans)+'】です。')
    print('リストの要素numは【'+str(num)+'】です。')
    if num==1:
        ans+=1
        print('<<<「1」を見つけたぞ!!!!!>>>')
    print('分岐後:現在の「1」の数は【'+str(ans)+'】です。')
    print('------------------------------')

print('このリストの最終的な「1」の数は【'+str(ans)+'】です。')

このトレースコードについて深く知りたい方の多くは基本情報技術者試験を目指されている方か、既にお持ちの方、または講師の方かもしれませんので、宜しければ当ブログの基本情報技術者試験トップページをご覧下さい。アルゴリズムや午後問題の勉強の仕方やオススメ参考書について、かなり詳しく書いています。

では、このコードの話に戻します。
このままでは、paizaの問題文の「リストの中に1が何個出現したか」に対して余分なコードがあるので、コメントアウトします。
最後にこの問題の解答である出力結果のprint文を追記しました。


#リストの長さNを取得
N=int(input())


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


#「1」の出現回数ansを0で初期化する
ans=0


#ループでリストを探索して「1」を見つけたらansをインクリメントする
for num in array:
    #print('分岐前:現在の「1」の数は【'+str(ans)+'】です。')
    #print('リストの要素numは【'+str(num)+'】です。')
    if num==1:
        ans+=1
        #print('<<<「1」を見つけたぞ!!!!!>>>')
    #print('分岐後:現在の「1」の数は【'+str(ans)+'】です。')
    #print('------------------------------')

#print('このリストの最終的な「1」の数は【'+str(ans)+'】です。')
print(ans)

ioの出力確認をしてコードを提出。

これで無事正解しました。

Pythonには指定の数を数える「count関数」があるので、このようなシンプルなコードでも正解します。

リストarray内に「1」が何個あるのか数えるcount関数の書き方とその場合のコード

print(array.count(1))

#リストの長さNを取得
N=int(input())


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


#count関数でリスト内の「1」の数を数える
print(array.count(1))

これですと、ループを使わなくても解答出来ますね。
更にカウントに使ったansの宣言も不要です。
ただ、一応この問題は「ループの練習」なので、冗長でしたが先ほどのコードも掲載しました。

<<GASでの解き方>>

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

黄色いセルの所に配列の最大値を出力します。

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

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

1:スプレッドシートからアクティブシートをアクセスする

2:緑色のセル(B1)にある、リストの長さNを取得(この例の場合N=6)

3:配列arrayを宣言して、灰色のセルの範囲の配列を格納する

4:ログで配列が取得できたことを確認

5:1の出現回数を数えるansを0で初期化する

6:ループとIFで配列の要素が「1」かどうかをトレースしながら探索してログ出力する
もしも上の配列の中から「1」が見つかったらansをインクリメント(加算)する

7:リスト内の最終的なansをログで出力して確認

8:スプレッドシート格納用に配列ans2を宣言

9:ans2にansを二次元配列になるように格納

10:スプレッドシート出力前にans2をログ出力して確認

11:スプレッドシートの黄色いセルにans2を出力

手順1: スプレッドシートからアクティブシートをアクセスする

const ss=SpreadsheetApp.getActiveSheet();

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

手順2:緑色のセル(B1)にある、リストの長さNを取得(この例の場合N=6)

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

手順3:配列arrayを宣言して、灰色のセルの範囲の配列を格納する

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

手順4:ログで配列を取得できたことを確認

console.log(array);

手順5:1の出現回数を数えるansを0で初期化する

let ans = 0;

手順6:ループとIFで配列の要素が「1」かどうかをトレースしながら探索してログ出力する。もしも上の配列の中から「1」が見つかったらansをインクリメント(加算)する。

  for (let i = 0; i < N; i++) {
    console.log(`分岐前:現在の「1」の数は【${ans}】です。`);
    console.log(`現在の配列array[0][${i}]の要素は【${array[0][i]}】です。`);
    if (array[0][i] == 1) {
      console.log('<<<「1」を見つけたぞ!!!!!>>>');
      ans += 1;
    }
    console.log(`分岐後:現在の「1」の数は【${ans}】です。`);
    console.log('--------------------------------------');
  }

スプレッドシートでは2次元配列で格納されているので、array[0][i]と記述して、配列の0行目の所をループで「中身が1かどうか確認」しています。

もしもarray[0][i]が「1」と等しかったら、変数ansをインクリメント(1つ加算)します。その後conole.logで、分岐前・現在の配列の添字と要素・分岐後をログで出力しています。
文章と数値を出力同時に出力するには「`」を使います。
これは、[Shift]+[@]です。
数値が入る所に${}と記述しています。

※二次元配列になっていることに注意!!
array=[[8,1,3,8,1,3]]に対して、array[0][I]のトレースをして行きます。

・i=0 array[0][0]=[[8]]の時のトレース

・i=1 array[0][1]=[[1]]の時のトレース

・i=2 array[0][2]=[[3]]の時のトレース

・i=3 array[0][3]=[[8]]の時のトレース

・i=4 array[0][4]=[[1]]の時のトレース

・i=5 array[0][5]=[[3]]の時のトレース

手順7:リスト内の最終的なansをログで出力して確認

console.log(ans);

手順8:スプレッドシート格納用に配列ans2を宣言

let ans2 = [];

手順9:ans2にansを二次元配列になるように格納
※スプレッドシートはタテとヨコの二次元配列で格納しているので、格納する前に二次元配列にします※

ans2.push([ans]);

手順10:スプレッドシート出力前にans2をログ出力して確認

console.log(ans2);

手順11:スプレッドシートの黄色いセルにans2を出力

ss.getRange(4, 2).setValues(ans2);

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

function loop20() {

  //スプレッドシートからアクティブシートをアクセスする
  const ss = SpreadsheetApp.getActiveSheet();

  //緑色のセル(B1)にある、リストの長さNを取得(この例の場合N=6)
  const N = ss.getRange(1, 2).getValue();

  //配列arrayを宣言して、灰色のセルの範囲の配列を格納する
  const array = ss.getRange(2, 2, 1, N).getValues();

  //ログで配列が取得できたことを確認
  console.log(array);

  //1の出現回数を数えるansを0で初期化する
  let ans = 0;


  //ループとIFで配列の要素が「1」かどうかをトレースしながら探索してログ出力する
  //もしも上の配列の中から「1」が見つかったらansをインクリメント(加算)する

  for (let i = 0; i < N; i++) {
    console.log(`分岐前:現在の「1」の数は【${ans}】です。`);
    console.log(`現在の配列array[0][${i}]の要素は【${array[0][i]}】です。`);
    if (array[0][i] == 1) {
      console.log('<<<「1」を見つけたぞ!!!!!>>>');
      ans += 1;
    }
    console.log(`分岐後:現在の「1」の数は【${ans}】です。`);
    console.log('--------------------------------------');
  }

  //リスト内の最終的なansをログで出力して確認
  console.log(ans);

  //スプレッドシート格納用に配列ans2を宣言
  let ans2 = [];


  //ans2にansを二次元配列になるように格納
  ans2.push([ans]);


  //スプレッドシート出力前にans2をログ出力して確認
  console.log(ans2);

  //スプレッドシートの黄色いセルにans2を出力
  ss.getRange(4, 2).setValues(ans2);


}

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

お疲れ様でした、ブレイクタイムフォトはこちらになります。

レインボーブリッジ

■ 参考文献の紹介■

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

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

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

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

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

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