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!