Skip to content

Java class that works like a mechanical counter, plus two more operation modes

License

Notifications You must be signed in to change notification settings

GuiRitter/TallyCounter

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

8 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

TallyCounter

Implements a counter as an array of numbers, like a mechanical counter. Every number can go from zero to Long.MAX_VALUE. Can operate in one of three modes: normal, unique numbers and unique combinations. The normal mode works like mechanical counters: actuating it increments the first (rightmost) number and when a number rolls over, the next number increments. For example, the following code

TallyCounter tallyCounter = new TallyCounter(2, Type.NORMAL, 1);
while (!tallyCounter.overflowFlag) {
    System.out.println(tallyCounter.toReadableString());
    tallyCounter.increment();
}

produces the following output

[0, 0]
[0, 1]
[1, 0]
[1, 1]

The unique numbers mode does not allow numbers with the same value. This is useful, for example, to generate all combinations that can be made where every value represents an unique object. For example, the following code

TallyCounter tallyCounter = new TallyCounter(2, Type.UNIQUE_NUMBERS, 1);
while (!tallyCounter.overflowFlag) {
    System.out.println(tallyCounter.toReadableString());
    tallyCounter.increment();
}

produces the following output

[0, 1]
[1, 0]

The unique combination mode does not allow values that appeared together to appear together again. This is useful, for example, to generate all combination of unique values, regardless of order. For example, the following code

TallyCounter tallyCounter = new TallyCounter(2, Type.UNIQUE_COMBINATION, 1);
while (!tallyCounter.overflowFlag) {
    System.out.println(tallyCounter.toReadableString());
    tallyCounter.increment();
}

produces the following output

[0, 1]

This class is also useful to replace a set of nested for loops, where every for command is replaced by a number, and every value is the value that would be iterated. For example, the following code

for (String c : new String[]{"a", "b"}) {
    for (String b : new String[]{"0", "1"}) {
        for (String a : new String[]{"&", "|"}) {
            System.out.format("[%s, %s, %s]\n", a, b, c);
        }
    }
}

produces the same output as the following code

Map<Long, String> mapA = new HashMap<>();
mapA.put(0l, "&");
mapA.put(1l, "|");
Map<Long, String> mapB = new HashMap<>();
mapB.put(0l, "0");
mapB.put(1l, "1");
Map<Long, String> mapC = new HashMap<>();
mapC.put(0l, "a");
mapC.put(1l, "b");
TallyCounter tallyCounter = new TallyCounter(3, Type.NORMAL, 1);
long array[];
while (!tallyCounter.overflowFlag) {
    array = tallyCounter.getArray();
        System.out.format("[%s, %s, %s]\n",
         mapA.get(array[0]),
         mapB.get(array[1]),
         mapC.get(array[2]));
    tallyCounter.increment();
}

which is

[&, 0, a]
[|, 0, a]
[&, 1, a]
[|, 1, a]
[&, 0, b]
[|, 0, b]
[&, 1, b]
[|, 1, b]

It's more verbose, but the amount of nested loops can be altered programatically, which would require recursive methods otherwise. It makes it easier to implement brute force algorithms and to skip combinations according to the modes mentioned above.

I've created a program here that demonstrates the functionality of this class.

A few words about Maven.

About

Java class that works like a mechanical counter, plus two more operation modes

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages