Raumnummernfinder

24

Raumnummernfinder

Ich habe in meinem Job eine interessante Problemlösungstechnik gefunden, als ich von einem Kollegen die falsche Zimmernummer für ein Meeting erhalten habe. Von Zeit zu Zeit schickt mir ein Mitglied meines Teams auf dem Weg zu einer Besprechung die falsche Zimmernummer, normalerweise, weil es an seinem Schreibtisch eilig ist und der dicke Finger den falschen Schlüssel hat.

Interessanterweise kann ich bei der Ankunft im falschen Zimmer normalerweise erraten, welches Zimmer sie wirklich meinten, indem ich mir ein numerisches Tastenfeld vorstelle :

und indem sie eine benachbarte Zahl erraten, wollten sie drücken.

Herausforderung

Ihre Herausforderung besteht darin, eine Funktion zu schreiben, die eine Büronummer (000-999) annimmt und die möglichen Tippfehlerlösungen ausgibt, vorausgesetzt, Ihr Kollege gibt nur eine Ziffer falsch ein.

Die folgende Tabelle zeigt, welche Nummern auf einem Ziffernblock nebeneinander liegen:

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

Eingang

Eine 3 - stellige Nummer: 000-999. Nehmen Sie die Eingabe von genau 3 Stellen an. Wenn die Zahl kleiner als 100 oder kleiner als 10 ist, erhalten Sie die führenden Nullen. (dh 004 & 028).

Ausgabe

Eine Liste der möglichen Zimmer. Dies kann in beliebiger Form erfolgen, sofern ein Trennzeichen zwischen den Zimmernummern vorhanden ist. (dh Leerzeichen, Komma, neue Zeile usw.) Wenn die Zahl kleiner als 100 oder kleiner als 10 ist, können Sie die führenden Nullen als Ausgabe haben oder nicht, das liegt an Ihnen. (dh 004 kann sein 004 04 4, und 028 kann sein 028 28)

