Programa de tablero triangular autovalidado

10

Un programa de tablero de ajedrez es un programa en el que el valor ordinal de cada carácter individual alterna de par a impar, excluyendo el terminador de línea (que puede ser cualquier final de línea estándar).

Un programa triangular es un programa en el que cada línea tiene un carácter adicional que la línea anterior, y la primera línea tiene un carácter. No necesita manejar entradas vacías.

Su tarea es construir un programa que valide que la entrada dada se adhiera a esos criterios y que produzca / devuelva algo verdadero si el programa cumple con los criterios, o algo falso de lo contrario.

Su programa también debe cumplir con estos criterios.

Ejemplos de programas válidos.

G
`e
@u^
5r{B

^
cB
+$C
VA01

Reglas

  • Su programa puede comenzar con un byte impar o par, siempre que la paridad de los caracteres se alterne.
  • Su programa debe validar los programas que comienzan con un carácter impar o par.
  • Para los caracteres unicode, los valores de byte subyacentes deben tener paridad alterna.
  • Puede suponer que la entrada solo contiene caracteres imprimibles. Si su programa contiene elementos no imprimibles, aún debería poder validarse.
  • Su programa puede incluir una nueva línea final, no es necesario que su validación lo permita, ya que puede suponer que se elimina antes de la validación.
  • Las lagunas estándar están prohibidas.
  • El código más corto en bytes, en cada idioma, gana.
Dom Hastings
fuente
@ Martininder ¡Gracias por tu aporte! Esperemos que esto ahora esté claro. En relación con esto, ¿debería haber dejado esto en el sandbox por más tiempo?
Dom Hastings
1
¿es el par / impar alternando horizontal y vertical? Supongo que sí del "tablero de ajedrez", pero no veo dónde lo dices.
Ton Hospel
@DomHastings Una semana parece estar bien. Si no recibe comentarios después de unos días, puede preguntar en el chat si alguien tiene más comentarios.
Martin Ender
1
@TonHospel Mis ejemplos originales hicieron esto, pero en contradicción con mi descripción, por lo que para esta aplicación, que no, que debe ser: E\nOE\nOEO. ¡Espero que ayude!
Dom Hastings
2
Mi opinión: dejar que las respuestas asuman que la entrada no comienza o termina con una nueva línea.
Lynn

Respuestas:

3

Stax , 26 bytes

L
Y$
i:-
 {2%
*OFyF
%vi =*

Ejecute casos de prueba en línea

Tuve que presentar 3 personajes basura. ies un no-op cuando está fuera de todas las construcciones de bucle. siempre es un no-op. Ocoloca un 1 debajo de la parte superior de la pila, pero el valor no se usa en el programa.

LY      move input lines into a list and store in Y register
$       flatten
i       no-op
:-      get pairwise differences
{2%*OF  foreach delta, mod by 2, and multiply, then tuck a 1 under the top of stack
yF      foreach line in original input do...
  %v    subtract 1 from length of line
  i=    is equal to iteration index?
  *     multiply

Ejecute este

recursivo
fuente
Oye, espero que esto no altere demasiado tu código, pero puedes descartar la validación líder de nueva línea.
Dom Hastings
8

C (gcc), 189 bytes

j
;l
;b;
d;f␉
(char
␉*␉t) 
{b=*␉t%
2;for␉(␉
j=d=0;j=j
+ 1,␉l=j+ 
1,␉*␉t; ) {
for␉(;l=l- 1
 ;t=t+ 1 )b= 
!b␉,␉d=d+ !(␉*
␉t␉*␉(␉*␉t- 10)
*␉(␉*␉t%2-b) ) ;
d␉|=*␉t- 10;t=t+ 
1 ; }b= !d; } ␉ ␉ 

Pruébalo en línea!

representa un carácter de tabulación (lo siento). Tenga en cuenta que hay varios espacios / pestañas finales (lo siento más). El original con las pestañas intactas se ve mejor en vim con :set tabstop=1(las palabras no pueden expresar cuánto lo siento).

Es una función (llamada f, que no es inmediatamente obvia al mirarla) que toma una cadena como argumento y devuelve 0o 1.

Me podría reducir esto al menos uno y probablemente dos o más líneas, pero nota que se pone cada vez más complicado y requiere poco esfuerzo hacia el final, sobre todo porque escribir dicho código horrible (incluso para los estándares PPCG) me hacía sentir como una mala persona y quería parar lo antes posible

La idea básica aquí es evitar construcciones que necesariamente romper el formato ( ++, +=, return, etc.). Milagrosamente, las palabras clave importantes como for, chary while(que no terminé usando) se ajustan a la regla de paridad alterna. Luego usé espacios (paridad par) y tabulaciones (paridad impar) como relleno para que el resto se ajustara a las reglas.

Pomo de la puerta
fuente
1
¡No esperaba ver una solución en C!
Dom Hastings
Si aísla la parte de la solución del programa en el TIO colocando otras cosas en las secciones "Encabezado" y "Pie de página", es más fácil para las personas verificar el recuento de bytes.
Jakob
4

Haskell , 1080 1033 bytes

;
f=
 g 
ij=f
a =hi
hi = g
hij= ij
g ' ' =0
g '"' =0;
 g '$' =0;
 g '&' =0-0
g '(' =0-0-0
g '*' =0-0-0;
 g ',' =0-0-0;
 g '.' =0-0-0-0
g '0' =0-0-0-0-0
g '2' =0-0-0-0-0;
 g '4' =0-0-0-0-0;
 g '6' =0; g '8' =0
g ':' =0; g '<' =0-0
g '>' =0; g '@' =0-0;
 g 'B' =0; g 'D' =0-0;
 g 'F' =0; g 'H' =0-0-0
g 'J' =0; g 'L' =0-0-0-0
g 'N' =0; g 'P' =0-0-0-0;
 g 'R' =0; g 'T' =0-0-0-0;
 g 'V' =0; g 'X' =0-0-0-0-0
g 'Z' =0; g '^' =0; g '`' =0
g 'b' =0; g 'd' =0; g 'f' =0;
 g 'h' =0; g 'j' =0; g 'l' =0;
 g 'n' =0; g 'p' =0; g 'r' =0-0
