100 Ruby practice problems with solutions

Here are 100 Ruby practice problems with solutions, covering core syntax, enumerables, OOP, blocks, metaprogramming, and algorithms.

Also try it: 100 Swift practice problems with solutions

1. Hello World

Print “Hello, World!”.

ruby

puts "Hello, World!"

2. Sum of Two Numbers

Write a method sum(a, b) that returns the sum.

ruby

def sum(a, b)
  a + b
end

3. Check Even or Odd

Return true if a number is even.

ruby

def even?(num)
  num.even?
end

4. Maximum of Three Numbers

ruby

def max_of_three(a, b, c)
  [a, b, c].max
end

5. Reverse a String

ruby

def reverse_string(str)
  str.reverse
end

6. Palindrome Check

Ignore case and non‑alphanumeric characters.

ruby

def palindrome?(str)
  cleaned = str.downcase.gsub(/[^a-z0-9]/, '')
  cleaned == cleaned.reverse
end

7. Count Vowels

ruby

def count_vowels(str)
  str.downcase.count('aeiou')
end

8. Longest Word in a Sentence

ruby

def longest_word(sentence)
  sentence.split.max_by(&:length)
end

9. Capitalize Every Word

ruby

def capitalize_words(str)
  str.split.map(&:capitalize).join(' ')
end

10. Truncate String

Truncate to max_length and add “…” if longer.

ruby

def truncate(str, max_length)
  str.length > max_length ? str[0...max_length] + '...' : str
end

11. Anagram Check

ruby

def anagram?(a, b)
  a.downcase.chars.sort == b.downcase.chars.sort
end

12. String Compression

“aaabbc” → “a3b2c1”.

ruby

def compress(str)
  str.gsub(/(.)\1*/) { "#{$1}#{$&.length}" }
end

13. All Substrings

Print all substrings of a given string.

ruby

def substrings(str)
  (0...str.length).each do |i|
    (i...str.length).each { |j| puts str[i..j] }
  end
end

14. Remove Duplicate Characters

ruby

def remove_duplicates(str)
  str.chars.uniq.join
end

15. Sum of Array Elements

ruby

def array_sum(arr)
  arr.sum
end

16. Find Min and Max

Return an array with min and max.

ruby

def min_max(arr)
  [arr.min, arr.max]
end

17. Remove Negatives from Array

ruby

def remove_negatives(arr)
  arr.select { |n| n >= 0 }
end

18. Reverse Array In‑Place

ruby

def reverse_in_place(arr)
  arr.reverse!
end

19. Merge Two Sorted Arrays

ruby

def merge_sorted(a, b)
  (a + b).sort
end

20. Remove Duplicates from Array (keep order)

ruby

def uniq_ordered(arr)
  arr.uniq
end

21. Rotate Array Right by K

ruby

def rotate_right(arr, k)
  arr.rotate(-k)
end

22. Find Missing Number 1..N

Given distinct numbers from 1 to N with one missing.

ruby

def missing_number(arr, n)
  n * (n + 1) / 2 - arr.sum
end

23. Intersection of Two Arrays

ruby

def intersection(a, b)
  a & b
end

24. Union of Arrays

ruby

def union(a, b)
  a | b
end

25. Factorial (Recursive)

ruby

def factorial(n)
  n <= 1 ? 1 : n * factorial(n - 1)
end

26. Fibonacci Array (first n)

ruby

def fib(n)
  return [0] if n == 1
  fib = [0, 1]
  (2...n).each { fib << fib[-1] + fib[-2] }
  fib
end

27. Prime Check

ruby

require 'prime'
def prime?(num)
  num.prime?
end

Alternatively:

ruby

def prime?(num)
  return false if num < 2
  (2..Math.sqrt(num)).none? { |i| num % i == 0 }
end

28. FizzBuzz (1..100)

ruby

(1..100).each do |i|
  if i % 15 == 0 then puts "FizzBuzz"
  elsif i % 3 == 0 then puts "Fizz"
  elsif i % 5 == 0 then puts "Buzz"
  else puts i
  end
end

29. Binary Search

Assume sorted array.

ruby

def binary_search(arr, target)
  low, high = 0, arr.length - 1
  while low <= high
    mid = (low + high) / 2
    if arr[mid] == target
      return mid
    elsif arr[mid] < target
      low = mid + 1
    else
      high = mid - 1
    end
  end
  nil
