【问题标题】:Codewars "Closest and Smallest" - mismatch with expected outputCodewars“最接近和最小” - 与预期输出不匹配
【发布时间】:2019-12-20 18:17:12
【问题描述】:

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

输入

  • 由 n 个正数组成的字符串 strng(n = 0 或 n >= 2)让我们调用 一个数的权重是其数字的总和。例如99 将有 “重量”18100 将具有“重量”1

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

任务:

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

  • 最小的权重差,即最接近的
  • 具有最小的权重
  • 并且具有最小的索引(或排名,编号 从 0) 在strng

输出:

  • 一个由两个数组组成的数组,每个子数组的格式如下:

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

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

我在节点中使用 Jest 在本地对其进行测试 - 一切正常。
但它没有通过 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] ]);
  });
});

【问题讨论】:

  • 你能把codewars测试结果的结果加进去,让我们看看失败的地方吗?
  • 它通过了一些,但也失败了一些:时间:1082ms 通过:82 失败:139 退出代码:1 失败测试示例:Expected: '[[10, 1, 154], [10, 9, 37]]', instead got: '[[10, 9, 37], [10, 1, 154]]'
  • 它是否未能通过与本地相同的测试?还是它们是不同的测试?
  • 我认为这是您的代码的问题,因为 Codewars 有两组测试,一组通常非常简单,然后是一组更深入的测试,其中 katas 通常会失败。我建议你添加更多的测试用例......如果仍然失败,也许对 kata 进行评论,有时测试是错误的......
  • 感谢 Keff - 好地方!

标签: javascript node.js testing jestjs


【解决方案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 进行排序可能是一个较差的解决方案。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-11
    • 1970-01-01
    • 2010-12-03
    • 2011-03-01
    相关资源
    最近更新 更多