Localizador de número de quarto

24

Localizador de número de quarto

Encontrei uma técnica interessante para resolver problemas no meu trabalho quando recebi o número errado da sala de um colega para uma reunião. De vez em quando, a caminho de uma reunião, um membro da minha equipe me envia o número da sala errado, geralmente porque está com pressa na mesa e com o dedo gordo na tecla errada.

Curiosamente, ao chegar na sala errada, normalmente posso adivinhar qual sala eles realmente queriam imaginar imaginando um teclado numérico :

e adivinhando um número adjacente, eles pretendiam pressionar.

Desafio

Seu desafio é escrever uma função que use um número de escritório (000-999) e produza as possíveis soluções de erros de digitação, assumindo que seu colega digita incorretamente apenas um dígito.

A tabela a seguir mostra quais números são adjacentes um ao outro em um teclado numérico:

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

Entrada

Um número de 3 dígitos: 000-999. Suponha a entrada de exatamente 3 dígitos. Se o número for menor que 100 ou menor que 10, você receberá os zeros à esquerda. (ou seja, 004 e 028).

Saída

Uma lista de quartos possíveis. Pode ser da forma que você quiser, desde que exista um delimitador entre os números dos quartos. (ou seja, espaço, vírgula, nova linha, etc.) Se o número for menor que 100 ou menor que 10, você poderá ou não ter os zeros à esquerda como saída, isso depende de você. (ou seja, 004 pode ser 004 04 4e 028 pode ser 028 28)

Casos de teste (zeros à esquerda são opcionais):

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

Isso é , portanto o código mais curto em bytes para cada idioma vence.

DevelopingDeveloper
fonte
1
Podemos considerar a entrada como uma lista de três dígitos (0 a 9)?
HyperNeutrino
9
... e é por isso que as salas de reunião devem ter nomes.
Jonathan Allan
2
@ JonathanAllan É muito mais difícil para as novas pessoas encontrarem a "Sala dos Golfinhos" do que a "Sala 218" (supondo que os números dos quartos sejam atribuídos em ordem). Um compromisso seria ordenar alfabeticamente os nomes, mas você só terá 26.
Andrew diz Reinstate Monica
1
@KellyLowder deveria ter sido, 933então eu o consertei .
Jonathan Allan
4
Relacionado, uma vez trabalhei em TI, onde havia um professor que teve problemas com a tecnologia da sala várias semanas seguidas. Ele estava no Bradley 210 (que eu sabia, Bradley sendo o nome do prédio. O prédio ao lado - Matheson - era conectado por uma ponte no céu no terceiro andar. Bradley tinha 5 andares, Matheson 4). Ele nunca poderia me dizer em que quarto estava corretamente. Uma vez, ele me disse que estava no "Matheson 605", que evidentemente não existia e não acertou nenhum dos dígitos.
Draco18s

Respostas:

13

Wolfram Language (Mathematica) , 112 106 bytes

Reconhecendo que um teclado numérico é basicamente um 3x3 GridGraphcom arestas adicionadas para 0, obtemos os dígitos adjacentes para cada dígito de entrada com AdjacencyList.

Isso pode ser visto abaixo:

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

insira a descrição da imagem aqui

Então eu costumo Tuplesdescobrir todos os erros possíveis e escolher aqueles com exatamente um erro com Selecte EditDistance. A propósito, isso funcionará para números de sala mais longos e você também pode aumentar o EditDistanceparâmetro para permitir mais de um erro. Pode ser capaz de jogar isso um pouco mais longe, mas queria mostrar minha abordagem.

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

Versão ligeiramente mais golfe codificada para o comprimento de 3 números de quarto (106 bytes). Isso será exibido como uma lista de classificação 3 correspondente a cada dígito:

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

Experimente online!

Kelly Lowder
fonte
Pode-se também usar outras funções de distância, como em DamerauLevenshteinDistancevez das EditDistancequais também incluiriam erros de transposição.
21418 Kelly Lowder
9

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

Experimente online!

O 1 st e 5 th caracteres podem não ser exibidos aqui (navegador dependente), mas a cadeia completa é equivalente a[21, 204, 1035, 62, 157, 2468, 359, 48, 579, 68]

Cajado
fonte
3

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

Experimente online!


Minha segunda tentativa no CodeGolf! Bastante longo, 190 bytes, mas o melhor que pude gerenciar com R. Curioso para ver se os outros têm feedback ou podem fazer melhor!

Florian
fonte
1
um monte de pequenas coisas: você tem um espaço extra na segunda linha; abusar da precedência do :over */+-pode eliminar alguns bytes na primeira linha, livrar-se do.call, tratar acomo matrixe transpor ele economiza cerca de 39 bytes: Experimente online!
Giuseppe
Você é bom nisso! Obrigado pelo feedback.
Florian
2

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

