방 번호 찾기


24

방 번호 찾기

나는 동료에게 회의를 위해 잘못된 방 번호를 주었을 때 직장에서 흥미로운 문제 해결 기술을 접하게되었습니다. 때때로 모임에가는 동안 팀원이 잘못된 방 번호를 보내 게됩니다. 일반적으로 책상에서 서두르고 굵은 손가락으로 잘못된 열쇠가 있기 때문입니다.

흥미롭게도 잘못된 방에 도착하면 일반적으로 숫자 키패드 를 상상하여 실제로 어떤 방을 의미했는지 추측 할 수 있습니다 .

그리고 인접한 숫자를 추측함으로써 그들은 눌러야했습니다.

도전

동료가 한 자리 만 잘못 입력 한다고 가정하면 건물 사무실 번호 (000-999)를 사용하고 가능한 오타 솔루션을 출력하는 기능을 작성해야합니다 .

다음 표는 숫자 키패드에서 서로 인접한 숫자를 보여줍니다.

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

입력

3 자리 숫자 : 000-999. 정확히 3 자리의 입력을 가정하십시오. 숫자가 100보다 작거나 10보다 작 으면 앞에 0이 표시됩니다. (즉, 004 & 028).

산출

가능한 방 목록. 객실 번호 사이에 구분자가있는 한 원하는 형식이 될 수 있습니다. (예 : 공백, 쉼표, 줄 바꿈 등) 숫자가 100보다 작거나 10보다 작 으면 앞에 오는 0을 출력으로 설정할 수 있습니다. (즉, 004는 004 04 4, 028은 가능 028 28)

테스트 사례 (선행 0은 선택 사항 임) :

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

이것은 이므로 각 언어에 대한 가장 짧은 바이트 단위의 코드가 이깁니다.


1
세 자리 (0-9)의 목록으로 입력 할 수 있습니까?
HyperNeutrino

9
... 그래서 회의실에는 이름이 있어야합니다.
Jonathan Allan

2
@JonathanAllan 새로운 사람들이 "Room 218"보다 "Dolphin Room"을 찾는 것이 훨씬 어렵습니다 (객실 번호가 순서대로 할당되었다고 가정). 타협은 알파벳 순서로 이름을 정렬하는 것이지만 26 개만 있습니다.
Andrew는 Reinstate Monica

1
@KellyLowder는 933내가 고쳐야 했을 것입니다.
Jonathan Allan

4
관련, 한 번은 몇 주 동안 실내 기술에 문제가있는 교수가있는 IT 부서에서 일했습니다. 그는 Bradley 210에있었습니다 (내가 아는 Bradley는 건물의 이름입니다. 옆집 건물 Matheson은 3 층의 하늘 다리를 통해 연결되었습니다. Bradley는 5 층 높이였습니다, Matheson 4). 그는 자신이 어느 방에 있는지 정확히 알 수 없었습니다. 한 번 그는 자신이 특허권이없는 "Matheson 605"에 있다고 말했지만 숫자가 맞지 않았습니다.
Draco18s

답변:


13

볼프람 언어 (티카) , 112 (106) 바이트

숫자 키패드가 기본적으로 GridGraph0에 가장자리가 추가 된 3x3이라는 것을 인식하면을 사용하여 각 입력 숫자에 대해 인접한 숫자를 얻습니다 AdjacencyList.

아래에서 볼 수 있습니다.

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

여기에 이미지 설명을 입력하십시오

그럼 난 사용 Tuples가능한 모든 실수를 알아낼와 함께 정확히 하나의 오류가있는 사람을 선택하는 SelectEditDistance. 그건 그렇고, 이것은 더 긴 방 번호에서 작동 EditDistance하며 둘 이상의 오류를 허용하도록 매개 변수를 늘릴 수도 있습니다 . 좀 더 아래로 골프를 칠 수는 있지만 내 접근 방식을 보여주고 싶었습니다.

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

길이가 3 개의 방 번호 (106 바이트)로 하드 코딩 된 약간 더 골프화 된 버전. 각 숫자에 해당하는 순위 3 목록으로 출력됩니다.

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

온라인으로 사용해보십시오!


전위 오류도 포함하는 DamerauLevenshteinDistance대신 다른 거리 기능을 사용할 EditDistance수도 있습니다.
Kelly Lowder

9

파이썬 2 , 89 바이트

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

온라인으로 사용해보십시오!

1 번째 와 5 번째 문자는 여기에 표시되지 않을 수 있지만 (브라우저에 따라 다름) 전체 문자열은 다음과 같습니다.[21, 204, 1035, 62, 157, 2468, 359, 48, 579, 68]



3

R , 190 바이트

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

온라인으로 사용해보십시오!


CodeGolf에서의 두 번째 시도! 꽤 길지만 190 바이트이지만 R로 관리 할 수있는 최선의 방법입니다. 다른 사람들이 피드백을 받거나 더 잘할 수 있는지 궁금합니다.


1
작은 것들의 전체 무리 : 당신은 두 번째 줄에 여분의 공간이 있습니다. 의 우선 순위를 학대 :를 통해 */+-첫 번째 줄에 몇 바이트를 면도 할 수 치우는 do.call치료, aA와 matrix: 그것은 모든 주위에 39 바이트를 저장 전치 온라인으로보십시오!
주세페

