Skip to content

Instantly share code, notes, and snippets.

@cyclotimia
Created March 29, 2016 08:25
Show Gist options
  • Save cyclotimia/2f7d29f846f48edae511 to your computer and use it in GitHub Desktop.
Save cyclotimia/2f7d29f846f48edae511 to your computer and use it in GitHub Desktop.
Prrof that k-hypercube is k-connected using Menger theorem
/*
Докажите, что k-мерный гиперкуб k-связен с помощью теоремы Менгера.
k-мерным гиперкубом называется граф, в котором вершины — битовые строки длины k,
а рёбра проведены между теми парами вершин, которые отличаются ровно в одном бите.
На вход подаётся две различные битовых строки A и B длины k<100 через пробел.
Выведите k простых путей в k-мерном гиперкубе из A в B, не пересекающихся по
внутренним вершинам.
Формат вывода: один путь на строку; путь – последовательности битовых строк, разделённая пробелами.
Sample Input 1:
1010 0010
Sample Output 1:
1010 0010
1010 1011 0011 0010
1010 1000 0000 0010
1010 1110 0110 0010
Sample Input 2:
0 1
Sample Output 2:
0 1
*/
import java.util.*;
import java.util.function.*;
import java.util.stream.*;
class ArrayWrapper {
private Boolean[] array;
public ArrayWrapper(final String str) {
array = new Boolean[str.length()];
for (int i = 0; i < str.length(); i++) {
if (str.charAt(i) == '1') {
array[i] = true;
} else {
array[i] = false;
}
}
}
public ArrayWrapper(final Boolean[] array) {
this.array = Arrays.copyOf(array, array.length);
}
public int length() {
return array.length;
}
public ArrayWrapper flipAtIdx(final int idx) {
final Boolean[] newArr = Arrays.copyOf(array, array.length);
newArr[idx] = !newArr[idx];
return new ArrayWrapper(newArr);
}
public long distanceTo(final ArrayWrapper other) {
return IntStream.range(0, array.length)
.mapToObj((i) -> array[i] != other.array[i])
.filter((v) -> v)
.count();
}
@Override
public String toString() {
return Arrays.stream(array)
.map((v) -> v ? "1" : "0")
.reduce(String::concat)
.orElseGet(() -> "NONE");
}
@Override
public boolean equals(final Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ArrayWrapper that = (ArrayWrapper) o;
return Arrays.equals(array, that.array);
}
@Override
public int hashCode() {
return Arrays.hashCode(array);
}
}
public class Main {
public static List<Supplier<ArrayWrapper>> invertOneByte(final ArrayWrapper arr) {
final List<Supplier<ArrayWrapper>> result = new ArrayList<>();
for (int i = 0; i < arr.length(); i++) {
final int ii = i;
result.add(() -> arr.flipAtIdx(ii));
}
return result;
}
public static void findPath(final ArrayWrapper from, final ArrayWrapper to) {
final Set<ArrayWrapper> visited = new HashSet<>();
visited.add(from);
for (int i = 0; i < from.length(); i++) {
findPathAux(from, to, visited).forEach(v -> System.out.print(v + " "));
System.out.println();
}
}
private static List<ArrayWrapper> findPathAux(final ArrayWrapper from, final ArrayWrapper to, final Set<ArrayWrapper> visited) {
final List<ArrayWrapper> path = new ArrayList<>();
path.add(from);
ArrayWrapper curr = from;
while (!to.equals(curr)) {
visited.add(curr);
long boundDist = curr.distanceTo(to) - 1;
long bestDist = Long.MAX_VALUE;
ArrayWrapper bestStep = null;
for (final Supplier<ArrayWrapper> ss : invertOneByte(curr)) {
final ArrayWrapper step = ss.get();
if (visited.contains(step)) continue;
long stepDist = step.distanceTo(to);
if (stepDist < bestDist) {
bestStep = step;
bestDist = stepDist;
}
if (bestDist <= boundDist) {
break;
}
}
if (null == bestStep) return null;
curr = bestStep;
path.add(curr);
}
return path;
}
public static void main(String[] args) {
final Scanner scanner = new Scanner(System.in);
final String start = scanner.next();
final String end = scanner.next();
final ArrayWrapper a = new ArrayWrapper(start);
final ArrayWrapper b = new ArrayWrapper(end);
findPath(a, b);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment