希尔伯特大酒店


23

介绍

你们中有些人可能听说过希尔伯特大酒店。那里的经理丢失了他的住所清单,但他仍然保留了他们的入住顺序。每个客人都不能住在房间号小于其房间值的房间中,并且如果客人被添加到较低的房间中房间,较高房间的所有客人之间都没有空的空间,新来的客人被转移到一个房间。您能帮他找到每位客人的住处吗?

要求

编写一个程序,该程序接收自然数的有序列表作为输入,并将其放在其索引处。如果该索引中已经有一个值,则将其上移到列表中的下一个条目。重复此过程,直到找到第一个空白(0或未定义)空间。当前最高索引与任何新输入之间的所有未定义空格都将加0。由于这是希尔伯特大酒店,因此不存在比当前最高入住指数更高的房间。

输入输出

输入将是自然数的有序列表(允许通过任何可接受的输入形式读取)输入中的
每个数均被视为一位到达酒店且按到达顺序排列的客人

输出将是客人的最终安排(人数)

例子

输入: 1 3 1
输出: 1 1 3
逐步:
1
在索引1处创建房间并将1放置在其中
1 0 3
在索引3处创建房间并将3放置在房间3中
1 1 3
向上移动房间1的内容一室一厅1

输入: 1 4 3 1 2 1
输出:1 1 2 1 3 4
逐步:
1
在索引1处创建房间并将1放置在其中
1 0 0 4
在索引4处创建房间并将4放置在房间4
1 0 3 4
将3放在房间3
1 1 1 3 4
将房间1的内容上移一个房间并将1放在房间1
1 2 1 3 4
将房间2的内容上移到1并将一个房间2放在房间2
1 1 2 1 4
将房间1到5的内容上移一个房间并将1放在房间1中

输入: 10
输出: 0 0 0 0 0 0 0 0 0 10
逐步:
0 0 0 0 0 0 0 0 0 10
创建房间直到10房间并将10放在房间10中。

注意:
使用0索引是可以的,在这种情况下,您可以在输出的前面插入0

禁止标准漏洞,以字节为单位的最短代码获胜

Answers:



5

PHP 93字节

for(;$r=$g?$r+1:$g=$argv[++$i];[$g,$h[$r]]=[$h[$r],$g])$h=array_pad($h?:[],$g,0);print_r($h);

0索引。使用2合1循环,在获得0(或超出当前最终房间的空表格)后查找下一个访客。使用方式如下:

php -r "for(;$r=$g?$r+1:$g=$argv[++$i];[$g,$h[$r]]=[$h[$r],$g])$h=array_pad($h?:[],$g,0);print_r($h);" 1 4 3 1 2 1

取消高尔夫:

for( $hotel = []; $room = $guest = $argv[ ++$i ]; )
{
    for( $hotel = array_pad( $hotel, $guest, 0 ); $guest; $room++ )
    {
        $last = $hotel[ $room ];
        $hotel[ $room ] = $guest;
        $guest = $last;
    }
}
print_r( $hotel );

哈哈哈,看起来几乎像是perl!
Zachary Craig


2

的JavaScript(ES6),144 120个字节

感谢Arnauld,节省了20B;感谢Neil,节省了11B

a=>a.map((d,c)=>b[d]?(b.splice(d,0,d),b.splice([...b,0].find‌​Index((e,g)=>g&&!e),‌​1)):b[d]=d,b=[])&&[...b].map(c=>c|0)

用法

您可以将函数分配给变量f,并且列表应作为数组给出。例:

f=a=>a.map((d,c)=>b[d]?(b.splice(d,0,d),b.splice([...b,0].find‌​Index((e,g)=>g&&!e),‌​1)):b[d]=d,b=[])&&[...b].map(c=>c|0)
f([1,4,3,1,2,1])

输出量

输出也位于数组中。由于Javascript的索引为零,因此前面有一个额外的0。

[0, 1, 1, 2, 1, 3, 4]

我没有真正测试过,但是可以(c+'').split`,`.map(Number)胜任吗?
Arnauld

聪明的把戏,是的,它确实有效。谢谢。
路加福音

