Números de caballero de un teclado numérico


33

Para los dígitos distintos de cero en un teclado numérico estándar

789
456
123

considere colocar un caballero de ajedrez en cualquier dígito y moverlo con cualquier número de saltos normales en forma de L, trazando un entero decimal positivo. ¿Qué enteros positivos se pueden expresar de tal manera?

Una de ellas es 38, ya que el caballero podría comenzar 3y moverse hacia la izquierda y hacia arriba 8. 381Y 383también son posibles.

3en sí es posible si no se realizan saltos (lo cual está permitido). 5también, pero no se puede llegar a otros dígitos desde 5, por lo que es el único número donde 5aparece el dígito .

Escriba un programa o función que tome un entero decimal positivo (puede tomarlo como una cadena si lo desea) e imprime o devuelve un valor verdadero si el número puede ser expresado por un caballero en un teclado numérico de la manera descrita, pero de lo contrario se genera un Falsy valor.

El código más corto en bytes gana. Tiebreaker es la respuesta anterior

Ejemplos

Verdad:

1, 2, 3, 4, 5, 6, 7, 8, 9, 16, 18, 38, 61, 81, 294, 349, 381, 383, 729, 767, 38183, 38383, 18349276, 183492761, 618349276

Falsy

10, 11, 50, 53, 55, 65, 95, 100, 180, 182, 184, 185, 186, 187, 188, 189, 209, 305, 2009, 5030, 3838384, 4838383, 183492760

2
¿Qué pasa con los caballeros de ajedrez hoy ? :-D
Luis Mendo

1
Sugerencia: si escribe los números como una línea de ajuste, entonces el caballero siempre salta cuatro espacios en el sentido de las agujas del reloj o cuatro espacios en sentido contrario. No sé si esto es útil.
Financia la demanda de Mónica el

3
Envoltura de @LuisMendo. Como en, si se trata es como una lista interminable de 78963214, repetida una y otra vez. Cuente las distancias: siempre son cuatro, de una forma u otra. Debería haber sido más claro y decir explícitamente que tienes que escribirlo en orden de círculo.
Fondo de la demanda de Mónica

@QPaysTaxes Oh, pensé que querías decir círculo pero 123...9. Lo siento
Luis Mendo

@LuisMendo No se preocupe. Como dije, debería haber sido más claro sobre lo que quise decir.
Fondo de la demanda de Mónica

Respuestas:


16

Jalea, 19 15 14 bytes

Doȷ’d3ạ2\P€=2P

Pruébalo en línea! o verificar todos los casos de prueba .

Cómo funciona

Doȷ’d3ạ2\P€=2P  Main link. Argument: n (integer)

D               Convert n to base 10 (digit array).
  ȷ             Yield 1000.
 o              Logical OR. This replaces each 0 with 1000.
   ’            Decrement each digit.
    d3          Divmod; replace each digit k with [k:3, k%3].
      ạ2\       Pairwise reduce by absolute difference.
                For each pair of adjacent digits [i, j], this computes
                [abs(i:3 - j:3), abs(i%3 - j%3)].
         P€     Compute the product of each result.
                n is a Numpad's Knight Number iff all products yield 2.
           =2   Compare each product with 2.
             P  Multiply the resulting Booleans.

18

Python 2, 52 bytes

f=lambda n:n<6or`n%100`in'18349276167294381'*f(n/10)

Comprueba que dos dígitos consecutivos están en la cadena '18349276167294381'. Para obtener dígitos consecutivos, en lugar de hacerlo zip(`n`,`n`[1:]), la función verifica repetidamente los dos últimos dígitos y elimina el último dígito.


13

Retina , 58 40 bytes

Gracias a Sp3000 por sugerir esta idea:

M&!`..
O%`.
A`16|18|27|29|34|38|49|67
^$

Pruébalo en línea!(Ligeramente modificado para ejecutar todo el conjunto de pruebas a la vez).

Impresiones 1para la verdad y0 resultados falsos.

Explicación

M&!`..

Encuentre todas las coincidencias superpuestas de .., es decir, todos los pares consecutivos de dígitos, y únalas con saltos de línea.

O%`.

Ordena los dígitos en cada línea, de modo que solo necesitemos verificar la mitad de los pares.

A`16|18|27|29|34|38|49|67

Elimine todas las líneas que corresponden a un movimiento válido.

^$

