Day 5 implementation in Java

main
MiguelMLorente 2023-12-07 23:23:57 +01:00
parent 61ef345ff3
commit 217ec505f7
2 changed files with 179 additions and 0 deletions

View File

@ -0,0 +1,132 @@
package day5;
import javafx.util.Pair;
import util.FileReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Function;
import java.util.stream.Collectors;
public class Main {
private static List<Function<Long, Optional<Long>>> seedToSoilMappers = new ArrayList<>();
private static List<Function<Long, Optional<Long>>> soilToFertilizerMappers = new ArrayList<>();
private static List<Function<Long, Optional<Long>>> fertilizerToWaterMappers = new ArrayList<>();
private static List<Function<Long, Optional<Long>>> waterToLightMappers = new ArrayList<>();
private static List<Function<Long, Optional<Long>>> lightToTemperatureMappers = new ArrayList<>();
private static List<Function<Long, Optional<Long>>> temperatureToHumidityMappers = new ArrayList<>();
private static List<Function<Long, Optional<Long>>> humidityToLocationMappers = new ArrayList<>();
private static final boolean IS_SEEDS_RANGE_ENABLED = true; // Controls if part 1 or 2 of the problem is executed
private static final String SEEDS_PREFIX = "seeds: ";
private static final Map<String, List<Function<Long, Optional<Long>>>> HEADERS_TO_MAPPERS =
new LinkedHashMap<String, List<Function<Long, Optional<Long>>>>() {{
put("seed-to-soil map:", seedToSoilMappers);
put("soil-to-fertilizer map:", soilToFertilizerMappers);
put("fertilizer-to-water map:", fertilizerToWaterMappers);
put("water-to-light map:", waterToLightMappers);
put("light-to-temperature map:", lightToTemperatureMappers);
put("temperature-to-humidity map:", temperatureToHumidityMappers);
put("humidity-to-location map:", humidityToLocationMappers);
}};
private static final List<List<Function<Long, Optional<Long>>>> MAPPERS = new ArrayList<>(HEADERS_TO_MAPPERS.values());
public static void main(String[] args) {
String inputFilePath = System.getProperty("user.dir") + "\\java\\src\\main\\java\\day5\\input.txt";
FileReader reader = new FileReader(inputFilePath);
List<String> inputData = new ArrayList<>(reader.readContents());
SeedGenerator seedGenerator = getSeedGenerator(inputData.remove(0));
buildElementMappers(inputData, seedGenerator);
Function<Long, Long> mergedMappers = MAPPERS.stream()
.map(Main::createMappersFunction)
.reduce(Function.identity(), Function::andThen);
Long closestLocation = Long.MAX_VALUE;
while (seedGenerator.hasNext()) {
Long seed = seedGenerator.getSeed();
Long location = mergedMappers.apply(seed);
closestLocation = Math.min(closestLocation, location);
seedGenerator.pushSkip();
}
System.out.println(closestLocation);
}
private static SeedGenerator getSeedGenerator(String seedsInputData) {
List<String> splitSeedsInputData = Arrays.asList(seedsInputData.replace(SEEDS_PREFIX, "").split(" "));
List<Pair<Long, Long>> seedRanges;
if (!IS_SEEDS_RANGE_ENABLED) {
seedRanges = splitSeedsInputData.stream()
.map(Long::parseLong)
.map(seedValue -> new Pair<Long, Long>(seedValue, 1L))
.collect(Collectors.toList());
} else {
seedRanges = new ArrayList<>();
for (Integer index = 0; index < splitSeedsInputData.size(); index = index + 2) {
Long seedRangeStart = Long.parseLong(splitSeedsInputData.get(index));
Long seedRangeLength = Long.parseLong(splitSeedsInputData.get(index + 1));
seedRanges.add(new Pair<>(seedRangeStart, seedRangeLength));
}
}
return new SeedGenerator(seedRanges);
}
private static void buildElementMappers(List<String> inputData, SeedGenerator seedGenerator) {
AtomicReference<List<Function<Long, Optional<Long>>>> currentMapper = new AtomicReference<>();
inputData.stream()
.filter(string -> !string.isEmpty())
.forEachOrdered(string -> {
if (HEADERS_TO_MAPPERS.containsKey(string)) {
currentMapper.set(HEADERS_TO_MAPPERS.get(string));
} else {
String[] splitString = string.split(" ", 3);
addMapperFunction(
currentMapper.get(),
seedGenerator,
Long.parseLong(splitString[0]),
Long.parseLong(splitString[1]),
Long.parseLong(splitString[2])
);
}
});
}
private static void addMapperFunction(
List<Function<Long, Optional<Long>>> mappersList,
SeedGenerator seedGenerator,
Long outputRangeStart,
Long inputRangeStart,
Long rangeLength
) {
mappersList.add((inputNumber) -> {
if (inputNumber < inputRangeStart) {
seedGenerator.addSkip(inputRangeStart - inputNumber);
return Optional.empty();
} else if (inputNumber >= inputRangeStart + rangeLength) {
return Optional.empty();
}
seedGenerator.addSkip(inputRangeStart + rangeLength - inputNumber);
return Optional.of(outputRangeStart + inputNumber - inputRangeStart);
});
}
private static Function<Long, Long> createMappersFunction(List<Function<Long, Optional<Long>>> mappers) {
return (inputValue) -> mappers.stream()
.map(mapper -> mapper.apply(inputValue))
.filter(Optional::isPresent)
.map(Optional::get)
.findFirst()
.orElse(inputValue);
}
}

View File

@ -0,0 +1,47 @@
package day5;
import javafx.util.Pair;
import java.util.ArrayList;
import java.util.List;
public class SeedGenerator {
private final List<Pair<Long, Long>> seedRanges;
private Long listIndex = 0L;
private Long rangeIndex = 0L;
private List<Long> skipValues = new ArrayList<>();
public SeedGenerator(List<Pair<Long, Long>> seedRanges) {
this.seedRanges = seedRanges;
}
public Long getSeed() {
if (rangeIndex >= seedRanges.get(Math.toIntExact(listIndex)).getValue()) {
listIndex++;
rangeIndex = 0L;
}
Long seed = seedRanges.get(Math.toIntExact(listIndex)).getKey() + rangeIndex;
rangeIndex++;
return seed;
}
public boolean hasNext() {
return !(listIndex >= seedRanges.size() - 1
&& rangeIndex >= seedRanges.get(seedRanges.size() - 1).getValue());
}
public void addSkip(Long skipValue) {
skipValues.add(skipValue - 1);
}
public void pushSkip() {
if (skipValues.isEmpty()) {
listIndex++;
rangeIndex = 0L;
} else {
rangeIndex += skipValues.stream().sorted().findFirst().orElse(0L);
skipValues = new ArrayList<>();
}
}
}