/** 2008 WCU Computer Science High School Programming Contest
* Solution to Problem Two, Copyright 2008, all rights reserved
* Western Carolina University 
* Department of Mathematics and Computer Science
*/
import java.io.*;
import java.util.*;

public class Problem2 
{
	
  /** This function returns 0 if the passed character is alphabetic, 
  * 1 if numeric, 2 otherwise (special). */
  public static int characterType(char c) 
  {
    if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))
      return 0;
    else if (c >= '0' && c <= '9')
      return 1;
    else
      return 2;
  }
	
  /** This method applies rules 0, 1, and 2. */
  public static int applyRules012(int strength, String str)
  {
    // rule 0: start at 0
    strength = 0;
		
    // rule 1: +10 if length >= 8
    if (str.length() >= 8)
      strength += 10;
			
    // rule 2: +1 for every two-chars further than 8
    if (str.length() >= 8)
      strength += (str.length()-8)/2;

    return strength;
  }

   /** This method applies rules 3, 4, and 5. */
   public static int applyRules345(int strength, String str)
   {
     // rules 3,4,5: contains UPPERCASE, lowercase, numeric, special
     boolean containsUpper   = false;
     boolean containsLower   = false;
     boolean containsSpecial = false;
     boolean containsNumeric = false;
		
     for (int i = 0; i < str.length(); i++)
     {
       containsLower   = containsLower   || 
         (str.charAt(i) >= 'a' && str.charAt(i) <= 'z');
       containsUpper   = containsUpper   || 
         (str.charAt(i) >= 'A' && str.charAt(i) <= 'Z');
       containsNumeric = containsNumeric || 
         (str.charAt(i) >= '0' && str.charAt(i) <= '9');
       containsSpecial = containsSpecial || 
         (Problem2.characterType(str.charAt(i)) == 2);
     }
		
     // rule 3: +1 if contains both upper and lower
     if (containsUpper && containsLower) strength += 1;
			
     // rule 4: +1 if contains numeric
     if (containsNumeric) strength += 1;
		
     // rule 5: +1 if contains special
     if (containsSpecial) strength += 1;
	
     return strength;
   }

   /** This function computes the strength of a password 
   * passed as argument. */
   public static int passwordStrength(String str) 
   {
     int strength = 0;
			
     strength = Problem2.applyRules012(strength, str);
     strength = Problem2.applyRules345(strength, str);
		
     // rule 6: +1 for every two-conseq chars of != type
     for (int i = 0; i < str.length()-1; i++)
     {
       if (characterType(str.charAt(i)) != 
         characterType(str.charAt(i+1)))
           strength += 1;
     }
		
     // we are done evaluating all the rules, 
     // return the final strength
     return strength;
  }
	
  public static void main(String[] args) 
  {
    Scanner scanIn = new Scanner(System.in);
		
    while(true) 
    {
      // get user input
      System.out.print(">> password (type 'quit' to "
        + "exit the program): ");
      String line = scanIn.nextLine();
			
      // check for need to quit
      if (line.equals("quit")) System.exit(0);
			
      // compute the stength
      System.out.println("strength = " + 
        Problem2.passwordStrength(line) + "\n");
				
    }// end of while
  }
}