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