# Logical Reasoning and Problem Solving With Ruby-Kickstarter

For those of you who aren’t regular readers of my blog, aka everyone but my mum and dad, allow me to set the scene:

I have enrolled on the intensive computer programming bootcamp at the Makers Academy. Before starting the full-time, on-campus, course you complete 4 weeks of pre-course. In this 4 weeks you get a real feel of how coders go about problem solving while learning some of the basics of Ruby, git & command line.

On week two we are given the choice of working through one of two Ruby tutorials:

Chris Pines Book, Learn to Programme. Chapter 8–End (since we did up to 8 for the interview).

Josh Cheeks Ruby Kickstarter, Session 1–3

Reading the reviews I saw past students had said the Kickstarter was more challenging and had video tutorials, so I decided I would go with that one.

I am not going to lie, I found it very challenging. Having got stuck on many of the challenges throughout sessions 1, 2 and 3 I thought I would write a post on one I am still struggling on, to show how I worked through this problem and hopefully expose where I am still going wrong.

Cue Session 3:2.

The Challenge:

Given a nonnegative integer, return a hash whose keys are all the odd nonnegative integers up to it and each key’s value is an array containing all the even non negative integers up to it.

Examples:

`staircase 1 # => {1 => []}staircase 2 # => {1 => []}staircase 3 # => {1 => [], 3 => [2]}staircase 4 # => {1 => [], 3 => [2]}staircase 5 # => {1 => [], 3 => [2], 5 =>[2, 4]}`

My Solution

How I broke the problem down and tried to solve the challenge. The steps I took:

Breaking the challenge down into smaller more manageable pieces:

Step 1

Check out possible examples and theory which may help, using ruby documents on hashes, google and Josh Cheeks cheatsheets:

The information I decided may be useful:

`Hash.new { |this_hash, key| this_hash[key] = Array.new }hash = Hash[ *[ Array(‘a’..’j’) , Array(1..10) ].transpose.flatten ] # populatinghash # => {“a”=>1, “b”=>2, “c”=>3, “d”=>4, “e”=>5, “f”=>6, “g”=>7, “h”=>8, “i”=>9, “j”=>10}hash.values_at ‘j’ , ‘e’ , ‘i’ , :x # => [10, 5, 9, nil]`

Step 2

Breaking the problem down into sudo code:

`(nr_given)integer_hash = [*[Array(starting from 0 increment numbers which   are odd up to the nr_given) , Array(starting from 0 increment numbers which are odd up to the nr_given).transpose.flattern]]key array upto(nr_given)value array up_to(nr_given) next if (i %2) != 0#need to work out how to increment values and if up_to is method`

Step 3

Deciding which bit to tackle first:

Incrementing the arrays seems like a good place to start as I can isolate my code for that part and test it with irb.

This was my first attempt:

`Array(0..nr_given).map! {|x| puts x next if(x.even?)}`

Next attempt:

`Array(0..nr_given).map! {|x| if x.even? puts “x”}`

Then:

`Array(0..nr_given).map {|x| if x.even? puts “x”}`

When I ran this in the irb it returned nothing even when I input a number, 77, in place of nr_given.

So I tried:

`Array(0..nr_given).select do |x|  if x.even?end`

When I run these in irb I still get no output even when I put a number in ‘nr_given’. I thought it may be something wrong with the way I created a new array so I tried to fix that:

`a = *(1..77)`

and that worked.

Then I tried setting a to that array. Checking it was definitely set by typing in a again, then playing with the .select method.

`a.select { |x| return x if (x%2)==0 }`

I got the following error:

`unexpected returnfrom (irb):8:in `block in irb_binding’from (irb):8:in `select’from (irb):8`

I looked up the select method in Ruby docs and it states the following:

`[1,2,3,4,5].select { |num| num.even? } #=> [2, 4]`

I therefore changed my code to:

`#keys are:a = *(0..nr_given)a.select {|x| x.odd?}And tested it doing:a = *(0..77)a.select {|x| x.odd?}`

And it worked!! I changed it to a shorter version and checked that also worked:

`a = *(0..77).select {|x| x.odd?}`

Step 4

Joining these to the rest of the code to solve the whole challenge.

My first attempt to put these arrays into the rest of my code:

`def staircase(nr_given)integer_hash = [*[*(0..nr_given).select {|x| x.odd?} , *(0..nr_given).select {|x| x.even?}.transpose.flattern]]end`

This failed the rake test. I got the following error message from it:

`Failure/Error: expect(method :staircase).to beNameError:undefined method `staircase’ for class`

So I referred back to my notes on how to set a hash out :

`character_counts = Hash.new { |this_hash, key| this_hash[key] = 0 }character_counts[“a”] # => 0character_counts # => {“a”=>0}`

Looking at this I changed my code to:

`def staircase(nr_given)   return_hash = Hash.new   *(0..nr_given).select {|x| x.odd?}   return_hash[x] = *(0..nr_given).select {|x| x.even?}.transpose.flattern   end endreturn_hashend`

It failed the rake test so I decided the get rid of the part I didn’t feel was necessary ‘.transpose.flattern’.

`def staircase(nr_given)   return_hash = Hash.new   *(0..nr_given).select {|x| x.odd?}   return_hash[x] = *(0..nr_given).select {|x| x.even?}   end endreturn_hashend`

This was still failing on the line starting with ‘*’. So I changed this round a bit:

`def staircase(nr_given)   return_hash = Hash.new   (0..nr_given).to_a.select {|x| x.odd?}   return_hash[x] = (0..nr_given).to_a.select {|x| x.even?}  end endreturn_hashend`

I realised I was missing an if statement in the .select method:

`def staircase(nr_given)   return_hash = Hash.new   (0..nr_given).to_a.select {|x| if x.odd?}   return_hash[x] = (0..nr_given).to_a.select {|x| x.even?}  end endreturn_hashend`

I was getting an error because I had closed the statement off too early . The ‘}’ after the odd meant that it was not finishing off the if statement. It was not putting this newly created array into the return_hash[x] — the keys of the hash. This statement could not accept the x as I had closed off the select method too early. I was saying if x.odd? then not telling it what to do with x. So I changed it:

`def staircase(nr_given)   return_hash = Hash.new   (0..nr_given).to_a.select do |x|   if x.odd?   return_hash[x] = (0..nr_given).to_a.select {|x| x.even?}   end  endreturn_hashend`

I was now getting an error about the .select method. I noticed a few errors here, first I had forgotten to ask if the x was even then I had forgotten to tell it to return the value if it was. So:

`def staircase(nr_given)   return_hash = Hash.new  (0..nr_given).to_a.select do |x|  if x.odd?  return_hash[x] = (0..nr_given).to_a.select {|x| return x if   x.even?}  end endreturn_hashend`

This is still failing. If anyone reading this can see where I am going wrong I would love to hear from you.

For now, I am parking this to move onto the next challenge in the hope a fresh head will shed some light on the problem and I will magically stumble upon the solution.

(This was originally posted on my blog : http://lebrunblack.com/index.php/2017/07/15/ruby-challenges/)