Pencari Nomor Kamar

24

Pencari Nomor Kamar

Saya telah menemukan teknik pemecahan masalah yang menarik di pekerjaan saya ketika diberi nomor kamar yang salah dari seorang kolega untuk rapat. Sesekali, saat dalam perjalanan ke sebuah pertemuan, seorang anggota di tim saya akan mengirim saya nomor kamar yang salah, biasanya karena mereka terburu-buru di meja mereka dan jari yang salah kunci yang salah.

Menariknya, setibanya di ruangan yang salah, saya biasanya bisa menebak kamar mana yang mereka maksud dengan membayangkan Keypad Numerik :

dan dengan menebak nomor yang berdekatan, mereka bermaksud menekan.

Tantangan

Tantangan Anda adalah menulis fungsi yang menggunakan nomor gedung kantor (000-999) dan menampilkan kemungkinan solusi salah ketik, dengan asumsi kolega Anda hanya salah ketik satu digit.

Tabel berikut menunjukkan nomor mana yang berdekatan satu sama lain pada Keypad Numerik:

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

Memasukkan

3 digit angka: 000-999 . Asumsikan input tepat 3 digit. Jika jumlahnya kurang dari 100 atau kurang dari 10, Anda akan diberi angka nol di depan. (yaitu 004 & 028).

Keluaran

Daftar kamar yang memungkinkan. Ini bisa dalam bentuk apa pun yang Anda inginkan, asalkan ada pembatas antara nomor kamar. (mis. spasi, koma, baris baru, dll.) Jika angkanya kurang dari 100 atau kurang dari 10, Anda dapat atau tidak dapat memiliki nol terkemuka sebagai output, itu terserah Anda. (Yaitu 004 bisa 004 04 4, dan 028 bisa 028 28)

Kasus Uji (angka nol di depan adalah opsional):

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

Ini adalah , jadi kode terpendek dalam byte untuk setiap bahasa akan menang.

Pengembang Berkembang
sumber
1
Bisakah kita mengambil input sebagai daftar tiga digit (0-9)?
HyperNeutrino
9
... dan inilah mengapa ruang pertemuan harus memiliki nama.
Jonathan Allan
2
@ JonathanAllan Jauh lebih sulit bagi orang baru untuk menemukan "Ruang Lumba-lumba" daripada "Ruang 218" (dengan asumsi bahwa nomor kamar ditetapkan secara berurutan). Sebuah kompromi akan secara alfabetis memesan nama-nama itu, tetapi kemudian Anda hanya memiliki 26.
Andrew mengatakan Reinstate Monica
1
@KellyLowder seharusnya 933jadi saya sudah memperbaikinya.
Jonathan Allan
4
Terkait, saya pernah bekerja di IT di mana ada seorang profesor yang mengalami masalah dengan teknologi kamar beberapa minggu berjalan. Dia berada di Bradley 210 (yang saya tahu, Bradley menjadi nama bangunan. Bangunan di sebelahnya - Matheson - terhubung melalui jembatan langit di lantai 3. Bradley setinggi 5 lantai, Matheson 4). Dia tidak pernah bisa memberi tahu saya kamar apa yang dia masuki dengan benar. Suatu kali dia mengatakan kepada saya dia berada di "Matheson 605" yang terang-terangan tidak ada, dan tidak ada satu pun digit yang benar.
Draco18s

Jawaban:

13

Bahasa Wolfram (Mathematica) , 112 106 byte

Menyadari bahwa keypad numerik pada dasarnya adalah 3x3 GridGraphdengan tepi ditambahkan untuk 0, kita mendapatkan angka yang berdekatan untuk setiap digit input AdjacencyList.

Ini bisa dilihat di bawah:

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

masukkan deskripsi gambar di sini

Lalu saya gunakan Tuplesuntuk mencari tahu semua kesalahan yang mungkin terjadi dan memilih mereka yang memiliki satu kesalahan dengan Selectdan EditDistance. Omong-omong, ini akan bekerja untuk nomor kamar yang lebih panjang dan Anda juga dapat meningkatkan EditDistanceparameter untuk memungkinkan lebih dari satu kesalahan. Mungkin bisa bermain golf ini sedikit lebih jauh tetapi ingin menunjukkan pendekatan saya.

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

Versi golf yang sedikit lebih keras, dikodekan dengan panjang 3 nomor kamar (106 Bytes). Ini akan ditampilkan sebagai daftar peringkat 3 yang sesuai dengan setiap digit:

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

Cobalah online!

