こちらの問題 を Java で解きました。
他の方の解答例は こちらの記事 のコメント欄から見れます。
1 時間では解き切れなかったので敗北です。
package org.example;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class Solver {
public String solve(String src) {
var squares = new ArrayList<Square>();
Arrays.stream(src.split(",")).map(Integer::parseInt).forEach(length -> {
var nextX = Integer.MAX_VALUE / 2;
var nextY = Integer.MAX_VALUE / 2;
for (int x : xs(squares)) {
for (int y : ys(squares)) {
var square = new Square(new Point(x, y), length);
if (squares.stream().allMatch(s -> s.isNotOverlapped(square))) {
// できるだけ下 ( x + y が小さい ) または同じ高さ ( x + y が同じ ) でできるだけ左 ( y が大きい ) が見つかったか判定
boolean b = (x + y < nextX + nextY) || (x + y == nextX + nextY) && (nextY < y);
if (b) {
nextX = x;
nextY = y;
}
}
}
}
squares.add(new Square(new Point(nextX, nextY), length));
});
Square maxSquare = squares.stream().max(Comparator.comparingInt(Square::length)).get();
return squares
.stream()
.filter(maxSquare::isNeighbor)
.mapToInt(Square::length)
.sorted()
.mapToObj(String::valueOf)
.collect(Collectors.joining(","));
}
private List<Integer> xs(List<Square> squares) {
return Stream.concat(
Stream.of(0),
squares.stream().map(square -> square.point.x + square.length)
).distinct().toList();
}
private List<Integer> ys(List<Square> squares) {
return Stream.concat(
Stream.of(0),
squares.stream().map(square -> square.point.y + square.length)
).distinct().toList();
}
private record Point(int x, int y) {
}
private record Square(Point point, int length) {
public boolean isNotOverlapped(Square other) {
return (point.x + length <= other.point.x) || (other.point.x + other.length <= point.x) || (
point.y + length <= other.point.y) || (other.point.y + other.length <= point.y);
}
public boolean isNeighbor(Square other) {
if ((point.x + length == other.point.x) || (point.x == other.point.x + other.length)) {
return (other.point.y < point.y + length) && (point.y < other.point.y + other.length);
}
if ((point.y + length == other.point.y) || (point.y == other.point.y + other.length)) {
return (point.x < other.point.x + other.length) && (other.point.x < point.x + length);
}
return false;
}
}
}