Gere números compatíveis com Numpad

22

Inspirado por Gerar números amigáveis ​​do teclado .

fundo

Muitos botões numéricos têm o seguinte layout:

789

456

123

    0    

Definimos a vizinhança de um número como o conjunto de células ortogonalmente adjacentes a ela no teclado numérico mostrado, incluindo a si próprio. Por exemplo, o bairro 2 é {1,5,3,0,2}e o bairro 0 é {1,2,0}. Há uma lista da vizinhança de cada número abaixo, acima dos casos de teste.

Definimos um número amigável do numpad como um número inteiro positivo, onde, quando escrito em decimal sem zeros à esquerda, cada dígito, exceto o primeiro, fica na vizinhança do dígito anterior.

Por exemplo,

  • 7856 é um número amigável para numpad porque 8 está no bairro de 7, 5 no bairro vizinho de 8 e 6 no bairro de 5.
  • 1201 é um número amigável para numpad porque 2 está no bairro de 1, 0 está no bairro de 2 e 1 está no bairro de 0.
  • 82 não é um número amigável para numpad porque 2 não está na vizinhança de 8.
  • 802 não é um número compatível com o teclado numérico, porque 0 não fica na faixa de 8 (as vizinhanças não ficam por aí).

Sequência OEIS relacionada . Observe que essa sequência relacionada é distinta porque conta 0como adjacente a em 7vez de 1e 2.

Desafio

Dado um número inteiro positivo n, retorne o n-ésimo ou o primeiro nnúmero amigável do teclado numérico, onde o primeiro é 1. Você pode usar a indexação baseada em 0, onde o número amigável do teclado numérico 0 seria 1.

Bairros

A vizinhança de cada dígito está listada aqui:

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}

Casos de teste / sequência

Estes são os primeiros 100 termos

[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
fonte
5
Eu gosto de como este desafio considera apenas números inteiros positivos (que mantém a essência e permite que mais idiomas para participar) e permite visualizar tanto o n -ésimo ou as primeiras n saídas de flexibilidade
Luis Mendo
Eu interpretei completamente o desafio, eis um script "este termo é válido na sequência": Experimente online!
Magic Octopus Urn

Respostas:

9

JavaScript (ES6), 104 93 89 88 bytes

Retorna o termo n-ésimo da sequência, indexada em 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)

Demo

Arnauld
fonte
Melhor eu poderia obter é de 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-1talvez algo não ajuda, o meu teste é provavelmente demasiado longo
Conor O'Brien
Esta resposta traz o conceito de números mágicos para um nível totalmente novo ... Eu não entendo como você os encontrou O_O
scottinet
2
@ scottinet Em grande medida, minha explicação para esta resposta se aplica a essa também. A diferença absoluta não funcionou muito bem nessa, então tentei com o XOR. Como observação, encontrei outra fórmula que funcionava em 96% dos casos sem a necessidade de uma máscara de bits de pesquisa. Mas processar os 4% restantes separadamente era muito caro em JS. Eu não tentar in Jelly , e agora eu não me lembro a fórmula de qualquer maneira ... ¯ \ _ (ツ) _ / ¯
Arnauld
Obrigado pelas explicações. Este ainda é impressionante :-)
scottinet
4

Perl 5 , 123 + 1 (-p) = 124 bytes

while($_){$r=@d=++$\=~/./g;map$r&&=(120,1240,12350,236,1457,24568,3569,478,5789,689)[$d[$_-1]]=~/$d[$_]/,1..$#d;$r&&$_--}}{

Experimente online!

Xcali
fonte
3

Geléia , 27 24 bytes

Retorna os N primeiros termos da sequência.

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

Experimente online!

Esta é uma porta da minha resposta 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
fonte
3

05AB1E , 24 23 bytes

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

Experimente online!

Retorna o enésimo número na sequência.

Explicações:

µ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

A idéia principal é que, além da 0chave, qualquer dígito decrementado e convertido na base 3 tenha as seguintes propriedades:

  • vizinhos esquerdo e direito têm uma diferença absoluta de 1
  • vizinhos acima e abaixo têm uma diferença absoluta de 10 que, invertida, é convenientemente igual a 1
  • qualquer outro par de teclas numpad resulta em valores diferentes, mesmo quando invertidos

É claro que precisamos de uma ifdeclaração para lidar com a 0tecla numpad.

escoteiro
fonte
Resposta sólida, veio oferecer mais melhorias, não consegue encontrar nenhuma. Oooo ... e isso aos pares também colocou você na liderança :).
Magic Octopus Urn
Eu não acho que eu seria capaz de criar essas três regras, tbh bastante impressionante; o que te deu a ideia?
Magic Octopus Urn
2

