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

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

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

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

アルゴリズム

アルゴリズムとは、定められた目的を達成するために、プログラムの理論的な動作を定義するものです。

Q&A

解決済

3回答

1571閲覧

Ruby:二次元配列の検索がわからない

kohei_04

総合スコア12

Ruby

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

アルゴリズム

アルゴリズムとは、定められた目的を達成するために、プログラムの理論的な動作を定義するものです。

0グッド

0クリップ

投稿2021/11/23 06:03

編集2021/11/23 06:41

#お題
Hashではなく配列で記述してください

ホームポジションでは左手で打つキーと右手で打つキーが決まっています。
左手で打つキーは、キーボードの左側の赤色で示した部分です。
右手で打つキーは、キーボードの右側の白色で示した部分です。

(b9e7ef048f822ca90c10aff22e45e1e0.png)明

あなたは癖で、直前に打ったキーをもう一度タイプする場合や、
直前に打ったキーに上下左右のいずれかで隣接しているキーを打った場合に、
ホームポジションに関わらず同じ手で入力してしまいます。
例えば、g を打ったあとに h を打つ場合には g を打った時の左手で h を打ってしまいます。
このまま h をもう一度打つ場合も、直前に h を打った左手で打ってしまいます。

もしytrewqと入力された場合yは右手で打ちその隣にあるtも癖で右手で打ちます。
次は更に左隣にあるrのため続けて癖で右手で打ってしまいます・・・・。

実際に与えられた文字列をタイプする際に、この癖によって違う手でタイピングしてしまう回数を出力してください。

#入出力例

入力例① ytrewq
出力① 5
入力例② qwertyy
出力② 2

#自分で記述中のコード

ruby

1keys = [ 2 %w(q w e r t y u i o p), %w(a s d f g h j k l), %w(z x c v b n m) 3 ] #キーボード 4count = 0 #条件分岐で分けていき癖タイプした時にここに1足してく 5words = gets.chomp  #入力値を受け取る 6words_chars = words.chars  #お題を1文字に分けて配列にする 7key_chars = ["t","g","b","y","h","n"] #左右のボーダーライン 8words_chars.each{|char| 9 if key_chars.include?(char) #左右のボーダーラインにかかったどうか判断 10 11 else 12 next 13 end 14}

ここで止まってしまいました。

#考えている流れ
まずkeys[x][y]の時に隣接しているかを判断する必要があるので
keys[x -1][y]||keys[x +1][y]||keys[x][y -1]||keys[x][y +1]
で分けれれば条件分岐ができると考えています。
もし与えられた値が"y"だった場合keys配列内の"keys[0][5]"になるので次の値が添字の±1の範囲であるかどうかの条件式にしたのですがどうすれば与えられた値"y"を使って検索して"keys[0][5]"すればいいのかがわかりません
Hashであればキーで検索したたらバリューでスグにだせそうな気がするのですが・・・

findメソッドを使用すればもってこれるのでしょうか??
それとも考え方から改めた方がいいのでしょうか??

どなたかご教授お願いいたします。

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

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

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

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

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

episteme

2021/11/23 06:17

しつもんはなんですか?
kohei_04

2021/11/23 06:31

すみません・・・書いたつもりだったのですが消えてしまっていますね スグに追記します。
guest

回答3

0

Hashではなく配列で記述してください

愚直に。

ruby

1def index_on_keyboard(c, keyboard) 2 keyboard.each_with_index{|arr, y| 3 x = arr.index(c) 4 break [x, y] if x != nil 5 } 6end 7 8keyboard = ["qwertyuiop", "asdfghjkl", "zxcvbnm"] 9inputs = "ytrewq" 10#inputs = "qwertyy" 11hand = index_on_keyboard(inputs[0], keyboard)[0] / 5 12mistake = 0 13 14inputs.chars.each_cons(2).map{|consecutive| 15 a, b = consecutive.map{|c| index_on_keyboard(c, keyboard)} 16 pos = [[1, 0], [-1, 0], [0, 1], [0, -1]].map{|x, y| [a[0]+x, a[1]+y]} 17 nhand = b[0] / 5 18 if ([a] + pos).include?(b) then 19 mistake += 1 if hand != nhand 20 else 21 hand = nhand 22 end 23} 24 25p mistake

