@@ -174,6 +174,11 @@ function nearest_neighbor(goal: Point, data: Point[]): Point | undefined {
174174// { x: 7, y: 2 }
175175// ];
176176//
177+
178+
179+ //////////////////////////////////////////////////////////////////////////////
180+
181+
177182// const goal: Point = { x: 6, y: 5 };
178183// const nearest = nearest_neighbor(goal, points);
179184// console.log(nearest); // Should output the closest point to (6, 5)
@@ -194,21 +199,68 @@ function rand_point_list(min: number, max: number, max_len: number): Point[] {
194199
195200// console.log(rand_point_list(-100, 100, 10))
196201
202+ // In the interest of time (sorry...)
203+ let cGood = 0
204+ let cUndef = 0
205+ let cInput = 0
206+ let cNearest = 0
207+
208+
197209function run_trial ( count : number ) {
198210 const goal = rand_point ( 0 , 5 )
199211 const data = rand_point_list ( 0 , 5 , 100 )
200- const expected = nearest_neighbor_reference ( goal , data )
212+ // What if we can't use a reference oracle?
213+ //const expected = nearest_neighbor_reference(goal, data)
214+
201215 const actual = nearest_neighbor ( goal , data )
216+
202217
203- if ( expected != actual ) {
204- console . log ( `Failed on trial ${ count } :` )
205- console . log ( `goal: ${ JSON . stringify ( goal ) } ` )
206- console . log ( `data: ${ JSON . stringify ( data ) } ` )
207- console . log ( `expected: ${ JSON . stringify ( expected ) } ` )
208- console . log ( `actual: ${ JSON . stringify ( actual ) } ` )
218+ //if(expected != actual) {
219+ const outcome = isValid ( goal , data , actual )
220+ if ( outcome !== OUTCOME . Good ) {
221+ if ( outcome === OUTCOME . Bad_Undefined ) cUndef ++
222+ if ( outcome === OUTCOME . Not_In_Input ) cInput ++
223+ if ( outcome === OUTCOME . Not_Nearest ) cNearest ++
224+ //console.log(`Failed on trial ${count}:`)
225+ //console.log(`goal: ${JSON.stringify(goal)}`)
226+ //console.log(`data: ${JSON.stringify(data)}`)
227+ //console.log(`expected: ${JSON.stringify(expected)}`)
228+ //console.log(`actual: ${JSON.stringify(actual)}`)
229+
230+ } else {
231+ cGood ++
232+ }
233+ // :-( we could define a custom type and pass one of these
234+ //return {good: cGood, input: cInput, undef: cUndef, nearest:cNearest}
235+ }
236+
237+ enum OUTCOME {
238+ Good ,
239+ Bad_Undefined ,
240+ Not_In_Input ,
241+ Not_Nearest
242+ }
243+
244+ function isValid ( goal : Point , data : Point [ ] , output : Point | undefined ) : OUTCOME {
245+ if ( output === undefined ) {
246+ // The output is undefined if-and-only-if data is empty
247+ if ( data . length !== 0 ) return OUTCOME . Bad_Undefined
248+ } else {
249+ // Property: the output must be an element of the data
250+ if ( ! data . includes ( output ) ) return OUTCOME . Not_In_Input
251+ // Property: distance from output is smallest across all data
252+ for ( const pt of data ) {
253+ // Use taxi distance
254+ const dist = Math . abs ( pt . x - goal . x ) + Math . abs ( pt . y - goal . y )
255+ const output_dist = Math . abs ( output . x - goal . x ) + Math . abs ( output . y - goal . y )
256+ if ( dist < output_dist )
257+ return OUTCOME . Not_Nearest
209258 }
259+ }
260+ return OUTCOME . Good
210261}
211262
212- for ( let count = 0 ; count < 1000000 ; count ++ ) {
263+ for ( let count = 0 ; count < 100000 ; count ++ ) {
213264 run_trial ( count )
214- }
265+ }
266+ console . log ( { good : cGood , input : cInput , undef : cUndef , nearest :cNearest } )
0 commit comments