Genera numeri compatibili con Numpad


22

Ispirato da Genera numeri compatibili con la tastiera .

sfondo

Molti tastierino numerico hanno il seguente layout:

789

456

123

    0    

Definiamo il vicinato di un numero come l'insieme di celle ortogonalmente adiacenti sul tastierino numerico mostrato, incluso se stesso. Ad esempio, il quartiere 2 è {1,5,3,0,2}e il quartiere 0 è {1,2,0}. Di seguito è riportato un elenco dei quartieri di ciascun numero, sopra i casi di test.

Definiamo un numero amico del tastierino numerico come un numero intero positivo in cui, quando è scritto in decimali senza zero iniziale, ogni cifra tranne la prima si trova nelle vicinanze della cifra precedente.

Per esempio,

  • 7856 è un numero amico del tastierino numerico perché 8 è nel quartiere di 7, 5 è nel vicinato di 8 e 6 è nel quartiere di 5.
  • 1201 è un numero amico del tastierino numerico perché 2 è nel quartiere di 1, 0 è nel quartiere di 2 e 1 è nel quartiere di 0.
  • 82 non è un numero amico del tastierino numerico perché 2 non è in prossimità di 8.
  • 802 non è un numero adatto al tastierino numerico perché 0 non è nel vicinato di 8 (i quartieri non vanno a capo).

Sequenza OEIS correlata . Si noti che questa sequenza correlata è distinta perché conta 0come adiacente 7invece di 1e 2.

Sfida

Dato un numero intero positivo n, restituisci il n-th o il primo nnumero amichevole del tastierino numerico, dove il primo è 1. Puoi usare l'indicizzazione basata su 0, dove il 0 ° numero amichevole del tastierino numerico sarebbe 1.

quartieri

Il quartiere di ogni cifra è elencato qui:

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}

Casi di prova / sequenza

Questi sono i primi 100 termini

[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]

5
Mi piace come questa sfida consideri solo numeri interi positivi (che mantengono l'essenza e consentono a più lingue di partecipare) e consentono di visualizzare la n -esima o la prima n uscita per flessibilità
Luis Mendo,

Ho letto male la sfida, ecco uno script "è questo termine valido nella sequenza": provalo online!
Magic Octopus Urn,

Risposte:


9

JavaScript (ES6), 104 93 89 88 byte

Restituisce il termine N-esimo della sequenza, 1 indicizzato.

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)

dimostrazione


Il migliore che potrei ottenere è 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-1forse qualcosa che aiuta, il mio test è probabilmente troppo lungo
Conor O'Brien,

Questa risposta porta il concetto di numeri magici a un livello completamente nuovo ... Non capisco nemmeno come li hai trovati o_O
scottinet,

2
@scottinet In larga misura, la mia spiegazione per questa risposta si applica anche a questa. La differenza assoluta non ha funzionato molto bene su quello, quindi ho provato con XOR. Come nota a margine, ho trovato un'altra formula che ha funzionato nel 96% dei casi senza la necessità di una maschera di bit di ricerca. Ma elaborare il restante 4% separatamente era troppo costoso in JS. Non ho provato a Jelly , e ora non ricordo comunque la formula ... ¯ \ _ (ツ) _ / ¯
Arnauld

Grazie per le spiegazioni Questo è ancora impressionante :-)
scottinet,

4

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

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

Provalo online!


3

Gelatina , 27 24 byte

Restituisce gli N primi termini della sequenza.

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

Provalo online!

Questa è una porta della mia risposta 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

3

05AB1E , 24 23 byte

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

Provalo online!

Restituisce l'ennesimo numero nella sequenza.

spiegazioni:

µ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

L'idea principale è che, a parte la 0chiave, qualsiasi cifra decrementata e convertita in base 3 ha le seguenti proprietà:

  • i vicini sinistro e destro hanno una differenza assoluta di 1
  • i vicini su e giù hanno una differenza assoluta di 10 che, al contrario, è convenientemente uguale a 1
  • qualsiasi altra coppia di tasti del tastierino numerico genera valori diversi, anche se invertiti

Naturalmente abbiamo bisogno di ifun'istruzione per gestire il 0tasto del tastierino numerico.


Risposta solida, arrivata per offrire ulteriori miglioramenti, non riesco a trovarne. Oooo ... e anche questo ti ha portato in testa anche tu :).
Magic Octopus Urn,

Non credo che sarei stato in grado di inventare quelle 3 regole, piuttosto impressionanti; cosa ti ha dato l'idea?
Magic Octopus Urn,

2

MATL , 29 27 byte

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

Emette i primi nnumeri compatibili con il tastierino numerico.

Provalo online!

Spiegazione

Ogni cifra da 1a 9è codificata come un numero complesso che rappresenta la sua posizione nel tastierino numerico, usando in una griglia step-2, dove la parte reale rappresenta la posizione verticale e la parte immaginaria rappresenta la posizione orizzontale. Così 1è 0+0j, 2è 0+2j, 3è 0+4j, 4è 2+0j, ... 9è 4+4j.

La cifra 0è codificata come 0+1j, cioè come se fosse posizionata esattamente tra 1e 2.

Per ciascun numero del tastierino numerico-friendly candidato, una conversione base "decimale" viene applicato impiegando il suddetto numeri complessi invece delle cifre 0, 1..., 9. Ciò fornisce un array, di cui vengono calcolate le differenze assolute consecutive. Il numero del candidato è compatibile con il tastierino numerico se e solo se tutte le differenze assolute sono al massimo 2(ovvero il passo della griglia). In tal caso, il numero viene lasciato in pila.

Il codice utilizza un ciclo do... while, che esce quando la quantità di numeri nello stack è uguale all'input n.

Una griglia unitaria sarebbe stata una scelta più naturale. Cifre 1, 2e 0sarebbe quindi conforme a 0+0j, 1+0je 0.5+0jrespecrively. Ma è più golfoso usare una griglia step-2, perché moltiplicare per 2(funzione E) e spingere 0+1j(funzione J) è più corto di un byte rispetto a spingere 0+0.5j( J2/o .5j)


2

Gelatina , 26 byte

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

Provalo online!

-2 byte grazie al cauto coinheringaahing
-2 byte grazie a Erik the Outgolfer

Spiegazione

’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

È possibile rimuovere il []per 2 byte
caird coinheringaahing

@cairdcoinheringaahing grazie!
HyperNeutrino,



1

Mathematica, 249 234 202 byte

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


Provalo online!

grazie user202729 per la compressione dei dati (-32 byte)

I miei risultati:

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


Penso che puoi comprimere i dati usando IntegerDigits:, IntegerDigits/@{210,4210,53210,632,7541,86542,9653,874,9875,986}e usa FreeQ, Trusa Doinvece di For, usa la notazione infix per AppendToe usa Doinvece di Whileripetere i Tr[1^s]tempi, anche eliminare la variabile p. Inoltre non hai dimostrato che l'algoritmo sia corretto, ovvero il numero risultante è sempre inferiore al suo indice quadrato, che è necessario per rendere valida una risposta.
user202729

1
@ user202729 Ho cambiato molte cose. La mia risposta è sicuramente valida. Comprimo i dati ora.
J42161217

perché il downvote?
J42161217

1

PHP, 124 + 1 byte

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;

Esegui come pipe con -nR o provalo online .


0

Java 8, 192 190 byte

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

Restituisce il numero (1-indicizzato) nnella sequenza.

Questo è stato sorprendentemente più difficile di quanto pensassi .. Probabilmente solo un po 'di scoregge cerebrali questo pomeriggio ..

Spiegazione:

Provalo qui.

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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.