Створення цифрових номерів для клавіатури


29

Найбільш поширені розкладки клавіатури комп’ютера мають клавіші з десятковою цифрою

1234567890

бігаючи вгорі, над клавішами для літер.

Нехай сусідство десяткової цифри - це набір цифр від його власного цифрового ключа та від цифрових клавіш негайно ліворуч та праворуч, якщо вони існують.

Наприклад, околиця 0 є {0, 9}, а околиця 5 - {4, 5, 6}.

Тепер визначте дружнє число на клавіатурі як натуральне ціле (у десятковій формі без провідних нулів), яке можна набрати на макеті вище, щоб кожна послідовна цифра числа після першої цифри знаходилась у сусідстві з попередньою цифрою.

  • Всі одноцифрові номери (1-9) є тривіально зручними для клавіатури.

  • Таке число, як 22321, є зручним для клавіатури, оскільки кожна цифра (не рахуючи першої) знаходиться поруч із цифрою безпосередньо раніше.

  • Таке число, як 1245, не є зручним для клавіатури, оскільки 4 не знаходиться поблизу 2 (а також навпаки).

  • Таке число, як 109, не є зручним для клавіатури, оскільки 0 не знаходиться поблизу 1. Кінці не обертаються навколо.

Встановивши зручні для клавіатури номери в порядку від найменшого до найбільшого, ми можемо створити цілу послідовність .

Ось перші 200 термінів послідовності чисел, присвячених клавіатурі:

N KFN(N)
1 1
2 2
3 3
4 4
5 5
6 6
7 7
8 8
9 9
10 11
11 12
12 21
13 22
14 23
15 32
16 33
17 34
18 43
19 44
20 45
21 54
22 55
23 56
24 65
25 66
26 67
27 76
28 77
29 78
30 87
31 88
32 89
33 90
34 98
35 99
36 111
37 112
38 121
39 122
40 123
41 211
42 212
43 221
44 222
45 223
46 232
47 233
48 234
49 321
50 322
51 323
52 332
53 333
54 334
55 343
56 344
57 345
58 432
59 433
60 434
61 443
62 444
63 445
64 454
65 455
66 456
67 543
68 544
69 545
70 554
71 555
72 556
73 565
74 566
75 567
76 654
77 655
78 656
79 665
80 666
81 667
82 676
83 677
84 678
85 765
86 766
87 767
88 776
89 777
90 778
91 787
92 788
93 789
94 876
95 877
96 878
97 887
98 888
99 889
100 890
101 898
102 899
103 900
104 909
105 987
106 988
107 989
108 990
109 998
110 999
111 1111
112 1112
113 1121
114 1122
115 1123
116 1211
117 1212
118 1221
119 1222
120 1223
121 1232
122 1233
123 1234
124 2111
125 2112
126 2121
127 2122
128 2123
129 2211
130 2212
131 2221
132 2222
133 2223
134 2232
135 2233
136 2234
137 2321
138 2322
139 2323
140 2332
141 2333
142 2334
143 2343
144 2344
145 2345
146 3211
147 3212
148 3221
149 3222
150 3223
151 3232
152 3233
153 3234
154 3321
155 3322
156 3323
157 3332
158 3333
159 3334
160 3343
161 3344
162 3345
163 3432
164 3433
165 3434
166 3443
167 3444
168 3445
169 3454
170 3455
171 3456
172 4321
173 4322
174 4323
175 4332
176 4333
177 4334
178 4343
179 4344
180 4345
181 4432
182 4433
183 4434
184 4443
185 4444
186 4445
187 4454
188 4455
189 4456
190 4543
191 4544
192 4545
193 4554
194 4555
195 4556
196 4565
197 4566
198 4567
199 5432
200 5433

Виклик

Напишіть програму або функцію, яка приймає додатне ціле число N (через stdin / командний рядок / функцію arg) та друкує (до stdout) або повертає N-й член у послідовній чисельності послідовності чисел.

Наприклад, якщо вхід є 191, вихід повинен бути 4544.

Необов'язково вихід може мати один зворотний новий рядок.

Виграє найкоротше подання в байтах.



Спасибі, @ Sp3000. Я прокрутився сюди, дивуючись цій самій речі.
luser droog

Відповіді:


8

Pyth, 27 24 байти

uf!f/h-FY3.:metsd`T2hGQ0

Демонстрація.

Покращення оригіналу:

  • Використовуючи metdзамість .r ... _UJ: 2 менше байтів. 1 прямий, 1 за відсутність використання Дж.

  • Використання sта `Tзамість JT10: 1 менший байт.


