КОД
КОД
Лістинг програми
public class Digit implements Comparable<Digit> {
int value;
String glyph;
@Nullable
public static Digit create(@NotNull String s) {
return new Digit(getValueOf(s), s);
}
@Override
public boolean equals(Object obj) {
if (obj.getClass().isAssignableFrom(Digit.class)) {
Digit d = (Digit) obj;
return d.value == getValue() &&
d.getGlyph().equalsIgnoreCase(getGlyph());
}
return super.equals(obj);
}
@Override
public Digit get(String glyph) {
for (Digit d:digits) {if (d.getGlyph().equalsIgnoreCase(glyph))
return d;}
return null;
}
sb.append(d.getGlyph()).append('(').append(d.getValue()).append(')');
}
sb.append(" ]]");
return sb.toString();
}
@Override
public int maxValue() { return maxValue; }
@Override
public int minValue() { return minValue; }
}
public CodeSequence() { }
public CodeSequence(List<Digit> code) { this.code = code; }
public CodeSequence(Digit... digits)
{this(Arrays.asList(reverse(digits)));}
public int size(){return this.code.size();}
public boolean isEmpty(){return this.code.isEmpty();}
public Digit get(int index){return this.code.get(index);}
public Digit getLower(){ return this.code.get(0);}
public Digit getHigher() { return this.code.get(this.size()-1);}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder();
for (Digit d:code) { sb.append(d); }
return sb.reverse().toString();
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null) return false;
if (!(o instanceof CodeSequence)) return false;
CodeSequence that = (CodeSequence) o;
for (int i = 0; i < size(); i++) {
if (!that.get(i).equals(this.get(i))) return false;
}
return true;
}
@Override
public int hashCode() {return code.hashCode();}
public List<Digit> values(){ return copy(this.code); }
public CodeSequence copy(){ return new CodeSequence(this.values()); }
public CodeSequence copy(int from, int to){ return new
CodeSequence(copy(this.code, from, to)); }
public CodeSequence copyHigher(int from){ return copy(from, size()); }
public CodeSequence copyLower(int to){ return copy(0, to); }
public CodeSequence[] split(int point){ return split(this, point); }
public CodeSequence concat(CodeSequence higherPart){ return concat(this,
higherPart); }
public CodeSequence addLower(Digit d){ return addLower(this, d); }
public CodeSequence addHigher(Digit d){ return addHigher(this, d); }
public CodeSequence addLower(Digit... d){ return concat(new
CodeSequence(d), this); }
public CodeSequence addHigher(Digit... d){ return concat(this, new
CodeSequence(d)); }
public CodeSequence exchange(Digit d, int index){return exchange(this, d,
index);}
public CodeSequence swap(int i, int j){return swap(this, i, j);}
public CodeSequence reverse(){ return reverse(this);}
public CodeSequence shiftLeft(){ return shiftLeft(this); }
public CodeSequence shiftRight(){ return shiftRight(this); }
public CodeSequence shiftLeft(Digit insertion){ return shiftLeft(this,
insertion); }
public CodeSequence shiftRight(Digit insertion){ return shiftRight(this,
insertion); }
//--------------------------------------------------------------
//COPY
public static List<Digit> copy(List<Digit> src){
List<Digit> dest = new ArrayList<>(src.size());
dest.addAll(src);
return dest;
}
public static List<Digit> copy(List<Digit> src, int from, int to){
List<Digit> dest = new ArrayList<>(src.size());
for (int i = from; i < to; i++)
if ((i>=0)&&(i<src.size()))
dest.add(src.get(i));
return dest;
}
//CONCATENATION
public static CodeSequence concat(CodeSequence lowerPart, CodeSequence
higherPart){
CodeSequence cs = lowerPart.copy();
cs.code.addAll(higherPart.code);
return cs;
}
public static CodeSequence concat(List<Digit> lowerPart, List<Digit>
higherPart){
CodeSequence cs = new CodeSequence(lowerPart);
cs.code.addAll(higherPart);
return cs;
}
public static CodeSequence addHigher(CodeSequence sequence, Digit d){
CodeSequence cs = sequence.copy();
cs.code.add(d);
return cs;
}
public static CodeSequence addLower(CodeSequence sequence, Digit d){
CodeSequence cs = new CodeSequence();
cs.code.add(d);
cs.code.addAll(sequence.code);
return cs;
}
//SPLIT
public static CodeSequence[] split(CodeSequence sequence, int point){
return new CodeSequence[]{sequence.copyLower(point),
sequence.copyHigher(point)};
}
//EXCHANGE
public static CodeSequence exchange(CodeSequence src, Digit d, int index)
{
CodeSequence cs = src.copy();
if ((index<0)||(index>=src.size())) return cs;
else{
cs.code.set(index, d);
return cs;
}
}
//SWAP
public static CodeSequence swap(CodeSequence src, int i, int j){
CodeSequence cs = src.copy();
if ((i<=0)||(i>=src.size())) return cs;
if ((j<=0)||(j>=src.size())) return cs;
else{
cs.code.set(i, src.get(j));
cs.code.set(j, src.get(i));
return cs;
}
}
//SHIFT
public static CodeSequence shiftLeft(CodeSequence sequence){
return shiftLeft(sequence, sequence.getHigher());
}
public static CodeSequence shiftRight(CodeSequence sequence){
return shiftRight(sequence, sequence.getLower());
}
public static CodeSequence shiftLeft(CodeSequence sequence, Digit
insertion){
CodeSequence cs = sequence.copyLower(sequence.size()-1);
return cs.addLower(insertion);
}
public static CodeSequence shiftRight(CodeSequence sequence, Digit
insertion){
CodeSequence cs = sequence.copyHigher(1);
return cs.addHigher(insertion);
}
//REVERSE
@Contract(pure = true)
public static Digit[] reverse(Digit[] sequence){
Digit[] narr = new Digit[sequence.length];
for (int i = 0; i < sequence.length; i++) {
narr[i] = sequence[sequence.length - i - 1];
}
return narr;
}
@Override
default boolean hasLink(ID id, ID to) {
return hasMonoLink(id, to) || hasMonoLink(to, id);
}
@Override
default void link(ID id, ID to) {
addMonoLink(id, to);addMonoLink(to, id);
}
@Override
default void unlink(ID id, ID to) {
removeMonoLink(id, to);removeMonoLink(to, id);
}
}
public interface IndirectedFatLinks<ID> extends IndirectedLinks<ID>,
FatLinks<ID> {
int getMonoLink(ID id, ID to);
void addMonoLink(ID id, ID to, int weight);
@Override
default boolean hasMonoLink(ID id, ID to) { return getMonoLink(id, to) !=
0; }
@Override
default void addMonoLink(ID id, ID to) { addMonoLink(id, to, 1); }
@Override
default void removeMonoLink(ID id, ID to) { addMonoLink(id, to, 0); }
@Override
default boolean hasLink(ID id, ID to) {
return hasMonoLink(id, to) || hasMonoLink(to, id);
}
@Override
default int getLink(ID id, ID to) {
return Math.max(getMonoLink(id, to), getMonoLink(to, id));
}
@Override
default void link(ID id, ID to) {
addMonoLink(id, to, 1);addMonoLink(to, id, 1);
}
@Override
default void link(ID id, ID to, int weight) {
addMonoLink(id, to, weight);addMonoLink(to, id, weight);
}
@Override
default void unlink(ID id, ID to) {
addMonoLink(id, to, 0);addMonoLink(to, id, 0);
}
@Override
default HashMap<ID, Integer> getInputWeights(ID id) {
HashMap<ID, Integer> map = new HashMap<>();
for (ID from:getIDs()) {
int w = getMonoLink(from, id);
if (w != 0) map.put(from, w);
}
return map;
}
@Override
default HashMap<ID, Integer> getOutputWeights(ID id) {
HashMap<ID, Integer> map = new HashMap<>();
for (ID to:getIDs()) {
int w = getMonoLink(id, to);
if (w != 0) map.put(to, w);
}
return map;
}
default HashMap<ID, Integer> getWeights(ID id){
HashMap<ID, Integer> map = new HashMap<>();
for (ID target:getIDs()) {
int w = getLink(id, target);
if (w != 0) map.putIfAbsent(target, w);
}
return map;
}
@Override
default Set<ID> getLinks(ID id) {return getWeights(id).keySet();}
@Override
default void unlinkAll(ID id) { unlink(id, getLinks(id)); }
}
ublic abstract class MappedGraph<ID, V> implements Links<ID> {
protected HashMap<ID, V> links = new HashMap<>();
protected LinkedList<ID> ids = new LinkedList<>();
public MappedGraph() { }
public MappedGraph(Collection<ID> ids) { this.ids.addAll(ids); }
@Override
public int getN() { return ids.size(); }
@Override
public List<ID> getIDs() { return ids; }
@Override
public boolean isPossibleToAdd(ID id) { return !ids.contains(id); }
@Override
public boolean isPossibleToRemove(ID id) { return ids.contains(id); }
@Override
public void forcedAdd(ID id) { ids.addLast(id); }
@Override
public void forcedRemove(ID id) {unlinkAll(id);ids.remove(id);}
@Override
public void clear() {links.clear();ids.clear();}
@Override
public void clearLinks() { links.clear(); }
}
public class Topology<ID> extends MappedGraph<ID, HashMap<ID, Integer>>
implements IndirectedFatLinks<ID> {
public Topology() { }
public Topology(Collection<ID> ids) { super(ids); }
@Override
public int getMonoLink(ID id, ID to) {
return links.getOrDefault(id, new HashMap<>()).getOrDefault(to, 0);
}
@Override
public void addMonoLink(ID id, ID to, int weight) {
if (id.equals(to)) return;
HashMap<ID, Integer> map = links.getOrDefault(id, new HashMap<>());
map.put(to, weight);
links.putIfAbsent(id, map);
}
@Override
public void removeMonoLink(ID id, ID to) {
if (id.equals(to)) return;
if (!links.containsKey(id)) return;
HashMap<ID, Integer> map = links.get(id);
if (!map.containsKey(to)) return;
map.remove(to);
}
@Override
public String toString(){
StringBuilder sb = new StringBuilder();
sb.append("IDs: {").append(PConsole.collectionToStr(getIDs(),
";")).append("}\n");
sb.append("Links:\n").append(PConsole.deepMapToString(links, "\n", "-
>\t", "; ", "="));
return sb.toString();
}
}
public interface TopologyParametrizer<ID> {
Links<ID> topo();
default HashMap<ID, Integer> getDegrees(){
HashMap<ID, Integer> degrees = new HashMap<>();
for (ID id:topo().getIDs()) {
degrees.put(id, topo().getLinks(id).size());
}
return degrees;
}
default int getLinkAsDistance(ID id, ID to){return 1;}
default HashMap<ID, HashMap<ID, Integer>> getDistances(){
HashMap<ID, HashMap<ID, Integer>> dist = new HashMap<>();
for (ID id:topo().getIDs()) {
dist.put(id, getDistances(id));
}
return dist;
}
default HashMap<ID, Integer> getDistances(ID id){
HashMap<ID, Integer> map = new HashMap<>();
Set<ID> nexts = new HashSet<>(), next2 = new HashSet<>();
map.put(id, 0);
nexts.add(id);
while (!nexts.isEmpty()){
for (ID n:nexts) {
Set<ID> outs = topo().getOutputs(n);
int dist = map.get(n);
for (ID to:outs) {
int ndist = dist + getLinkAsDistance(n, to);
int pdist = map.getOrDefault(to, Integer.MAX_VALUE);
if (ndist<pdist){
map.put(to, ndist);
next2.add(to);
}
}
}
nexts = next2;
next2 = new HashSet<>();
}
if(map.size() < topo().getN()){
for (ID k:topo().getIDs()) {
map.putIfAbsent(k, Integer.MAX_VALUE);
}
}
return map;
}
default int getMax(HashMap<ID, Integer> map){
return Collections.max(map.values());
}
}
map.put(inner, m);
}
return result;
}
public void createLinks(Links<ID> topology,
Links<ID1> cluster,
Links<ID2> external,
HashMap<ID1, HashMap<ID2, ID>> map
){
List<ID1> inners = cluster.getIDs();
List<ID2> outers = external.getIDs();
for (int i = 0; i < inners.size()-1; i++) {
ID1 in1 = inners.get(i);
for (int j = 0; j < outers.size()-1; j++) {
ID2 out1 = outers.get(j);
ID id1 = map.get(in1).get(out1);
for (int k = i+1; k < inners.size(); k++) {
ID1 in2 = inners.get(k);
for (int l = j+1; l < outers.size(); l++) {
ID2 out2 = outers.get(l);
if (
((in1.equals(in2))&&(external.hasLink(out1, out2))) ||
((out1.equals(out2))&&(cluster.hasLink(in1, in2)))
){
ID id2 = map.get(in2).get(out2);
topology.link(id1, id2);
}
}
}
}
}
}
@Override
public Links<ID> build(Links<ID1> cluster, Links<ID2> external,
Object... args) {return build(cluster, external);}
public Links<ID> build(Links<ID1> cluster, Links<ID2> external){
HashMap<ID1, HashMap<ID2, ID>> map = new HashMap<>();
Links<ID> topo = createNew(cluster, external, map);
createLinks(topo, cluster, external, map);
return topo;
}
public static CartesianProductBuilder<Integer, Integer, Integer>
getIntBuilder(){
return new CartesianProductBuilder<Integer, Integer, Integer>(){
@Override
public Integer getID(Integer inner, Integer outer,
Links<Integer> cluster, Links<Integer> external) {return outer*cluster.getN()
+inner;}
};
}
public static CartesianProductBuilder<CodeSequence, CodeSequence,
CodeSequence> getCodeSeqBuilder(){
return new CartesianProductBuilder<CodeSequence, CodeSequence,
CodeSequence>(){
@Override
public CodeSequence getID(CodeSequence inner, CodeSequence
outer, Links<CodeSequence> cluster, Links<CodeSequence> external) {
return CodeSequence.concat(inner, outer);
}
};
}