193 lines
4.4 KiB
GDScript
193 lines
4.4 KiB
GDScript
extends Control
|
|
|
|
|
|
|
|
|
|
func _ready():
|
|
pass
|
|
|
|
func read_map(lines, i):
|
|
var map = []
|
|
|
|
while true:
|
|
var line = lines[i]
|
|
if line == '':
|
|
break
|
|
i += 1
|
|
|
|
var map_entry_string = line.split(' ')
|
|
var entry = MapEntry.new()
|
|
entry.dst_start = int(map_entry_string[0])
|
|
entry.src_start = int(map_entry_string[1])
|
|
entry.range = int(map_entry_string[2])
|
|
|
|
map.append(entry)
|
|
|
|
return [map, i]
|
|
|
|
func parse_input(input):
|
|
var lines = input.split('\n')
|
|
var i = 0
|
|
var maps = Maps.new()
|
|
|
|
# Parse seeds
|
|
var seeds_str = lines[i].split(' ').slice(1)
|
|
|
|
var seeds = []
|
|
for s in seeds_str:
|
|
seeds.append(int(s))
|
|
|
|
# Skip to seed-to-soil map
|
|
i += 3
|
|
|
|
var map_i = read_map(lines, i)
|
|
maps.seed2soil = map_i[0]
|
|
i = map_i[1]
|
|
|
|
# Skip to soil-to-fertilizer map
|
|
i += 2
|
|
|
|
map_i = read_map(lines, i)
|
|
maps.soil2fertilizer = map_i[0]
|
|
i = map_i[1]
|
|
|
|
# Skip to fertilizer-to-water map
|
|
i += 2
|
|
|
|
map_i = read_map(lines, i)
|
|
maps.fertilizer2water = map_i[0]
|
|
i = map_i[1]
|
|
|
|
# Skip to water-to-light map
|
|
i += 2
|
|
|
|
map_i = read_map(lines, i)
|
|
maps.water2light = map_i[0]
|
|
i = map_i[1]
|
|
|
|
# Skip to light-to-temperature map
|
|
i += 2
|
|
|
|
map_i = read_map(lines, i)
|
|
maps.light2temperature = map_i[0]
|
|
i = map_i[1]
|
|
|
|
# Skip to temperature-to-humidity map
|
|
i += 2
|
|
|
|
map_i = read_map(lines, i)
|
|
maps.temperature2humidity = map_i[0]
|
|
i = map_i[1]
|
|
|
|
# Skip to humidity-to-location map
|
|
i += 2
|
|
|
|
map_i = read_map(lines, i)
|
|
maps.humidity2location = map_i[0]
|
|
i = map_i[1]
|
|
|
|
return [seeds, maps]
|
|
|
|
func _on_part1():
|
|
var input = $TextEdit.text + '\n' # Safety newline :)
|
|
var seeds_maps = parse_input(input)
|
|
var seeds = seeds_maps[0]
|
|
var maps = seeds_maps[1]
|
|
|
|
print(seeds)
|
|
print(maps)
|
|
|
|
var overall_closest = INF
|
|
for seed in seeds:
|
|
var closest = maps.find_closest(seed)
|
|
overall_closest = min(overall_closest, closest)
|
|
|
|
print("Closest location: " + str(overall_closest))
|
|
|
|
func _smallest_dst(a, b):
|
|
return a.dst_start < b.dst_start
|
|
|
|
func _find_ranges(map, range):
|
|
# Determine what input ranges can yeild the given input range
|
|
var ranges = []
|
|
|
|
# Sort dest ranges from lowest->higest since thats what we care about
|
|
var entries = map.duplicate()
|
|
entries.sort_custom(_smallest_dst)
|
|
|
|
# Define search range
|
|
# This will get bumped to the right as each new range is found
|
|
var search_range_start = range.src_start
|
|
var search_range_len = range.range
|
|
|
|
for entry in map:
|
|
#print('Trying entry')
|
|
#print(entry)
|
|
#print('Range is')
|
|
#print(range)
|
|
|
|
# Input range is before entry, shift it to where the entry starts
|
|
var nd_start = entry.dst_start - search_range_start
|
|
if entry.dst_start > search_range_start and nd_start < search_range_len:
|
|
search_range_start += nd_start
|
|
search_range_len -= nd_start
|
|
#print("Range was before entry. New range is")
|
|
#print(str(search_range_start) + " (" + str(search_range_len) + ")")
|
|
#print(entry)
|
|
|
|
var d_start = search_range_start - entry.dst_start
|
|
# Search range is contained within entry
|
|
if entry.dst_start <= search_range_start and d_start < entry.range:
|
|
var new_entry = MapEntry.new()
|
|
# New range's destination is the start of the search range
|
|
# This was given
|
|
new_entry.dst_start = search_range_start
|
|
# New range's source is the reverse apply of this mapentry
|
|
new_entry.src_start = entry.apply_rev(search_range_start)
|
|
# New range's range is either the end of the search range
|
|
# or the end of entry, whichever is less
|
|
new_entry.range = min(entry.range - d_start, search_range_len)
|
|
ranges.append(new_entry)
|
|
|
|
# Bump search range past this new entry
|
|
search_range_start += new_entry.range
|
|
search_range_len -= new_entry.range
|
|
|
|
if len(ranges) == 0:
|
|
ranges.append(range)
|
|
|
|
return ranges
|
|
|
|
func _on_part2():
|
|
var input = $TextEdit.text + '\n' # Safety newline :)
|
|
var seeds_maps = parse_input(input)
|
|
var seeds = seeds_maps[0]
|
|
var maps = seeds_maps[1]
|
|
|
|
print(seeds)
|
|
print(maps)
|
|
|
|
# Sort by closest locations
|
|
var closest_locs = maps.seed2soil.duplicate()
|
|
closest_locs.sort_custom(_smallest_dst)
|
|
|
|
print('Closest Humidities')
|
|
print(closest_locs)
|
|
|
|
# for loc in closest_locs:
|
|
var light_ranges = _find_ranges(maps.light2temperature, closest_locs[1])
|
|
print('Light ranges')
|
|
print(light_ranges)
|
|
var water_ranges = _find_ranges(maps.water2light, light_ranges[0])
|
|
print('Water ranges')
|
|
print(water_ranges)
|
|
|
|
var search_maps = [
|
|
maps.humidity2location,
|
|
maps.temperature2humidity,
|
|
maps.light2temperature,
|
|
maps.water2light,
|
|
maps.fertilizer2water,
|
|
maps.soil2fertilizer,
|
|
maps.seed2soil
|
|
]
|