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

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

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

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

Q&A

解決済

3回答

1979閲覧

配列の中身が条件にあうかどうか

torisan

総合スコア678

Ruby

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

0グッド

0クリップ

投稿2016/04/02 04:36

Ruby1.9.4です。

<前提>
要素の数が0~4個の配列があります。
値は1~7,11~17,21~27のいずれかが入り、同じ数が重複する場合もあります。
並びは小さい順にソートされています。

<やりたい事>
配列の中身の内、いずれか3つの値を調べて
『十の位と一の位がそれぞれ、連続する数値の組み合わせ(順不同)であった時 フラグを立てる。』
という処理を行いたいです。

わかりにくいと思うので例を列挙します。

[]=>false
[1,12]=>false
[2,13,24]=>true #十の位と一の位がそれぞれ、連続する数値である
[4,12,23]=>true #true。一の位が4,2,3だが数値の順序は問わない
[5,6,7]=>false #十の位が一致してしまっている
[7,11,22]=>false #7と1は繋がったりはしない
[3,7,11,22]=>true #余剰データがあってもいずれか3つが条件にあっていればOK
[5,13,13,24]=>true #データが重複していてもOK
[1,4,13,22]=>true #条件が合う組み合わせが2つあっても、ただのtrue

一応自前の処理は動いてはいるのですが、
あまりにも『……。』な処理だったので今回投稿した次第です。
軽い処理が望ましいですが、考え方のみでも結構ですので
お知恵を拝借頂ければと思います。
よろしくお願いします。

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

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

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

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

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

guest

回答3

0

自己解決

自分の回答を置いておきます。

Ruby

1def check0(tmp) 2 tmp2=[] 3 if tmp.size >= 3 then 4 if tmp.size == 4 then #[1,14,17,21] を [1,14,21] と [1,17,21] に分ける 5 for i in 0..2 6 if tmp[i] / 10 == tmp[i + 1] / 10 then 7 tmp2 = Marshal.load(Marshal.dump(tmp)) 8 tmp.delete_at(i + 1) 9 tmp2.delete_at(i) 10 break 11 end 12 end 13 end 14 tmp3 = [tmp[0] % 10,tmp[1] % 10,tmp[2] % 10].sort 15 if tmp3[0] + 1 == tmp3[1] and tmp3[1] + 1 == tmp3[2] then 16 tmp3 = [tmp[0] / 10,tmp[1] / 10,tmp[2] / 10].sort 17 if tmp3[0] == 0 and tmp3[1] == 1 and tmp3[2] == 2 then 18 return true 19 end 20 end 21 if tmp2.size >= 3 then 22 tmp3 = [tmp2[0] % 10,tmp2[1] % 10,tmp2[2] % 10].sort 23 if tmp3[0] + 1 == tmp3[1] and tmp3[1] + 1 == tmp3[2] then 24 tmp3 = [tmp2[0] / 10,tmp2[1] / 10,tmp2[2] / 10].sort 25 if tmp3[0] == 0 and tmp3[1] == 1 and tmp3[2] == 2 then 26 return true 27 end 28 end 29 end 30 end 31 return false 32end

投稿2016/04/03 11:30

torisan

総合スコア678

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

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

0

質問文にある配列の判定はできることを確認しています。

ruby

1# ary が 連続した3つの数字列をもっているかをチェックする 2def has_seq?(ary) 3 ary.each_cons(3) do |nums| 4 return true if nums[-1] - nums[0] == 2 5 end 6 false 7end 8 9def check(ary) 10 keta1 = ary.map { |x| x % 10 }.sort.uniq # 1の位の数字だけを取り出す 11 keta10 = ary.map { |x| x / 10 }.sort.uniq # 10の位の数字だけを取り出す 12 13 return false unless has_seq?(keta1) 14 return false unless has_seq?(keta10) 15 true 16end 17 18TESTS = [ 19 [[], false], 20 [[1, 12], false], 21 [[2, 13, 24], true], # 十の位と一の位がそれぞれ、連続する数値である 22 [[4, 12, 23], true], # true。一の位が4,2,3だが数値の順序は問わない 23 [[5, 6, 7], false], # 十の位が一致してしまっている 24 [[7, 11, 22], false], # 7と1は繋がったりはしない 25 [[3, 7, 11, 22], true], # 余剰データがあってもいずれか3つが条件にあっていればOK 26 [[5, 13, 13, 24], true], # データが重複していてもOK 27 [[1, 4, 13, 22], true] # 条件が合う組み合わせが2つあっても、ただのtrue 28].freeze 29 30TESTS.each do |test| 31 puts "ERROR #{test}" if test[1] != check(test[0]) 32end

投稿2016/04/02 08:42

katoy

総合スコア22324

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

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

torisan

2016/04/03 11:30

シンプルでいい感じですね。 回答ありがとうございました。
guest

0

Ruby

1def check(list) 2 list. 3 # 無駄な重複を無くします。 4 uniq. 5 # 10の位と1の位に分離して配列にします。 6 map { |i| [i / 10, i % 10] }. 7 # 3個を抜き出した全ての組み合わせを羅列します。 8 combination(3). 9 # 10の位と1の位それぞれをまとめた配列にします。 10 map { |a| 2.times.map { |x| 3.times.map { |y| a[y][x] } } }. 11 # 組み合わせのうち何れかが条件を満たせばtrueにします。 12 any? do |a| 13 # 10の位と1の位それぞれについて、両方条件を満たせばtrueにします。 14 a.all? do |ak| 15 # ソートした後に重複しながら2つ取り出してその差分がすべて1であるかを 16 # 確認することで、連続している数値なのかを確認します。 17 ak.sort.each_cons(2).all? { |ai| ai[1] - ai[0] == 1 } 18 end 19 end 20end

要素数が多く、組み合わせが膨大になる場合は、combination(3).の後にlazy.を足すと、配列を作らずにtrueが見つかり次第返るようになり、メモリ消費量も抑えられます。(ただし、lazyが使えるのは2.0.0からです)
lazyを使わない場合は、any?前のmapでやっていることをany?の中ですると良いでしょう。そこは自分で工夫してみてください。

投稿2016/04/02 06:19

raccy

総合スコア21735

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

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

torisan

2016/04/03 11:19

関数をフル活用している感じですね。 条件の指定によっては効率の良いものができるかもしれません。 回答ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問