/**
 * A class that contains examples of the
 * starts and completions pattern.
 *
 * @author  Prof. David Bernstein, James Madison University
 * @version 1.0
 */
public class StartsAndCompletions {
    /**
     * A method to hold the fragments.
     *
     * @param args  The command line arguments
     */
    public static void main(String[] args) {
        for (int miles = 0; miles < 27; miles++) {
            System.out.printf("Miles: %d\tStarts: %d\tCompletions: %d\n",
                               miles, starts(miles, 3), completions(miles, 3));
        }
        
        int completions, indicator, length, miles, starts;
        miles = 0;
        length = 3;

//[astarts1
        indicator = ((miles % length) + length) / (length + 1);
//]astarts1

//[astarts2
        starts = (miles / length)
            + (((miles % length) + length) / (length + 1));
//]astarts2

//[alt0
        starts = ((miles - 1) / length) + 1;
//]alt0
        System.out.println("alt0 starts: " + starts);
        

//[alt1
        starts = Math.floorDiv((miles - 1), length) + 1;
//]alt1
        System.out.println("alt1 starts: " + starts);
    }



//[completions
    /**
     * Determine the number of completed tasks from
     * an amount of work and a numeraire.
     *
     * @param work        The amount of work
     * @param workPerTask The work per task
     * @return The number of completed tasks
     */
    public static int completions(int work, int workPerTask) {
        return work / workPerTask;
    }
//]completions

//[starts
    /**
     * Determine the number of started tasks from
     * an amount of work and a numeraire.
     *
     * @param work        The amount of work
     * @param workPerTask The work per task
     * @return The number of started tasks
     */
    public static int starts(int work, int workPerTask) {
        return completions(work, workPerTask) 
            + remainderIndicator(work, workPerTask);
    }
//]starts


//[indicator
    /**
     * Returns 0 if numerator is evenly divisible by denominator
     * and 1 otherwise. That is, returns 1 if there is a remainder
     * and 0 otherwise.
     *
     * @param num  The numerator
     * @param den  The denominator
     * @return 1 if there is a remainder; 0 otherwise
     */
    public static int remainderIndicator(int num, int den) {
        if ((num % den) == 0) {
            return 0;
        } else {
            return 1;
        }
    }
//]indicator
}