g 't' =0; g 'v' =0; g 'x' =0-0-0
g 'z' =0; g '\92' =0-0; g '|' =0;
 g '~' =0; g y = 1 ;z=0; i(-0)z=z;
 i m('\10':y ) ="y"; ; ; ; ; ; ; ; 
i m(mnmnmnmnm:y ) = i(m - 1 ) y ; ; 
i k m ="y"; ; k i [ ] =01<1010101010;
 k m('\10':y ) = k(m + 1 )(i m y ) ; ;
 k m y =01>10; m o = k 1$'\10':o ; ; ; 
o i('\10':y ) = o i y ; ; ; ; ; ; ; ; ; 
o i(k:y )|g k<i = o(1 - i ) y ; ; ; ; ; ;
 o i(k:y )|g k>i = o(1 - i ) y ; ; ; ; ; ;
 o i [ ] =01<10; o i y =01>10;v=01>10101010
s y|o 1 y = m y|o(-0) y = m y ; s y =v; ; ; 

Pruébalo en línea!

Explicación

Esta ha sido una tarea bastante interesante para Haskell.

Paridad

Para comenzar, necesitamos alguna forma de determinar si un personaje tiene un punto de código par o impar. La forma normal en que se puede hacer esto es obtener el punto de código y modificarlo en 2. Sin embargo, como se puede saber, obtener el punto de código de un personaje requiere una importación, lo que debido a la restricción de origen significa que no puede ser usado. Un Haskeller más experimentado pensaría usar la recursividad. Char's son parte de la Enumclase de tipos para que podamos obtener sus predecesores y sucesores. Sin embargo pred, y succtambién son tanto inutilizable porque no hacen byte de paridad alternativo.

Esto nos deja bastante atascados, prácticamente no podemos hacer ninguna manipulación con los caracteres. La solución a esto es codificar todo. Podemos representar (la mayoría) caracteres pares como literales, probabilidades con las que tenemos problemas porque 'es extraño, por lo que no puede estar al lado del personaje en sí, haciendo que el literal sea imposible de expresar la mayoría de los caracteres impares. Así que codificamos todos los bytes pares y luego agregamos un catch all para los bytes impares al final.

El problema Bytes

Puede notar que hay algunos bytes pares para los que no se pueden hacer literales envolviéndolos entre comillas simples. Son los no imprimibles, las nuevas líneas y \. No debemos preocuparnos por los no imprimibles, ya que siempre que no usemos ninguno de ellos no necesitamos verificarlo. De hecho, todavía podemos usar extrables no imprimibles, como tab, simplemente no termino necesitando. Newline puede ignorarse sabiamente porque de todos modos será recortado del programa. (Podríamos incluir nueva línea, porque su punto de código es bastante conveniente, pero no es necesario). Esto deja \, ahora \tiene el punto de código 92, que convenientemente es un número impar seguido de un número par, por lo que \92alterna entre pares e impares , por lo tanto, el literal'\92'Es perfectamente válido. Más adelante, cuando necesitemos representar una nueva línea, notaremos que, afortunadamente, tiene esta misma propiedad '\10'.

