I'm trying to print a single element from an array of 500 numbers. I initialized it using
arr = (1..500)
I can print from for loops:
for n in arr
print n +"\n"
end
I can print using arr.each, but if I try to just grab one element I get an error.
print arr[0]
>undefined method `[]' for 1..500:Range (NoMethodError)
If I initialize an array arr2 = ["a", "b", "c"] and try to grab a single element that way it works fine.
I am assuming it is because of the way I initialized it (using the range) but eveywhere I look they say that is how you should initialize an array of numbers.
Is there any way for me to get a single element from my array?
That's not a Array, it's a Range. You can convert it to an Array using to_a:
range = 0..500
arr = range.to_a
puts arr[7] # => 6
Here is how to do it without converting the whole thing into array.
class Range
def index(n)
return nil unless n < self.size
self.each_with_index { |x, i| return x if i == n }
end
end
range = 0..100000000000
range.index(120) # => 120
Related
My input is:
aaabbbb
I have written the following code:
here = string.split(//)
count = Hash.new(0)
there = here.each {|a|
count[a] += 1
}
This gives me the following output:
{"a"=>3, "b"=>4}
Now, I want to check the number of odd values in my hash for example if my output had been:
{"a"=>3, "b"=>4, "c"=>3}
Then the answer should be:
2
Note: I am doing this to check if aaabbbb can form an anagram which could be a palindrome. So if there are more than 2 characters with odd value then it would not form a palindrome and vice-versa.
Just use count method.
count.count{|k,v| v.odd?}
You can use Hash#values to get an array of values. Then count the number of odd elements in it:
res = {"a"=>3, "b"=>4, "c"=>3}
res.values.count(&:odd?)
#=> 2
You can do that by using iterating over each_value of count and then select and then check the length
count.each_value.select { |n| n.odd? }.length
When creating a method to find the mode of an array, I see people iterating over the array through a hash with default value 0:
def mode(array)
hash = Hash.new(0)
array.each do |i|
hash[i]+=1
end
end
or
freq = arr.inject(Hash.new(0)) { |h,v| h[v] += 1; h }
Can someone explain the following part of the block?
hash[i] = hash[i] + 1 or h[v] = h[v] + 1
How does the iterator know to add +1 to each unique key of the hash? For example:
array = [1,1,1,2,3]
freq = arr.inject(Hash.new(0)) { |h,v| h[v] += 1; h }
#=> {1:3, 2:1, 3:1}
If someone can explain how to find the mode of an array, I would be grateful.
In you first example, you need the method to return the hash that is created, or do some manipulation of the hash to compute the mode. Let's try it, just returning the hash (so I've added hash as the last line):
def hash_for_mode(array)
hash = Hash.new(0)
array.each do |i|
hash[i]+=1
end
hash
end
array = [1,3,1,4,3]
hash_for_mode(array) #=> {1=>2, 3=>2, 4=>1}
With hash_for_mode you can easily compute the mode.
By defining the hash h = Hash.new(0), we are telling Ruby that the default value is zero. By that, we mean that if a calculation is performed that depends on h[k] when k is not a key of h, h[k] will be set equal to the default value.
Consider, for example, when the first value of array (1 in my example) is passed into the block and assigned to the block variable i. hash does not have a key 1. (It has no keys yet.) hash[1] += 1 is shorthand for hash[1] = hash[1] + 1, so Ruby will replace hash[1] on the right side of the equality with the default value, zero, resulting in hash[1] => 1.
When the third value of array (another 1) is passed into the block, hash[1] already exists (and equals 1) so we just add one to give it a new value 2.
In case you were wondering, if we have:
hash = Hash.new(0)
hash[1] += 1
hash #=> {1=>1}
puts hash[2] #=> nil
hash #=> {1=>1}
That is, merely referencing a key that is not in the hash (here puts hash[2]), does not add a key-value pair to the hash.
Another common way to do the same thing is:
def hash_for_mode(array)
array.each_with_object({}) { |i,hash| hash[i] = (hash[i] || 0) + 1 }
end
hash_for_mode(array) #=> {1=>2, 3=>2, 4=>1}
This relies on the fact that:
(hash[i] || 0) #=> hash[i] if hash already has a key i
(hash[i] || 0) #=> 0 if hash does not have a key i, so hash[k]=>nil
(This requires that your hash does not contain any pairs k=>nil.)
Also, notice that rather than having the first statement:
hash = {}
and the last statement:
hash
I've used the method Enumerable#each_with_object, which returns the value of the hash. This is preferred here to using Enumerable#inject (a.k.a reduce) because you don't need to return hash to the iterator (no ; h needed).
array = [1,3,1,4,3]
array.group_by(&:itself).transform_values(&:count)
# => {1=>2, 3=>2, 4=>1}
Say I have an array that looks like:
a = [cat, dog, cat, mouse, rat, dog, cat]
How do I cycle through that, and do something with duplicates - e.g. say delete them?
In other words, if I did a.each do |i|, how do I evaluate a[0], against a[1], a[2], a[3]...and then when I find the one I want, say a[2] in this case has the first duplicate, I then push it to a stack or remove it or something.
I know how to evaluate keys, versus values...but how do I evaluate values against each other within the same array?
Thanks.
You can create a hash to store number of times any element is repeated. Thus iterating over array just once.
h = Hash.new(0)
['a','b','b','c'].each{ |e| h[e] += 1 }
Should result
{"a"=>1, "b"=>2, "c"=>1}
This works efficiently and is rather simple:
require 'set'
visited = Set.new
array.each do |element|
if visited.include?(element)
# duplicated item
else
# first appearance
visited << element
end
end
Try this:
class Array
def find_dups
uniq.map {|v| (self - [v]).size < (self.size - 1) ? v : nil}.compact
end
end
a = ['cat', 'dog', 'cat', 'mouse', 'rat', 'dog', 'cat']
print a - a.find_dups # Removes duplicates
find_dups will return elements that have duplicates
Try this:
array.inject({}){|h, e| h[e] = h[e].to_i + 1; h}
Use
a.uniq! to remove duplicates .
also checkout the ruby-doc.org where you can find more info on ruby's class methods .
A simple solution is to run a double loop:
a.each_with_index do |a1, idx1|
a.each_with_index do |a2, idx2|
next if idx1 >= idx2 # Don't compare element to itself
# and don't repeat comparisons already made
# do something with a pair of elements (a1, a2)
end
end
If you just want to eliminate duplicates, there's a method: Array#uniq.
This will print all the duplicates in an array:
array.inject(Hash.new(0)) { |hash,val|
hash[val] += 1;
hash
}.each_pair { |val,count|
puts "#{val} -> #{count}" if count > 1
}
The best way to do it is to compare it with a unique version of itself. If its the same then it has no duplicates, if not then duplicates exist.
unique_array = original_array.uniq
get a unique version of your array
if original_array == unique_array then return true else return false
compare it to your original array.
Simple!
If you just want to get rid of duplicates, the easiest thing to do is take the array and do array&array. Use the & operator.
If you want to know what those repeats are, just compare array to array&array.
If array is sortable, then something like below will return only the duplicates.
array.sort.each_cons(2).select {|p| p[0] == p[1] }.map &:first
Sorts the array, then maps it to consecutive pairs of elements, selects pairs which are same, maps to elements.
I'm new to Ruby, how can I count elements in a loop?
In Java I would write it like this
int[] tablica = { 23,53,23,13 };
int sum = 0;
for (int i = 0; i <= 1; i++) { // **only first two**
sum += tablica[i];
}
System.out.println(sum);
EDIT: I want only first two
You can sum all the elements in an array like this:
arr = [1,2,3,4,5,6]
arr.inject(:+)
# any operator can be here, it will be
# interpolated between the elements (if you use - for example
# you will get 1-2-3-4-5-6)
Or, if you want to iterate over the elements:
arr.each do |element|
do_something_with(element)
Or, if you need the index too:
arr.each_with_index do |element, index|
puts "#{index}: #{element}"
tablica.take(2).reduce(:+)
But seriously? What's wrong with just
tablica[0] + tablica[1]
Hey, it even works in Ruby and Java … and C, C++, Objective-C, Objective-C++, D, C#, ECMAScript, PHP, Python. Without changes.
There are many ways, but if you want the current object and a counter use the each_with_index method
some_collection.each_with_index do |o, i|
# 'o' is your object, 'i' is your index
end
EDIT: Oops, read that too quickly. You can do this
sum = 0
some_collection.each { |i| sum += i }
With Enumerable#inject:
tablica = [23, 53, 23, 13]
tablica.inject(0, :+) # 112
If you just need a sum, here is a simple way:
tablica = [ 23,53,23,13 ]
puts tablica.inject(0){|sum,current_number| sum+current_number}
For first two elements (or whatever contiguous range) you can use a range:
tablica = [ 23,53,23,13 ]
puts tablica[0..1].inject(0){|sum,current_number| sum+current_number}
What this does:
The block (the statement within {...}) is called internally by inject, once for each element in the array.
At the first iteration, sum has the initial value 0 (that we passed to inject)
And current_number contains the 0th element in the array.
We add the two values (0 and 23) and this value gets assigned to sum when the block returns.
Then on the next iteration, we get sum variable as 23 and current_number as 53. And the process repeats.
So, I'm doing Project Euler to solidify my Ruby skills. I'm on problem #4, which reads:
A palindromic number reads the same
both ways. The largest palindrome made
from the product of two 2-digit
numbers is 9009 = 91 * 99.
Find the largest palindrome made from
the product of two 3-digit numbers.
First, I'm trying to verify my code using the information from the first paragraph. I've defined a palindrome function as so:
def palindrome?(blah)
string = blah.to_s
string.reverse == string
end
My code looks like:
array = (90..99).to_a
array = array.map{|u| array.map{|y| u*y}}
array = array.sort
array = array.select{|u| palindrome?(u)}
puts array
The program doesn't output anything. If I do the following:
array = (90..99).to_a
array = array.map{|u| array.map{|y| u*y}}
array = array.sort
#array = array.select{|u| palindrome?(u)}
puts array
I get a long series of unsorted four-digit numbers, so I guess it's ignoring the sort. Finally, if I simply do:
#array = (90..99).to_a
#array = array.map{|u| array.map{|y| u*y}}
#array = array.sort
array = [7447, 9009, 3551, 2419]
array = array.select{|u| palindrome?(u)}
puts array
I get 7447 and 9009, like I should. Why is this happening?
I'm using 1.8.6, because that's the only version available on this Windows machine.
This line of yours
array = array.map{|u| array.map{|y| u*y}}
returns a nested array, you should unwrap.
Hints: (but I'm not going to tell you how)
You probably don't need sort on the intermediary value
You need to remove duplicates
Tips:
next time, run your code in the interactive interpreter, that way you'll see the result of each line of code.
You can use something like this
new_arr = array.inject([]) { |a,u| a += array.map { |y| u*y } }
instead of
array = array.map{|u| array.map{|y| u*y}}
it returns a nested "[ [8100,..],[],[] ] " type of array. So thats the reason why your code doesn't work
This looks more understandable:-
#Steps
# Define a method for palindrome
# List out all 3-digit numbers
# Multiply each numbers by each numbers
# List out all palindrome numbers
# Choose the largest (max) palindrome number
def is_a_palindrome?(n)
n == n.to_s.reverse.to_i
end
def problem_four
palindrome = [ ]
array = 111.upto(999)
array.each do |x|
array.each do |y|
multiply = x * y
if is_a_palindrome?(multiply)
palindrome << multiply
end
end
end
palindrome.max
end
puts problem_four
#$ ruby problem_four.rb
#906609
Find the largest palindrome made from the product of two 3-digit numbers.
I have made this solution, I hope this will help some newbie
to=999
from=100
palindromes=[]
for i in from..to do
for j in 1..to do
k=i*j
palindromes << k if k.to_s==k.to_s.reverse
end
end
palindromes.max #this will return 906609