paiza レベルアップ問題集 「STEP: 8 毎日増加するお金」をPythonとGASで解いてみた

この記事を読むことで、PythonとGASでwhileループを使って、変動する値を加算をしていく過程で、変数がどのように変化するのかを学べます。

毎日、所持金A円にA円の10%ずつ加算して行って、何日加算したら目標金額B円を超えるのかを求めます。

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

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

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

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

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

毎日増加するお金 (paizaランク D 相当)

問題:
現在所持金を A 円持っています。
所持金が毎日 10% ずつ増えるとき、何日後に B 円を超えるか出力してください。
また、増加するお金は小数点以下切り捨てで考えることとします。
例として、所持金が 831 円 のとき、10% は 83.1円 ですが、増加するお金は 83 円 です。

この記事では、下記の入力例3の場合を例にして、A円の813円が10%ずつ増えると「何日後にB円の10000円を超えるか」を求めて行きます。

入力例3
813 10000

出力例3
27

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

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

■ Pythonでの解き方 ■

下準備として、paiza.ioにこの様に入力します。
(入力例1をそのままioにコピーしただけ。)

手順として、

1:A,Bを標準入力で取り込む

2:ループの何日目でAの813円がBの10000を超えるかの日数を数える変数dayを0で初期化する


3:whileループでA<=Bの条件を満たす間、ループを回して加算する。dayをインクリメントする


4:dayを表示

で、行います。

まずは、プログラムの各変数の動きを追いやすいように、トレースのio出力結果と、トレースのコードを添えます。

Whileループのトレースをします。
27日間の増加の詳細です。

<1日〜3日目までのトレース>

<4日〜6日目までのトレース>

<7日〜9日目までのトレース>

<10日〜12日目までのトレース>

<13日〜15日目までのトレース>

<16日〜18日目までのトレース>

<19日〜21日目までのトレース>

<22日〜24日目までのトレース>

<25日〜27日目までのトレース>

元手のA円から目標金額B円までかかった日数dayはこちらです。

ここまでのwhileループによるトレースの部分のコードです。

#標準入力で元手の金額A円と基準の金額B円を取得する
A,B=map(int,input().rstrip().split(' '))


#元手A円がB円を超える日数dayを0で初期化する
day=0


#whileループでA<=Bの間、お金を増やす

print('<<<whileループに入る>>>')

while A<=B:
    print('計算前のAの金額:'+str(A)+'円')
    
    #増加するお金
    print('増加するお金は「'+str(int(A/10))+'円」です。')
    
    #お金を増やす
    A+=int(A/10)
    
    print('計算後のAの金額:'+str(A)+'円')
    
    #dayをインクリメント
    day+=1
    print('経過日数【'+str(day)+'】')
    
    print(('---------------------------'))

print('<<<whileループを抜ける>>>')

print(day)    

このままでは、出力結果である出力例3に対して冗長なコードが含まれているので、解答以外のprint文をコメントアウトします。

#標準入力で元手の金額A円と基準の金額B円を取得する
A,B=map(int,input().rstrip().split(' '))


#元手A円がB円を超える日数dayを0で初期化する
day=0


#whileループでA<=Bの間、お金を増やす

#print('<<<whileループに入る>>>')

while A<=B:
    #print('計算前のAの金額:'+str(A)+'円')
    
    #増加するお金
    #print('増加するお金は「'+str(int(A/10))+'円」です。')
    
    #お金を増やす
    A+=int(A/10)
    
    #print('計算後のAの金額:'+str(A)+'円')
    
    #dayをインクリメント
    day+=1
    #print('経過日数【'+str(day)+'】')
    
    #print(('---------------------------'))

#print('<<<whileループを抜ける>>>')

print(day)  

スッキリするように、コメントアウトした部分を省いたコードです。

#標準入力で元手の金額A円と基準の金額B円を取得する
A,B=map(int,input().rstrip().split(' '))


#元手A円がB円を超える日数dayを0で初期化する
day=0


#whileループでA<=Bの間、お金を増やす
while A<=B:
    
    #お金を増やす
    A+=int(A/10)
    
    #dayをインクリメント
    day+=1

print(day)    

ioの出力結果です。

■ GASでの解き方 ■

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

スプレッドシートの黄色いセルの所に「加算される整数N(=1)、増加する数M(=3)、加算して超える基準値K(=8)」でKを超えるまでに加算した回数を出力します。
Whileループで加算する回数を変数countに格納します。
また、countを二次元配列count2に追加して、スプレッドシートに出力します。

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

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

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

2:整数A,Bを取得する配列arrayを宣言する


3:スプレッドシートの緑色のセルにある金額A円(この例では「813」)と、灰色のセルにある目標金額B円(この例では10000)を2行1列の配列分取得して、arrayに格納する


4:arrayを出力して、各数が配列に格納されていることをログで確認する


5:A=array[0][0]、B=array[1][0]として代入する。この時Aは変数で、Bは定数になる。


6:それぞれの変数、定数が正しく代入されたことをログで確認する


7:Aに10%の金額ずつ足していく日数dayを0で初期化する


8:whileループを使ってAに現在のAの10%ずつ加算する「A+=Math.floor(A/10)」の計算をして、dayをインクリメントする


