nodes: 0, module; 1, function_definition; 2, function_name:lexical_distance; 3, parameters; 4, type; 5, block; 6, typed_parameter; 7, typed_parameter; 8, identifier:int; 9, expression_statement; 10, if_statement; 11, expression_statement; 12, expression_statement; 13, comment:# Any case change counts as a single edit; 14, if_statement; 15, expression_statement; 16, for_statement; 17, for_statement; 18, return_statement; 19, identifier:a_str; 20, type; 21, identifier:b_str; 22, type; 23, comment:"""Computes the lexical distance between strings A and B.
  
      The "distance" between two strings is given by counting the minimum number of edits
      needed to transform string A into string B. An edit can be an insertion, deletion,
      or substitution of a single character, or a swap of two adjacent characters.
  
      This distance can be useful for detecting typos in input or sorting.
      """; 24, comparison_operator:a_str == b_str; 25, block; 26, assignment; 27, assignment; 28, comparison_operator:a == b; 29, block; 30, assignment; 31, identifier:i; 32, call; 33, block; 34, identifier:i; 35, call; 36, block; 37, subscript; 38, identifier:str; 39, identifier:str; 40, identifier:a_str; 41, identifier:b_str; 42, return_statement; 43, pattern_list; 44, expression_list; 45, pattern_list; 46, expression_list; 47, identifier:a; 48, identifier:b; 49, return_statement; 50, identifier:d; 51, list; 52, identifier:range; 53, argument_list; 54, expression_statement; 55, identifier:range; 56, argument_list; 57, for_statement; 58, subscript; 59, identifier:b_len; 60, integer:0; 61, identifier:a; 62, identifier:b; 63, call; 64, call; 65, identifier:a_len; 66, identifier:b_len; 67, call; 68, call; 69, integer:1; 70, list_comprehension; 71, integer:1; 72, binary_operator:a_len + 1; 73, call; 74, integer:1; 75, binary_operator:a_len + 1; 76, identifier:j; 77, call; 78, block; 79, identifier:d; 80, identifier:a_len; 81, attribute; 82, argument_list; 83, attribute; 84, argument_list; 85, identifier:len; 86, argument_list; 87, identifier:len; 88, argument_list; 89, identifier:j; 90, for_in_clause; 91, identifier:a_len; 92, integer:1; 93, attribute; 94, argument_list; 95, identifier:a_len; 96, integer:1; 97, identifier:range; 98, argument_list; 99, expression_statement; 100, expression_statement; 101, if_statement; 102, identifier:a_str; 103, identifier:lower; 104, identifier:b_str; 105, identifier:lower; 106, identifier:a; 107, identifier:b; 108, identifier:j; 109, call; 110, identifier:d; 111, identifier:append; 112, binary_operator:[i] + [0] * b_len; 113, integer:1; 114, binary_operator:b_len + 1; 115, assignment; 116, assignment; 117, boolean_operator; 118, block; 119, identifier:range; 120, argument_list; 121, list; 122, binary_operator:[0] * b_len; 123, identifier:b_len; 124, integer:1; 125, identifier:cost; 126, conditional_expression:0 if a[i - 1] == b[j - 1] else 1; 127, subscript; 128, call; 129, boolean_operator; 130, comparison_operator:a[i - 2] == b[j - 1]; 131, expression_statement; 132, integer:0; 133, binary_operator:b_len + 1; 134, identifier:i; 135, list; 136, identifier:b_len; 137, integer:0; 138, comparison_operator:a[i - 1] == b[j - 1]; 139, integer:1; 140, subscript; 141, identifier:j; 142, identifier:min; 143, argument_list; 144, boolean_operator; 145, comparison_operator:a[i - 1] == b[j - 2]; 146, subscript; 147, subscript; 148, assignment; 149, identifier:b_len; 150, integer:1; 151, integer:0; 152, subscript; 153, subscript; 154, identifier:d; 155, identifier:i; 156, binary_operator:d[i - 1][j] + 1; 157, binary_operator:d[i][j - 1] + 1; 158, binary_operator:d[i - 1][j - 1] + cost; 159, comparison_operator:i > 1; 160, comparison_operator:j > 1; 161, subscript; 162, subscript; 163, identifier:a; 164, binary_operator:i - 2; 165, identifier:b; 166, binary_operator:j - 1; 167, subscript; 168, call; 169, identifier:a; 170, binary_operator:i - 1; 171, identifier:b; 172, binary_operator:j - 1; 173, subscript; 174, integer:1; 175, subscript; 176, integer:1; 177, subscript; 178, identifier:cost; 179, identifier:i; 180, integer:1; 181, identifier:j; 182, integer:1; 183, identifier:a; 184, binary_operator:i - 1; 185, identifier:b; 186, binary_operator:j - 2; 187, identifier:i; 188, integer:2; 189, identifier:j; 190, integer:1; 191, subscript; 192, identifier:j; 193, identifier:min; 194, argument_list; 195, identifier:i; 196, integer:1; 197, identifier:j; 198, integer:1; 199, subscript; 200, identifier:j; 201, subscript; 202, binary_operator:j - 1; 203, subscript; 204, binary_operator:j - 1; 205, identifier:i; 206, integer:1; 207, identifier:j; 208, integer:2; 209, identifier:d; 210, identifier:i; 211, subscript; 212, binary_operator:d[i - 2][j - 2] + cost; 213, identifier:d; 214, binary_operator:i - 1; 215, identifier:d; 216, identifier:i; 217, identifier:j; 218, integer:1; 219, identifier:d; 220, binary_operator:i - 1; 221, identifier:j; 222, integer:1; 223, subscript; 224, identifier:j; 225, subscript; 226, identifier:cost; 227, identifier:i; 228, integer:1; 229, identifier:i; 230, integer:1; 231, identifier:d; 232, identifier:i; 233, subscript; 234, binary_operator:j - 2; 235, identifier:d; 236, binary_operator:i - 2; 237, identifier:j; 238, integer:2; 239, identifier:i; 240, integer:2
code: def lexical_distance(a_str: str, b_str: str) -> int:
      """Computes the lexical distance between strings A and B.
  
      The "distance" between two strings is given by counting the minimum number of edits
      needed to transform string A into string B. An edit can be an insertion, deletion,
      or substitution of a single character, or a swap of two adjacent characters.
  
      This distance can be useful for detecting typos in input or sorting.
      """
      if a_str == b_str:
          return 0
  
      a, b = a_str.lower(), b_str.lower()
      a_len, b_len = len(a), len(b)
  
      # Any case change counts as a single edit
      if a == b:
          return 1
  
      d = [[j for j in range(0, b_len + 1)]]
      for i in range(1, a_len + 1):
          d.append([i] + [0] * b_len)
  
      for i in range(1, a_len + 1):
          for j in range(1, b_len + 1):
              cost = 0 if a[i - 1] == b[j - 1] else 1
  
              d[i][j] = min(d[i - 1][j] + 1, d[i][j - 1] + 1, d[i - 1][j - 1] + cost)
  
              if i > 1 and j > 1 and a[i - 1] == b[j - 2] and a[i - 2] == b[j - 1]:
                  d[i][j] = min(d[i][j], d[i - 2][j - 2] + cost)
  
      return d[a_len][b_len]