Created
May 11, 2026 16:35
-
-
Save menjaraz/82eccc064f2cf801cd00926bf81897e6 to your computer and use it in GitHub Desktop.
Saturation Attack Simulation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| use std::error::Error; | |
| use std::fmt; | |
| /// Represents a defense system with interceptors. | |
| #[derive(Debug, Clone)] | |
| pub struct DefenseSystem { | |
| pub interceptors: usize, | |
| pub interceptor_success_rate: f64, | |
| } | |
| impl DefenseSystem { | |
| /// Creates a new defense system. | |
| /// | |
| /// # Arguments | |
| /// * `interceptors` - Number of interceptors. | |
| /// * `interceptor_success_rate` - Probability of a single interceptor destroying a missile (must be in [0.0, 1.0]). | |
| /// | |
| /// # Returns | |
| /// * `DefenseSystem` if inputs are valid, otherwise an error. | |
| pub fn new(interceptors: usize, interceptor_success_rate: f64) -> Result<Self, DefenseError> { | |
| if interceptor_success_rate < 0.0 || interceptor_success_rate > 1.0 { | |
| Err(DefenseError::InvalidProbability) | |
| } else { | |
| Ok(DefenseSystem { | |
| interceptors, | |
| interceptor_success_rate, | |
| }) | |
| } | |
| } | |
| /// Calculates the probability that at least one missile penetrates the defense. | |
| /// | |
| /// # Arguments | |
| /// * `missiles` - Number of missiles launched. | |
| /// | |
| /// # Returns | |
| /// * Probability of at least one penetration. | |
| pub fn penetration_probability(&self, missiles: usize) -> f64 { | |
| if missiles > self.interceptors { | |
| 1.0 // Saturation: M > N guarantees penetration | |
| } else { | |
| let (floor, remainder) = self.distribute_interceptors(missiles); | |
| let prob_all_intercepted = self.calculate_all_intercepted_prob(floor, remainder, missiles); | |
| 1.0 - prob_all_intercepted | |
| } | |
| } | |
| /// Distributes interceptors optimally across missiles. | |
| /// | |
| /// # Arguments | |
| /// * `missiles` - Number of missiles. | |
| /// | |
| /// # Returns | |
| /// * Tuple: (floor, remainder), where: | |
| /// - `floor` = minimum interceptors per missile. | |
| /// - `remainder` = number of missiles with an extra interceptor. | |
| fn distribute_interceptors(&self, missiles: usize) -> (usize, usize) { | |
| let floor = self.interceptors / missiles; | |
| let remainder = self.interceptors % missiles; | |
| (floor, remainder) | |
| } | |
| /// Calculates the probability that all missiles are intercepted. | |
| /// | |
| /// # Arguments | |
| /// * `floor` - Minimum interceptors per missile. | |
| /// * `remainder` - Number of missiles with an extra interceptor. | |
| /// * `missiles` - Total number of missiles. | |
| /// | |
| /// # Returns | |
| /// * Probability that all missiles are intercepted. | |
| fn calculate_all_intercepted_prob( | |
| &self, | |
| floor: usize, | |
| remainder: usize, | |
| missiles: usize, | |
| ) -> f64 { | |
| let mut prob_all_intercepted = 1.0; | |
| // Probability for missiles with floor + 1 interceptors | |
| if remainder > 0 { | |
| let intercept_prob = 1.0 - (1.0 - self.interceptor_success_rate).powi((floor + 1) as i32); | |
| prob_all_intercepted *= intercept_prob.powi(remainder as i32); | |
| } | |
| // Probability for missiles with floor interceptors | |
| if missiles > remainder { | |
| let intercept_prob = 1.0 - (1.0 - self.interceptor_success_rate).powi(floor as i32); | |
| prob_all_intercepted *= intercept_prob.powi((missiles - remainder) as i32); | |
| } | |
| prob_all_intercepted | |
| } | |
| } | |
| /// Custom error type for invalid inputs. | |
| #[derive(Debug, Clone, PartialEq)] | |
| pub enum DefenseError { | |
| InvalidProbability, | |
| } | |
| impl fmt::Display for DefenseError { | |
| fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | |
| match self { | |
| DefenseError::InvalidProbability => write!(f, "Probability must be between 0.0 and 1.0"), | |
| } | |
| } | |
| } | |
| impl Error for DefenseError {} | |
| /// Helper macro to print penetration probability with precise formatting. | |
| macro_rules! print_penetration_prob { | |
| ($defense:expr, $missiles:expr) => { | |
| let prob = $defense.penetration_probability($missiles); | |
| println!( | |
| "Missiles (M) = {:<3} | Interceptors (N) = {:<3} | Success Rate (p) = {:<4.2} | Penetration Probability = {:<.6}", | |
| $missiles, | |
| $defense.interceptors, | |
| $defense.interceptor_success_rate, | |
| prob | |
| ); | |
| }; | |
| } | |
| #[cfg(test)] | |
| mod tests { | |
| use super::*; | |
| #[test] | |
| fn test_saturation_attack() { | |
| // Example 1: M = 10, N = 8, p = 0.7 | |
| let defense = DefenseSystem::new(8, 0.7).unwrap(); | |
| assert_eq!(defense.penetration_probability(10), 1.0); | |
| // Example 2: M = 5, N = 10, p = 0.8 | |
| let defense = DefenseSystem::new(10, 0.8).unwrap(); | |
| assert!((defense.penetration_probability(5) - 0.1846).abs() < 0.0001); | |
| // Example 3: M = 3, N = 5, p = 0.9 | |
| let defense = DefenseSystem::new(5, 0.9).unwrap(); | |
| assert!((defense.penetration_probability(3) - 0.1198).abs() < 0.0001); | |
| } | |
| #[test] | |
| fn test_invalid_probability() { | |
| assert!(DefenseSystem::new(5, -0.1).is_err()); | |
| assert!(DefenseSystem::new(5, 1.1).is_err()); | |
| } | |
| } | |
| fn main() { | |
| println!("=== Saturation Attack Simulation ==="); | |
| println!("------------------------------------"); | |
| // Example 1: M = 10, N = 8, p = 0.7 | |
| let defense1 = DefenseSystem::new(8, 0.7).unwrap(); | |
| print_penetration_prob!(defense1, 10); | |
| // Example 2: M = 5, N = 10, p = 0.8 | |
| let defense2 = DefenseSystem::new(10, 0.8).unwrap(); | |
| print_penetration_prob!(defense2, 5); | |
| // Example 3: M = 3, N = 5, p = 0.9 | |
| let defense3 = DefenseSystem::new(5, 0.9).unwrap(); | |
| print_penetration_prob!(defense3, 3); | |
| println!("------------------------------------"); | |
| println!("End of Simulation."); | |
| } |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
The “mathematics of saturation” is not really about perfect destruction.
It is about:
Many analysts now describe this as:
In modern missile warfare, quantity itself becomes a weapon.