Grand Hotel Hilbert

23

pengantar

Beberapa dari Anda mungkin pernah mendengar tentang Hilbert's Grand Hotel . Manajer di sana telah kehilangan daftar di mana para tamu menginap tetapi dia masih memiliki urutan di mana mereka check in. Setiap tamu tidak dapat tinggal di kamar dengan nomor kamar kurang dari nilai mereka dan jika tamu ditambahkan ke yang lebih rendah kamar, semua tamu di kamar yang lebih tinggi tanpa ruang kosong antara mereka dan tamu baru digeser ke atas satu kamar. Bisakah Anda membantunya menemukan di mana masing-masing tamu menginap?

Persyaratan

Tulis program yang menerima daftar nomor alami sebagai input dan letakkan di indeks mereka. Jika sudah ada nilai dalam indeks itu, itu bergeser ke entri berikutnya dalam daftar. Proses ini berulang sampai ruang kosong pertama (0 atau tidak ditentukan) ditemukan. Setiap ruang yang tidak terdefinisi antara indeks tertinggi saat ini dan setiap input baru akan diisi dengan menambahkan 0s. Karena ini adalah Grand Hotel Hilbert, kamar yang lebih tinggi dari indeks tertinggi saat ini tidak ada.

Masukan dan keluaran

Input akan menjadi daftar nomor alami yang diurutkan (diizinkan untuk dibaca melalui setiap bentuk input yang diterima).
Setiap nomor dalam input dianggap sebagai satu tamu yang tiba di hotel dan dalam urutan kedatangan

Output akan menjadi pengaturan terakhir tamu (angka)

Contohnya

Input: 1 3 1
Output: 1 1 3
Langkah demi langkah:
1
Buat kamar di indeks 1 dan tempat 1 di dalamnya
1 0 3
Buat kamar hingga indeks 3 dan tempat 3 di kamar 3
1 1 3
Geser isi kamar 1 ke atas satu kamar dan tempat 1 di kamar 1

Input: 1 4 3 1 2 1
Output : 1 1 2 1 3 4
Langkah demi langkah:
1
Buat kamar di indeks 1 dan tempat 1 di dalamnya
1 0 0 4
Buat kamar hingga indeks 4 dan tempat 4 di kamar 4
1 0 3 4
Tempat 3 di kamar 3
1 1 3 4
Menggeser isi kamar 1 ke atas satu kamar dan tempat 1 di kamar 1
1 2 1 3 4
Menggeser isi kamar 2 ke 4 ke atas satu kamar dan menempatkan 2 di kamar 2
1 1 2 1 3 4
Geser isi kamar 1 ke 5 ke atas satu kamar dan letakkan 1 di kamar 1

Input: 10
Output: 0 0 0 0 0 0 0 0 0 0 10
Langkah demi langkah:
0 0 0 0 0 0 0 0 0 10
Buat kamar hingga kamar 10 dan tempat 10 di kamar 10

Catatan:
Bekerja dengan 0 diindeks baik-baik saja dan Anda dapat memasukkan 0 di depan output dalam kasus itu

Celah standar dilarang, kode terpendek dalam byte menang

fəˈnɛtɪk
sumber

Jawaban:

5

PHP 93 byte

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

0 diindeks. Menggunakan loop 2 in 1 yang mencari tamu berikutnya setelah mendapat 0 (atau bentuk nol melampaui ruang akhir saat ini). Gunakan seperti:

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

Tidak Disatukan:

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 );
pengguna59178
sumber
Hahaha, itu hampir seperti perl!
Zachary Craig
3

Haskell , 107 byte

h=foldl(\h n->let{(b,a)=splitAt n h;(c,d)=span(>0)a;e=0:e;f=take n$b++e;g(0:m)=m;g m=m}in f++[n]++c++g d)[]

Cobalah online!

Roman Czyborra
sumber
2

JavaScript (ES6), 144 120 byte

