Hilbert's hotel paradox
With three guests in rooms 1 to 3 and two new arrivals, everyone moves up two rooms and rooms 1 and 2 open up. Enter your register and the number arriving to see each guest's new room. Free in your browser.
- Free
- Runs in your browser
- No sign-up
- Your data stays on your device
Run — free
Runs in your browser. Free, unlimited — your data never leaves this page.
Hilbert's hotel is the classic thought experiment about infinity: a fully booked hotel with infinitely many rooms can always make space for more guests, simply by asking every current guest to move up. You send the current register — each guest and their room number — plus how many new guests have arrived, and you get back the new room assignment for every guest together with the list of rooms that have just been freed. A negative arrival count is rejected, because guests cannot un-arrive. It runs deterministically, with no randomness and no external calls, so the same input always produces the same reassignment.
The paradox, made concrete
David Hilbert's thought experiment imagines a hotel with infinitely many rooms, all of them occupied. When a new guest arrives, an ordinary full hotel must turn them away; Hilbert's hotel does not. The manager simply asks the guest in room 1 to move to room 2, the guest in room 2 to move to room 3, and so on — every guest shifts up by one, and room 1 is suddenly free.
If a bus with forty new tourists arrives, everyone moves up by forty rooms instead, freeing rooms 1 through 40. The hilbert's hotel paradox simulator performs this exact shift on whatever register you give it: each current guest's room number is increased by the arrival count, and the rooms freed at the bottom of the numbering are returned explicitly, so you can see precisely where the newcomers would go. The counterintuitive lesson — that a full infinite hotel always has room — becomes a plain, checkable list of room moves.
How the shift is computed
The algorithm is deliberately simple and fully deterministic. You provide a list of current guests, each with a name and a positive integer room number, plus the number of new arrivals. The simulator validates the register — every room must be a positive integer and the arrival count must be a non-negative integer — and then adds the arrival count to every room number.
A guest in room 7 with three new arrivals ends up in room 10. The output returns, for each guest, their old room and their new room, alongside the complete list of freed rooms: the integers from 1 up to the arrival count. There is no randomness, no clock, and no network access anywhere in the computation, so repeated calls with the same input return byte-identical results.
What you can do with it
Teach the paradox interactively
Show students exactly which room every guest moves to when one, ten, or a thousand new arrivals show up at a full hotel.
Demo a deterministic shift function
Illustrate the 'move every key up by a constant' pattern used in rehashing and load balancing with a memorable example.
Generate puzzle and quiz data
Produce consistent before-and-after room assignments for math puzzles without computing the shifts by hand.
FAQ
Why is a negative arrival count rejected?
Because the paradox only works in one direction: a full infinite hotel can always absorb more guests, but guests cannot un-arrive.
Is the simulation random in any way?
No. It is fully deterministic — no randomness, no clock, no network. The same input always returns the same assignments.
What are the input limits?
Every room number must be a positive integer.
Does this model an actually infinite hotel?
It simulates the finite step of the paradox: shifting a given register by a given arrival count. The infinity is the takeaway — the shift works no matter how large the hotel is.
Which rooms are freed when new guests arrive?
Rooms 1 up to the number of arrivals. With two new guests, rooms 1 and 2 open up while Ada moves from room 1 to 3, Alan from 2 to 4 and Grace from 3 to 5.
Related tools
For developers — API access
Everything on this page is available programmatically. This section is for teams who want to wire it into their own systems; everyone else can just use the tool above.
API endpoint
Prefer to automate it? One authenticated POST creates the task; the result comes back by webhook or a signed link. The same capability also runs here on the web, by email and from Telegram — and soon from our app too.
Call it from your stack
curl -X POST https://api.kit.forhosting.com/math/hilberts-hotel-paradox \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"guests":[{"guest":"Ada","room":1},{"guest":"Alan","room":2},{"guest":"Grace","room":3}],"new_arrivals":2}'const res = await fetch("https://api.kit.forhosting.com/math/hilberts-hotel-paradox", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"guests": [
{
"guest": "Ada",
"room": 1
},
{
"guest": "Alan",
"room": 2
},
{
"guest": "Grace",
"room": 3
}
],
"new_arrivals": 2
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/math/hilberts-hotel-paradox",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"guests": [
{
"guest": "Ada",
"room": 1
},
{
"guest": "Alan",
"room": 2
},
{
"guest": "Grace",
"room": 3
}
],
"new_arrivals": 2
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/math/hilberts-hotel-paradox", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"guests":[{"guest":"Ada","room":1},{"guest":"Alan","room":2},{"guest":"Grace","room":3}],"new_arrivals":2}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"guests":[{"guest":"Ada","room":1},{"guest":"Alan","room":2},{"guest":"Grace","room":3}],"new_arrivals":2}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/math/hilberts-hotel-paradox", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"guests": [
{
"guest": "Ada",
"room": 1
},
{
"guest": "Alan",
"room": 2
},
{
"guest": "Grace",
"room": 3
}
],
"new_arrivals": 2
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "math.hilberts_hotel_paradox",
"status": "queued",
"_links": {
"result": "/tasks/tsk_…/result"
}
}The API is asynchronous: the call returns a task_id immediately and the result arrives by webhook. Polling is capped at 1 req/s per task.
Pricing
Published price — no tokens, no invented credits. A failed task is never charged.
Limits
max_guests | 10000 |
max_arrivals | 1000000 |
Errors
| HTTP | Code | Meaning |
|---|---|---|
401 | unauthorized | Missing or invalid API key. |
402 | insufficient_balance | Your balance doesn't cover the task price. |
404 | unknown_type | That task type doesn't exist. |
429 | rate_limited | Too many requests. Use the webhook instead of polling. |
Technical notes
This API simulates exactly that move.
How the shift is computed
A negative arrival count is rejected with an invalid_input error and is never charged, because the paradox only works in one direction — you can always squeeze more guests in, but you cannot un-arrive them.
Where it fits
This capability is built for teaching, demonstrations and quick sanity checks. Educators use it to turn an abstract paradox into something students can poke at: change the arrival count, watch every assignment update, and confirm that the freed rooms always match the newcomers. It also works as a playful example of a pure reassignment function — the same 'shift every key by a constant' operation appears in load balancing, ring buffers and rehashing schemes, and this endpoint demonstrates it with zero setup. It runs free in your browser on this page with the same code that serves the API, so you pay only when you automate it, at $0.002 per request. Input limits keep the register sane — up to ten thousand guests and a million arrivals per call — which is far beyond anything a classroom or a demo needs, while keeping responses instant.
Technical questions
What does it cost?
$0.002 per request via the API. It is also free to run in your browser on this page with the same code.
What does the freed_rooms field contain?
The room numbers freed by the shift: the integers from 1 up to the arrival count. These are the rooms the new guests would occupy.