9:スプレッドシートにdayに格納された日数を二次元配列として格納するday2を宣言する


10:day2に二次元配列になるようにdayを追加


11:スプレッドシートに出力前のday2を出力して確認する


12:スプレッドシートの黄色い所に日数を二次元配列として格納したday2を出力する

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

const ss=SpreadsheetApp.getActiveSheet();

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

手順2:整数A,Bを取得する配列arrayを宣言する

let array=[];

手順3:スプレッドシートの緑色のセルにある金額A円(この例では「813」)と、灰色のセルにある目標金額B円(この例では10000)を2行1列の配列分取得して、arrayに格納する。
下のスプレッドシートより、セルB1つまり(1,2)から2行分を取得するので、getRangeの引数に(1,2,2)と書きます。

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

手順4:arrayを出力して、各数が配列に格納されていることをログで確認する

console.log(array);

手順5:A=array[0][0]、B=array[1][0]として代入する。この時Aは変数で、Bは定数になる。

let A=array[0][0];
const B=array[1][0];

※ Aは10%ずつ加算されていくので値が変わるから変数、それに対して基準値のBは値が変わらないので定数 ※

手順6:それぞれの変数、定数が正しく代入されたことをログで確認する

数値と文字を一緒に出力するときは、[Shiftキー]を押しながら「@」を押して「 ` 」で囲います。

console.log(`現在の所持金A:「${A}円」,目標金額B:「${B}円」`);

手順7:Aに10%の金額ずつ足していく日数dayを0で初期化する

let day=0;

手順8:whileループを使ってAに現在のAの10%ずつ加算する「A+=Math.floor(A/10)」の計算をして、dayをインクリメントする

<1日〜3日目までのトレース>

<4日〜6日目までのトレース>

<7日〜9日目までのトレース>

<10日〜12日目までのトレース>

<13日〜15日目までのトレース>

<16日〜18日目までのトレース>

<19日〜21日目までのトレース>

<22日〜24日目までのトレース>

<25日〜27日目までのトレース>

Whileループの部分のコードです。

  //whileループを使ってAに現在のAの10%ずつ加算する「A+=Math.floor(A/10)」の計算をして、dayをインクリメントする
  
  console.log('<<<ループに入ります。>>>');

  while(A<=B){
    console.log(`加算前の金額A:${A}円`);
    console.log(`加算するAの10%の金額:${Math.floor(A/10)}円`);

    //加算処理
    A+=Math.floor(A/10);

    console.log(`加算後の金額A:${A}円`);

    //日数をインクリメント
    day++;

    console.log(`【${day}】日目`);

    console.log('----------------------');

  }

  console.log('<<<ループを抜けました。>>>');

手順9:スプレッドシートにdayに格納された日数を二次元配列として格納するday2を宣言する

let day2=[];

手順10:day2に二次元配列になるようにdayを追加

day2.push([day]);

手順11:スプレッドシートに出力前のday2を出力して確認する

console.log(day2);

手順12:スプレッドシートの黄色い所に日数を二次元配列として格納したday2を出力する

ss.getRange(5,2).setValue(day2);

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

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

function loop2no13() {

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

  //整数A,Bを取得する配列arrayを宣言する
  let array = [];

  //スプレッドシートの緑色のセルにある金額A円(この例では「813」)と、灰色のセルにある目標金額B円(この例では10000)を2行1列の配列分取得して、arrayに格納する
  array = ss.getRange(1, 2, 2).getValues();

  //arrayを出力して、各数が配列に格納されていることをログで確認する
  console.log(array);

  //A=array[0][0]、B=array[1][0]として代入する。この時Aは変数で、Bは定数になる。
  let A = array[0][0];
  const B = array[1][0];

  //それぞれの変数、定数が正しく代入されたことをログで確認する
  console.log(`現在の所持金A:「${A}円」,目標金額B:「${B}円」`);

  //Aに10%の金額ずつ足していく日数dayを0で初期化する
  let day = 0;

  //whileループを使ってAに現在のAの10%ずつ加算する「A+=Math.floor(A/10)」の計算をして、dayをインクリメントする

  console.log('<<<ループに入ります。>>>');

  while (A <= B) {
    console.log(`加算前の金額A:${A}円`);
    console.log(`加算するAの10%の金額:${Math.floor(A / 10)}円`);

    //加算処理
    A += Math.floor(A / 10);

    console.log(`加算後の金額A:${A}円`);

    //日数をインクリメント
    day++;

    console.log(`【${day}】日目`);

    console.log('----------------------');

  }

  console.log('<<<ループを抜けました。>>>');

  //スプレッドシートにdayに格納された日数を二次元配列として格納するday2を宣言する
  let day2 = [];

  //day2に二次元配列になるようにdayを追加
  day2.push([day]);


  //スプレッドシートに出力前のday2を出力して確認する
  console.log(day2);

  //スプレッドシートの黄色い所に日数を二次元配列として格納したday2を出力する
  ss.getRange(5, 2).setValue(day2);

}

宜しかったらコピペしてアレンジして見て下さい。
お疲れ様でした、ブレイクタイムフォトはこちらになります。

お食事中の方、ごめんなさい、浅草で有名な「うんこビル」です。

■ 参考文献の紹介■

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

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

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

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

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

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

モバイルバージョンを終了