ヒルバーツグランドホテル


23

前書き

ヒルベルトグランドホテルのことを聞いたことがある人もいるかもしれません。マネージャーは、ゲストが滞在している場所のリストを失いましたが、まだチェックインした順番を持っています。各ゲストは、値よりも小さい部屋番号の客室に滞在することはできません。部屋、空いているスペースのない上位の部屋のすべてのゲストと新しいゲストは1部屋上に移動します。各ゲストが滞在している場所を見つけるのを手伝ってもらえますか?

必要条件

入力として自然数の順序付きリストを受け取り、それらをインデックスに配置するプログラムを作成します。そのインデックスに既に値が存在する場合、リスト内の次のエントリまでシフトされます。このプロセスは、最初の空の(0または未定義の)スペースが見つかるまで繰り返されます。現在の最高のインデックスと新しい入力との間の未定義のスペースは、0を追加することによって埋められます。これはヒルベルトのグランドホテルであるため、現在最も高い占有インデックスよりも高い部屋は存在しません。

入出力

入力は、自然数の順序付きリストになります(入力の受け入れられた形式を介して読み取ることができます)入力の
各数字は、1人のゲストがホテルに到着したと見なされ、到着順になります

出力は、ゲストの最終配置(番号)になります

入力: 1 3 1
出力: 1 1 3
ステップバイステップ:
1
インデックス1に部屋を作成し、その中に
1を配置1 0 3
インデックス3までの部屋を作成し、部屋3に3を配置
1 1 1 3
部屋1の内容を上にシフト1つの部屋と部屋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 3 4
部屋1の内容を1部屋上に移動し、部屋1に
1を配置1 2 1 3 4
部屋2の内容を1部屋上に移動し、2を部屋2に配置
1 1 2 1 3 4
部屋1の内容を1部屋から5部屋にシフトし、部屋1に1を配置します。

入力: 10
出力: 0 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を挿入できます

標準的な抜け穴は禁止されており、バイト単位の最短コードが勝ちます

回答:



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 in 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になりそうだ!
ザカリークレイグ


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)、仕事はできますか?
アーナウド

巧妙なトリック、そしてはい、それは動作します。ありがとう。
ルーク

おっと、私はテストのテストケース2に忘れてしまった、それは...、配列の先頭に物事を追加サポートしていない私の機能を判明
ルーク

私はあなたがc.map(n=>n|0)むしろできると信じています(c+'').split`,`.map(Number)
ETHproductions

@ETHproductions問題はmap()、配列内の未定義の値をまったく反復しないことです。(とはいえ、私が提案した方法よりも短い方法があると確信しています。)
アーナウド

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},#]空のhotelから始めて、この関数を元のリストに繰り返し適用し{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

パイソン、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になるまでスワップすることによって機能します。まだ配列にないインデックスに到達すると、配列にインデックス。ウィートウィザードとxnorのおかげで、それぞれ9バイトのゴルフができました


1
すべてのインデントにスペースを使用する代わりに、レベル1のインデントにスペース、レベル2にタブ、レベル3にスペースが続くタブを使用できます。
小麦ウィザード

私はタブを4スペースXPに変換する愚かなエディターで作業していました
-fəˈnɛtɪk

1
かっこを必要whileifしない条件。後のステートメントに制御フローがない限り、複数のステートメントを;同じように区切って1行に配置できif(i<d):r.extend([0]*(d-i));i=dます。
xnor
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.