/* package whatever; // don't place package name! */
import java.util.*;
import java.lang.*;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
/* Name of the class has to be "Main" only if the class is public. */
class Ideone
{
{
new Pair
(new ArrayList
<>(List.
of(new Endpoint
("p1",
1000),
new Endpoint
("p2",
2000)))),
new Pair
(new ArrayList
<>(List.
of(new Endpoint
("p1",
3000),
new Endpoint
("p3",
4000)))),
new Pair
(new ArrayList
<>(List.
of(new Endpoint
("p2",
5000),
new Endpoint
("p3",
6000)))),
new Pair
(new ArrayList
<>(List.
of(new Endpoint
("p1",
2000),
new Endpoint
("p2",
3000)))),
new Pair
(new ArrayList
<>(List.
of(new Endpoint
("p1",
2001),
new Endpoint
("p2",
3001)))),
new Pair
(new ArrayList
<>(List.
of(new Endpoint
("p1",
4000),
new Endpoint
("p3",
5000)))),
new Pair
(new ArrayList
<>(List.
of(new Endpoint
("p1",
4001),
new Endpoint
("p3",
5001)))),
new Pair
(new ArrayList
<>(List.
of(new Endpoint
("p2",
6000),
new Endpoint
("p3",
7000)))),
new Pair
(new ArrayList
<>(List.
of(new Endpoint
("p2",
6001),
new Endpoint
("p3",
7001)))) ));
System.
out.
println("Input: "); for (Pair p : pairs) {
}
List<CustomPair> listRes = pairs.stream()
.collect(Collectors.groupingBy(Pair::getPairKeys)) //Grouping the Pairs by the keys of the two EndPoints (key1:key2)
.entrySet().stream() //Streaming the entries of the map
.map(entry -> {
String key1
= null, key2
= null;
//Lists for the values of the CustomEndpoint
List<Integer> listValues1 = new ArrayList<>();
List<Integer> listValues2 = new ArrayList<>();
//Retrieving the keys and adding each pair's number to the respective lists
for (Pair p : entry.getValue()) {
key1 = p.getPair().get(0).getKey();
key2 = p.getPair().get(1).getKey();
listValues1.add(p.getPair().get(0).getNumber());
listValues2.add(p.getPair().get(1).getNumber());
}
//Returning the new CustomPair in place of the two grouped by Pair
return new CustomPair
(new ArrayList
<>(List.
of( new CustomEndpoint(key1, listValues1),
new CustomEndpoint(key2, listValues2))));
})
.
sorted(Comparator.
comparing(CustomPair
::getFirstPairInitialNumber
)) //Ordering the CustomPair by the beginning of their endpoint range .collect(Collectors.toList()); //Collecting the CustomPair
System.
out.
println("\nOutput: "); for (CustomPair cp : listRes) {
}
}
static class Endpoint {
this.key = key;
this.number = number;
}
return key;
}
return number;
}
@Override
public boolean equals
(Object o
) { if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Endpoint other = (Endpoint) o;
return Objects.equals(key, other.key) && Objects.equals(number, other.number);
}
@Override
public int hashCode() {
return Objects.hash(key, number);
}
@Override
return String.
format("{%s,%d}", key, number
); }
}
static class Pair {
// It will have exactly 2 entries
List<Endpoint> pair;
public Pair(List<Endpoint> pair) {
this.pair = pair;
}
public List<Endpoint> getPair() {
return pair;
}
if (pair == null || pair.size() < 2) {
return null;
}
Endpoint e1 = pair.get(0);
Endpoint e2 = pair.get(1);
return String.
format("%s:%s", e1.
getKey(), e2.
getKey()); }
@Override
public boolean equals
(Object o
) { if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Pair other = (Pair) o;
return Objects.equals(pair, other.pair);
}
@Override
public int hashCode() {
return Objects.hash(pair);
}
@Override
return String.
format("%s", pair
); }
}
static class CustomEndpoint {
private List<Integer> numbers;
public CustomEndpoint
(String key, List
<Integer
> numbers
) { this.key = key;
this.numbers = numbers;
}
public List<Integer> getNumbers() {
return numbers;
}
@Override
return String.
format("{%s,%s}", key, numbers
); }
}
static class CustomPair {
// It will have exactly 2 entries
List<CustomEndpoint> pair;
public CustomPair(List<CustomEndpoint> pair) {
this.pair = pair;
}
public Integer getFirstPairInitialNumber
() { return pair.get(0).getNumbers().get(0);
}
@Override
return pair.toString();
}
}
}
LyogcGFja2FnZSB3aGF0ZXZlcjsgLy8gZG9uJ3QgcGxhY2UgcGFja2FnZSBuYW1lISAqLwoKaW1wb3J0IGphdmEudXRpbC4qOwppbXBvcnQgamF2YS5sYW5nLio7CmltcG9ydCBqYXZhLmlvLio7CmltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OwppbXBvcnQgamF2YS51dGlsLkxpc3Q7CmltcG9ydCBqYXZhLnV0aWwuT2JqZWN0czsKaW1wb3J0IGphdmEudXRpbC5zdHJlYW0uQ29sbGVjdG9yczsKaW1wb3J0IGphdmEudXRpbC5zdHJlYW0uSW50U3RyZWFtOwoKLyogTmFtZSBvZiB0aGUgY2xhc3MgaGFzIHRvIGJlICJNYWluIiBvbmx5IGlmIHRoZSBjbGFzcyBpcyBwdWJsaWMuICovCmNsYXNzIElkZW9uZQp7CglwdWJsaWMgc3RhdGljIHZvaWQgbWFpbiAoU3RyaW5nW10gYXJncykgdGhyb3dzIGphdmEubGFuZy5FeGNlcHRpb24KCXsKCQlMaXN0PFBhaXI+IHBhaXJzID0gbmV3IEFycmF5TGlzdChMaXN0Lm9mKAogICAgICAgICAgICAgICAgbmV3IFBhaXIobmV3IEFycmF5TGlzdDw+KExpc3Qub2YobmV3IEVuZHBvaW50KCJwMSIsIDEwMDApLCBuZXcgRW5kcG9pbnQoInAyIiwgMjAwMCkpKSksCiAgICAgICAgICAgICAgICBuZXcgUGFpcihuZXcgQXJyYXlMaXN0PD4oTGlzdC5vZihuZXcgRW5kcG9pbnQoInAxIiwgMzAwMCksIG5ldyBFbmRwb2ludCgicDMiLCA0MDAwKSkpKSwKICAgICAgICAgICAgICAgIG5ldyBQYWlyKG5ldyBBcnJheUxpc3Q8PihMaXN0Lm9mKG5ldyBFbmRwb2ludCgicDIiLCA1MDAwKSwgbmV3IEVuZHBvaW50KCJwMyIsIDYwMDApKSkpLAogICAgICAgICAgICAgICAgbmV3IFBhaXIobmV3IEFycmF5TGlzdDw+KExpc3Qub2YobmV3IEVuZHBvaW50KCJwMSIsIDIwMDApLCBuZXcgRW5kcG9pbnQoInAyIiwgMzAwMCkpKSksCiAgICAgICAgICAgICAgICBuZXcgUGFpcihuZXcgQXJyYXlMaXN0PD4oTGlzdC5vZihuZXcgRW5kcG9pbnQoInAxIiwgMjAwMSksIG5ldyBFbmRwb2ludCgicDIiLCAzMDAxKSkpKSwKICAgICAgICAgICAgICAgIG5ldyBQYWlyKG5ldyBBcnJheUxpc3Q8PihMaXN0Lm9mKG5ldyBFbmRwb2ludCgicDEiLCA0MDAwKSwgbmV3IEVuZHBvaW50KCJwMyIsIDUwMDApKSkpLAogICAgICAgICAgICAgICAgbmV3IFBhaXIobmV3IEFycmF5TGlzdDw+KExpc3Qub2YobmV3IEVuZHBvaW50KCJwMSIsIDQwMDEpLCBuZXcgRW5kcG9pbnQoInAzIiwgNTAwMSkpKSksCiAgICAgICAgICAgICAgICBuZXcgUGFpcihuZXcgQXJyYXlMaXN0PD4oTGlzdC5vZihuZXcgRW5kcG9pbnQoInAyIiwgNjAwMCksIG5ldyBFbmRwb2ludCgicDMiLCA3MDAwKSkpKSwKICAgICAgICAgICAgICAgIG5ldyBQYWlyKG5ldyBBcnJheUxpc3Q8PihMaXN0Lm9mKG5ldyBFbmRwb2ludCgicDIiLCA2MDAxKSwgbmV3IEVuZHBvaW50KCJwMyIsIDcwMDEpKSkpCiAgICAgICAgKSk7CgogICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiSW5wdXQ6ICIpOwogICAgICAgIGZvciAoUGFpciBwIDogcGFpcnMpIHsKICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKHApOwogICAgICAgIH0KCiAgICAgICAgTGlzdDxDdXN0b21QYWlyPiBsaXN0UmVzID0gcGFpcnMuc3RyZWFtKCkKICAgICAgICAgICAgICAgIC5jb2xsZWN0KENvbGxlY3RvcnMuZ3JvdXBpbmdCeShQYWlyOjpnZXRQYWlyS2V5cykpICAvL0dyb3VwaW5nIHRoZSBQYWlycyBieSB0aGUga2V5cyBvZiB0aGUgdHdvIEVuZFBvaW50cyAoa2V5MTprZXkyKQogICAgICAgICAgICAgICAgLmVudHJ5U2V0KCkuc3RyZWFtKCkgICAgLy9TdHJlYW1pbmcgdGhlIGVudHJpZXMgb2YgdGhlIG1hcAogICAgICAgICAgICAgICAgLm1hcChlbnRyeSAtPiB7CiAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGtleTEgPSBudWxsLCBrZXkyID0gbnVsbDsKCiAgICAgICAgICAgICAgICAgICAgLy9MaXN0cyBmb3IgdGhlIHZhbHVlcyBvZiB0aGUgQ3VzdG9tRW5kcG9pbnQKICAgICAgICAgICAgICAgICAgICBMaXN0PEludGVnZXI+IGxpc3RWYWx1ZXMxID0gbmV3IEFycmF5TGlzdDw+KCk7CiAgICAgICAgICAgICAgICAgICAgTGlzdDxJbnRlZ2VyPiBsaXN0VmFsdWVzMiA9IG5ldyBBcnJheUxpc3Q8PigpOwoKICAgICAgICAgICAgICAgICAgICAvL1JldHJpZXZpbmcgdGhlIGtleXMgYW5kIGFkZGluZyBlYWNoIHBhaXIncyBudW1iZXIgdG8gdGhlIHJlc3BlY3RpdmUgbGlzdHMKICAgICAgICAgICAgICAgICAgICBmb3IgKFBhaXIgcCA6IGVudHJ5LmdldFZhbHVlKCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAga2V5MSA9IHAuZ2V0UGFpcigpLmdldCgwKS5nZXRLZXkoKTsKICAgICAgICAgICAgICAgICAgICAgICAga2V5MiA9IHAuZ2V0UGFpcigpLmdldCgxKS5nZXRLZXkoKTsKCiAgICAgICAgICAgICAgICAgICAgICAgIGxpc3RWYWx1ZXMxLmFkZChwLmdldFBhaXIoKS5nZXQoMCkuZ2V0TnVtYmVyKCkpOwogICAgICAgICAgICAgICAgICAgICAgICBsaXN0VmFsdWVzMi5hZGQocC5nZXRQYWlyKCkuZ2V0KDEpLmdldE51bWJlcigpKTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIC8vUmV0dXJuaW5nIHRoZSBuZXcgQ3VzdG9tUGFpciBpbiBwbGFjZSBvZiB0aGUgdHdvIGdyb3VwZWQgYnkgUGFpcgogICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgQ3VzdG9tUGFpcihuZXcgQXJyYXlMaXN0PD4oTGlzdC5vZigKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBDdXN0b21FbmRwb2ludChrZXkxLCBsaXN0VmFsdWVzMSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgQ3VzdG9tRW5kcG9pbnQoa2V5MiwgbGlzdFZhbHVlczIpKSkpOwogICAgICAgICAgICAgICAgfSkKICAgICAgICAgICAgICAgIC5zb3J0ZWQoQ29tcGFyYXRvci5jb21wYXJpbmcoQ3VzdG9tUGFpcjo6Z2V0Rmlyc3RQYWlySW5pdGlhbE51bWJlcikpICAgIC8vT3JkZXJpbmcgdGhlIEN1c3RvbVBhaXIgYnkgdGhlIGJlZ2lubmluZyBvZiB0aGVpciBlbmRwb2ludCByYW5nZQogICAgICAgICAgICAgICAgLmNvbGxlY3QoQ29sbGVjdG9ycy50b0xpc3QoKSk7ICAvL0NvbGxlY3RpbmcgdGhlIEN1c3RvbVBhaXIKCiAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJcbk91dHB1dDogIik7CiAgICAgICAgZm9yIChDdXN0b21QYWlyIGNwIDogbGlzdFJlcykgewogICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oY3ApOwogICAgICAgIH0KICAgIH0KCiAgICBzdGF0aWMgY2xhc3MgRW5kcG9pbnQgewogICAgICAgIHByaXZhdGUgU3RyaW5nIGtleTsKICAgICAgICBwcml2YXRlIEludGVnZXIgbnVtYmVyOwoKICAgICAgICBwdWJsaWMgRW5kcG9pbnQoU3RyaW5nIGtleSwgSW50ZWdlciBudW1iZXIpIHsKICAgICAgICAgICAgdGhpcy5rZXkgPSBrZXk7CiAgICAgICAgICAgIHRoaXMubnVtYmVyID0gbnVtYmVyOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIFN0cmluZyBnZXRLZXkoKSB7CiAgICAgICAgICAgIHJldHVybiBrZXk7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgSW50ZWdlciBnZXROdW1iZXIoKSB7CiAgICAgICAgICAgIHJldHVybiBudW1iZXI7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG8pIHsKICAgICAgICAgICAgaWYgKHRoaXMgPT0gbykgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIGlmIChvID09IG51bGwgfHwgZ2V0Q2xhc3MoKSAhPSBvLmdldENsYXNzKCkpIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgRW5kcG9pbnQgb3RoZXIgPSAoRW5kcG9pbnQpIG87CiAgICAgICAgICAgIHJldHVybiBPYmplY3RzLmVxdWFscyhrZXksIG90aGVyLmtleSkgJiYgT2JqZWN0cy5lcXVhbHMobnVtYmVyLCBvdGhlci5udW1iZXIpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgICAgICAgcmV0dXJuIE9iamVjdHMuaGFzaChrZXksIG51bWJlcik7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewogICAgICAgICAgICByZXR1cm4gU3RyaW5nLmZvcm1hdCgieyVzLCVkfSIsIGtleSwgbnVtYmVyKTsKICAgICAgICB9CiAgICB9CgogICAgc3RhdGljIGNsYXNzIFBhaXIgewogICAgICAgIC8vIEl0IHdpbGwgaGF2ZSBleGFjdGx5IDIgZW50cmllcwogICAgICAgIExpc3Q8RW5kcG9pbnQ+IHBhaXI7CgogICAgICAgIHB1YmxpYyBQYWlyKExpc3Q8RW5kcG9pbnQ+IHBhaXIpIHsKICAgICAgICAgICAgdGhpcy5wYWlyID0gcGFpcjsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBMaXN0PEVuZHBvaW50PiBnZXRQYWlyKCkgewogICAgICAgICAgICByZXR1cm4gcGFpcjsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0UGFpcktleXMoKSB7CiAgICAgICAgICAgIGlmIChwYWlyID09IG51bGwgfHwgcGFpci5zaXplKCkgPCAyKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgRW5kcG9pbnQgZTEgPSBwYWlyLmdldCgwKTsKICAgICAgICAgICAgRW5kcG9pbnQgZTIgPSBwYWlyLmdldCgxKTsKCiAgICAgICAgICAgIHJldHVybiBTdHJpbmcuZm9ybWF0KCIlczolcyIsIGUxLmdldEtleSgpLCBlMi5nZXRLZXkoKSk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG8pIHsKICAgICAgICAgICAgaWYgKHRoaXMgPT0gbykgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIGlmIChvID09IG51bGwgfHwgZ2V0Q2xhc3MoKSAhPSBvLmdldENsYXNzKCkpIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgUGFpciBvdGhlciA9IChQYWlyKSBvOwogICAgICAgICAgICByZXR1cm4gT2JqZWN0cy5lcXVhbHMocGFpciwgb3RoZXIucGFpcik7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICAgICAgICByZXR1cm4gT2JqZWN0cy5oYXNoKHBhaXIpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKICAgICAgICAgICAgcmV0dXJuIFN0cmluZy5mb3JtYXQoIiVzIiwgcGFpcik7CiAgICAgICAgfQogICAgfQoKICAgIHN0YXRpYyBjbGFzcyBDdXN0b21FbmRwb2ludCB7CiAgICAgICAgcHJpdmF0ZSBTdHJpbmcga2V5OwogICAgICAgIHByaXZhdGUgTGlzdDxJbnRlZ2VyPiBudW1iZXJzOwoKICAgICAgICBwdWJsaWMgQ3VzdG9tRW5kcG9pbnQoU3RyaW5nIGtleSwgTGlzdDxJbnRlZ2VyPiBudW1iZXJzKSB7CiAgICAgICAgICAgIHRoaXMua2V5ID0ga2V5OwogICAgICAgICAgICB0aGlzLm51bWJlcnMgPSBudW1iZXJzOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIExpc3Q8SW50ZWdlcj4gZ2V0TnVtYmVycygpIHsKICAgICAgICAgICAgcmV0dXJuIG51bWJlcnM7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewogICAgICAgICAgICByZXR1cm4gU3RyaW5nLmZvcm1hdCgieyVzLCVzfSIsIGtleSwgbnVtYmVycyk7CiAgICAgICAgfQogICAgfQoKICAgIHN0YXRpYyBjbGFzcyBDdXN0b21QYWlyIHsKICAgICAgICAvLyBJdCB3aWxsIGhhdmUgZXhhY3RseSAyIGVudHJpZXMKICAgICAgICBMaXN0PEN1c3RvbUVuZHBvaW50PiBwYWlyOwoKICAgICAgICBwdWJsaWMgQ3VzdG9tUGFpcihMaXN0PEN1c3RvbUVuZHBvaW50PiBwYWlyKSB7CiAgICAgICAgICAgIHRoaXMucGFpciA9IHBhaXI7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgSW50ZWdlciBnZXRGaXJzdFBhaXJJbml0aWFsTnVtYmVyKCkgewogICAgICAgICAgICByZXR1cm4gcGFpci5nZXQoMCkuZ2V0TnVtYmVycygpLmdldCgwKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CiAgICAgICAgICAgIHJldHVybiBwYWlyLnRvU3RyaW5nKCk7CiAgICAgICAgfQogICAgfQp9
Input:
[{p1,1000}, {p2,2000}]
[{p1,3000}, {p3,4000}]
[{p2,5000}, {p3,6000}]
[{p1,2000}, {p2,3000}]
[{p1,2001}, {p2,3001}]
[{p1,4000}, {p3,5000}]
[{p1,4001}, {p3,5001}]
[{p2,6000}, {p3,7000}]
[{p2,6001}, {p3,7001}]
Output:
[{p1,[1000, 2000, 2001]}, {p2,[2000, 3000, 3001]}]
[{p1,[3000, 4000, 4001]}, {p3,[4000, 5000, 5001]}]
[{p2,[5000, 6000, 6001]}, {p3,[6000, 7000, 7001]}]