# pell.r
# Task 1 – Pell numbers and approximation to sqrt(2)

# 1. Generate first 200 Pell and Fibonacci numbers ----------------------

# Number of terms
n_terms <- 200

# Generate Pell numbers
pell <- numeric(n_terms)
pell[1] <- 0
pell[2] <- 1
for (i in 3:n_terms) {
  pell[i] <- 2 * pell[i - 1] + pell[i - 2]
}

# Generate Fibonacci numbers
fib <- numeric(n_terms)
fib[1] <- 0
fib[2] <- 1
for (i in 3:n_terms) {
  fib[i] <- fib[i - 1] + fib[i - 2]
}

# Create dataframe
pelldata <- data.frame(
  n = 0:(n_terms - 1),
  Fibonacci = fib,
  Pell = pell
)

# 2. Calculate nth approximation to sqrt(2) ----------------------------
# Formula: (P_{n-1} + P_n) / P_n

approx_sqrt2 <- numeric(n_terms)
approx_sqrt2[1] <- NA  # undefined for n = 0
for (i in 2:n_terms) {
  approx_sqrt2[i] <- (pell[i - 1] + pell[i]) / pell[i]
}

pelldata$Approximation <- approx_sqrt2

# 3. Difference from true sqrt(2) -------------------------------------

true_sqrt2 <- sqrt(2)
difference <- abs(pelldata$Approximation - true_sqrt2)
difference <- round(difference, 5)
pelldata$Difference <- difference

# 4. Accuracy (number of matching decimal places) ----------------------

# Function to count matching decimal digits
count_matching_decimals <- function(x, true_value) {
  if (is.na(x)) return(NA)
  # Format to 15 decimal places for comparison
  x_str <- sprintf("%.15f", x)
  true_str <- sprintf("%.15f", true_value)
  
  # Compare character by character after decimal point
  dec_x <- strsplit(strsplit(x_str, "\\.")[[1]][2], "")[[1]]
  dec_true <- strsplit(strsplit(true_str, "\\.")[[1]][2], "")[[1]]
  
  matches <- 0
  for (i in seq_along(dec_x)) {
    if (dec_x[i] == dec_true[i]) {
      matches <- matches + 1
    } else {
      break
    }
  }
  return(matches)
}

accuracy <- sapply(pelldata$Approximation, count_matching_decimals, true_value = true_sqrt2)
pelldata$Accuracy <- accuracy

# View final dataframe --------------------------------------------------
print(head(pelldata, 25))

# Optionally save to CSV
write.csv(pelldata, "pelldata.csv", row.names = FALSE)