end

30. Bubble Sort

ruby

def bubble_sort(arr)
  n = arr.length
  (n-1).times do
    (0...n-1).each do |i|
      if arr[i] > arr[i+1]
        arr[i], arr[i+1] = arr[i+1], arr[i]
      end
    end
  end
  arr
end

31. Sum of Digits

ruby

def sum_of_digits(num)
  num.digits.sum
end

32. Convert String to Number

"123" → 123 without using to_i.

ruby

def string_to_int(str)
  str.bytes.reduce(0) { |sum, b| sum * 10 + (b - 48) }
end

33. Check if Array Contains All Elements of Another

ruby

def contains_all?(arr, sub)
  (sub - arr).empty?
end

34. Shuffle Array (Fisher‑Yates)

ruby

def shuffle(arr)
  arr.each_index do |i|
    j = rand(i..arr.length-1)
    arr[i], arr[j] = arr[j], arr[i]
  end
  arr
end

35. Flatten Nested Array (one level)

ruby

def flatten_one(arr)
  arr.flat_map { |e| e.is_a?(Array) ? e : [e] }
end

36. Deep Flatten (any depth)

ruby

def deep_flatten(arr)
  arr.flatten
end

37. Count Occurrences of Each Element

ruby

def count_occurrences(arr)
  arr.tally
end

38. Most Frequent Element

ruby

def most_frequent(arr)
  arr.max_by { |e| arr.count(e) }
end

39. Unique Characters in String

ruby

def all_unique?(str)
  str.chars.uniq.length == str.length
end

40. Convert to Roman Numerals (1..3999)

ruby

def to_roman(num)
  map = {
    1000 => "M", 900 => "CM", 500 => "D", 400 => "CD",
    100 => "C", 90 => "XC", 50 => "L", 40 => "XL",
    10 => "X", 9 => "IX", 5 => "V", 4 => "IV", 1 => "I"
  }
  roman = ""
  map.each do |value, letter|
    while num >= value
      roman << letter
      num -= value
    end
  end
  roman
end

41. Hash Map Creation

Given two arrays, create a hash where keys from one array map to values from another.

ruby

def map_arrays(keys, values)
  keys.zip(values).to_h
end

42. Find Hash Key by Value

Return the first key that has a given value.

ruby

def key_by_value(hash, val)
  hash.key(val)
end

43. Merge Two Hashes (deep merge simple)

ruby

def deep_merge(h1, h2)
  h1.merge(h2) { |key, old, new| old.is_a?(Hash) ? deep_merge(old, new) : new }
end

44. Symbolize Keys

Convert string keys to symbols.

ruby

def symbolize_keys(hash)
  hash.transform_keys(&:to_sym)
end

45. Word Frequency in a Sentence

Return a Hash with word counts.

ruby

def word_frequency(sentence)
  sentence.split.each_with_object(Hash.new(0)) { |word, h| h[word.downcase.gsub(/[^a-z]/, '')] += 1 }
end

46. Group Anagrams from a List

ruby

def group_anagrams(words)
  words.group_by { |word| word.downcase.chars.sort.join }.values
end

47. Enumerable: Select and Map

Select even numbers and square them.

ruby

def even_squares(nums)
  nums.select(&:even?).map { |n| n * n }
end

48. Reduce Example

Implement join using reduce.

ruby

def join_strings(arr, delimiter = ",")
  arr.reduce { |memo, str| "#{memo}#{delimiter}#{str}" }
end

49. Find Duplicate Elements in Array

Return elements that appear more than once.

ruby

def duplicates(arr)
  arr.select { |e| arr.count(e) > 1 }.uniq
end

50. First Non‑Repeating Character in String

ruby

def first_non_repeating(str)
  freq = str.each_char.tally
  str.each_char.find { |c| freq[c] == 1 }
end

51. Validate Email (simple)

With regex.

ruby

def valid_email?(email)
  !!(email =~ /\A[\w+\-.]+@[a-z\d\-]+(\.[a-z\d\-]+)*\.[a-z]+\z/i)
end

52. Extract All Numbers from a String

Return an array of integers.

ruby

def extract_numbers(str)
  str.scan(/\d+/).map(&:to_i)
