@@ -87,39 +87,30 @@ func (r *Runner) suggestTasks(name string) []string {
8787
8888// levenshtein returns the edit distance between a and b — the minimum number
8989// of single-character insertions, deletions, or substitutions needed to turn
90- // one into the other. The implementation uses two rolling rows so memory
91- // stays O(min(len(a), len(b))) even for long task names .
90+ // one into the other. A single rolling row plus one scalar holding the
91+ // previous diagonal keeps memory at O(min(len(a), len(b))).
9292func levenshtein (a , b string ) int {
93- ra := []rune (a )
94- rb := []rune (b )
93+ ra , rb := []rune (a ), []rune (b )
9594 if len (ra ) < len (rb ) {
9695 ra , rb = rb , ra
9796 }
98- if len (rb ) == 0 {
99- return len (ra )
100- }
10197
102- prev := make ([]int , len (rb )+ 1 )
103- curr := make ([]int , len (rb )+ 1 )
104- for j := range prev {
105- prev [j ] = j
98+ row := make ([]int , len (rb )+ 1 )
99+ for j := range row {
100+ row [j ] = j
106101 }
107102
108103 for i := 1 ; i <= len (ra ); i ++ {
109- curr [0 ] = i
104+ diag := row [0 ] // dp[i-1][0] before we overwrite it
105+ row [0 ] = i
110106 for j := 1 ; j <= len (rb ); j ++ {
111107 cost := 1
112108 if ra [i - 1 ] == rb [j - 1 ] {
113109 cost = 0
114110 }
115- curr [j ] = min (
116- prev [j ]+ 1 , // deletion
117- curr [j - 1 ]+ 1 , // insertion
118- prev [j - 1 ]+ cost , // substitution
119- )
111+ diag , row [j ] = row [j ], min (row [j ]+ 1 , row [j - 1 ]+ 1 , diag + cost )
120112 }
121- prev , curr = curr , prev
122113 }
123114
124- return prev [len (rb )]
115+ return row [len (rb )]
125116}
0 commit comments