힐버트 그랜드 호텔


23

소개

힐버트 그랜드 호텔에 대해 들어 본 적이있을 것 입니다. 그곳의 관리자는 손님이 머무르는 곳의 목록을 잃어 버렸지 만 여전히 체크인 순서가 있습니다. 각 손님은 자신의 가치보다 낮은 방 번호를 가진 방에 머물 수 없으며 손님이 더 낮은 곳에 추가되면 방, 더 높은 방에있는 모든 손님과 그들 사이에 빈 공간이 없으면 한 방 위로 이동합니다. 각 손님이 머무는 곳을 찾도록 도와 줄 수 있습니까?

요구 사항

순서대로 자연수 목록을 입력으로 받아 색인에 배치하는 프로그램을 작성하십시오. 해당 색인에 값이 이미 있으면 목록의 다음 항목으로 이동합니다. 이 프로세스는 첫 번째 비어있는 (0 또는 정의되지 않은) 공간이 발견 될 때까지 반복됩니다. 현재 최고 색인과 새로운 입력 사이에 정의되지 않은 공백은 0을 추가하여 채워집니다. 이것이 힐버트의 그랜드 호텔이므로 현재 가장 높은 점유 지수보다 높은 객실은 존재하지 않습니다.

입력과 출력

입력은 순서가 지정된 자연수 목록입니다 (허용되는 모든 형식의 입력을 통해 읽을 수 있음) 입력의
각 숫자는 호텔에 도착한 한 명의 손님으로 간주되며 도착 순서대로 표시됩니다

출력은 손님의 최종 배열입니다 (숫자).

입력 : 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 2 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 4
방 1 ~ 5의 내용을 한 방 위로 옮기고 1을 방 1에 놓으십시오.

입력 : 10
출력 : 0000 0000 10
단계적으로 :
0000 10 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입니다. 0을 얻은 후 다음 손님을 찾는 2 in 1 루프를 사용합니다 (또는 현재 마지막 방을 넘어서는 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

언 골프 드 :

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

하하, 거의 펄이 될 것 같습니다!
Zachary Craig


2

자바 스크립트 (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이 필요합니다.

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

나는 그것을 실제로 테스트하지는 않았지만 일을 할 수 (c+'').split`,`.map(Number)있습니까?
Arnauld

영리한 속임수와 그렇습니다. 감사.
Luke

죄송합니다. 테스트 사례 2를 테스트하는 것을 잊어 버렸습니다. 함수가 배열 앞에 항목을 추가하는 것을 지원하지 않는 것으로 나타났습니다.
Luke

나는 당신이 c.map(n=>n|0)오히려 할 수 있다고 생각합니다 (c+'').split`,`.map(Number).
ETHproductions

@ETHproductions 문제는 map()배열의 정의되지 않은 값을 전혀 반복하지 않는다는 것입니다. (저는 제가 제안한 것보다 더 짧은 방법이 있다고 확신합니다.)
Arnauld

1

자바 스크립트 (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으로 인덱스되므로 결과에서 선행 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

자바 스크립트 (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으로 채우고 끝에서 제거합니다. 이것이 최선의 해결책은 아니지만 효과가 있습니다.


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이 될 때까지 보류 된 값을 각 인덱스에 포함 된 값으로 바꾸는 방식으로 작동합니다. 아직 배열에없는 인덱스에 도달하면 배열에 해당 값이 포함될 때까지 배열 끝에 0을 추가합니다. 색인. Wheat Wizard와 xnor 덕분에 각각 9 바이트의 골프를 쳤습니다.


1
모든 들여 쓰기에 공백을 사용하는 대신 1 단계 들여 쓰기를위한 공간, 2 단계를위한 탭 및 3 단계를위한 공백을 사용할 수 있습니다.
밀 마법사

나는 탭을 4 개의 공백으로 변환 한 바보 같은 편집기로 작업하고 있었다
fəˈnɛtɪk

1
에 대한 조건 whileif할 필요가 없습니다 괄호. 나중 명령문에 제어 플로우가없는 경우 ;처럼 여러 명령문을 한 행에 같은 방식으로 구분하여 둘 수 있습니다 if(i<d):r.extend([0]*(d-i));i=d.
xnor
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.