[Question]
  [
# Room Number Locator
I have come across an interesting problem solving technique at my job when given the wrong room number from a colleague for a meeting. Every now and then, while on the way to a meeting, a member on my team will send me the wrong room number, typically because they are in a rush at their desk and fat finger the wrong key.
Interestingly, upon arrival at the wrong room, I typically can guess which room they really meant by imagining a [Numeric Keypad](https://en.wikipedia.org/wiki/Numeric_keypad):
![](https://upload.wikimedia.org/wikipedia/commons/thumb/9/99/Numpad.svg/220px-Numpad.svg.png)
and by guessing an adjacent number they meant to press.
## Challenge
Your challenge is to write a function that takes a building office number (000-999) and outputs the possible typo solutions, **assuming your colleague only mistypes one digit.**
The following table shows which numbers are adjacent to each other on a Numeric Keypad:
```
0 -> 1,2
1 -> 0,2,4
2 -> 0,1,3,5
3 -> 2,6
4 -> 1,5,7
5 -> 2,4,6,8
6 -> 3,5,9
7 -> 4,8
8 -> 5,7,9
9 -> 6,8
```
## Input
A 3 digit number: `000-999`. Assume input of exactly 3 digits. If the number is less than 100 or less than 10, you will be given the leading zeros. (i.e. 004 & 028).
## Output
A list of possible rooms. This can be in any form you want, as long as there is a delimiter between room numbers. (i.e. space, comma, new line, etc..) If the number is less than 100 or less than 10, you can or cannot have the leading zeros as output, that is up to you. (i.e. 004 can be `004 04 4`, and 028 can be `028 28`)
Test Cases(leading zeros are optional):
```
008 -> 108, 208, 018, 028, 005, 007, 009 
123 -> 023, 223, 423, 103, 113, 133, 153, 122, 126
585 -> 285, 485, 685, 885, 555, 575, 595, 582, 584, 586, 588
777 -> 477, 877, 747, 787, 774, 778
963 -> 663, 863, 933, 953, 993, 962, 966
555 -> 255, 455, 655, 855, 525, 545, 565, 585, 552, 554, 556, 558
```
This is [code-golf](/questions/tagged/code-golf "show questions tagged 'code-golf'"), so the shortest code in bytes for each language wins.
  
[Answer]
# [Wolfram Language (Mathematica)](https://www.wolfram.com/wolframscript/), ~~112~~ 106 bytes
Recognizing that a numeric keypad is basically a 3x3 `GridGraph` with edges added for 0, we get the adjacent digits for each input digit with `AdjacencyList`. 
This can be seen below:
`EdgeAdd[GridGraph[{3,3},VertexLabels->"Name",GraphLayout->"SpringEmbedding"],{0<->1,0<->2}]` yields:
[![enter image description here](https://i.stack.imgur.com/nxinX.png)](https://i.stack.imgur.com/nxinX.png)
Then I use `Tuples` to figure out all the possible mistakes and pick out those with exactly one error with `Select` and `EditDistance`. By the way, this will work for longer room numbers and you can also increase the `EditDistance` parameter to allow for more than one error. Might be able to golf this down a little further but wanted to show my approach.
```
h@u_:=Select[Tuples[AdjacencyList[EdgeAdd[GridGraph[{3,3}],{0<->1,0<->2}],#]~Join~{#}&/@u],#~EditDistance~u==1&]
```
Slightly more golfed version hardcoded to length 3 room numbers (106 Bytes). This will output as a rank 3 list corresponding to each digit:
```
Thread/@ReplacePart[#~Table~3,{i_,i_}:>(AdjacencyList[GridGraph@{3,3}~EdgeAdd~{0<->1,0<->2},#]&/@#)[[i]]]&
```
[Try it online!](https://tio.run/##LYxNC4JAGITv/Q3B0xv5gWUfhkIiRIegbovEsru0G2qi6yGW9a9vbxADM8wwPC3VUrRUK0adk/n02GU30QimyX3qGzGSgr8oEx37XNSoScmfouCcVIPi1UB7SUwMsa3BBIflMYSfR1i9ej6/VTcbz/qrfMJhLrnSJ2TQjol5yrLQr911UJ0mMvdqfBkTQACpBRNChFAwCaSQYG4AhbmF9X9HWbtfuC8 "Wolfram Language (Mathematica) – Try It Online")
[Answer]
# [Python 2](https://docs.python.org/2/), 89 bytes
```
lambda r:[r[:i]+[c]+r[i+1:]for i,n in enumerate(r)for c in`ord(u'ÌЋ>তŧ0ɃD'[n])`]
```
[Try it online!](https://tio.run/##LYsxDoIwGEZ3dvc/cQDkJwEMik1k8ha1CQhUm0ghTRmcHfUKbkbvoXFw8wjeBEti3vCSl@9rD3rXyKgfgz/xoWhKIbcEOs39ZCgWX677fV5vyhwUoYoSwTxaME9R4YWE8UaBQAlCQiW7ulK5rhzlDrkwMWtU6XT26Hn@nNLH5Xu7vu7B@7iyqWRuxvphp4czpQEGmDCkIUY4NY4xwdh4jgbjBc7@3cAYsaBVQmrQaPupjdzRbv8D "Python 2 – Try It Online")
The 1st and 5th characters may not being displayed here (browser dependent), but the full string is equivalent to `[21, 204, 1035, 62, 157, 2468, 359, 48, 579, 68]`
[Answer]
# [05AB1E](https://github.com/Adriandmen/05AB1E), 29 bytes
```
v•4TË\ªye-³—Ïʒ••Ćδn¼•S£yèʒNǝ,
```
[Try it online!](https://tio.run/##MzBNTDJM/f@/7FHDIpOQw90xh1ZVpuoe2vyoYcrh/lOTgKJAdKTt3Ja8Q3uArOBDiysPrzg1ye/4XJ3//y3NjAE "05AB1E – Try It Online")
[Answer]
# [R](https://www.r-project.org/), 190 bytes
```
function(x){l=list(c(1,2),c(0,2,4),c(0,1,3,5),c(2,6),c(1,5,7),c(2,4,6,8),c(3,5,9),c(4,8),c(5,7,9),c(6,8))
a=do.call(expand.grid, mapply(c,l[x+1],x))
a[apply(a,1,function(y){sum(x==y)==2}),]}
```
[Try it online!](https://tio.run/##PY7LCoMwFET3/Youb@hUTKp9QPMl4iLEWgJRgw@IiN@eGgJd3TNzB2bG0L6voV16PZuhJ882K62ZZtLEIRg05RAoEnDcUEYUuMfDUeKRdIE7nhGPBF4RiqSPRNLxz05KNkOmlbX08U71TfYdTYNzp5yzK2nYyl94DR@jVTLV0fsfuLJtWjryUq5MSrEz1Htwo@lnailuzGMNCz8 "R – Try It Online")
---
My second attempt at CodeGolf! Pretty long, 190 bytes, but the best I could manage with R. Curious to see if others have feedback or can do better!
[Answer]
## JavaScript (Firefox 30-57), ~~115~~ 109 bytes
```
f=([c,...a],p=``)=>c?[...(for(n of``+[12,240,1350,26,157,2468,359,48,579,68][c])p+n+a.join``),...f(a,p+c)]:[]
```
Edit: Saved 6 bytes thanks to @edc65 (although suggested `0`s now appear after other suggestions). ES6 version, ~~118~~ 112 bytes:
```
f=([c,...a],p=``)=>c?[...[...``+[12,240,1350,26,157,2468,359,48,579,68][c]].map(n=>p+n+a.join``),...f(a,p+c)]:[]
```
```
<input oninput=o.textContent=f(this.value).join`\n`><pre id=o>
```
[Answer]
# Java, 205 177 bytes
```
b->{for(int c=0;c<3;c++){char[]d=b.toCharArray();for(char e:"12,024,0135,26,157,2468,359,48,579,68".split(",")[new Byte(""+d[c])].toCharArray()){d[c]=e;System.out.println(d);}}}
```
I know it's long compared to the other answers. My excuse: it's in Java.  
Oracle should rename `toCharArray` to something like `getCrs`.
## Credits
-28 characters by [**Kevin Cruijssen**](https://codegolf.stackexchange.com/users/52210/kevin-cruijssen)
[Answer]
# [Ruby](http://www.ruby-lang.org) 97 bytes
```
->i{c=0;i.map{|j|[12,204,1035,26,157,2468,359,48,579,68][j].digits.map{|k|f=*i;f[c]=k;p f};c+=1}}
```
[Try it online!](https://tio.run/##NY1NCoMwGET3PYXQXTuVJPrFSEgvkmbRWlKiCNKfRVDPnlqLzOrBm5nn5xZTNJd0OoexMUyHvL8O49ROlgsIVoKzgiAkOFUQpVQoqEapQFUNqZxtXX4Pj/B@/Yvd5M0haG8bZzo9ZH7WzdHweU77LFrLwKCc263AIVBsQFg2N6iwZIPlZ9VWiX5S@gI)
### Alternatively, 94 chars but 100 bytes
```
->i{c=0;i.map{|j|"\fÌЋ\u001A\u009Dতŧ0ɃD".unpack("U*")[j].digits.map{|k|f=*i;f[c]=k;p f};c+=1}}
```
[Try it online!](https://tio.run/##KypNqvxfaRvzX9cuszrZ1sA6Uy83saC6JqtGKSbtcM@F7phSAwNDRxBp6fJg2ZKjyw1ONrso6ZXmFSQmZ2sohWopaUZnxeqlZKZnlhRD9GbXpNlqZVqnRSfH2mZbFyik1Vona9sa1tb@V1aojI420DHQsYiN5QJzDHWMdIxhHFMdCx1TGMdcBwhhHEsdM7AysCJTkKL/AA)
[Answer]
# [C (gcc)](https://gcc.gnu.org/), 136 or 114 bytes
## ASCII version 136 bytes
```
m[]={12,240,1350,26,157,2468,359,48,579,68},p,i,X=10;f(n){for(i=100;i;i/=X)for(p=m[n/i%X];p;p/=X)printf("%d ",n/(i*X)*(i*X)+p%X*i+n%i);}
```
[Try it online!](https://tio.run/##PY3NioMwEMfPm6cIgpDYKSbamMjgPkeg9LBYlDmYhm73JD67m1R2LzP/j/kx43kex31frrdh1Q00FwW6NQqaDrSxyXcOWtPDxYGxPXRugwgEftAKJxHkOj2egpJTSEj14GUO4rBcQ02lv2HEmNP4pPCaRFHeeQGhFlR5Wb3nKZa@olMoSeK2zyLd8SDZyj7@GdXe@fkzgalAnt8ijz@vb1EUEtnGWGaWLwrizc3CpTgt3bSHMM4cwlp7iL77q0yutv0X "C (gcc) – Try It Online")
## Unicode ~~114~~ 108 bytes (TiO seems to count weirdly for this)
Thanks to @ceilingcat for this version.
```
p,i,X=10;f(n){for(i=1e3;i/=X;)for(p=L"\fðՆ\32\x9dতŧ0ɃD"[n/i%X];p;p/=X)printf("%d ",n/i/X*i*X+p%X*i+n%i);}
```
[Try it online!](https://tio.run/##S9ZNT07@/79AJ1MnwtbQwDpNI0@zOi2/SCPT1jDV2DpT3zbCWhPEL7D1UYpJO7zhaluMsVFMhWXKg2VLji43ONnsohSdp5@pGhFrXWBdAFSuWVCUmVeSpqGkmqKgpAOU0o/QytSK0C5QBdLaeaqZmta1/9M1gGoU8jS5qrk44eoNjFMUdO2AmoAS1gogl1grFJSWFGsoKWlac9VycYH05CZm5mmA9aVrWACFgZShkTGEYWphCmGYm5tDGJZmMClTkFTtfwA "C (gcc) – Try It Online")
[Answer]
# [Perl 5](https://www.perl.org/), ~~120~~ 85 + 2 (`-F`) = 87 bytes
```
map{@,=@F;$,[$i]=$_,say@,for(12,240,1350,26,157,2468,359,48,579,68)[$_]=~/./g;$i++}@F
```
[Try it online!](https://tio.run/##DcexDoIwFAXQn@mg4QJt4ZUS0qRTN7@AEMKgpgnaBlyM0U/36dlOPm8rMd@W/PJwPgwCo4iTEzP25elxSdtBaehWQjUkoQ0Udf8bi4Z6tBbU9TD2OIp5cp@6qq@DiEXx9oFZSvtN@RHTfefyRJVUksvwAw "Perl 5 – Try It Online")
Saved 35 bytes by borrowing an idea from @AsoneTuhid's ruby answer.
[Answer]
# [Python 2](https://docs.python.org/2/), 103 bytes
thanks to @Lynn for -4 bytes.
```
lambda n:{n[:i]+r+n[i+1:]for i,v in enumerate(n)for r in`0x134cd9a07d1e58feab643f7db24102`[int(v)::10]}
```
[Try it online!](https://tio.run/##JYzRCoMgGEbv9xT/nUVdqOUsYU/SgmwqE9ZfiIuNsWd3ya4OnI/vbO94X5End7mmh15mowHVBwflxypUOPiKqdGtAXy9g0ew@Fxs0NEWWGZ9DDjRF2vam@k1lYZZ0Tmr53PbOGlm3jLKp8FjLPZSKUbHb8q/mGOE0o7UQBhvMkQnMqSUGf35L4Ug6gSwhaMBsQZXxDL9AA "Python 2 – Try It Online")
[Answer]
# [Julia 0.6](http://julialang.org/), 93 bytes
```
~r=[(R=copy(r);R[j]=i;R)for i=0:9,j=1:3 if(big(1)<<(i+10r[j]))&0x502A044228550A21102B05406>0]
```
[Try it online!](https://tio.run/##VY1LT8MwEITv/RVWDpUtVurajUP6MFIRd6RQTsaHvtko2JEJolz619O4Ug/sXD7tzszWPw1tir6/RGN5ZXah/eNRLCpbO0OLShxDZGRwPoPayPmU0ZFv6cSlWC45PUiMg1GIMZ41qhXmuVKl1rhSUqJ6Rp1j8YSuTy0xhC9GnlmLgFA6YFaCgmkCDSXoBI8wKMEMivtpkHMjNkwbyXeN56lK3Dbfn@GXv61fXt/XwLLucO4mbbMhnwG73B6Kf8Hsw2didPD7/go "Julia 0.6 – Try It Online")
* Takes a vector of digits and returns a list in the same format.
* `0x502A044228550A21102B05406` is a `UInt128` in which the `1+10j`th bit is set iff `i` is next to `j` on the numpad.
* `big(1)` is a `BigInt`. It is used to prevent overflow and uses less characters than `Int128(1)` or `UInt128(1)`.
[Answer]
# [Jelly](https://github.com/DennisMitchell/jelly), 35 bytes
```
ḷþị“-ⱮⱮVḟ|żṣ~ẋ³ɱgẆ’ḃ⁽¦ḳ¤$ṛ¦DŒp$¥"JẎ
```
[Try it online!](https://tio.run/##AV0Aov9qZWxsef//4bi3w77hu4vigJwt4rGu4rGuVuG4n3zFvOG5o37huovCs8mxZ@G6huKAmeG4g@KBvcKm4bizwqQk4bmbwqZExZJwJMKlIkrhuo7///9bMCwgMCwgOF0 "Jelly – Try It Online")
-1 thanks to [Jonathan Allan](https://codegolf.stackexchange.com/users/53748/jonathan-allan).
*Explanation being updated...*
[Answer]
## SQL (SQLite), 533 bytes
```
with m as (select 0 as i, 1 as o union values (0,2),(1,0),(1,2),(1,4),(2,0),(2,1),(2,3),(2,5),(3,2),(3,6),(4,1),(4,5),(4,7),(5,2),(5,4),(5,6),(5,8),(6,3),(6,5),(6,9),(7,4),(7,8),(8,5),(8,7),(8,9),(9,6),(9,8))select o || substr('008', 2, 1) || substr('008', 3, 1)from m where substr('008', 1, 1) = cast(i as text)union select substr('008', 1, 1) || o || substr('008', 3, 1)from m where substr('008', 2, 1) = cast(i as text)union select substr('008', 1, 1) || substr('008', 2, 1) || o from m where substr('008', 3, 1) = cast(i as text)
```
### Ungolfed
```
with m as (
    select 0 as i, 1 as o
    union
    values
    /*(0,1),*/(0,2),
    (1,0),(1,2),(1,4),
    (2,0),(2,1),(2,3),(2,5),
    (3,2),(3,6),
    (4,1),(4,5),(4,7),
    (5,2),(5,4),(5,6),(5,8),
    (6,3),(6,5),(6,9),
    (7,4),(7,8),
    (8,5),(8,7),(8,9),
    (9,6),(9,8)
)
select o || substr(s, 2, 1) || substr(s, 3, 1)
from m, t
where substr(s, 1, 1) = cast(i as text)
union
select substr(s, 1, 1) || o || substr(s, 3, 1)
from m, t
where substr(s, 2, 1) = cast(i as text)
union
select substr(s, 1, 1) || substr(s, 2, 1) || o
from m, t
where substr(s, 3, 1) = cast(i as text)
```
### Explanation
The input is a single text row on table `t` with column `s`. My understanding is that [according to this meta answer](https://codegolf.meta.stackexchange.com/a/5341/36915) this is an acceptable form of input. The input can be created as below.
```
drop table if exists t;
create table t (s text);
insert into t values('555'); -- Your input here
```
### Annotated solution
```
with m as ( -- Using this in the "with" allows us to only type is once
    select 0 as i, 1 as o -- The first pair is here and it names the columns
    union
    values
    /*(0,1),*/(0,2),
    (1,0),(1,2),(1,4),
    (2,0),(2,1),(2,3),(2,5),
    (3,2),(3,6),
    (4,1),(4,5),(4,7),
    (5,2),(5,4),(5,6),(5,8),
    (6,3),(6,5),(6,9),
    (7,4),(7,8),
    (8,5),(8,7),(8,9),
    (9,6),(9,8)
)
select o || substr(s, 2, 1) || substr(s, 3, 1) -- concat the first wrong char with two correct chars
from m, t
where substr(s, 1, 1) = cast(i as text) -- when the first char is in the i (input) column from above
union
select substr(s, 1, 1) || o || substr(s, 3, 1)
from m, t
where substr(s, 2, 1) = cast(i as text)
union
select substr(s, 1, 1) || substr(s, 2, 1) || o
from m, t
where substr(s, 3, 1) = cast(i as text)
```
[Answer]
# [Kotlin](https://kotlinlang.org), 117 bytes
```
mapIndexed{i,c->"12,024,0135,26,157,2468,359,48,579,68".split(",")[c-'0'].map{replaceRange(i,i+1,it+"")}}.flatMap{it}
```
## Beautified
```
mapIndexed { i, c ->
    "12,024,0135,26,157,2468,359,48,579,68"
        .split(",")[c - '0']
        .map { replaceRange(i, i + 1, it + "") }
}.flatMap { it }
```
## Test
```
fun String.f(): List<String> =
mapIndexed{i,c->"12,024,0135,26,157,2468,359,48,579,68".split(",")[c-'0'].map{replaceRange(i,i+1,it+"")}}.flatMap{it}
data class Test(val input:Int, val answers: List<Int>)
val tests = listOf(
    Test(8, listOf(108, 208, 18, 28, 5, 7, 9)),
    Test(123, listOf(23, 223, 423, 103, 113, 133, 153, 122, 126)),
    Test(585, listOf(285, 485, 685, 885, 555, 575, 595, 582, 584, 586, 588)),
    Test(777, listOf(477, 877, 747, 787, 774, 778)),
    Test(963, listOf(663, 863, 933, 953, 993, 962, 966)),
    Test(555, listOf(255, 455, 655, 855, 525, 545, 565, 585, 552, 554, 556, 558))
)
fun main(args: Array<String>) {
    for (r in tests) {
        val input = r.input.toString().padStart(3, '0')
        val expected = r.answers.map { it.toString().padStart(3, '0') }.sorted()
        val actual = input.f().sorted()
        if (expected != actual) {
            throw AssertionError("$input -> $actual | $expected")
        }
    }
}
```
## TIO
[TryItOnline](https://tio.run/##fZNNi9swEIbv/hWqCazMKiZWLFlemsAeelhoKXR7Kz0Ix05FvbaRle6W1L89q9fOx6aFCvJkPNbMvMOMf7auNs0hqHYNeXTWNNu4otEd+Wh6935yrMnq8KS7h2ZTvpSbvWHFfB0mnC14yhbJUjAuWSIyxlOp2FLkLFVMZDmTKoz7rjaOhiyMvhXzm8XN99hn2tuyq3VRftHNtqSGmduEGXcbhtEwxFWt3Sd/x7jhEGy006Sodd+Tr2Xv6C9dE9N0O3f30DhG8Kib/rm0/VGxd6+jIMAL5wN6siK193+uaED8GZModvIlC29zIIHhf4KRjJE8itjlfsKX5wiYHEiBZAEkwBIQAOeAvEohlLikgJ0CElCAEEAG5IDiQApIQF1ly7LsnC2FrYAsBRSQpcB1UC4vXUjYCsihO4fuPAckB/4SL96Ih50CElCjbg6kgBzFjw2hA4EOBDoQXkzgB4M1e9Kmodpu/czurdW/T2sWkf1YtGotodbPeRrhyY1znr+fq41HK3btFE+juNObR6eto74Vv2zRVVz50pWFKzdj6HFrsI1kT8x/s5Ah7lvrI+l1Ql24nf9bTYrw2fx7z1SEngu/Wx1j3raE437Y9pnc931pnWmbD9a2loazqdP5msyOpf6Q2SlZeKkxBBOHwys)
[Answer]
# [T-SQL](https://www.microsoft.com/sql-server), 322 bytes
```
WITH m AS(SELECT LEFT(value,1)i,RIGHT(value,1)o FROM STRING_SPLIT('01,02,10,12,14,20,21,23,25,32,36,41,45,47,52,54,56,58,63,65,69,74,78,85,87,89,96,98',','))SELECT o+RIGHT(s,2)FROM t,m WHERE i=LEFT(s,1)UNION SELECT LEFT(s,1)+o+RIGHT(s,1)FROM t,m WHERE i=SUBSTRING(s,2,1)UNION SELECT LEFT(s,2)+o FROM t,m WHERE i=RIGHT(s,1)
```
The input is taken from the column `s` of a single-row table named `t`:
```
DROP TABLE IF EXISTS t
CREATE TABLE t (s CHAR(3))
INSERT INTO t VALUES('008')
```
Ungolfed:
```
WITH m AS (
    SELECT LEFT(value,1) i, RIGHT(value,1) o
    FROM STRING_SPLIT('01,02,10,12,14,20,21,23,25,32,36,41,45,47,52,54,56,58,63,65,69,74,78,85,87,89,96,98',',')
)
SELECT o+RIGHT(s,2) FROM t,m WHERE i=LEFT(s,1)
UNION
SELECT LEFT(s,1)+o+RIGHT(s,1) FROM t,m WHERE i=SUBSTRING(s,2,1)
UNION
SELECT LEFT(s,2)+o FROM t,m WHERE i=RIGHT(s,1)
```
[SQLFiddle](http://sqlfiddle.com/#!18/bfeb4/1)
]