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

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

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

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

アルゴリズム

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

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

コードレビュー

コードレビューは、ソフトウェア開発の一工程で、 ソースコードの検査を行い、開発工程で見過ごされた誤りを検出する事で、 ソフトウェア品質を高めるためのものです。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

Q&A

解決済

7回答

1622閲覧

Rubyのワードビンゴアルゴリズムに困っております。

test_user_222

総合スコア20

Ruby

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

アルゴリズム

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

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

コードレビュー

コードレビューは、ソフトウェア開発の一工程で、 ソースコードの検査を行い、開発工程で見過ごされた誤りを検出する事で、 ソフトウェア品質を高めるためのものです。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

0グッド

0クリップ

投稿2020/11/13 06:18

編集2020/11/15 08:29

前提・実現したいこと

Rubyでワードビンゴを作成しています。
Sを入力させるとSxSマスが出力されて、次にNを入力させると
N個の文字を表示させて、それが先ほどのSxSマスでビンゴであった場合Yes.Noで判定するものです。
SxSマスにある文字とN個の文字が一致していれば印も出さないといけないです。
例えば、S=3の場合、カードマスは
test1 test2 test3
test4 test5 test6
test7 test8 test9
と出力し、
次に、マスを開ける回数をNとしN個カードマスを出力します。
例、N=5
test1
test5
test8
test9
test6

ビンゴがあれば、「Yes」、なかったら、「No」と表示させるプログラムを作成したいです。

発生している問題

S = gets.to_i nums=S*S #1 ~ S x S row=Array.new(S).map{Array.new(S,0)} #横 col=Array.new(S).map{Array.new(S,0)} #縦

初学者でそもそもアルゴリズムが思いつきません。
どういうコードを書けばいいのかすらわからない状態です。

https://teratail.com/questions/298325を
見ても理解できなかったです。

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

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

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

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

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

no1knows

2020/11/13 06:27

Lancersなどのお仕事を依頼するサイトの活用をおすすめします。 もしくは「Ruby ビンゴ」で検索すればそれなりの情報が出てくると思います。
dodox86

2020/11/13 06:37

初のご質問のようなので質問者さんのRubyの習熟度は分かりませんが、最初から難しいことをやろうとしすぎです。 まず、頭の中でビンゴゲームをどのように進めるか、つまり、最初に盤面をどのように作るか、 次に"test1"と言う目がきたら盤面からどう探し、穴をあけるかを具体的にイメージします。 それを素直にRubyのコードに書けば、実直、あるいは愚直かもしれませんがプログラムは出来上がります。アルゴリズムを考える(<設計)のと、プログラムを書く(<実装)のとは別に考えましょう。
test_user_222

2020/11/13 06:37

ruby ビンゴで調べてもマスが決まっている数字のビンゴは出てくるんですが、gets.to_iの数値でマスを選択するアルゴリズムが出てこないです。
dodox86

2020/11/13 06:39

いや、そのアルゴリズムは質問者さんが考えるんですよ。。。メソッドを使えば魔法のように解ける訳ではありません。
test_user_222

2020/11/13 06:44

そうですよね笑。かれこれ三時間くらい思考したんですけど、ランダム文字をマスのように横に広げる方法が一向に思いつきません。ヒントもらえないでしょうか?
no1knows

2020/11/13 06:47

dodox86さん 丁寧な対応ありがとうございます。僕のコメントは良くなかったです。。。 onsinhutuuさん > gets.to_iの数値でマスを選択する これはgets.to_iの使い方がわからないということでしょうか? それともどのようにマスを選択させるのかがわからないということでしょうか?
test_user_222

2020/11/13 06:54

gets.to_iの使い方は理解しているんですが、上記の例で言うとtest1,test2,test3のように横にマスを広げるやり方がわからないです。普通は縦にしか出力しないと思うんですが横にgets.to_i分出力させる方法がわからないです。、縦にgets.to_i分させる方法は分かりました。
test_user_222

2020/11/13 07:20 編集

S=gets.to_i row = Array.new(S).map{Array.new(S," ")} puts S.times.map{|i| row[i][i]}.join "test" puts S.times.map{|i| row[i][S-i-1]}.join "test" puts S.times.map{|i| row[i][S-i-2]}.join "test" 調べてこのコードで3x3のマスを出力できたんですが、 [i][i]なぜ[i][i]を二個続けてるんでしょうか
dodox86

2020/11/13 07:20

参考にされた https://teratail.com/questions/298325 でも他回答者さんに指摘されていますが、どちらかの競技プログラミング系のサイトの問題ではないのでしょうか。そうであれば出典(URL等)を明示してください。※よくよく見たら、私も別のコメントをしていましたね。
test_user_222

2020/11/13 07:23

競技プログラミング系のサイトの問題ではないです。
no1knows

2020/11/13 07:24

> [i][i]なぜ[i][i]を二個続けてるんでしょうか 2次元配列ですね。
dodox86

2020/11/13 07:26

。。。なぜ、ご自身で理解できないコードを使おうとするのか。 とりあえず複数人からコメントされると混乱すると思いますので、私は以降、コメントおよび回答を控えます。
test_user_222

2020/11/13 07:57

Sの回数だけブロック要素として|i|を渡してる思うんですが[i][i]には0などが入るのでしょうか。
guest

回答7

0

まず、あなたがすべきは入力と出力を明確にする事かと思います。

この問題文からはハッキリしないのですが
おそらく例示された入力は

3 test1 test2 test3 test4 test5 test6 test7 test8 test9 5 test1 test5 test8 test9 test6

でしょうか


次に、前半の

3 test1 test2 test3 test4 test5 test6 test7 test8 test9

から

ruby

1S = 3 2ビンゴカード = [ 3 ["test1", "test2", "test3"], 4 ["test4", ...] 5 ... 6]

というデータを作成します。

やり方としては、getsで一行(test1 test2 test3)入力させ、String#splitにて分割するのが楽かと思います。


そして、後半の入力に対してビンゴカードから検索して

  • 当該箇所をnilに置換する
  • 判定用のビンゴカードを別に用意してそちらに記入する

どちらか好きな方法をとるとよいでしょう。


最後にビンゴ判定を行います。
縦(S)・横(S)・斜め(2)の計S+S+2のパターンに対して判定を行い
結果を出力します

投稿2020/11/13 22:58

編集2020/11/14 06:00
asm

総合スコア15147

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

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

test_user_222

2020/11/13 23:47

質問が曖昧で申し訳ございません。 Sを入力させるとSxSマスが出力されて、次にNを入力させると N個の文字を表示させて、それが先ほどのSxSマスでビンゴであった場合Yes.Noで判定するものです。 SxSマスにある文字とN個の文字が一致していれば印も出さないといけないです。
test_user_222

2020/11/14 00:07

S*S*2の判定はnil?/empty?/blank?/present?などですか?
asm

2020/11/14 00:16

> Sを入力させるとSxSマスが出力されて、次にNを入力させると なるほど、そういう問題なのですね > S*S*2の判定はnil?/empty?/blank?/present?などですか? ひとつでもビンゴがあればYesなのでany?およびall?ですね 最も楽な横の判定の場合 横判定 = ビンゴカード.any?{|line| line.all?(nil) }
test_user_222

2020/11/14 00:43 編集

row = word_arr.any?{|line| line.all?(nil) } if row = false puts 'Yes' else puts 'NO' end みたいな感じで作ったのですがビンゴカードは最初のSxSマスのものですか?
test_user_222

2020/11/14 00:44

