Prelude Syntax-Checker


10

Prelude es un lenguaje de programación esotérico, que tiene muy pocas, pero inusuales, restricciones sobre lo que constituye un programa válido. Cualquier bloque de texto ASCII imprimible ("bloque" significa que las líneas de ASCII imprimibles están separadas por nuevas líneas - 0x0A) es válido siempre que:

  • Cada columna de texto (vertical) contiene como máximo uno de (y ).
  • Ignorando su posición vertical, los (y )están equilibrados, es decir, cada uno (está emparejado con exactamente uno )a la derecha de la misma, y ​​viceversa.

Escriba un programa o función que, dada una cadena que contenga ASCII imprimible y líneas nuevas, determine si constituye un programa Prelude válido. Puede recibir información a través de STDIN (o la alternativa más cercana), argumento de línea de comando o argumento de función. El resultado puede devolverse o imprimirse a STDOUT, utilizando cualquiera de los dos valores de verdad / falsedad fijos que elija.

Debe no asume que la entrada es rectangular.

Este es el código de golf, por lo que gana el envío más corto (en bytes).

Ejemplos

Los siguientes son programas Prelude válidos (de hecho, incluso son programas Prelude reales ):

?1-(v  #1)-             
1   0v ^(#    0)(1+0)#)!
    (#)  ^#1-(0 #       
1(#  1) v #  - 1+)
    vv (##^v^+
? v-(0 # ^   #)
?
  1+              1-!

Y aquí hay una serie de entradas, todas las cuales no son válidas :

#(#(##)##)##(
)##(##(##)#)#
#(#)
)###
#(##
(##)
(##)
(#)#
(##)
(###
#(#)
(##)
#(#)
###)
#()#
()##
#(#)##
###
###(#)

¿Prelude tiene comentarios que podrían bloquear un par cercano?
Alex A.

@Alex No. Las reglas anteriores son realmente todo lo que hay para decidir si un programa es válido o no.
Martin Ender

Genial, gracias por aclarar. Sólo quería asegurarme.
Alex A.

Regla 1 - "Cada columna de texto contiene como máximo uno de (y)"; Ejemplo 1, línea 2: "1 0v ^ (# 0) (1 + 0) #)!" -> Veo 3 )y 2 (. ¿No debería ser solo 1 por línea?
Ismael Miguel

1
@IsmaelMiguel "columna" generalmente se entiende que se refiere a líneas verticales (especialmente en el contexto de cuadrículas). Sin embargo, lo he aclarado de todos modos.
Martin Ender

Respuestas:


3

CJam, 57 56 bytes

qN/z_{_"()"--W<},,\s:Q,{)Q/({_')/,\'(/,-}:T~\sT0e>+z+}/!

Demasiado tiempo, se puede jugar mucho al golf. Explicación que se agregará una vez que lo juegue.

Breve explicacion

Hay dos verificaciones en el código:

  • El primer filtro verifica que cada columna como máximo 1 corchete. El resultado final del filtro es el número de columnas con más de 1 paréntesis.
  • En segundo lugar, convertimos la entrada al formato principal de columna y luego la dividimos en cada índice en dos partes.
    • En cada una de estas dos partes, ( Number of "(" - Number of ")") debe complementarse mutuamente. Entonces, cuando los sumas, debería resultar en 0. Cualquier parte que falle esta propiedad hace que toda la entrada tenga corchetes no coincidentes.
    • También tengo que asegurarme de que "(" están a la izquierda de ")". Esto significa que el valor de Number of "(" - Number of ")"no puede ser negativo para el bloque del lado derecho.

Pruébalo en línea aquí


6

Python 2, 128 119 105 bytes

def F(p):
 v=n=1
 for r in map(None,*p.split("\n")):A,B=map(r.count,"()");n+=B-A;v*=n<2>A+B
 return n*v>0

¿Sabía que puede asignar Ninguno en Python 2?

Explicación

Queremos comenzar transponiendo el Preludio para que las columnas se conviertan en filas. Por lo general, haríamos esto con zip, pero dado que se ziptrunca a la longitud de fila más corta y itertools.zip_longestes demasiado larga para el golf de código, parece que no hay una forma corta de hacer lo que queremos ...

Excepto para el mapeo None:

>>> print map(None,*[[1,2,3],[4],[5,6]])
[(1, 4, 5), (2, None, 6), (3, None, None)]

Desafortunadamente (o más bien, afortunadamente para todos los propósitos que no sean de golf), esto solo funciona en Python 2.

En cuanto a ny v:

  • nactúa como una pila, contando 1 - <number of unmatched '(' remaining>. Por cada (que vemos, restamos 1, y por cada )que vemos sumamos 1. Por lo tanto, si n >= 2en algún momento, hemos visto demasiados )sy el programa no es válido. Si nno termina en 1, entonces tenemos al menos un (resto sin igual .
  • vcomprueba la validez y comienza en 1. Si el programa no es válido ( n >= 2o A+B >= 2), se vconvierte en 0 para marcar la invalidez.

Por lo tanto, si el programa es válido, al final debemos tenerlo n = 1, v = 1. Si el programa no es válido, al final debemos tener v = 0, o v = 1, n <= 0. Por lo tanto, la validez se puede expresar sucintamente como n*v>0.

(¡Gracias a @feersum por una multitud de buenas sugerencias que despegaron 14 bytes!)

Envío anterior, más legible:

def F(p):
 p=map(None,*p.split("\n"));v=n=0
 for r in p:R=r.count;A=R("(");B=R(")");n+=A-B;v|=A+B>1or n<0
 return n<1>v

Ese es un uso loco de map...
xnor

1
119 -> 106def F(p): v=n=3 for r in map(None,*p.split("\n")):A,B=map(R.count,"()");n+=A-B;v*=n>2>A+B return n*v==9
feersum

@feersum ¡Gracias! Había estado tratando de cambiar el oren el encadenamiento de comparación, pero yo no había pensado en cambiar |=a *=. Sin embargo, eliminó otro byte, haciendo las cosas aún más al revés :)
Sp3000

2

J, 64 bytes

La entrada es una cadena con una nueva línea final. La salida es 0 o 1.

(0=(1<|s)s+[:(|@{:+(0>])s)[:+/\]s=.+/@:)@(1 _1 0{~[:'()'&i.];.2)

Ejemplo de uso

   ]in=.'#(#)##',LF,'###',LF,'###(#)',LF
#(#)##
###
###(#)

   ((0=(1<|s)s+[:(|@{:+(0>])s)[:+/\]s=.+/@:)@(1 _1 0{~[:'()'&i.];.2)) in
0

El método es el siguiente.

  • cortar la entrada en las nuevas líneas y poner en una matriz ];.2
  • mapa (/ )/ anything elseen 1/ -1/0 1 _1 0{~[:'()'&i.]
  • definir un s=.+/@:adverbio que agregado a un verbo suma la salida de la matriz de verbos
  • agregar valores en columnas ]s

    • verificar ()saldo positivo en cada prefijo [:(0>])s)[:+/\]
    • comprobar el ()saldo igual en toda la lista (es decir, en el último prefijo) |@{:@]
  • agregue abs (valores) en columnas y verifique que cada elemento tenga un valor máximo de 1 (1<|s)s

  • Como todas las comprobaciones anteriores arrojaron resultados positivos en caso de fallo, las sumamos y las comparamos con 0 para obtener la validez de la entrada 0=]


2

J, 56 bytes

3 :'*/0<: ::0:(+/\*:b),-.|b=.+/+.^:_1]0|:''()''=/];.2 y'

Esa es una función anónima que acepta una cadena con una nueva línea final y devuelve 0 o 1. Lectura de derecha a izquierda:

  • ];.2 y, como en la otra presentación J, corta la cadena yen todas las apariciones de su último carácter (por lo que la entrada necesita una nueva línea final) y crea una matriz rectangular cuyas filas son las piezas, rellenadas con espacios si es necesario.

  • '()'=/compara cada carácter en esa matriz primero con (y luego con la )devolución de una lista de dos matrices 0-1.

  • +.^:_1]0|:convierte esa lista de dos matrices en una única matriz de números complejos. Hasta ahora, el programa convierte cada (entrada en un 1, cada una )en i y cualquier otro carácter en 0.

  • b=.+/asigna la suma de las filas de esa matriz compleja a b.

  • -.|bhace una lista de 1- | z | por cada z en b. La condición de que cada columna contenga como máximo un paréntesis se traduce en todos estos números 1- | z | ser no negativo

  • +/\*:bes el vector de ejecutar sumas de los cuadrados de los números en b. Si cada columna contiene como máximo un paréntesis, los cuadrados de los números bson todos 0, 1 o -1. Los ,concatena este vector con el vector de 1- | z | 's.

  • ahora todo lo que tenemos que hacer es probar que las entradas de nuestro vector concatenado vson números reales no negativos, esto es casi */0<:v, excepto que causa un error si algunas entradas de vno son reales, por lo que reemplazamos <:con el <: ::0:que solo devuelve 0 en caso de error .


Grandes ideas con los números complejos, pero también debe verificar si, 0={:+/\*:bpor ejemplo, porque (no es válido.
randomra

Oh, tienes razón, @randomra, ¡lo olvidé!
Omar

1
0=(-|)ves 2 bytes más corto para verificar reales no negativos. (¡Vamos a vencer a CJam!: P)
randomra

1
Ah, y en invlugar de ^:_1 guardar otro byte.
randomra

1
Volver a 56 (con la consulta de saldos): 3 :'*/0=({:,]-|)(-.@|,+/\@:*:)+/+.inv]0|:''()''=/];.2 y'.
randomra
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.