Localizzatore del numero di stanza


24

Localizzatore del numero di stanza

Mi sono imbattuto in un'interessante tecnica di problem solving nel mio lavoro quando mi è stato dato un numero di stanza errato da un collega per una riunione. Di tanto in tanto, mentre si recano a una riunione, un membro del mio team mi invia il numero della stanza sbagliato, in genere perché hanno fretta alla loro scrivania e il dito grasso la chiave sbagliata.

È interessante notare che, all'arrivo nella stanza sbagliata, in genere riesco a indovinare quale camera intendessero davvero immaginando un tastierino numerico :

e indovinando un numero adiacente intendevano premere.

Sfida

La tua sfida è scrivere una funzione che accetta un numero di ufficio dell'edificio (000-999) e produce le possibili soluzioni di errore di battitura, supponendo che il tuo collega digiti solo una cifra.

La tabella seguente mostra quali numeri sono adiacenti l'uno all'altro su un tastierino numerico:

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

Ingresso

Un numero di 3 cifre: 000-999. Si supponga di inserire esattamente 3 cifre. Se il numero è inferiore a 100 o inferiore a 10, ti verranno dati gli zeri iniziali. (ovvero 004 e 028).

Produzione

Un elenco di possibili stanze. Questo può essere in qualsiasi forma tu voglia, purché ci sia un delimitatore tra i numeri delle stanze. (ad es. spazio, virgola, nuova riga, ecc.) Se il numero è inferiore a 100 o inferiore a 10, è possibile o meno avere gli zeri iniziali come output, dipende da te. (ovvero 004 può essere 004 04 4e 028 può essere 028 28)

Casi di test (gli zeri iniziali sono facoltativi):

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

Questo è , quindi vince il codice più breve in byte per ogni lingua.


1
Possiamo prendere l'input come un elenco di tre cifre (0-9)?
HyperNeutrino,

9
... ed è per questo che le sale riunioni dovrebbero avere nomi.
Jonathan Allan,

2
@JonathanAllan È molto più difficile per le nuove persone trovare "Stanza dei delfini" rispetto a "Stanza 218" (supponendo che i numeri delle stanze siano assegnati in ordine). Un compromesso sarebbe in ordine alfabetico i nomi, ma poi hai solo 26.
Andrew dice Reinstate Monica

1
@KellyLowder avrebbe dovuto essere 933così l'ho risolto.
Jonathan Allan,

4
In relazione, una volta ho lavorato nell'IT dove c'era un professore che aveva avuto problemi con la tecnologia della stanza per diverse settimane consecutive. Era a Bradley 210 (che conoscevo, Bradley era il nome dell'edificio. L'edificio accanto - Matheson - era collegato tramite un ponte sopra il cielo al 3 ° piano. Bradley era alto 5 piani, Matheson 4). Non potrebbe mai dirmi in che stanza si trovava correttamente. Una volta mi ha detto che era in "Matheson 605" che non esisteva, e che non aveva le cifre giuste.
Draco18s

Risposte:


13

Wolfram Language (Mathematica) , 112 106 byte

Riconoscendo che un tastierino numerico è fondamentalmente un 3x3 GridGraphcon bordi aggiunti per 0, otteniamo le cifre adiacenti per ogni cifra di input con AdjacencyList.

Questo può essere visto sotto:

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

inserisci qui la descrizione dell'immagine

Quindi uso Tuplesper capire tutti i possibili errori e selezionarli con esattamente un errore con Selecte EditDistance. A proposito, questo funzionerà per numeri di stanza più lunghi e puoi anche aumentare il EditDistanceparametro per consentire più di un errore. Potrebbe essere in grado di giocare a golf un po 'più in là, ma volevo mostrare il mio approccio.

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

Versione leggermente più golfizzata codificata in lunghezza per 3 numeri di camere (106 byte). Verrà visualizzato un elenco di grado 3 corrispondente a ciascuna cifra:

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

Provalo online!


Si potrebbero anche usare altre funzioni di distanza come DamerauLevenshteinDistanceinvece EditDistanceche includerebbe anche errori di trasposizione.
Kelly Lowder,

9

Python 2 , 89 byte

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

Provalo online!

Il 1 ° e il 5 th caratteri potrebbero non essere visualizzati qui (browser dipendente), ma la stringa completa è equivalente a[21, 204, 1035, 62, 157, 2468, 359, 48, 579, 68]



3

R , 190 byte

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

Provalo online!


