Định vị số phòng


24

Định vị số phòng

Tôi đã bắt gặp một kỹ thuật giải quyết vấn đề thú vị trong công việc của mình khi đưa nhầm số phòng từ một đồng nghiệp cho một cuộc họp. Thỉnh thoảng, trên đường đến một cuộc họp, một thành viên trong nhóm của tôi sẽ gửi cho tôi số phòng sai, điển hình là vì họ đang vội vàng ở bàn làm việc và ngón tay sai chìa khóa.

Thật thú vị, khi đến nhầm phòng, tôi thường có thể đoán được họ thực sự có ý nghĩa gì khi tưởng tượng Bàn phím số :

và bằng cách đoán một số liền kề họ có nghĩa là nhấn.

Thử thách

Thách thức của bạn là viết một hàm lấy số văn phòng tòa nhà (000-999) và đưa ra các giải pháp lỗi chính tả có thể, giả sử đồng nghiệp của bạn chỉ nhập sai một chữ số.

Bảng sau đây cho biết các số nào liền kề nhau trên Bàn phím số:

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

Đầu vào

Một số có 3 chữ số : 000-999. Giả sử đầu vào đúng 3 chữ số. Nếu số lượng nhỏ hơn 100 hoặc dưới 10, bạn sẽ được cung cấp các số 0 đứng đầu. (tức là 004 & 028).

Đầu ra

Một danh sách các phòng có thể. Điều này có thể ở bất kỳ hình thức nào bạn muốn, miễn là có một dấu phân cách giữa các số phòng. (ví dụ: dấu cách, dấu phẩy, dòng mới, v.v.) Nếu số nhỏ hơn 100 hoặc nhỏ hơn 10, bạn có thể hoặc không thể có các số 0 đứng đầu làm đầu ra, điều đó tùy thuộc vào bạn. (tức là 004 có thể 004 04 4và 028 có thể 028 28)

Các trường hợp thử nghiệm (các số 0 đứng đầu là tùy chọn):

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

Đây là , vì vậy mã ngắn nhất tính theo byte cho mỗi ngôn ngữ sẽ thắng.


1
Chúng ta có thể lấy đầu vào là một danh sách gồm ba chữ số (0-9) không?
HyperNeutrino

9
... Và đây là lý do tại sao phòng họp nên có tên.
Jonathan Allan

2
@Jonathan ALLan Người mới tìm thấy "Phòng cá heo" khó hơn rất nhiều so với "Phòng 218" (giả sử rằng số phòng được chỉ định theo thứ tự). Một sự thỏa hiệp sẽ được sắp xếp theo thứ tự abc các tên, nhưng sau đó bạn chỉ có 26.
Andrew nói Phục hồi Monica

1
@KellyLowder nên đã được 933sửa chữa.
Jonathan Allan

4
Liên quan, tôi đã từng làm việc trong ngành CNTT nơi có một giáo sư gặp rắc rối với công nghệ phòng trong vài tuần chạy. Anh ta ở Bradley 210 (mà tôi biết, Bradley là tên của tòa nhà. Tòa nhà bên cạnh - Matheson - được kết nối qua một cây cầu trên tầng 3, Bradley cao 5 tầng, Matheson 4). Anh ấy không bao giờ có thể nói cho tôi biết anh ấy ở phòng chính xác. Một lần, anh ấy nói với tôi rằng anh ấy ở "Matheson 605", điều đó rõ ràng không tồn tại và không có chữ số nào đúng.
Draco18

Câu trả lời:


13

Ngôn ngữ Wolfram (Mathicala) , 112 106 byte

Nhận thấy rằng một bàn phím số về cơ bản là 3x3 GridGraphvới các cạnh được thêm vào 0, chúng tôi nhận được các chữ số liền kề cho mỗi chữ số đầu vào với AdjacencyList.

Điều này có thể được nhìn thấy dưới đây:

EdgeAdd[GridGraph[{3,3},VertexLabels->"Name",GraphLayout->"SpringEmbedding"],{0<->1,0<->2}] sản lượng:

nhập mô tả hình ảnh ở đây

Sau đó, tôi sử dụng Tuplesđể tìm ra tất cả các lỗi có thể xảy ra và chọn ra những lỗi có chính xác một lỗi với SelectEditDistance. Nhân tiện, điều này sẽ làm việc cho số phòng dài hơn và bạn cũng có thể tăng EditDistancetham số để cho phép nhiều hơn một lỗi. Có thể chơi golf này xuống một chút nữa nhưng muốn thể hiện cách tiếp cận của tôi.

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

Phiên bản chơi gôn nhiều hơn một chút được mã hóa theo chiều dài 3 số phòng (106 Byte). Điều này sẽ xuất ra dưới dạng một danh sách xếp hạng 3 tương ứng với mỗi chữ số:

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

Hãy thử trực tuyến!


