diff --git a/resources/input05.txt b/resources/input05.txt new file mode 100644 index 0000000..1c16908 --- /dev/null +++ b/resources/input05.txt @@ -0,0 +1,189 @@ +seeds: 1848591090 462385043 2611025720 154883670 1508373603 11536371 3692308424 16905163 1203540561 280364121 3755585679 337861951 93589727 738327409 3421539474 257441906 3119409201 243224070 50985980 7961058 + +seed-to-soil map: +3305253869 1699909104 39566623 +3344820492 1130725752 384459310 +3244681427 1739475727 60572442 +951517531 1800048169 868898709 +1820416240 951517531 179208221 +1999624461 2668946878 219310925 +3729279802 1515185062 184724042 +2218935386 2898481077 1015522767 +3234458153 2888257803 10223274 + +soil-to-fertilizer map: +1569885498 220184682 161941102 +3711640300 872157831 344226893 +1934701528 0 25420995 +3394438846 2543943059 181930710 +2957858493 2070565336 135870012 +1416178127 25420995 36071868 +1030022714 2029369539 9317803 +1039340517 1216384724 133685745 +695011633 382125784 335011081 +2317056551 1350070469 640801942 +1731826600 2887680679 151926123 +0 3039606802 695011633 +2030497645 2257384153 286558906 +1960122523 2038687342 31877994 +3576369556 2840047597 42331426 +1536338434 4027621785 33547064 +1452249995 3964767856 62853929 +1331718081 787697785 84460046 +4055867193 2882379023 5301656 +3093728505 3734618435 230149421 +1173026262 61492863 158691819 +1883752723 2206435348 50948805 +3618700982 2725873769 92939318 +1515103924 2818813087 21234510 +1992000517 1990872411 38497128 +3323877926 717136865 70560920 + +fertilizer-to-water map: +898769374 211542615 277361469 +2901739042 2299030230 213178977 +207924763 1114173904 26774777 +3752402183 1968349402 71176470 +1176130843 625299169 68863743 +3114918019 3783121220 137843736 +1244994586 488904084 103878858 +3252761755 2915409726 98951129 +2779748334 3652754391 121990708 +3351712884 2593688676 245406043 +0 1252990064 95883380 +2007290234 3920964956 325008750 +3823578653 2039525872 202532901 +2443486939 2512209207 81479469 +4231974038 3371954615 62993258 +3698239076 2242058773 54163107 +2340675105 3014360855 102811834 +4219112930 4245973706 12861108 +4026111554 2839094719 76315007 +3597118927 3434947873 101120149 +2332298984 3774745099 8376121 +95883380 1140948681 112041383 +4102426561 3536068022 116686369 +1968349402 2296221880 2808350 +1971157752 4258834814 36132482 +866253147 592782942 32516227 +446242155 694162912 420010992 +2524966408 3117172689 254781926 +234699540 0 211542615 + +water-to-light map: +3564276417 3073533986 256027539 +540951899 3329561525 136112599 +3123682450 3465674124 119685876 +2479417373 4222809437 72157859 +1957776831 2195006920 74795586 +3089045940 3585360000 28951457 +3820985109 2269802506 288781515 +1285562478 1664965131 530041789 +234319697 234026754 79806762 +3243368326 1344057040 320908091 +3117997397 541633052 5685053 +2551575232 547318105 349893979 +3820303956 540951899 681153 +0 369583040 292943 +314126459 313833516 55749524 +4109766624 2888333314 185200672 +292943 0 234026754 +677064498 3614311457 608497980 +2032572417 897212084 446844956 +2901469211 2700756585 187576729 +1815604267 2558584021 142172564 + +light-to-temperature map: +2658328410 4044901271 250066025 +866264123 157899985 185676775 +2062023507 343576760 307684950 +1535723010 981670684 313982539 +3292868240 2534053678 579746095 +3905180794 3703329819 341571452 +2908394435 3318856014 384473805 +1194970869 1601263273 340752141 +427693043 1299669198 158564104 +748173107 651261710 118091016 +1051940898 1458233302 143029971 +586257147 0 157899985 +4246752246 2485838628 48215050 +1849705549 769352726 212317958 +0 2368902754 805703 +744157132 1295653223 4015975 +805703 1942015414 426887340 +3872614335 3113799773 32566459 +2485838628 3146366232 172489782 + +temperature-to-humidity map: +2731357374 2535823037 72664015 +2987243945 1266132780 17518070 +3983567677 3876954134 113067367 +1669770178 435765631 9597802 +192217183 2087059527 132586479 +324803662 1449340061 36910958 +82239523 1283650850 47718149 +4251710314 3400860374 43256982 +788691045 2012848120 74211407 +139712452 383260900 52504731 +1679367980 1064470362 18439862 +3627675589 3649605531 101947626 +1761484189 1024489895 39980467 +3964889474 4132263773 7628253 +469056934 1486251019 222779936 +3808503415 3992550600 118386133 +4096635044 4139892026 155075270 +0 328658745 54602155 +3929418647 3751553157 35470827 +3729623215 3787023984 78880200 +129957672 2003093340 9754780 +3926889548 3990021501 2529099 +2130123401 3260061108 28438224 +1154320063 445363433 515450115 +2331952939 1331368999 72869773 +2804021389 1082910224 183222556 +1140184340 2219646006 14135723 +3606348549 4110936733 21327040 +3004762015 1709030955 50302777 +1801464656 0 328658745 +691836870 1759333732 96854175 +447785309 2608487052 21271625 +3400860374 3444117356 205488175 +3055064792 2233781729 261071908 +2185047506 1856187907 146905433 +1697807842 960813548 63676347 +361714620 2494853637 40969400 +2404822712 2933526446 326534662 +402684020 1404238772 45101289 +3972517727 3865904184 11049950 +2158561625 2907040565 26485881 +862902452 2629758677 277281888 +54602155 3288499332 27637368 + +humidity-to-location map: +1368371614 3063096196 39876417 +2318920763 3734391855 138926764 +2980019498 3984955289 310012007 +3732521234 1430493364 562446062 +213274662 484132485 78936678 +0 892307918 213274662 +1023610211 575518293 214768297 +2807160244 2776517513 21582263 +2457847527 2833630022 176634966 +3619027057 2663023336 113494177 +2926107621 1368371614 53911877 +1784866635 3524616139 209775716 +2695523574 3873318619 111636670 +1250827638 790286590 102021328 +3290031505 1992939426 224427328 +954760770 415283044 68849441 +1408248031 2286404732 376618604 +292211340 0 415283044 +1994642351 3102972613 324278412 +2642692366 3034347120 28749076 +3514458833 2798099776 35530246 +1238378508 563069163 12449130 +2828742507 3427251025 97365114 +3549989079 2217366754 69037978 +2671441442 3010264988 24082132 +707494384 1105582580 247266386 +2634482493 1422283491 8209873 diff --git a/src/main/java/sugui/Day05.java b/src/main/java/sugui/Day05.java new file mode 100644 index 0000000..55388ed --- /dev/null +++ b/src/main/java/sugui/Day05.java @@ -0,0 +1,119 @@ +package sugui; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.StringReader; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; +import java.util.stream.Collectors; + +import sugui.util.Pair; + +public class Day05 { + + public static Path inputPath = Paths.get("resources/input05.txt"); + + private record ProductionKit(List seeds, List> maps) { + } + + private record ProductionKitRanged(List> seedPairs, List> maps) { + } + + private record MapInfo(long destination, long source, long range) { + } + + private static long getLocation(List mapper, long origin) { + for (var mapInfo : mapper) { + var originSourceDiff = origin - mapInfo.source; + if (originSourceDiff >= 0 && originSourceDiff <= mapInfo.range) + return mapInfo.destination + originSourceDiff; + } + return origin; + } + + public static void main(String[] args) throws IOException { + var input = Files.readString(inputPath); + var firstResult = getFirstPuzzleResult(input); + var secondResult = getSecondPuzzleResult(input); + System.out.println("First result: " + firstResult); + System.out.println("Second result: " + secondResult); + } + + public static ProductionKit parseFirst(String input) { + String[] parts = input.split("\\n\\n", 2); + List seeds = Arrays.stream(parts[0].substring(7).split(" ")).map(Long::parseLong) + .collect(Collectors.toList()); + + String sepRegex = "\\n*[^\\n\\d]+\\n"; + String[] mapsData = parts[1].split(sepRegex, 2)[1].split(sepRegex); + List> maps = new ArrayList<>(); + for (var mapData : mapsData) { + var bufferedReader = new BufferedReader(new StringReader(mapData)); + List map = bufferedReader.lines().map(line -> { + String[] data = line.split(" "); + return new MapInfo(Long.parseLong(data[0]), Long.parseLong(data[1]), Long.parseLong(data[2])); + }).collect(Collectors.toList()); + maps.add(map); + } + return new ProductionKit(seeds, maps); + } + + public static ProductionKitRanged parseSecond(String input) { + String[] parts = input.split("\\n\\n", 2); + Iterator seedsData = Arrays.asList(parts[0].substring(7).split(" ")).iterator(); + List> seedPairs = new ArrayList<>(); + while (seedsData.hasNext()) { + long seedInit = Long.parseLong(seedsData.next()); + long seedRange = Long.parseLong(seedsData.next()); + seedPairs.add(new Pair(seedInit, seedRange)); + } + String sepRegex = "\\n*[^\\n\\d]+\\n"; + String[] mapsData = parts[1].split(sepRegex, 2)[1].split(sepRegex); + List> maps = new ArrayList<>(); + for (var mapData : mapsData) { + var bufferedReader = new BufferedReader(new StringReader(mapData)); + List map = bufferedReader.lines().map(line -> { + String[] data = line.split(" "); + return new MapInfo(Long.parseLong(data[0]), Long.parseLong(data[1]), Long.parseLong(data[2])); + }).collect(Collectors.toList()); + maps.add(map); + } + return new ProductionKitRanged(seedPairs, maps); + } + + public static String getFirstPuzzleResult(String input) { + ProductionKit prodKit = parseFirst(input); + var locations = new ArrayList<>(prodKit.seeds); + for (var map : prodKit.maps) { + for (int i = 0; i < locations.size(); i++) { + long currentLocation = locations.get(i); + locations.set(i, getLocation(map, currentLocation)); + } + } + long minimumLocation = locations.stream().min(Long::compare).get(); + return Long.toString(minimumLocation); + } + + public static String getSecondPuzzleResult(String input) { + ProductionKitRanged prodKit = parseSecond(input); + long minLocation = Long.MAX_VALUE; + for (var seedPair : prodKit.seedPairs) { + for (long seed = seedPair._1(); seed < seedPair._1() + seedPair._2(); seed++) { + long currLocation = seed; + for (var map : prodKit.maps) { + long newLocation = getLocation(map, currLocation); + currLocation = newLocation; + } + if (minLocation > currLocation) { + minLocation = currLocation; + } + } + } + return Long.toString(minLocation); + } +} diff --git a/src/main/java/sugui/util/Interval.java b/src/main/java/sugui/util/Interval.java new file mode 100644 index 0000000..f757480 --- /dev/null +++ b/src/main/java/sugui/util/Interval.java @@ -0,0 +1,31 @@ +package sugui.util; + +import java.util.Iterator; +import java.util.LinkedList; + +/** + * Class for intervals. From is inclusive, to is exclusive. + */ +public class Interval { + private record Node(long value, boolean canBeLess) { + } + LinkedList interval = new LinkedList<>(); + + public Interval(long from, long to) { + Node fromNode = new Node(from, false); + Node toNode = new Node(to, true); + interval.add(fromNode); + interval.add(toNode); + } + + public boolean contains(long x) { + Iterator iterator = interval.iterator(); + while(iterator.hasNext()) { + Node currNode = iterator.next(); + if (x < currNode.value) { + return currNode.canBeLess; + } + } + return false; + } +} diff --git a/src/test/java/sugui/Day05Test.java b/src/test/java/sugui/Day05Test.java new file mode 100644 index 0000000..2040ec1 --- /dev/null +++ b/src/test/java/sugui/Day05Test.java @@ -0,0 +1,64 @@ +package sugui; + +import static org.junit.Assert.assertEquals; + +import java.io.IOException; + +import org.junit.Test; + +/** + * Unit test for simple App. + */ +public class Day05Test { + + public static String firstBasicInput = """ + seeds: 79 14 55 13 + + seed-to-soil map: + 50 98 2 + 52 50 48 + + soil-to-fertilizer map: + 0 15 37 + 37 52 2 + 39 0 15 + + fertilizer-to-water map: + 49 53 8 + 0 11 42 + 42 0 7 + 57 7 4 + + water-to-light map: + 88 18 7 + 18 25 70 + + light-to-temperature map: + 45 77 23 + 81 45 19 + 68 64 13 + + temperature-to-humidity map: + 0 69 1 + 1 0 69 + + humidity-to-location map: + 60 56 37 + 56 93 4 + """; + public static String secondBasicInput = firstBasicInput; + public static String firstBasicResult = "35"; + public static String secondBasicResult = "46"; + + @Test + public void firstBasicCase() throws IOException { + String actualResult = Day05.getFirstPuzzleResult(firstBasicInput); + assertEquals(firstBasicResult, actualResult); + } + + @Test + public void secondBasicCase() throws IOException { + String actualResult = Day05.getSecondPuzzleResult(secondBasicInput); + assertEquals(secondBasicResult, actualResult); + } +} diff --git a/src/test/java/sugui/IntervalTest.java b/src/test/java/sugui/IntervalTest.java new file mode 100644 index 0000000..7db3d67 --- /dev/null +++ b/src/test/java/sugui/IntervalTest.java @@ -0,0 +1,29 @@ +package sugui; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.io.IOException; + +import org.junit.Test; + +import sugui.util.Interval; + +/** + * Unit test for simple App. + */ +public class IntervalTest { + + public static Interval interval1 = new Interval(2, 8); + + @Test + public void containsTest() throws IOException { + assertTrue(interval1.contains(2)); + assertTrue(interval1.contains(5)); + assertTrue(interval1.contains(7)); + assertFalse(interval1.contains(1)); + assertFalse(interval1.contains(8)); + assertFalse(interval1.contains(10)); + } +}