end

53. Replace Spaces with %20

URL‑encode a string (simple version).

ruby

def urlify(str)
  str.gsub(" ", "%20")
end

54. Check Balanced Parentheses

(){}[] balanced.

ruby

def balanced?(str)
  stack = []
  pairs = { '(' => ')', '{' => '}', '[' => ']' }
  str.each_char do |c|
    if pairs.key?(c)
      stack.push(c)
    elsif pairs.value?(c)
      return false if stack.empty? || pairs[stack.pop] != c
    end
  end
  stack.empty?
end

55. Reverse Words in a Sentence

Keep word order, reverse each word.

ruby

def reverse_words(sentence)
  sentence.split.map(&:reverse).join(' ')
end

56. Title Case (Ignore Small Words)

A simple version that capitalizes all words regardless.

ruby

def title_case(str)
  str.split.map(&:capitalize).join(' ')
end

57. CamelCase to snake_case

ruby

def camel_to_snake(str)
  str.gsub(/([A-Z])/) { "_#{$1.downcase}" }.sub(/^_/, '')
end

58. snake_case to CamelCase

ruby

def snake_to_camel(str)
  str.split('_').map(&:capitalize).join
end

59. Random Number in Range (min..max)

Return a random integer inclusive.

ruby

def random_in_range(min, max)
  rand(min..max)
end

60. Shuffle a String

ruby

def shuffle_string(str)
  str.chars.shuffle.join
end

61. Class Person

With attributes nameage and method introduce.

ruby

class Person
  attr_accessor :name, :age
  def initialize(name, age)
    @name = name
    @age = age
  end
  def introduce
    "Hi, I'm #{name} and I'm #{age} years old."
  end
end

62. Inheritance

Employee < Person with additional salary.

ruby

class Employee < Person
  attr_accessor :salary
  def initialize(name, age, salary)
    super(name, age)
    @salary = salary
  end
  def introduce
    super + " I earn $#{salary}."
  end
end

63. Module Mixin

Define a Drivable module and include it in a Car class.

ruby

module Drivable
  def drive
    "Moving forward"
  end
end
class Car
  include Drivable
end

64. Module with Class Methods

Use extend to add class methods.

ruby

module Utility
  def greet
    "Hello"
  end
end
class Speaker
  extend Utility
end
puts Speaker.greet

65. Singleton Class

Add a class method dynamically.

ruby

class MyClass
end
instance = MyClass.new
def instance.unique_method
  "unique"
end

66. Method Missing

Implement a simple method_missing to print a message.

ruby

class Spy
  def method_missing(meth, *args, &block)
    puts "You called #{meth} with #{args.inspect}"
  end
end

67. Overriding to_s

ruby

class Book
  attr_accessor :title, :author
  def to_s
    "#{title} by #{author}"
  end
end

68. Comparable Mixin

Include Comparable and define <=> using age.

ruby

class Student
  include Comparable
  attr_reader :age
  def initialize(age)
    @age = age
  end
  def <=>(other)
    age <=> other.age
  end
end

69. Enumerable Integration

Include Enumerable and define each.

ruby

class Library
  include Enumerable
  def initialize
    @books = []
  end
  def add(book)
    @books << book
  end
  def each(&block)
    @books.each(&block)
  end
end

70. Struct

Create a simple data container.

ruby

Point = Struct.new(:x, :y)
p = Point.new(1, 2)

71. Blocks: Yield

Write a method that yields and passes a parameter.

ruby

def with_logging
  puts "Starting"
  result = yield
  puts "Finished"
  result
end

72. Block Given?

Check if a block is provided.

ruby

def optional_block
  if block_given?
    yield
  else
    "No block"
  end
end

73. Proc vs Lambda

Demonstrate the difference in return.

ruby

my_proc = Proc.new { return "proc return" }  # would jump out of method
my_lambda = -> { return "lambda return" }    # returns from lambda

74. Lambda as Hash Key

ruby

actions = {
  add: ->(a,b) { a + b },
  subtract: ->(a,b) { a - b }
}
actions[:add].call(5,3)

75. Map with Proc

ruby

double = Proc.new { |x| x * 2 }
[1,2,3].map(&double) # => [2,4,6]

76. File Read Entire

ruby

