Home>

### i'm having trouble with ruby's word bingo algorithm

I am creating a word bingo in Ruby.
When S is input, SxS mass is output, and when N is input next,
N characters are displayed, and if it is bingo in the SxS square, it is judged by Yes.No.
If the letters in the SxS square and the N letters match, you have to put out a mark.
For example, if S = 3, the card mass is
test1 test2 test3
test4 test5 test6
test7 test8 test9
Is output,
Next, the number of times to open the square is set to N, and N card squares are output.
Example, N = 5
test1
test5
test8
test9
test6

I want to create a program that displays "Yes" if there is a bingo, and "No" if it does not.

The problem i am having
``````S = gets.to_i
nums = S * S # 1 ~ S x S
row = Array.new (S) .map {Array.new (S, 0)} #horizontal
col = Array.new (S) .map {Array.new (S, 0)} #vertical``````

I'm a beginner and can't think of an algorithm in the first place.
I don't even know what kind of code to write.

https://www.tutorialfor.com/go.php?id=298325To
I couldn't understand it even if I saw it.

First of all, I think what you should do is clarify the input and output.

It's not clear from this problem statement
Probably the illustrated input

``````3
test1 test2 test3
test4 test5 test6
test7 test8 test9
Five
test1
test5
test8
test9
test6``````

Is not it

Next, in the first half

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

From

``````S = 3
Bingo card = [
["test1", "test2", "test3"],
["test4", ...]
...
]``````

Create the data.

As a method,`gets`In one line (`test1 test2 test3`) I think it's easy to input and split with String # split.

Then, for the latter half of the input, search from the bingo card

The relevant part`nil`Replace with

Prepare a separate bingo card for judgment and fill it out

You can use either method you like.

Finally, the bingo judgment is performed.
Vertical (S), horizontal (S), diagonal (2) total`S + S + 2`Judgment is made for the pattern of
Output the result

It is a script that creates word_arr and word_n when a word is input from the screen (standard input).
It is difficult to enter a word every time, so you can easily test by doing the following.
First, create the data to be input in advance and save it as a text file. (As data.txt)
If the script is sample.rb, at the command prompt
ruby sample.rb If you enter, you will get the same result as typing the contents written in data.txt from the standard input.

``````S = gets.to_i
word_arr = Array.new
(0..S-1) .each do | i |
arr = gets.chomp.split (nil)
word_arr<</pre>
<p>Below is the execution result. (The script is goo1.rb)<br />
D: \ goo \ ruby>ruby ​​goo1.rb<data.txt<br />
[["apple1", "egg1", "word1", "http1"],
<br />
["apple2", "egg2", "word2", "http2"],
<br />
["apple3", "egg3", "word3", "http3"],
<br />["apple4", "egg4", "word4", "http4"]]<br />
["apple1", "apple2", "apple3", "apple4", "egg1", "word1", "http1"]</p>
<p>Contents of data.txt<br />
D: \ goo \ ruby>type data.txt<br />
Four<br />
apple1 egg1 word1 http1<br />
apple2 egg2 word2 http2<br />
apple3 egg3 word3 http3<br />
apple4 egg4 word4 http4<br />
7<br />
apple1<br />
apple2<br />
apple3<br />
apple4<br />
egg1<br />
word1<br />
http1</p>

``````
``` ```
• ``` ```
• ``` Answer # 3 ```
``` ```

```<p>This is a sample in which the value of S is entered first, and then the numbers are entered in order from test1.<br /> I'm glad if you can use it as a reference.</p> <pre><code data-language = "Ruby">S = gets.to_i arr = Array.new (S) test_no = 0 (0..S-1) .each do | i | ar = Array.new (S) (0..S-1) .each do | j | test_no + = 1 ar [j] = "test" + test_no.to_s end arr [i] = ar end p arr # show whole #Display individually (0..S-1) .each do | i | (0..S-1) .each do | j | printf ("% s", arr [i] [j]) end printf ("\ n") end```

Execution result (when 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

>How do you think of the method of marking if the Yes/No judgment of bingo and the characters in the SxS square match N characters?
1. 1. First, create an array of S x S. The initial value of all elements is 0.
Create hantei in the same way as arr in the previous answer. (All contents are 0)
2. Extract N characters one by one and perform the following processing.
1) Compare all the elements of arr with the extracted characters and identify the matching part.
Suppose arr [i] [j] match.
2) Set 1 to hanntei [i] [j].
3) Judge whether the position including hantei [i] [j] is bingo.
3-1) Side-by-side judgment
Do not change i, let j = 0 to S-1, and if hantei [i] [j] are all 1, bingo
3-2) Judgment of vertical alignment
Do not change j, let i = 0 to S-1, and if hantei [i] [j] are all 1, bingo
3-3) Judgment of diagonal alignment (downward to the right)
If i == j, it is in an oblique position, so the following processing
Let i = 0 to S-1, and if hantei [i] [j] are all 1, bingo (j uses the same value as i)
3-4) Judgment of diagonal alignment (upward to the right)
If i + j == S-1, it is in an oblique position, so the following processing
Let i = 0 to S-1, and if hantei [i] [j] are all 1, bingo (j uses S-1-i)

@word_n and word_arr just use yours

``````def find_position (arr, s, val)
(0..s-1) .each do | i |
(0..s-1) .each do | j |
if arr [i] [j] == val
return i, j
end
end
end
return nil, nil
end
Hantei in the same format as # arr (initial value: 0)
hantei = Array.new (S)
(0..S-1) .each do | i |
ar = Array.new (S, 0)
hantei [i] = ar
end
pp hantei
Create # @ word_n (appropriate inside)
@word_n = ["aaa", "bbb", "ccc"]
Create #word_arr (without contents)
word_arr = Array.new (S)
(0..S-1) .each do | i |
ar = Array.new (S)
word_arr [i] = ar
end
@ word_n.each do | val |
i, j = find_position (word_arr, S, val)
if i == nil
printf ("Exit due to bug \ n")
exit 10
end
hantei [i, j] = 1
# The following 4 bingo judgments (I think it is better to create 4 methods)
end``````

``````S = gets.to_i
# Bingo card input
bingo_card = Array.new (S) {gets.split}
word_list = bingo_card.flatten
### Enter the winning word ###
N = gets.to_i
hit_words = Array.new (N) {gets.chomp}
hit_list = Array.new (S * S)
hit_words.each do | hit |
if ix = word_list.find_index (hit)
hit_list [ix] = true
end
end
hit_card = hit_list.each_slice (S) .to_a
# pp hit_card # DEBUG: For debugging, delete it if unnecessary
### Bingo Judgment ###
# Diagonal judgment
naname1 = Array.new (S) {| i | hit_card [i] [i]} .all?
naname2 = Array.new (S) {| i | hit_card [i] [-i-1]} .all?
# Horizontal judgment
yoko = hit_card.any? (&: all?)
# Vertical judgment
tate = hit_card.transpose.any? (&: all?)
#Result output
#puts "--------------------------------" # DEBUG: It was hard to see, so put a ruled line
if yoko || tate || naname1 || naname2
puts "Yes"
else else
puts "No"
end``````

Well, like this