package algocraft.function;
import java.util.HashMap;
import java.util.Map;
import static algocraft.function.ArrayUtil.intArray;
import static algocraft.function.SixFlags.Header.*;
import static algocraft.function.SixFlags.Initializer.init;
import static algocraft.function.SixFlags.Initializer.setup;
import static algocraft.function.StringUtil.*;
import static com.google.common.base.Joiner.on;
import static java.lang.Math.pow;
public enum SixFlags {
YYYYYY,
_YYYYY,
Y_YYYY,
__YYYY,
YY_YYY,
_Y_YYY,
Y__YYY,
___YYY,
YYY_YY,
_YY_YY,
Y_Y_YY,
__Y_YY,
YY__YY,
_Y__YY,
Y___YY,
____YY,
YYYY_Y,
_YYY_Y,
Y_YY_Y,
__YY_Y,
YY_Y_Y,
_Y_Y_Y,
Y__Y_Y,
___Y_Y,
YYY__Y,
_YY__Y,
Y_Y__Y,
__Y__Y,
YY___Y,
_Y___Y,
Y____Y,
_____Y,
YYYYY_,
_YYYY_,
Y_YYY_,
__YYY_,
YY_YY_,
_Y_YY_,
Y__YY_,
___YY_,
YYY_Y_,
_YY_Y_,
Y_Y_Y_,
__Y_Y_,
YY__Y_,
_Y__Y_,
Y___Y_,
____Y_,
YYYY__,
_YYY__,
Y_YY__,
__YY__,
YY_Y__,
_Y_Y__,
Y__Y__,
___Y__,
YYY___,
_YY___,
Y_Y___,
__Y___,
YY____,
_Y____,
Y_____,
______;
/**
* Format this class and its variables into a table.
*
* @return
*/
public static CharSequence display() {
return Describer.describe();
}
/**
* @param description
* @return the value of the boolean on the ordinal of the given description enum.
*/
public boolean valueOf(Enum description) {
return flags[description.ordinal()];
}
/**
* @param index
* @return the value of the boolean on the given index.
*/
public boolean valueAt(int index) {
return flags[index];
}
/**
* @param description
* @param flag
* @return itself or the flipped instance which has the same value as the given value
* on the ordinal of the given description enum.
*/
public SixFlags resolve(Enum description, boolean flag) {
int ordinal = description.ordinal();
return flag == flags[ordinal] ? this : flippedFlags[ordinal];
}
/**
* @param index
* @param flag
* @return itself or the flipped instance which has the same value as the given value
* on the given index.
*/
public SixFlags resolve(int index, boolean flag) {
return flag == flags[index] ? this : flippedFlags[index];
}
/**
* Build the following line according to its value,
* |YYYYYY|0b111111=63|Y|Y|Y|Y|Y|Y|_YYYYY |Y_YYYY |YY_YYY |YYY_YY |YYYY_Y |YYYYY_ |
*
* @return
*/
public CharSequence describe() {
return Describer.describe(this);
}
/**
* Description this instance according to the give description enum instances.
*
* @param descriptions
* @return
*/
public CharSequence toString(Enum... descriptions) {
return concatenate("[", Describer.describe(this.flags, descriptions), "]");
}
private final boolean[] flags = init(this.name());
private final SixFlags[] flippedFlags = new SixFlags[flags.length];
public final CharSequence description = concatenate("[", Describer.describe("flag", flags), "]").toString();
{
setup(this);
}
static class Header {
static final CharSequence LINE = "+------+-----------+-----------+-----------------------------------------------+\n";
static final CharSequence HEADER = concatenate(LINE, "| | flags | flippedFlags |\n", LINE);
static final CharSequence HEADER_2 = concatenate("|flag |key |", header("|"), header(" |"), "\n");
static CharSequence header(String filler) {
return stringify(intArray(YYYYYY.flippedFlags.length), i -> i + filler);
}
}
static class Describer {
static CharSequence describe() {
return concatenate(HEADER, HEADER_2, LINE, displayAll(), LINE, HEADER_2, HEADER);
}
static CharSequence describe(SixFlags flag) {
return concatenate("|", flag.name(), "|0b", encodeAll(flag), "=", key(flag), "|", value(flag), "|", flippedFlags(flag), " |\n");
}
static CharSequence displayAll() {
return stringify(SixFlags.values(), SixFlags::describe);
}
static CharSequence flippedFlags(SixFlags flag) {
return on(" |").join(flag.flippedFlags);
}
static CharSequence value(SixFlags flag) {
return on("|").join(flag.name().split(""));
}
static CharSequence key(SixFlags flag) {
int key = Initializer.encodeAll(flag.flags);
return concatenate((key < 10 ? " " : ""), key);
}
static CharSequence encodeAll(SixFlags flag) {
StringBuilder sb = new StringBuilder();
for (int i = flag.flags.length - 1; i >= 0; i--) {
sb.append(flag.flags[i] ? "1" : "0");
}
return sb;
}
static CharSequence describe(boolean flags[], Enum... indexes) {
return removeLastChar(stringify(indexes, index -> concatenate(flags[index.ordinal()] ? "" : "!", index, ",")));
}
static CharSequence describe(String desc, boolean[] flags) {
return removeLastChar(stringify(intArray(flags.length), i -> concatenate(flags[i] ? "" : "!", desc + i, ",")));
}
}
static class Initializer {
static void setup(SixFlags flag) {
lookup.put(encodeAll(flag.flags), flag);
if (lookup.size() == pow(2, flag.flags.length)) {
lookup.keySet().forEach(key -> flipFlags(key));
lookup.clear();
lookup = null;
}
}
public static void flipFlags(int key) {
SixFlags original = lookup.get(key);
int mask = 1;
for (int i = 0; i < original.flags.length; i++) {
int flippedKey = original.flags[i] ? key ^ mask : key | mask;
mask <<= 1;
SixFlags flipped = lookup.get(flippedKey);
original.flippedFlags[i] = flipped;
flipped.flippedFlags[i] = original;
}
}
static boolean[] init(String name) {
char[] chars = name.toCharArray();
boolean[] flags = new boolean[chars.length];
for (int i = 0; i < chars.length; i++) {
flags[i] = chars[i] == 'Y';
}
return flags;
}
static int encodeAll(boolean[] flags) {
int code = 0;
int mask = 1;
for (boolean flag : flags) {
if (flag) {
code |= mask;
}
mask <<= 1;
}
return code;
}
static Map<Integer, SixFlags> lookup = new HashMap<>();
}
}
Sunday, May 4, 2014
sixflags over java 8
I rewrote this using Java 8, if you see -> in the code, that's lambda expression from Java 8,
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment