/**
 * An example that illustrates an elegant approach to
 * implementing a checklist.
 *
 * @author  Prof. David Bernstein, James Madison University
 * @version 1.0
 */
public class Elegant {
    /**
     * The entry point.
     *
     * @param args  The command line arguments (ignored)
     */
    public static void main(String[] args) {
        String[] checklist = {"Shirts", "Socks", "Pants", "Skirts"};

        String[][] accomplished   = {
            {"Shirts", "Socks", "Pants", "Dresses", "Shoes"}, // true
            {"Socks", "Shirts", "Skirts", "Pants"},            // true
            {"Dresses", "Shirts"},  // false
        };
        

        boolean[] expected = {true, true, false};
                
        for (int i = 0; i < accomplished.length; i++) {
            System.out.println("Test " + i + " ---------------");
            if (checkFor(checklist, accomplished[i], 2) != expected[i]) {
                System.out.println("Incorrect answer for: " + i);
            }
        }
    }

//[outerChecklist
    /**
     * An m (required) out of n (size) checklist.
     *
     * @param checklist  The checklist
     * @param accomplished  The array of accomplished items
     * @param needed     The required number of checklist items
     * @return true if the checklist is satisfied; false otherwise
     */
    private static boolean checkFor(String[] checklist, String[] accomplished, 
                                    int needed) {
        int       count;        
        count = 0;
        for (int c = 0; c < checklist.length; c++) {
            for (int a = 0; a < accomplished.length; a++) {
                if (checklist[c].equals(accomplished[a])) {
                    count++;
                    
                    if (count >= needed) return true;
                    else                 break;
                }
            }
        }
        return false; // Not enough items were accomplished
    }
//]outerChecklist


//[outerAccomplished
    /**
     * An elegant implementation of a checklist.
     *
     * @param checklist  The checklist
     * @param accomplished  The array of accomplished items
     * @param needed     The requried number of checklist items
     */
/*
    private static boolean checkFor(String[] checklist, String[] accomplished,
                                    int needed) {
        boolean[] checked;
        int       count;        

        // Early return
        if (accomplished.length < checklist.length) return false;

        checked = new boolean[checklist.length];
        count   = 0;
        
        // The outer loop is over the accomplished array
        for (int a = 0; a < accomplished.length; a++) {
            // The inner loop is over the checklist array        
            for (int c = 0; c < checklist.length; c++) {
                if (accomplished[a].equals(checklist[c])) {
                    if (!checked[c]) {
                        count++;
                        checked[c] = true;
                        if (count >= needed) return true;
                    }
                    break;
                }
            }
        }
        return count > needed;
    }
*/
//]outerAccomplished

}