Почну з строковим поданням числа: `T.

Потім ми перетворюємо рядок у список цифр і обертаємо цифри цифр назад на одну, (9876543210) з metsd. Потім беремо 2 підряд елементів .: ... 2. Ці послідовності фільтрують по /h-FY3. Цей вираз відповідає ((a-b)+1)/3, що дорівнює нулю, якщо і тільки тоді, коли різниця між aі bстановить максимум 1. Таким чином, відфільтрований список буде порожнім, якщо і лише якщо число є зручним для клавіатури. З !, результат вірний лише в тому випадку, якщо номер відповідає клавіатурі.

f ... hGфільтрує вгору з G+1тих пір, поки результат не стане істинним, даючи номер дружнього клавіатури першого G+1або вище. u ... Q0застосовує цю функцію до власних Qчасових виходів , починаючи з 0, де Qвхід. Це дає номер Qдружнього клавіатури за бажанням.


4

Python 3, 112 102 байт

f=lambda n,k=0:n+1and f(n-all(-2<~-int(a)%10-~-int(b)%10<2for a,b in zip(str(k),str(k)[1:])),k+1)or~-k

Ми відстежуємо кількість дружніх номерів, які ще потрібно знайти, nі останній зареєстрований номер уk .

5 та 5 байтів збережено завдяки @isaacg та @ Sp3000.


Використовуйте вираз lamba замість повернення def. Ламби дозволяють використовувати за замовчуванням.
isaacg

@isaacg Спасибі, я не знав, як повторити ламбда.
випадкова

Ага правильно. На перше місце виходять одинарні. Моя помилка.
mbomb007

Ви можете скинути [:-1]вzip
Sp3000

4

CJam, 29 28 байт

ri_4#{AbAfe|_1>.-W<3,:(-!},=

Спробуйте його в Інтернеті в інтерпретаторі CJam .


Чи є легкий доказ того, що верхня межа N-го дружнього числа - N ** 2
Оптимізатор

Ще не знайшли. Доказ N ** 4досить легкий, оскільки 2 ** kнижче є принаймні KFN 10 ** k < 16 ** k. Заміна _*на 4#не змінить кількість байтів, але це зробить код жахливо неефективним.
Денніс

Тоді ваш код невірний для великого вхідного номера?
Оптимізатор

1
Сподіваюсь, що ні. Але я його зміню, поки не знаю. бурчить
Денніс

3

CJam, 34 31 байт

Денніс врятував 3 байти.

Я впевнений, що розрив до Pyth можна якось закрити, але зараз я не встигаю займатись цим гольфом ...

0q~{{)_s:_2ew{A,s(+f#~m2/},}g}*

Перевірте це тут.


Ви можете замінити )_++з , :_щоб зберегти 2 символів і -z1>з , m2/щоб врятувати іншого.
Денніс

@Dennis О, це приємно, дякую!
Мартін Ендер

3

JavaScript (ES6), 95

F=k=>{for(i=0;k;k-=(f=1,p=NaN,[for(d of''+i)(d=(8-~d)%10,d-p>1|p-d>1?f=0:p=d)],f))++i;return i}

Безумовно

F=k=>{
  for(i=0; k>0; )
  {
    ++i;
    f = 1; // presume i it's friendly
    p = NaN; // initial value so that first comparison gives false
    for(d of ''+i) // loop for each digit of i
    {
      // rotate digits 1->0, 2->1 ... 9->8, 0->9
      // note d is string, ~~ convert to number (golfed: 8-~d)
      d = (~~d+9) % 10 
      if (p-d>1 || p-d<-1) 
        f = 0 // not friendly
      else 
        // this can go in the 'else', if not friendly I don't care anymore
        p = d // move current digit to prev digit
    }
    k -= f // count if it's friendly, else skip
  }
  return i
}

Тест : виконати фрагмент у Firefox


Я не знаю багато JS, але не могли б ви зробити що - щось подібне , abs(p-d)>1а не p-d>1|p-d<-1?
Олексій А.

@AlexA. Вирази в розгорнутих і гольф рівнозначні. Math.abs(p-d)>1довше, ніжp-d>1|p-d<-1
edc65

Ага, гаразд. Я знав, що вони рівноцінні, я просто не знав, що вам потрібен Math.префікс.
Олексій А.

2

Haskell, 90 80 байт

([x|x<-[0..],all((<2).abs)$zipWith(-)=<<tail$[mod(1+fromEnum c)10|c<-show x]]!!) 

Це функція без імені. Щоб використовувати його, викликайте його параметром, наприклад: ([x|x<-[0..],all((<2).abs)$zipWith(-)=<<tail$[mod(1+fromEnum c)10|c<-show x]]!!) 199який повертається5432 .

Як це працює:

[x|x<-[0..]           ]  make a list of all integers x starting with 0
           ,             where
             c<-show x   each character in the string representation of x
  mod(1+fromEnum c)10    turned into the number '(ascii+1) mod 10'
 zipWith(-)=<<tail       then turned into a list of differences between neighbor elements
all((<2).abs)            only contains elements with an absolute value less than 2


                   !!    ... take the element given by the parameter (!! is 0 
                         based, that's why I'm starting the initial list with 0)

Редагувати: @Mauris знайшов кілька байтів для збереження. Спасибі!


Замість того , щоб x<-[1..]... !!n-1, ви можете зробити x<-[0..]... !!n.
Лінн

І тоді, звичайно, f n=[...]!!nможна f=([...]!!).
Лінн

Я звів її до однієї функції, усунувши a:f=([x|x<-[0..],all((<2).abs)$zipWith(-)=<<tail$[mod(1+fromEnum c)10|c<-show x]]!!)
Лінн

@Mauris: вау, дякую! Без цього aми також можемо усунути f.
німі

2

Дарт, 92 байти

f(n,[x=0]){t(x)=>x>9?((x+9)%10-((x~/=10)+9)%10).abs()>1||t(x):--n>0;while(t(++x));return x;}

З рядками:

f(n,[x=0]){
  t(x)=>x>9?((x+9)%10-((x~/=10)+9)%10).abs()>1||t(x):--n>0;
  while(t(++x));  
  return x;
}

Подивіться / запустіть його на DartPad


1

Пакетна - 520 байт

Здригаються.

@echo off&setLocal enableDelayedExpansion&set a=0&set b=0
:a
set/ab+=1&set l=0&set c=%b%
:b
if defined c set/Al+=1&set "c=%c:~1%"&goto b
set/am=l-2&set f=0&for /l %%a in (0,1,%m%)do (
set x=!b:~%%a,1!&set/an=%%a+1&for %%b in (!n!)do set y=!b:~%%b,1!
set z=0&set/ad=x-1&set/ae=x+1&if !e!==10 set e=0
if !d!==-1 set d=9
if !y!==!d! set z=1
if !y!==!e! set z=1
if !y!==!x! set z=1
if !y!==0 if !x!==1 set z=0
if !y!==1 if !x!==0 set z=0
if !z!==0 set f=1)
if !f!==0 set/aa+=1
if %a% NEQ %1 goto :a
echo %b%

1

Bash + coreutils, 120 байт

seq $1$1|tr 1-90 0-9|sed 's#.#-&)%B)/3)||(((C+&#g;s/^/(0*((/;s/$/))*0)/'|bc|nl -nln|sed '/1$/d;s/   0//'|sed -n "$1{p;q}"

Деякі тести:

$ for i in 1 10 11 99 100 200; do ./kfn.sh $i; done
1     
11    
12    
889   
890   
5433  
$ 

0

JavaScript ES6, 126 байт

f=n=>{b=s=>[...++s+''].every((e,i,a,p=(+a[i-1]+9)%10)=>i?p==(e=+e?e-1:9)|p-e==1|e-p==1:1)?s:b(s)
for(p=0;n--;)p=b(p)
return p}

Невикористаний код і тести нижче. Це, безумовно, можна вдосконалити більше.

f=function(n){
  b=function(s){
    return (s+'').split('').every(function(e,i,a){
      e=+e?e-1:9
      p=i?(+a[i-1]+9)%10:e
      return p==e|p-e==1|e-p==1
    })?s:b(s+1)
  }
  for(p=i=0;i<n;i++){
    p=b(p+1)
  }
  return p
}

var input = document.getElementById('n'), results = [];
input.onchange = function(){
  document.getElementById('s').innerHTML = f(input.value)
}
for(var i=0;i<200;i++){
  results.push(i + ':&nbsp;' + f(i))
}
document.getElementById('r').innerHTML=results.join('<br />')
N = <input type="number" id="n" min="1" value="191" /><br />
KBD(N) = <samp id="s">4544</samp>
<div id="r"></div>


0

Кобра - 135

Цього часу не робив, але ось:

def f(n,i=0)
    while n,if all for x in (s='[i+=1]').length-1get s[x+1]in' 1234567890'[(int.parse(s[x:x+1])+9)%10:][:3],n-=1
    print i

Безголовки:

def fn(n as int)
    i = 0
    while n <> 0
        i += 1
        s = i.toString
        l = s.length - 1
        v = true
        for x in l
            k = (int.parse(s[x].toString) + 9) % 10
            if s[x + 1] not in ' 1234567890'[k : k + 3], v = false
        if v, n -= 1
    print i


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.