Cuenta los partidos de esta expresión regular. Es decir, si se eliminaron todas las líneas, esto coincide con la cadena vacía resultante una vez, de lo contrario, no coincide y da cero en su lugar.



7

Ruby, 57 bytes

Función anónima. El argumento es una cadena.

->n{(0..n.size).count{|i|!"16729438183492761"[n[i,2]]}<1}

Programa con el conjunto de pruebas:

f=->n{(0..n.size).count{|i|!"16729438183492761"[n[i,2]]}<1}

a=%w{1 2 3 4 5 6 7 8 9 16 18 38 61 81 294 349 381 383 729 767 38183 38383 18349276 183492761 618349276
10 11 50 53 55 65 95 100 180 182 184 185 186 187 188 189 209 305 2009 5030 3838384 4838383 183492760}

a.each {|e|p [e, f[e]]}

Acabo de codificar todos los movimientos posibles de caballeros en una cadena y verifiqué si cada 2 dígitos dentro de la entrada existían en esa cadena.


Oh, esa cadena de búsqueda también me ahorraría 17 bytes. ¿Te importa si uso eso para mi respuesta de Retina?
Martin Ender

¡Ve a por ello! Solo dale crédito, supongo.
Value Ink el

Gracias, pero terminé con una solución aún más corta basada en una sugerencia de Sp3000 :)
Martin Ender

6

grep 58 bytes

grep "^((?=18|16|29|27|34|38|49|43|61|67|72|76|81|83|94|92).)*.$"

Porque realmente, si no puedes vencer a grep ...


2
Ni 5tampoco 185emiten 1con su línea de comandos, mientras que 5está en el Truthy, y 185en la lista Falsy.
Guntram Blohm apoya a Monica el

1
@GuntramBlohm solucionado - se perdió en una negación regular
Yakk

6

Haskell 46 bytes

q=zip<*>tail
all(`elem`q"16729438183492761").q

Ejemplo de uso: all(`elem`q"16729438183492761").q $ "183492761" ->True

Cómo funciona: utiliza la cadena de búsqueda que se encuentra en la respuesta de @Kevin Lau . qhace una lista de pares de caracteres adyacentes de una cadena, por ejemplo q "1672" -> [('1','6'),('6','7'),('7','2')]. La función devuelve verdadero si todos los pares de la entrada aparecen en los pares de la cadena de búsqueda. qconvierte entradas de un solo dígito en la lista vacía, por lo que elemsiempre tiene éxito.


¿Por qué zip<*>tailfunciona como una versión invertida de zip=<<tail? Creo que no entiendo qué generalizan los solicitantes.
xnor

@xnor: Solo lo uso. <*> se define como (<*>) f g x = f x (g x) .
nimi

6

JavaScript (ES6), 65 62 bytes

s=>[...s].every((c,i)=>!i|"16729438183492761".match(s[i-1]+c))

Devuelve verdadero o falso. Anteriormente probé una solución recursiva, que toma 63 bytes, mape incluso, reducepero me tomaron 73 bytes.

Editar: Guardado 3 bytes gracias a @ user81655.


No podría hacerlo mejor, mi mejor intento fue en 88 bytes. ¡Bravo!
Naouak

@ user81655 Te refieres a que matchfunciona en lugar de ~search(pero de cualquier manera, eso es realmente sencillo) y |puede reemplazar ||(pero no en la versión recursiva, lamentablemente).
Neil

@ user81655 Me refería a la forma en que !i|...matchfunciona porque el resultado de la coincidencia, si tiene éxito, es una matriz de una sola cadena de dos dígitos, que el |operador termina convirtiendo en un entero válido.
Neil

@Neil Ah, cierto.
user81655

6

C, 85 81 bytes

Golfizado:

i;f(char*b){i=*b++-49;return*b?(*b=="8749x7214"[i]||*b=="6983x1632"[i])&&f(b):1;}

Antigua versión no recursiva (85 bytes):

i;f(char*b){for(;(i=*b++-49),*b&&*b=="8749x7214"[i]||*b=="6983x1632"[i];);return!*b;}

Código antiguo con espacios en blanco y programa principal:

i;
f(char*b){
    for (; (i=*b++-49), *b     // i = index of digit + 1 in following arrays
        &&*b=="8749x7214"[i]   // 1st possible jump for 1..9
        ||*b=="6983x1632"[i];  // 2nd possible jump for 1..9
    );
    return !*b;
}

