Генерация чисел, дружественных к Numpad

22

Вдохновленный генерировать дружественные номера клавиатуры .

Задний план

Многие цифровые планшеты имеют следующую раскладку:

789

456

123

    0    

Мы определяем окрестность числа как набор ячеек, ортогонально смежных с ним на показанной цифровой клавиатуре, включая самого себя. Например, соседство 2 равно, {1,5,3,0,2}а соседство 0 {1,2,0}. Ниже приведен список окрестностей каждого числа, над тестовыми примерами.

Мы определяем число, удобное для числовых чисел, как положительное целое число, где при записи в десятичном виде без начальных нулей каждая цифра, кроме первой, находится в окрестности предыдущей цифры.

Например,

  • 7856 - число, удобное для числовых чисел, потому что 8 находится в окрестности 7, 5 - в соседнем доме 8, а 6 - в окрестности 5.
  • 1201 является дружественным числом, потому что 2 находится в окрестности 1, 0 - в окрестности 2, а 1 - в окрестности 0.
  • 82 не является числовым номером, потому что 2 не находится рядом с 8.
  • 802 не является числовым значением, потому что 0 не находится в окрестности 8 (окрестности не переносятся).

Связанная последовательность OEIS . Обратите внимание, что эта связанная последовательность отличается, потому что она считается 0смежной, 7а не 1и 2.

Вызов

Если задано положительное целое число n, верните числа, удобные для числа n-й nили первых n, где первое - 1. Вы можете использовать индексирование на основе 0, где число, удобное для чисел 0-го числа, будет равно 1.

Окрестности

Район каждой цифры указан здесь:

0:{0,1,2}
1:{0,1,2,4}
2:{0,1,2,3,5}
3:{2,3,6}
4:{1,4,5,7}
5:{2,4,5,6,8}
6:{3,5,6,9}
7:{4,7,8}
8:{5,7,8,9}
9:{6,8,9}

Тестовые случаи / последовательность

Это первые 100 терминов

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 20, 21, 22, 23, 25, 32, 33, 36, 41, 44, 45, 47, 52, 54, 55, 56, 58, 63, 65, 66, 69, 74, 77, 78, 85, 87, 88, 89, 96, 98, 99, 100, 101, 102, 110, 111, 112, 114, 120, 121, 122, 123, 125, 141, 144, 145, 147, 200, 201, 202, 210, 211, 212, 214, 220, 221, 222, 223, 225, 232, 233, 236, 252, 254, 255, 256, 258, 320, 321, 322, 323, 325, 332, 333, 336, 363, 365, 366, 369, 410, 411, 412, 414, 441, 444, 445, 447]
fireflame241
источник
5
Мне нравится, что в этом задании учитываются только положительные целые числа (что сохраняет сущность и позволяет участвовать в большем количестве языков) и что для гибкости можно отображать n-й или первый n выходных данных
Luis Mendo
Я полностью неверно истолковал задачу, вот сценарий «этот термин действителен в последовательности»: попробуйте онлайн!
Волшебная Урна Осьминога

Ответы:

9

JavaScript (ES6), 104 93 89 88 байт

Возвращает N-й член последовательности, 1-индексированный.

f=(i,k,n=k,N=n/5>>1)=>(N?8530025>>(n%10*6191^N%10*6191)%26&1:!i--)?N?f(i,k,N):k:f(i,-~k)

демонстрация

Arnauld
источник
Лучшее, что я мог получить, это 151, k=(n,a=1)=>n?k(n-([...(x=a+[]).slice(0,-1)].reduce((a,c)=>a*!!~"012 0124 01235 236 1457 24568 3569 478 5789 689".split` `[c].indexOf(x[i++]),i=1)),a+1):a-1может быть, что-то там поможет, мой тест, вероятно, слишком длинный
Конор О'Брайен,
Этот ответ выводит концепцию магических чисел на совершенно новый уровень ... Я даже не понимаю, как вы их нашли o_O
scottinet
2
@scottinet В значительной степени мое объяснение этого ответа относится и к этому. Абсолютная разница не очень хорошо сработала, поэтому я попробовал использовать XOR. Как примечание, я нашел другую формулу, которая работала в 96% случаев без необходимости поиска битовой маски. Но обработка оставшихся 4% отдельно была слишком дорогой в JS. Я не пробовал в желе , и теперь я все равно не помню формулу ... ¯ \ _ (ツ) _ / ¯
Арно
Спасибо за объяснения. Это все еще впечатляет :-)
scottinet
3

Желе , 27 24 байта

Возвращает N первых членов последовательности.

D⁽ÞȦ×^2\%26“⁷wð’æ»ḂẠ
1Ç#

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