糟糕,我忘了测试测试用例2,结果发现我的函数不支持将内容添加到数组的前面...
Luke

我相信你可以做到,c.map(n=>n|0)而不是(c+'').split`,`.map(Number)
ETHproductions

@ETHproductions问题是map()根本不对数组中的未定义值进行迭代。(也就是说,我很确定有比我建议的方法更短的方法。)
Arnauld

1

JavaScript(ES6),86个字节

f=([n,...a],r=[],p=n,m=r[p],_=r[p]=n)=>n?m?f([m,...a],r,p+1):f(a,r):[...r].map(n=>n|0)

由于JavaScript的索引为0,因此结果的前导零。


1

Mathematica,98个字节

Fold[If[Length@#<#2,PadRight@##~Append~#2,Join[Take@##,{#2},Drop@##/.{a___,0,b__}->{a,b}]]&,{0},#]&

未命名函数,取一个正整数列表,并返回一个0索引的整数列表。整个If函数采用部分完成的列表和要插入的下一个整数作为参数。如果下一个整数超过部分列表的长度,则相应地PadRight@##~Append~#2增加部分列表;否则,增加部分列表的长度。否则,Join[Take@##,{#2},Drop@##/.{a___,0,b__}->{a,b}]]将下一个整数插入其位置,然后丢弃在其后0找到的第一个整数。Fold[...,{0},#]从空的酒店开始,将此功能反复应用于原始列表{0},然后输出最终的酒店列表。


1

JavaScript(ES6),81

使用0索引

l=>l.map(v=>(s=(p,v,w=r[p])=>(w&&s(p+1,w),r[p]=v))(v,v),r=[])&&[...r].map(x=>~~x)

少打高尔夫球

l => {
  s = ( // recursively insert a value, shifting present values up until it finds an empty spot
       p, // insert position
       v, // value to insert
       w = r[p] // value a current position
      ) => ( 
         w && s(p+1,w), // if there is a value, put it in the next position
         r[p] = v // now the current place is empty
      );
  r = []; // initialize the result array   
  l.map( // execute the following for each value in input
     v => s(v,v) // insert value
  );
  return [...r].map(x=>~~x) // fill the missing places with 0
}

测试

F=
l=>l.map(v=>(s=(p,v,w=r[p])=>(w&&s(p+1,w),r[p]=v))(v,v),r=[])&&[...r].map(x=>~~x)

out=x=>O.textContent+=x+'\n'

out([1,3,1]+' -> '+F([1,3,1]))
out([10]+' -> '+F([10]))

function go() {
   var v = I.value.match(/\d+/g).map(x=>+x)
   out(v +' -> ' + F(v))
}
go()
<input id=I value='1 4 3 1 2 1'><button onclick='go()'>go</button>
<pre id=O></pre>


1

R,133字节

a=scan()
z=rep(0,max(a))
for(i in a){b=match(0,z[-1:-i])+i
if(z[i])z[i:b]=c(i,z[i:(b-1)])else(z[i]=i)
z=c(z,0)}
z[1:max(which(z!=0))]

为避免索引编制不正确的问题,我填充了一些零,然后在末尾将其删除。这可能不是最好的解决方案,但它可以工作。


0

Python中,134个 125 116字节

def a(b):
 r=[]
 i=0
 for n in b:
    d=n
    while n:
     if i<d:r.extend([0]*(d-i));i=d
     n,r[d-1]=r[d-1],n;d+=1
 return r

对Python 2.7.13和3.6.0有效。该代码通过将保持的值与每个索引中包含的值交换直到保持的值为0来起作用。如果到达的索引尚未到达数组,则在数组的末尾添加零,直到数组包含该值为止。指数。感谢Wheat Wizard和xnor分别打出9个字节


1
代替为所有缩进使用空格,您可以为第一层缩进使用空格,为第二层使用制表符,然后为第三层使用制表符。
小麦巫师

我当时正在使用一个愚蠢的编辑器,该编辑器将Tab转换为4个空格XP
fəˈnɛtɪk

1
的条件whileif不需要括号。您可以将多个语句放在一行之间,并用;like 分隔,if(i<d):r.extend([0]*(d-i));i=d除非后面的语句中有控制流。
xnor
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.