-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
i am getting really tired :(
- Loading branch information
Showing
2 changed files
with
375 additions
and
0 deletions.
There are no files selected for viewing
219 changes: 219 additions & 0 deletions
219
aoc2023/src/main/java/io/github/zebalu/aoc2023/days/Day22.java
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
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
156
aoc2023/src/main/java/io/github/zebalu/aoc2023/days/Day22_restart.java
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
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) { | ||
|
||
} | ||
} |