Help us understand the problem. What is going on with this article?

Ruby練習問題1[ボーナスドリンク問題]

ボーナスドリンク問題

今回はアウトプットのネタに困ったらこれ!?Ruby初心者向けのプログラミング問題を集めてみた(全10問)からボーナスドリンク問題を解いてみました!

#この問題文は上の記事から引用しています
問題
ある駄菓子屋で飲み物を買うと、空き瓶3本で新しい飲み物を1本プレゼントしてくれる。
最初に購入した飲み物の本数から、トータルで飲める本数を算出するプログラムを作成せよ。
また、最初に100本購入した場合、トータルで何本飲めるか。

備考
この問題は小学校3年生の算数の問題をベースとしている。

すごく簡単な問題、、、のはずなんだけどアルゴリズムに弱すぎて15分くらいの見積もりが3時間くらいかかりました。。。

ではコードの解説をしていきます。
100.timesのところは最初にwhile文を試したんですが100回までというところの書き方がわからなくて、まず100回繰り返すというところでわかりやすいtimesメソッドを選択しました(ここまでで1時間くらい泣)。
次に引っかかったのはここも初心者まる出しで恥ずかしいんですけど、3本毎に1つ追加というところを(単に3で割るだけなんですが、、、)

n += 1 if n %= 3

n += 1 if n /= 3

最初は上で書いていてなんか変だなと思い、次に下の割り方書いてたんですがどうも数値が期待と違い、なんだろうなとチェリー本をめくっていたら

n % 3 == 0

という記述を見つけて”ああこれだ!”と。
計算式を使うところが基本的にn += 1ばかりでほとんど他に書いてこなかったので基本のキから抜けていました。

そして最後まで躓いたのがここで

100.times do |n|
n += 1
n += 1 if n % 3 == 0
puts n
end
1
2
4
4
5
7
7
8
.
.
.
97
97
98
100
100

3の倍数のところはちゃんと+1が出来てるがその後は+1されずにそのまま繰り返されてました。
そして考えに考えた結果、3の倍数以外のとこで別に加算するための変数が必要なのに気づいて最終的に

n = 0
m = 0

100.times do |n|
n += 1
m += 1 if n % 3 == 0
n = n + m
puts n
end
1
2
4
5
6
8
9
10
12
13
14
16
17
18
20
21
22
24
25
26
28
29
30
32
33
34
36
37
38
40
41
42
44
45
46
48
49
50
52
53
54
56
57
58
60
61
62
64
65
66
68
69
70
72
73
74
76
77
78
80
81
82
84
85
86
88
89
90
92
93
94
96
97
98
100
101
102
104
105
106
108
109
110
112
113
114
116
117
118
120
121
122
124
125
126
128
129
130
132
133
=> 100

こちらのコードになりました。
書いてみたら大したことないコードになったので、設計のところでちゃんと考えて気がつけるかどうかって感じでした。

まだリファクタリングやテストコードを書いてちゃんとやるってのが出来ていないのでまた改善して再度更新します.


5/6時点

コメントで@jnchitoさんに指摘を頂いて、
最初に100本購入した場合、トータルで何本飲めるか。
ところも誤った認識で違うコードを書いていました。
考えとしては
3本買ったら1つ無料だと思ってたのが誤りで、文章通り
空き瓶3本で新しい飲み物を1本無料が正しいのと、
最初に購入した飲み物の本数から、トータルで飲める本数を算出するプログラムを作成せよ。
また、最初に100本購入した場合、トータルで何本飲めるか。

と求めている式が違っていました。

以下はまず最初に100本購入した場合、トータルで何本飲めるか。を求める式を考えることにしました。
まずはn = 購入した本数, m = ボーナスボトル, sum = 合計の本数と置き換えて考えたんですが、

100.times do |sum|
n += 1
m += 1 if n % 3 == 0
sum = n + m
sum += 1 if sum % 3 == 0
puts sum
end
1
2
4
5
7
8
10
10
13
13
14
.
.
.
127
128
130
130
133
133

コードの解説をすると、
100回繰り返す(ボトルを買う)中で
n += 1がボトルを購入、
m += 1 if n % 3 == 0がボトルを3本になる毎にボーナスボトルを1本追加するという意味で、
sum = n + mが(購入したボトル + ボーナスボトル)の合計になります。
sum += 1 if sum % 3 == 0でボトルの合計が3の本数であれば+1でボーナスボトルを追加というものになってます。

ただこれで出力結果に3の倍数はなくなったものの、数字が重複してしまい100本購入した時の結果も期待とは異なるもののままです。

この後も色々考えて試してみたんですが結局この問題を解くことはできなかったです(小3の算数の問題...)。
2日で5h以上考えたんですが最終的には上記のコードで少し前回のものから表示結果が変わっただけで期待する結果が出るコードを今の所を書くことができませんでした。

学習効率の観点で今回でこの問題は一旦解くのを中断してまた新しい繰り返しや上手な処理の仕方を知ったり閃いたら解答を再開しようかなと思います。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away