Editar: salvou 6 bytes graças a @ edc65 (embora os 0s sugeridos agora apareçam após outras sugestões). Versão ES6, 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>

Neil
fonte
Eu vejo isso [em (...)] em muitos códigos de golfe, mas não o entendo completamente e não consigo encontrá-lo em nenhuma documentação. Você poderia explicar ou postar um link para uma explicação?
Anton Ballmaier
salve 6 bytes[...[12,240,1350,26,157,2468,359,48,579,78][c]+'']
edc65
1
O @AntonBallmaier [for(...)]foi uma das várias propostas de sintaxe de compreensão de array que nunca chegaram ao ECMAscript. Ele permitiu que você circulasse sobre um iterador e filtrasse e / ou mapeasse sucintamente os resultados. (Eu achei particularmente útil quando se faz duplo iteração.)
Neil
2

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

Eu sei que é longo comparado com as outras respostas. Minha desculpa: é em Java.
Oracle deve renomear toCharArraypara algo como getCrs.

Créditos

-28 caracteres de Kevin Cruijssen

Reinis Mazeiks
fonte
1
Algumas pequenas coisas para jogar golfe. (String b)->pode ser justo b->e você pode remover o final ;. Quanto às coisas reais do golfe: você usa apenas auma vez, para poder remover String[]a=...;e usar "12,024,0135,26,157,2468,359,48,579,68".split(",")[...]diretamente. Além disso, Byte.parseBytepode ser new Byte. No total: 177 bytes .
Kevin Cruijssen 22/01
1
@KevinCruijssen graças, esses são alguns truques que eu vou ter que aprender :)
Reinis MAZEIKS
1
Dicas para jogar golfe em Java e Dicas para jogar golfe em <todos os idiomas> podem ser interessantes para ler, caso você ainda não o tenha feito. :)
Kevin Cruijssen
2

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

Experimente online!

Como alternativa, 94 caracteres, mas 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}}

Experimente online!

Asone Tuhid
fonte
2

C (gcc) , 136 ou 114 bytes

Versão ASCII 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);}

Experimente online!

Unicode 114 108 bytes (o TiO parece contar estranhamente para isso)

Obrigado a @ceilingcat para esta versão.

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

Experimente online!

gastropner
fonte
@ceilingcat Hm. TiO diz 108 bytes.
gastropner 28/11
Eu não acho que o TIO conta UTF-8 bytes corretamente em C. Tente alterar o idioma para bash ou algo mais e observe a alteração na contagem de bytes.
roofcat 28/11
@ceilingcat Sim, também era instável localmente. O arquivo salvo é 114, é verdade.
gastropner 28/11
111 bytes
ceilingcat 28/11
1

Perl 5 , 120 85 + 2 ( -F) = 87 bytes

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

Experimente online!

Economizou 35 bytes emprestando uma idéia da resposta ruby ​​de @ AsoneTuhid.

Xcali
fonte
1

Python 2 , 103 bytes

graças a @Lynn por -4 bytes.

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

Experimente online!

ovs
fonte
Guardar 4 bytes com: in`0x134cd9a07d1e58feab643f7db24102`[int(v)::10](Eu tentei int('…',36)muito, mas é um byte mais tempo.)
Lynn
1

Julia 0.6 , 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]

Experimente online!

  • Pega um vetor de dígitos e retorna uma lista no mesmo formato.
  • 0x502A044228550A21102B05406é UInt128aquele em que o 1+10jth bit é definido se iestiver ao lado jdo teclado numérico.
  • big(1)é um BigInt. É usado para impedir o estouro e usa menos caracteres que Int128(1)ou UInt128(1).
LukeS
fonte
1

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)

Explicação

A entrada é uma única linha de texto na tabela tcom coluna s. Meu entendimento é que, de acordo com essa meta resposta, essa é uma forma aceitável de entrada. A entrada pode ser criada como abaixo.

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

Solução anotada

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)
Capitão Homem
fonte
1

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

Embelezado

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

Teste

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

jrtapsell
fonte
0

Geléia , 35 bytes

ḷþị“-ⱮⱮVḟ|żṣ~ẋ³ɱgẆ’ḃ⁽¦ḳ¤$ṛ¦DŒp$¥"JẎ

Experimente online!

-1 graças a Jonathan Allan .

Explicação sendo atualizada ...

Erik, o Outgolfer
fonte
3
Sinceramente, não tenho idéia de como isso é analisado, muito menos de como funciona. Uma explicação seria muito apreciada.
você precisa saber é o seguinte
@cairdcoinheringaahing desculpe, não há tempo agora
Erik the Outgolfer
-1 byte: Wẋ3->ḷþ
Jonathan Allan
0

T-SQL , 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)

A entrada é obtida da coluna sde uma tabela de linha única denominada 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

Razvan Socol
fonte