Converting Binary Coded decimal (BCD) to ASCii in ruby - ruby

I looking for ruby code to convert BCD to Ascii.I have tried with many codes but i am not getting proper result.
Any suggestions or code samples?

I actually wrote a gem for this sort of thing.
https://rubygems.org/gems/bcd
The source code is at https://github.com/dafyddcrosby/ruby_bcd

Although this question is long dead, I just dealt with this. Assuming you've already converted to bcd:
bcd_val.to_s(16)
This converts the bcd value to hex, but because each nibble is a digit, and all digits are between 0-9, it effectively displays as an integer string.
Note that if your bcd number is stored LSB to MSB (depending on how you converted to bcd) the number will display backwards. At that point you can always user str.reverse as necessary.

It is not too clear what do you want to do, but hope that the following can help:
def to_bcd(n)
str = n.to_s
bin = ""
str.each_char do |c|
bin << c.to_i.to_s(2).rjust(4,'0')
end
bin
end
def to_dec(bcd)
n = ""
(bcd.length / 4).times do |i|
n << Integer('0b'+bcd[i*4..(i*4+3)]).to_s
end
n
end
result = to_bcd(120)
p result #=> "000100100000"
p to_dec(result) #=> "120"
p to_dec(result).to_i.chr #=> "x"
If you like, you could extend the Integer and String class with the two methods above, respectively, without arguments and substituting the parameter name with self. But someone does not like the idea to extend standard classes, because it is not a clean/safe programming habit.

Related

Is there a string "constant" that is guaranteed to be after all other strings?

I changed how I was doing things but at one point I needed to append a string to the end of an array of strings and I wanted it guaranteed to be lexicologically after all of the other strings. For integers this would be MAXINT or some similar constant.
In my particular case, I'm using Ruby. I want some Ω such that "Ω" > "s" for all s.
There's no such string satisfying that behavior. Such a string would have to be an infinite sequence of the largest Unicode codepoint, and strings in Ruby cannot be infinite.
However, we can always make a class for which we control the comparison operator.
class OmegaType
include Comparable
def <=>(other)
if other.is_a? OmegaType
0
else
1
end
end
end
Omega = OmegaType.new
And then, if we really want to, we can monkeypatch String to agree with our assessment.
class String
alias old_cmp <=>
def <=>(other)
if other.is_a? OmegaType
-1
else
self.old_cmp other
end
end
end
Now, we find
puts(Omega > 'a') # true
puts('a' < Omega) # true
But is this good practice? Not really. It's probably best to go through whatever list of strings your actual program uses and just pick the "maximum" string to be your "after" value. Or pick something that works in your use case. For instance, if all the strings you're dealing with are alphanumeric, then pick a Unicode character larger than all alphanumerics.

Taking input of two different data type in Ruby

