Номер комнаты Локатор


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

вход

Трехзначное число: 000-999 . Предположим, ввод точно 3 цифры. Если число меньше 100 или меньше 10, вы получите ведущие нули. (т.е. 004 и 028).

Выход

Список возможных номеров. Это может быть любая форма, если вы хотите, если между номерами есть разделитель. (т. е. пробел, запятая, новая строка и т. д.). Если число меньше 100 или меньше 10, вы можете или не можете иметь начальные нули в качестве выходных данных, это ваше дело. (т.е. 004 может быть 004 04 4, а 028 может быть 028 28)

Тестовые случаи (начальные нули необязательны):

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
... и именно поэтому конференц-залы должны иметь имена.
Джонатан Аллан

2
@JonathanAllan Новым людям гораздо сложнее найти «Комнату Дельфина», чем «Комнату 218» (при условии, что номера комнат назначаются по порядку). Компромиссом было бы упорядочить имена в алфавитном порядке, но тогда у вас есть только 26.
Эндрю говорит восстановить Монику

1
@KellyLowder должно было быть, 933поэтому я исправил это.
Джонатан Аллан

4
В связи с этим, я когда-то работал в IT, где был профессор, у которого были проблемы с технологиями помещений в течение нескольких недель подряд. Он был в Брэдли-210 (я знал, что Брэдли - это название здания. Здание по соседству - Мэтисон - было соединено через небесный мост на 3-м этаже. Брэдли был 5 этажным, Мэтисон 4). Он никогда не мог сказать мне, в какой комнате он был правильно. Однажды он сказал мне, что находится в «Мэтисоне 605», которого явно не существует, и не получил ни одной из правильных цифр.
Draco18s

Ответы:


13

Wolfram Language (Mathematica) , 112 106 байт

Признавая, что цифровая клавиатура - это в основном 3x3 GridGraphс ребрами, добавленными для 0, мы получаем соседние цифры для каждой входной цифры с помощью AdjacencyList.

Это можно увидеть ниже:

EdgeAdd[GridGraph[{3,3},VertexLabels->"Name",GraphLayout->"SpringEmbedding"],{0<->1,0<->2}] выходы:

введите описание изображения здесь

Затем я использую, Tuplesчтобы выяснить все возможные ошибки и выбрать те, которые имеют ровно одну ошибку с Selectи EditDistance. Кстати, это будет работать для длинных номеров, и вы также можете увеличить 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которых также будут включены ошибки транспонирования.
Келли Лоудер

9

Python 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
целая куча мелочей: у вас есть лишний пробел во второй строке; злоупотребление приоритетом :over */+-может сбрить несколько байтов в первой строке, избавиться от них do.call, трактовать их aкак a matrixи транспонировать - это сэкономит всего около 39 байтов: попробуйте онлайн!
Джузеппе

Вы хороши в этом! Спасибо за ответ.
Флориан

2

JavaScript (Firefox 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 байт (хотя предлагаемые 0s теперь появляются после других предложений). Версия 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>


Я вижу это [для (...)] во многих кодах, но не до конца понимаю и не могу найти его ни в одной документации. Не могли бы вы объяснить это или опубликовать ссылку на объяснение?
Антон Баллмайер

сохранить 6 байтов[...[12,240,1350,26,157,2468,359,48,579,78][c]+'']
edc65

1
@AntonBallmaier [for(...)]был одним из нескольких предложений синтаксиса понимания массива, который никогда не включался в ECMAscript. Это позволило вам зацикливаться на итераторе и кратко фильтровать и / или отображать результаты. (Я нашел это особенно полезным при выполнении двойной итерации.)
Нил

2

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

Я знаю, что это долго по сравнению с другими ответами. Мое оправдание: это на Java.
Oracle следует переименовать toCharArrayв нечто подобноеgetCrs .

кредиты

-28 персонажей Кевина Круйссена


1
Некоторые мелочи в гольф. (String b)->может быть просто b->, и вы можете удалить трейлинг ;. Что касается реальных вещей в гольф: вы используете только aодин раз, так что вы можете удалить String[]a=...;и использовать "12,024,0135,26,157,2468,359,48,579,68".split(",")[...]напрямую. Также Byte.parseByteможет быть new Byte. Всего: 177 байтов .
Кевин Круйссен

1
@KevinCruijssen спасибо, вот некоторые уловки, которые я должен выучить :)
Рейнис Мажейкс

1
Советы по игре в гольф на Java и советы по игре в гольф на <все языки> могут быть интересными, если вы еще этого не сделали. :)
Кевин Круйссен


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

Попробуйте онлайн!

Unicode 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 Хм. ТиО говорит 108 байтов.
гастропнер

Я не думаю, что TIO правильно подсчитывает байты UTF-8 в C. Попробуйте изменить язык на bash или что-то еще и посмотрите, как меняется количество байтов.
потолок кошка

@ceilingcat Да, в местном масштабе это тоже было вялым. Сохраненный файл - 114, достаточно верно.
гастропнер



1

Python 2 , 103 байта

спасибо @Lynn за -4 байта.

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

Юлия 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]

Попробуйте онлайн!

  • Берет вектор цифр и возвращает список в том же формате.
  • 0x502A044228550A21102B05406это бит, UInt128в котором установлен 1+10jбит, если он iнаходится рядом с jцифровой клавиатурой.
  • 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)

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)

объяснение

Ввод представляет собой одну строку текста в таблице tсо столбцом 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Ẏ

Попробуйте онлайн!

-1 спасибо Джонатану Аллану .

Объяснение обновляется ...


3
Я, честно говоря, понятия не имею о том, как это анализируется, не говоря уже о том, как это работает. Объяснение будет с благодарностью.
caird coinheringaahing

@cairdcoinheringaahing извините, сейчас нет времени
Эрик Outgolfer

-1 байт: Wẋ3->ḷþ
Джонатан Аллан

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')

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.