diff options
| author | Ian Goodnight <goodnight.ian@gmail.com> | 2021-10-09 14:55:44 -0400 |
|---|---|---|
| committer | Ian Goodnight <goodnight.ian@gmail.com> | 2021-10-09 14:55:44 -0400 |
| commit | c0428c3468203840d5cd0948d298fa86a72f1c9c (patch) | |
| tree | c1b13cc2490ebf075763b5730b97f752a945445e /challenge-133/iangoodnight/ruby | |
| parent | 7e31b242f4012d100b2949c29f00a3597a9bb80f (diff) | |
| download | perlweeklychallenge-club-c0428c3468203840d5cd0948d298fa86a72f1c9c.tar.gz perlweeklychallenge-club-c0428c3468203840d5cd0948d298fa86a72f1c9c.tar.bz2 perlweeklychallenge-club-c0428c3468203840d5cd0948d298fa86a72f1c9c.zip | |
solutions 133
Diffstat (limited to 'challenge-133/iangoodnight/ruby')
| -rw-r--r-- | challenge-133/iangoodnight/ruby/README.md | 146 | ||||
| -rwxr-xr-x | challenge-133/iangoodnight/ruby/ch-1.rb | 79 | ||||
| -rwxr-xr-x | challenge-133/iangoodnight/ruby/ch-2.rb | 81 |
3 files changed, 306 insertions, 0 deletions
diff --git a/challenge-133/iangoodnight/ruby/README.md b/challenge-133/iangoodnight/ruby/README.md new file mode 100644 index 0000000000..8854a2dfb4 --- /dev/null +++ b/challenge-133/iangoodnight/ruby/README.md @@ -0,0 +1,146 @@ +# [Perl Weekly Challenge - 133] _Ruby Edition_ + +This is my first crack at a Ruby submission for the PWC. I'm still pretty new +to the language, and porting my Perl to Ruby is a fun way to explore the syntax. + +## Task 1 > Integer Square Root + +You are given a positive integer `$N`. + +Write a script to calculate the integer square root of the given number. + +Please avoid using built-in function. Find out more about it [here]. + +**Examples** + +``` +Input: $N = 10 +Output: 3 + +Input: $N = 27 +Output: 5 + +Input: $N = 85 +Output: 9 + +Input: $N = 101 +Output: 10 +``` + +### Solution + +This is pretty much a direct translation of my Perl solution, so it may be that +I am missing some opportunities here. + +```ruby + +def int_sqr_root(input) + if !input.integer? || !input.positive? + puts 'Input must be a positive integer' + return + end + # Crawl through squares starting with 0 + i = 0 + (i += 1) while i * i <= input + # Return the highest passing number + i -= 1 +end + +``` + +#### `ch-1.rb` + +Running `./ch-1.rb` initiates a mini REPL. The REPL prompts for input and +returns the integer square root. Sample output is shown below: + +``` +$> ./ch-1.rb + +============================== +Integer Square Root Calculator +============================== + +Enter a positive integer (or, type "exit" to quit)> 10 +Integer square root: 3 +Try again? (y/n)> y +Enter a positive integer (or, type "exit" to quit)> 27 +Integer square root: 5 +Try again? (y/n)> 85 +Integer square root: 9 +Try again? (y/n)> y +Enter a positive integer (or, type "exit" to quit)> 101 +Integer square root: 10 +Try again? (y/n)> n +Goodbye. + +``` + +## Task 2 > Smith Number + +Write a script to generate the first 10 `Smith Numbers` in base 10. + +According to Wikipedia: + +> In number theory, a Smith number is a composite number for which, in a given +> number base, the sum of its digits is equal to the sum of the digits in its +> prime factorization in the given number base. + +### Solution + +```ruby + +# First, a utility method to find and return our prime factors +def prime_factors(number) + factors = [] + while number >= 2 # Starting with 2, divide and check modulo + if (number % divisor ||= 2).zero? # If modulo is zero, push to `factors` + factors.push(divisor) + number /= divisor + else + divisor += 1 # Else, increment divisor and try again + end + end + factors +end + +# Helper method to reduce number to sum of it digits +def sum_digits(number) + number.to_s.split(//).map(&:to_i).inject(0, :+) +end + +# Method to reduce our primes to the sum of their digits +def sum_primes(primes) + primes.reduce(0) { |sum, prime| sum + sum_digits(prime) } +end + +# Find `Smith Numbers` with our methods, `prime_factors`, `sum_digits`, +# `sum_primes` +def find_smith_numbers(limit: 10) + smith_numbers = [] + test = 4 + while smith_numbers.length < limit.to_i + primes = prime_factors(test) + prime_sum = sum_primes(primes) + digit_sum = sum_digits(test) + smith_numbers.push(test) if prime_sum == digit_sum && primes.length > 1 + test += 1 + end + smith_numbers +end + +``` + +#### `ch-2.rb` + +Running `./ch-2.rb` outputs the first 10 `Smith Numbers`. Optionally, a number +argument can be provided to output an arbitrary number of `Smith Numbers` (i.e, +`./ch-2 27` print out the first 27 `Smith Numbers`). Sample output is shown +below: + +``` +$> ./ch-2.rb 10 +The first 10 Smith Number(s) are 4, 22, 27, 58, 85, 94, 121, 166, 202, and 265. +``` + +[Perl Weekly Challenge - 133]: https://theweeklychallenge.org/blog/perl-weekly-challenge-133/ +[here]: https://en.wikipedia.org/wiki/Integer_square_root diff --git a/challenge-133/iangoodnight/ruby/ch-1.rb b/challenge-133/iangoodnight/ruby/ch-1.rb new file mode 100755 index 0000000000..8cbf10b8da --- /dev/null +++ b/challenge-133/iangoodnight/ruby/ch-1.rb @@ -0,0 +1,79 @@ +#!/usr/bin/ruby -w +# frozen_string_literal: false + +# ch-1.rb + +# https://theweeklychallenge.org/blog/perl-weekly-challenge-133/ +# +# Task 1 > Integer Square Root +# ============================ +# +# You are given a positive integer `$N`. +# +# Write a script to calculate the integer square root of the given number. +# +# Please avoid using built-in function. Find out more about it here +# (https://en.wikipedia.org/wiki/Integer_square_root). +# +# Examples +# -------- +# +# Input: $N = 10 +# Output: 3 +# +# Input: $N = 27 +# Output: 5 +# +# Input: $N = 85 +# Output: 9 +# +# Input: $N = 101 +# Output: 10 + +################################################################################ +# Our PWC Solution +################################################################################ + +def int_sqr_root(input) + if !input.integer? || !input.positive? + puts 'Input must be a positive integer' + return + end + # Crawl through squares starting with 0 + i = 0 + (i += 1) while i * i <= input + # Return the highest passing number + i - 1 +end + +################################################################################ +# REPL +################################################################################ + +def print_banner + message = 'Integer Square Root Calculator' + outline = '=' * message.length + puts "\e[36m\n#{outline}\n#{message}\n#{outline}\n\e[0m" +end + +prompt = "Enter a positive integer (or, type \"\e[33mexit\e[0m\" to quit)> " +check_continue = "Try again? (\e[33my\e[0m/\e[33mn\e[0m)> " + +print_banner +print prompt + +loop do + input = gets.chomp + input.strip! + case input + when /\A\d+\z/ + puts "Integer square root: #{int_sqr_root(input.to_i)}" + print check_continue + when /\Ay\z/ + print prompt + when /\A(exit|n)\z/ + puts 'Goodbye.' + exit + else puts 'Arguments must be positive integers only.' + end +end diff --git a/challenge-133/iangoodnight/ruby/ch-2.rb b/challenge-133/iangoodnight/ruby/ch-2.rb new file mode 100755 index 0000000000..f10aeda49b --- /dev/null +++ b/challenge-133/iangoodnight/ruby/ch-2.rb @@ -0,0 +1,81 @@ +#!/usr/bin/ruby -w +# frozen_string_literal: false + +# ch-2.rb + +# https://theweeklychallenge.org/blog/perl-weekly-challenge-133/ +# +# Task 2 > Smith Numbers +# ====================== +# +# Write a script to generate the first 10 `Smith Numbers` in base 10. +# +# According to Wikipedia: +# +# > In number theory, a Smith number is a composite number for which, in a given +# > number base, the sum of its digits is equal to the sum of the digits in its +# > prime factorization in the given number base. + +################################################################################ +# Our PWC Solution +################################################################################ + +# First, a utility method to find and return our prime factors +def prime_factors(number) + factors = [] + while number >= 2 # Starting with 2, divide and check modulo + if (number % divisor ||= 2).zero? # If modulo is zero, push to `factors` + factors.push(divisor) + number /= divisor + else + divisor += 1 # Else, increment divisor and try again + end + end + factors +end + +# Helper method to reduce number to sum of it digits +def sum_digits(number) + number.to_s.split(//).map(&:to_i).inject(0, :+) +end + +# Method to reduce our primes to the sum of their digits +def sum_primes(primes) + primes.reduce(0) { |sum, prime| sum + sum_digits(prime) } +end + +# Find `Smith Numbers` with our methods, `prime_factors`, `sum_digits`, +# `sum_primes` +def find_smith_numbers(limit) + smith_numbers = [] + test = 4 + while smith_numbers.length < limit.to_i + primes = prime_factors(test) + prime_sum = sum_primes(primes) + digit_sum = sum_digits(test) + smith_numbers.push(test) if prime_sum == digit_sum && primes.length > 1 + test += 1 + end + smith_numbers +end + +################################################################################ +# Utilities +################################################################################ + +def list_with_oxford(list) + last = list.pop + list.join(', ') + ', and ' + last.to_s +end + +################################################################################ +# Main +################################################################################ + +def main(limit) + smith_numbers = find_smith_numbers(limit.to_i) + result_str = list_with_oxford(smith_numbers) + puts "The first #{limit} Smith Number(s) are #{result_str}." +end + +main(ARGV.shift || 10) |