Problemas de espacio

Ahora, para comenzar a escribir el código real, necesitamos poder colocar una cantidad considerable de caracteres en una sola línea. Para hacer esto escribí el gorro:

;
f=
 g 
ij=f
a =hi
hi = g
hij= ij

La gorra no hace nada excepto ser válida Haskell. Inicialmente esperaba hacer definiciones que nos ayudaran en el código más tarde, pero no fue así. También hay formas más fáciles de hacer el límite, por ejemplo, espacios en blanco y punto y coma, pero no guardan bytes de esta manera, así que no me he molestado en cambiarlo.

Codificador duro

Entonces, ahora que tengo suficiente espacio en una línea, comienzo a codificar valores. Esto es bastante aburrido, pero hay algunas cosas de interés. Por una vez, las líneas comienzan a alargarse aún más, podemos usar ;para poner varias declaraciones en una línea, lo que nos ahorra una tonelada de bytes.

La segunda es que, dado que no siempre podemos comenzar una línea con una gfrecuencia cada tanto, debemos sangrar un poco las líneas. Ahora Haskell realmente se preocupa por la sangría, por lo que se quejará de esto. Sin embargo, si la última línea antes de la línea con sangría termina en punto y coma, lo permitirá. ¿Por qué? No tengo nada, pero funciona. Así que solo tenemos que recordar poner los puntos y comas al final de las líneas.

Bloques de construcción de funciones

Una vez que el hardcoder está listo, es fácil navegar hasta el final del programa. Necesitamos construir algunas funciones simples. Primero construyo una versión de drop, llamada i. ies diferente de dropeso si intentamos pasar más allá del final de la cadena, simplemente regresa "y". ies diferente de soltar también en que si intenta soltar una nueva línea, volverá "y". Esto será útil porque más tarde, cuando verifiquemos que el programa es un triángulo, nos permitirá volver Falsecuando la última línea no esté completa, o cuando una línea termina temprano.

kknortessTruenorteknorte+1False

A continuación hacemos un alias para k, m. mes solo kcon 1en el primer argumento, y una nueva línea antepuesta al segundo argumento.

A continuación tenemos o. otoma un número y una cadena. Determina si los bytes de cadena (ignorando las nuevas líneas) se alternan en paridad (usando nuestro g) comenzando con el número de entrada.

Por último, tenemos scuál funciona ocon ambos 1y 0, si alguno tiene éxito, difiere m. Si falla ambos, simplemente regresa False. Esta es la función que queremos. Determina que la entrada es triangular y alterna.

Ad Hoc Garf Hunter
fuente
1
Una cadena triangular comienza con una línea de 1 carácter, no una línea vacía.
Jakob
@Jakob Creo que es tonto, pero fue una solución bastante fácil.
Ad Hoc Garf Hunter
3

05AB1E , 34 26 bytes

