General FizzBuzz/jFizzBuzz: Difference between revisions

no edit summary
(jFizzBuzz - FizzBuzz for the Enterprise World)
 
No edit summary
 
(6 intermediate revisions by one other user not shown)
Line 1:
<syntaxhighlight lang="java">
 
/**
{{works with|Java|1.8.x}}
* @file GeneralFizzBuzz.java
 
User-supplied values must be passed as command-line arguments.
 
<lang Java>/**
*
* FizzBuzz Enterprise Edition (c) 2016
*
*
* TODO: Add End-User License Agreement
* TODO: Add JavaDoc Comments
* TODO: Add Unit Tests
* TODO: Add Dependency Injection (FizzBuzzProvider, BuzzerProvider, etc.)
*
*
*/
 
import java.io.InputStream;
 
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.IteratorNoSuchElementException;
import java.util.Scanner;
 
 
/**
class BuzzException extends Exception
* This class follows the "God class" pattern.
* See {@link #main(String[])} for example usage.
*/
class FizzBuzzer
implements
Iterable<FizzBuzzer.Entry>,
Iterator<FizzBuzzer.Entry>
{
private static final long DEFAULT_START_NUM = 1;
public BuzzException(
private static final long DEFAULT_MAX_NUM = Long.MAX_VALUE;
String textualRepresentation
)
{
super(textualRepresentation);
}
}
 
public class Entry {
 
public final long num;
interface IBuzzer
public final List<String> names;
{
void buzz(
Integer numericValue
)
throws BuzzException;
}
 
private Entry(Long num, List<String> names) {
this.num = num;
this.names = names;
}
}
 
private Map<Integer, String> modToName = new HashMap<>();
interface IFizzBuzz
{
Boolean addBuzzer(
IBuzzer buzzerToAddToTheListOfBuzzers
);
 
private long currNum = DEFAULT_START_NUM;
String doExecute();
private long maxNum = DEFAULT_MAX_NUM;
}
private Map<Long, List<Integer>> schedule = new HashMap<>();
 
public long getCurrNum() { return currNum; }
public void setCurrNum(long currNum) { this.currNum = currNum; }
 
public long getMaxNum() { return maxNum; }
public void setMaxNum(long maxNum) { this.maxNum = maxNum; }
 