main(){
    char b[16];
    while(scanf("%s", b) == 1) printf("%d",f(b));
    return 0;
}

Esto acepta números delimitados por espacios a través de la entrada estándar y las salidas 0 si no-numpad-knight, o 1 de lo contrario.

La nueva versión recursiva de 81 bytes ahorra 4 bytes.


5

MATL , 38 37 29 bytes

Esto utiliza la idea @QPaysTaxes .

I:8JK5:7Pvj!Uttnqh?)d|2:EQm}h

La salida es una matriz 2D, compleja, no vacía. Es verdad si todos sus valores tienen una parte real distinta de cero, y falsa de lo contrario.

Pruébalo en línea!


1
¿Esto está permitido?
CalculatorFeline

La pregunta pide una Truthy o un valor Falsy, no una matriz entera.
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳

2
@CatsAreFluffy Esta es nuestra definición de verdad / falsedad. Como en MATLAB / Octave, las matrices son verdaderas en MATL si todos sus elementos son verdaderos. ( ejemplo )
Dennis

CC @ n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳
Dennis


4

MATL, 25 24 33 26 bytes

¡Afeitado 1 byte gracias a @LuisMendo!
@Dennis encontró un error y luego lo solucionó. ¡Gracias!

'bSVYXbTUZW'j47-)d2^48\1=A

Toma un entero como entrada. Salidas 1/0.

Pruébalo en línea!


@LuisMendo Correcto en ambos aspectos, ¡gracias!
vaso de precipitados

@Dennis Actualizado, y con suerte correcto. Gracias por tu ayuda.
vaso de precipitados

No creo que necesites el Aal final. Los vectores de MATL son verdaderos si no contienen un 0.
Dennis

4

C, 140 92 bytes

c;L(char*i){while(*i&&(!c||*i=="6743x1212"[c-49]||*i=="8989x7634"[c-49]))c=*i++;return !*i;}

Asumiendo ASCII

Detallado Pruébalo aquí

// valid transition from x to n[x-'1'][0 or 1]

int n[9][2] =
{
    {'6','8'},{'7','9'},{'4','8'},
    {'3','9'},{'x','x'},{'1','7'},
    {'2','6'},{'1','3'},{'2','4'}
};

// i is a pointer to where to start on a string

bool L(char * i)
{
    char c = 0;

    // move if not \0 and (not-first-char or is a valid move)

    while((*i) && (!c || (*i)==n[c-'1'][0] || (*i)==n[c-'1'][1]))
    {
        c = (*i++);
    }

    return !(*i); // success if it's \0
}

esas tablas de búsqueda son enormes. Puede mejorar mucho su puntaje si se deshace de todos los delimitadores {,}[]y lo codifica como una char*cadena. Además, tenga en cuenta que #defineno es rentable cuando lo usa solo dos veces: eliminarlo le ahorrará 4 bytes.
tucuxi

@tucuxi gracias por los consejos, logré reducirlo a 92, ya que \0dentro de la matriz causó un comportamiento indefinido, así que lo reemplacé conx
Khaled.K

Agradable: también, no olvide usarlo <s>oldscore</s> newscorecuando edite para reflejar mejoras en la puntuación, y <!-- language-all: lang-c -->antes de que su código comience a corregir el resaltado de sintaxis. También me las arreglé para reducir un poco mi recuento de bytes dejando caer el bucle por completo
tucuxi

Su 'detallado' se ve muy diferente de una simple expansión del código de golf (¿dónde está nen la versión corta?). Además, probablemente deba mencionar que está asumiendo la codificación ASCII: obtendrá números diferentes en las máquinas EBCDIC.
Toby Speight

@TobySpeight se supone que la versión detallada muestra cómo se construyó básicamente, sí, supongo que ASCII es el caso común en C.
Khaled.K

3

Julia, 51 49 bytes

n->diff(["@1634@8725"...][digits(n)+1]).^2%48⊆1

Verificación

julia> f=n->diff(["@1634@8725"...][digits(n)+1]).^2%48⊆1
(anonymous function)

julia> all(map(f,(1,2,3,4,5,6,7,8,9,16,18,38,61,81,294,349,381,383,729,767,38183,38383,18349276,183492761,618349276)))
true

julia> any(map(f,(10,11,50,53,55,65,95,100,180,182,184,185,186,187,188,189,209,305,2009,5030,3838384,4838383,183492760)))
false