undefined method `all?' for "p9s7":String (NoMethodError)というエラーが出ます
test_user_222

2020/11/14 00:49

そもそもnillに置換してなかったです笑これ印もつけたいんですがnilに置換したものに印をつけるみたいにかけばいいんですか?
asm

2020/11/14 01:09

> ビンゴカードは最初のSxSマスのものですか? とりあえず今の所の想定はそうですねS*Sの二次元配列を想定したものでした > そもそもnillに置換してなかったです笑これ印もつけたいんですが マスに入る単語に制限があり印とやらと区別が付くのならnilへ置換する代わりに印をつけたものに置換してもよいです
test_user_222

2020/11/14 01:25

印をつけるやり方が思いつきません。includeで試したんですがどんなやり方がありますか?
asm

2020/11/14 01:38

条件次第ですね。 同じ単語のマスが複数存在しない前提ならばfind_indexで探して置換します。 複数あるのならばmapにて検索と置換を行います
test_user_222

2020/11/14 02:16

複数存在しないのでfind_indexだと思います。調べてみます。
test_user_222

2020/11/14 02:25

find_indexの検索方法が引数と一致する要素が最初に見つかったときの添え字を返すなんですが、一つだけしか印つかないってことですか?
asm

2020/11/14 03:18

複数存在しないのですよね?問題ないように思いますが
test_user_222

2020/11/15 12:11

asmさんが最初に提示されてたやつが正しかったんだ。。
asm

2020/11/15 12:18

どういったデータが、どういう形式・書式で入力されるか それを最初に確認する事が大事なのです。
test_user_222

2020/11/15 12:21

今回のような事がおきてしまうんですよね。深く反省します
guest

0

ベストアンサー

画面(標準入力)から単語を入力した場合のword_arrとword_nを作成するスクリプトです。
単語を毎回入力するのは大変なので、以下のようにすると楽に試験ができるようになります。
まず、入力するデータを予め作成し、それをテキストファイルとして保存します。(data.txtとします)
スクリプトがsample.rbとすると、コマンドプロンプトで
ruby sample.rb < data.txt
と入力すると、標準入力から、data.txtに書かれている内容を打ち込んだのと同じ結果になります。

Ruby

1S = gets.to_i 2word_arr = Array.new 3(0..S-1).each do |i| 4 arr = gets.chomp.split(nil) 5 word_arr << arr 6end 7N = gets.to_i 8word_n = Array.new 9(0..N-1).each do |i| 10 word_n << gets.chomp 11end 12 13pp word_arr 14pp word_n 15

以下実行結果です。(スクリプトはgoo1.rb)
D:\goo\ruby>ruby goo1.rb < data.txt
[["apple1", "egg1", "word1", "http1"],
["apple2", "egg2", "word2", "http2"],
["apple3", "egg3", "word3", "http3"],
["apple4", "egg4", "word4", "http4"]]
["apple1", "apple2", "apple3", "apple4", "egg1", "word1", "http1"]

data.txtの内容
D:\goo\ruby>type data.txt
4
apple1 egg1 word1 http1
apple2 egg2 word2 http2
apple3 egg3 word3 http3
apple4 egg4 word4 http4
7
apple1
apple2
apple3
apple4
egg1
word1
http1

投稿2020/11/15 23:31

tatsu99

総合スコア5438

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

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

tatsu99

2020/11/15 23:47

ちょっと、気になったのですが、 >N 個の単語が選ばれた時点で勝利条件を満たしているか(ビンゴかどうか)、すなわち 縦・横・なな >めのいずれか1列にある S マスが揃って印がついているかどうかを判定してください。 ということなので、ビンゴ判定はN個の単語を全て処理した後(★印を付けた後)、一気にやるような気がします。(私が前回提示したのは1つの単語を処理するごとにビンゴ判定し、ビンゴならそれで打ち切りです。N個の単語全てを処理しません)
tatsu99

2020/11/15 23:51

更に気になる点を連投していきます。 サンプルをみるとN個の単語は、かならずしもS個の単語中にあるとは限らないと思いますが以下がでしょうか。そうであれば、find_positonからnilが返ります。それは、バグではなく、word_arrの中になかったということなので印をつけずに、スキップするようにしなければいけません。
tatsu99

2020/11/15 23:57

N個の単語を全て、処理の後、ビンゴ判定ということであれば、それらの判定に先立ち以下の条件を チェックするのは意味のあることかと思います。 word_arr中の単語に同じものがないこと。 word_arr中の1つの単語は1文字~100文字の範囲であること。 Sは3~1000の範囲内であること。 Nは1から???の範囲内であること。(???は不明) N個の単語に同じものがないこと。 N個の単語の各単語は、1文字~100文字の範囲内であること。 これらの条件は、問題文にはどのように書かれていますか?
test_user_222

2020/11/15 23:59

>ビンゴならそれで打ち切りです。N個の単語全てを処理しません) 一気にやらないとだめそうですね。 >サンプルをみるとN個の単語は、かならずしもS個の単語中にあるとは限らないと思いますが以下がでしょうか。 条件に書いてないのでかならずしもS個の単語中にあるとは限らないと思います。
tatsu99

2020/11/16 00:05

試験官は、あなたが書いたスクリプトを実行し、標準出力に出力された内容をチェックし(プログラムで自動チェック)、合否を判定しようとしています。したがって、標準出力に出力する内容は1文字たりとも違っていてはいけません。(例えばYESはOKだがyesはNGのようなことがあり得ます) 問題文にはどのように出力しなさいと記述されていますか。(ビンゴの場合とビンゴでない場合を提示してください)
test_user_222

2020/11/16 00:55 編集

ビンゴが小文字のyesでそうでない場合が小文字のnoです。 >word_arr中の単語に同じものがないこと。 word_arr中の1つの単語は1文字~100文字の範囲であること。 Sは3~1000の範囲内であること。 Nは1から???の範囲内であること。(???は不明) N個の単語に同じものがないこと。 N個の単語の各単語は、1文字~100文字の範囲内であること。 これらの条件は、問題文にはどのように書かれていますか? Aij, wiは半角英数字のみ 3 ≤ S ≤ 1000 Ai1,j1 ≠ Ai2,j2 ((i1j1≠i2j2)) 1 ≤ Ai,j の文字数≤ 100 1 ≤ N ≤ 2000 1 ≤ wi の文字数 ≤ 100 wi ≠ wj(i ≠ j) です
tatsu99

2020/11/16 00:08

出力するのは、yes又はnoだけですか。word_arrもしくはhanteiの内容を出力しなくてよいのですか。 それなら☆印にこだわる必要はありません。
test_user_222

2020/11/16 00:15

>出力するのは、yes又はnoだけですか。word_arrもしくはhanteiの内容を出力しなくてよいのですか。 それなら☆印にこだわる必要はありません。 word_arrとhanteiの内容を出力しなくも良いです。さいごにyesかnoだけ出力します。
test_user_222

2020/11/16 00:56 編集

おそらく完成しました!!! Aij, wiは半角英数字のみ 3 ≤ S ≤ 1000 Ai1,j1 ≠ Ai2,j2 ((i1j1≠i2j2)) 1 ≤ Ai,j の文字数≤ 100 1 ≤ N ≤ 2000 1 ≤ wi の文字数 ≤ 100 wi ≠ wj(i ≠ j) この条件文の解釈が合っていればできました
tatsu99

2020/11/16 01:02

完成であれば、あなたが、回答欄に投稿も可能ですので、そのスクリプトを回答欄に投稿していただけませんでしょうか。 投稿時は、<code>をクリックして ```Ruby ここにスクリプトを貼り付ける ``` のようにしてください。そうしないと、インデントがくずれて醜くなります。
tatsu99

2020/11/16 01:09

もし、なにか理由があって投稿出来ない場合は、しなくてかまいません。
test_user_222

2020/11/16 01:24 編集

>もし、なにか理由があって投稿出来ない場合は、しなくてかまいません。 完成のコードを載せるのは怒られるかもしれないのでやめておきます。 本当に金曜日から、ありがとうございました。tatsu99さんのような聖人が世にいることに感動しました。 プログラミング学習始めて4ヶ月目なので最初何もわからなかったんですが、このビンゴで少しはruby鍛えられたと思うのでこれからも学習に励んでいきたいと思います。
guest

0

当たりのところに☆をつけるバージョンです。
横ビンゴの判定のみです。ほかは、付け加えてください。
かなり、書き換えました。これを使って下さい。

ruby

1#配列の印字 2def print_array(arr_name,arr) 3 printf("Array=%s\n",arr_name) 4 (0..S-1).each do |i| 5 (0..S-1).each do |j| 6 printf("%s ",arr[i][j]) 7 end 8 printf("\n") 9 end 10end 11#文字の検索 12def find_position(arr,val) 13 (0..S-1).each do |i| 14 (0..S-1).each do |j| 15 if arr[i][j] == val 16 return i,j 17 end 18 end 19 end 20 return nil,nil 21end 22#横のビンゴ判定 23def bingo_row(hantei,i0,j0) 24 (0..S-1).each do |j| 25 #1つでも頭に星がついていないならNO 26 if hantei[i0][j][0] != "☆" 27 return false 28 end 29 end 30 #全て頭に星がついている場合、YES 31 return true 32end 33 34S = gets.to_i 35word_arr = Array.new(S) 36data = [*'a'..'z', *'0'..'9'] 37(0..S-1).each do |i| 38 ar = Array.new(S){data.sample(4).join} 39 word_arr[i] = ar 40end 41print_array("word_arr",word_arr) 42 43N = gets.to_i 44word_arr_flat = word_arr.flatten 45word_n = word_arr_flat.sample(N) 46 47word_n.each do |word| 48 printf("%s ",word) 49end 50printf("\n") 51 52hantei = Marshal.load(Marshal.dump(word_arr)) 53print_array("hantei",hantei) 54ctr = 0 55word_n.each do |val| 56 i,j = find_position(word_arr,val) 57 if i == nil 58 printf("バグのため終了\n") 59 exit 10 60 end 61 hantei[i][j] = "☆" + hantei[i][j] 62 # 以下4つのビンゴ判定(4つのメソッドをつくったほうがよいかと思います) 63 ret = bingo_row(hantei,i,j) 64 if ret == true 65 printf("横 ビンゴ\n") 66 ctr += 1 67 break 68 end 69end 70if ctr == 0 71 printf("ビンゴなし\n") 72end 73print_array("hantei",hantei) 74 75

投稿2020/11/14 13:30

編集2020/11/14 14:24
tatsu99

総合スコア5438

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

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

test_user_222

2020/11/14 13:41

w6jz 5m6q 7kjo cnom lh1u 1og8 w0vt 1l7p 26mc lrus 2g9x urfm ze6n 6kpe kxon ql8z rl2g d873 0mho 1sa8 otgs wfv0 ku6r bjth bqci みたいに 出したいのですが、本日は就寝します。 明日も引き続きご指導お願いします。
test_user_222

2020/11/14 22:25 編集

おはようございます。自分のしたい感じにアレンジして今動作確認しました。 hantei = Marshal.load(Marshal.dump(word_arr))を調べたんですが >marshalライブラリによるディープコピーで書き換える。これなら元の配列の要素を破壊的に変更しても複製した配列に影響はない。 とのことなのでword.arrが書き換えられないようにしてると思うんですが、それをやる意味は何ですか?
tatsu99

2020/11/14 22:40

そうしないと、hanteiを書き換えたとき、word_arrも同じように書き換えられてしまうからです。 それを防止するためにディープコピーしています。 以下のスクリプトを実行してください。 S = gets.to_i word_arr = Array.new(S) data = [*'a'..'z', *'0'..'9'] (0..S-1).each do |i| ar = Array.new(S){data.sample(4).join} word_arr[i] = ar end hantei = word_arr #コピー pp word_arr pp hantei hantei[0][0] = "ABC" pp hantei pp word_arr 両方書き換わることがわかります。 hantei = word_arr.dup #コピー にしても同じ結果です。
test_user_222

2020/11/14 22:43 編集

あと、3 <= S <= 1000とか条件判定したい場合って4つの判定メソッドの if hantei[i0][j][0] != "☆" return false end if (ここに、1000 >= S >= 3)を入れればOKですか? return false end それともelsifとかでつなげていんですか?
tatsu99

2020/11/14 22:49

S = gets.to_i の直後にしてください。 ちなみに if 1000 >= S >= 3  OKの処理 else  NGの処理 end とは書けません。 if 1000 >= S && S <= 3  OKの処理 else  NGの処理 end と書いてください
test_user_222

2020/11/14 22:56

>hanteiを書き換えたとき、word_arrも同じように書き換えられてしまうからです。 後から書き換えると元のword_arrも変わるんですね。これってrubyだけでなく他の言語でもA = Bだったら Aを書き換えたら自動的にBも書き換えられるんですか? >if 1000 >= S && S <= なるほどです。これをビンゴのtrue条件に入れたい場合ってどうしたらいいですか。
tatsu99

2020/11/14 23:04

他の言語でも書き換わったと記憶しています。 (私が体験したのはperl,C#だけですが) 横のビンゴ判定なら以下のようになります def bingo_row(hantei,i0,j0) if S > 1000 || S < 3 return false end (0..S-1).each do |j| #1つでも頭に星がついていないならNO if hantei[i0][j][0] != "☆" return false end end #全て頭に星がついている場合、YES return true end
tatsu99

2020/11/14 23:15

そもそも論ですが Sに-1をいれると異常終了しますが、それはそれでよいのでしょうか。
test_user_222

2020/11/14 23:17 編集

>if S > 1000 || S < ここ>=でも大丈夫ですか? 今のところ考えたのが word_arr[i1][j1] != word_arr[i2][j2] && [i1][j1] != [i2][j2] 1000 >= S && S <= 3 2000 >= N && N <= 1 100 >= word_arr[i][j] && word_arr[i][j] <= 1 100 >= word_n[i] && word_n <= 1 word_n[i1][j1] != word_n[i2][j2] ですが、これもreturn falseのところに挿入すれば大丈夫ですか?
test_user_222

2020/11/14 23:20

>Sに-1をいれると異常終了しますが、それはそれでよいのでしょうか。 先ほど記述した1000 >= S && S <= 3以外の入力がない前提です。
tatsu99

2020/11/14 23:22

100 >= word_arr[i][j] && word_arr[i][j] <= 1 この意味が分かりません。word_arr[i][j]の内容は文字列"acd3"などのはずです
test_user_222

2020/11/14 23:28 編集

word_arr[i][j] <= 1はword_arr[i][j] >= 1でした。 ym8a tp9l sfol avr0 zl8a zlfn 1uw2 7yl1 cwuq この標準出力されたマスの文字が1以上100以下を判定したいです。
tatsu99

2020/11/14 23:25

>>Sに-1をいれると異常終了しますが、それはそれでよいのでしょうか。 >先ほど記述した1000 >= S && S <= 3以外の入力がない前提です。 それなら、判定のメソッドにいれる必要もないとおもいますがいかがでしょうか。
tatsu99

2020/11/14 23:27

>この標準出力された文字が1以上100以下を判定したいです。 文字数が1以上100以下を判定したいということですか?(この場合は4文字)
test_user_222

2020/11/14 23:29

>それなら、判定のメソッドにいれる必要もないとおもいますがいかがでしょうか。 自分もそう思いますが、いれないといけない条件文にそう記述されていたので仕方なしです。 >文字数が1以上100以下を判定したいということですか?(この場合は4文字) そうです!
tatsu99

2020/11/14 23:38

それなら word_arr[i][j].size としてください。それで文字数が判定できます。 word_n[i1][j1] != word_n[i2][j2] の意味が分かりません。word_nは1次元配列のはずです。添え字が2つになるのはおかしいです。 word_arr[i1][j1].size != word_arr[i2][j2].size は、両者の文字数がことなることを判定していますが、 今回は必ず4文字なのでこれは成立しませんが宜しいですか。
test_user_222

2020/11/14 23:44

>word_arr[i1][j1].size != word_arr[i2][j2].size は、両者の文字数がことなることを判定していますが、 今回は必ず4文字なのでこれは成立しませんが宜しいですか。 ここは違う文字であることを証明したいので.size使わないと思いますがword_arr[i1][j1].で返る値って文字列ですよね。”aaa"の” ”を外して判定ってできますか?
tatsu99

2020/11/14 23:47

>ここは違う文字であることを証明したいので ああ、それであれば、 word_arr[i1][j1] != word_arr[i2][j2] で問題ありません。
tatsu99

2020/11/14 23:48

ちょっと、30分~40分ほどこれから外出します。
test_user_222

2020/11/14 23:49

承知致しました。手探りでtry&errorします
tatsu99

2020/11/15 00:43

すみません。冷静になって考えると、問題とかけ離れたことをしているような気がしてきました。 問題そのものをそのまま、質問欄に提示できないしょうか。 たぶん、想像ですが、 word_nはword_arrと同じ構成であり(従って1次元配列ではない)、そこにN個の文字列を 埋め込むような気がします。各文字列の位置は、word_arrと同じ位置です。 word_nの各文字列を1つずつオープンし、それが、横1列又は縦1列又は斜め1列に並べばYes のような気がしてきました。
test_user_222

2020/11/15 04:24

入力される値 入力は以下の形式で標準入力から与えられます。 S A ... 1,1 A1,2 A1,S A ... 2,1 A2,2 A2,S … A ... S,1 AS,2 AS,S N w1 w2 … wN 1行目には、ビンゴカードのサイズ S が入力されます。 続いて、ビンゴカードの単語がスペース区切りで S 行入力されます。 次の行には、選ばれた単語の数 N が入力されます。 続いて、選ばれた単語が N 行入力されます。
test_user_222

2020/11/15 04:29

今のままで大丈夫な気がしますが、、どうなんでしょう笑
tatsu99

2020/11/15 04:54

いままで作成したソースにはビンゴの単語の入力の個所がありませんが、これは後で組み込むということでしょうか。 条件判定の個所に word_arr[i1][j1] != word_arr[i2][j2] && [i1][j1] != [i2][j2] 1000 >= S && S <= 3 2000 >= N && N <= 1 100 >= word_arr[i][j] && word_arr[i][j] <= 1 100 >= word_n[i] && word_n <= 1 word_n[i1][j1] != word_n[i2][j2] を組み込みたいということですが、それはうまくいったのでしょうか。 又、問題には、条件判定に組み込むべきことを、どのように記述されているのでしょうか。
test_user_222

2020/11/15 06:23

いままで作成したソースにはビンゴの単語の入力の個所がありませんが、これは後で組み込むということでしょうか。 > 3 apple orange cube batch web cloud sql http https 7 web https windows batch keyboard apple cpu 入力例がこれなので動きは正しいと思います。 >を組み込みたいということですが、それはうまくいったのでしょうか。 判定メソッド4つの中で書くと 100 >= word_arr[i][j] && word_arr[i][j] <= 1 100 >= word_n[i] && word_n <= 1 word_n[i1][j1] != word_n[i2][j2] のword.arrとword_nがundefineとなってしまいます。 >問題には、条件判定に組み込むべきことを、どのように記述されているのでしょうか。 N 個の単語が選ばれた時点で勝利条件を満たしているか(ビンゴかどうか)、すなわち 縦・横・なな めのいずれか1列にある S マスが揃って印がついているかどうかを判定してください。
test_user_222

2020/11/15 06:30

条件の最後が wi =/ wj (i =/ j) となっていてここだけ理解できないです。
asm

2020/11/15 06:38

あれ、やっぱり私が最初に想定した奴っぽいですね
test_user_222

2020/11/15 06:50

あともうちょいなんですが笑
asm

2020/11/15 07:16

=/って≠でしょうか?
asm

2020/11/15 07:22 編集

wi ≠ wj (i≠j) 「"入力"される単語wiとwjは(iとjが別ならば)同じ単語ではない、つまりw0..wNに同じ単語はない」という意味ですね
test_user_222

2020/11/15 07:22

そのはずです。自分はそう解釈しております。
asm

2020/11/15 07:40

出力ではなく入力というところがポイントですね。 あなたが単語w0..wNを生成する必要はないでしょう。 (あなたが出題者なら別ですが)
test_user_222

2020/11/15 07:53

本当ですね。自動テストを通せるように、必ず入力は標準入力から受け取り、答えの出力は標準出力に行って ください。と書いてるのでどうなんですかね。入力される = 出力ではないんですかね。
asm

2020/11/15 07:58

> 入力される = 出力 違います。 標準入力と標準出力は、コンソールの場合表示の関係上同一に見えますが 別の装置(筒みたいなもん)になります。
test_user_222

2020/11/15 08:03 編集

おそらく杞憂ではないかと思うですが、どう思われますか?
asm

2020/11/15 08:03

標準入力から受け取ってください
test_user_222

2020/11/15 08:06

getsが標準入力から受け取るものではないんですか?
asm

2020/11/15 08:10

そうです。 ビンゴカードおよび単語リストもgetsにて受け取ります
test_user_222

2020/11/15 09:50

ビンゴカードおよび単語リストも自分で入力するってことですか?
tatsu99

2020/11/15 10:03

入力される値 >入力は以下の形式で標準入力から与えられます。 >S >A ... 1,1 A1,2 A1,S >A ... 2,1 A2,2 A2,S をすなおに受け取ると、そうなりますね。 問題の全文が提示されているサイトのURLを提示可能でしょうか? それとも、問題の全文は紙であなたが持たれているのでしょうか? 私たち回答者は、どのようにすれば、問題の全文を知ることができますか?
asm

2020/11/15 10:10

「あなたがあなたのコンソール上で動かす」のならばそうです。 自動テストを通す際には、動かす人(?)が入力してくれます。
test_user_222

2020/11/15 10:28

>自動テストを通す際には、動かす人(?)が入力してくれます。 自動テストが一個ずつ入力してくれるってことですよね。 >私たち回答者は、どのようにすれば、問題の全文を知ることができますか? pdfで所持していますがおそらくネットで公開するべきではないので全文掲載は厳しいです。 しかし、 >入力は以下の形式で標準入力から与えられます。 >自動テストを通せるように、必ず入力は標準入力から受け取り、答えの出力は標準出力に行って ください。 とのことのなので自動テストで一個ずつ入力するんだと思います。
test_user_222

2020/11/15 10:30

条件判定メソッドは自力で完成しました!
test_user_222

2020/11/15 10:31

もし全てを標準入力で行うとすると4で指定しているところをgets.to_iで取得するってことですか?
guest

0

今までの分をまとめたものを張っておきます。
前の回答での誤記がいくつかありましたので、修正しました。
動作確認済みです。
縦ビンゴ、斜めビンゴはあなたのほうで加えてください。

ruby

1#文字の検索 2def find_position(arr,val) 3 (0..S-1).each do |i| 4 (0..S-1).each do |j| 5 if arr[i][j] == val 6 return i,j 7 end 8 end 9 end 10 return nil,nil 11end 12#横のビンゴ判定 13def bingo_row(hantei,i0,j0) 14 (0..S-1).each do |j| 15 #1つでも0ならNO 16 if hantei[i0][j] == 0 17 return false 18 end 19 end 20 #全て1の場合、YES 21 return true 22end 23 24 25S = gets.to_i 26word_arr = Array.new(S) 27data = [*'a'..'z', *'0'..'9'] 28(0..S-1).each do |i| 29 ar = Array.new(S){data.sample(4).join} 30 word_arr[i] = ar 31end 32 33(0..S-1).each do |i| 34 (0..S-1).each do |j| 35 printf("%s ",word_arr[i][j]) 36 end 37 printf("\n") 38end 39 40N = gets.to_i 41word_arr_flat = word_arr.flatten 42word_n = word_arr_flat.sample(N) 43 44word_n.each do |word| 45 printf("%s ",word) 46end 47printf("\n") 48 49hantei = Array.new(S) 50(0..S-1).each do |i| 51 ar = Array.new(S,0) 52 hantei[i] = ar 53end 54ctr = 0 55word_n.each do |val| 56 i,j = find_position(word_arr,val) 57 if i == nil 58 printf("バグのため終了\n") 59 exit 10 60 end 61 hantei[i][j] = 1 62 # 以下4つのビンゴ判定(4つのメソッドをつくったほうがよいかと思います) 63 ret = bingo_row(hantei,i,j) 64 if ret == true 65 printf("横 ビンゴ\n") 66 ctr += 1 67 break 68 end 69end 70if ctr == 0 71 printf("ビンゴなし\n") 72end 73pp hantei

実行結果
5
w6jz 5m6q 7kjo cnom lh1u
1og8 w0vt 1l7p 26mc lrus
2g9x urfm ze6n 6kpe kxon
ql8z rl2g d873 0mho 1sa8
otgs wfv0 ku6r bjth bqci
20
2g9x 1l7p 5m6q 6kpe 1sa8 cnom lrus ze6n lh1u w0vt wfv0 rl2g ql8z ku6r bqci 7kjo d873 kxon 0mho w6jz
横 ビンゴ
[[0, 1, 1, 1, 1],
[0, 1, 1, 0, 1],
[1, 0, 1, 1, 1],
[1, 1, 1, 1, 1],
[0, 1, 1, 0, 1]]

投稿2020/11/14 09:28

編集2020/11/14 09:29
tatsu99

総合スコア5438

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

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

test_user_222

2020/11/14 11:41 編集

ありがとうございます。 #縦 def bingo_col(hantei,i0,j0) (0..S-1).each do |i| #1つでも0ならNO if hantei[i][j0] = 0 return false end end #全て1の場合、YES return true end #右下がり def bingo_down(hantei,i0,j0) (0..S-1).each do |i| #1つでも0ならNO if hantei[i0][i] = 0 return false end end #全て1の場合、YES return true end #右上がり def bingo_up(hantei,i0,j0) (0..S-1).each do |j| #1つでも0ならNO if hantei[i0][S-1-j] = 0 return false end end #全て1の場合、YES return true end 縦と斜め書いてみたんですけど全部NOになってしまします。 後、Nを100 とか入力するとでないです。
tatsu99

2020/11/14 11:53

Nは1~S×Sの範囲でないと意味がないです。 必要ならそのチェックをいれてください。(そうなるとSもチェックという話になりますが) def bingo_col(hantei,i0,j0)ですが if hantei[i][j0] = 0ではなく if hantei[i][j0] == 0 です。(前の回答でそのように書いていましたが誤りです。失礼しました) ほかも、同様です。 def bingo_up(hantei,i0,j0)は以下のようにします。 def bingo_up(hantei,i0,j0) (0..S-1).each do |i| j = S-1-i #1つでも0ならNO if hantei[i][j] == 0 return false end end #全て1の場合、YES return true end
tatsu99

2020/11/14 11:56

def bingo_up(hantei,i0,j0)の訂正です。失礼しました。 def bingo_up(hantei,i0,j0) if i0+j0 != S-1 return false end (0..S-1).each do |i| j = S-1-i #1つでも0ならNO if hantei[i][j] == 0 return false end end #全て1の場合、YES return true end
test_user_222

2020/11/14 11:59

>Nは1~S×Sの範囲でないと意味がないです。 そうですよね。そもそも論でした。 ret = bingo_col(hantei,i,j) if ret == true printf("YeS\n") ctr += 1 break end ret = bingo_row(hantei,i,j) if ret == true printf("YeS\n") ctr += 1 break end ret = bingo_down(hantei,i,j) if ret == true printf("YeS\n") ctr += 1 break end ret = bingo_up(hantei,i,j) if ret == true printf("YeS\n") ctr += 1 break end こんな感じで合ってますか?
tatsu99

2020/11/14 12:03

はい。呼び出し側はあっています。 老婆心ながら デバッグ中はどの判定でYesになったかを知るために、例えばYseS1,YeS2のようにしておいた方がよいかも知れません。
test_user_222

2020/11/14 12:08

>デバッグ中はどの判定でYesになったかを知るために、例えばYseS1,YeS2のようにしておいた方がよいかも知れません つくづく自分の効率の悪さを痛感します。 def bingo_down(hantei,i0,j0) (0..S-1).each do |i| #1つでも0ならNO j = i if hantei[i0][j] == 0 return false end end #全て1の場合、YES return true end と自分で直してみたんですが右下がりそろってもNOとでてしまいます。
test_user_222

2020/11/14 12:09

|i|がJになっていないですね。分かりました!
test_user_222

2020/11/14 12:14

いけました。 def bingo_down(hantei,i0,j0) (0..S-1).each do |j| #1つでも0ならNO j == i0 if hantei[i0][j] == 0 return false end end #全て1の場合、YES return true end であってますか>
tatsu99

2020/11/14 12:19

こちらが、正解かと。 def bingo_down(hantei,i0,j0) if i0 != j0 return false end (0..S-1).each do |i| j = i #1つでも0ならNO if hantei[i][j] == 0 return false end end #全て1の場合、YES return true end i0とj0が同じ値でない場合は、右下がりの位置にいませんのでチェック不要です。
test_user_222

2020/11/14 12:26

なるほど。動作確認って手動でやってますか? pp hanteiのところに再度カードを出して当たったところに印つける場合って1とゼロのところに印をいれたらいけますか?
tatsu99

2020/11/14 12:38

>動作確認って手動でやってますか? 手動の意味が分かりませんが、コマンドプロンプトでスクリプトを実行し、表示された結果をみて確認しています。これを手動というなら、手動です。 >pp hanteiのところに再度カードを出して当たったところに印つける場合って1とゼロのところに印をいれたらいけますか? pp hannteiは、私が提示したスクリプトでは一番最後の行に書いてあります。 従って、1のところが当たったところです。 「再度カードを出して当たったところに印つける場合って」・・・この意味がよくわかりません。 もう少し、具体的に説明していただけますか。 又 pp hanteiはどの位置に埋め込む前提での話ですか?
test_user_222

2020/11/14 12:40

NO [[0, 0, 0, 0, 1], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [1, 1, 1, 0, 0], [0, 0, 0, 1, 0]] これを ☆g7rl ☆dzly ☆ki68 ☆rpqw ☆sgyi ajyv xe1q fy8z w9q5 3qh0 h8sb whgj c8ag w48x n8cg uorb h9pd i3vj 8kg1 i6p2 slh8 keip 5l2e t2me 52iu みたいにしたいです。
tatsu99

2020/11/14 12:56

まず、 word_n.each do |val|のなかの hantei[i][j] = 1 を hantei[i][j] = val に変えます。 次に bing_rowの場合は、以下のようにします。ほかも同じ考え方で変えてください。 チェックした列又は行又は斜めの範囲のマスに☆を付けることをしています。 def bingo_row(hantei,i0,j0) (0..S-1).each do |j| #1つでも0ならNO if hantei[i0][j] == 0 return false end end #全て1の場合、YES (0..S-1).each do |j| #全てに☆を付ける hantei[i0][j] = "☆" + hantei[i0][j] end return true end
tatsu99

2020/11/14 13:17

すみません。なさりたいのは 1.hanteiの内容を初期値として、word_arrと同じ内容にする 2.当たった個所の先頭に☆をつける ということでしょうか。 そうであれば、かなり、変わってしますますので、まるまる再提示します。
test_user_222

2020/11/14 13:23

1.hanteiの内容を初期値として、word_arrと同じ内容にする 2.当たった個所の先頭に☆をつける その通りでございます。 全然思いつかないです。
tatsu99

2020/11/14 13:28

新しく回答します。
guest

0

ruby

1S = gets.to_i 2# ビンゴカードの入力 3bingo_card = Array.new(S){ gets.split } 4word_list = bingo_card.flatten 5 6### 当選ワードの入力 ### 7 8N = gets.to_i 9hit_words = Array.new(N){ gets.chomp } 10 11hit_list = Array.new(S*S) 12hit_words.each do |hit| 13 if ix = word_list.find_index(hit) 14 hit_list[ix] = true 15 end 16end 17 18hit_card = hit_list.each_slice(S).to_a 19# pp hit_card # DEBUG: デバッグ用なので不要なら消す 20 21### ビンゴ判定 ### 22# 斜め判定 23naname1 = Array.new(S){|i| hit_card[i][i] }.all? 24naname2 = Array.new(S){|i| hit_card[i][-i-1] }.all? 25# 横判定 26yoko = hit_card.any?(&:all?) 27# 縦判定 28tate = hit_card.transpose.any?(&:all?) 29# 結果出力 30# puts "--------------------------------" # DEBUG: 見づらかったので罫線いれとく 31if yoko || tate || naname1 || naname2 32 puts "Yes" 33else 34 puts "No" 35end

まぁ、こんなん

投稿2020/11/14 07:18

編集2020/11/15 12:08
asm

総合スコア15147

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

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

test_user_222

2020/11/14 07:48

すごいです。。まだ全て理解してませんが印をつけて生成ってどうやるんですか?
asm

2020/11/14 09:20

印とやらの詳細がないのでなんとも言えないですね
test_user_222

2020/11/14 10:21 編集

S => S*S => N => N個表示して、 再度ビンゴカードを生成しSxSマスにある文字とN個の文字が一致していれば印を表示して YES、NO判定です! 印は☆でも○でもなんでもいいです。
asm

2020/11/14 11:29

・test1 ☆ test3 ・test1 ☆test2 test3 ・☆test2 ・☆ その説明で想起される表示は上の通り4つはあります
test_user_222

2020/11/14 11:43

左に表示さしたいですね。
asm

2020/11/14 12:08

ならばword_list[ix].prepend("☆")ですね
test_user_222

2020/11/14 12:34

display(word_list[ix])をしてみたんですけどエラーがでました。
asm

2020/11/14 12:37

display(word_list.each_slice(S).to_a)
test_user_222

2020/11/14 12:43

すごい。。感動しました。asmさんのコードまだ全然理解してないので読みます。
test_user_222

2020/11/14 12:57

これ判定ってhit_list使ってやるんですか?
asm

2020/11/14 12:59

hit_listでもhit_cardでも使いやすい方をどうぞ
asm

2020/11/15 03:34

判定まで含めて、これでいいんじゃない?程度には書いてみました。
test_user_222

2020/11/15 06:32

すごいですね。こんなコンパクトにして同じ動きとは、、
test_user_222

2020/11/15 07:08

uniq!で重複してるやつを消せるんですね。 lenの設定次第では全パターン網羅してもnumに届かない場合がありうるので対策が必要ってかいてるんですけど、どんな場合ですか?
asm

2020/11/15 07:14

numがめちゃくちゃ多くてALPHABETS.size**LENGTHよりも多い場合です たとえば、ALPHABETS=["A", "B"]でLENGTHが2の場合、5マス以上を重複なく埋めることは不可能です。
test_user_222

2020/11/15 07:17

なるほど!LENGTHをランダムにすれば解消できますか?
test_user_222

2020/11/15 07:23

naname1 = Array.new(S){|i| hit_card[i][i] }.all? naname2 = Array.new(S){|i| hit_card[i][-i-1] }.all? # 横判定 yoko = hit_card.any?(&:all?) # 縦判定 tate = hit_card.transpose.any?(&:all?) .all?どうやって判定してるんですか?
asm

2020/11/15 07:25

それも手段ではありますね。 見づらくなるなどの弊害はありますが
asm

2020/11/15 07:26

.all?は前段の配列等が全てtruthy(nil,false以外)であればtrueになります
test_user_222

2020/11/15 07:27

hit_cardはtrueかfalseに置き換えられてるんですね!
test_user_222

2020/11/15 07:29

なんでnaname2はhit_card[i][-i-1]にしないといけないんんですか?
asm

2020/11/15 07:35

別に[i][S-i-1]でもいいですよ 1***2 *1*2* **x** *2*1* 2***1
test_user_222

2020/11/15 07:54 編集

S = 5の場合のマスです。 5ril g31t 67df b4c5 lo89 3tgj w4li g6bs eyqu t58s yc2f rtej 6rqh 9q3e to34 5d1t ipah 3q7m niet yhmc frl1 9b1z kihj 6p1w 6osd 二次元配列の[1][-2]の-2ってどの値ですか?
asm

2020/11/15 07:56 編集

2行目の後ろから2番目です。 5ril g31t 67df b4c5 lo89 3tgj w4li g6bs ここ t58s yc2f rtej 6rqh 9q3e to34 5d1t ipah 3q7m niet yhmc frl1 9b1z kihj 6p1w 6osd
test_user_222

2020/11/15 07:55

マイナスでうしろからになるんですね。
test_user_222

2020/11/15 08:00

Array.new(S){|i| hit_card[i][i] }.all?で S=5のときって |i|は1~5になるんですか?
test_user_222

2020/11/15 08:07

0ですよね笑勘違いしてました。
test_user_222

2020/11/15 12:27

これでやってみたんですが、 w6jz 5m6q 7kjo cnom lh1u 1og8 w0vt 1l7p 26mc lrus 2g9x urfm ze6n 6kpe kxon ql8z rl2g d873 0mho 1sa8 otgs wfv0 ku6r bjth bqci みたいに入力できないですよね?
test_user_222

2020/11/15 12:31

普通にできました。すいません
test_user_222

2020/11/15 12:40

標準出力したマスに判定がでてから☆をつける事って無理ですよね?
test_user_222

2020/11/15 12:44

再表示しないときついですよね。
asm

2020/11/15 13:04

何が言いたいのか不明瞭ですが、おそらく無理ですね。 また、要求されたもの以外を出力すると自動テストが通らなくなりますよ
test_user_222

2020/11/15 13:16 編集

そうだと思うんですが、なぜか設問に S × S のサイズの、各マスに単語が書かれたビンゴカードがあります。上から i 行目、左から j 列目の 単語は Ai,j です。 続けて N 個の単語 w1 ,w2 ,…,wN が選ばれます。 選ばれた単語がビンゴカードの中にあった場合、ビンゴカードのその単語に印を付けます。 N 個の単語が選ばれた時点で勝利条件を満たしているか(ビンゴかどうか)、すなわち 縦・横・なな めのいずれか1列にある S マスが揃って印がついているかどうかを判定してください。 と書いてあるので、これはどう解釈しますか?
test_user_222

2020/11/15 13:17

標準出力で出さないけど、裏では印をつけてるってことですかね?
asm

2020/11/15 13:36

そうですね。 「印をつけたビンゴカードを出力しろ」などと言われていないのですから (ビンゴかどうか)の条件を明確に、「揃って印がついているかどうか」と判定させるための前提みたいなものですね。
test_user_222

2020/11/15 13:48

「印をつけたビンゴカードを出力しろ」などと言われていないのですから (ビンゴかどうか)の条件を明確に、「揃って印がついているかどうか」と判定させるための前提みたいなものですね。 > では、今のままで大丈夫ですか? 他のビンゴかどうかの条件は成功したんですけど、 Ai,j 、wi(単語) は半角英数字のみです。スペースや記号は含まれません。 の判定で、 def validate_word(word_list) if /\A\ word_list\z/ == word_list return true else puts "no1" return false end end みたいにかいたんですが、半角英数字を判定するのってどうすればいいですか?
test_user_222

2020/11/15 14:09 編集

def validate_word(word_list,hit_words) if (/\A[a-zA-Z0-9]+\z/.match?(word_list)) && (/\A[a-zA-Z0-9]+\z/.match?(hit_words)) return true else puts "no1" return false end end 後もう少しでいけそうなのですが、each doで配列を一個ずつ判定しないといけないですか?
asm

2020/11/15 14:29

それ判定する必要あるのですか?
test_user_222

2020/11/15 22:08

判定条件としてAi,j 、wi(単語) は半角英数字のみです。スペースや記号は含まれません。 とあるので、必要です。 試しに記号などを含めてもyesとででしまいます。
asm

2020/11/15 22:19

入力側の制約として公開されている条件なだけの気がします。 「その条件を満たさない場合はnoを出力しろ」と問題文に書かれていますか?
test_user_222

2020/11/15 22:32 編集

「その条件を満たさない場合はnoを出力しろ」と問題文に書かれていますか? > 条件を満たしてるならyes、そうでなければnoと出力してくださいとかいております。
asm

2020/11/15 23:17 編集

なるほど、それならば判定しましょう。 といってもビンゴ判定と大して変わりません [*word_list, *hit_words].all?{|w| w.match?(/\A[a-zA-Z0-9]+\z/) }
test_user_222

2020/11/15 22:54

all?を使って各要素を.match?で判定してるんですね! ちなみになぜ*をつける必要があるのでしょうか?
test_user_222

2020/11/15 23:06

qqq www eee aaa sss ddd zzz xxx ccc 3 qqq sss ccc no1 no7 先ほどの判定をするとyesであるはずのビンゴにもnoがでてしまいます。
asm

2020/11/15 23:06 編集

簡単に説明すると配列の前に*をつけると 配列の(一番外側の)[]を取り除けます。 [*[1,2,3], *[4]] →[1,2,3,4] a=[1,2] b=[3] [*a,*b]→[1,2,3]
test_user_222

2020/11/15 23:17 編集

一つの配列にしてるんですね! def validate_word(word_list,hit_words) if [*word_list, *hit_words].all?{|w| w.match?(/\A[a-z0-9]\z/) } return true else puts "no1" return false end end でやってるんですが、noがでてしまいます。 w.match?(/\A[a-z0-9]\z/)ここを(/\A[a-z0-9]\z/).match?(w)にしても無理でした
asm

2020/11/15 23:16

> 先ほどの判定をするとyesであるはずのビンゴにもnoがでてしまいます。 ああ、ポカってましたね。繰り返しを忘れていたようです。
test_user_222

2020/11/15 23:23

.all?ってブロックの要素に対して一つずつ判定するやつじゃないんですか?
asm

2020/11/15 23:40

いえ、正規表現の繰り返しです。 /\A[a-z0-9]\z/→/\A[a-z0-9]+\z/
test_user_222

2020/11/15 23:46

そっちも繰り返さないとだめってことですね。なるほどです。
test_user_222

2020/11/16 00:44

if array.grep(/\A[a-z0-9]\z/) == true return true else やり方変えてみたんですけど無理です。。
test_user_222

2020/11/16 00:51 編集

できました!!1!!yesでも通るようになりました!
test_user_222

2020/11/16 01:27

長い間お世話になりました。コードが簡潔で初学者にも読みやすく、目指すべきコードです。 ベストアンサーか迷ったのですが、金曜日から対応していただいたtastu99さんを選びました。本当にありがとうございました。
guest

0

ビンゴのYes/No判定とSxSマスにある文字とN個の文字が一致していれば印をつけるメソッドはどう言う風に考えますか?

1.まず、S×S個の配列を作ります。全要素は初期値は0にします。
前の回答のarrと同じ要領でhanteiをつくります。(中身は全て0)
2.N個の文字を1つずつ取り出し、以下の処理を行います。
1)arrの全要素を取り出した文字と比較し、一致した個所を特定します。
arr[i][j]が一致したとします。
2)hanntei[i][j]に1をセットします。
3)hantei[i][j]を含む位置がビンゴか否かの判定をします。
3-1)横並びの判定
iは変えずj=0からS-1迄させ、hantei[i][j]が全て1ならビンゴ
3-2)縦並びの判定
jは変えずi=0からS-1迄させ、hantei[i][j]が全て1ならビンゴ
3-3)斜め並びの判定(右下がり)
i==jなら斜めの位置にあるので以下の処理
i=0からS-1迄させ、hantei[i][j]が全て1ならビンゴ(jはiと同じ値を使用)
3-4)斜め並びの判定(右上がり)
i+j==S-1なら斜めの位置にあるので以下の処理
i=0からS-1迄させ、hantei[i][j]が全て1ならビンゴ(jはS-1-iを使用)

@word_nとword_arrはあなたのをそのまま使用してください

ruby

1def find_position(arr,s,val) 2 (0..s-1).each do |i| 3 (0..s-1).each do |j| 4 if arr[i][j] == val 5 return i,j 6 end 7 end 8 end 9 return nil,nil 10end 11 12 13# arrと同じ形式のhantei(初期値:0) 14 15hantei = Array.new(S) 16(0..S-1).each do |i| 17 ar = Array.new(S,0) 18 hantei[i] = ar 19end 20 21pp hantei 22#@word_nを作成(なかみは適当) 23@word_n = ["aaa","bbb","ccc"] 24#word_arrを作成(中身は入れてない) 25word_arr = Array.new(S) 26(0..S-1).each do |i| 27 ar = Array.new(S) 28 word_arr[i] = ar 29end 30@word_n.each do |val| 31 i,j = find_position(word_arr,S,val) 32 if i == nil 33 printf("バグのため終了\n") 34 exit 10 35 end 36 hantei[i,j] = 1 37 # 以下4つのビンゴ判定(4つのメソッドをつくったほうがよいかと思います) 38end 39 40

投稿2020/11/14 02:32

編集2020/11/14 03:37
tatsu99

総合スコア5438

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

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

test_user_222

2020/11/14 03:04

hantei = Array.new (1..S*S).each do |i| hantei2 = 0 hantei << hantei2 end (0..S*S-1).each do |i| @word_n.each do |val| val.index(word_arr[i]) end end こんな感じで少し書いたんですけですけど、arrの全要素を取り出した文字と比較し、一致した個所を特定して印をつける書き方が分かりません。ご指導お願いします。
tatsu99

2020/11/14 03:35

回答欄に追記します。 hanteiはhantei[i][j]でアクセスできる形式にします。
test_user_222

2020/11/14 04:16

hantei[i][j]としてつくることでfind_position(arr,s,val)で位置を特定してるんですね。 def bingo_row (0..S-1).each do |j| if hantei[i,j] = 1 printf("YES\n") else printf("NO\n") end end 横のメソッド書いてみたんですがどうですか?
test_user_222

2020/11/14 04:22

iには何を入れればいいのでしょうか?
tatsu99

2020/11/14 04:26

hanteiとSは共有変数(パラメータで渡さない)としても、i,jはパラメータ渡しの方が良いです。 又、YES/NOの印字は呼び出し側で行った方が良いです。 YESになるのはjが全要素1の場合です。逆に言えば、1つでも0があればNOです。 上記を踏まえて、以下のようにします。(YESならtrue、NOならfalseを返します) def bingo_row(i0,j0) (0..S-1).each do |j| #1つでも0ならNO if hantei[i0,j] = 0 return false end end #全て1の場合、YES return true end
test_user_222

2020/11/14 04:40

なるほどです。[[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]] バグのため終了が出たんですが N = gets.to_i (0..N-1).each do |i| @word_n = word_arr.shuffle[i] puts @word_n end これの書き方がだめなんですか?
test_user_222

2020/11/14 04:47

けどword_n新規作成してるから関係ないですかね。
tatsu99

2020/11/14 05:02

word_arrはword_arr[i][j]でアクセスできる形式のはずです。 word_arr.shuffle[i]自体がおかしい。word_arr[i].shuffleなら構文てきにはOK たぶん、word_arrからランダムな要素を1つ取り出したいのかと思いますが、 shuffleは配列全体を返します。したがって、shuffleは使用すべきではありません。 また、@word_nは配列なので @word_n << ランダムな1要素 か @word_n[i] = ランダムな1要素 のどちらかと思います。 ところで、word_nではなく@word_nにしたのは何か理由があるのでしょうか?
test_user_222

2020/11/14 05:11

最初putsを外に出していたのでword_nだとundefineって言われたのでインスタンスにすればいけると思い@をつけたのですが必要ありませんね。 word_arr[i].shuffleにするとエラーがでて、word_arr.shuffle[i]にすると取得できました。 ランダム要素は.sampleですか?
test_user_222

2020/11/14 05:13

word_n = word_arr[i].sampleと書くと undefined method `sample' for "k7ry":String (NoMethodError)このエラーが出ます。
tatsu99