Il mio secondo tentativo di CodeGolf! Abbastanza lungo, 190 byte, ma il migliore che ho potuto gestire con R. Curioso di vedere se gli altri hanno feedback o possono fare di meglio!


1
un sacco di piccole cose: hai uno spazio extra nella seconda riga; abusare della precedenza di :over */+-può radere qualche byte nella prima riga, liberarsene do.call, trattarlo acome matrixe trasporlo salva tutti i 39 byte circa: Provalo online!
Giuseppe,

Sei bravo in questo! Grazie per il feedback.
Florian,

2

JavaScript (Firefox 30-57), 115 109 byte

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

Modifica: salvato 6 byte grazie a @ edc65 (anche se i suggerimenti 0ora vengono visualizzati dopo altri suggerimenti). Versione ES6, 118 112 byte:

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>


Lo vedo [per (...)] in molti codici golf, ma non lo capisco completamente e non riesco a trovarlo in nessuna documentazione. Potresti spiegarlo o pubblicare un link a una spiegazione?
Anton Ballmaier

salva 6 byte [...[12,240,1350,26,157,2468,359,48,579,78][c]+'']
edc65,

1
@AntonBallmaier è [for(...)]stata una delle numerose proposte di sintassi per la comprensione di array che non è mai diventata ECMAscript. Ti ha permesso di scorrere su un iteratore e di filtrare e / o mappare in modo succinto i risultati. (L'ho trovato particolarmente utile quando ho fatto la doppia iterazione.)
Neil

2

Java, 205 177 byte

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

So che è lungo rispetto alle altre risposte. La mia scusa: è in Java.
Oracle dovrebbe rinominare toCharArrayqualcosa di simile getCrs.

Crediti

-28 caratteri di Kevin Cruijssen


1
Alcune piccole cose da golf. (String b)->può essere giusto b->e puoi rimuovere il finale ;. Per quanto riguarda le cose reali al golf: le usi auna sola volta, quindi puoi rimuoverle String[]a=...;e usarle "12,024,0135,26,157,2468,359,48,579,68".split(",")[...]direttamente. Inoltre, Byte.parseBytepuò essere new Byte. In totale: 177 byte .
Kevin Cruijssen il

1
@KevinCruijssen grazie, questi sono alcuni trucchi che dovrò imparare :)
Reinis Mazeiks,

1
Suggerimenti per giocare a golf in Java e Suggerimenti per giocare a golf in <tutte le lingue> potrebbero essere interessanti da leggere nel caso in cui non l'avessi ancora fatto. :)
Kevin Cruijssen il

2

Ruby 97 byte

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

Provalo online!

In alternativa, 94 caratteri ma 100 byte

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

Provalo online!


2

C (gcc) , 136 o 114 byte

Versione ASCII 136 byte

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

Provalo online!

Unicode 114 108 byte (TiO sembra contare stranamente per questo)

Grazie a @ceilingcat per questa versione.

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

Provalo online!


@ceilingcat Hm. TiO dice 108 byte.
Gastropner

Non penso che TIO conteggi correttamente i byte UTF-8 in C. Prova a cambiare la lingua in bash o qualcos'altro e guarda cambiare il conteggio dei byte.
ceilingcat

@ceilingcat Sì, anche a livello locale era traballante. Il file salvato è 114, abbastanza vero.
Gastropner


1

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

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

Provalo online!

Hai salvato 35 byte prendendo in prestito un'idea dalla risposta rubino di @ AsoneTuhid.


1

Python 2 , 103 byte

grazie a @Lynn per -4 byte.

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

Provalo online!


Salva 4 byte con: in`0x134cd9a07d1e58feab643f7db24102`[int(v)::10](Ho provato int('…',36)anche io ma è un byte più lungo.)
Lynn

1

Julia 0.6 , 93 byte

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

Provalo online!

  • Prende un vettore di cifre e restituisce un elenco nello stesso formato.
  • 0x502A044228550A21102B05406è un UInt128in cui 1+10jè impostato il th bit sef iè vicino al jtastierino numerico.
  • big(1)è un BigInt. Viene utilizzato per prevenire il trabocco e utilizza meno caratteri di Int128(1)o UInt128(1).

1

SQL (SQLite), 533 byte

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)

Spiegazione

L'input è una singola riga di testo sulla tabella tcon colonna s. La mia comprensione è che secondo questa meta risposta questa è una forma accettabile di input. L'input può essere creato come di seguito.

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

Soluzione annotata

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 byte

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

Abbellire

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



0

T-SQL , 322 byte

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)

L'input è tratto dalla colonna sdi una tabella a riga singola denominata 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

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.