Skip to content

Commit

Permalink
Day14
Browse files Browse the repository at this point in the history
  • Loading branch information
zebalu committed Dec 14, 2023
1 parent d1968d6 commit b194740
Show file tree
Hide file tree
Showing 2 changed files with 193 additions and 0 deletions.
191 changes: 191 additions & 0 deletions aoc2023/src/main/java/io/github/zebalu/aoc2023/days/Day14.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
package io.github.zebalu.aoc2023.days;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Comparator;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.SequencedSet;
import java.util.Set;

public class Day14 {
public static void main(String[] args) {
String input = readInput();
Platform p = new Platform(input);
p.tiltNorth();
System.out.println(p.loadOnNorth());
p.cycle(1_000_000_000);
System.out.println(p.loadOnNorth());
}

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

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

private static class Platform {
int width;
int height;

Set<Coord> stoppers = new HashSet<>();
Set<Coord> rollers = new HashSet<>();

Platform(String descS) {
List<String> desc = descS.lines().toList();
height = desc.size();
width = desc.getFirst().length();
for(int y=0; y<desc.size(); ++y) {
String line = desc.get(y);
for(int x=0; x<line.length(); ++x) {
switch (line.charAt(x)) {
case '#' -> stoppers.add(new Coord(x,y));
case 'O' -> rollers.add(new Coord(x,y));
}
}
}
}

void tiltNorth() {
var todo = rollers.stream().sorted(Comparator.comparingInt(Coord::y).thenComparingInt(Coord::x)).toList();
todo.stream().forEach(move->{
boolean foundBlocker = false;
int y = move.y;
Coord target = null;
while(y>0 && !foundBlocker) {
--y;
Coord next = new Coord(move.x, y);
foundBlocker = stoppers.contains(next) || rollers.contains(next);
if(!foundBlocker) {
target = next;
}
}
if(target != null) {
rollers.remove(move);
rollers.add(target);
}
});
}

void tiltSouth() {
var todo = rollers.stream().sorted(Comparator.comparingInt(Coord::y).reversed().thenComparingInt(Coord::x)).toList();
todo.stream().forEach(move->{
boolean foundBlocker = false;
int y = move.y;
Coord target = null;
while(y<height-1 && !foundBlocker) {
++y;
Coord next = new Coord(move.x, y);
foundBlocker = stoppers.contains(next) || rollers.contains(next);
if(!foundBlocker) {
target = next;
}
}
if(target != null) {
rollers.remove(move);
rollers.add(target);
}
});
}

void titlWest() {
var todo = rollers.stream().sorted(Comparator.comparingInt(Coord::x).thenComparingInt(Coord::y)).toList();
todo.stream().forEach(move->{
boolean foundBlocker = false;
int x = move.x;
Coord target = null;
while(x>0 && !foundBlocker) {
--x;
Coord next = new Coord(x, move.y);
foundBlocker = stoppers.contains(next) || rollers.contains(next);
if(!foundBlocker) {
target = next;
}
}
if(target != null) {
rollers.remove(move);
rollers.add(target);
}
});
}

void tiltEast() {
var todo = rollers.stream().sorted(Comparator.comparingInt(Coord::x).reversed().thenComparingInt(Coord::y)).toList();
todo.stream().forEach(move->{
boolean foundBlocker = false;
int x = move.x;
Coord target = null;
while(x<width-1 && !foundBlocker) {
++x;
Coord next = new Coord(x, move.y);
foundBlocker = stoppers.contains(next) || rollers.contains(next);
if(!foundBlocker) {
target = next;
}
}
if(target != null) {
rollers.remove(move);
rollers.add(target);
}
});
}

void cycle() {
tiltNorth();
titlWest();
tiltSouth();
tiltEast();
}

void cycle(int times) {
int steps = 1;
cycle();
SequencedSet<Set<Coord>> history = new LinkedHashSet<>();
while(!history.contains(rollers)) {
history.add(new HashSet<>(rollers));
cycle();
++steps;
}
int length = 0;
var iterator = history.reversed().iterator();
boolean found = false;
while(iterator.hasNext() && !found) {
var value = iterator.next();
++length;
found = value.equals(rollers);
}
int remaining = (times - steps) % length;
for(int i=0; i<remaining; ++i) {
cycle();
}
}

int loadOnNorth() {
return rollers.stream().sorted(Comparator.comparingInt(Coord::y).thenComparingInt(Coord::x)).mapToInt(c->height-c.y).sum();
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
for(int y=0; y<height; ++y) {
for(int x=0; x<width; ++x) {
Coord c=new Coord(x,y);
if(stoppers.contains(c)) {
sb.append('#');
} else if(rollers.contains(c)) {
sb.append('O');
} else {
sb.append('.');
}
}
sb.append('\n');
}
return sb.toString();
}
}
}
2 changes: 2 additions & 0 deletions aoc2023/src/main/java/io/github/zebalu/aoc2023/main/App.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import io.github.zebalu.aoc2023.days.Day11;
import io.github.zebalu.aoc2023.days.Day12;
import io.github.zebalu.aoc2023.days.Day13;
import io.github.zebalu.aoc2023.days.Day14;

public class App {

Expand Down Expand Up @@ -53,6 +54,7 @@ public static void main(String[] args) {
exec(new DisplayData(11, "Cosmic Expansion", Day11::main));
exec(new DisplayData(12, "Hot Springs", Day12::main));
exec(new DisplayData(13, "Point of Incidence", Day13::main));
exec(new DisplayData(14, "Parabolic Reflector Dish", Day14::main));
Instant end = Instant.now();
System.out.println("so far:\t"+Duration.between(start, end).toMillis()+" ms...");
}
Expand Down

0 comments on commit b194740

Please sign in to comment.