2020/11/14 05:21

>ランダム要素は.sampleですか? はい、sampleが良いかと思います。 word_arrが配列の配列なので、まず1次元配列に直します。 word_arr_flat = word_arr.flatten word_n = word_arr_flat.sample(N) でN個のランダムな要素がword_nに格納されます。
test_user_222

2020/11/14 05:38

N = gets.to_i word_arr_flat = word_arr.flatten word_n = word_arr_flat.sample(N) puts word_n に書き換えたんですがやはり [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]] バグのため終了になってしまします。
tatsu99

2020/11/14 05:44

そもそも、word_arrが全て0のようにみえます。 pp word_arr でword_arrの中身はどうなっているか確認してください。
test_user_222

2020/11/14 05:47

[[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]] [[nil, nil, nil, nil], [nil, nil, nil, nil], [nil, nil, nil, nil], [nil, nil, nil, nil]] になってます。Sは4です。
tatsu99

2020/11/14 05:50

word_arrの作り方がだめです。 どうやってつくったのですか?
test_user_222

2020/11/14 05:53

word_arr = Array.new(S) (0..S-1).each do |i| ar = Array.new(S) word_arr[i] = ar end pp word_arr
tatsu99

2020/11/14 06:01

わたしが、そのように書いたのは、つぎのステップ(find_position)のためです。 実際にはあなたがすでに文字列をいれているものを作成済みと思ったので、そのように書きました。 ここに文字列をいれないといけませんが、あなたは、どのような文字列を入れたいのでしょうか。 test1,test2。。。等 abc0,xy09,等がいままでの候補で考えられますが。
test_user_222

