Talk:Range consolidation: Difference between revisions

(Similar.)
Line 20:
Are the boundaries included in the range? What notation is used to describe ranges with the opposite boundary properties? E.G. [2,4] - boundaries included; (2,4) - boundaries not included; [2,4) - lower boundary included, upper boundary not included, etc. Really, it seems like this is just a version of the [[Set_of_real_numbers]] task, except no operator requirement. The range building logic could be lifted directly though --[[User:Thundergnat|Thundergnat]] ([[User talk:Thundergnat|talk]]) 13:05, 3 February 2019 (UTC)
 
Hi Thundergnat, I state "covering all numbers between and including both bounds"; (other boundsboundary types not used in the task). It could be similar to the task you mention. A quick look leaves me wondering if this consolidation could use the operators mentioned? --[[User:Paddy3118|Paddy3118]] ([[User talk:Paddy3118|talk]]) 15:17, 3 February 2019 (UTC)
 
==Python tester==
I wrote a black-box, randomized tester for the Python example. All boundaries are generated as multiples of 0.5.
Each boundary generates three testpoints <tt>x-.25, x, x+.25</tt>, i.e on a finer grid of 0.25. I then find the set of testpoints that are within the original ranges and this should equal the set of these same initialtestpoints that are within the consolidated ranges. I don't test that the consolidation is the smallest set of ranges that could be found, only that the number of consolidated ranges is no larger than the number of original ranges.
 
Apend the following below the Python entry text:
<lang python>#%%
from random import randint
 
gen_grid = 0.5 # Ranges will be generated on a 0.5 grid
gen_range = (-100, 100) # The generation bounds are within thse limits
range_counts = (1, 10) # Count of number of ranges to be consolidated
tests = 100_000
 
def range_gen():
x, y = gen_range
x, y = x / gen_grid, y / gen_grid
return [randint(x, y) * gen_grid for _ in (1, 2)]
 
range_set = normalize([range_gen() for _ in range(randint(*range_counts))])
 
def gen_test_points(ranges):
"tp generated on a finer gen_grid/2 grid, around each boundary"
testpoint = set()
for r in ranges:
for bound in r:
for tp in (bound - gen_grid / 2, bound, bound + gen_grid / 2):
testpoint.add(tp)
return sorted(testpoint)
 
def in_a_range(testpoints, ranges):
"Returns only those tp that are within any of the ranges, in order."
inrange = []
for tp in testpoints:
for x, y in ranges:
if x <= tp <= y:
inrange.append(tp)
break
return inrange
 
#%%
if __name__ == '__main__':
fail = 0
print()
for n in range(tests):
ranges = normalize([range_gen() for _ in range(randint(*range_counts))])
consolidated = consolidate(ranges)
tp = gen_test_points(ranges)
good = (len(consolidated) <= len(ranges)
and in_a_range(tp, ranges) == in_a_range(tp, consolidated))
if not good:
print(f"{'PASS' if good else 'FAIL'} {ranges} => {consolidated}")
fail += 1
print(f"PASS RATE: {tests - fail}/{tests}")</lang>
 
{{out}}
<pre>[1.1, 2.2] => [1.1, 2.2]
[6.1, 7.2], [7.2, 8.3] => [6.1, 8.3]
[4, 3], [2, 1] => [1, 2], [3, 4]
[4, 3], [2, 1], [-1, -2], [3.9, 10] => [-2, -1], [1, 2], [3, 10]
[1, 3], [-6, -1], [-4, -5], [8, 2], [-6, -6] => [-6, -1], [1, 8]
 
PASS RATE: 100000/100000</pre>
Anonymous user