房间编号定位器


24

房间编号定位器

同事开会时给我错误的房间号时,我遇到了一种有趣的问题解决技术。时不时地,在开会的过程中,我们团队中的一个成员会给我发送错误的房间号,通常是因为他们急于在办公桌前用笨拙的手指输入错误的密钥。

有趣的是,到达错误的房间后,我通常可以通过想象一个数字键盘来猜测它们真正意味着的房间:

并猜测他们要按的相邻数字。

挑战

假设您的同事只输错了一位数字,那么您面临的挑战就是编写一个函数,该函数需要一个办公楼号码(000-999)并输出可能的错字解决方案

下表显示了数字键盘上哪些数字彼此相邻:

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

输入项

3位数字:000-999。假设正好输入3位数字。如果数字小于100或小于10,则会为您提供前导零。(即004和028)。

输出量

可能的房间列表。只要房间号之间有分隔符,它就可以采用您想要的任何形式。(即空格,逗号,换行符等。)如果数字小于100或小于10,则可以或不可以将前导零作为输出,这取决于您。(即004可以是004 04 4028可以028 28

测试用例(前导零是可选的):

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

这是,因此每种语言的最短代码(以字节为单位)获胜。


1
我们可以将输入作为三位数(0-9)的列表吗?
HyperNeutrino

9
...这就是为什么会议室要有名称的原因。
乔纳森·艾伦

2
@JonathanAllan对于新人们来说,找到“海豚房”比“ 218房间”要难得多(假设房间号是按顺序分配的)。一个折衷会按字母顺序排序的名字,但你只有26
安德鲁恢复莫妮卡说,

1
@KellyLowder应该已经存在,933所以我已将其修复。
乔纳森·艾伦

4
与此相关,我曾经在IT部门工作,当时有一位教授在运行会议室技术几周后遇到了麻烦。他在Bradley 210(我知道,Bradley是建筑物的名称。隔壁的建筑物-Matheson是通过3层的天桥连接的。Bradley高5层,Matheson 4)。他永远无法告诉我他正确地在哪个房间里。有一次他告诉我他在“ Matheson 605”中,这显然是不存在的,而且没有正确的数字。
Draco18s

Answers:


13

Wolfram语言(Mathematica)112106字节

认识到数字小键盘基本上是3x3 GridGraph,其边缘增加了0,我们使用来获得每个输入数字的相邻数字AdjacencyList

可以在下面看到:

EdgeAdd[GridGraph[{3,3},VertexLabels->"Name",GraphLayout->"SpringEmbedding"],{0<->1,0<->2}] 产量:

在此处输入图片说明

然后我用Tuples找出所有可能的错误,并挑选出那些只有一个误差SelectEditDistance。顺便说一下,这将适用于更长的房间号,您还可以增加EditDistance参数以允许多个错误。可能可以进一步打高尔夫球,但想展示我的方法。

h@u_:=Select[Tuples[AdjacencyList[EdgeAdd[GridGraph[{3,3}],{0<->1,0<->2}],#]~Join~{#}&/@u],#~EditDistance~u==1&]

略微打高尔夫球的版本硬编码为3个房间号(106字节)。这将输出为与每个数字相对应的3级列表:

Thread/@ReplacePart[#~Table~3,{i_,i_}:>(AdjacencyList[GridGraph@{3,3}~EdgeAdd~{0<->1,0<->2},#]&/@#)[[i]]]&

在线尝试!


一个人也可以使用其他距离函数,例如DamerauLevenshteinDistance代替EditDistance它也将包括转置误差。
凯利·洛德

9

Python 2,89个字节

lambda r:[r[:i]+[c]+r[i+1:]for i,n in enumerate(r)for c in`ord(u'ÌЋ>তŧ0ɃD'[n])`]

在线尝试!

1 和5 字符可能不被显示在这里(浏览器相关的),但完整的字符串相当于[21, 204, 1035, 62, 157, 2468, 359, 48, 579, 68]



3

R,190字节

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

在线尝试!


我第二次尝试CodeGolf!相当长,为190个字节,但是我可以用R来管理。最好是看看其他人是否有反馈或可以做得更好!


1
一堆小东西:第二行中有多余的空间;滥用:over 的优先级*/+-可以在第一行中删除几个字节,将其删除do.calla当作a matrix并进行转置可以节省大约39个字节:在线尝试!
朱塞佩

你擅长这个!感谢您的反馈。
Florian

2

的JavaScript(火狐30-57),115个 109字节

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

编辑:感谢@ edc65保存了6个字节(尽管建议0s现在出现在其他建议之后)。ES6版本,118个 112字节:

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>


我在很多代码中都看到了这个[for(...)],但是我并不完全理解,在任何文档中似乎都找不到。您能解释一下还是发布说明链接?
安东·鲍尔迈尔

保存6个字节[...[12,240,1350,26,157,2468,359,48,579,78][c]+'']
edc65 '18

1
@AntonBallmaier [for(...)]是从未纳入ECMAscript的几种数组理解语法建议之一。它允许您循环遍历迭代器,并简洁地过滤和/或映射结果。(我发现进行双重迭代时特别有用。)
Neil

2

Java中,205个 177字节

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

与其他答案相比,我知道这已经很久了。我的借口是在Java中。
Oracle应该重命名toCharArraygetCrs

学分

-28个字符,凯文·克鲁伊森Kevin Cruijssen)


1
打高尔夫球的一些小东西。(String b)->可以是公正的b->,也可以删除尾随的;。至于打高尔夫球的实际情况:您只使用a一次,因此可以直接删除String[]a=...;和使用"12,024,0135,26,157,2468,359,48,579,68".split(",")[...]。也Byte.parseByte可以new Byte。总共:177个字节
凯文·克鲁伊森

1
@KevinCruijssen谢谢,这些是我必须学习的技巧:)
Reinis Mazeiks

1
如果您还没有阅读过Java高尔夫技巧<all language>高尔夫技巧,可能会很有趣。:)
Kevin Cruijssen

2

Ruby 97字节

->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}}

