This question already has an answer here:
replacing an element in nested array ruby
(1 answer)
Closed 7 years ago.
Hello I have my following bingo code that marks X for numbers that get returned:
class BingoBoard
def initialize(board)
#bingo_board = board
end
def number_letter
#letter = ['B','I','N','G','O'].sample
#number = rand(1..100)
end
def checker
number_letter
#bingo_board.map! do |n|
if n.include?(#number) #cleaned up code from the initial solution.
n.map! { |x| x == #number ? 'X' : x}
else
n
end
end
end
end
My question is how do I change my code so that when I'm using the test code:
board = [[47, 44, 71, 8, 88],
[22, 69, 75, 65, 73],
[83, 85, 97, 89, 57],
[25, 31, 96, 68, 51],
[75, 70, 54, 80, 83]]
new_game = BingoBoard.new(board)
new_game.checker
It will appear neatly like a bingo board in irb.
Right now it looks like:
=>[[47, 44, 71, 8, 88], [22, 69, 75, 65, 73], ["X", 85, 97, 89, 57], [25, 31, 96, 68, 51], [75, 70, 54, 80, "X"]]
Append .map { |block| puts block.inspect } to the new_game.checker call.
Related
I am trying to generate a list of prime nos b/w 1-100 in ruby. I have initally done this through an iterative method which works well.
require 'prime'
def Primenos(n)
Prime.prime?(n)
end
def f1
(1..100).collect do |e|
if Primenos(e)
then p "this is prime - #{e}"
end
end
end
f1
But I would also like to know if this could be done recursively ? Any idea?
Other option:
require 'prime'
def primes_smaller_than(num, res=[])
return res if num < 2
res << num if Prime.prime?(num)
primes_smaller_than(num - 1, res)
end
primes_smaller_than 100
#=> [97, 89, 83, 79, 73, 71, 67, 61, 59, 53, 47, 43, 41, 37, 31, 29, 23, 19, 17, 13, 11, 7, 5, 3, 2]
To print it out:
primes_smaller_than(100).each { |e| puts "this is prime - #{e}" }
(Also open to other similar non-Rails methods)
Given (0..99), return entries that are randomly picked in-order.
Example results:
0, 5, 11, 13, 34..
3, 12, 45, 67, 87
0, 1, 2, 3, 4, 5.. (very unlikely, of course)
Current thought:
(0..99).step(rand(0..99)).each do |subindex|
array.push(subindex)
end
However, this sets a single random value for all the steps whereas I'm looking for each step to be random.
Get a random value for the number of elements to pick, randomly get this number of elements, sort.
(0..99).to_a.sample((0..99).to_a.sample).sort
#⇒ [7, 20, 22, 29, 45, 48, 57, 61, 62, 76, 80, 82]
Or, shorter (credits to #Stefan):
(0..99).to_a.sample(rand(0..99)).sort
#⇒ [7, 20, 22, 29, 45, 48, 57, 61, 62, 76, 80, 82]
Or, in more functional manner:
λ = (0..99).to_a.method(:sample)
λ.(λ.()).sort
To feed exactly N numbers:
N = 10
(0..99).to_a.sample(N).sort
#⇒ [1, 5, 8, 12, 45, 54, 60, 65, 71, 91]
There're many ways to achieve it.
For example here's slow yet simple one:
# given `array`
random_indexes = (0...array.size).to_a.sample(rand(array.size))
random_indexes.sort.each { |i| puts array[i] }
Or why don't you just:
array.each do |value|
next if rand(2).zero?
puts value
end
Or you could use Enumerator#next random number of times.
Below example returns a sorted array with random entries from given range based on randomly picked true or false from array [true, false]:
(0..99).select { [true, false].sample }
=> [0, 3, 12, 13, 14, 17, 20, 24, 26, 28, 30, 32, 34, 35, 36, 38, 39, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 53, 54, 55, 56, 58, 59, 60, 61, 62, 65, 67, 69, 70, 71, 79, 81, 84, 86, 91, 93, 94, 95, 98, 99]
To reduce the chances of a bigger array being returned, you can modify your true/false array to include more falsey values:
(0..99).select { ([true] + [false] * 9).sample }
=> [21, 22, 28, 33, 37, 58, 59, 63, 77, 85, 86]
I'm trying to see if an index, say index 3, all has the same character. For example:
nested_array = [[47, 44, 71, 'x', 88],
[22, 69, 75, 'x', 73],
[83, 85, 97, 'x', 57],
[25, 31, 96, 'x', 51],
[75, 70, 54, 'x', 83]]
As we can see, index 3 has all x'x in it instead of numbers. I want to be able to verify if ALL of the indexes have an x, if so, program returns true. If all but 1 have x's it would return false.
I have now implemented this conditional statement as it iterates through each index looking for a value the size equal to 1. This seemed to do the trick.
if array.map {|zero| zero[0]}.uniq.size == 1
return true
elsif array.map {|one| one[1]}.uniq.size == 1
return true
elsif array.map {|two| two[2]}.uniq.size == 1
return true
elsif array.map {|three| three[3]}.uniq.size == 1
return true
elsif array.map {|four| four[4]}.uniq.size == 1
return true
else
return false
end
nested_array.empty? || nested_array.map {|row| row[3]}.uniq.one?
The special condition for empty arrays is necessary because they trivially fulfill any condition that is specified for each element, but the uniqueness test would not pick it up. Feel free to drop it if you will not in fact have an empty array, or the test should fail if the array is empty.
EDIT: Seems I misunderstood the question - try this as an alternative to your multi-if:
nested_array.transpose.any? { |column| column.uniq.one? }
"When you flip rows and columns, does any of the rows (that used to be columns) have only one unique element?"
(if you want true for [], again, prefix with nested_array.empty? || ...).
EDIT: Thanks to spickermann, replaced .size == 1 with .one?. It really does read better.
You did not specify that all elements of nested_array are necessarily of the same size, so I will offer a solution does not have that as a requirement:
nested_array = [[47, 44, 71, 'x', 88],
[75, 70, 54, 'x', 83, 85, 90],
[22, 69, 75, 'x', 73],
[83, 85, 97, 'x', 57],
[25, 31, 96, 'x', 51, 33]]
nested_array.first.zip(*nested_array[1..-1]).any? {|row| row.uniq.size==1}
#=> true
We have:
b = nested_array.first.zip(*nested_array[1..-1])
#=> [[47, 75, 22, 83, 25],
# [44, 70, 69, 85, 31],
# [71, 54, 75, 97, 96],
# ["x", "x", "x", "x", "x"],
# [88, 83, 73, 57, 51]]
b.any? { |row| row.uniq.size == 1 }
#=> true
Initally, I had:
nested_array.first.zip(*nested_array[1..-1]).any? {|row|
row[1..-1].all? { |e| e == row.first } }
rather than { |row| row.uniq.size==1 }. As #Amadan points out, the former should be a bit faster.
If the question is whether a specific element of b contains all the same values:
index = 3
a = nested_array.first.zip(*nested_array[1..-1])
(index >= a.size) ? false : a[index].uniq.size==1
#=> true
I'm blanking big time on this one. This is all i've got. Help all mighty Overflow gods!
ages = [23, 101, 7, 104, 11, 94, 100, 121, 101, 70, 44]
under_100 = Proc.new { |x| x < 100 }
Do as below
ages = [23, 101, 7, 104, 11, 94, 100, 121, 101, 70, 44]
under_100 = Proc.new { |x| x < 100 }
ages.select(&under_100) # => [23, 7, 11, 94, 70, 44]
ages.select { |x| x < 100 } # I would do this way or
ages.select(&100.method(:>)) # this way.
100.method(:>) created Method object(check this Object#method), same as the one you created as Proc.new { |x| x < 100 }. Now applying & to that proc/method object converting it to a block with #select method.
ages = [23, 101, 7, 104, 11, 94, 100, 121, 101, 70, 44]
under_100 = Proc.new { |x| x < 100 }
p under_100.call(201) #=> false
p under_100.call(23) #=> true
Map runs the proc on each element and returns the result:
p ages.map(&under_100) #=> [true, false, true, false, true, true, false, false, false, true, true]
Select goes through all elements and only returns the ones that evaluates to true:
p ages.select(&under_100) #=> [23, 7, 11, 94, 70, 44]
It could also be written like this:
result = []
ages.each{|age| result.push(age) if under_100.call(age)}
p result #=> [23, 7, 11, 94, 70, 44]
So that is why you do not need to use any if when using the select method of the Array.
without proc we can check it as
ages = [23, 101, 7, 104, 11, 94, 100, 121, 101, 70, 44]
ages.each do |x|
if x < 100;
puts "#{x} is less than 100";
end
end
Is there any cool way in Ruby to create an array with 1 to 100 with only odd entries (1, 3 etc). I now have a loop for this but that is obviously not a cool way to do it! Any suggestions?
My current code:
def create_1_to_100_odd_array
array = [1]
i = 3
while i < 100
array.push i
i += 2
end
array
end
Thanks in advance
The Range class comes with a very cool feature for that purpose:
1.9.3-p286 :005 > (1..10).step(2).to_a
=> [1, 3, 5, 7, 9]
May not be efficient, but a short piece of code:
(1..100).select(&:odd?)
# => [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41, 43, 45, 47, 49, 51, 53, 55, 57, 59, 61, 63, 65, 67, 69, 71, 73, 75, 77, 79, 81, 83, 85, 87, 89, 91, 93, 95, 97, 99]
Just toying...
(0...50).map(&:object_id)
#or
1.step(100,2).to_a
Since you need a function, then:
def odd_to(n)
(1..n).step(2).to_a
end
Not very effective solution, but quite elegant:
(1..100).select {|a| a%2 != 0}
You can do it as a one-liner when you instantiate the array:
def create_array_of_odds_to(n)
Array.new((n + 1) / 2) {|i| 2 * i + 1}
end
create_array_of_odds_to 10 # => [1, 3, 5, 7, 9]