How do I make the following array programatically in Ruby (1.9).
It follows the pattern 7n + 1 and I'd like it to contain 24 numbers.
arr = ["8","15","22","29","36","43","50","57","64","71" ]
Use collect and apply to_s on the result:
(1..24).collect{|n| (n*7 + 1).to_s}
EDIT: sorry forgot to convert numbers to strings. Code is edited now.
Array.new(24){|i| (i * 7 + 8).to_s}
Related
I am using the below code to get the number of records.
self.size.to_s
How can i add '1' to the size from above?
Integer#next:
self.size.next.to_s
(self.size + 1).to_s # Like this
You can either add it before converting to string
(self.size + 1).to_s
Or if you already have a string
"2".to_i + 1
Combined this could be something like
self.size.to_s.to_i + 1
but that is hardly practical
In spreadsheets I have cells named like "F14", "BE5" or "ALL1". I have the first part, the column coordinate, in a variable and I want to convert it to a 0-based integer column index.
How do I do it, preferably in an elegant way, in Ruby?
I can do it using a brute-force method: I can imagine loopping through all letters, converting them to ASCII and adding to a result, but I feel there should be something more elegant/straightforward.
Edit: Example: To simplify I do only speak about the column coordinate (letters). Therefore in the first case (F14) I have "F" as the input and I expect the result to be 5. In the second case I have "BE" as input and I expect getting 56, for "ALL" I want to get 999.
Not sure if this is any clearer than the code you already have, but it does have the advantage of handling an arbitrary number of letters:
class String
def upcase_letters
self.upcase.split(//)
end
end
module Enumerable
def reverse_with_index
self.map.with_index.to_a.reverse
end
def sum
self.reduce(0, :+)
end
end
def indexFromColumnName(column_str)
start = 'A'.ord - 1
column_str.upcase_letters.map do |c|
c.ord - start
end.reverse_with_index.map do |value, digit_position|
value * (26 ** digit_position)
end.sum - 1
end
I've added some methods to String and Enumerable because I thought it made the code more readable, but you could inline these or define them elsewhere if you don't like that sort of thing.
We can use modulo and the length of the input. The last character will
be used to calculate the exact "position", and the remainders to count
how many "laps" we did in the alphabet, e.g.
def column_to_integer(column_name)
letters = /[A-Z]+/.match(column_name).to_s.split("")
laps = (letters.length - 1) * 26
position = ((letters.last.ord - 'A'.ord) % 26)
laps + position
end
Using decimal representation (ord) and the math tricks seems a neat
solution at first, but it has some pain points regarding the
implementation. We have magic numbers, 26, and constants 'A'.ord all
over.
One solution is to give our code better knowlegde about our domain, i.e.
the alphabet. In that case, we can switch the modulo with the position of
the last character in the alphabet (because it's already sorted in a zero-based array), e.g.
ALPHABET = ('A'..'Z').to_a
def column_to_integer(column_name)
letters = /[A-Z]+/.match(column_name).to_s.split("")
laps = (letters.length - 1) * ALPHABET.size
position = ALPHABET.index(letters.last)
laps + position
end
The final result:
> column_to_integer('F5')
=> 5
> column_to_integer('AK14')
=> 36
HTH. Best!
I have found particularly neat way to do this conversion:
def index_from_column_name(colname)
s=colname.size
(colname.to_i(36)-(36**s-1).div(3.5)).to_s(36).to_i(26)+(26**s-1)/25-1
end
Explanation why it works
(warning spoiler ;) ahead). Basically we are doing this
(colname.to_i(36)-('A'*colname.size).to_i(36)).to_s(36).to_i(26)+('1'*colname.size).to_i(26)-1
which in plain English means, that we are interpreting colname as 26-base number. Before we can do it we need to interpret all A's as 1, B's as 2 etc. If only this is needed than it would be even simpler, namely
(colname.to_i(36) - '9'*colname.size).to_i(36)).to_s(36).to_i(26)-1
unfortunately there are Z characters present which would need to be interpreted as 10(base 26) so we need a little trick. We shift every digit 1 more then needed and than add it at the end (to every digit in original colname)
`
I have a variable in ruby on rails which contains this value 8,375 TND
_result = _orig_account.formatted_balance(_currency)
I want if it is possible to eliminate TND and then multiply the rest by 1000 in order to have as a result 8375
can sameone help me to solve this problem
I try with this code :
I try with : _tes = _orig_account.formatted_balance().tr(',', '.').to_f
_te = _tes * 1000
and I have as a result : 8375.0
but as I said I want juste 8375
UPDATE: Just use this '8,375 TND'.tr(',', '').to_i
It's a simple manipulation:
'8,375 TND'.tr(',', '.').to_f
=> 8.375
Multiply that by 1000.
I have a problem I can't for the life of me solve. I'm writing a Ruby app (I've been a PHP developer for 8 years, just starting with Ruby) that sells tickets for a concert hall. Each seat has a row (a...z) and a number (1...x). The database model has row (string) and num (int) for each seat.
How can I convert my array of seats from the database into a 2d array? For example, seat A1 would go into seat[1][1] = "value"; seat C4 would map to seat[3][4] = value. The issue is converting the row string to Ascii and subtracting the offset? Or is there an easier way?
Many thanks
The simplest way is probably to use a hash instead. For example: seat['A'][1] = value
But if you really need an array for some reason, then the method you describe is the simplest. Assuming the row string is a single character 'A' through 'Z', you can do it using row_string[0] - ?A (or row_string[0] - ?A + 1 if you want the index starting at 1 as in your example). For a multi-character version where row AA is after row Z, you can do this in 1.8.7 and newer:
row_num = row_string.bytes.inject(0) {|total, x| total = total * 26 + x - ?A + 1}
You may want to upcase your row string beforehand, just to be on the safe side.
In 1.8.6 and below, String does not have a bytes method. You can accomplish the same thing by doing:
row_num = 0
row_string.each_byte {|x| row_num = row_num * 26 + x - ?A + 1}
Ok, the solution I've come up with that seems to do the trick:
seat_array = Hash.new{|h,k| h[k]=Hash.new(&h.default_proc) }
for seat in self.seats
seat_array[seat.row.downcase][seat.num] = seat
end
return seat_array
Many thanks to everyone for such quick and useful responses. I'll certainly be helping others with PHP!
Well to get the index of a letter you could do something like this
('A'..'Z').to_a.index('C')
which would return 2
I notice in the array examples you gave you started A = 1 instead of 0.
('1' * N) !~ /^1?$|^(11+?)\1+$/
On the net, I found this piece of Ruby code that works for N >= 0 that determines whether or not N is a prime. From what I can tell, it looks like play with regex but I have no idea how it works. Could someone tell me how it works?
You can find a lengthy explanation of this code here:
http://www.noulakaz.net/weblog/2007/03/18/a-regular-expression-to-check-for-prime-numbers/
This is probably rather off-topic, but in Ruby 1.9, you can do this:
require 'mathn'
38749711234868463.prime?
=> false
require 'prime'
Prime.prime?(4)
# => false
Prime.prime?(5)
# => true
Or:
require 'prime'
Prime.instance.prime?(4)
# => false
Prime.instance.prime?(5)
# => true
See also What is the most brilliant regex you’ve ever used? (and yes, I can confirm that this regexp was originally written by Abigail. I've even heard her explain how it works :)
Greatest Common Divisor (gcd):
/^(1+)\1*=\1+$/.match('1' * x + '=' + '1' * y)[1].length
Both this and the is_prime one works in about the same way. It tries all combinations before giving up.
This one will try to split the first number in even parts, and match the second number with one or more of those parts. If it finds a match it returns the length of the selected part.
Yet another blog with a pretty good explanation: Famous Perl One-Liners Explained (part III)
If the length of a string of 1's is composite, then the string can be decomposed into multiple identical substrings, like 111111 -> 11 11 11
For example, 1111111111, has 10 1's, and it matches (11){5} or (11111){2}, where {2} means repeated 2 times.
111111111, has 9 1's, and it matches (111){3}.
By generalizing the count of 1's and the number in {}, the regexp is
/(1{2,}){2,}/.
However, 1{2,} can also be written as 11+, and (...){2,} can be rewritten as (...)\1+, with backreferences.
The ^1?$ part in the first alternation checks for 0 and 1-cases.