Skip to main content

Hackerrank > Ruby > Methods



In our previous challenges, we have been using methods (def method() .. endconstruct) to abstract compound operations, perform data manipulations and learn various concepts of the language, without talking in much detail about the concept of methods themselves, and how they are useful for a programmer. In this set of challenges, we will explore the guiding principles behind methods, learn more features and how to use them efficiently in our programs.
In simpler terms, a method is a group of several expressions (block, so to say) that can be referred with a name, can be passed some arguments (input) and are associated with one or more objects.
If you have programmed before, you might notice that the description above sounds almost same as functions in other languages (e.g, Python) except the last part which talks about association with one or more objects. It might be a bit non trivial to comprehend since Classes haven't been introduced, but what it means is that these methods, even though they appear like global functions, are instead private methods of a root Object class on which they are implicitly defined and invoked automatically.
So, when you write -
def hello_world
    'Eha! Ruby'

> hello_world
'Eha! Ruby'
You are essentially adding a private method to Object class -
class Object

    def hello_world2
        'Eha! Ruby'

> hello_world2
=> 'Eha! Ruby'
This, however, is not the focus of this challenge. Instead, it was just to show you the true object nature of Ruby, and we'll return to it again later during our challenges on classes.
In this challenge, you need to write a method prime? that takes an argument and returns true or false depending on if the number is prime or not.
> prime? 3
> prime? 17
> prime? 22

Further reading

These methods, unlike functions in other object oriented programming language (e.g., Python) are not a first-class citizens, because they cannot be passed to other methods as arguments, returned by other methods, or assigned to variables.
# :)
def prime?(n)


In our previous challenge, we learned about methods and how they help us to abstract similar computations into logical chunks of code that otherwise would be very clumsy and difficult to manage. Methods, in a way, also behave like ablack box where the programmer should ideally be concerned only with a basic description of the box - what it does, what is it input and what is the expected output, without having to worry about how it does it. This allows us to focus more on the functionality and correctness of program instead of implementation details. In these set of tutorials, we will make the same black box assumptions and focus on building a better understanding of the three aspects described above.
The ability to pass arguments is of critical importance as it determines the complexity and variability of output that we can generate. We have already seen straight forward cases of passing several values as variables to our methods, but however, there's much more to Ruby's methods. Let's examine it with practical scenarios.
Consider a case where you have a method that is invoked from different portions of your code with some variation in one of the arguments. However, you still need to pass a value for the remaining arguments which mostly remain constant through these calls. In such cases, the ability to assign default values to your arguments becomes increasingly useful as it helps you to avoid passing a value for all arguments and decrease chances of making errors. It is quite analogous to an on-demand behavior where you pass an argument only when you need it to affect your output, otherwise let the default action go on.
For example,
def prefix(s, len=1)

> prefix("Ruby", 3) # => "Rub"
> prefix("Ruby")    # => "R"
In this challenge, your task is to figure out what take method does using the examples below and implement the method. It should help you understand how to build on implementation through the expected functionality.
> take([1,2,3], 1)
[2, 3]
> take([1,2,3], 2)
> take([1,2,3])
[2, 3]


One can invoke method by simply writing name('Foolan', 'Barik') or without the parentheses like name 'Foolan', 'Barik', although the latter convention can be confusing and hence is not recommended.
def take(arr, n)
    return arr

03-Variable Arguments

In our previous challenges, we explored a couple of ways to pass arguments to our methods, but both of there were limited in the terms of the number of arguments we can pass at a time. Sure enough, using default parameters allowed us to lower the number of arguments in some cases but didn't help in the situations where we want to pass a variable (and possibly large!) number of arguments.
For example, consider a method to compute the sum of numbers. Obviously, neither you wouldn't want to write different method for adding different count of numbers, or create one method with hundred default arguments each initialized to 0. What if I wan to add 1000 numbers?
That's where Ruby's * come into play. Take a look.
def sum(first, *rest)
    rest.reduce(first) { |o, x| o + x }

> sum(1) # first = 1, rest = []
> sum(1, 2) # first = 1, rest = [2]
> sum(1, 2, 3) # first = 1, rest = [2, 3]
Putting the * (called splat) to a parameter assigns all of the values starting from that position in the method call to an array referred by the name rest inside the method. So, in this case our method requires at least one compulsory parameter because of the named variable first and rest all values are assigned as an array to rest.
In this challenge, your task is to write a method for generating the full names of people, given their compulsory first name, last name and variable number of middle names.
> full_name('Harsha', 'Bhogle')
"Harsha Bhogle"
> full_name('Pradeep', 'Suresh', 'Satyanarayana')
"Pradeep Suresh Satayanarayana"
> full_name('Horc', 'G.', 'M.', 'Moon')
"Horc G. M. Moon"
> full_name('Marc') # error
def full_name(firstName, *middleName, lastName)
    if middleName.empty?
        return firstName.to_s + " " + lastName.to_s
        return firstName.to_s + " " + (middleName * " ") + " " + lastName.to_s