Kelly Lowder
sumber
Satu juga dapat menggunakan fungsi jarak lain seperti DamerauLevenshteinDistancebukan EditDistanceyang juga akan mencakup kesalahan transposisi.
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])`]

Cobalah online!

1 st dan 5 th karakter mungkin tidak ditampilkan di sini (browser tergantung), tapi string lengkap setara dengan[21, 204, 1035, 62, 157, 2468, 359, 48, 579, 68]

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

Cobalah online!


Upaya kedua saya di CodeGolf! Cukup panjang, 190 byte, tetapi yang terbaik yang bisa saya kelola dengan R. Curious untuk melihat apakah orang lain memiliki umpan balik atau dapat melakukan lebih baik!

Florian
sumber
1
banyak hal kecil: Anda memiliki ruang ekstra di baris kedua; menyalahgunakan prioritas :lebih dari */+-dapat mengurangi beberapa byte di baris pertama, menyingkirkan do.call, memperlakukan asebagai matrixdan mentransposisi menyimpan sekitar 39 byte: Cobalah online!
Giuseppe
Anda pandai dalam hal ini! Terima kasih untuk umpan baliknya.
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)]:[]

Sunting: Disimpan 6 byte berkat @ edc65 (meskipun disarankan 0sekarang muncul setelah saran lainnya). Versi 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>

Neil
sumber
Saya melihat ini [untuk (...)] di banyak kode golf, tetapi saya tidak sepenuhnya memahaminya, dan sepertinya saya tidak dapat menemukannya di dokumentasi mana pun. Bisakah Anda menjelaskannya atau memposting tautan ke penjelasan?
Anton Ballmaier
simpan 6 byte[...[12,240,1350,26,157,2468,359,48,579,78][c]+'']
edc65
1
@AntonBallmaier [for(...)]adalah salah satu dari beberapa proposal sintaks pemahaman array yang tidak pernah berhasil masuk ke dalam ECMAscript. Ini memungkinkan Anda untuk mengulangi iterator dan menyaring dan / atau memetakan hasilnya secara ringkas. (Saya menemukannya sangat berguna ketika melakukan iterasi ganda.)
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);}}}

Saya tahu ini sudah lama dibandingkan dengan jawaban lainnya. Alasan saya: ada di Jawa.
Oracle harus mengubah nama toCharArraymenjadi sesuatu sepertigetCrs .

Kredit

-28 karakter oleh Kevin Cruijssen

Reinis Mazeiks
sumber
1
Beberapa hal kecil untuk golf. (String b)->bisa adil b->, dan Anda bisa menghapus trailing ;. Adapun hal-hal aktual untuk golf: Anda hanya menggunakan asekali, sehingga Anda dapat menghapus String[]a=...;dan menggunakannya "12,024,0135,26,157,2468,359,48,579,68".split(",")[...]secara langsung. Juga Byte.parseBytebisa new Byte. Total: 177 byte .
Kevin Cruijssen
1
@KevinCruijssen terima kasih, itu adalah beberapa trik yang harus saya pelajari :)
Reinis Mazeiks
1
Tips untuk bermain golf di Jawa dan Tips untuk bermain golf di <semua bahasa> mungkin menarik untuk dibaca jika Anda belum. :)
Kevin Cruijssen
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}}

Cobalah online!

Atau, 94 karakter tetapi 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}}

Cobalah online!

Asone Tuhid
sumber
2

C (gcc) , 136 atau 114 byte

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

Cobalah online!

Unicode 114 108 bytes (Sepertinya TiO menghitung aneh untuk ini)

Terima kasih kepada @ceilingcat untuk versi ini.

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

Cobalah online!

gastropner
sumber
@ceilingcat Hm. TiO mengatakan 108 byte.
gastropner
Saya tidak berpikir TIO menghitung UTF-8 byte dengan benar dalam C. Cobalah mengubah bahasa menjadi bash atau yang lainnya dan perhatikan perubahan jumlah byte.
ceilingcat
@ceilingcat Ya, juga tidak enak secara lokal. File yang disimpan adalah 114, cukup benar.
gastropner
111 byte
ceilingcat
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

Cobalah online!

Disimpan 35 byte dengan meminjam ide dari jawaban ruby ​​@ AsoneTuhid.

Xcali
sumber
1

Python 2 , 103 byte

terima kasih kepada @Lynn untuk -4 byte.

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

Cobalah online!

ovs
sumber
Simpan 4 byte dengan: in`0x134cd9a07d1e58feab643f7db24102`[int(v)::10](Saya mencoba int('…',36)juga tetapi satu byte lebih lama.)
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]

Cobalah online!

  • Mengambil vektor angka dan mengembalikan daftar dalam format yang sama.
  • 0x502A044228550A21102B05406adalah UInt128di mana 1+10jbit th diatur jika iff di isebelah jnumpad.
  • big(1)adalah a BigInt. Ini digunakan untuk mencegah overflow dan menggunakan lebih sedikit karakter daripada Int128(1)atau UInt128(1).
LukeS
sumber
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)

Tidak disatukan

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)

Penjelasan

Input adalah satu baris teks pada tabel tdengan kolom s. Pemahaman saya adalah bahwa menurut jawaban meta ini adalah bentuk input yang dapat diterima. Input dapat dibuat seperti di bawah ini.

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

Solusi beranotasi

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)
Kapten Man
sumber
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}

Yg diperindahkan

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

Uji

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

Jelly , 35 byte

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

Cobalah online!

-1 terima kasih kepada Jonathan Allan .

Penjelasan sedang diperbarui ...

Erik the Outgolfer
sumber
3
Jujur saya tidak punya petunjuk tentang bagaimana ini diuraikan, apalagi cara kerjanya. Penjelasan akan sangat dihargai.
caird coinheringaahing
@cairdcoinheringaahing maaf, tidak ada waktu sekarang
Erik the Outgolfer
-1 byte: Wẋ3->ḷþ
Jonathan Allan
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)

Input diambil dari kolom stabel baris tunggal bernama t:

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

Tidak Disatukan:

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
sumber