Это порт моего ответа JS .

D⁽ÞȦ×^2\%26“⁷wð’æ»ḂẠ    - helper link: test numpad-friendliness of a number, e.g. 1257
D                       - get decimal digits             -> [1, 2, 5, 7]
    ×                   - multiply by ...
 ⁽ÞȦ                    - ... the integer 6191           -> [6191, 12382, 30955, 43337]
     ^2\                - bitwise XOR overlapping reduce -> [10353, 18613, 53666]
        %26             - modulo 26                      -> [5, 23, 2]
                æ»      - right-shift by each value ...
           “⁷wð’        - ... the integer 8530025        -> [266563, 1, 2132506]
                  Ḃ     - isolate the LSB                -> [1, 1, 0] which means that 1->2
                                                            and 2->5 are OK and 5->7 is not
                   Ạ    - all (0 if there's any 0)       -> 0, i.e. not numpad-friendly :'(

1Ç#                     - main link: return the [input] first matching numbers,
                          using our helper link as a monad and starting with 1
Arnauld
источник
3

05AB1E , 24 23 байта

µNSü‚εW_iO<ë<3BÆ}ÄR2‹}P

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

Возвращает n-е число в последовательности.

Пояснения:

µNSü‚εW_iO<ë<3BÆ}ÄR2‹}P    Full program
µ                          Until counter is equal to input
 N                         Push current iteration number (e.g. 1025)
  S                        Split to a list of chars (-> ['1', '0', '2', '5'])
   ü‚                      Group into pairs (-> ['1', '0'], ['0', '2'], ['2', '5'])
     ε                     For each pair
      W_                      Is smallest digit equal to 0?
        iO<                      True: sum all digits and decrement 
           ë                     False: 
            <                       - decrement all digits
             3B                     - convert to base 3
               Æ                    - reduced substraction
                }             End if
                 Ä            Absolute value
                  R           Reverse 
                   2‹         1 if result is < 2, 0 otherwise
                     }     End for each
                      P    Cumulative product (1 if all pair results are 
                                     1, 0 otherwise)
                           -- implicit counter increment if stack value is 1

Основная идея состоит в том, что, кроме 0ключа, любая цифра, уменьшенная и преобразованная в основание 3, обладает следующими свойствами:

  • левые и правые соседи имеют абсолютную разницу 1
  • верхние и нижние соседи имеют абсолютную разницу 10, которая в обратном порядке обычно равна 1
  • любая другая пара клавиш numpad приводит к другим значениям, даже в обратном порядке

Конечно, нам нужен ifоператор для обработки 0ключа numpad.

scottinet
источник
Твердый ответ, пришел предложить больше улучшений, не могу найти ни одного. Оооо ... и это попарно ставит вас в лидеры тоже :).
Волшебная Урна Осьминога
Я не думаю, что смог бы придумать эти 3 правила, довольно впечатляюще; что дало вам идею?
Волшебная Осьминог Урна
2

MATL , 29 27 байт

