축약되지 않은 IPv6주소는 32자리의 16진수 숫자를 4자리씩 끊어서 표현된다. 이때 4자리마다 :으로 구분된다. 예를 들어 2001:0db8:85a3:0000:0000:8a2e:0370:7334 으로 표현된다. 이때 각 4자리에서 앞선 0은 생략될 수 있다. 0db8은 db8으로 축약될 수 있다. 연속된 0은 ::으로 표현될 수 있다. 예를 들어 0000:0000:0000:1111:1111:1111:0001:0011은 ::1111:1111:1111:1:1으로 표현될 수 있다. 하지만 ::은 한 번만 사용할 수 있다.
입력으로 축약된 IPv6 주소가 주어질 때 축약되지 않은 주소를 출력하면 된다.
주어진 입력을 4가지 경우로 나누어서 생각할 수 있다. ::인 경우 ::가 앞에 나온 경우 ::가 뒤에 나온 경우 ::가 중간에 나온 경우로 생각할 수 있다.
::인 경우
::인 경우에는 그냥 0000 8개를 만들어서 :으로 이어주면 된다.
Ex) :: -> 0000:0000:0000:0000:0000:0000:0000:0000
::이 앞에 나온 경우
::을 제외한 나머지 문자열을 :으로 분리하면 N개가 나온다. 그러면 8 - N만큼의 0000을 앞에 먼저 생성한다. 이후에는 분리된 각 문자열에 0을 붙이면서 4자리로 채워준다.
Ex) ::1:1 -> {1, 1} -> 0000:0000:0000:0000:0000:0000:0001:00001
::이 뒤에 나온 경우
::이 앞에 나온 경우랑 동일하게 하지만 순서만 바뀐다.
Ex) 1:1:: -> {1, 1} -> 0001:0001:0000:0000:0000:0000:0000:0000
::이 중간에 나온 경우
전체 문자열을 :으로 분리하고 중간에 빈 문자열은 9 - N개의 0000으로 변환한다.
Ex) 1:1::1 -> {1, 1, , 1} -> 0001:0001:0000:0000:0000:0000:0000:0001
String in = reader.readLine();
List<String> out = new ArrayList<>();
if (in.equals("::")) {
Stream.generate(() -> "0000").limit(8).forEach(out::add);
} else if (in.startsWith("::")) {
String[] parts = in.substring(2).split(":");
Stream.generate(() -> "0000").limit(8 - parts.length).forEach(out::add);
for (String part : parts) out.add("0".repeat(4 - part.length()) + part);
} else if (in.endsWith("::")) {
String[] parts = in.substring(0, in.length() - 2).split(":");
for (String part : parts) out.add("0".repeat(4 - part.length()) + part);
Stream.generate(() -> "0000").limit(8 - parts.length).forEach(out::add);
} else {
String[] parts = in.split(":");
for (String part : parts) {
if (part.length() == 0) {
Stream.generate(() -> "0000").limit(9 - parts.length).forEach(out::add);
} else {
out.add("0".repeat(4 - part.length()) + part);
}
}
}
result.append(String.join(":", out));