2020/11/14 06:04

abc0,xy09,等です。文字列は S = gets.to_i word_arr = Array.new data = [*'a'..'z', *'0'..'9'] (1..S*S).each do |i| word = data.sample(4).join word_arr << word end (0..S*S-1).each do |i| printf("%s ",word_arr[i]) if (i+1)%S == 0 printf("\n") end end でさくせいしております。
test_user_222

2020/11/14 06:04

Array.newに(S)が抜けてるんですかね。
tatsu99

2020/11/14 06:12

それだと1次元配列ですね。 S = gets.to_i word_arr = Array.new(S) data = [*'a'..'z', *'0'..'9'] (0..S).each do |i| ar = Array.new(S) (0..S-1).each do |j| word = data.sample(4).join ar[j] = word end word_arr[i] = ar end pp word_arr にしてください。
test_user_222

2020/11/14 06:18

いま出力して気づきました!(0..S).each do |i|ここもS-1ですよね
asm

2020/11/14 06:20

> ar = Array.new(S) > (0..S-1).each do |j| > ar[j] = word > end Array.newにブロック渡した方が意味が明確ですしパフォーマンス的にもよいです
tatsu99

2020/11/14 06:43 編集

>いま出力して気づきました!(0..S).each do |i|ここもS-1ですよね 失礼しました。S-1です。
test_user_222

