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

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

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

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

Q&A

解決済

4回答

1678閲覧

書いたコードのどこが間違っているのか分かりません

tsukacchan

総合スコア17

Ruby

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

0グッド

0クリップ

投稿2017/02/15 13:01

編集2017/02/15 13:15

num = gets.chomp.split("").map(&:to_i)

while 1
flag = true
(0..num.size-2).each do |i|

diff = num[i + 1] - num[i] ←ここでエラー if diff==1 || diff==-1 num.delete_at(i+1) num.delete_at(i) flag = false end end break if flag==true

end

(0..num.size-1).each do |i|
print num[i]
end

趣味でコード書いている者です。
上コードで問題なく動作すると思っていたのですが、実行すると下ののエラーが発生しうまくいきません。
もしぱっと見て分かる方教えていただけないでしょうか?
今までエラー発生してなぜなのかわからなかったことがないので
どうしていいか分かりません。
よろしくお願いします。

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

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

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

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

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

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

退会済みユーザー

退会済みユーザー

2017/02/15 13:11 編集

numに何を入力したのか教えていただけると助かります。 あとstrという配列の内容を教えてほしいです。
tsukacchan

2017/02/15 13:11

数値の列です。 もし隣り合う数値が連続した数値(差が1)であればその2つの数値を消すといったことを繰り返しています
tsukacchan

2017/02/15 13:17

申し訳ありません入力ミスですstrではなく全てnumです。申し訳ありません以後質問時は気をつけます
guest

回答4

0

なにが起こっているかを調べる方法を2つ示してみます。

1. print 文をいれて状況の変化を知る。

プログラムに次のように、状態を表示する行を追加して実行してみます。

z.rb

ruby

1num = gets.chomp.split(' ').map(&:to_i) 2 3while 1 4 flag = true 5 (0..num.size - 2).each do |i| 6 p i # これを追加 7 p num # これを追加 8 diff = num[i + 1] - num[i] # ←ここでエラー 9 if diff == 1 || diff == -1 10 num.delete_at(i + 1) 11 num.delete_at(i) 12 flag = false 13 end 14 end 15 break if flag == true 16end 17 18(0..num.size - 1).each do |i| 19 print num[i] 20end

走らせてみます。

$ ruby z.rb 1 2 3 0 [1, 2, 3] 1 [3] z.rb:8:in `block in <main>': undefined method `-' for nil:NilClass (NoMethodError) from z.rb:5:in `each' from z.rb:5:in `<main>'

i = 1 になったとき、 num が [3] とサイズ1の配列になっていることがわかります。
この状態で num[1], num[2] にアクセスしようとすることになるので、エラーが発生しているのです。

2. デバッガで、エラーが起こったときブレークさせて、状況を調べる。

プログラムにつぎにように ブレークポイントを設定します。

ruby

1num = gets.chomp.split(' ').map(&:to_i) 2 3while 1 4 flag = true 5 (0..num.size - 2).each do |i| 6 binding.pry if num[ i + 1].nil? # これを追加 7 diff = num[i + 1] - num[i] # ←ここでエラー 8 if diff == 1 || diff == -1 9 num.delete_at(i + 1) 10 num.delete_at(i) 11 flag = false 12 end 13 end 14 break if flag == true 15end 16 17(0..num.size - 1).each do |i| 18 print num[i] 19end

走らせてみます。

$ ruby -r pry z.rb 1 2 3 From: /Users/katoy/zzz/zzz4/z.rb @ line 7 : 2: 3: while 1 4: flag = true 5: (0..num.size - 2).each do |i| 6: binding.pry if num[ i + 1].nil? # これを追加 => 7: diff = num[i + 1] - num[i] # ←ここでエラー 8: if diff == 1 || diff == -1 9: num.delete_at(i + 1) 10: num.delete_at(i) 11: flag = false 12: end [1] pry(main)> i => 1 [2] pry(main)> num => [3] [3] pry(main)> num[i + 1] - num[i] NoMethodError: undefined method `-' for nil:NilClass from (pry):3:in `block in <main>' [4] pry(main)> num[i + 1] => nil

↑では pry というデバッガをつかっています。
$ gem install pry とすることで、pry が利用可能になります。

pry については、 google で "ruby pry" などで検索すれば、たくさんの情報を得ることができます。

投稿2017/02/15 16:36

katoy

総合スコア22324

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

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

0

回答ありがとうございました1行修正で正常に動作しました

num = gets.chomp.split("").map(&:to_i)

while 1
flag = true
(0..num.size-2).each do |i|

diff = num[i + 1] - num[i]

if diff==1 || diff==-1
num.delete_at(i+1)
num.delete_at(i)
flag = false
break ←ここだけ修正
end
end
break if flag==true
end

(0..num.size-1).each do |i|
print num[i]
end

投稿2017/02/15 13:45

tsukacchan

総合スコア17

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

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

0

ベストアンサー

何をしたいのかよく分かりませんが、0からnum.size-2までのループの中で、num自体を切り縮めているので、添え字がそのときの切り縮められたnumからはみ出てしまいます。

投稿2017/02/15 13:17

otn

総合スコア84423

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

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

0

Ruby

1num = gets.chomp.split("").map(&:to_i) 2 3while 1 4flag = true 5(0..num.size-2).each do |i| 6 7diff = num[1] - num[0] 8 9if diff==1 || diff==-1 10num.delete_at(i+1) 11num.delete_at(i) 12flag = false 13end 14end 15break if flag==true 16end 17 18(0..num.size-1).each do |i| 19print num[i] 20end

これで動くかもしれません。
#補足
やっぱり無理かもしれません。

Ruby

1input = gets.chomp.split("").map(&:to_i) 2 3i = 0 4loop{ 5 if input[i + 1] == nil 6 break 7 end 8 if (input[i] - input[i + 1]).abs == 1 9 input.delete_at(i) 10 input.delete_at(i) 11 else 12 i += 1 13 end 14} 15print input.join

自己満足のために追記
332211に対応しています。

投稿2017/02/15 13:24

編集2017/02/16 09:23
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問