Steven Aguilar Steven Aguilar - 2 months ago 9
Ruby Question

How to not allowed taking in a number into a variable in Ruby

Given a string S of length N that is indexed from 0 to N-1 , print its even-indexed and odd-indexed characters as space-separated strings on a single line (see the Sample below for more detail).
Sample Input:

2
Hacker
Rank


Sample output:

Hce akr
Rn ak


explanation:


S="Hacker" S[0]="H", S[1]="a", S[2]= "c", S[3]="k", S[4]="e", S[5]="r"


However, with the following code I haven't been able to complete the challenge. How do I constraint taken input as an integer?

S = gets.chomp.chars.to_a


for i in 0..S.length
if i%2 == 0
s1 = S[i]
else
s2 = S[i]
end
end

puts s1.to_s + " " + s2.to_s

Answer

Here is the basic algorithm that would take O(n).

tests = gets.to_i

# run the loop for number of tests given
tests.times do
  string = gets.chomp # sanitize string from input, i.e. removes \n \r
  s_length = string.length # String length N
  new_string = " " * s_length # create of string of length N
  even_index = 0 # because evens are going to come first
  odd_index = s_length - (s_length/2) + 1 # odds are going to start where even numbers end + 1
  0.upto(s_length-1) do |i|
    if i%2 == 0
      new_string[even_index] = string[i]
      even_index += 1
    elsif
      new_string[odd_index] = string[i]
      odd_index += 1
    end
  end
  puts new_string
end

Benchmark:

require 'benchmark'

def using_ugly_algo(tests, string)
  # tests = gets.to_i

  tests.times do
    string = string
    s_length = string.length # String length N
    new_string = " " * s_length # creat of string of length N
    even_index = 0
    odd_index = s_length - (s_length/2) + 1
    0.upto(s_length-1) do |i|
      if i%2 == 0
        new_string[even_index] = string[i]
        even_index += 1
      elsif
        new_string[odd_index] = string[i]
        odd_index += 1
      end
    end
    # new_string
  end
end

def with_partition(amount, string)
  amount.times do
    input = string
    (input.split('').partition.with_index do |_, i|
      i.even?
    end.map(&:join).join(' '))
  end
end


n = 10_000
string = (0...500).map { ('a'..'z').to_a[rand(26)] }.join

Benchmark.bmbm(100) do |x|
  x.report("using_ugly_algo "){ n.times { using_ugly_algo(5, string) } }
  x.report("with_partition  "){ n.times { with_partition(5, string) } }
end

Report:

Rehearsal ----------------------------------------------------------------------------------------------------------------------------------------
using_ugly_algo                                                                                       13.790000   0.030000  13.820000 ( 13.843560)
with_partition                                                                                        16.790000   0.030000  16.820000 ( 16.830992)
------------------------------------------------------------------------------------------------------------------------------ total: 30.640000sec

                                                                                                           user     system      total        real
using_ugly_algo                                                                                       13.930000   0.060000  13.990000 ( 14.070378)
with_partition                                                                                        18.640000   0.210000  18.850000 ( 19.392816)
Comments