MATL , 29 27 bytes

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

Produz os primeiros nnúmeros compatíveis com o teclado.

Experimente online!

Explicação

Cada dígito de 1a 9é codificado como um número complexo que representa sua posição no teclado numérico, usando em uma grade da etapa 2, onde a parte real representa a posição vertical e a parte imaginária representa a posição horizontal. Então 1é 0+0j, 2é 0+2j, 3é 0+4j, 4é 2+0j, ..., 9é 4+4j.

O dígito 0é codificado como 0+1j, ou seja, como se fosse colocado exatamente entre 1e 2.

Para cada número amigável-numpad candidato, um "decimal" conversão de base é aplicado usando o acima números complexos em vez dos dígitos 0, 1, ..., 9. Isso fornece uma matriz, da qual as diferenças consecutivas absolutas são calculadas. O número do candidato é compatível com numpad se e somente se todas as diferenças absolutas forem no máximo 2(isto é, a etapa da grade). Se for esse o caso, o número é deixado na pilha.

O código usa um loop do... while, que é encerrado quando a quantidade de números na pilha é igual à entrada n.

Uma grade de unidades teria sido uma escolha mais natural. Dígitos 1, 2e 0, então, correspondem a 0+0j, 1+0je 0.5+0jrespecrively. Mas é mais golfista usar uma grade do passo 2, porque multiplicar por 2(função E) e pressionar 0+1j(função J) é um byte menor que pressionar 0+0.5j( J2/ou .5j)

Luis Mendo
fonte
2

Geléia , 26 bytes

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

Experimente online!

-2 bytes graças a caird coinheringaahing
-2 bytes graças a Erik the Outgolfer

Explicação

’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
fonte
Você pode remover o []por 2 bytes
Caird coinheringaahing
@cairdcoinheringaahing thanks!
HyperNeutrino 24/09
1
Golfe um par fora.
Erik the Outgolfer
2

Python 2 , 134 bytes

g=lambda n,k=1:n and g(n-(lambda l:all(abs(a-b)<1.2for a,b in zip(l,l[1:])))([~-d%3+~-d/3*1j-d/~d*1.5for d in map(int,`k`)]),k+1)or~-k

Experimente online!

Lynn
fonte
Ao definir fe usá-lo uma vez , você pode incorporá-lo e salvar dois bytes .
Jonathan Frech 25/09
1

Mathematica, 249 234 202 bytes

(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)&


Experimente online!

agradece user202729 por compactar dados (-32 bytes)

Meus resultados:

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

J42161217
fonte
Eu acho que você pode compactar os dados usando IntegerDigits:, IntegerDigits/@{210,4210,53210,632,7541,86542,9653,874,9875,986}e use FreeQ, Truse em Dovez de For, use notação infix para AppendToe use em Dovez de Whilerepetir Tr[1^s]vezes, também elimine a variável p. Além disso, você não provou que o algoritmo está correto, ou seja, o número resultante é sempre menor que seu índice ao quadrado, o que é necessário para validar uma resposta.
user202729
1
@ user202729 Alterei muitas coisas. Minha resposta é definitivamente válida. Vou comprimir os dados agora.
J42161217
por que o voto negativo?
precisa saber é o seguinte
1

PHP, 124 + 1 bytes

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;

Execute como pipe -nRou experimente online .

Titus
fonte
0

Java 8, 192 190 bytes

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

Retorna o número (indexado 1) nna sequência.

Isso foi surpreendentemente mais difícil do que eu pensava .. Provavelmente apenas tendo alguns peidos cerebrais esta tarde ..

Explicação:

Experimente aqui.

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
Kevin Cruijssen
fonte