Problem:
Score : 100 points

Problem Statement

You are given a 4-character string S consisting of uppercase English letters.
Determine if S consists of exactly two kinds of characters which both appear twice in S.

Constraints

The length of S is 4.

S consists of uppercase English letters.

Input

Input is given from Standard Input in the following format:

S

Output

If S consists of exactly two kinds of characters which both appear twice in S, print Yes; otherwise, print No.

Sample Input 1

ASSA

Sample Output 1

Yes

S consists of A and S which both appear twice in S.

Sample Input 2

STOP

Sample Output 2

No

Sample Input 3

FFEE

Sample Output 3

Yes

Sample Input 4

FREE

Sample Output 4

No

Solution in Rust (1.15.1) (judge verdict: Accepted)

use std::collections::HashMap;
fn read<T: std::str::FromStr>() -> T {
  let mut s = String::new();
  std::io::stdin().read_line(&mut s).ok();
  s.trim().parse().ok().unwrap()
}

fn read_vec<T: std::str::FromStr>() -> Vec<T> {
  read::<String>().split_whitespace()
    .map(|e| e.parse().ok().unwrap()).collect()
}

fn read_vec2<T: std::str::FromStr>(n: u32) -> Vec<Vec<T>> {
  (0..n).map(|_| read_vec()).collect()
}

pub trait LexicalPermutation {
  /// Return `true` if the slice was permuted, `false` if it is already
  /// at the last ordered permutation.
  fn next_permutation(&mut self) -> bool;
}
impl<T> LexicalPermutation for [T] where T: Ord {
  /// Original author in Rust: Thomas Backman <serenity@exscape.org>
  fn next_permutation(&mut self) -> bool {
    // These cases only have 1 permutation each, so we can't do anything.
    if self.len() < 2 { return false; }

    // Step 1: Identify the longest, rightmost weakly decreasing part of the vector
    let mut i = self.len() - 1;
    while i > 0 && self[i-1] >= self[i] {
      i -= 1;
    }

    // If that is the entire vector, this is the last-ordered permutation.
    if i == 0 {
      return false;
    }

    // Step 2: Find the rightmost element larger than the pivot (i-1)
    let mut j = self.len() - 1;
    while j >= i && self[j] <= self[i-1]  {
      j -= 1;
    }

    // Step 3: Swap that element with the pivot
    self.swap(j, i-1);

    // Step 4: Reverse the (previously) weakly decreasing part
    self[i..].reverse();

    true
  }
}
fn main() {
  let s: String = read();
  let mut hash = HashMap::new();
  for i in s.chars() {
    let count = hash.entry(i).or_insert(0);
    *count += 1;
  }
  if hash.len() != 2 { println!("No"); }
  else {
    for (_, v) in hash {
      if v != 2 {
        println!("No");
        return;
      }
    }
    println!("Yes");
  }
}