Menyelamatkan 20B berkat Arnauld dan 11B berkat Neil

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)

Pemakaian

Anda dapat menetapkan fungsi ke variabel fdan daftar harus diberikan sebagai array. Contoh:

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])

Keluaran

Outputnya juga ada dalam array. Karena Javascript berfungsi tanpa indeks, ada 0 tambahan di bagian depan.

[0, 1, 1, 2, 1, 3, 4]
Luke
sumber
Saya tidak benar-benar menguji itu, tetapi dapat (c+'').split`,`.map(Number)melakukan pekerjaan itu?
Arnauld
Trik cerdas, dan ya, itu berhasil. Terima kasih.
Luke
Ups, saya lupa menguji testcase 2, dan ternyata fungsi saya tidak mendukung penambahan hal-hal di depan array ...
Luke
Saya percaya Anda bisa melakukan c.map(n=>n|0)daripada (c+'').split`,`.map(Number).
ETHproduksi
@ ETHproductions Masalahnya adalah map()tidak mengulangi sama sekali pada nilai yang tidak ditentukan dalam array. (Yang mengatakan, aku cukup yakin ada jalan yang lebih pendek daripada yang aku sarankan.)
Arnauld
1

JavaScript (ES6), 86 byte

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)

Memimpin nol dalam hasil karena JavaScript diindeks 0.

Neil
sumber
1

Mathematica, 98 byte

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

Fungsi yang tidak disebutkan namanya mengambil daftar bilangan bulat positif dan mengembalikan daftar bilangan bulat 0-diindeks. Seluruh Iffungsi mengambil daftar yang diselesaikan sebagian dan bilangan bulat berikutnya untuk dimasukkan sebagai argumen. Jika bilangan bulat berikutnya melebihi panjang daftar parsial, PadRight@##~Append~#2tambahkan daftar parsial yang sesuai; jika tidak, Join[Take@##,{#2},Drop@##/.{a___,0,b__}->{a,b}]]masukkan bilangan bulat berikutnya ke posisinya, lalu buang yang pertama 0ditemukan setelah itu. Fold[...,{0},#]menerapkan fungsi ini berulang kali ke daftar asli, dimulai dengan hotel kosong {0}, dan menampilkan daftar hotel akhir.

Greg Martin
sumber
1

JavaScript (ES6), 81

Menggunakan 0 pengindeksan

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)

Kurang golf

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
}

Uji

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>

edc65
sumber
1

R, 133 byte

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))]

Untuk menghindari masalah dengan pengindeksan yang buruk, saya pad dengan beberapa nol, dan kemudian menghapusnya di akhir. Ini mungkin bukan solusi terbaik, tetapi berhasil.

ixodesbeta
sumber
0

Python, 134 125 116 byte

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

Berlaku untuk Python 2.7.13 dan 3.6.0. Kode ini berfungsi dengan cara menukar nilai ditahan dengan nilai yang terkandung di setiap indeks hingga nilai ditahan adalah 0. Jika mencapai indeks yang belum ada dalam array, kode ini menambahkan angka nol di akhir array hingga array berisi itu indeks. Terima kasih kepada Wheat Wizard dan xnor untuk bermain golf masing-masing 9 byte

fəˈnɛtɪk
sumber
1
Alih-alih menggunakan spasi untuk semua indentasi Anda, Anda bisa menggunakan ruang untuk indentasi level satu, tab untuk level dua dan tab diikuti oleh spasi untuk level tiga.
Wheat Wizard
Saya sedang bekerja dengan editor bodoh yang mengubah tab menjadi 4 spasi XP
fəˈnɛtɪk
1
Kondisi untuk whiledan iftidak perlu orangtua. Anda bisa meletakkan banyak pernyataan pada satu baris yang dipisahkan oleh ;like if(i<d):r.extend([0]*(d-i));i=dkecuali jika ada kontrol flow di pernyataan selanjutnya.
xnor