3

En realidad, 30 bytes

;#pXZdX`Σ"67294381";'1+R+íu`Mπ

Toma la entrada como una cadena. Emite un entero positivo para verdadero y 0 para falso.

Pruébalo en línea!

Explicación:

;#pXZdX`Σ"67294381";'1+R+íu`Mπ
                                 (implicit) push input
;#pXZdx                         push zip(n[:-1], n[1;]) (pairs of digits)
       `Σ"67294381";'1+R+íu`M   map:
        Σ                         join digits
         "67294381";'1+R+         push "16729438183492761" (the magic string used in many other solutions)
                         íu       0-based index (-1 if not found), increment so 0 is not found and >=1 is the 1-based index
                             π  product

3

PowerShell v2 +, 105 96 bytes

param($a)((1..$a.length|%{'27618349294381672'.IndexOf($a[$_-1]+$a[$_])+1})-join'*'|iex)-or$a-eq5

Itera a través de la entrada (que debe encapsularse con "") al verificar que el índice de cualquier par secuencial de caracteres está en la cadena de búsqueda válida. Veo que Kevin Lau tenía algo similar , pero se me ocurrió esto de forma independiente. Se agrega cada uno de esos índices +1, ya que la .IndexOf()función volverá -1si no se encuentra la cadena. Esto convertirá "no encontrado" en0 .

Luego, -jointodos los valores enteros resultantes con *y canalizamos eso a iex(similar a eval). Esto significará que si alguno de los índices no se encuentra, la expresión completa resultará en 0. Eso está encapsulado en parens y -or'd con $a-eq5para el caso especial de entrada"5" para lograr nuestra salida resultante.

Ejecuciones de prueba

PS C:\Tools\Scripts\golfing> 1, 2, 3, 4, 5, 6, 7, 8, 9, 16, 18, 38, 61, 81, 294, 349, 381, 383, 729, 767, 38183, 38383, 18349276, 183492761, 618349276 | %{.\numpad-knight-numbers.ps1 "$_"}
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True

PS C:\Tools\Scripts\golfing> 10, 11, 50, 53, 55, 65, 95, 100, 180, 182, 184, 185, 186, 187, 188, 189, 209, 305, 2009, 5030, 3838384, 4838383, 183492760 | %{.\numpad-knight-numbers.ps1 "$_"}
False
False
False
False
False
False
False
False
False
False
False
False
False
False
False
False
False
False
False
False
False
False
False

2

C, 78 bytes

char*a="9614397052";f(x){int b=x/10;return!b||abs(a[x%10]-a[b%10])%6==1&f(b);}

Como todos los demás han tomado la entrada como una cadena, intenté hacerlo en enteros. Funciona recursivamente desde el dígito menos significativo ( a%10); si es el único dígito, entonces devuelve verdadero. De lo contrario, devuelva verdadero solo si b%10no se puede alcanzar el dígito de las decenas ( ) desde el dígito de las unidades y (recursivamente), el resto de la entrada satisface la misma prueba.

La prueba de accesibilidad funciona codificando el recorrido del caballero linealmente y convirtiendo cada dígito a su posición (cero a siete) en el recorrido. Para los dígitos 0y 5, asignamos la posición nueve, que está desconectada de las otras posiciones. Luego, los números mutuamente accesibles difieren en uno (mod ocho); es decira[x%10]-a[b%10]es es ± 1 o ± 7. Entonces probamos la diferencia absoluta (mod 6) contra 1.

Esta solución funciona para cualquier codificación de caracteres que sea válida para C (es decir, los dígitos tienen códigos contiguos de 0 a 9).


1

Java 8, 179 167 Bytes

Coloca las entradas del teclado numérico (menos 5 y 0) en un círculo. lcontiene el índice circular de estas entradas. Si la diferencia de dos índices es +/- 3 mod 8, entonces hay un movimiento de caballeros entre las entradas correspondientes a esos índices. Tenga en cuenta que xes un int[].

x->{if(x.length<2)return 1;int[] l={0,0,1,2,7,0,3,6,5,4};int o=l[x[1]];for(int i:x){int n=l[i];if(i%5==0||(Math.abs(n-o)!=3&&Math.abs(n-o)!=5))return 0;o=n;}return 1;}

Actualizar

  • -11 [16-12-10] Cambiado a una lambda
  • -1 [16-12-10] Usar en <2lugar de==1
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.