複雑な問題をより単純で短いサブパートに分割することは、常に良い考えです。この場合、次のように、最初に部分問題の解決策を書くことで、一般的な解決策を単純化できます。
- 最初に、文字列のリストを作成するプロシージャを作成します。ここで、文字列は
"*****"
or"****"
または ... または"*"
- 次に、
repeat
文字列と数値を指定して、その文字列を何度も繰り返すヘルパー プロシージャを作成します。たとえば、次の(repeat "*" 3)
ように返されます。"***"
最初の部分問題が 2 番目の部分問題でどのように表現されるかは簡単にわかります。これは宿題のように見えるので、ここで完全な解決策を求めるべきではありません。自分で答えにたどり着く方が便利です。一般的な考え方は次のとおりです。空欄を埋めてください。
(define (triangle n)
(cond [<???> <???>] ; if n is zero return the empty list: '()
[else ; otherwise
(cons <???> ; cons n repetitions of * (using `repeat`)
(triangle <???>))])) ; and advance the recursion
(define (repeat str n)
(cond [<???> <???>] ; if n is zero return the empty string: ""
[else ; otherwise
(string-append <???> ; append the given string
(repeat <???> <???>))])) ; and advance the recursion
注意深く見ると、両方の手順がまったく同じ構造を共有しています。変更点は、基本ケース (空のリストと空の文字列) で返される値と、部分的な回答 (cons
およびstring-append
) を結合するために使用される手順です。