Crea una lista de números de serpiente menores de 50,000

24

Snaking Number Challenge

Me pregunto cuántos números serpientes hay entre 1 y 50,000.

Serpiente en un Nokia

Los números serpientes, en este juego, son números que se pueden escribir en un teclado numérico tradicional (formato a continuación) moviendo una tecla hacia arriba, hacia abajo, hacia la izquierda o hacia la derecha.

7 8 9
4 5 6
1 2 3
 0

Por ejemplo, si comienza con el número 5, puede seleccionar 4, 6, 8 o 2 como su próximo movimiento válido; sin embargo, 7, 3, 9 y 1 están fuera de los límites, ya que se colocan en diagonal a la tecla actual . Entonces, si tiene 5, entonces 2, sus próximas opciones clave viables son 0, 1, 3 o 5 nuevamente.

En este ejercicio de Code Golf, debe generar una lista de todos los números positivos entre 1 y 50k, junto con un recuento final de todos los números que cumplen con el criterio.

Reglas

  1. Los números no pueden comenzar con un cero.
  2. Los números deben ser enteros enteros positivos.
  3. Cada número consecutivo, leído de izquierda a derecha, debe "serpentear" alrededor del teclado numérico.
  4. La serpiente no puede viajar diagonalmente a través de las teclas.
  5. Se puede acceder al número 0 desde los números 1 y 2
  6. Los números no se pueden emparejar (p. Ej .: 22)

Ejemplos de números serpientes válidos:

12369
45201
1254
10102
1
12
987

Ejemplos de números inválidos

1238 - 8 is not connected
0001 - multiple leading 0s
0101 - leading 0
159  - snake cannot travel diagonally
4556 - duplicate 5

Según Code Golfs normales, ¡el objetivo es la menor cantidad de bytes!

De acuerdo con mis matemáticas y reglas, debe tener 670 números válidos de serpiente en su lista, más 670 impresos como el último número.

MightBeAlon
fuente
2
¿Se debe ordenar la salida? ¿O está permitido en cualquier orden?
tsh
2
Como nos está pidiendo que generemos un conjunto fijo y finito de enteros, sugiero incluir la lista completa en la especificación.
Shaggy
Relacionado
Arnauld
44
Este es un subconjunto de A215009 .
bigyihsuan
¿Estaría bien imprimir 670 primero ?
dana

Respuestas:

14

K (ngn / k) , 60 57 bytes

