Created
March 29, 2016 08:25
-
-
Save cyclotimia/2f7d29f846f48edae511 to your computer and use it in GitHub Desktop.
Prrof that k-hypercube is k-connected using Menger theorem
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Докажите, что 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