2020/11/14 06:27

配列ででてしまうので(0..S*S-1).each do |i| puts word_arr[i].join(' ') if (i+1)%S == 0 printf("\n") end end を試したんですが undefined method `join' for nil:NilClass (NoMethodError)がでてしましまいます。
test_user_222

2020/11/14 06:28

puts word_arr[i].join(' ')を試しました
tatsu99

2020/11/14 06:31

>Array.newにブロック渡した方が意味が明確ですしパフォーマンス的にもよいです ar = Array.new(S){data.sample(4).join} word_arr[i] = ar このほうがシンプルですね。ご指摘ありがとうございました。
tatsu99

2020/11/14 06:34

pp word_arrではだめなんでしょうか。 どうしてもprintfでword_arrの内容を表示したいのでしょうか。
test_user_222

2020/11/14 06:37

そうですね。SxSのマスを表示させたいので配列だとだめですね。
tatsu99

2020/11/14 06:38

(0..S-1).each do |i| (0..S-1).each do |j| printf("%s ",word_arr[i][j]) end printf("\n") end どうしてもprintfで表示したいなら上のようにしてください。
test_user_222

2020/11/14 06:43

S = 4をいれると右に13個でて下に3個でます n896 jmzn jg2l r438 7mfp w06x yg03 5m2s e7sh lfhv k38j 5mfr 28aj m5fq 1ejo wh2u
test_user_222

2020/11/14 06:51

puts word_arr[i].join(" ")でいけました!
tatsu99

2020/11/14 06:52

S = gets.to_i word_arr = Array.new(S) data = [*'a'..'z', *'0'..'9'] (0..S-1).each do |i| ar = Array.new(S){data.sample(4).join} word_arr[i] = ar end pp word_arr (0..S-1).each do |i| (0..S-1).each do |j| printf("%s ",word_arr[i][j]) end printf("\n") end 実行結果 4 5be9 6sgo vag9 598b jia1 fn19 ynzc nc1s qjbz y5pl cgfw gbx2 vpwk u6zv cn4t ey7k でこちらは想定通りです。
test_user_222

2020/11/14 06:52

しかし、 [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]] バグのため終了 と出ます
test_user_222

2020/11/14 06:55

pp word_arrが抜けてました。しかし、[[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]] バグのため終了とでてしまいます。
tatsu99

2020/11/14 06:56

bingo_rowを呼び出す前に word_arrの内容を pp word_arrで確認してください。 どこかで、せっかく作ったものを壊しているかも知れません。
test_user_222

2020/11/14 06:58

bingo_rowを呼び出す前の word_n.each do |val| i,j = find_position(word_arr,S,val) if i == nil printf("バグのため終了\n") exit 10 end hantei[i,j] = 1 # 以下4つのビンゴ判定(4つのメソッドをつくったほうがよいかと思います) end でエラーがでています。
tatsu99

2020/11/14 06:59

なんというエラーですか。どの行ですか。
test_user_222

2020/11/14 07:03

word_arr = Array.new(S) (0..S-1).each do |i| ar = Array.new(S) word_arr[i] = ar end pp word_arr すいませんエラーではないです。バグのため終了がでてしますと言うことです。 ちなみに上記のところでppをすると [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]] [[nil, nil, nil, nil], [nil, nil, nil, nil], [nil, nil, nil, nil], [nil, nil, nil, nil]]がでました
test_user_222

2020/11/14 07:04

ここで全部0の配列がつくれていないと言うことでしょうか?
tatsu99

2020/11/14 07:08

pp word_arrですよね。 pp hanteiではないですね。 word_arrは以下のようにして作ってくださいとかきましたが、そのようにしてないように思われます。 S = gets.to_i word_arr = Array.new(S) data = [*'a'..'z', *'0'..'9'] (0..S-1).each do |i| ar = Array.new(S) (0..S-1).each do |j| word = data.sample(4).join ar[j] = word end word_arr[i] = ar end
tatsu99

2020/11/14 07:09

これから外出します。戻りは18時過ぎになる予定です。それまで、返信できません。 ご了承ください。
test_user_222

2020/11/14 07:17

pp word_arrです。コピペしても変わらなかったです。 ご迷惑をおかけして申し訳ございません。 自力で頑張ってみます。
test_user_222

2020/11/14 07:28

勘違いしてました 一個目のword_arrと二個目のword_arrの命名が同じだったので呼ばれてませんでした。 しかし、バグのため終了とでてしまいます。
guest

0

最初にSの値を入力し、そのますにtest1から順に数字を入れるサンプルです。
参考になれば幸いです。

Ruby

1S = gets.to_i 2arr = Array.new(S) 3test_no = 0 4(0..S-1).each do |i| 5 ar = Array.new(S) 6 (0..S-1).each do |j| 7 test_no += 1 8 ar[j] = "test" + test_no.to_s 9 end 10 arr[i] = ar 11end 12 13p arr #全体を表示 14 15#個別に表示 16(0..S-1).each do |i| 17 (0..S-1).each do |j| 18 printf("%s ",arr[i][j]) 19 end 20 printf("\n") 21end 22

実行結果(S=6の場合)
6
[["test1", "test2", "test3", "test4", "test5", "test6"], ["test7", "test8", "test9", "test10", "test11", "test12"], ["test13", "test14", "test15", "test16", "test17", "test18"], ["test19", "test20", "test21", "test22", "test23", "test24"], ["test25", "test26", "test27", "test28", "test29", "test30"], ["test31", "test32", "test33", "test34", "test35", "test36"]]
test1 test2 test3 test4 test5 test6
test7 test8 test9 test10 test11 test12
test13 test14 test15 test16 test17 test18
test19 test20 test21 test22 test23 test24
test25 test26 test27 test28 test29 test30
test31 test32 test33 test34 test35 test36

投稿2020/11/13 08:11

tatsu99

総合スコア5438

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

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

test_user_222

2020/11/13 08:55

ありがとうございます。test_no = 0を定義しておくことで(0..S-1).each do |j| test_no += 1の度に数字が増えていくってことですね。 Sが4であった場合まず|i|に0,1,2,3の順で入力されて|i|一回につき|j|も4回実施されるから4x4で四個の配列の中に四個配列が入ってる二次元配列になっていて、個別表示のところで、Sが4であった場合arr[i][j]にiが0のときarr[0]でarrの0を呼んでarr[0]に格納されてる四個のarを呼んでるってことで合ってますか? 行を区切ってるのはprintf("\n")で実装してるのでしょうか?
tatsu99

2020/11/13 09:21

はい。あってます。
test_user_222

2020/11/13 09:37

これって(0..S-1)を(1..S)じゃだめなんですか?
tatsu99

2020/11/13 09:41

それだと、arr[0]を使わない方法になりますね。 arr = Array.new(S+1)とすると arr[0]からarr[S]までの配列になります。 arr = Array.new(S)とすると arr[0]からarr[S-1]までの配列になります。
test_user_222

2020/11/13 10:13 編集

なるほどです。 apple orange cola bath web cloud sql http https みたいに文字で出す場合ってどうしたらいいですか?
test_user_222

2020/11/13 10:14

考え方としては、arに一個ずつ違う文字を格納すればいけると思うんですが
tatsu99

2020/11/13 10:52

data = ["apple","orange","cola",....] のようにdataを作っておいて、data[0],data[1]....の順に格納していけば良いかと。 但し、S×S個の単語を予め作っておく必要があります。
test_user_222

2020/11/13 13:35 編集

S×S個のランダム文字列作るってなると data = [*'a'..'z', *'0'..'9'] word = data.sample(引数).join みたいなのしか思い浮かばなかったんですが、どうすればS×S個作れますか?
tatsu99

2020/11/13 15:14

word = data.sample(引数).join をS×S回繰り返せばよいと思いますが。 S = gets.to_i word_arr = Array.new data = [*'a'..'z', *'0'..'9'] (1..S*S).each do |i| word = data.sample(4).join word_arr << word end p word_arr 4文字のランダム文字列をS*S回作る場合です。
asm

2020/11/13 22:36

> p arr #全体を表示 pよりもppの方がこの場合見やすいかと思いますよ
test_user_222

2020/11/13 23:33

(0..S*S).each do |i| printf("%s ",word_arr[i]) printf("\n") end でSが4のとき文字は16文字でるんですけど縦に並んでしまいます。SxSマスにするにはどうすればいいですか?
tatsu99

2020/11/13 23:34

たしかにppのほうが見やすいですね。ご指摘ありがとうございました。
tatsu99

2020/11/13 23:42

以下のようにしてください。S個打つごとに改行を入れます。 (0..S*S-1).each do |i| printf("%s ",word_arr[i]) if (i+1)%S == 0 printf("\n") end end
test_user_222

2020/11/13 23:54

if (i+1)%S == 0でS個文字が出る度改行するんですね!すごいです。こんなのどうやって思いつくんですか。尊敬です。全然思いつかない
tatsu99

2020/11/14 00:03

S個打つごとに改行する・・・ということは思いつくかと。 そうすれば、すなおに書くと、以下のようになります。 これが、かければそれで良いと思います。 ctr = 0 (0..S*S-1).each do |i| printf("%s ",word_arr[i]) ctr += 1 if ctr%S == 0 printf("\n") end end
test_user_222

2020/11/14 00:33

なるほどです。ビンゴのYes/No判定とSxSマスにある文字とN個の文字が一致していれば印をつけるメソッドはどう言う風に考えますか?
tatsu99

2020/11/14 02:32

別記に回答しました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問