Hey How can I take two kinds of data input from a single line in Ruby. Generally I use
X, Y = gets.split.map(&:to_i)
For taking two integer number from the same line. Now what can I do for taking integer and decimal number input from the same line?
Thanks in advance!
The simplest answer is to replace to_i with to_f (to_float). This will cope with floats, but will convert all your inputs to float, even if an int would do.
You have some other difficulties with your code:
X andY are constants, because they start with capital letters. This will cause difficulties if you ever want to reassign them.
It expects 2 inputs – no more or no less. A 3rd input will be ignored. If you only have one input, Y will be nil.
To take different types of input, you'll have to parse it intelligently. Here I'm using regular expressions for the parsing. You could take other approaches, eg test if arg.to_i == arg.to_f (false if it's a float, true if it's an int...or if it's neither float nor int).
def parse_input(args)
args.map do |arg|
case arg
when /^-?[\d]+$/
arg.to_i
when /^-?[\d]+\.?[\d]+$/
arg.to_f
else
arg
end
end
end
input = parse_input(gets.split)
input.each { |i| puts "#{i} (#{i.class})"}
You can take that input array and pass it round other functions, without it having to tontain exactly 2 members.
You could try this.
types = [:to_i, :to_f]
x, y = gets.split.zip(types).map {|i| i[0].send i[1]}

Swap adjacent elements in array

I am trying to build a method in Ruby that will take in a string that has been split into an array of letters and then iterate through the array, swapping the element at index n with that at index n+1. The method will then join the new array into a string and push it to another array.
Here is an example of what I am looking to do:
string = "teh"
some_method(string)
some ruby magic here
array << new_string
end
Expected output:
["eth", "the"]
This is for a spell checker program I am writing for school. The method will check if letters in a misspelled word are swapped by checking to see if the output array elements are in the dictionary. If they are, it will return the word with that is most likely the correct word. I haven't had any luck finding articles or documentation on how to build such a method in ruby or on an existing method to do this. I've been tinkering with building this method for awhile now but my code isn't behaving anything like what I need. Thanks in advance!
As #Sergio advised, you want to use parallel assignment for this:
def reverse_em(str)
(0...str.size-1).map do |i|
s = str.dup
s[i], s[i+1] = s[i+1], s[i]
s
end
end
candidates = reverse_em "alogrithm"
#=> ["laogrithm", "aolgrithm", "algorithm", "alorgithm",
# "alogirthm", "alogrtihm", "alogrihtm", "alogritmh"]
dictionary_check(candidates)
#=> algorithm
# al·go·rithm
# noun \ˈal-gə-ˌri-thəm\
# a set of steps that are followed in order to solve a
# mathematical problem or to complete a computer process
Without splitting it into arrays then joining to new arrays (because that doesn't seem necessary):
def some_method(string)
swapped_strings = []
(0...string.size-1).each do |i|
temp_string = string.dup
temp_string[i], temp_string[i+1] = temp_string[i+1], temp_string[i]
swapped_strings << temp_string
end
swapped_strings
end

Iterate over digits of integers inside of array

I have this code below:
a = [435,276,434]
def product(a)
final = 1
for e in a
for p in a[e]
final*=p
end
end
final
end
puts product(a)
I'm wondering how I can iterate over this array twice where the result is 4*3*5 = 60, 2*7*6 = 85, and 4*3*4 = 48
I wrote some code up above which I thought would do the trick here but Ruby keeps on returning an error.
A few points to consider:
In Ruby you basically never use a for loop to iterate over things. #each is better. You get to pass a block to that, which gives you all kinds of room for flexibility and expressiveness.
Also, you can't - normally - iterate over an Integer. Remember that an Integer is a store of numerical value, not a particular representation, so it would have to be dependent on the base of the representation you wanted. If you want a string of characters, each of which happen to be numbers, well, guess what? You want a String, like seph's solution here. Or an Array, which would probably make even more sense because each integer would remain an integer and wouldn't have to be parsed back and forth.
Tell you what, let's build a really cool method to do this and staple this on to Integer, and hopefully demonstrate some of Ruby's cool features.
class Integer
include Enumerable
def each(base = 10, &blk)
front, back = abs.divmod(base)
if front > 0
front.each(base, &blk)
end
yield back
end
end
This little number takes a base and a block, gets the absolute value of the integer (since technically the minus isn't a digit), then uses divmod to split the number, chopping off the final digit. We store the pieces in front and back. We check to see if there are any more digits, indicated by front being 0, and if there is we recursively call this method, with that block. Then we just yield the back, sending the digit to the block.
Since we have now defined an each method, we are now free to include Enumerable which gets us a ton of stuff!
As long as that modification is active, your product method becomes:
(if you wanted to print 60 84 48): a.map {|n| n.reduce(:*)}
(or if you wanted to print 241920): a.reduce(:*).reduce(:*)
Pretty nice!
So, this total solution is quite a bit longer than seph's one-liner, and in truth if I needed to actually do something I would just to_s. Is my solution quicker to execute? Who knows? It's certainly more expressive, though, and that's why you're using Ruby in the first place.
If you want to solve a problem, yeah, absolutely, to_s. But if you want your code to express a philosophy you have about numbers, about how really they're just collections too - and they are, in a weird set theory kind of way, Ruby lets you empower them to be that. And this way that doesn't need Strings at all, they're totally free of their grudging assistance. And you can iterate through different bases, which is super useful if you're doing hex or binary, which preserves more of the numbery essence of them.
In this world that you and I have built together, Jamaal, little integers run wild through the forests with the big boys. And that's wonderful.
You could convert it to a string(.to_s). Then it's easy to get each digit as a char(.chars), convert them back to an integers(.map(&:to_i)) and multiply them together(.reduce(:*))
a = [435,276,434]
a.map {|n| n.to_s.chars.map(&:to_i).reduce(:*) }
=> [60, 84, 48]
Here's one way you could fix your code:
a = [435,276,434]
def product(a)
result = [] # Create an empty array that will become [60, 85, 48]
for e in a
final = 1
# Convert the integer e to a string (e.g., "435")
str = e.to_s
# Iterate over each char of the string (e.g., "4", "3" and "5")
str.each_char do |c|
# Convert the character 'c' to an integer (digit) then multiply final by that integer
final *= c.to_i
end
# Append the value of final to the result array
result << final # e.g., when result = [60], result << 85 => [60, 85]
end
result # => [60, 85, 48]
end
product(a) # => [60, 85, 48]
Now let's see how we can improve it. Firstly, we can chain operations and avoid the use of the temporary variable str. Also, you'll find that for loops, each is generally preferable to for (especially because you can use a block with each), so I'll change that too. While I'm at it, since the each_char loop contains only one statement, I'll write the block with brackets rather than do/end. We now have:
def product(a)
result = [] # Create an empty array that will become [60, 85, 48]
a.each do |e|
final = 1
e.to_s.each_char {|c| final *= c.to_i}
result << final
end
result
end
When I look at this, I'm thinking I want to convert each element of the array a to something else (the product of its digits). That suggests the use of the Array method map! (or its synonym, collect!), rather than each. Since a is the argument of the method product, if I use a.map!, that will change the values of a in the method that calls product. That may or may not be OK, but since I'm returning an array of the computed values, it's probably not OK, so I'll apply map! to a copy of a. (It's called a "shallow" copy, which is not important here, but can be in other situations.) We now have this:
def product(a)
result = a.dup
result.map! do |e|
final = 1
e.to_s.each_char {|c| final *= c.to_i}
final
end
result
end
We don't need the last result, because map! returns result (as well as changing result). Hey, that also means we can use just map (makes no difference). Also, we can chain a.dup and map to get rid of result:
def product(a)
a.dup.map do |e|
final = 1
e.to_s.each_char {|c| final *= c.to_i}
final
end
end
Man, we're cookin' with gas! Next, whenever you see a block that computes the product or sum of something, think inject (or its synomym, reduce):
def product(a)
a.dup.map do |e|
e.to_s.each_char.inject(1) {|final, c| final * c.to_i}
end
end
Suppose a < 0. What to do? (#Leon's answer twigged me to that possibility.) A negative receiver makes no sense to each, so let's raise an exception if that happens:
def product(a)
raise RuntimeError, "Receiver must be non-negative" if self < 0
a.dup.map do |e|
e.to_s.each_char.inject(1) {|final, c| final * c.to_i}
end
end
You may want to stop here, but you could replace map with another `inject:
def product(a)
raise RuntimeError, "Receiver must be non-negative" if self < 0
a.inject([]) {|result, e| result.concat.e.to_s.each_char.inject(1) {|final, c| final * c.to_i}}
end
Here the argument for inject is an empty array called result. Notice that, since we haven't changed a, we no longer needed dup. (I see #Kingston arrived at a similar answer.) If you prefer, you could write this as:
def product(a)
raise RuntimeError, "Receiver must be non-negative" if self < 0
a.inject([]) {|result, e| result << e.to_s.each_char.inject(1) {|final, c| final * c.to_i}; result}
end
but notice the need for that pesky ; result an the end.
You might think that the end result of all these "improvements" is too much of a mind-bender, or that the author is just showing off. That's what I thought when I was new to Ruby. With experience, however, you will find it is very natural and reads like a sentence. It also makes debugging easier: working left-to-right, you can test each link of the chain to make sure it's working.
a.collect{|x|
result = 1
x.to_s.split('').each{|y| result *= y.to_i}
result
}
If the intent is to just iterate over the digits, you can use the string slice methods too.
num = a[0].to_s # "435"
final = num[0,1].to_i * num[1,1].to_i * num[2,1].to_i #4*3*5
or
final = num[0..1].to_i * num[1..2].to_i * num[2..3].to_i
For the given question, if you know it is an array of 3 digits each, then you can skip the inner loop and the solution could be like this:
a = [435,276,434]
def product(a)
a.map! do |digits|
final = 1
num = digits.to_s
final = num[0,1].to_i * num[1,1].to_i * num[2,1].to_i
end
end
puts product(a).inspect
This answer is just for the said question. Since it manipulates the same array, it edits the receiver. For a more detailed and complete solution, check out Cary Swoveland's answer.

How do I generate a random 10 digit number in ruby?

Additionally, how can I format it as a string padded with zeros?
To generate the number call rand with the result of the expression "10 to the power of 10"
rand(10 ** 10)
To pad the number with zeros you can use the string format operator
'%010d' % rand(10 ** 10)
or the rjust method of string
rand(10 ** 10).to_s.rjust(10,'0')
I would like to contribute probably a simplest solution I know, which is a quite a good trick.
rand.to_s[2..11]
=> "5950281724"
This is a fast way to generate a 10-sized string of digits:
10.times.map{rand(10)}.join # => "3401487670"
The most straightforward answer would probably be
rand(1e9...1e10).to_i
The to_i part is needed because 1e9 and 1e10 are actually floats:
irb(main)> 1e9.class
=> Float
DON'T USE rand.to_s[2..11].to_i
Why? Because here's what you can get:
rand.to_s[2..9] #=> "04890612"
and then:
"04890612".to_i #=> 4890612
Note that:
4890612.to_s.length #=> 7
Which is not what you've expected!
To check that error in your own code, instead of .to_i you may wrap it like this:
Integer(rand.to_s[2..9])
and very soon it will turn out that:
ArgumentError: invalid value for Integer(): "02939053"
So it's always better to stick to .center, but keep in mind that:
rand(9)
sometimes may give you 0.
To prevent that:
rand(1..9)
which will always return something withing 1..9 range.
I'm glad that I had good tests and I hope you will avoid breaking your system.
Random number generation
Use Kernel#rand method:
rand(1_000_000_000..9_999_999_999) # => random 10-digits number
Random string generation
Use times + map + join combination:
10.times.map { rand(0..9) }.join # => random 10-digit string (may start with 0!)
Number to string conversion with padding
Use String#% method:
"%010d" % 123348 # => "0000123348"
Password generation
Use KeePass password generator library, it supports different patterns for generating random password:
KeePass::Password.generate("d{10}") # => random 10-digit string (may start with 0!)
A documentation for KeePass patterns can be found here.
Just because it wasn't mentioned, the Kernel#sprintf method (or it's alias Kernel#format in the Powerpack Library) is generally preferred over the String#% method, as mentioned in the Ruby Community Style Guide.
Of course this is highly debatable, but to provide insight:
The syntax of #quackingduck's answer would be
# considered bad
'%010d' % rand(10**10)
# considered good
sprintf('%010d', rand(10**10))
The nature of this preference is primarily due to the cryptic nature of %. It's not very semantic by itself and without any additional context it can be confused with the % modulo operator.
Examples from the Style Guide:
# bad
'%d %d' % [20, 10]
# => '20 10'
# good
sprintf('%d %d', 20, 10)
# => '20 10'
# good
sprintf('%{first} %{second}', first: 20, second: 10)
# => '20 10'
format('%d %d', 20, 10)
# => '20 10'
# good
format('%{first} %{second}', first: 20, second: 10)
# => '20 10'
To make justice for String#%, I personally really like using operator-like syntaxes instead of commands, the same way you would do your_array << 'foo' over your_array.push('123').
This just illustrates a tendency in the community, what's "best" is up to you.
More info in this blogpost.
I ended up with using Ruby kernel srand
srand.to_s.last(10)
Docs here: Kernel#srand
Here is an expression that will use one fewer method call than quackingduck's example.
'%011d' % rand(1e10)
One caveat, 1e10 is a Float, and Kernel#rand ends up calling to_i on it, so for some higher values you might have some inconsistencies. To be more precise with a literal, you could also do:
'%011d' % rand(10_000_000_000) # Note that underscores are ignored in integer literals
('%010d' % rand(0..9999999999)).to_s
or
"#{'%010d' % rand(0..9999999999)}"
I just want to modify first answer. rand (10**10) may generate 9 digit random no if 0 is in first place. For ensuring 10 exact digit just modify
code = rand(10**10)
while code.to_s.length != 10
code = rand(11**11)
end
Try using the SecureRandom ruby library.
It generates random numbers but the length is not specific.
Go through this link for more information: http://ruby-doc.org/stdlib-2.1.2/libdoc/securerandom/rdoc/SecureRandom.html
Simplest way to generate n digit random number -
Random.new.rand((10**(n - 1))..(10**n))
generate 10 digit number number -
Random.new.rand((10**(10 - 1))..(10**10))
This technique works for any "alphabet"
(1..10).map{"0123456789".chars.to_a.sample}.join
=> "6383411680"
Just use straightforward below.
rand(10 ** 9...10 ** 10)
Just test it on IRB with below.
(1..1000).each { puts rand(10 ** 9...10 ** 10) }
To generate a random, 10-digit string:
# This generates a 10-digit string, where the
# minimum possible value is "0000000000", and the
# maximum possible value is "9999999999"
SecureRandom.random_number(10**10).to_s.rjust(10, '0')
Here's more detail of what's happening, shown by breaking the single line into multiple lines with explaining variables:
# Calculate the upper bound for the random number generator
# upper_bound = 10,000,000,000
upper_bound = 10**10
# n will be an integer with a minimum possible value of 0,
# and a maximum possible value of 9,999,999,999
n = SecureRandom.random_number(upper_bound)
# Convert the integer n to a string
# unpadded_str will be "0" if n == 0
# unpadded_str will be "9999999999" if n == 9_999_999_999
unpadded_str = n.to_s
# Pad the string with leading zeroes if it is less than
# 10 digits long.
# "0" would be padded to "0000000000"
# "123" would be padded to "0000000123"
# "9999999999" would not be padded, and remains unchanged as "9999999999"
padded_str = unpadded_str.rjust(10, '0')
rand(9999999999).to_s.center(10, rand(9).to_s).to_i
is faster than
rand.to_s[2..11].to_i
You can use:
puts Benchmark.measure{(1..1000000).map{rand(9999999999).to_s.center(10, rand(9).to_s).to_i}}
and
puts Benchmark.measure{(1..1000000).map{rand.to_s[2..11].to_i}}
in Rails console to confirm that.
An alternative answer, using the regexp-examples ruby gem:
require 'regexp-examples'
/\d{10}/.random_example # => "0826423747"
There's no need to "pad with zeros" with this approach, since you are immediately generating a String.
This will work even on ruby 1.8.7:
rand(9999999999).to_s.center(10, rand(9).to_s).to_i
A better approach is use Array.new() instead of .times.map. Rubocop recommends it.
Example:
string_size = 9
Array.new(string_size) do
rand(10).to_s
end
Rubucop, TimesMap:
https://www.rubydoc.info/gems/rubocop/RuboCop/Cop/Performance/TimesMap
In my case number must be unique in my models, so I added checking block.
module StringUtil
refine String.singleton_class do
def generate_random_digits(size:)
proc = lambda{ rand.to_s[2...(2 + size)] }
if block_given?
loop do
generated = proc.call
break generated if yield(generated) # check generated num meets condition
end
else
proc.call
end
end
end
end
using StringUtil
String.generate_random_digits(3) => "763"
String.generate_random_digits(3) do |num|
User.find_by(code: num).nil?
end => "689"(This is unique in Users code)
I did something like this
x = 10 #Number of digit
(rand(10 ** x) + 10**x).to_s[0..x-1]
Random 10 numbers:
require 'string_pattern'
puts "10:N".gen

Resources