:- table lookup_in/3. :- table lookup/3. answer(Answer) :- seeds(SeedsMap), seed_list(SeedsMap, Seeds), locations_of_seeds(Seeds, Locations), min(Locations, Answer). % seed_list(Pairs, FlattenedListOfSeeds) builds the seeds list from the pairs seed_list([], []). seed_list([Seed, 1 | RestOfPairs], [Seed | RestOfSeeds]) :- seed_list(RestOfPairs, RestOfSeeds). seed_list([Seed, Range | RestOfPairs], [Seed | RestOfSeeds]) :- Range > 1, NewSeedStart is Seed + 1, NewRange is Range - 1, seed_list([NewSeedStart, NewRange | RestOfPairs], RestOfSeeds). % locations_of_seeds(Seeds, Locations) locations_of_seeds([], []). locations_of_seeds([Seed | RestOfSeeds], [Location | RestOfLocations]) :- lookup_in(seed_to_soil, Seed, Soil), lookup_in(soil_to_fertilizer, Soil, Fertilizer), lookup_in(fertilizer_to_water, Fertilizer, Water), lookup_in(water_to_light, Water, Light), lookup_in(light_to_temperature, Light, Temperature), lookup_in(temperature_to_humidity, Temperature, Humidity), lookup_in(humidity_to_location, Humidity, Location), locations_of_seeds(RestOfSeeds, RestOfLocations). % lookup_in(NamedMap, In, Out) lookup_in(NamedMap, In, Out) :- G =.. [NamedMap, Map], G, lookup(Map, In, Out). % lookup(Map, In, Out) lookup([], In, In). lookup([[OutStart, InStart, Range] | RestOfMap], In, Out) :- ((In >= InStart, In < InStart + Range) -> Out is OutStart + (In - InStart); lookup(RestOfMap, In, Out)). % min(List, Min) finds min value of a list min([X], X). min([Item | Rest], Min) :- min(Rest, MinRest), (Item < MinRest -> Min is Item; Min is MinRest).