Codewars“最近和最小”-与预期输出不匹配

时间:2019-12-20 09:27:11

标签: javascript node.js testing jestjs

我为Codewars 5kyu挑战Closest and Smallest编写了以下代码。

  

输入

     
      
  • n个正数(n = 0或n> = 2)的字符串strng   数字的权重数字的总和。例如99将具有   “权重” 18100将具有“权重” 1
  •   
     

如果两个数字的权重之差很小,则它们是“接近的”。

     

任务:

     

strng中的每个数字计算其“权重”,然后找到   strng的两个数字具有:

     
      
  • 最小的权重差
  •   
  • 权重最小
  •   
  • ,索引(或等级,编号最小)   在strng
  • 中从0开始   
     

输出:

     
      
  • 由两个数组组成的数组,每个子数组均采用以下格式:

    [number-weight, index in strng of the corresponding number, original
    corresponding number in strng]
    
  •   
     

两个子数组按其编号升序排列   如果这些权重不同,则以它们在字符串中的索引为准   如果它们具有相同的权重。

我正在Jest in节点中对其进行本地测试-一切正常。
但是它没有通过Codewars的测试。我真的很感谢任何提示。谢谢!

function closest(string) {
  if (string.length < 1)
    return [];
  const nums = string.split(" ");
  const weights = nums.map(e => e.split('').reduce((p, a) => Number(p) + Number(a)));
  const indexedWeights = [];
  let indexCounter = 0;
  for (let w of weights)
    indexedWeights.push([w, indexCounter++, Number(nums.shift())])
  let collected = [];
  indexedWeights.forEach(iw => {
    const iWCopy = indexedWeights.filter(item => item !== iw);
    const closest = iWCopy.reduce((a, b) => Math.abs(b[0] - iw[0]) < Math.abs(a[0] - iw[0]) ? b : a);
    const diff = Math.abs(closest[0] - iw[0]);
    collected.push([diff, iw[0], iw[1], iw[2]]);
  });
  collected.sort((a, b) => a[0] - b[0])
  const lowestDiff = collected[0][0]
  const result = collected.filter(n => n[0] === lowestDiff)
  result.sort((a, b) => a[1] - b[1])
  return [result[0].splice(1, 4), result[1].splice(1, 4)];
}

测试:

const closest = require("../5kyu_challenges/closestAndSmallest");
describe("closest", () => {
  test("returns an array containing 2 sub-arrays which consist of 3 numbers representing closest and smallest numbers", () => {
    expect(closest("")).toEqual([]);
    expect(closest("456899 50 11992 176 272293 163 389128 96 290193 85 52")).toEqual([ [13, 9, 85], [14, 3, 176] ]);
  });
  test("sorts by index number if weights are equal", () => {
    expect(closest("239382 162 254765 182 485944 134 468751 62 49780 108 54")).toEqual([ [8, 5, 134], [8, 7, 62] ]);
    expect(closest("403749 18 278325 97 304194 119 58359 165 144403 128 38")).toEqual([ [11, 5, 119], [11, 9, 128] ]);
  });
});

1 个答案:

答案 0 :(得分:1)

要求是还要根据匹配项的索引对输出进行排序(我突出显示):

  

如果两个子数组的权重不同,则按其数字权重按升序排序;如果权重相同,则按字符串中的索引进行排序。

因此,请在代码中更改此行:

result.sort((a, b) => a[1] - b[1])

与此:

result.sort((a, b) => a[1] - b[1] || a[2] - b[2])

效率

请注意,排序的时间复杂度为 O(nlogn)。因此,如果输入是一个非常大的数组,则与扫描collected数组中的最小值相比,对collected进行排序可能是一个较差的解决方案。