# Header
# Programmer: [Abrar saiyad]
# Title: pell.r
# Purpose: Calculate the first 200 Pell and Fibonacci numbers, compute sqrt(2) approximations,
#          differences from sqrt(2), and accuracy in decimal places, storing results in a dataframe.
# Date: October 2025



# 1. Initialize vectors for the sequences (200 terms, n = 0 to 199)
  n <- 0:199  # Index column
  fibonacci <- numeric(200)      # Fibonacci numbers
  pell <- numeric(200)           # Pell numbers
  sqrt2_approx <- numeric(200)   # Sqrt(2) approximations (P_n / P_{n-1})
  sqrt2_diff <- numeric(200)     # Difference from actual sqrt(2)
  accuracy <- numeric(200)       # Number of correct decimal places

  
  
# Set initial values for Fibonacci and Pell sequences
  fibonacci[1] <- 0     # F_0 = 0
  fibonacci[2] <- 1     # F_1 = 1
  pell[1] <- 0          # P_0 = 0
  pell[2] <- 1          # P_1 = 1

  
  
  
# 2. Loop to compute Fibonacci and Pell numbers for n = 2 to 199
  for (i in 3:200) {
                        # Fibonacci: F_n = F_{n-1} + F_{n-2}
    fibonacci[i] <- fibonacci[i-1] + fibonacci[i-2]
                        # Pell: P_n = 2 * P_{n-1} + P_{n-2}
    pell[i] <- 2 * pell[i-1] + pell[i-2]
  }

  
  
# 3. Loop to compute sqrt(2) approximation (P_n / P_{n-1}) for n = 1 to 199
# For n = 0, set approximation to NA (since P_0 = 0 causes division by zero)
  sqrt2_approx[1] <- NA        # No approximation for n = 0
    for (i in 2:200) {
    sqrt2_approx[i] <- pell[i] / pell[i-1]
  }

  
  
# 4. Loop to compute difference from actual sqrt(2), rounded to 5 decimal places
  actual_sqrt2 <- sqrt(2)     # R's sqrt() function for true sqrt(2)
  sqrt2_diff[1] <- NA         # No difference for n = 0
  for (i in 2:200) {
    sqrt2_diff[i] <- round(abs(sqrt2_approx[i] - actual_sqrt2), 5)
  }

  
  
# 5. Loop to compute accuracy (number of matching decimal places)
  accuracy[1] <- NA  # No accuracy for n = 0
  for (i in 2:200) {
     # Convert approximation and sqrt(2) to strings with high precision
        approx_str <- format(sqrt2_approx[i], nsmall = 10, scientific = FALSE)
        actual_str <- format(actual_sqrt2, nsmall = 10, scientific = FALSE)
  
     # Split into integer and decimal parts
        approx_parts <- strsplit(approx_str, "\\.")[[1]]
        actual_parts <- strsplit(actual_str, "\\.")[[1]]
  
     # Compare decimal parts character by character
        if (length(approx_parts) > 1 && length(actual_parts) > 1) {
        decimal_approx <- strsplit(approx_parts[2], "")[[1]]
        decimal_actual <- strsplit(actual_parts[2], "")[[1]]
    
     # Count matching digits
         matches <- 0
         for (j in 1:min(length(decimal_approx), length(decimal_actual))) {
            if (decimal_approx[j] == decimal_actual[j]) {
            matches <- matches + 1
          } else {
          break  # Stop at first mismatch
         }
        }
        accuracy[i] <- matches
      } else {
       accuracy[i] <- 0  # No matching decimal places if format fails
    }
  }

  
  
# 6. Create the pelldata dataframe
  pelldata <- data.frame(
    Index = n,
    Fibonacci = fibonacci,
    Pell = pell,
    Sqrt2_Approx = sqrt2_approx,
    Sqrt2_Diff = sqrt2_diff,
    Accuracy = accuracy
  )

  
  
# Display the first few rows for verification
  print(head(pelldata, 40))  
  
  