Skip to content

Commit 05f442d

Browse files
authored
Feat : Pascal's_Traingle (#255)
1 parent 4ed293c commit 05f442d

File tree

1 file changed

+328
-0
lines changed

1 file changed

+328
-0
lines changed

mathematics/pascal_triangle.r

Lines changed: 328 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,328 @@
1+
# pascal_triangle.r
2+
# Script for generating and working with Pascal's Triangle.
3+
# Provides:
4+
# - pascal_triangle(n): Returns a list of n rows of Pascal's Triangle (input: integer n > 0; output: list of numeric vectors).
5+
# - pascal_row(n): Returns the nth row as a numeric vector (input: integer n >= 0; output: numeric vector).
6+
# - pascal_element(n, k): Returns the binomial coefficient C(n, k) (inputs: integers n >= 0, 0 <= k <= n; output: numeric value).
7+
# - print_pascal_triangle(n, centered=TRUE): Prints the triangle formatted (input: integer n > 0, logical centered; output: printed output).
8+
# No external dependencies.
9+
10+
#' Generate Pascal's Triangle up to n rows
11+
#' @param n Number of rows
12+
#' @return List of rows, each containing the triangle values
13+
pascal_triangle <- function(n) {
14+
if (n <= 0) {
15+
stop("Number of rows must be positive")
16+
}
17+
18+
triangle <- list()
19+
20+
for (i in 1:n) {
21+
row <- numeric(i)
22+
row[1] <- 1
23+
row[i] <- 1
24+
25+
if (i > 2) {
26+
for (j in 2:(i-1)) {
27+
row[j] <- triangle[[i-1]][j-1] + triangle[[i-1]][j]
28+
}
29+
}
30+
31+
triangle[[i]] <- row
32+
}
33+
34+
return(triangle)
35+
}
36+
37+
#' Generate single row of Pascal's Triangle
38+
#' @param n Row number (0-indexed)
39+
#' @return Vector containing the nth row
40+
pascal_row <- function(n) {
41+
if (n < 0) {
42+
stop("Row number must be non-negative")
43+
}
44+
45+
row <- numeric(n + 1)
46+
row[1] <- 1
47+
48+
for (i in 1:n) {
49+
row[i + 1] <- row[i] * (n - i + 1) / i
50+
}
51+
52+
return(row)
53+
}
54+
55+
#' Get specific element from Pascal's Triangle
56+
#' @param n Row number (0-indexed)
57+
#' @param k Column number (0-indexed)
58+
#' @return Value at position (n, k) - binomial coefficient C(n, k)
59+
pascal_element <- function(n, k) {
60+
if (n < 0 || k < 0) {
61+
stop("Row and column numbers must be non-negative")
62+
}
63+
if (k > n) {
64+
return(0)
65+
}
66+
67+
# Use symmetry: C(n, k) = C(n, n-k)
68+
if (k > n - k) {
69+
k <- n - k
70+
}
71+
72+
result <- 1
73+
for (i in seq_len(k)) {
74+
result <- result * (n - i + 1) / i
75+
}
76+
77+
return(result)
78+
}
79+
80+
#' Print Pascal's Triangle in formatted style
81+
#' @param n Number of rows
82+
#' @param centered Whether to center the triangle (default: TRUE)
83+
print_pascal_triangle <- function(n, centered = TRUE) {
84+
triangle <- pascal_triangle(n)
85+
86+
if (centered) {
87+
# Calculate maximum width for centering
88+
max_row <- triangle[[n]]
89+
max_width <- sum(nchar(as.character(max_row))) + length(max_row) - 1
90+
91+
for (i in 1:n) {
92+
row <- triangle[[i]]
93+
row_str <- paste(row, collapse = " ")
94+
row_width <- nchar(row_str)
95+
padding <- (max_width - row_width) / 2
96+
97+
cat(rep(" ", floor(padding)), row_str, "\n", sep = "")
98+
}
99+
} else {
100+
for (i in 1:n) {
101+
cat(paste(triangle[[i]], collapse = " "), "\n")
102+
}
103+
}
104+
}
105+
106+
#' Get diagonal sums from Pascal's Triangle
107+
#' @param n Number of rows
108+
#' @return Vector of diagonal sums (Fibonacci sequence)
109+
pascal_diagonal_sums <- function(n) {
110+
triangle <- pascal_triangle(n)
111+
sums <- numeric(n)
112+
113+
for (i in 1:n) {
114+
diagonal_sum <- 0
115+
row <- i
116+
col <- 1
117+
118+
while (row >= 1 && col <= length(triangle[[row]])) {
119+
diagonal_sum <- diagonal_sum + triangle[[row]][col]
120+
row <- row - 1
121+
col <- col + 1
122+
}
123+
124+
sums[i] <- diagonal_sum
125+
}
126+
127+
return(sums)
128+
}
129+
130+
#' Get row sum of Pascal's Triangle
131+
#' @param n Row number (0-indexed)
132+
#' @return Sum of row n (equals 2^n)
133+
pascal_row_sum <- function(n) {
134+
if (n < 0) {
135+
stop("Row number must be non-negative")
136+
}
137+
return(2^n)
138+
stop("Number of rows must be positive")
139+
140+
#' Get all row sums up to n rows
141+
#' @param n Number of rows
142+
#' @return Vector of row sums
143+
pascal_all_row_sums <- function(n) {
144+
if (n <= 0) {
145+
return(numeric(0))
146+
}
147+
return(2^(0:(n-1)))
148+
}
149+
150+
#' Generate Pascal's Triangle as matrix (padded with zeros)
151+
#' @param n Number of rows
152+
#' @return Matrix representation of Pascal's Triangle
153+
pascal_triangle_matrix <- function(n) {
154+
triangle <- pascal_triangle(n)
155+
mat <- matrix(0, nrow = n, ncol = n)
156+
157+
for (i in 1:n) {
158+
for (j in 1:length(triangle[[i]])) {
159+
mat[i, j] <- triangle[[i]][j]
160+
}
161+
}
162+
163+
return(mat)
164+
}
165+
166+
#' Get odd numbers pattern in Pascal's Triangle (Sierpinski pattern)
167+
#' @param n Number of rows
168+
#' @return Matrix with 1 for odd, 0 for even
169+
pascal_odd_pattern <- function(n) {
170+
triangle <- pascal_triangle(n)
171+
mat <- matrix(0, nrow = n, ncol = n)
172+
173+
for (i in 1:n) {
174+
for (j in 1:length(triangle[[i]])) {
175+
mat[i, j] <- triangle[[i]][j] %% 2
176+
}
177+
}
178+
179+
return(mat)
180+
}
181+
182+
# Examples
183+
if (FALSE) {
184+
# Example 1: Generate and print Pascal's Triangle
185+
cat("Example 1: Pascal's Triangle (10 rows)\n")
186+
cat("======================================\n\n")
187+
print_pascal_triangle(10)
188+
189+
# Example 2: Generate specific row
190+
cat("\nExample 2: Row 7 of Pascal's Triangle\n")
191+
cat("======================================\n")
192+
cat(sprintf("C(10, 3) = %.0f\n", pascal_element(10, 3)))
193+
cat(sprintf("C(8, 4) = %.0f\n", pascal_element(8, 4)))
194+
cat(sprintf("C(6, 2) = %.0f\n", pascal_element(6, 2)))
195+
196+
# Example 3: Get specific element
197+
cat("\nExample 3: Specific Elements\n")
198+
cat("============================\n")
199+
cat(sprintf("C(10, 3) = %d\n", pascal_element(10, 3)))
200+
cat(sprintf("C(8, 4) = %d\n", pascal_element(8, 4)))
201+
cat(sprintf("C(6, 2) = %d\n", pascal_element(6, 2)))
202+
203+
# Example 4: Row sums (powers of 2)
204+
cat("\nExample 4: Row Sums\n")
205+
cat("===================\n")
206+
sums <- pascal_all_row_sums(8)
207+
for (i in 1:8) {
208+
cat(sprintf("Row %d sum: %d = 2^%d\n", i-1, sums[i], i-1))
209+
}
210+
211+
# Example 5: Diagonal sums (Fibonacci sequence)
212+
cat("\nExample 5: Diagonal Sums (Fibonacci Sequence)\n")
213+
cat("=============================================\n")
214+
diag_sums <- pascal_diagonal_sums(12)
215+
cat("Diagonal sums:", paste(diag_sums, collapse = ", "), "\n")
216+
cat("This is the Fibonacci sequence!\n")
217+
218+
# Example 6: Pascal's Triangle as matrix
219+
cat("\nExample 6: Pascal's Triangle as Matrix\n")
220+
cat("======================================\n")
221+
mat <- pascal_triangle_matrix(8)
222+
print(mat)
223+
224+
# Example 7: Odd/Even pattern (Sierpinski Triangle)
225+
cat("\nExample 7: Odd Numbers Pattern (Sierpinski Triangle)\n")
226+
cat("===================================================\n")
227+
odd_pattern <- pascal_odd_pattern(16)
228+
229+
for (i in 1:16) {
230+
# Center the pattern
231+
padding <- 16 - i
232+
cat(rep(" ", padding))
233+
for (j in 1:i) {
234+
if (odd_pattern[i, j] == 1) {
235+
cat("* ")
236+
} else {
237+
cat(" ")
238+
}
239+
}
240+
cat("\n")
241+
}
242+
243+
# Example 8: Properties of Pascal's Triangle
244+
cat("\nExample 8: Properties of Pascal's Triangle\n")
245+
cat("==========================================\n")
246+
247+
n <- 10
248+
triangle <- pascal_triangle(n)
249+
250+
cat("\n1. Symmetry Property:\n")
251+
cat("Row 6:", paste(triangle[[7]], collapse = " "), "\n")
252+
cat("(Each row is symmetric)\n")
253+
254+
cat("\n2. Sum of row n = 2^n:\n")
255+
for (i in 1:5) {
256+
row_sum <- sum(triangle[[i]])
257+
cat(sprintf("Row %d: sum = %d = 2^%d\n", i-1, row_sum, i-1))
258+
}
259+
260+
cat("\n3. Binomial Theorem:\n")
261+
cat("(a + b)^4 = ")
262+
row4 <- triangle[[5]]
263+
terms <- character(5)
264+
for (i in 1:5) {
265+
power_a <- 4 - (i - 1)
266+
power_b <- i - 1
267+
coef <- row4[i]
268+
269+
if (power_a == 0) {
270+
terms[i] <- sprintf("%db^%d", coef, power_b)
271+
} else if (power_b == 0) {
272+
terms[i] <- sprintf("%da^%d", coef, power_a)
273+
} else if (power_a == 1 && power_b == 1) {
274+
terms[i] <- sprintf("%dab", coef)
275+
} else if (power_a == 1) {
276+
terms[i] <- sprintf("%dab^%d", coef, power_b)
277+
} else if (power_b == 1) {
278+
terms[i] <- sprintf("%da^%db", coef, power_a)
279+
} else {
280+
terms[i] <- sprintf("%da^%db^%d", coef, power_a, power_b)
281+
}
282+
}
283+
cat(paste(terms, collapse = " + "), "\n")
284+
285+
cat("\n4. Hockey Stick Pattern:\n")
286+
cat("Sum of diagonal: 1 + 4 + 10 + 20 = 35 = C(7,3)\n")
287+
cat("Formula: C(n,r) + C(n+1,r) + ... + C(n+k,r) = C(n+k+1,r+1)\n")
288+
289+
cat("\n5. Catalan Numbers:\n")
290+
# Catalan numbers: C(2n, n)/(n+1) for n = 1..4
291+
catalan <- function(n) choose(2*n, n)/(n+1)
292+
n_vals <- 1:4
293+
cat("Catalan numbers for n=1..4:", paste(catalan(n_vals), collapse = ", "), "\n")
294+
295+
# Example 9: Application - Probability
296+
cat("\nExample 9: Application - Coin Flip Probability\n")
297+
cat("===============================================\n")
298+
cat("Flipping 5 coins, probability of exactly k heads:\n\n")
299+
row5 <- pascal_row(5)
300+
total <- sum(row5)
301+
302+
for (k in 0:5) {
303+
prob <- row5[k + 1] / total
304+
cat(sprintf("%d heads: %d/%d = %.4f (%.2f%%)\n",
305+
k, row5[k + 1], total, prob, prob * 100))
306+
}
307+
308+
# Example 10: Large row computation
309+
cat("Last 5 elements:", paste(row50[47:51], collapse = ", "), "\n")
310+
cat("==================================\n")
311+
cat("Row 50 (too large to display fully):\n")
312+
row50 <- pascal_row(50)
313+
cat("Number of elements:", length(row50), "\n")
314+
cat("First 5 elements:", paste(row50[1:5], collapse = ", "), "\n")
315+
cat("Middle element C(50,25):", format(row50[26], scientific = FALSE), "\n")
316+
cat("Last 5 elements:", paste(row50[46:51], collapse = ", "), "\n")
317+
318+
cat(sprintf("C(%d,%d) using Pascal's Triangle: %.0f\n", n, k, element))
319+
cat(sprintf("C(%d,%d) using factorials: %.0f\n", n, k, factorial_calc))
320+
cat("========================\n")
321+
n <- 10
322+
k <- 4
323+
element <- pascal_element(n, k)
324+
factorial_calc <- factorial(n) / (factorial(k) * factorial(n - k))
325+
cat(sprintf("C(%d,%d) using Pascal's Triangle: %d\n", n, k, element))
326+
cat(sprintf("C(%d,%d) using factorials: %d\n", n, k, factorial_calc))
327+
cat(sprintf("Match: %s\n", ifelse(element == factorial_calc, "", "")))
328+
}

0 commit comments

Comments
 (0)