04-Keyword Arguments

In our previous challenge, we explored one way to pass a variable number of arguments to our methods. While it may seem handy feature to have, except few circumstances, you are never going to use that many variables for your method. Also, if your are passing several different types of variables to the method which then will be assigned to the array, it can be difficult for the programmer invoking the method to remember the proper order for those arguments.
Ruby allows you to (partially) mitigate this problem by passing a Hash as an argument or one of the arguments. For example, you have a method that takes a URI to download a file and another argument containing a Hash of other named options (proxy, timeout, active-connections etc.,)
def fetch_file(uri, options)
    if options.has_key?(:proxy)
        # do something
The main problem with this technique, however, is that you cannot easily set default value for arguments (Read more). Since this construct is highly useful, Ruby 2 introduced keyword arguments which allows you to write -
def foo(x, str: "foo", num: 424242)
  [x, str, num]

foo(13) #=> [13, 'foo', 424242]
foo(13, str: 'bar') #=> [13, 'bar', 424242]
Also, introducing the double splat (**) which similar to it's counterpart collects all the extra named keywords as a hash parameter.
def foo(str: "foo", num: 424242, **options)
  [str, num, options]

foo #=> ['foo', 424242, {}]
foo(check: true) # => ['foo', 424242, {check: true}]
In this challenge, your task is to write a method convert_temp that helps in temperature conversion. The method will receive a number as an input (temperature), a named parameter input_scale (scale for input temperature), and an optional parameter output_scale (output temperature scale, defaults to Celsius) and return the converted temperature. It should perform interconversion between Celsius, Fahrenheit and Kelvin scale.
For example,
> convert_temp(0, input_scale: 'celsius', output_scale: 'kelvin')
=> 273.15 
> convert_temp(0, input_scale: 'celsius', output_scale: 'fahrenheit')
=> 32.0
Note that the input values are lowercase version of corresponding scales.
def converttemp(temperature, inputscale: "" , outputscale: 'celsius')
    if inputscale == outputscale
        return temperature
    if inputscale == 'celsius'
        if outputscale == 'fahrenheit'
            return (temperature * 9.0 / 5) + 32
        elsif outputscale == 'kelvin'
            return temperature + 273.15
    elsif inputscale == 'fahrenheit'
        if outputscale == 'celsius'
            return (temperature - 32)  5.0 / 9 
        elsif output_scale == 'kelvin'
            return ((temperature - 32)  (5.0 / 9)) + 273.15
    elsif inputscale == 'kelvin'
        if outputscale == 'celsius'
            return temperature - 273.15
        elsif outputscale == 'fahrenheit'
            return ((temperature - 273.15) * 9.0 / 5) + 32 
        return "Unknown inputscale" #error

    return "Unknown output_scale" #error


Popular posts from this blog

ORACLE 9i practice solutions

Created by BCL easyConverter SDK 3 (HTML Version)

Zoho Puzzle Questions With Answers

Measuring Time Logic Puzzle You are given with two ropes with variable width. However if we start burning both the ropes, they will burn at exactly same time i.e. an hour. The ropes are non-homogeneous in nature. You are asked to measure 45 minutes by using these two ropes.

How can you do it?

Please note that you can’t break the rope in half as it is being clearly stated that the ropes are non-homogeneous in nature.
Answer & Explanation Solution: 45 minutes

Explanation :
All you have to do is burn the first rope from both the ends and the second rope from one end only simultaneously. The first rope will burn in 30 minutes (half of an hour since we burned from both sides) while the other rope would have burnt half. At this moment, light the second rope from the other end as well. Where, the second rope would have taken half an hour more to burn completely, it will take just 15 minutes as we have lit it from the other end too.

Thus you have successfully calculated 30+15 = 45 minutes …

Hackerrank > SQL > Basic Select

01-Select All
Given a City table, whose fields are described as +-------------+----------+ | Field       | Type     | +-------------+----------+ | ID          | int(11)  | | Name        | char(35) | | CountryCode | char(3)  | | District    | char(20) | | Population  | int(11)  | +-------------+----------+
write a query that will fetch all columns for every row in the table.

My Solution
02-Select by ID
Given a City table, whose fields are described as