Локатор номерів кімнати


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, то вам дадуть провідні нулі. (тобто 004 та 028).

Вихід

Список можливих номерів. Це може бути в будь-якій бажаній формі, якщо між номерами номерів є роздільник. . (тобто 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
Так само я колись працював в ІТ, де був професор, який кілька тижнів працював з технологією приміщення. Він був у Бредлі 210 (про що я знав. Бредлі називали назву будівлі. Сусідня будівля - Метесон - була з'єднана через небесний міст на 3-му поверсі. Бредлі був 5-ти поверховим, Матсон 4). Він ніколи не міг сказати мені, в якій кімнаті він був правильно. Одного разу він сказав мені, що він був у "Matheson 605", який, очевидно, не існував, і жодної цифри не отримав правильно.
Draco18s

Відповіді:


13

Мова Вольфрама (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 байт, але найкраще, що я міг би впоратися з Р. Цікаво, щоб дізнатися, чи мають інші відгуки чи можуть краще!


1
ціла купа дрібниць: у вас є додатковий простір у другому рядку; зловживання пріоритетом може :перевищити */+-кілька байтів у першому рядку, позбувшись do.call, трактуючи 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)]:[]

Редагувати: збережено 6 байт завдяки @ edc65 (хоча пропоновані елементи 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>


Я бачу це [для (...)] у багатьох гольфах з кодом, але я не цілком його розумію, і я не можу знайти його в жодній документації. Чи можете ви пояснити це або опублікувати посилання на пояснення?
Антон Балмаєр

зберегти 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 дякую, це деякі хитрощі, які я повинен буде навчитися :)
Reinis Mazeiks

1
Поради щодо гольфу на Яві та Поради щодо гольфу на <всіх мовах> можуть бути цікавими для прочитання, якщо ви ще цього не зробили. :)
Кевін Кройсейсен


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 Hm. TiO каже 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це a, UInt128в якому встановлюється 1+10jth біт iff iзнаходиться поруч jіз numpad.
  • 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)

Пояснення

Вхід - це один текстовий рядок таблиці 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")
        }
    }
}

ТІО

TryItOnline


0

Желе , 35 байт

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

Спробуйте в Інтернеті!

-1 завдяки Джонатану Аллану .

Пояснення оновлюється ...


3
Я, чесно кажучи, не маю поняття про те, як це розбирають, не кажучи вже про те, як це працює. Пояснення були б дуже вдячні.
caird coinheringaahing

@cairdcoinheringaahing Вибачте, зараз немає часу
Ерік Вихідний

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

Безголівки:

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.