New trail: Ruby Challenges

Guess who’s got a new trail to work on? That’d be you!

Meet the Ruby Challenges trail.

In this thread, a number of people mentioned that they thought the exercises were a bit too constrained, with most solutions looking the same.

This exercises in this trail are both harder and more open-ended. I expect to see people taking very different approaches. I’m looking forward to seeing how you do!

By the way, if you’re the first person to complete the trail there’s something in it for you.

1 Like

This topic is now a banner. It will appear at the top of every page until it is dismissed by the user.

This topic is no longer a banner. It will no longer appear at the top of every page.

I started this ruby challenge but I feel like I went about the wrong way to approach this. This is the first exercise to analyze Macbeth. So I used nokogiri gem to parse the xml.

@doc = Nokogiri::HTML(open("http://www.ibiblio.org/xml/examples/shakespeare/macbeth.xml"))

Then I took out all the speech and return them as array.
all_speeches = @doc.xpath("//speech").remove.to_a

From the array of arrays, I made an array of hashes for each speaker and their lines.count:
a = all_speeches.map{ |s| { s.css("speaker/text()").to_s => s.css("line").count } }

This is where I went to stackoverflow for help. I want to combine values of hashes with the same key.
Stackoverflow suggested:
cache = Hash.new { |h, k| h[k] = { k => 0 } }
puts a.flat_map(&:to_a).each_with_object(cache) { |(k,v),h| h[k][k] += v }.values

Those two lines did the trick, but I am having a hard time understanding what is going on. especially h[k][k] in the block. I know a new hash was created called cache, and it is passed into each_with_object(). I don’t know if this is the best way to go about solving this exercise. For me this is crazy ruby, haha. Any pointers will help. Thanks in advance!

I answered this in a new topic: Question about Analyzing Shakespeare

I’m a little stuck on the Ranking Poker Hands exercise.

I’ve got classes for Rank and Suit (I think this is the Value Object pattern?) which support ordering, and classes for Card (composed of a Rank and Suit), and Hand (a collection of Card objects).

I’ve got the specs passing for comparing different strengths against each other, e.g. straight vs a flush, and I’m using a separate class for each type of hand (Rule::Flush, Rule::Straight, etc.).

Now I need to implement the tie-breaking, but I’m unsure where that behaviour should go, or what the interface should look like.

Any tips?

@jferris went through this exercise. Any thoughts, Joe?

In my implementation, I had classes like yours for each type of hand (flush, straight, etc). They had a cards method which returned an array of cards used to form that hand.

I added a decorator, PlayWithSideCards, which had its own <=>. It would first delegate directly to the play, and then break ties by looking at the left over cards.

1 Like

I have a question about the first sudoku challenge on the ruby trail.

There is a test for invalid sudoku challenges, and since this came baked into the project files I don’t think we should alter it much. But how is the Validator class supposed to know, and why should it know, the name of the file? The expected error message from the Validator class is expected to give that, but all that is supplied to the Validator class is a string.

What am I missing?

EDIT: Ben replied to me and pointed out that there is no expectation of the kind I described; it is the error message that follows the failed expectation, not the expectation itself. my bad.

context "when the sudoku is invalid" do
    invalid_fixtures = ["spec/fixtures/invalid_due_to_row_dupe.sudoku",
                        "spec/fixtures/invalid_due_to_column_dupe.sudoku",
                        "spec/fixtures/invalid_due_to_subgroup_dupe.sudoku"]

    invalid_fixtures.each do |fixture|
      it "returns a string saying so" do
        result = Validator.validate(File.read(fixture))

        expect(result).to(
          eq("This sudoku is invalid."),
          "Expected #{fixture} to be invalid but it wasn't."
        )
      end
    end
  end