¶
¡D
©€g
´ā´Q
´sJÇÈ
¥Ä{´нP

Pruébalo en línea!

Toma la entrada como una cadena multilínea (entrada entre "" " ). Explicaciones que vendrán más adelante.

Kaldo
fuente
1
A menos que haya entendido mal las reglas, el programa también debe ser capaz de validar la entrada comenzando con una nueva línea.
Emigna
@Emigna Creo que su programa tiene que poder validar una nueva línea principal solo si en sí comienza con una nueva línea principal.
Ton Hospel
No tengo idea si esto es correcto (soy horrible leyendo las especificaciones): ¡ Pruébelo en línea!
Magic Octopus Urn
@MagicOctopusUrn Su respuesta me parece bien, pero me pregunto sobre la entrada: ¿podemos tomarla como una matriz? En su enlace, su primera entrada es un espacio vacío, no un carácter de nueva línea.
Kaldo
1
Oye, espero que esto no altere demasiado tu código, pero puedes descartar la validación líder de nueva línea.
Dom Hastings
1

Java 10, 209 bytes

Un lambda vacío que toma un iterable o una matriz de byte. Indica verdadero al regresar normalmente, falso al lanzar una excepción de tiempo de ejecución. El programa espera que la línea final se termine correctamente, es decir, que termine con un carácter de nueva línea. La línea final del programa se termina de manera similar.

Todo se hace bajo UTF-8, con la interpretación de que "carácter" se refiere a puntos de código Unicode.

Las pestañas se reemplazan con espacios en esta vista.

d
->
{  
long
f= 1,
 h=0 ,
c = - 1
,e ;for 
( byte a:
 d) {var b
=(e = a^10)
<1&e>- 1 ;f=
b?( h ^ f)> 0
?0/0 : f+ 1: f
;h=b?0 :a>-65 ?
h+ 1: h; c =b? c
:c>=0 & ( (c^a )&
1 )<1 ?0/0 :a ; } 
/*1010101010101*/ }

Pruébalo en línea

Hex dump

Revertir con xxd -p -ren Unix.

640a2d3e0a7b20090a6c6f6e670a663d20312c0a09683d30092c0a63203d
202d20310a2c65203b666f72090a28096279746520613a0a096429207b76
617209620a3d2865203d20615e3130290a3c3126653e2d2031203b663d0a
623f280968095e0966293e09300a3f302f30093a09662b20313a09660a3b
683d623f30093a613e2d3635203f0a682b20313a09683b2063203d623f20
630a3a633e3d30092609280928635e612029260a3120293c31203f302f30
093a61203b207d200a2f2a313031303130313031303130312a2f207d0a

Sin golf

d -> {
    long f = 1, h = 0, c = ~h, e;
    for (byte a : d) {
        var b = (e = a^10) < 1 & e > -1;
        f = b ?
            (h^f) > 0 ? 0/0 : f + 1
            : f
        ;
        h = b ? 0 :
            a > -65 ? h + 1 : h
        ;
        c = b ? c :
            c >= 0 & ((c^a) & 1) < 1 ? 0/0 : a
        ;
    }
}

fes el número esperado de caracteres en la línea actual, hes el número de caracteres vistos hasta ahora en la línea actual, ces el último byte visto y bes si aes la nueva línea.

La condición a > -65prueba si aes el primer byte de un carácter. Esto funciona porque los caracteres de un solo byte (ASCII) no son negativos en el complemento de dos bits de 8 bits, el primer byte de caracteres más largos tiene forma binaria 11xxxxxx(al menos -64 en el complemento de dos), y los bytes no iniciales en esos caracteres son de la forma 10xxxxxx, como máximo -65 en complemento a dos. ( Fuente )

Cuando un personaje viola el patrón triangular o de tablero de ajedrez (es decir, una nueva línea aparece temprano o tarde o aparece un byte de la paridad incorrecta), la rama izquierda del ternario correspondiente (en asignación fao c) se activa y el método arroja una excepción aritmética.

Jakob
fuente
0

Python 3 (3.4?), 350 bytes

Un desafío complicado para un lenguaje tan particular sobre los espacios en blanco como Python 3. El envío se imprime 0o se 1estandariza y se bloquea para algunas entradas. El programa espera que la línea final se termine correctamente, es decir, que termine con un carácter de nueva línea. La línea final del programa se termina de manera similar. UTF-8 se utiliza para verificar la paridad de bytes.

Las pestañas se reemplazan con espacios en esta vista.

0
i\
= 1
t=(#
 '0'*
 0) ;(
g,) =(#
 open (1
, "w"),) 
k = eval (
'p' + 'rin'
 + 't' ) #01
for  a in (#0
open ( 0) ):#0
#01010101010101
 a = a [:- 1 ] #
 if ( len (a )<i\
or len (a )>i ):[\
k('0' ),1 /0] #0101
 i, t= -~i, t+ a #01
(k( 2-len ({(c^i )&1\
 for  i,c in  eval (#0
 "enu"+"m"+"erate")(#01
 eval ( " byte"+"s")( t#
,' u8' ) ) } ) ) ) #01010

Funciona para mí con Python 3.4.2; no funciona en ningún Python 3 en TIO. Me parece que es un error en los intérpretes de TIO.

Hex Dump

Revertir con xxd -p -ren Unix.

300a695c0a3d20310a743d28230a202730272a0a093029203b280a672c29
203d28230a206f70656e0928310a2c09227722292c29200a6b203d206576
616c09280a277027202b202772696e270a202b202774272029202330310a
666f7209206120696e092823300a6f70656e092809302920293a23300a23
30313031303130313031303130310a2061203d2061205b3a2d2031205d20
230a2069660928096c656e09286120293c695c0a6f72096c656e09286120
293e6920293a5b5c0a6b2827302720292c31202f305d2023303130310a20
692c09743d202d7e692c09742b2061202330310a286b2809322d6c656e09
287b28635e69202926315c0a09666f720920692c6320696e09206576616c
092823300a0922656e75222b226d222b2265726174652229282330310a20
6576616c092809220962797465222b22732229280974230a2c2720753827
20292029207d202920292029202330313031300a
Jakob
fuente