aboutsummaryrefslogtreecommitdiff
path: root/challenge-133/iangoodnight/ruby
diff options
context:
space:
mode:
authorIan Goodnight <goodnight.ian@gmail.com>2021-10-09 14:55:44 -0400
committerIan Goodnight <goodnight.ian@gmail.com>2021-10-09 14:55:44 -0400
commitc0428c3468203840d5cd0948d298fa86a72f1c9c (patch)
treec1b13cc2490ebf075763b5730b97f752a945445e /challenge-133/iangoodnight/ruby
parent7e31b242f4012d100b2949c29f00a3597a9bb80f (diff)
downloadperlweeklychallenge-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.md146
-rwxr-xr-xchallenge-133/iangoodnight/ruby/ch-1.rb79
-rwxr-xr-xchallenge-133/iangoodnight/ruby/ch-2.rb81
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)