โรงแรม Hilbert's Grand


23

บทนำ

บางท่านอาจจะเคยได้ยินของฮิลแบร์ตแกรนด์โฮเต็ล ผู้จัดการที่นั่นสูญเสียรายชื่อแขกที่เข้าพัก แต่เขายังคงมีคำสั่งในการเช็คอินแขกแต่ละคนไม่สามารถเข้าพักในห้องที่มีจำนวนห้องน้อยกว่ามูลค่าของพวกเขาและหากแขกถูกเพิ่มลงต่ำ ห้องแขกทุกคนในห้องที่สูงขึ้นโดยไม่มีที่ว่างระหว่างพวกเขาและแขกใหม่จะเลื่อนขึ้นหนึ่งห้อง คุณช่วยเขาค้นหาว่าแขกแต่ละคนพักอยู่ที่ไหน?

ความต้องการ

เขียนโปรแกรมที่ได้รับรายการคำสั่งของตัวเลขธรรมชาติเป็นอินพุตและวางไว้ที่ดัชนีของพวกเขา หากมีค่าอยู่ในดัชนีนั้นมันจะถูกเลื่อนขึ้นเป็นรายการถัดไปในรายการ กระบวนการนี้ทำซ้ำจนกว่าจะพบพื้นที่ว่างเปล่า (0 หรือไม่ได้กำหนด) แรก ช่องว่างที่ไม่ได้กำหนดระหว่างดัชนีสูงสุดในปัจจุบันและอินพุตใหม่ใด ๆ จะถูกเติมด้วยการเพิ่ม 0s เนื่องจากที่นี่เป็นโรงแรมแกรนด์ของฮิลแบร์ตจึงไม่มีห้องพักที่สูงกว่าดัชนีที่ครอบครองสูงสุดในปัจจุบัน

อินพุตและเอาต์พุต

ข้อมูลที่ป้อนจะเป็นรายการหมายเลขธรรมชาติเรียงลำดับ (อนุญาตให้อ่านผ่านรูปแบบที่ยอมรับได้)
แต่ละหมายเลขในข้อมูลเข้าถือว่าเป็นแขกหนึ่งท่านที่เดินทางมาถึงโรงแรมและอยู่ในลำดับที่เดินทางมาถึง

ผลลัพธ์จะเป็นการจัดการสุดท้ายของแขก (หมายเลข)

ตัวอย่าง

ข้อมูลเข้า: 1 3 1
เอาท์พุท: 1 1 3
ทีละขั้นตอน:
1
สร้างห้องที่ดัชนี 1 และวาง 1 ในนั้น
1 0 3
สร้างห้องถึงดัชนี 3 และวาง 3 ในห้อง 3
1 1 3
เลื่อนเนื้อหาของห้อง 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 2 1 3
4 เลื่อนเนื้อหาของห้อง 2 ถึง 4 ขึ้นหนึ่งห้องและวาง 2 ในห้อง 2
1 1 2 1 3 3 4
เปลี่ยนเนื้อหาของห้องที่ 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 ในห้อง 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 (หรือแบบฟอร์ม null จะเกินห้องสุดท้ายปัจจุบัน) ใช้เช่น:

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

Ungolfed:

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 ไบต์

บันทึก 20B ขอบคุณ Arnauld และ 11B ขอบคุณ 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)

การใช้

คุณสามารถกำหนดฟังก์ชั่นให้กับตัวแปร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

เคล็ดลับที่ชาญฉลาดและใช่มันทำงานได้ดี ขอบคุณ
ลุค

โอ๊ะฉันลืมทดสอบ testcase 2 และปรากฎว่าฟังก์ชั่นของฉันไม่รองรับการเพิ่มสิ่งต่าง ๆ ลงในแถวหน้า ...
Luke

ผมเชื่อว่าคุณสามารถทำอะไรได้มากกว่าc.map(n=>n|0) (c+'').split`,`.map(Number)
ประโยชน์ทับซ้อน

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

น้อย golfed

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

เพื่อหลีกเลี่ยงปัญหาเกี่ยวกับการจัดทำดัชนีที่ไม่ดีฉันใช้ pad กับศูนย์บางส่วนแล้วดึงออกมาจนสุด นี่อาจไม่ใช่ทางออกที่ดีที่สุด แต่ใช้งานได้


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
แทนที่จะใช้ช่องว่างสำหรับการเยื้องทั้งหมดของคุณคุณสามารถใช้ช่องว่างสำหรับการเยื้องระดับหนึ่งแท็บสำหรับระดับสองและแท็บตามด้วยช่องว่างสำหรับระดับที่สาม
ข้าวสาลีตัวช่วยสร้าง

ฉันทำงานกับเครื่องมือแก้ไขโง่ที่แปลงแท็บเป็น 4 ช่องว่าง XP
fəˈn Jantɪk

1
เงื่อนไขสำหรับwhileและifไม่จำเป็นต้องมี parens คุณสามารถใส่หลาย statement ในหนึ่งบรรทัดโดยคั่นด้วย;like if(i<d):r.extend([0]*(d-i));i=dเว้นเสียแต่ว่าจะมีโฟลว์การควบคุมในข้อความสั่งในภายหลัง
xnor
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.