/** * Constructs a K2 with the expected number of indices to hold (the number of A and number of B items is always * the same, and this will be more efficient if expected is greater than that number) and the load factor to use, * between 0.1f and 0.8f usually (using load factors higher than 0.8f can cause problems). * @param expected the amount of indices (the count of A items is the same as the count of B items) this should hold * @param f the load factor, probably between 0.1f and 0.8f */ public K2(int expected, float f) { keysA = new Arrangement<>(expected, f); keysB = new Arrangement<>(expected, f); }
public void putAll(K[] keyArray) { int n = keyArray.length; if (f <= .5) ensureCapacity(n); // The resulting map will be sized for // m.size() elements else tryCapacity(size() + n); // The resulting map will be // tentatively sized for size() + keyArray.length elements for (int i = 0; i < n; i++) { add(keyArray[i]); } }
/** * Adds an A key and a B key at the given index in the ordering to this K2. Neither a nor b can be * present in this collection before this is called. If you want to change or update an existing key, use * {@link #alterA(Object, Object)} or {@link #alterB(Object, Object)}. The index this is given should be at * least 0 and no greater than {@link #size()}. * @param index the point in the ordering to place a and b into; later entries will be shifted forward * @param a an A key to add; cannot already be present * @param b a B key to add; cannot already be present * @return true if this collection changed as a result of this call */ public boolean putAt(int index, A a, B b) { if(!keysA.containsKey(a) && !keysB.containsKey(b)) { keysA.addAt(index, a); keysB.addAt(index, b); return true; } return false; }
/** * Changes the K at the given index to replacement while keeping replacement at the same point in the ordering. * * @param index an index to replace the K key at * @param replacement another K key that will replace the original at the remembered index * @return the int associated with the possibly-altered key; should be equal to index */ public int alterAt(int index, K replacement) { return alter(keyAt(index), replacement); }
Arrangement<String> body = new Arrangement<>(corpus.length() / 5 + 5); body.add(INITIAL); body.add(FULL_STOP); body.add(EXCLAMATION); body.add(QUESTION); body.add(ELLIPSIS); ArrayList<IntVLA> working = new ArrayList<>(corpus.length() / 5 + 5); working.add(new IntVLA(128)); while (matcher.find()) current = body.addOrIndex(matcher.group()); if(working.size() != body.size()) final int len = working.size(); words = new String[len]; body.keySet().toArray(words); processed = new int[len][]; w = new IntVLA(128);
public int putInts(CharSequence name, int[][] item) { int i = names.getInt(name); if(i < 0) { i = names.size(); names.add(name); charMaps.add(null); intMaps.add(item); doubleMaps.add(null); floatMaps.add(null); } else { charMaps.set(i, null); intMaps.set(i, item); doubleMaps.set(i, null); floatMaps.set(i, null); } return i; } public int putDoubles(CharSequence name, double[][] item)
/** * Changes the A key at {@code index} to another A key, {@code future}, if index is valid and future does not * yet exist in this K2. The position in the ordering for future will be the same as index, and the same * as the key this replaced, if this succeeds, so the other key(s) at that position will still be associated in * the same way. * @param index a position in the ordering to change; must be at least 0 and less than {@link #size()} * @param future an A key, that cannot currently exist in this K2's A keys, but will if this succeeds * @return this for chaining */ public K2<A, B> alterAAt(int index, A future) { if(!keysA.containsKey(future) && index >= 0 && index < keysA.size) keysA.alter(keysA.keyAt(index), future); return this; }
/** * Constructor that allows you to specify the adjective and noun collections used by * {@link #toWordMnemonic(int, boolean)} as well as a seed. This should be useful when you want to enforce a stable * relationship between word mnemonics produced by {@link #toWordMnemonic(int, boolean)} and the int values they * decode to with {@link #fromWordMnemonic(String)}, because the default can change if the adjective and noun * collections in {@link Thesaurus} change. There should be a fairly large amount of unique adjectives and nouns; * {@code (long)adjectives.size() * nouns.size() * adjectives.size() * nouns.size()} should be at least 0x80000000L * (2147483648L), with case disregarded. If the total is less than that, not all possible ints can be encoded with * {@link #toWordMnemonic(int, boolean)}. Having 216 adjectives and 216 nouns is enough for a rough target. Each * word (adjectives and nouns alike) can have any characters in it except for space, since space is used during * decoding to separate words. * @param seed a long seed that will be used to randomize the syllables and words used. * @param adjectives a Collection of unique Strings (case-insensitive) that will be used as adjectives * @param nouns a Collection of unique Strings (case-insensitive) that will be used as nouns */ public Mnemonic(long seed, Collection<String> adjectives, Collection<String> nouns) { RNG rng = new RNG(new LightRNG(seed)); int[] order = rng.randomOrdering(431); int o; for (int i = 0; i < 256; i++) { o = order[i]; items.add(baseTriplets.substring(o * 3, o * 3 + 3)); } allAdjectives.putAll(adjectives); allAdjectives.shuffle(rng); allNouns.putAll(nouns); allNouns.shuffle(rng); } /**
/** * Produces a copy of this Arrangement, but only using up to the given amount of items to take. Does a shallow copy * of individual keys, so the references will be shared. * @param amount the number of items to copy from this Arrangement; will copy all items if greater than size * @return a new Arrangement with up to amount items copied from this into it. */ public Arrangement<K> take(int amount) { amount = Math.min(size, Math.max(0, amount)); Arrangement<K> nx = new Arrangement<>(amount, f); for (int i = 0; i < amount; i++) { nx.add(keyAt(i)); } return nx; } protected int positionOf(final Object k) {
names = new Arrangement<>(0); regions = new ArrayList<>(0); connections = new ArrayList<>(0); names.clear(); connections.clear(); GreasedRegion t, all = new GreasedRegion(map, 0); regions.add(all); names.add("unused0"); connections.add(new IntVLA(0)); for (int i = 0; i < rf.rooms.size(); i++) { regions.add(t); all.andNot(t); t.writeIntsInto(map, names.size()); names.add("room"+names.size()); connections.add(new IntVLA(rf.rooms.getAt(i).size())); regions.add(t); all.andNot(t); t.writeIntsInto(map, names.size()); names.add("corridor"+names.size()); connections.add(new IntVLA(rf.corridors.getAt(i).size())); regions.add(t); all.andNot(t); t.writeIntsInto(map, names.size()); names.add("cave"+names.size()); connections.add(new IntVLA(rf.caves.getAt(i).size()));
/** * Given an A object key, finds the position in the ordering that A has, or -1 if key is not present. * Unlike {@link java.util.List#indexOf(Object)}, this runs in constant time. * @param key the A to find the position of * @return the int index of key in the ordering, or -1 if it is not present */ public int indexOfA(Object key) { return keysA.getInt(key); } /**
if (original == null) { if (containsNullKey) { return alterNullEntry(replacement); return add(replacement); return getInt(original); K curr; final K[] key = this.key; return add(replacement); if (hasher.areEqual(original, curr)) return alterEntry(pos, replacement); while (true) { if ((curr = key[pos = (pos + 1) & mask]) == null) return add(replacement); if (hasher.areEqual(original, curr)) return alterEntry(pos, replacement);
/** * Changes an existing B key, {@code past}, to another B key, {@code future}, if past exists in this K2 * and future does not yet exist in this K2. This will retain past's point in the ordering for future, so * the associated other key(s) will still be associated in the same way. * @param past a B key, that must exist in this K2's B keys, and will be changed * @param future a B key, that cannot currently exist in this K2's B keys, but will if this succeeds * @return this for chaining */ public K2<A, B> alterB(B past, B future) { if(keysB.containsKey(past) && !keysB.containsKey(future)) keysB.alter(past, future); return this; }
/** * Given an int index, finds the associated B key (using index as a point in the ordering). * @param index an int index into this K2 * @return the B object with index for its position in the ordering, or null if index was invalid */ public B getBAt(int index) { return keysB.keyAt(index); }
/** * Returns true if this contains the A, key, in its collection of A items. * @param key the A to check the presence of * @return true if key is present in this; false otherwise */ public boolean containsA(A key) { return keysA.containsKey(key); } /**
/** * Adds an A key and a B key at the same point in the ordering (the end) to this K2. Neither parameter can be * present in this collection before this is called. If you want to change or update an existing key, use * {@link #alterA(Object, Object)} or {@link #alterB(Object, Object)}. * @param a an A key to add; cannot already be present * @param b a B key to add; cannot already be present * @return true if this collection changed as a result of this call */ public boolean put(A a, B b) { if(!keysA.containsKey(a) && !keysB.containsKey(b)) { keysA.add(a); keysB.add(b); return true; } return false; }
public K2(Arrangement<A> aItems, Arrangement<B> bItems) { if(aItems == null || bItems == null) { keysA = new Arrangement<>(); keysB = new Arrangement<>(); } else { int amt = Math.min(aItems.size, bItems.size); keysA = aItems.take(amt); keysB = bItems.take(amt); } } /**
/** * Gets and caches the B keys as a Collection that implements SortedSet (and so also implements Set). This Set is * shared with this collection; it is not a copy. * @return the B keys as a SortedSet */ public SortedSet<B> getSetB() { return keysB.keySet(); }