The series of increasing prime numbers begins: 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, ...

The task applies a filter to the series returning groups of successive primes, (s'primes), that differ from the next by a given value or values.

Example 1: Specifying that the difference between s'primes be 2 leads to the groups:

(3, 5), (5, 7), (11, 13), (17, 19), (29, 31), ...

(Known as Twin primes or Prime pairs)

Example 2: Specifying more than one difference between s'primes leads to groups of size one greater than the number of differences. Differences of 2, 4 leads to the groups:

(5, 7, 11), (11, 13, 17), (17, 19, 23), (41, 43, 47), .... 

In the first group 7 is two more than 5 and 11 is four more than 7; as well as 5, 7, and 11 being successive primes.
Differences are checked in the order of the values given, (differences of 4, 2 would give different groups entirely).

Task

 In each case use a list of primes less than 1_000_000
 For the following Differences show the first and last group, as well as the number of groups found:
 Differences of 2.
 Differences of 1.
 Differences of 2, 2.
 Differences of 2, 4.
 Differences of 4, 2.
 Differences of 6, 4, 2.
 Show output here.

Note: Generation of a list of primes is a secondary aspect of the task. Use of a built in function, well known library, or importing/use of prime generators from other Rosetta Code tasks is encouraged.

references
https://pdfs.semanticscholar.org/78a1/7349819304863ae061df88dbcb26b4908f03.pdf
https://www.primepuzzles.net/puzzles/puzz_011.htm
https://matheplanet.de/matheplanet/nuke/html/viewtopic.php?topic=232720&start=0
 
fn is_prime(num: u32) -> bool {
  match num {
      x if x < 4 => x > 1,
      x if x % 2 == 0 => false,
      x => { let limit = (x as f32).sqrt().ceil() as u32;
              (3..=limit).step_by(2).all(|a| x % a != 0)
            }
  } 
}
 
fn primes_by_diffs(primes: &[u32], diffs: &[u32]) -> Vec<Vec<u32>> {
 
  fn select(diffs: &[u32], prime_win: &[u32], acc: bool) -> bool {
    if diffs.is_empty() || !acc {
      acc
    }
    else {
      let acc1 = prime_win[0] + diffs[0] == prime_win[1];
      select(&diffs[1..], &prime_win[1..], acc1)
    }
  }
 
  primes.windows(diffs.len() + 1)
        .filter(|&win| select(diffs, win, true))
        .map(|win| win.to_vec())
        .collect()
}
 
fn main() {
  let limit = 1_000_000u32;
  let start = std::time::Instant::now();
  let primes = (2..).filter(|&i| is_prime(i));
  let prime_list: Vec<u32> = primes.take_while(|&p| p <= limit).collect();
  let duration = start.elapsed();
  println!("primes time: {:?}", duration);
  for diffs in vec!(vec!(1), vec!(2), vec!(2,2), vec!(2,4), vec!(4,2), vec!(6,4,2), vec!(2,4,6)) {
    let result_list = primes_by_diffs(&prime_list, &diffs);
    let len = result_list.len();
    println!("{:?} number: {}\n\tfirst: {:?}", diffs, len, result_list[0]);
    if len == 1 {
      println!()
    }
    if len > 1 {
      println!("\tlast: {:?}\n", result_list.last().unwrap())
    }
  }
}
 