@@ -232,145 +232,136 @@ private func diff_computeDiffsBetweenArrays<T: Equatable>(arrayA: [T], arrayB: [
232232 return diff_bisectOfArrays ( arrayA: arrayA, arrayB: arrayB)
233233}
234234
235- private struct FrontPathParameters < T> {
236- let currentD : Int
235+ private class Kay {
236+ var start : Int = 0
237+ var end : Int = 0
238+ var index : Int = 0
239+ }
240+
241+ private struct CommonPathParameters < T: Equatable > {
237242 let vOffset : Int
238243 let inArrayA : [ T ]
239244 let inArrayB : [ T ]
245+ let front : Bool
246+ let delta : Int
247+ let vLength : Int
240248}
241249
242- // swiftlint:disable function_parameter_count
243- private func walkFrontPath< T> ( parameters: FrontPathParameters < T > ,
244- kIndex1: inout Int ,
245- k1end: inout Int ,
246- vectors1: inout [ Int ] ,
247- k1start: inout Int ,
248- front: Bool ,
249- delta: Int ,
250- vLength: Int ,
251- vectors2: inout [ Int ] ,
252- diffs: inout [ Diff < T > ] ) -> Bool {
253-
254- var haveFoundDiffs = false // assume
255- while kIndex1 <= parameters. currentD - k1end {
250+ private func walkFrontPath< T: Equatable > (
251+ commonParameters: CommonPathParameters < T > ,
252+ currentD: Int ,
253+ kay1: Kay ,
254+ vectors1: inout [ Int ] ,
255+ vectors2: inout [ Int ] ) -> [ Diff < T > ] {
256+
257+ while kay1. index <= currentD - kay1. end {
256258 defer {
257- kIndex1 += 2
259+ kay1 . index += 2
258260 }
259- let k1Offset = parameters . vOffset + kIndex1
261+ let k1Offset = commonParameters . vOffset + kay1 . index
260262 var x1 = 0
261263
262- if kIndex1 == - parameters . currentD || ( kIndex1 != parameters . currentD && vectors1 [ k1Offset - 1 ] < vectors1 [ k1Offset + 1 ] ) {
264+ if kay1 . index == - currentD || ( kay1 . index != currentD && vectors1 [ k1Offset - 1 ] < vectors1 [ k1Offset + 1 ] ) {
263265 x1 = vectors1 [ k1Offset + 1 ]
264266 } else {
265267 x1 = vectors1 [ k1Offset - 1 ] + 1
266268 }
267269
268- var y1 = x1 - kIndex1
270+ var y1 = x1 - kay1 . index
269271
270272 // follow the snake!
271- while x1 < parameters . inArrayA. count && y1 < parameters . inArrayB. count && parameters . inArrayA [ x1] == parameters . inArrayB [ y1] {
273+ while x1 < commonParameters . inArrayA. count && y1 < commonParameters . inArrayB. count && commonParameters . inArrayA [ x1] == commonParameters . inArrayB [ y1] {
272274 x1 += 1
273275 y1 += 1
274276 }
275277
276278 vectors1 [ k1Offset] = x1
277279
278- if x1 > parameters . inArrayA. count {
280+ if x1 > commonParameters . inArrayA. count {
279281 // Ran off the right of the graph.
280- k1end += 2
281- } else if y1 > parameters . inArrayB. count {
282+ kay1 . end += 2
283+ } else if y1 > commonParameters . inArrayB. count {
282284 // Ran off the bottom of the graph.
283- k1start += 2
284- } else if front {
285- let k2Offset = parameters . vOffset + delta - kIndex1
285+ kay1 . start += 2
286+ } else if commonParameters . front {
287+ let k2Offset = commonParameters . vOffset + commonParameters . delta - kay1 . index
286288
287- if k2Offset >= 0 && k2Offset < vLength && vectors2 [ k2Offset] != - 1 {
289+ if k2Offset >= 0 && k2Offset < commonParameters . vLength && vectors2 [ k2Offset] != - 1 {
288290 // Mirror x2 onto top-left coordinate system.
289- let x2 = parameters . inArrayA. count - vectors2[ k2Offset]
291+ let x2 = commonParameters . inArrayA. count - vectors2[ k2Offset]
290292 if x1 >= x2 {
291293 // diffs = diff_bisectSplitOfStrings(text1, text2, x1, y1, properties);
292- diffs = diff_bisectSplitOfArrays ( arrayA: parameters. inArrayA, arrayB: parameters. inArrayB, x: x1, y: y1)
293- haveFoundDiffs = true
294- break
294+ return diff_bisectSplitOfArrays ( arrayA: commonParameters. inArrayA, arrayB: commonParameters. inArrayB, x: x1, y: y1)
295295 }
296296 }
297297 }
298298 }
299-
300- return haveFoundDiffs
299+ return [ ]
301300}
302301
303- private func walkReversePath< T: Equatable > ( kIndex2: inout Int ,
304- currentD: Int ,
305- k2end: inout Int ,
306- vOffset: Int ,
307- vectors2: inout [ Int ] ,
308- inArrayA: [ T ] ,
309- inArrayB: [ T ] ,
310- k2start: inout Int ,
311- front: Bool ,
312- delta: Int ,
313- vLength: Int ,
314- vectors1: inout [ Int ] ,
315- diffs: inout [ Diff < T > ] ,
316- haveFoundDiffs: inout Bool ) {
317- while kIndex2 <= currentD - k2end {
302+ private func walkReversePath< T: Equatable > (
303+ commonParameters: CommonPathParameters < T > ,
304+ currentD: Int ,
305+ kay2: Kay ,
306+ vectors1: inout [ Int ] ,
307+ vectors2: inout [ Int ] ) -> [ Diff < T > ] {
308+
309+ while kay2. index <= currentD - kay2. end {
318310
319311 defer {
320- kIndex2 += 2
312+ kay2 . index += 2
321313 }
322- let k2Offset = vOffset + kIndex2
314+ let k2Offset = commonParameters . vOffset + kay2 . index
323315 var x2 = 0
324316
325- if kIndex2 == - currentD || ( kIndex2 != currentD && vectors2 [ k2Offset - 1 ] < vectors2 [ k2Offset + 1 ] ) {
317+ if kay2 . index == - currentD || ( kay2 . index != currentD && vectors2 [ k2Offset - 1 ] < vectors2 [ k2Offset + 1 ] ) {
326318 x2 = vectors2 [ k2Offset + 1 ]
327319 } else {
328320 x2 = vectors2 [ k2Offset - 1 ] + 1
329321 }
330322
331- var y2 = x2 - kIndex2
323+ var y2 = x2 - kay2 . index
332324
333- while x2 < inArrayA. count && y2 < inArrayB. count && ( inArrayA [ inArrayA. count - x2 - 1 ] == inArrayB [ inArrayB. count - y2 - 1 ] ) {
325+ while x2 < commonParameters . inArrayA. count && y2 < commonParameters . inArrayB. count && ( commonParameters . inArrayA [ commonParameters . inArrayA. count - x2 - 1 ] == commonParameters . inArrayB [ commonParameters . inArrayB. count - y2 - 1 ] ) {
334326 x2 += 1
335327 y2 += 1
336328 }
337329
338330 vectors2 [ k2Offset] = x2
339331
340- if x2 > inArrayA. count {
332+ if x2 > commonParameters . inArrayA. count {
341333 // Ran off the left of the graph.
342- k2end += 2
343- } else if y2 > inArrayB. count {
334+ kay2 . end += 2
335+ } else if y2 > commonParameters . inArrayB. count {
344336 // Ran off the top of the graph.
345- k2start += 2
346- } else if !front {
347- let k1Offset = vOffset + delta - kIndex2
337+ kay2 . start += 2
338+ } else if !commonParameters . front {
339+ let k1Offset = commonParameters . vOffset + commonParameters . delta - kay2 . index
348340
349- if k1Offset >= 0 && k1Offset < vLength && vectors1 [ k1Offset] != - 1 {
341+ if k1Offset >= 0 && k1Offset < commonParameters . vLength && vectors1 [ k1Offset] != - 1 {
350342 let x1 = vectors1 [ k1Offset]
351- let y1 = vOffset + x1 - k1Offset
343+ let y1 = commonParameters . vOffset + x1 - k1Offset
352344 // Mirror x2 onto top-left coordinate system.
353- x2 = inArrayA. count - x2
345+ x2 = commonParameters . inArrayA. count - x2
354346
355347 if x1 >= x2 {
356348 // Overlap detected.
357- diffs = diff_bisectSplitOfArrays ( arrayA: inArrayA, arrayB: inArrayB, x: x1, y: y1)
358- haveFoundDiffs = true
359- break
349+ return diff_bisectSplitOfArrays ( arrayA: commonParameters. inArrayA, arrayB: commonParameters. inArrayB, x: x1, y: y1)
360350 }
361351 }
362352 }
363353 }
354+ return [ ]
364355}
365356
366357// yes this method is way too long. Pull requests welcome!
367- func diff_bisectOfArrays< T: Equatable > ( arrayA inArrayA: [ T ] , arrayB inArrayB: [ T ] ) -> [ Diff < T > ] {
368- let arrayALength = inArrayA. count
369- let arrayBLength = inArrayB. count
370- var haveFoundDiffs = false
371- var diffs : [ Diff < T > ] = [ ]
358+ private func debugPrint( kay: Kay , vectors1: [ Int ] , vectors2: [ Int ] ) {
359+ print ( " --- kIndex: \( kay. index) , kstart: \( kay. start) , kend: \( kay. end) , " )
360+ print ( " --- vectors1: \( vectors1) , vectors2: \( vectors2) " )
361+ }
372362
373- let maxD = ( arrayALength + arrayBLength + 1 ) / 2
363+ func diff_bisectOfArrays< T: Equatable > ( arrayA inArrayA: [ T ] , arrayB inArrayB: [ T ] ) -> [ Diff < T > ] {
364+ let maxD = ( inArrayA. count + inArrayB. count + 1 ) / 2
374365 let vOffset = maxD
375366 var vLength = 2 * maxD
376367
@@ -385,72 +376,59 @@ func diff_bisectOfArrays<T: Equatable>(arrayA inArrayA: [T], arrayB inArrayB: [T
385376 vectors1. append ( - 1 )
386377 vectors2. append ( - 1 )
387378 }
388-
389379 vectors1 [ vOffset + 1 ] = 0
390380 vectors2 [ vOffset + 1 ] = 0
391381
392- let delta = arrayALength - arrayBLength
382+ let delta = inArrayA . count - inArrayB . count
393383
394384 // If the total number of characters is odd, then the front path will collide with the reverse path.
395385 let front = delta % 2 != 0
396386
397387 // Offsets for start and end of k loop. Prevents mapping of space beyond the grid.
398- var k1start = 0
399- var k1end = 0
400- var k2start = 0
401- var k2end = 0
388+ let kay1 = Kay ( )
389+ let kay2 = Kay ( )
390+
391+ let commonParameters = CommonPathParameters ( vOffset : vOffset , inArrayA : inArrayA , inArrayB : inArrayB , front : front , delta : delta , vLength : vLength )
402392
403- //
404393 for currentD in 0 ..< maxD {
405394
406395 // Walk the front path one step.
407- var kIndex1 = - currentD + k1start
408-
409- let parameters = FrontPathParameters ( currentD: currentD, vOffset: vOffset, inArrayA: inArrayA, inArrayB: inArrayB)
410- if walkFrontPath (
411- parameters: parameters,
412- kIndex1: & kIndex1,
413- k1end: & k1end,
414- vectors1: & vectors1,
415- k1start: & k1start,
416- front: front,
417- delta: delta,
418- vLength: vLength,
419- vectors2: & vectors2,
420- diffs: & diffs) {
421- haveFoundDiffs = true
422- break
396+ kay1. index = - currentD + kay1. start
397+ debugPrint ( kay: kay1, vectors1: vectors1, vectors2: vectors2)
398+
399+ let frontDiffs = walkFrontPath (
400+ commonParameters: commonParameters,
401+ currentD: currentD,
402+ kay1: kay1,
403+ vectors1: & vectors1,
404+ vectors2: & vectors2)
405+
406+ debugPrint ( kay: kay1, vectors1: vectors1, vectors2: vectors2)
407+
408+ if !frontDiffs. isEmpty {
409+ return frontDiffs
423410 }
424411
425412 // Walk the reverse path one step.
426- var kIndex2 = - currentD + k2start
427- walkReversePath ( kIndex2: & kIndex2,
428- currentD: currentD,
429- k2end: & k2end,
430- vOffset: vOffset,
431- vectors2: & vectors2,
432- inArrayA: inArrayA,
433- inArrayB: inArrayB,
434- k2start: & k2start,
435- front: front,
436- delta: delta,
437- vLength: vLength,
438- vectors1: & vectors1,
439- diffs: & diffs,
440- haveFoundDiffs: & haveFoundDiffs)
441-
442- if haveFoundDiffs {
443- break
413+ kay2. index = - currentD + kay2. start
414+ debugPrint ( kay: kay2, vectors1: vectors1, vectors2: vectors2)
415+ let reverseDiffs = walkReversePath (
416+ commonParameters: commonParameters,
417+ currentD: currentD,
418+ kay2: kay2,
419+ vectors1: & vectors1,
420+ vectors2: & vectors2)
421+
422+ debugPrint ( kay: kay2, vectors1: vectors1, vectors2: vectors2)
423+
424+ if !reverseDiffs. isEmpty {
425+ return reverseDiffs
444426 }
445427 }
446428
447- if !haveFoundDiffs {
448- // we haven't found a snake at all so we couldn't cut the problem in half.
449- // This means we have no common element. Just add the diffs straight away.
450- diffs = [ Diff ( operation: . delete, array: inArrayA) , Diff ( operation: . insert, array: inArrayB) ]
451- }
452-
453- return diffs
429+ // we haven't found a snake at all so we couldn't cut the problem in half.
430+ // This means we have no common element. Just add the diffs straight away.
431+ return [ Diff ( operation: . delete, array: inArrayA) , Diff ( operation: . insert, array: inArrayB) ]
454432}
455433// swiftlint:enable function_body_length
456434
0 commit comments