秘密圣诞老人-再访


11

圣诞节快到了,圣诞节也随之而来,安排了一年一度的家庭秘密圣诞老人。我想尝试Bob先行一步,但要确保夫妻之间不互相购买会继续造成问题,尽管这样做了很多年,但仍然存在着一个问题,那就是为大多数受赠人购买礼物是一件很垃圾的事情,Erin可能会感到失望,但他知道Frank喜欢塔利斯克,所以他很适合他。这使得现有的简单解决方案都无法满足我的需求。

为了使我的生活更轻松,您的任务是编写一个函数(或您语言中最接近的替代方法),当给定一个数组数组(或您所选择语言中最接近的替代方法)时,返回(或输出)一对“ gifters”给以最短的代码(字节)为单位的“ giftees”,从而满足以下条件:

  • 每个名称都与输入数据中另一个随机选择的名称配对(请注意,并非总是可能根据提供的条件对输出进行随机化)
  • 名称将带有标志列表,这些标志表示具有相同顺序的邻接矩阵,因此column n表示与row相同的人n
  • 如果不能满足条件,请以您的语言返回错误的内容。
  • 如果有多个解决方案,则如果多次运行,您的程序必须能够生成所有解决方案。

你可以假定你将永远不会有重名的呈现,我们需要能够判断哪些家庭成员是的,但你可能会包含空格来区分数据呈现Bob SeniorBob Junior!对于相当大的系列,它应该在一小时内完成所有提供的测试用例,例如源数据中的100个唯一名称(请参阅下面的示例数据集,您必须能够在分配的时间内解析所有这些名称)。

输入示例:

santa([
    ["Alice", 0, 0, 1, 1, 1, 1, 1],
    ["Bob",   0, 0, 0, 0, 0, 1, 0],
    ["Carla", 1, 1, 0, 0, 0, 1, 1],
    ["Dan",   1, 1, 0, 0, 0, 1, 1],
    ["Erin",  1, 1, 0, 0, 0, 1, 1],
    ["Frank", 1, 1, 1, 1, 1, 0, 1],
    ["Gary",  1, 1, 1, 1, 1, 1, 0]
]);
// might return something like:
[
    ["Alice", "Erin"],
    ["Bob", "Frank"],
    ["Carla", "Alice"],
    ["Dan", "Gary"],
    ["Erin", "Bob"],
    ["Frank", "Dan"],
    ["Gary", "Carla"]
]
santa([
    ["Alice", 0, 1, 1, 1, 0, 1],
    ["Bob",   0, 0, 1, 1, 0, 1],
    ["Carla", 0, 1, 0, 1, 0, 1],
    ["Dan",   0, 1, 1, 0, 0, 0],
    ["Erin",  0, 0, 1, 0, 0, 1],
    ["Frank", 1, 1, 1, 1, 1, 0]
]);
false
santa([
    ["Alice", 0, 1, 1],
    ["Bob",   1, 0, 1],
    ["Carla", 1, 1, 0]
]);
[
    ["Alice", "Bob"],
    ["Bob", "Carla"],
    ["Carla", "Alice"]
]

根据语言,输入可以采用其他格式,例如,有关的详细信息STDIN 可以提供为:

script <<< 'Alice,0,0,1,1,1,1,1
Bob,0,0,0,0,0,1,0
Carla,1,1,0,0,0,1,1
Dan,1,1,0,0,0,1,1
Erin,1,1,0,0,0,1,1
Frank,1,1,1,1,1,0,1
Gary,1,1,1,1,1,1,0'

输出也可以任何合理的格式提供,以您的语言最简单的形式为准。可接受的格式包括数组数组(如上所述),或者可能是哈希Object//关联数组,甚至只是将对等打印到STDOUT

Alice:Dan
Bob:Erin
Carla:Bob
Dan:Alice
Erin:Frank
Frank:Carla

如有疑问,请询问并在答案中提供所需输入格式和预期输出格式的示例。

参考JavaScript实现

更大的数据集:100100200200 -许多解决方案200 -只有一个解决方案

参考实现在我的计算机上用不到4秒的时间完成了所有这些工作。

以上用此脚本生成的集。


1
我们是否假设子数组的元素与父数组的顺序相同?并且1在第k子阵列的(N + 1)个元素意味着第k人可以给第n个人?
msh210

@ msh210的确,抱歉,我没有详细说明,我将更新问题以进行确认。
Dom Hastings 2015年

在第一个示例中,它在哪里提供从Bob到的映射Erin?我只看到一个从ErinBob
LegionMammal978

@ LegionMammal978啊,这是一个很好的问题,只能通过编辑来回答...抱歉!固定!
唐·黑斯廷斯

1
N0!这是圣诞节过早的方式!这应该是送礼物的秘密土耳其。
格兰特·戴维斯

Answers:


4

Javascript ES6、191

此解决方案将所有可能的配对返回为配对列表的列表:

f=l=>(h=l=>l.length,n=l.map(i=>i.shift()),o=[],(r=s=>(g=h(s))<h(n)?l[g].map((e,x)=>e&&r([...s,x])):o.push([...s]))([]),o.filter(i=>h([...new Set(i)])==h(n)).map(l=>l.map((t,f)=>[n[f],n[t]])))

示例运行:

>> example = f([
    ["Alice", 0, 0, 1, 1, 1, 1, 1],
    ["Bob",   0, 0, 0, 0, 0, 1, 0],
    ["Carla", 1, 1, 0, 0, 0, 1, 1],
    ["Dan",   1, 1, 0, 0, 0, 1, 1],
    ["Erin",  1, 1, 0, 0, 0, 1, 1],
    ["Frank", 1, 1, 1, 1, 1, 0, 1],
    ["Gary",  1, 1, 1, 1, 1, 1, 0]])

<< Array [ Array[7], Array[7], Array[7], Array[7], Array[7], Array[7], Array[7], Array[7], Array[7], Array[7], 26 more… ]

>> example[0]

<< Array [ "Alice:Carla", "Bob:Frank", "Carla:Alice", "Dan:Bob", "Erin:Gary", "Frank:Dan", "Gary:Erin" ]

我认为基于较大的测试用例,这将失败,因为它将生成所有排列...您是否可以验证计算机上较大集合的完成情况?谢谢!抱歉,最初没有这些较大的集合。
Dom Hastings 2015年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.