Skip to content

Commit

Permalink
day22
Browse files Browse the repository at this point in the history
i am getting really tired :(
  • Loading branch information
zebalu committed Dec 22, 2023
1 parent 2f37702 commit 3a09293
Show file tree
Hide file tree
Showing 2 changed files with 375 additions and 0 deletions.
219 changes: 219 additions & 0 deletions aoc2023/src/main/java/io/github/zebalu/aoc2023/days/Day22.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,219 @@
package io.github.zebalu.aoc2023.days;

import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.SequencedSet;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;

public class Day22 {
public static void main(String[] args) {
String input = readInput(); //example; //readInput();
System.out.println(input);
var bricks = input.lines().map(Brick::read).peek(System.out::println).toList();
System.out.println(bricks.size());
System.out.println("-------------------");
List<Brick> zOrdered = bricks.stream().sorted(Brick.Z_COMPARATOR).toList();
zOrdered.forEach(System.out::println);
Map<Brick, VerticalCounter> counterMap = new HashMap<>();
for(int i=0; i<zOrdered.size(); ++i) {
Brick lower = zOrdered.get(i);
counterMap.put(lower, new VerticalCounter(new AtomicInteger(0), new AtomicInteger(0)));
for(int j=i+1; j<zOrdered.size(); ++j) {
Brick upper = zOrdered.get(j);
if(upper.isAbove(lower)) {
counterMap.compute(lower, (k,v)-> {
if(v== null) {
return new VerticalCounter(new AtomicInteger(0), new AtomicInteger(1));
} else {
v.below.incrementAndGet();
return v;
}
});
counterMap.compute(upper, (k,v)-> {
if(v== null) {
return new VerticalCounter(new AtomicInteger(1), new AtomicInteger(0));
} else {
v.above.incrementAndGet();
return v;
}
});
System.out.println("found");
}
}
}
Map<Brick, BrickSupport> network = new HashMap<>();
for(var br : zOrdered) {
network.put(br, BrickSupport.create(br));
}
for(int i=0; i<zOrdered.size(); ++i) {
Brick lower = zOrdered.get(i);
for(int j=i+1; j<zOrdered.size(); ++j) {
Brick upper = zOrdered.get(j);
if(upper.isAbove(lower)) {
var ls = network.get(lower);
ls.addSupported(upper, network);
}
}
}
//network.entrySet().forEach(System.out::println);
//counterMap.values().stream().filter(vc->vc.above.get()==0 ||)
int desintegratable = 0;
Set<Brick> desB = new LinkedHashSet<Day22.Brick>();
for(int i=0; i<zOrdered.size(); ++i) {
Brick lower = zOrdered.get(i);
// System.out.println("ol:\t"+bricks.indexOf(lower));
int onlySupportCount = 0;
for(int j=i+1; j<zOrdered.size() && onlySupportCount==0; ++j) {
Brick upper = zOrdered.get(j);
// System.out.println("ou:\t"+bricks.indexOf(upper));
if(upper.isAbove(lower)) {
boolean hasOtherSupport = false;
for(int k=0; k<j && !hasOtherSupport; ++k) {
Brick other = zOrdered.get(k);
//System.out.println("oo:\t"+bricks.indexOf(other));
if(other != lower && !lower.isAbove(other) && upper.isAbove(other)) {
hasOtherSupport = true;
}
}
if(!hasOtherSupport) {
++onlySupportCount;
}
}
}
if(onlySupportCount==0) {
++desintegratable;
desB.add(lower);
}
}
//338 too low
//340 too high
System.out.println(desintegratable);
System.out.println(desB);
System.out.println(desB.size());
}

private static int countDesintegrationByElimination(Map<Brick, BrickSupport> originalNetwork) {
Map<Brick, BrickSupport> network = BrickSupport.copyNetwork(originalNetwork);
boolean changed = false;
Set<Brick> desintegrated = new HashSet<>();
do {

} while(changed);
return desintegrated.size();
}

private static String readInput() {
try {
return Files.readString(Path.of("day22.txt").toAbsolutePath());
} catch (Exception e) {
throw new IllegalStateException(e);
}
}
private record Brick(int x1, int y1, int z1, int x2, int y2, int z2) {
private static final Comparator<Brick> Y_COMPARATOR = Comparator.comparingInt(Brick::y1).thenComparingInt(Brick::y2);
private static final Comparator<Brick> Z_COMPARATOR = Comparator.comparingInt(Brick::z1).thenComparing(Comparator.comparingInt(Brick::z2).reversed());

static Brick read(String line) {
var parts = line.split("~");
var p1s = parts[0].split(",");
var p2s = parts[1].split(",");
return new Brick(
Integer.parseInt(p1s[0]),
Integer.parseInt(p1s[1]),
Integer.parseInt(p1s[2]),
Integer.parseInt(p2s[0]),
Integer.parseInt(p2s[1]),
Integer.parseInt(p2s[2])
);
}


long size() {
return (Math.abs(x1-x2)+1)*(Math.abs(y1-y2)+1)*(Math.abs(z1-z2)+1);
}

boolean contains(int x, int y, int z) {
return x1<=x&& x<=x2 && y1<=y && y<=y2 && z1<= z && z <= z2;
}

boolean isInRightOrder() {
return x1 <= x2 && y1 <= y2 && z1 <= z2;
}

boolean isAbove(Brick other) {
return other.z2 < z1 && hasCommonX(other) && hasCommonY(other);
}

boolean hasCommonX(Brick other) {
Brick a = x1 <= other.x1 ? this : other;
Brick b = this == a ? other : this;
return a.x1 <= b.x1 && b.x1 <= a.x2;
}

boolean hasCommonY(Brick other) {
Brick a = y1 <= other.y1 ? this : other;
Brick b = this == a ? other : this;
return a.y1 <= b.y1 && b.y1 <= a.y2;
}

boolean hasCommonZ(Brick other) {
Brick a = z1 <= other.z1 ? this : other;
Brick b = this == a ? other : this;
return a.z1 <= b.z1 && b.z1 <= a.z2;
}
}

private record VerticalCounter(AtomicInteger above, AtomicInteger below) {

}

private record BrickSupport(Brick brick, SequencedSet<Brick> supports, SequencedSet<Brick> supportedBy) {
static BrickSupport create(Brick b) {
return new BrickSupport(b, new LinkedHashSet<>(), new LinkedHashSet<>());
}

public static Map<Brick, BrickSupport> copyNetwork(Map<Brick, BrickSupport> originalNetwork) {
Map<Brick, BrickSupport> result = new HashMap<Day22.Brick, Day22.BrickSupport>();
for(var k: originalNetwork.keySet()) {
result.put(k, originalNetwork.get(k).copy());
}
return result;
}

void addSupported(Brick upper, Map<Brick, BrickSupport> network) {
if(supports.contains(upper)) {
return;
}
supports.forEach(s -> {
if(upper.isAbove(s)) {
network.get(s).addSupported(upper, network);
}
});
supports.add(upper);
supportedBy.forEach(sb -> {
network.get(sb).addSupported(upper, network);
});
}

BrickSupport copy() {
return new BrickSupport(brick, new LinkedHashSet<>(supports), new LinkedHashSet<>(supportedBy));
}
}

private static String example ="""
1,0,1~1,2,1
0,0,2~2,0,2
0,2,3~2,2,3
0,0,4~0,2,4
2,0,5~2,2,5
0,1,6~2,1,6
1,1,8~1,1,9""";
}
156 changes: 156 additions & 0 deletions aoc2023/src/main/java/io/github/zebalu/aoc2023/days/Day22_restart.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
package io.github.zebalu.aoc2023.days;

import java.nio.file.*;
import java.util.*;

public class Day22_restart {
public static void main(String[] args) {
String input = readInput(); //example; //readInput();
var lines = input.lines().toList();
List<Brick> bricks = new ArrayList<>();
for(int i=0; i<lines.size(); ++i) {
bricks.add(new Brick(i, lines.get(i)));
}
bricks.sort(Brick.Z_COMPARATOR);
SequencedMap<Brick, BrickSupport> network = makeThemFall(bricks);
//338 too low
//340 too high
System.out.println(countDesintegrateable(network));
System.out.println(countDesintegration(network));
}

private static SequencedMap<Brick, BrickSupport> makeThemFall(List<Brick> zSorted) {
SequencedMap<Brick, BrickSupport> network = new LinkedHashMap<>();
SequencedMap<Coord, Brick> stopped = new LinkedHashMap<>();
List<Brick> copy = zSorted.stream().map(Brick::clone).peek(c->network.put(c, new BrickSupport(c, new LinkedHashSet<>(), new LinkedHashSet<>()))).toList();
copy.forEach(brick -> {
SequencedSet<Brick> standingOn = new LinkedHashSet<>();
while(brick.z1>0 && standingOn.isEmpty()) {
for(int x=brick.x1; x<=brick.x2; ++x) {
for(int y=brick.y1; y<=brick.y2; ++y) {
for(int z=brick.z1; z<=brick.z2; ++z) {
Coord below = new Coord(x,y,z-1);
if(stopped.containsKey(below)) {
standingOn.add(stopped.get(below));
}
}
}
}
if(standingOn.isEmpty()) {
--brick.z1;
--brick.z2;
}
}
for (int x = brick.x1; x <= brick.x2; ++x) {
for (int y = brick.y1; y <= brick.y2; ++y) {
for (int z = brick.z1; z <= brick.z2; ++z) {
stopped.put(new Coord(x, y, z), brick);
}
}
}
for (Brick on : standingOn) {
network.get(on).supports.add(brick);
network.get(brick).supportedBy.add(on);
}
});
return network;
}

private static long countDesintegrateable(SequencedMap<Brick, BrickSupport> network) {
return network.values().stream().filter(bs->bs.supports().size() == 0 || bs.supports.stream().allMatch(sb -> network.get(sb).supportedBy.size() > 1)).count();
}

private static long countDesintegration(SequencedMap<Brick, BrickSupport> network) {
return network.keySet().stream().mapToLong(b->countDesintegrationFrom(b, network)).sum();
}

private static long countDesintegrationFrom(Brick brick, SequencedMap<Brick, BrickSupport> network) {
SequencedSet<Brick> desintegrated = new LinkedHashSet<>();
Queue<Brick> toRemove = new LinkedList<>();
desintegrated.add(brick);
toRemove.add(brick);
while(!toRemove.isEmpty()) {
Brick toDelete = toRemove.poll();
network.get(toDelete).supports.forEach(b->{
BrickSupport support = network.get(b);
long remainingSupport = support.supportedBy.stream().filter(s->!desintegrated.contains(s)).count();
if(remainingSupport < 1) {
toRemove.add(b);
desintegrated.add(b);
}
});
}
return desintegrated.size()-1;
}

private static String readInput() {
try {
return Files.readString(Path.of("day22.txt").toAbsolutePath());
} catch (Exception e) {
throw new IllegalStateException(e);
}
}

private record Coord(int x, int y, int z) {

@Override
public int hashCode() {
return x*1_000_000 + y*1_000 + z;
}

}

private static class Brick implements Cloneable {
static final Comparator<Brick> Z_COMPARATOR = Comparator.comparingInt(b->b.z1);
int id;
int x1,x2,y1,y2,z1,z2;

Brick(int id, String line) {
this.id = id;
var parts = line.split("~");
var p1s = parts[0].split(",");
var p2s = parts[1].split(",");
x1 = Integer.parseInt(p1s[0]);
y1 = Integer.parseInt(p1s[1]);
z1 = Integer.parseInt(p1s[2]);
x2 = Integer.parseInt(p2s[0]);
y2 = Integer.parseInt(p2s[1]);
z2 = Integer.parseInt(p2s[2]);
}

@Override
public Brick clone() {
try {
return (Brick) super.clone();
} catch (CloneNotSupportedException e) {
throw new IllegalAccessError(e.getMessage());
}
}

@Override
public int hashCode() {
return Objects.hash(id);
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Brick other = (Brick) obj;
return id == other.id && x1 == other.x1 && x2 == other.x2 && y1 == other.y1 && y2 == other.y2
&& z1 == other.z1 && z2 == other.z2;
}

@Override
public String toString() {
return String.format("{%4d %3d,%3d,%3d~%3d,%3d,%3d}", id, x1, y1, z1, x2, y2, z2);
}
}

private record BrickSupport(Brick brick, SequencedSet<Brick> supportedBy, SequencedSet<Brick> supports) {

}
}

0 comments on commit 3a09293

Please sign in to comment.