投稿2021/11/24 02:48

編集2021/11/24 03:29
melian

総合スコア20655

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

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

kohei_04

2021/11/26 10:42

すごい!!かなりコンパクトなコードになっててすごいです!! ありがとうございます!!
guest

0

ああ! 「Hashではなく配列」って制約があったのか
すると末尾にかいた

x,y=nil,nil y = kyes.index{|ary| x = ary.index(char) }

ですね。

以下ボツ
Hashにしたらどうですか?

{ 'q' => [0,0], 'w' => [0,1], : }

あとこういう手も

{ 'q' => %w[w a], 'h' => %w[y g j n], : }

こんなのもあるかな

{ 'q' => %w[w a], 'h' => %w[y G j n], 't' => %w[R y G] : }

配列の配列の検索ってやったことはないですが、index をつかうのかな

x,y=nil,nil y = kyes.index{|ary| x = ary.index(char) }

投稿2021/11/23 13:17

編集2021/11/24 03:00
winterboum

総合スコア23567

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

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

kohei_04

2021/11/26 10:44

いつも回答してくださりありがとうございます!! ハッシュのコードまでありがとうございます!!参考にさせて頂きます!!
guest

0

ベストアンサー

あなたのソースをできるだけ生かしてつくってみました。

Ruby

1# 指定された文字がキーボードのどちら側に属するかを返す(左側:L 右側:R) 2def get_LR(char) 3 if $left_key_chars.include?(char) 4 return "L" 5 end 6 return "R" 7end 8# 指定されたキーの上下左右のキーを配列にして返す(指定されたキー自身も含む) 9def get_border_keys(char) 10 b_keys = [] 11 $keys.each_index do |i| 12 $keys[i].each_index do |j| 13 if $keys[i][j] == char 14 b_keys << char 15 b_keys << $keys[i][j-1] if j > 0 16 b_keys << $keys[i][j+1] if j+1 < $keys[i].length 17 b_keys << $keys[i-1][j] if i > 0 18 b_keys << $keys[i+1][j] if i+1 < $keys.length 19 return b_keys 20 end 21 end 22 end 23end 24 25$keys = [ 26 %w(q w e r t y u i o p), %w(a s d f g h j k l), %w(z x c v b n m) 27 ]#キーボード 28$left_key_chars = %w(q w e r t a s d f g z x c v b) #左のキー一覧 29 30count = 0 #条件分岐で分けていき癖タイプした時にここに1足してく 31words = gets.chomp #入力値を受け取る 32words_chars = words.chars #お題を1文字に分けて配列にする 33prev_key = nil 34prev_LR = nil 35words_chars.each { |char| 36 char_LR = get_LR(char) 37 if prev_key != nil 38 border_keys = get_border_keys(prev_key) 39 if border_keys.include?(char) 40 if char_LR != prev_LR 41 count += 1 42 char_LR = prev_LR 43 end 44 end 45 end 46 prev_key = char 47 prev_LR = char_LR 48} 49puts count 50

以下、実行結果(スクリプトのファイル名はgoo1.rbです)
D:\goo\ruby>ruby goo1.rb
ytrewq
5

D:\goo\ruby>ruby goo1.rb
qwertyy
2

投稿2021/11/24 11:36

編集2021/11/24 12:58
tatsu99

総合スコア5493

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

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

kohei_04

2021/11/26 10:40

ありがとうございます!! ちゃんと動きました!! まだアルゴリズムを追えてなので、しっかり読んでみます!!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問