breaking down the problem

One of my favourite programming problems on cyber-dojo is Print Diamond:
Given a letter print a diamond starting with 'A'
with the supplied letter at the widest point.

For example: print-diamond 'E' prints

    A
   B B
  C   C
 D     D
E       E
 D     D
  C   C
   B B
    A

For example: print-diamond 'C' prints

  A
 B B
C   C
 B B
  A
A lot of participants are surprised how tricky this simple looking exercise is. It's a good exercise to explore ways of working step by step. How would you break it down? I urge you to try the exercise now. On cyber-dojo naturally. Then come back here and read on.


How did you do it? Was your first test something like this (Ruby)
def test_diamond_B
  assert_equal [" A ",
                "B B",
                " A "], diamond('B')
end
Maybe then a bit of slime:
def diamond(widest)
  [" A ",
   "B B",
   " A "
  ]
end
What then? Perhaps observe that the slime is not using the widest parameter, so write another test for diamond('C'). What then? Slime that too? Then what?

What I find really interesting is something my friend Seb Rose pointed out to me recently - almost no participants try to create steps by breaking down the problem itself.
For example:
Step 1:
def test_only_letters
  assert_equal ["A"], diamond_letters('A')
  assert_equal ["A","B","A"], diamond_letters('B')
  assert_equal ["A","B","C","B","A"], diamond_letters('C')
end
Step 2:
def test_plus_cardinality
  assert_equal ["A"], diamond_cardindality('A')
  assert_equal ["A","BB","A"], diamond_cardindality('B')
  assert_equal ["A","BB","CC","BB","A"], diamond_cardindality('C')
end
Step 3:
def test_plus_leading_space
  assert_equal ["A"], diamond_leading_space('A')
  assert_equal [" A",
                "BB",
                " A"], diamond_leading_space('B')
  assert_equal ["  A",
                " BB",
                "CC",
                " BB",
                "  A"], diamond_leading_space('C')
end
Step 4:
def test_plus_mid_space
  assert_equal ["A"], diamond('A')
  assert_equal [" A",
                "B B",
                " A"], diamond('B')
  assert_equal ["  A",
                " B B",
                "C   C",
                " B B",
                "  A"], diamond('C')
end
It's amazing how a tiny exercise like Print Diamond can so effectively mirror project scale Waterfall style development!

No comments:

Post a Comment