`@J3:qEt!J*+hYAd|2>~A?@]NG-

Выводит первые числа, nудобные для чисел.

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

объяснение

Каждая цифра от 1до 9кодируется как комплексное число, представляющее ее положение в цифровой клавиатуре, используя сетку шага 2, где действительная часть представляет вертикальное положение, а мнимая часть представляет горизонтальное положение. Так 1есть 0+0j, 2есть 0+2j, 3есть 0+4j, 4есть 2+0j, ..., 9есть 4+4j.

Цифра 0кодируется как 0+1j, то есть как если бы она была расположена точно между 1и 2.

Для каждого кандидата Numpad людей числа, «десятичная» базовая преобразование применяется с использованием выше комплексных чисел вместо цифр 0, 1..., 9. Это дает массив, из которого вычисляются абсолютные последовательные различия. Номер кандидата удобен для чисел, если и только если все абсолютные различия максимально 2(то есть шаг сетки). Если это так, номер остается в стеке.

Код использует цикл do... while, который завершается, когда количество чисел в стеке равно входному значению n.

Единичная сетка была бы более естественным выбором. Цифры 1, 2а 0затем будет соответствовать 0+0j, 1+0jи 0.5+0jсоответственно. Но лучше использовать сетку шага 2, потому что умножение на 2(функция E) и нажатие 0+1j(функция J) на один байт короче нажатия 0+0.5j( J2/или .5j)

Луис Мендо
источник
2

Желе , 26 байт

’d-,.⁸?3µ€ạ/S
Dṡ2Ç€<2Ạ
1Ç#

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

-2 байта благодаря Caird Cinheringaahing
-2 байта благодаря Эрику Outgolfer

объяснение

’d-,.⁸?3µ€ạ/S  Helper Link; compute the distance between two keys z = [x, y]
      ?        Switch:
     ⁸         If z (is not 0):
’              Decrement
 d             Divmod by:
  -,.          Else: [-1, 0.5] (special position for 0)
       3       3; right argument for divmod otherwise ignored
        µ      Begin a new monadic link / end this link
         €     Compute the position for each [x, y]
           /   Reduce on
          ạ    Absolute Difference
            S  Sum (this gives the Manhattan Distance)
Dṡ2Ç€<2Ạ       Helper Link; determine if a number <z> is numpad friendly
D              Convert number to decimal digits
 ṡ             Slice into overlapping slices of length
  2            2 (pairs)
    €          For each pair,
   Ç           The distance between the keys
     <2        Compare with 2 (the distance between two adjacent keys is 1; corners 2; 0 - 1 and 0 - 2 are 1.5)
       Ạ       All; either all of the distances are less than 2 or there were no distances
1Ç#            Main Link; find the first (input) numpad friendly numbers
  #            nfind; counting up from _ collect the first _______ matches that are
1                                      1
                                                           (input)
 Ç             Numpad Friendly
HyperNeutrino
источник
Вы можете удалить []за 2 байта
caird coinheringaahing
@cairdcoinheringaahing спасибо!
HyperNeutrino
1
Гольф пара прочь.
Эрик Outgolfer
1

Mathematica, 249 234 202 байта

(a=o=1;While[a<=#,s=IntegerDigits@o;t=1;p=0;While[t+p<Length@s,If[!FreeQ[(IntegerDigits/@{210,4210,53210,632,7541,86542,9653,874,9875,986})[[s[[t]]+1]],s[[t+1]]],t++,p++]];If[t==Length@s,a++];o++];o-1)&


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

спасибо user202729 за сжатие данных (-32 байта)

Мои результаты:

100 -> 447
1000 -> 20023
10000 -> 788777

J42161217
источник
Я думаю, что вы можете сжать данные с помощью IntegerDigits:, IntegerDigits/@{210,4210,53210,632,7541,86542,9653,874,9875,986}и использовать FreeQ, Trиспользовать Doвместо For, использовать инфиксную нотацию для AppendToи использовать Doвместо того, Whileчтобы повторять Tr[1^s]времена, а также исключить переменную p. Также вы не доказали, что алгоритм корректен, то есть результирующее число всегда меньше, чем его квадрат в квадрате, что необходимо для правильного ответа.
user202729
1
@ user202729 Я многое изменил. Мой ответ определенно действителен. Я сожму данные сейчас.
J42161217,
почему отрицание?
J42161217,
1

PHP, 124 + 1 байт

while($argn-=$r)for($p=$r=~0,$x=++$n;$x>=1;$p=[7,23,47,76,178,372,616,400,928,832][$c],$x/=10)$r&=!!($p&1<<$c=$x%10);echo$n;

Запустите как трубу с -nRили попробуйте онлайн .

Titus
источник
0

Java 8, 192 190 байт

n->{int r=1,p;a:for(;n>0;){p=-1;for(int c:(r+++"").getBytes())if(p>-1&!"012;0124;01235;236;1457;24568;3568;478;5789;689".split(";")[c-=48].contains(p+""))continue a;else p=c;n--;}return~-r;}

Возвращает (1-индексированное) nчисло в последовательности.

Это было на удивление сложнее, чем я думал .. Вероятно, у меня было несколько головорезов сегодня днем ​​...

Объяснение:

Попробуй это здесь.

n->{                 // Method with integer as both parameter and return-type
  int r=1,           //  Return-integer
      p;             //  Previous digit
  a:for(;n>0;){      //  Loop (1) as long as the input is larger than 0
    p=-1;            //   Start `p` at an integer that is not 0-9 (-1 in this case)
    for(int c:(r+++"").getBytes())
                     //   Loop (2) over the digits of the current number
      if(p>=0        //    If this is not the first digit (`p` != -1),
         &!"012;0124;01235;236;1457;24568;3568;478;5789;689".split(";")[c-=48]
           .contains(p+""))
                     //    and the adjacent digits are NOT part of a NumberPad-Friendly Nr:
        continue a;  //     Go to the next iteration of loop (1)
      else           //    Else:
        p=c;         //     Set `p` to the current digit for the next iteration
                     //   End of loop (2) (implicit / single-line body)
      n--;           //   If we haven't encountered the `continue`, decrease `n` by 1
  }                  //  End of loop (1)
  return~-r;         //  Return the result-integer - 1
}                    // End of method
Кевин Круйссен
источник