在线尝试!

或者,94个字符但100个字节

->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}}

在线尝试!


2

C(gcc),136或114字节

ASCII版本136字节

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

在线尝试!

Unicode 114108字节(TiO对此似乎很奇怪)

感谢@ceilingcat提供此版本。

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

在线尝试!


@ceilingcat嗯。TiO表示108个字节。
gastropner

我认为TIO在C中无法正确计数UTF-8字节。尝试将语言更改为bash或其他内容,然后观察字节数的变化。
ceilingcat

@ceilingcat是的,在本地也很古怪。保存的文件是114,足够真实。
gastropner


1

Perl 5中120 85 + 2(-F)= 87个字节

map{@,=@F;$,[$i]=$_,say@,for(12,240,1350,26,157,2468,359,48,579,68)[$_]=~/./g;$i++}@F

在线尝试!

通过从@AsoneTuhid的ruby答案中借用一个想法节省了35个字节。


1

Python 2,103个字节

感谢@Lynn -4个字节。

lambda n:{n[:i]+r+n[i+1:]for i,v in enumerate(n)for r in`0x134cd9a07d1e58feab643f7db24102`[int(v)::10]}

在线尝试!


使用以下命令保存4个字节:(in`0x134cd9a07d1e58feab643f7db24102`[int(v)::10]我也尝试int('…',36)过,但是再长一个字节。)
Lynn

1

朱莉娅0.6,93字节

~r=[(R=copy(r);R[j]=i;R)for i=0:9,j=1:3 if(big(1)<<(i+10r[j]))&0x502A044228550A21102B05406>0]

在线尝试!

  • 获取数字向量,并以相同格式返回列表。
  • 0x502A044228550A21102B05406是numpad 旁边UInt1281+10j第一个被设置的位。ij
  • big(1)是一个BigInt。它用于防止溢出,并且使用的字符少于Int128(1)UInt128(1)

1

SQL(SQLite),533字节

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)

不打高尔夫球

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)

说明

输入是表格上t带有列的单个文本行s。我的理解是根据这个元答案这是可接受的输入形式。可以如下创建输入。

drop table if exists t;
create table t (s text);
insert into t values('555'); -- Your input here

带注释的解决方案

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)

1

Kotlin,117字节

mapIndexed{i,c->"12,024,0135,26,157,2468,359,48,579,68".split(",")[c-'0'].map{replaceRange(i,i+1,it+"")}}.flatMap{it}

美化

mapIndexed { i, c ->
    "12,024,0135,26,157,2468,359,48,579,68"
        .split(",")[c - '0']
        .map { replaceRange(i, i + 1, it + "") }
}.flatMap { it }

测试

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")
        }
    }
}

蒂奥

在线试用



0

T-SQL,322字节

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)

输入来自s名为的单行表的列t

DROP TABLE IF EXISTS t
CREATE TABLE t (s CHAR(3))
INSERT INTO t VALUES('008')

取消高尔夫:

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.