content = File.read("file.txt")

77. File Write

ruby

File.write("output.txt", "Hello Ruby")

78. Read Lines with Each

ruby

File.foreach("data.txt") { |line| puts line }

79. CSV Reading

ruby

require 'csv'
CSV.foreach("data.csv", headers: true) do |row|
  puts row['Name']
end

80. Exception Handling

ruby

def safe_divide(a, b)
  a / b
rescue ZeroDivisionError => e
  puts e.message
  0
end

81. Custom Exception

ruby

class NegativeNumberError < StandardError; end
def sqrt_positive(x)
  raise NegativeNumberError, "Negative!" if x < 0
  Math.sqrt(x)
end

82. Begin/Rescue/Ensure

ruby

begin
  File.open("example.txt") do |f|
    # file ops
  end
rescue Errno::ENOENT
  puts "File not found"
ensure
  puts "Cleanup"
end

83. Retry in Rescue

ruby

attempts = 0
begin
  attempts += 1
  puts "attempt #{attempts}"
  raise "fail" if attempts < 3
rescue
  retry
end

84. Metaprogramming: send

Call a method by name.

ruby

obj = "hello"
obj.send(:upcase) # "HELLO"

85. Dynamic Method Definition

ruby

class Person
  def initialize
    @attributes = {}
  end
  def define_attr(name)
    self.class.send(:define_method, name) { @attributes[name] }
    self.class.send(:define_method, "#{name}=") { |val| @attributes[name] = val }
  end
end

86. Singletons

ruby

require 'singleton'
class AppConfig
  include Singleton
  attr_accessor :data
end

87. Memoization

Cache expensive computation.

ruby

def expensive_result
  @result ||= compute_something
end

88. Keyword Arguments and Defaults

ruby

def create_user(name:, age: 18, admin: false)
  { name: name, age: age, admin: admin }
end

89. Splat Operator

ruby

def sum_all(*nums)
  nums.sum
end

90. Array Destructuring

ruby

first, *rest = [1, 2, 3, 4]
# first=1, rest=[2,3,4]

91. Enumerable Lazy for Infinite Sequence

Generate first 5 even squares from an infinite list.

ruby

(1..Float::INFINITY).lazy.select(&:even?).map { |n| n * n }.first(5)

92. Timed Execution

ruby

start = Time.now
# work
elapsed = Time.now - start

93. Simple Benchmark

ruby

require 'benchmark'
time = Benchmark.measure { 1000.times { "a" * 1000 } }
puts time

94. Random Array Element

ruby

arr.sample

95. Integer Palindrome

Check if a number is a palindrome.

ruby

def palindrome_number?(num)
  num.to_s == num.to_s.reverse
end

96. Angle Between Clock Hands

Given hour and minute, approximate.

ruby

def clock_angle(hour, minute)
  hour_angle = (hour % 12) * 30 + minute * 0.5
  minute_angle = minute * 6
  (hour_angle - minute_angle).abs
end

97. Decimal to Binary String

ruby

def to_binary(num)
  num.to_s(2)
end

Also try it: 100 Python practice problems with solutions

8. Distance Between Two Points

ruby

def distance(x1, y1, x2, y2)
  Math.sqrt((x2 - x1)**2 + (y2 - y1)**2)
end

99. Remove Vowels

ruby

def remove_vowels(str)
  str.gsub(/[aeiou]/i, '')
end

100. Count Words in a File

ruby

def count_words_in_file(filename)
  File.read(filename).split.length
end

Final Thought

And that’s 100 Ruby problems — solved, line by line, with your own two hands.
No grand parade, just a quiet warm glow that says, “I’m really getting this.”

You’ve danced through blocks, tamed hashes, trusted enumerables, and written code that reads almost like a sentence. That’s the quiet magic of Ruby — it meets you halfway, and with practice, it starts feeling like a thoughtful friend rather than a tool.

Be proud in your own understated way. Every little def, every map and each, gently shaped your thinking into something cleaner, kinder, and more elegant. This confidence won’t shout — but it will sit calmly inside you the next time you open an editor.

Bookmark this page. Come back on rainy days when you just want to tinker. And if you ever wonder if you belong in this developer world — look at 100 problems finished and know, without a doubt, that you already do. Happy coding, soft heart and all.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top