Recursion
• Spec FAQ Project Submit
The purpose of this assignment is to give you practice writing programs with recursion.
1.
2. Trinomial coefficients (brute force). Write a program TrinomialBrute.java that takes two integer command-line arguments n and k and computes the corresponding trinomial coefficient. The trinomial coefficient T(n,k)
T
(
n
,
k
)
is the coefficient of x
n+k
x
n
+
k
in the expansion of (1+x+x
2
)
n
(
1
+
x
+
x
2
)
n
. For example,
(1+x+x
2
)
3
=1+3x+6x
2
+7x
3
+6x
4
+3x
5
+x
6
(
1
+
x
+
x
2
)
3
=
1
+
3
x
+
6
x
2
+
7
x
3
+
6
x
4
+
3
x
5
+
x
6
Thus, T(3,3)=1
T
(
3
,
3
)
=
1
, T(3,2)=3
T
(
3
,
2
)
=
3
, T(3,1)=6
T
(
3
,
1
)
=
6
, and T(3,0)=7
T
(
3
,
0
)
=
7
.
Implement a recursive function trinomial() to compute T(n,k)
T
(
n
,
k
)
by using the following recurrence relation:
T(n,k)=⎧
⎩
⎨
⎪
⎪
1
0
T(n−1,k−1)+T(n−1,k)+T(n−1,k+1)
if n=0 and k=0
if k<−n or k>n
otherwise
T
(
n
,
k
)
=
{
3. 1
4. if n=0 and k=0
5. 0
6. if k<−n or k>n
7. T(n−1,k−1)+T(n−1,k)+T(n−1,k+1)
8. otherwise
9.
To do so, organize your program according to the following public API:
public class TrinomialBrute {
10.
11. // Returns the trinomial coefficient T(n, k).
12. public static long trinomial(int n, int k)
13.
14. // Takes two integer command-line arguments n and k and prints T(n, k).
15. public static void main(String[] args)
16. }
17.
As you will see, this approach is hopeless slow for moderately large values of n and k.
~/Desktop/recursion> java-introcs TrinomialBrute 3 3
18. 1
19.
20. ~/Desktop/recursion> java-introcs TrinomialBrute 3 2
21. 3
22.
23. ~/Desktop/recursion> java-introcs TrinomialBrute 3 1
24. 6
25.
26. ~/Desktop/recursion> java-introcs TrinomialBrute 3 0
27. 7
28.
29. ~/Desktop/recursion> java-introcs TrinomialBrute 24 12
30. 287134346
31.
32. ~/Desktop/recursion> java-introcs TrinomialBrute 30 0
33. [takes too long]
34.
Note: you may assume that n is a non-negative integer.
Trinomial coefficients arise in combinatorics. For example, T(n,k)
T
(
n
,
k
)
is the number of permutations of n symbols, each of which is −1
−
1
, 0
0
, or +1
+
1
, which sum to exactly k and T(n,k−n)
T
(
n
,
k
−
n
)
is the number of different ways of randomly drawing k cards from two identical decks of n playing cards.
35. Trinomial coefficients (dynamic programming). Write a program TrinomialDP.java that takes two integer command-line arguments n and k and computes the trinomial coefficient T(n,k)
T
(
n
,
k
)
using dynamic programming. To do so, organize your program according to the following public API: public class TrinomialDP {
36.
37. // Returns the trinomial coefficient T(n, k).
38. public static long trinomial(int n, int k)
39.
40. // Takes two integer command-line arguments n and k and prints T(n, k).
41. public static void main(String[] args)
42. }
43.
This version should be fast enough to handle larger values of n and k. ~/Desktop/recursion> java-introcs TrinomialDP 3 0
44. 7
45.
46. ~/Desktop/recursion> java-introcs TrinomialDP 24 12
47. 287134346
48.
49. ~/Desktop/recursion> java-introcs TrinomialDP 30 0
50. 18252025766941
51.
52. ~/Desktop/recursion> java-introcs TrinomialDP 40 0
53. 934837217271732457
54.
55.
56. Reve’s puzzle. Reve’s puzzle is identical to the towers of Hanoi problem, except that there are 4 poles (instead of 3). The task is to move n discs of different sizes from the starting pole to the destination pole, while obeying the following rules:
◦
◦ Move only one disc at a time.
◦ Never place a larger disc on a smaller one.
57. 
58. The following remarkable algorithm, discovered by Frame and Stewart in 1941, transfers n
n
discs from the starting pole to the destination pole using the fewest moves (although this fact was not proven until 2014).
◦
◦ Let k
k
denote the integer nearest to n+1−2n+1
‾
‾
‾
‾
‾
‾
√
n
+
1
−
2
n
+
1
.
◦ Transfer (recursively) the k smallest discs to a single pole other than the start or destination poles.
◦ Transfer the remaining n−k
n
−
k
disks to the destination pole (without using the pole that now contains the smallest k discs). To do so, use the algorithm for the 3-pole towers of Hanoi problem.
◦ Transfer (recursively) the k smallest discs to the destination pole.
59. Write a program RevesPuzzle.java that takes an integer command-line argument n and prints a solution to Reve’s puzzle. Assume that the the discs are labeled in increasing order of size from 1 to n and that the poles are labeled A, B, C, and D, with A representing the starting pole and D representing the destination pole. Here are a few sample executions:
~/Desktop/recursion> java-introcs RevesPuzzle 3
60. Move disc 1 from A to B
61. Move disc 2 from A to C
62. Move disc 3 from A to D
63. Move disc 2 from C to D
64. Move disc 1 from B to D
65.
66. ~/Desktop/recursion> java-introcs RevesPuzzle 4
67. Move disc 1 from A to D
68. Move disc 2 from A to B
69. Move disc 1 from D to B
70. Move disc 3 from A to C
71. Move disc 4 from A to D
72. Move disc 3 from C to D
73. Move disc 1 from B to A
74. Move disc 2 from B to D
75. Move disc 1 from A to D
76.
77. ~/Desktop/recursion> java-introcs RevesPuzzle 5
78. Move disc 1 from A to D
79. Move disc 2 from A to C
80. Move disc 3 from A to B
81. Move disc 2 from C to B
82. Move disc 1 from D to B
83. Move disc 4 from A to C
84. Move disc 5 from A to D
85. Move disc 4 from C to D
86. Move disc 1 from B to A
87. Move disc 2 from B to C
88. Move disc 3 from B to D
89. Move disc 2 from C to D
90. Move disc 1 from A to D
91.
Note: you may assume that n is a positive integer.
Recall that for the towers of Hanoi problem, the minimum number of moves for a 64-disc problem is 2
64
−1
2
64
−
1
. With the addition of a fourth pole, the minimum number of moves for a 64-disc problem is reduced to 18,433
18
,
433
.
92. Recursive squares. Write a program RecursiveSquares.java that takes an integer command-line argument n and plots a recursive square pattern of order n.
93. 
94. 
95. 
96. 
97. 
98. order 1
99. order 2
100. order 3
101. order 4
102. order 5
103.
To do so, organize your program according to the following public API: public class RecursiveSquares {
104.
105. // Draws a square centered on (x, y) of the given side length
106. // with a light gray background and a black border.
107. public static void drawSquare(double x, double y, double length)
108.
109. // Draws a recursive square pattern of order n, centered on (x, y)
110. // of the given side length.
111. public static void draw(int n, double x, double y, double length)
112.
113. // Takes an integer command-line argument n and draws a recursive
114. // square pattern of order n, centered on (0.5, 0.5) with side length 0.5.
115. public static void main(String[] args)
116. }
117.
The largest square is centered on the canvas and has side length 0.5. The side length of each square is one-half that of the next largest square. ~/Desktop/recursion> java-introcs RecursiveSquares 2
118.
119. 
120.
121.
122. ~/Desktop/recursion> java-introcs RecursiveSquares 4
123.
124. 
125.
Note: you may assume that n is a non-negative integer.
Submission. Submit a .zip file containing TrinomialBrute.java, TrinomialDP.java, RevesPuzzle.java, and RecursiveSquares.java. You may not call library functions except those in the java.lang (such as Integer.parseInt() and Math.sqrt()). Use only Java features that have already been introduced in the course (e.g., functions and recursion, but not objects).
This assignment was developed by Kevin Wayne.
Copyright © 2019.