당신은 이것에 능숙합니다! 피드백 감사드립니다.
Florian

2

자바 스크립트 (파이어 폭스 30-57) 115 109 바이트

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

편집 : @ edc65 덕분에 6 바이트가 절약되었습니다 (제안 된 제안은 0다른 제안 후에 나타납니다). ES6 버전 118 112 바이트 :

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>


많은 코드 골프에서이 [for (...)]를 보았지만 완전히 이해하지 못하고 문서에서 찾을 수없는 것 같습니다. 설명하거나 설명에 대한 링크를 게시 할 수 있습니까?
안톤 볼 마이어

6 바이트 저장 [...[12,240,1350,26,157,2468,359,48,579,78][c]+'']
edc65

1
@AntonBallmaier [for(...)]는 ECMAscript로 만들지 않은 몇 가지 배열 이해 구문 제안 중 하나였습니다. 반복자를 반복하고 결과를 간결하게 필터링 및 / 또는 매핑 할 수있었습니다. (이중 반복을 수행 할 때 특히 유용하다는 것을 알았습니다.)
Neil

2

자바, 205 177 바이트

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

나는 그것이 다른 답변과 비교하여 오래 걸렸다는 것을 알고 있습니다. 내 변명 : 그것은 자바에 있습니다.
Oracle은 toCharArray다음과 같이 이름 을 바꿔야 합니다 getCrs.

크레딧

-28 자 Kevin Cruijssen의


1
골프에 작은 것들. (String b)->그냥있을 수 있고 b->후행을 제거 할 수 있습니다 ;. 골프에 대한 실제 사항 : a한 번만 사용 하므로 직접 제거 String[]a=...;하고 사용할 수 "12,024,0135,26,157,2468,359,48,579,68".split(",")[...]있습니다. 또한 일 Byte.parseByte수 있습니다 new Byte. : 총 177 바이트 .
Kevin Cruijssen

1
@KevinCruijssen 고마워, 그것은 내가 배울 몇 가지 트릭입니다 :)
Reinis Mazeiks

1
Java의 골프 팁<모든 언어>의 골프 팁은 아직 읽지 않은 경우 읽어 보는 것이 흥미로울 수 있습니다. :)
Kevin Cruijssen


2

C (gcc) , 136 또는 114 바이트

ASCII 버전 136 ​​바이트

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

온라인으로 사용해보십시오!

유니 코드 114 108 바이트 (TiO가 이상하게 계산하는 것 같습니다)

이 버전의 @ceilingcat에게 감사합니다.

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

온라인으로 사용해보십시오!


@ceilingcat 흠. TiO는 108 바이트를 말합니다.
gastropner

TIO가 C에서 UTF-8 바이트를 올바르게 계산한다고 생각하지 않습니다. 언어를 bash 또는 다른 것으로 변경하고 바이트 수 변경을보십시오.
ceilingcat

@ceilingcat 예, 현지에서도 당황했습니다. 저장된 파일은 114 개입니다.
gastropner



1

파이썬 2 , 103 바이트

-4 바이트에 대한 @Lynn 덕분에.

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

온라인으로 사용해보십시오!


4 바이트를 절약하십시오 : in`0x134cd9a07d1e58feab643f7db24102`[int(v)::10](나도 시도 int('…',36)했지만 1 바이트 더 깁니다.)
Lynn

1

줄리아 0.6 , 93 바이트

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

온라인으로 사용해보십시오!

  • 숫자로 구성된 벡터를 가져와 같은 형식으로 목록을 반환합니다.
  • 0x502A044228550A21102B05406A는 UInt128되는 1+10j번째 비트가 설정되어 IFF가 ij에 숫자 키패드.
  • big(1)입니다 BigInt. 오버플로를 방지하고 Int128(1)또는 보다 적은 문자를 사용하는 데 사용됩니다 UInt128(1).

1

SQL (SQLite), 533 바이트

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)

언 골프

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)

설명

입력은 tcolumn이있는 테이블의 단일 텍스트 행입니다 s. 나는 이 메타 답변에 따르면 이것이 허용 가능한 입력 형식 이라는 것을 이해 합니다. 입력은 아래와 같이 만들 수 있습니다.

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

주석이 달린 솔루션

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

코 틀린 , 117 바이트

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

미화

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

테스트

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

젤리 , 35 바이트

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

온라인으로 사용해보십시오!

Jonathan Allan 에게 -1 감사합니다 .

설명이 업데이트 중입니다 ...


3
솔직히 이것이 어떻게 구문 분석되는지에 대한 단서가 없습니다. 설명은 크게 감사하겠습니다.
caird coinheringaahing

@cairdcoinheringaahing 죄송합니다, 지금 시간이 없습니다
Outgolfer Erik

-1 바이트 : Wẋ3->ḷþ
Jonathan Allan

0

T-SQL , 322 바이트

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)

입력은 다음 s과 같은 단일 행 테이블 의 열에서 가져옵니다 t.

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

언 골프 드 :

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

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.