Người ta cũng có thể sử dụng các hàm khoảng cách khác như DamerauLevenshteinDistancethay vì EditDistancecũng bao gồm các lỗi chuyển vị.
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])`]

Hãy thử trực tuyến!

1 st và 5 ngày ký tự có thể không được hiển thị ở đây (trình duyệt phụ thuộc), nhưng chuỗi đầy đủ tương đương với[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}),]}

Hãy thử trực tuyến!


Nỗ lực thứ hai của tôi tại CodeGolf! Khá dài, 190 byte, nhưng tốt nhất tôi có thể quản lý với R. Tò mò để xem người khác có phản hồi hay có thể làm tốt hơn không!


1
cả đống thứ nhỏ nhặt: bạn có thêm một khoảng trống ở dòng thứ hai; lạm dụng quyền ưu tiên :hơn */+-có thể loại bỏ một vài byte trong dòng đầu tiên, loại bỏ do.call, xử lý anhư một matrixvà chuyển đổi nó sẽ tiết kiệm tất cả khoảng 39 byte: Hãy thử trực tuyến!
Giuseppe

Bạn giỏi trong việc này! Cảm ơn vì bạn đã phản hồi.
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)]:[]

Chỉnh sửa: Đã lưu 6 byte nhờ @ edc65 (mặc dù 0hiện tại các đề xuất đã xuất hiện sau các đề xuất khác). Phiên bản 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>


Tôi thấy điều này [cho (...)] trong rất nhiều môn đánh gôn, nhưng tôi không hiểu hết về nó và dường như tôi không thể tìm thấy nó trong bất kỳ tài liệu nào. Bạn có thể giải thích nó hoặc gửi một liên kết đến một lời giải thích?
Anton Ballmaier

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

1
@AntonBallmaier [for(...)]là một trong một số đề xuất cú pháp hiểu mảng chưa bao giờ được đưa vào ECMAscript. Nó cho phép bạn lặp qua một trình vòng lặp và bộ lọc ngắn gọn và / hoặc ánh xạ qua các kết quả. (Tôi thấy nó đặc biệt hữu ích khi thực hiện lặp lại gấp đôi.)
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);}}}

Tôi biết nó dài so với các câu trả lời khác. Lý do của tôi: đó là trong Java.
Oracle nên đổi tên toCharArraythành một cái gì đó như getCrs.

Tín dụng

-28 nhân vật của Kevin Cruijssen


1
Một số điều nhỏ để chơi golf. (String b)->có thể chỉ b->, và bạn có thể loại bỏ dấu vết ;. Đối với những thứ thực tế để chơi golf: Bạn chỉ sử dụng amột lần, vì vậy bạn có thể loại bỏ String[]a=...;và sử dụng "12,024,0135,26,157,2468,359,48,579,68".split(",")[...]trực tiếp. Ngoài ra, Byte.parseBytecó thể được new Byte. Tổng cộng: 177 byte .
Kevin Cruijssen

1
@KevinCruijssen cảm ơn, đó là một số mẹo tôi sẽ phải học :)
Reinis Mazeiks

1
Mẹo chơi gôn trong JavaMẹo chơi gôn bằng <tất cả các ngôn ngữ> có thể thú vị để đọc qua trong trường hợp bạn chưa có. :)
Kevin Cruijssen


2

C (gcc) , 136 hoặc 114 byte

Phiên bản 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);}

Hãy thử trực tuyến!

Unicode 114 108 byte (TiO dường như được tính một cách kỳ lạ cho việc này)

Cảm ơn @ceilingcat cho phiên bản này.

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

Hãy thử trực tuyến!


@ceilingcat Hừm. TiO nói 108 byte.
dạ dày

Tôi không nghĩ TIO đếm chính xác các byte UTF-8 trong C. Hãy thử thay đổi ngôn ngữ thành bash hoặc một cái gì đó khác và xem sự thay đổi số lượng byte.
trần mèo

@ceilingcat Vâng, địa phương cũng rất hay. Tệp đã lưu là 114, đủ đúng.
dạ dày


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

Hãy thử trực tuyến!

Đã lưu 35 byte bằng cách mượn ý tưởng từ câu trả lời ruby ​​của @ AsoneTuhid.


1

Python 2 , 103 byte

cảm ơn @Lynn cho -4 byte.

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

Hãy thử trực tuyến!


Lưu 4 byte với: in`0x134cd9a07d1e58feab643f7db24102`[int(v)::10](Tôi cũng đã thử int('…',36)nhưng nó dài hơn một byte.)
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]

Hãy thử trực tuyến!

  • Lấy một vectơ các chữ số và trả về một danh sách có cùng định dạng.
  • 0x502A044228550A21102B05406là một bit UInt128trong đó 1+10jbit thứ được đặt iff ibên cạnh jtrên numpad.
  • big(1)là một BigInt. Nó được sử dụng để ngăn chặn tràn và sử dụng ít ký tự hơn Int128(1)hoặc 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)

Bị đánh cắp

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)

Giải trình

Đầu vào là một hàng văn bản duy nhất trên bàn tvới cột s. Hiểu biết của tôi là theo câu trả lời meta này, đây là một hình thức đầu vào chấp nhận được. Đầu vào có thể được tạo ra như dưới đây.

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

Giải pháp chú thích

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}

Làm đẹp

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

Kiểm tra

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

Dùng thử


0

Thạch , 35 byte

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

Hãy thử trực tuyến!

-1 cảm ơn Jonathan Allan .

Giải thích đang được cập nhật ...


3
Tôi thực sự không có manh mối về cách phân tích cú pháp này, chứ chưa nói đến cách nó hoạt động. Một lời giải thích sẽ được đánh giá rất cao.
caird coinheringaahing

@cairdcoinheringaahing xin lỗi, không có thời gian bây giờ
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)

Đầu vào được lấy từ cột scủa một bảng đơn có tênt :

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

Ung dung:

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

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.