(x;#x:{*/1=3!5&+/x*x:+1_-':(+0 1,'2*!3 3)@10\x}#1+!50000)

Pruébalo en línea!

!50000lista de 0..49999

1+ agregue 1 a todos

{ }# filtrar con la función en { }

10\x dígitos decimales del argumento

( )@ utilizar como índices en ...

  • !3 3 un par de listas: (0 0 0 1 1 1 2 2 2;0 1 2 0 1 2 0 1 2)

  • 2* multiplica todo por 2

  • 0 1,'anteponer 0a la primera lista y 1a la segunda

  • +transposición (par de listas -> lista de pares). esto nos da los botones de botones aprox.

-':restar de cada par el par anterior. utilizar 0 0como elemento imaginario antes del primero.

1_ soltar el primero

+ transponer

x*x:cuadrado (asignar xy multiplicar por x). Aquí xhay un par de listas: ∆xs y ∆ys

+/ suma las dos listas (elemento por elemento)

5& min con 5

3! mod 3

1= lista booleana de donde es igual a 1

*/ producto (booleano "y")

(x;#x: )hacer un par del resultado y la longitud ( #) del resultado

ngn
fuente
9

Jalea ,  24  23 bytes

5ȷ4µDo1.’d3ZIASĊ’ẸµÐḟṄL

Un programa completo que imprime una lista de todos los resultados y luego el número de resultados.

Pruébalo en línea!

¿Cómo?

5ȷ4µDo1.’d3ZIASĊ’ẸµÐḟṄL - Main Link: no arguments
5ȷ4                     - 5*10^4 = 50000
   µ              µÐḟ   - filter discard those for which this is truthy:
                        -                  e.g.: 8520        ... or           4559 
    D                   -   decimal digits       [8,5,2,0]                    [4,5,5,9]
      1.                -   literal 1.5
     o                  -   logical OR           [8,5,2,1.5]                  [4,5,5,9]
        ’               -   decrement            [7,4,1,0.5]                  [3,4,4,8]
         d3             -   div-mod by 3         [[2,1],[1,1],[0,1],[0,0.5]]  [[1,0],[1,1],[1,1],[2,2]]
           Z            -   transpose            [[2,1,0,0],[1,1,1,0.5]]      [[1,1,1,2],[0,1,1,2]]
            I           -   deltas               [[-1,-1,0],[0,0,-0.5]]       [[0,0,1],[1,0,1]]
             A          -   absolute value       [[1,1,0],[0,0,0.5]]          [[0,0,1],[1,0,1]]
              S         -   sum (vectorises)     [1,1,0.5]                    [1,0,2]
               Ċ        -   ceiling              [1,1,1]                      [1,0,2]
                ’       -   decrement            [0,0,0]                      [0,-1,1]
                 Ẹ      -   any?                 0 (i.e. keep)                1 (i.e. discard)
                     Ṅ  - print and yield
                      L - length
                        - implicit print
Jonathan Allan
fuente
Me encantaría saber cómo funciona este. ¿Alguna posibilidad de que puedas dar un desglose?
MightBeAlon
1
@MightBeAlon lo hará más tarde ...
Jonathan Allan
Tengo curiosidad, ¿cómo se 1.evalúa 1.5?
Encarnación de la ignorancia
@EmbodimentofIgnorance durante el análisis literal de un dígito faltante después de un período se trata como un cinco. Vea la cláusula final de parse_literal en interpreter.py
Jonathan Allan
7

Python 3 , 140 bytes

f=lambda s:''==s[1:]or s[1]in'10021234562216565878 43 749 9   5  8'[int(s[0])::10]and f(s[1:])
print(*filter(f,map(str,range(1,50000))),670)

Pruébalo en línea!

Estoy seguro de que alguien podrá hacer esto con una expresión en lugar de una cadena de búsqueda.

Jitse
fuente
7

Python 2 , 101 bytes

print[n for n in range(1,50000)if all(`n`[i:i+2]in`0x20b33ec8bc49a10589e76b15`for i in range(4))],670

Pruébalo en línea!

El número hexadecimal es decimal 10120214525632365878969854741, que codifica cada par ordenado de dígitos que pueden aparecer adyacentes entre sí.

siete negativo
fuente
5

JavaScript (V8) ,  112106104  bytes

Guardado 2 bytes gracias a @NahuelFouilleul

Un programa completo

for(n=0;++n<5e4;)[...n+''].every(x=>'6589632145201478'.match(x+p+'|'+p+(p=x)),p='')&&print(n)
print(670)

Pruébalo en línea!

O 96 bytes si podemos generar los números en orden inverso:

for(n=5e4;n--;)[...n+''].every(x=>'6589632145201478'.match(x+p+'|'+p+(p=x)),p='')&&print(n||670)

Pruébalo en línea!

Arnauld
fuente
también funciona eliminando el último 3quizás porque 36ya está en cadena
Nahuel Fouilleul
@NahuelFouilleul Buena captura. ¡Gracias!
Arnauld
1
también 6589632145201478es un byte más corto
Nahuel Fouilleul
4

Stax , 37 35 bytes

ü╞╡~▄ⁿ♪eµïê◙ü╔ï▼ΔJr¥æ≤PH╟♀I♣Δz8─¶Γ╞Ç▓

¡Ejecútelo y depúrelo en staxlang.xyz!

Fue tan agradable y breve, hasta que no lo fue.

Desempaquetado (42 bytes) y explicación

49999{E2B{{om"#qYY>!(AFI"%A|E2B{{om-C_Qf%p
49999{                                 f      Filter range [1..49999]:
      E2B                                       All adjacent pairs of digits
         {{om                                   Each sorted
             "#qYY>!(AFI"%A|                    Literal 2012365478963258741
                            E2B{{om             Pairs of digits, each sorted
                                   -            Set difference
                                    C           Cancel block execution if any remain
                                     _Q         Print current value
                                        %p    Print length

2012365478963258741 codifica el teclado. Mira los pares de dígitos adyacentes. Quizás si pudiera obtener una alternativa decentemente corta que vaya en ambas direcciones para cada par, podría cortar los ocho bytes de{{om .

Sin ese 670 final, un simple filtro sería suficiente: en f..!lugar de {..C_Qf%p. Puede haber una mejor manera de manejar esta irregularidad. En cualquier caso, este comportamiento de rango de filtro no está documentado.

Khuldraeseth na'Barya
fuente
Perdón por la falta de documentación. FWIW, ese estará en la próxima versión, 1.1.7. Puedes ver una vista previa en stax.tomtheisen.com , pero es un secreto, así que no se lo digas a nadie. ;)
recursivo el
3

PHP , 145 bytes

for(;$i++<5e4;$f&&print$i._)for($f=1,$l=b;''<$d=("$i")[$$i++];$l=$d)$f&=$l>a||strstr([12,240,1053,26,157,2468,359,48,579,68][$l],$d)>'';echo 670;

Pruébalo en línea!

Para cada número del 1 al 50,000, verifica cada dígito de ese número de izquierda a derecha. Si todos los dígitos están en la lista de dígitos válidos del dígito anterior, ese número se imprime. Al final imprime un 670 codificado, ya que toma menos bytes de los que realmente lo cuenta.

Noche2
fuente
3

05AB1E , 23 bytes

ŽÅKLʒSÌYX;:3‰üαï€OP}=g=

Pruébalo en línea!

Port of Jonathan Allan's Jelly respuesta .

Mugriento
fuente
1
Ah, inteligente de simplemente comprimir el 50000 en 3 bytes. Estaba usando ₄50*o 4°5*cuando estaba haciendo un intento antes. Y al principio estaba confundido por qué lo tenía en €OPlugar de solo OP, pero luego me di cuenta de que los números de un solo dígito (que es una lista vacía después de üα) serían en [] → 0 → 0lugar de [] → [] → 1. :)
Kevin Cruijssen
1
@KevinCruijssen ¿Por qué 4°5*cuando puedes 5°;? Aunque me gusta más ZAK. Y sí, ese caso límite para números de un solo dígito es una molestia.
Grimmy
3

Perl 5 ( -M5.01), 96 , 92 bytes

-4 bytes gracias a @Xcali

$r=join"|",map$t++."[^$_]",12,240,1350,26,157,2648,359,48,579,68;map/$r/||say,1..5e4;say 670

TIO

Nahuel Fouilleul
fuente
92
Xcali
gracias de hecho, demasiado complicado porque la primera respuesta fue una coincidencia positiva
Nahuel Fouilleul
3

JavaScript (SpiderMonkey) , 179 173 151 129 bytes

[12,240,1350,26,157,2468,359,48,579,68].map((_,i,l)=>i&&(f=(v,t)=>print(v)|v<5e3&&[...l[t]+''].map(k=>f(v+k,k)))(i,i)),print(670)

Pruébalo en línea!

-22 bytes gracias a Arnauld -22 bytes gracias a dana

explicación:

[12,240,1350,26,157,2468,359,48,579,68] 
// an array where keys are current position and values, the possible destinations
.map((_,i,l)=>                    // loop over it
    i&&(                          // if key is not 0
        f=(v,t)=>                 // create a function
                 print(v)|        // which print the value
                          v<5e3&& // and if the limit is not attained
                                 [...l[t]+''].map(k=>f(v+k,k)) 
                    // recurcively call itself with for each destinations
                                                              )(i,i)),
                    // make the first call with each digit
print(670) // finally print 670

@dana también dio una solución de 123 bytes si podemos imprimir 670 primero

[21,420,5310,62,751,8642,953,84,975,86].map((_,i,a)=>(f=(v,t)=>print(i?v:640)|i&v<5e3&&[...a[t]+''].map(k=>f(v+k,k)))(i,i))
jonatjano
fuente
@Arnauld gracias, olvidé esta regla
jonatjano
129 ?
dana
123 si 640 se puede imprimir primero.
dana
2

Ruby , 99 bytes

1.upto(5e4){|n|w,*x=n.digits;x.all?{|d|[6,21,43,68,162,340,552,272,672,320][w][w=d]>0}&&p(n)}
p 670

Pruébalo en línea!

GB
fuente
2

Stax , 28 26 bytes

Δh┤♣É╦&·é╝n$K»à¶▲v═NÆ;↨m≥8

Ejecutar y depurarlo

Desempaquetado, sin golf y comentado, se ve así.

G               Call to unbalanced trailing '}', then resume here
670P            Print 670
}               Call target
219J            219 squared (47961)
f               Filter 1-based range by the rest of the program; implicitly output
  $2B           Convert to string and get adjacent pairs; e.g. 213 -> ["21", "13"]
  O             Push 1 under list of pairs
  F             Iterate over pairs, using the rest of the program
    o           Order each pair; e.g. "21" -> "12"
    "{<f:[/T8Z" string literal with code points [123 60 102 58 91 47 84 56 90]
    $           concate as string i.e. "12360102589147845690"
    s#          How many times does the current pair appear in the constant string?
    *           Multiply this by running total.  Any zero will cause the result to be zero.

Ejecute este

La salsa secreta está en la cadena literal "{<f:[/T8Z". Después de atascar todos los puntos de código juntos, obtienes 12360102589147845690. Los pares ascendentes en esta cadena son los movimientos válidos de la serpiente.

recursivo
fuente
1
15JJen lugar de 219Jfuncionaría bien, pero no creo que pueda jugar ningún byte desde allí a menos que haya una constante de 1 byte para 15.
Arnauld
2

Haskell , 118 bytes

(filter(and.(zipWith elem.tail<*>map f).show)[1..50000],670)
f c=words"12 024 0135 26 157 2468 359 48 579 68"!!read[c]

Pruébalo en línea!

Un primer pase; No soy bueno en compresión.

El s=no cuenta, ya que en realidad no necesitamos vincular el resultado.

Código sin golf .

col
fuente
1

Carbón , 42 bytes

≔ΦI…·¹×⁵⁰φ⬤ι№”)¶∧XRτ_ΠGêR⁵m⎇λ”✂ιμ⁺²μ¹θθILθ

Pruébalo en línea! El enlace es a la versión detallada del código. Explicación:

≔ΦI…·¹×⁵⁰φ

Procesar el rango inclusivo de 1al 50,000elenco de cadena.

⬤ι№”)¶∧XRτ_ΠGêR⁵m⎇λ”✂ιμ⁺²μ¹θ

Filtre los que tienen pares de dígitos no contenidos en la cadena comprimida 01478963202125458565236987410.

θILθ

Salida de la matriz restante y su longitud.

Neil
fuente
1

Perl 6 , 64 bytes

{670,grep {[+&](:36<12HGX91H8VCL3MG0FDVQ>X+>m:ov/../)%2},1..5e4}

Pruébalo en línea!

Explicación

{670,grep {...},1..5e4}  # Meet questionable output requirements

# Actual decision problem

     :36<12HGX91H8VCL3MG0FDVQ>  # Bit field of allowed transitions
                                # encoded in base 36
                                 m:ov/../  # All 2-digit substrings
                              X+>  # Right shift by each substring
                                   # (implicitly converted to an integer)
[+&](                                    )  # Binary and
                                          %2  # Modulo 2
nwellnhof
fuente
Es una pena que ~>aún no se haya implementado, de lo contrario, podría hacerlo solo con operadores de cadena, con el campo de bits como una cadena
Jo King
1

Pyth , 68 65 45 bytes

l
f.Am}dCtB+J`65874589632012541_PJCtB`TS50000

Pruébalo en línea!

La inspiración para el proceso de búsqueda revisado vino de la respuesta Stax de Khuldraeseth na'Barya, ¡dales un voto positivo !


Edición 2: reescrito para guardar un montón de bytes, versión anterior:

l
f.Am}ed@c"12 024 0135 26 157 2468 359 48 579 68";shdCtB`TS50000

Editar: Golfed 3 bytes mediante búsquedas de cadenas, versión anterior:

l
f.Am}ed@sMMc"12 024 0135 26 157 2468 359 48 579 68";hdCtBjT;S50000
Sok
fuente