Problem:
Find the number of ways you can have breakfast in ‘n’ days, given Bread-butter can be eaten every day, Pizza can be eaten every alternate day and Burger can be eaten every two days. Only one item can be eaten on a given day.
Solution:
Let us call the sequence of breakfast item on the days as timetable. And the condition of whether a particular item can be consumed on a given day as constraint.
Approach 1:
Create the timetable while checking that the constraints are met.
Approach 2:
Generate all possible timetables and eliminate the timetables that do not meet the constraints.
Java Program:
Sample Output:
Unit Tests:
Find the number of ways you can have breakfast in ‘n’ days, given Bread-butter can be eaten every day, Pizza can be eaten every alternate day and Burger can be eaten every two days. Only one item can be eaten on a given day.
Solution:
Let us call the sequence of breakfast item on the days as timetable. And the condition of whether a particular item can be consumed on a given day as constraint.
Approach 1:
Create the timetable while checking that the constraints are met.
Approach 2:
Generate all possible timetables and eliminate the timetables that do not meet the constraints.
Java Program:
package com.sourabh.practice;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class Breakfast {
public static void main(String[] args) {
String[] menu = new String[]{"Bread-butter", "Pizza", "Burger"};
int[] constraint = new int[]{1, 2, 3};
List<List<String>> timeTableList = new ArrayList<>();
List<String> timeTable = new ArrayList<>();
int n = 3;
Breakfast breakfast = new Breakfast();
breakfast.countNumberOfWaysEvaluationApproach(menu, constraint, timeTableList, timeTable, n);
System.out.println(timeTableList.size());
}
public void countNumberOfWaysEvaluationApproach(String[] menu, int[] constraint, List<List<String>> timeTableList, List<String> timeTable, int n) {
if(timeTable.size() == n) {
// For unit-testing purpose
List<String> output = new ArrayList<>();
for(String food : timeTable) {
System.out.print(food + " ");
output.add(food);
}
System.out.println();
timeTableList.add(output);
} else {
List<String> possibilities = new ArrayList<>();
boolean found = false;
for(int i=0; i<constraint.length; i++) {
for(int j=1; j<constraint[i]; j++) {
if(timeTable.size() - j >=0 && timeTable.get(timeTable.size() - j).equals(menu[i])) {
found = true;
}
}
if(!found) {
possibilities.add(menu[i]);
} else {
found = false;
}
}
for(String possibility : possibilities) {
timeTable.add(possibility);
countNumberOfWaysEvaluationApproach(menu, constraint, timeTableList, timeTable, n);
timeTable.remove(timeTable.size() - 1);
}
}
}
public void countNumberOfWaysExhaustiveApproach(String[] menu, int[] constraint, List<List<String>> timeTableList, List<String> timeTable, int n) {
generatePermutation(menu, timeTableList, timeTable, n);
Iterator<List<String>> iterator = timeTableList.iterator();
while(iterator.hasNext()) {
List<String> output = iterator.next();
boolean passed = true;
for(int i=0; i<menu.length; i++) {
int occ1 = -1;
int occ2 = -1;
for(int j = 0; j < output.size(); j++) {
if(output.get(j).equals(menu[i])) {
if(occ1 < 0) {
occ1 = j;
} else {
occ2 = occ1;
occ1 = j;
}
}
if(occ1 >= 0 && occ2 >= 0 && occ1 > occ2 && occ1 - occ2 < constraint[i]) {
passed = false;
}
}
}
if(!passed) {
iterator.remove();
}
}
for(List<String> output : timeTableList) {
for(String food : output) {
System.out.print(food + " ");
}
System.out.println();
}
System.out.println(timeTableList.size());
}
public void generatePermutation(String[] menu, List<List<String>> timeTableList, List<String> timeTable, int n) {
if(timeTable.size() == n) {
// For unit-testing purpose
List<String> output = new ArrayList<>();
for(String food : timeTable) {
output.add(food);
}
timeTableList.add(output);
} else {
for(int i=0; i<menu.length; i++) {
timeTable.add(menu[i]);
generatePermutation(menu, timeTableList, timeTable, n);
timeTable.remove(timeTable.size() - 1);
}
}
}
}
Sample Output:
Bread-butter Bread-butter Bread-butter Bread-butter Bread-butter Pizza Bread-butter Bread-butter Burger Bread-butter Pizza Bread-butter Bread-butter Pizza Burger Bread-butter Burger Bread-butter Bread-butter Burger Pizza Pizza Bread-butter Bread-butter Pizza Bread-butter Pizza Pizza Bread-butter Burger Pizza Burger Bread-butter Pizza Burger Pizza Burger Bread-butter Bread-butter Burger Bread-butter Pizza Burger Pizza Bread-butter 15
Unit Tests:
package com.sourabh.practice;
import static org.junit.Assert.*;
import java.util.ArrayList;
import java.util.List;
import org.junit.Assert;
import org.junit.Test;
public class BreakfastTests {
Breakfast breakfast = new Breakfast();
@Test
public void testCountNumberOfWaysInTermsOfFrequency() {
String[] menu = new String[]{"Bread-butter", "Pizza", "Burger"};
int[] constraint = new int[]{1, 2, 3};
List<List<String>> timeTableList = new ArrayList<>();
List<String> timeTable = new ArrayList<>();
int n = 3;
Breakfast breakfast = new Breakfast();
breakfast.countNumberOfWaysEvaluationApproach(menu, constraint, timeTableList, timeTable, n);
boolean passed = true;
for(List<String> output : timeTableList) {
for(int i=0; i<menu.length; i++) {
int occ1 = -1;
int occ2 = -1;
for(int j = 0; j < output.size(); j++) {
if(output.get(j).equals(menu[i])) {
if(occ1 < 0) {
occ1 = j;
} else {
occ2 = occ1;
occ1 = j;
}
}
if(occ1 >= 0 && occ2 >= 0 && occ1 > occ2 && occ1 - occ2 < constraint[i]) {
passed = false;
}
}
}
}
Assert.assertTrue(passed);
}
@Test
public void testCountNumberOfWaysInTermsOfExhaustiveness() {
String[] menu = new String[]{"Bread-butter", "Pizza", "Burger"};
int[] constraint = new int[]{1, 2, 3};
List<List<String>> timeTableList = new ArrayList<>();
List<String> timeTable = new ArrayList<>();
int n = 3;
Breakfast breakfast = new Breakfast();
breakfast.countNumberOfWaysExhaustiveApproach(menu, constraint, timeTableList, timeTable, n);
boolean passed = true;
for(List<String> output : timeTableList) {
for(int i=0; i<menu.length; i++) {
int occ1 = -1;
int occ2 = -1;
for(int j = 0; j < output.size(); j++) {
if(output.get(j).equals(menu[i])) {
if(occ1 < 0) {
occ1 = j;
} else {
occ2 = occ1;
occ1 = j;
}
}
if(occ1 >= 0 && occ2 >= 0 && occ1 > occ2 && occ1 - occ2 < constraint[i]) {
passed = false;
}
}
}
}
Assert.assertTrue(passed);
}
@Test
public void testCountNumberOfWaysInTermsOfAccuracy() {
String[] menu = new String[]{"Bread-butter", "Pizza", "Burger"};
int[] constraint = new int[]{1, 2, 3};
List<List<String>> timeTableList = new ArrayList<>();
List<String> timeTable = new ArrayList<>();
int n = 3;
Breakfast breakfast = new Breakfast();
Long start1 = System.currentTimeMillis();
breakfast.countNumberOfWaysEvaluationApproach(menu, constraint, timeTableList, timeTable, n);
Long end1 = System.currentTimeMillis();
int size1 = timeTableList.size();
timeTableList = new ArrayList<>();
timeTable = new ArrayList<>();
Long start2 = System.currentTimeMillis();
breakfast.countNumberOfWaysExhaustiveApproach(menu, constraint, timeTableList, timeTable, n);
Long end2 = System.currentTimeMillis();
int size2 = timeTableList.size();
Assert.assertEquals(size1, size2);
System.out.println(end1 - start1);
System.out.println(end2 - start2);;
}
}