質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Q&A

解決済

2回答

727閲覧

複数行の数字が入力された時の計算について

nakatievent

総合スコア38

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

0グッド

0クリップ

投稿2020/03/03 12:08

前提・実現したいこと

例えば、
t = [1、10、50、70、100] のような配列があり、
2個目以降の数字から1個前の数字を引いた数を求めたいとします。

(回答例)
9
40
20
30

現在、ある問題を解いていて、上記のような回答をプログラムを書いているのですが、
エラーメッセージがでて困っています。
解決できる方がいましたら、お手数ではございますが教えていただければ助かります。

発生している問題・エラーメッセージ

Main.rb:5:in block in <main>': undefined method -' for nil:NilClass (NoMethodError)
from Main.rb:4:in each' from Main.rb:4:in <main>'

該当のソースコード

t = readlines.map(&:to_i)
r = t.length

(1..r).each do |i|
puts t[i] - t[i - 1]
end

試したこと

何度もソースコードを書いたり変えたりしましたが、解決しません。
上記のソースコードで動作確認をしたところ、答えが一緒[期待する出力と一緒]にも関わらずエラーが出てしまいます。

補足情報(FW/ツールのバージョンなど)

ruby

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

1回目の処理は、何から何を引くつもりで、そのコードを書いたのでしょうか?
そのあたりを考え直せばいいです。

投稿2020/03/03 12:43

otn

総合スコア85901

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

nakatievent

2020/03/03 13:12

回答ありがとうございます。 少し配列を変えてみたのですが、やはりエラーが出てしまいます。 t = readlines.map(&:to_i) r = t.length (0..(r-1)).each do |i| puts t[i + 1] - t[i] end まず、t = readlines.map(&:to_i)で配列を作り、 r = t.lengthで配列の長さを決めました。 そして、最初の処理はt[1]からt[0]を引き、それを配列内の要素を変えて繰り返していきたいので、 (0..(r-1)).each do |i| puts t[i + 1] - t[i] end という配列にしたのですが、やはりエラーが出てしまします。 答えは当たってるのに[期待された出力]にならずに数日考えこんでいます。 どうしたらエラーが出ずに済むのでしょうか?
otn

2020/03/03 13:19

失礼しました。初回ではなく、最終回でのエラーですね。 4要素の場合、rは4でt[0],t[1],t[2],t[3]に値が入っています。 t[4]にアクセスしていますが、t[4]はnilなので、nilから引き算しようとしてエラーです。 ループは何回回るかわかりますか?
nakatievent

2020/03/03 13:44

回答ありがとうございます。 一応、要素数については5要素になるので、t[0]~t[4]になります。 なので、(0..(r-1))でループを0~4の5回にしたつもりです。 そして、期待されている出力個数については4個です。 ループの回数と出力個数はイコールじゃないとダメですか?(コメントの意味が分からなければすいません)
otn

2020/03/04 08:00

> ループの回数と出力個数はイコールじゃないとダメですか? 考え方としては、「差を取って出力する」という処理を何回したいかです。 5回ですか?4回ですか?
nakatievent

2020/03/04 12:02

回答ありがとうございます。 とりあえず、(1..r)を(1...r)にすることで問題は解決しました。 色々とご指導ありがとうございます。 今後も分からない点がございましたら、宜しくお願いします!
otn

2020/03/04 12:10

解決はいいのですが、理解できたのでしょうか?
nakatievent

2020/03/04 12:46

お疲れ様です。 t = readlines.map(&:to_i) r = t.length (0..r).each do |i| puts t[i + 1] - t[i] end 最初のプログラムでは、5が変数に代入されると+1されてt[6]になってしまい、そこでエラーが生じるのだと理解しました。 ですので、 (1..(r-1)).each do |i| puts t[i] - t[i - 1] end にすると、t[0]~t[4]の間に収まるのでエラーもでず解決できました。 今までの回答を見返したおかげで気づきました。 ありがとうございます。 あと、もう一つ教えてほしいのですが、今は(1..r)と(1...r)の違いについて調べているところです。 ググっていますが、まだピンとくる答えが出ません。 もしよろしければ、ご教授頂けますでしょうか?
otn

2020/03/04 12:54

> 5が変数に代入されると+1されてt[6]になってしまい、そこでエラーが生じるのだと理解しました。 長さが5の場合、有効な添え字は 0 1 2 3 4 の5個なので、 「4が変数に代入されると+1されてt[5]になってしまい、そこでエラーが生じる」 ですね。 > 今は(1..r)と(1...r)の違いについて調べているところです。 基本文法的なものはググるより、リファレンスを見たほうがいいです。 https://docs.ruby-lang.org/ja/latest/doc/spec=2fliteral.html#range https://docs.ruby-lang.org/ja/latest/doc/spec=2foperator.html#range というか、入門書を読んで入門していれば、書いてあるはず。
nakatievent

2020/03/04 13:02

教えていただきありがとうございます。 少し難しい解説もありますが、参考にさせていただきます。 昨日から回答していただきありがとうございました!
guest

0

ベストアンサー

(1..r).each do |i| を
(1...r).each do |i|
に変えてください。
(1..r).each do |i|だと、最後はt[5]になりますが、それは存在しないのでエラーになっています。
t = [1、10、50、70、100]の場合
要素数はt[0]~t[5]はなく、t[0]~t[4]なので、t[1]~t[4]を処理するようにします。

投稿2020/03/04 01:58

tatsu99

総合スコア5493

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

nakatievent

2020/03/04 12:09

回答ありがとうございます。 上記の方法で試してみたら、解決できました! 最後に、ググっても見つからないので教えてほしいのですが、(1..r)と(1...r)は何が違うのですか?
tatsu99

2020/03/04 13:44

(1..r)は1からrまでの範囲になります。 (1...r)は1からr-1までの範囲になります。 例 (1..4)は1~4迄の範囲 (1...4)は1~3迄の範囲
nakatievent

2020/03/04 13:55

勉強になりました! 回答ありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問