Testfälle (führende Nullen sind 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

Das ist , also gewinnt der kürzeste Code in Bytes für jede Sprache.

Entwicklungsentwickler
quelle
1
Können wir Eingaben als dreistellige Liste (0-9) annehmen?
HyperNeutrino
9
... und deshalb sollten Besprechungsräume Namen haben.
Jonathan Allan
2
@JonathanAllan Für Neulinge ist es viel schwieriger, "Dolphin Room" zu finden als "Room 218" (vorausgesetzt, die Zimmernummern werden in der richtigen Reihenfolge vergeben). Ein Kompromiss wäre die alphabetische Reihenfolge der Namen, aber dann haben Sie nur 26.
Andrew sagt Reinstate Monica
1
@ KellyLowder sollte so gewesen sein 933, ich habe es behoben.
Jonathan Allan
4
Im Zusammenhang damit habe ich einmal in der IT gearbeitet, wo es einen Professor gab, der mehrere Wochen lang Probleme mit der Raumtechnik hatte. Er befand sich in Bradley 210 (ich wusste, Bradley war der Name des Gebäudes. Das Gebäude nebenan - Matheson - war über eine Himmelsbrücke im 3. Stock verbunden. Bradley war 5 Stockwerke groß, Matheson 4). Er konnte mir nie sagen, in welchem ​​Raum er sich richtig befand. Einmal sagte er mir, er sei in "Matheson 605", was offenbar nicht existiere, und habe keine der Ziffern richtig verstanden.
Draco18s

Antworten:

13

Wolfram Language (Mathematica) , 112 106 Bytes

Wenn GridGraphwir erkennen, dass ein Ziffernblock im Grunde ein 3x3-Ziffernblock mit Kanten für 0 ist, erhalten wir die benachbarten Ziffern für jede eingegebene Ziffer mit AdjacencyList.

Dies ist unten zu sehen:

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

Bildbeschreibung hier eingeben

Dann nutze ich Tuples, um alle möglichen Fehler herauszufinden und diejenigen mit genau einem Fehler mit Selectund auszuwählen EditDistance. Dies funktioniert übrigens bei längeren Zimmernummern, und Sie können den EditDistanceParameter auch erhöhen , um mehr als einen Fehler zuzulassen. Könnte dies ein wenig weiter Golf spielen können, wollte aber meine Herangehensweise zeigen.

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

Etwas mehr Golf-Version auf Länge 3 Zimmernummern (106 Bytes) fest codiert. Dies wird als Rang 3-Liste ausgegeben, die jeder Ziffer entspricht:

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

Probieren Sie es online!

Kelly Lowder
quelle
Man könnte auch andere Abstandsfunktionen verwenden, die DamerauLevenshteinDistancestattdessen EditDistanceauch Umsetzungsfehler enthalten würden.
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])`]

Probieren Sie es online!

Die 1 st und 5 th Zeichen können hier nicht angezeigt werden (Browser abhängig), aber die vollständige Zeichenfolge entspricht[21, 204, 1035, 62, 157, 2468, 359, 48, 579, 68]

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

Probieren Sie es online!


Mein zweiter Versuch bei CodeGolf! Ziemlich lang, 190 Bytes, aber das Beste, was ich mit R. schaffen konnte. Neugierig, ob andere Feedback haben oder es besser machen können!

Florian
quelle
1
eine ganze Reihe von Kleinigkeiten: Sie haben einen zusätzlichen Platz in der zweiten Zeile; Wenn Sie die Priorität von :over missbrauchen, */+-können Sie ein paar Bytes in der ersten Zeile einsparen, es entfernen do.call, aals matrixTransponieren behandeln und rund 39 Bytes einsparen: Probieren Sie es online aus!
Giuseppe
Das kannst du gut! Danke für die Rückmeldung.
Florian
2

JavaScript (Firefox 30-57), 115 bis 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)]:[]

Bearbeiten: 6 Bytes dank @ edc65 gespeichert (obwohl Vorschläge 0jetzt nach anderen Vorschlägen erscheinen). 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>

Neil
quelle
Ich sehe das [für (...)] in vielen Code-Golfspielen, aber ich verstehe es nicht ganz und kann es anscheinend in keiner Dokumentation finden. Könntest du es erklären oder einen Link zu einer Erklärung posten?
Anton Ballmaier
save 6 bytes[...[12,240,1350,26,157,2468,359,48,579,78][c]+'']
edc65
1
@AntonBallmaier [for(...)]war einer von mehreren Syntaxvorschlägen für das Array-Verständnis, die es nie in ECMAscript geschafft haben. Sie haben die Möglichkeit, einen Iterator zu durchlaufen und die Ergebnisse genau zu filtern und / oder zuzuordnen. (Ich fand es besonders nützlich, wenn ich eine doppelte Iteration durchführte.)
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);}}}

Ich weiß, es ist lang im Vergleich zu den anderen Antworten. Meine Entschuldigung: Es ist in Java.
Oracle sollte toCharArrayin so etwas wie umbenennen getCrs.

Credits

-28 Zeichen von Kevin Cruijssen

Reinis Mazeiks
quelle
1
Einige Kleinigkeiten zum Golfen. (String b)->kann gerecht sein b->, und Sie können das nachgestellte entfernen ;. Was das Golfen angeht: Du verwendest es nur aeinmal, also kannst du es direkt entfernen String[]a=...;und verwenden "12,024,0135,26,157,2468,359,48,579,68".split(",")[...]. Auch Byte.parseBytekann new Byte. Insgesamt: 177 Bytes .
Kevin Cruijssen
1
@ KevinCruijssen danke, das sind einige Tricks, die ich lernen muss :)
Reinis Mazeiks
1
Tipps zum Golfen in Java und Tipps zum Golfen in <allen Sprachen> könnten interessant sein, falls Sie dies noch nicht getan haben. :)
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}}

Probieren Sie es online!

Alternativ 94 Zeichen, aber 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}}

Probieren Sie es online!

Asone Tuhid
quelle
2

C (gcc) , 136 oder 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);}

Probieren Sie es online!

Unicode 114 108 Bytes (TiO scheint dafür seltsam zu zählen)

Vielen Dank an @ceilingcat für diese 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);}

Probieren Sie es online!

Gastropner
quelle
@ceilingcat Hm. TiO sagt 108 Bytes.
Gastropner
Ich denke nicht, dass TIO UTF-8-Bytes in C korrekt zählt. Versuchen Sie, die Sprache in bash oder etwas anderes zu ändern, und beobachten Sie, wie sich die Bytes ändern.
Ceilingcat
@ceilingcat Ja, war auch vor Ort wackelig. Gespeicherte Datei ist 114, wahr genug.
Gastropner
111 Bytes
Ceilingcat
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

Probieren Sie es online!

35 Bytes durch Ausleihen einer Idee aus der Ruby-Antwort von @ AsoneTuhid gespart.

Xcali
quelle
1

Python 2 , 103 Bytes

danke an @Lynn für -4 bytes.

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

Probieren Sie es online!

ovs
quelle
Speichern Sie 4 Bytes mit: in`0x134cd9a07d1e58feab643f7db24102`[int(v)::10](Ich habe es auch versucht, int('…',36)aber es ist ein Byte länger.)
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]

Probieren Sie es online!

  • Nimmt einen Vektor von Ziffern und gibt eine Liste im gleichen Format zurück.
  • 0x502A044228550A21102B05406ist ein, UInt128bei dem das 1+10jth-Bit gesetzt ist, wenn f ineben stehtj auf dem Nummernblock .
  • big(1)ist ein BigInt. Es wird verwendet, um einen Überlauf zu verhindern und verwendet weniger Zeichen als Int128(1)oder UInt128(1).
LukeS
quelle
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)

Erläuterung

Die Eingabe ist eine einzelne Textzeile in einer Tabelle tmit einer Spalte s. Mein Verständnis ist, dass dies nach dieser Meta-Antwort eine akzeptable Form der Eingabe ist. Die Eingabe kann wie folgt erstellt werden.

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

Kommentierte Lösung

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)
Captain Man
quelle
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}

Verschönert

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

Prüfung

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
quelle
0

Gelee , 35 Bytes

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

Probieren Sie es online!

-1 Danke an Jonathan Allan .

Erklärung wird aktualisiert ...

Erik der Outgolfer
quelle
3
Ich habe ehrlich gesagt keine Ahnung, wie das analysiert wird, geschweige denn, wie es funktioniert. Eine Erklärung wäre sehr dankbar.
Caird Coinheringaahing
@cairdcoinheringaahing Entschuldigung, keine Zeit jetzt
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)

Die Eingabe stammt aus der Spalte seiner einzeiligen Tabelle mit dem Namen 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
quelle