---
title: "exam"
author: "prexa ahir"
date: "2025-10-14"
output: html_document
---

```{r}


# pell.r

### Q1 – Compute first 200 Pell numbers and Fibonacci numbers

# Set number of terms (n_terms defines how many sequence entries we will compute)
n_terms <- 200

# n is the index vector: 0, 1, 2, ..., n_terms-1.
# This is purely for display and aligns each row with a sequence index.

n <- 0:(n_terms - 1)
# Pre-allocate numeric vectors for speed and clarity
fib <- numeric(n_terms) # Fibonacci sequence container
pell <- numeric(n_terms)

# Initial values (1-based R indexing)
# Fibonacci: F0 = 0, F1 = 1
fib[1] <- 0
fib[2] <- 1

# Pell: P0 = 0, P1 = 1 (standard Pell initialization)
pell[1] <- 0
pell[2] <- 1

# Generate both sequences using loops implementing recurrence relations:
# Fibonacci: F(n) = F(n-1) + F(n-2)
# Pell:     P(n) = 2*P(n-1) + P(n-2)
for (i in 3:n_terms) {
  fib[i] <- fib[i - 1] + fib[i - 2]
  pell[i] <- 2 * pell[i - 1] + pell[i - 2]
}

# Create dataframe to store and display results together
pelldata <- data.frame(
  n = n,
  Fibonacci = fib,
  Pell = pell
)
#quick view of rows
head(pelldata,10)
```

```{r}

### Q2 – Add the √2 approximation column (using Pell-based (x,y) sequences)

# The x and y sequences below generate integer solutions to x^2 - 2*y^2 = ±1.
# The ratio x[i]/y[i] gives rational approximations that converge to sqrt(2).
# We choose initial values (x0,x1) = (1,3) and (y0,y1) = (0,1) which are small integer solutions.

x <- numeric(n_terms)
y <- numeric(n_terms)

# Initial values (these correspond to small Pell-equation solutions)
x[1] <- 1   # x0
x[2] <- 3   # x1
y[1] <- 0   # y0
y[2] <- 1   # y1

# Generate x and y using same recurrence as Pell numbers
# This recurrence yields (x, y) pairs that satisfy x^2 - 2*y^2 = ±1
for (i in 3:n_terms) {
  # Comment: recurrence derived from Pell-equation solution propagation
  x[i] <- 2 * x[i - 1] + x[i - 2]
  y[i] <- 2 * y[i - 1] + y[i - 2]
}

# Compute approximation of sqrt(2) as x[i] / y[i].
# The first entry (i=1) will be NA because y[1] == 0 (division by zero)
approx_sqrt2 <- numeric(n_terms)
approx_sqrt2[1] <- NA
for (i in 2:n_terms) {
  approx_sqrt2[i] <-( x[i] + x[i-1]) / x[i] 
}

# Add to dataframe
pelldata$Approx_Sqrt2 <- approx_sqrt2
head(pelldata,10)
```

```{r}

### Q3 – Add the difference between approximation and true sqrt(2)

# true_val is the reference value computed with R's sqrt function

true_val <- sqrt(2)
# Compute absolute difference rounded to 5 decimals (for tidy display)
diff_sqrt2 <- numeric(n_terms)

for (i in 1:n_terms) {
  # Keep NA where approximation is NA to avoid misleading values
  diff_sqrt2[i] <- round(abs(pelldata$Approx_Sqrt2[i] - true_val), 5)
}

pelldata$Difference <- diff_sqrt2
head(pelldata,10)
```
```{r}

### Q4 – Calculate accuracy in decimal places (count matching decimals)

# We compare string representations to count how many decimal digits match

accuracy <- numeric(n_terms)

for (i in 1:n_terms) {
  if (is.na(pelldata$Approx_Sqrt2[i])) {
    # If approximation undefined, mark accuracy as 0
    accuracy[i] <- 0
  } else {
    # Create string forms with sufficient digits for comparison
    # format(..., digits = 15) gives a consistent significant-digit representation
    true_str <- format(true_val, digits = 15)
    approx_str <- format(pelldata$Approx_Sqrt2[i], digits = 15)
    
    # Count matching decimal characters after "1."
    match <- 0
    for (j in 3:nchar(true_str)) { # skip "1."
      if (substring(true_str, j, j) == substring(approx_str, j, j)) {
        match <- match + 1
      } else break
    }
    accuracy[i] <- match
  }
}

pelldata$Accuracy <- accuracy
head(pelldata,10)
```

