/*
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <cassert>
#include <cstring>
#include <fstream>
#include <iostream>
#include <string>

// this include is only used when building as a buck target to get diff signals
#include "se_defines.h"

SE_GLOBALS()

int is_prime(int n) {
  if (n <= 1 || (n % 2 == 0 && n > 2)) {
    return 0;
  }
  for (int i = 3; i * i <= n; i += 2) {
    if (n % i == 0) {
      return 0;
    }
  }
  return 1;
}
int count_vowels(const char* str) {
  int count = 0;
  for (int i = 0; str[i] != 0; i++) {
    if (isalpha(str[i])) {
      if (tolower(str[i]) == 'a' || tolower(str[i]) == 'e' ||
          tolower(str[i]) == 'i' || tolower(str[i]) == 'o' ||
          tolower(str[i]) == 'u') {
        count++;
      }
    }
  }
  return count;
}
int count_consonants(const char* str) {
  int count = 0;
  for (int i = 0; str[i] != 0; i++) {
    if (isalpha(str[i])) {
      if (!(tolower(str[i]) == 'a' || tolower(str[i]) == 'e' ||
            tolower(str[i]) == 'i' || tolower(str[i]) == 'o' ||
            tolower(str[i]) == 'u')) {
        count++;
      }
    }
  }
  return count;
}
int count_numeric(const char* str) {
  int count = 0;
  for (int i = 0; str[i] != 0; i++) {
    if (isdigit(str[i])) {
      count++;
    }
  }
  return count;
}
char* strrev(char* str) {
  char *p1, *p2;
  if (!str || !*str)
    return str;
  for (p1 = str, p2 = str + strlen(str) - 1; p2 > p1; ++p1, --p2) {
    *p1 ^= *p2;
    *p2 ^= *p1;
    *p1 ^= *p2;
  }
  return str;
}

bool check_input(const char* input_string) {
  int length = strlen(input_string);
  int has_uppercase = 0, has_lowercase = 0, has_digit = 0, has_special = 0;
  int has_vowel = 0, has_consonant = 0, has_whitespace = 0;
  int unique_chars = 0, is_palindrome = 0;
  int has_alphabet = 0;
  int vowel_count = 0;
  int numeric_count = 0;
  int consonant_count = 0;
  float case_ratio = 0;
  for (int i = 0; i < length; i++) {
    if (isupper(input_string[i]))
      has_uppercase = 1;
    if (islower(input_string[i]))
      has_lowercase = 1;
    if (isdigit(input_string[i]))
      has_digit = 1;
    if (!isalnum(input_string[i]))
      has_special = 1;
    if (strchr("aeiouAEIOU", input_string[i]))
      has_vowel = 1;
    if (strchr("bcdfghjklmnpqrstvwxyzBCDFGHJKLMNPQRSTVWXYZ", input_string[i]))
      has_consonant = 1;
    if (isspace(input_string[i]))
      has_whitespace = 1;
    if (isalpha(input_string[i]))
      has_alphabet = 1;
  }
  int first_three_chars_same = 0;
  if (length >= 3) {
    first_three_chars_same = strncmp(input_string, "xSO", 3) == 0;
  }
  is_palindrome = strcmp(input_string, strrev(strdup(input_string))) == 0;
  case_ratio = has_lowercase != 0 ? (float)has_uppercase / has_lowercase : -1;
  int total_tests = 16;
  int passed_tests = 0;
  numeric_count = count_numeric(input_string);
  consonant_count = count_consonants(input_string);
  vowel_count = count_vowels(input_string);
  for (int i = 0; i < length; i++) {
    for (int j = i + 1; j < length; j++) {
      if (input_string[i] == input_string[j]) {
        unique_chars++;
        break;
      }
    }
  }
  if (consonant_count == 9) {
    SE_STEP(true)
  } else {
    return false;
  }
  if (vowel_count == 3) {
    SE_STEP(true)
  } else {
    return false;
  }
  if (numeric_count == 3) {
    SE_STEP(true)
  } else {
    return false;
  }
  if ((is_prime(length) == 0)) {
    SE_STEP(true)
  } else {
    return false;
  }
  if ((has_uppercase == 1)) {
    SE_STEP(true)
  } else {
    return false;
  }
  if ((has_lowercase == 1)) {
    SE_STEP(true)
  } else {
    return false;
  }
  if ((has_digit == 1)) {
    SE_STEP(true)
  } else {
    return false;
  }
  if ((has_special == 0)) {
    SE_STEP(true)
  } else {
    return false;
  }
  if ((has_vowel == 1)) {
    SE_STEP(true)
  } else {
    return false;
  }
  if ((has_consonant == 1)) {
    SE_STEP(true)
  } else {
    return false;
  }
  if ((has_whitespace == 0)) {
    SE_STEP(true)
  } else {
    return false;
  }
  if ((is_palindrome == 0)) {
    SE_STEP(true)
  } else {
    return false;
  }
  if ((has_alphabet == 1)) {
    SE_STEP(true)
  } else {
    return false;
  }
  if ((case_ratio == 1)) {
    SE_STEP(true)
  } else {
    return false;
  }
  if ((unique_chars == 1)) {
    SE_STEP(true)
  } else {
    return false;
  }
  if ((first_three_chars_same == 1)) {
    SE_STEP(true)
  } else {
    return false;
  }
  return true;
}

int main(int argc, char* argv[]) {
  std::istream* input;
  std::ifstream file;
  if (argc < 2) {
    input = &std::cin; // No file name provided, read from stdin
  } else {
    file.open(argv[1]);
    if (!file) {
      std::cerr << "Could not open the file.\n";
      return 1;
    }
    input = &file; // File opened successfully, read from file
  }
  std::string content(
      (std::istreambuf_iterator<char>(*input)),
      std::istreambuf_iterator<char>());
  SE_TARGET_STATE(check_input(content.c_str()));
  return 0;
}