class Buzzer implements IBuzzer
{
protected final Integer numericValue;
protected final String textualRepresentation;
 
private List<Integer> scheduledAt(long num) {
public Buzzer(
return schedule.computeIfAbsent(num, num_ -> new ArrayList<>());
Integer numericValue,
String textualRepresentation
)
{
this.numericValue = numericValue;
this.textualRepresentation = textualRepresentation;
}
 
publicprivate void buzzscheduleNearest(Integer mod) {
Integer numericValue
)
throws BuzzException
{
Integer moduloOfNumericValues = new Integer(numericValue % this.getNumericValue());
 
long nearestNum = currNum + (mod - currNum % mod);
if (moduloOfNumericValues.equals(new Integer(0)))
{
throw new BuzzException(this.getTextualRepresentation());
}
 
scheduledAt(nearestNum).add(mod);
}
 
public boolean add(Integer mod, String name) {
Integer getNumericValue()
{
return this.numericValue;
}
 
if (modToName.containsKey(mod)) {
String getTextualRepresentation()
return false;
{
}
return this.textualRepresentation;
}
}
 
modToName.put(mod, name);
scheduleNearest(mod);
 
return true;
/**
*
* Thread-safe implementation of {@link IFizzBuzz}.
*
*/
class FizzBuzz implements IFizzBuzz
{
protected final Integer numericvalueOfUpperLimit;
protected final List<IBuzzer> listOfBuzzers;
 
public FizzBuzz(
Integer numericvalueOfUpperLimit
)
{
this.numericvalueOfUpperLimit = numericvalueOfUpperLimit;
this.listOfBuzzers = new ArrayList<IBuzzer>();
}
 
public void addAll(Map<Integer, String> modToName) {
public synchronized Boolean addBuzzer(
 
IBuzzer buzzerToAddToTheListOfBuzzers
for (Map.Entry<Integer, String> modAndName : modToName.entrySet()) {
)
add(modAndName.getKey(), modAndName.getValue());
{
}
return new Boolean(this.listOfBuzzers.add(buzzerToAddToTheListOfBuzzers));
}
 
public synchronized String doExecute()
{
StringBuilder textualRepresentationOfFizzBuzzProgramOutput = new StringBuilder();
 
for (@Override
public Entry next() {
Integer loopIndex = new Integer(1);
loopIndex <= this.numericvalueOfUpperLimit;
loopIndex += new Integer(1)
)
{
Boolean atLeastOneBuzzerBuzzed = new Boolean(false);
 
List<Integer> currMods = for scheduledAt(currNum);
Integer buzzerIndex = new Integer(0);
buzzerIndex < new Integer(this.listOfBuzzers.size());
buzzerIndex += new Integer(1)
)
{
IBuzzer buzzer = this.listOfBuzzers.get(buzzerIndex);
try
{
buzzer.buzz(loopIndex);
}
catch (BuzzException buzzException)
{
textualRepresentationOfFizzBuzzProgramOutput.append(buzzException.getMessage());
atLeastOneBuzzerBuzzed = new Boolean(true);
}
}
 
List<String> currNames = new ArrayList<>();
if (atLeastOneBuzzerBuzzed.equals(new Boolean(false)))
{
textualRepresentationOfFizzBuzzProgramOutput.append(loopIndex.toString());
}
 
for (Integer m : currMods) {
textualRepresentationOfFizzBuzzProgramOutput.append(new String("\n"));
}
 
String name = modToName.get(m);
return textualRepresentationOfFizzBuzzProgramOutput.toString();
currNames.add(name);
 
long newNum = currNum + m;
}
scheduledAt(newNum).add(m);
 
}
 
 
class FizzBuzzEnterpriseDemo
{
public static void main(
String[] programArgumentsAsProvidedByTheEndUser
)
{
final UserSuppliedArguments userSuppliedArguments;
 
try
{
userSuppliedArguments = new UserSuppliedArguments(programArgumentsAsProvidedByTheEndUser);
}
catch (IllegalArgumentException illegalArgumentException)
{
System.err.println(illegalArgumentException.getMessage());
System.exit(1);
return;
}
 
Entry result = new Entry(currNum, currNames);
final FizzBuzz fizzBuzz = new FizzBuzz(userSuppliedArguments.numericValueOfUpperLimit);
 
currNum++;
Iterator buzzerEntriesIterator = userSuppliedArguments.buzzerEntries.entrySet().iterator();
 
return result;
while (buzzerEntriesIterator.hasNext())
{}
Map.Entry numericValueTextualRepresentationPair = (Map.Entry) buzzerEntriesIterator.next();
 
@Override
fizzBuzz.addBuzzer(new Buzzer(
public void remove() {
(Integer) numericValueTextualRepresentationPair.getKey(),
schedule.remove(currNum - 1);
(String) numericValueTextualRepresentationPair.getValue()
));}
}
 
@Override
System.out.println(fizzBuzz.doExecute());
public boolean hasNext() {
return (maxNum < 0) || (currNum <= maxNum);
}
 
@Override
public Iterator<Entry> iterator() {
return this;
}
 
 
privatepublic static classFizzBuzzer UserSuppliedArgumentsreadFrom(InputStream in) {
{
public final Integer numericValueOfUpperLimit;
public final LinkedHashMap<Integer,String> buzzerEntries;
 
privateFizzBuzzer UserSuppliedArgumentsfizzBuzzer = new FizzBuzzer();
String[] sourceArguments
)
throws IllegalArgumentException
{
Integer requiredAmountOfUserSuppliedArguments = new Integer(7);
Integer actualAmountOfUserSuppliedArguments = new Integer(sourceArguments.length);
 
try (Scanner scanner = new Scanner(in)) {
if (actualAmountOfUserSuppliedArguments < requiredAmountOfUserSuppliedArguments)
{
throw new IllegalArgumentException(String.format(
"End user did not provide sufficient amount of command-line program arguments.\n"+
"Required amount of arguments: %d\n"+
"Amount of arguments supplied by the end used: %d\n",
requiredAmountOfUserSuppliedArguments, actualAmountOfUserSuppliedArguments
));
}
 
this.buzzerEntrieslong maxNum = new LinkedHashMap<Integer,String>scanner.nextLong();
fizzBuzzer.setMaxNum(maxNum);
 
while (scanner.hasNext()) {
 
String Integer textualValueOfUpperLimit mod = sourceArguments[new Integerscanner.nextInt(0)];
Integer scanner.skip("[\t numericValueOfUpperLimit]*");
String name = scanner.nextLine();
 
try fizzBuzzer.add(mod, name);
{
numericValueOfUpperLimit = new Integer(textualValueOfUpperLimit);
if (numericValueOfUpperLimit < new Integer(0))
{
throw new IllegalArgumentException();
}
}
catch (IllegalArgumentException illegalArgumentException)
{
throw new IllegalArgumentException(String.format(
"End user supplied invalid value for upper limit for the FizzBuzz execution.\n"+
"Required non-negative integer value.\n"+
"Value supplied by the end user: %s\n",
textualValueOfUpperLimit
));
}
}
 
return fizzBuzzer;
this.numericValueOfUpperLimit = numericValueOfUpperLimit;
}
 
public void printTo(OutputStream out) {
 
try (PrintWriter writer = fornew PrintWriter(out)) {
Integer loopIndex = new Integer(0);
loopIndex < new Integer(3);
loopIndex += new Integer(1)
)
{
Integer numericValueArgumentIndex = new Integer(1) + loopIndex * new Integer(2);
Integer textualRepresentationArgumentIndex = numericValueArgumentIndex + new Integer(1);
 
for (FizzBuzzer.Entry e : Integerthis) buzzerNumericValue;{
String buzzerTextualValue;
String buzzerTextualRepresentation;
 
String strNames = String.join(" ", e.names);
buzzerTextualRepresentation = sourceArguments[textualRepresentationArgumentIndex];
String line = String.format("%d %s", e.num, strNames);
buzzerTextualValue = sourceArguments[numericValueArgumentIndex];
 
trywriter.println(line);
{writer.flush();
buzzerNumericValue = new Integer(buzzerTextualValue);
if (buzzerNumericValue <= new Integer(0))
{
throw new IllegalArgumentException();
}
}
catch (IllegalArgumentException illegalArgumentException)
{
throw new IllegalArgumentException(String.format(
"End user supplied invalid numeric value for buzzer.\n"+
"Required positive integer value.\n"+
"Value supplied by the end user: %s\n",
buzzerTextualValue
));
}
 
this.buzzerEntries.putremove(buzzerNumericValue, buzzerTextualRepresentation);
}
 
}
}
 
@Override
public String toString() {
return String.format("%s; current %d; max %d",
modToName, currNum, maxNum);
}
 
}
 
class GeneralFizzBuzz {
</lang>
 
public static void main(String[] args) {
 
try {
FizzBuzzer.readFrom(System.in).printTo(System.out);
}
 
catch (NoSuchElementException | IllegalStateException e) {
 
System.err.format("Error: %s\n", e.toString());
System.exit(1);
}
}
}</syntaxhighlight>