Claramente entre paréntesis trenes APL


19

En APL, puede escribir funciones tácitas, llamadas trenes . Cómo funcionan es irrelevante para este desafío. Estas son las diferentes formas en que se pueden agrupar, utilizando como función:

⍴      -> ⍴
⍴⍴     -> ⍴⍴
⍴⍴⍴    -> ⍴⍴⍴
⍴⍴⍴⍴   -> ⍴(⍴⍴⍴)
⍴⍴⍴⍴⍴  -> ⍴⍴(⍴⍴⍴)
⍴⍴⍴⍴⍴⍴ -> ⍴(⍴⍴(⍴⍴⍴))
...

El orden sigue siendo el mismo. El procedimiento es que, siempre que haya estrictamente más de 3 funciones, las últimas 3 funciones se agrupan en una función. Si nos encontramos con un tren anidado, lo paréntesis primero, antes de continuar. Aquí está el procedimiento aplicado a ⍴⍴⍴⍴⍴⍴:

Step 0: ⍴⍴⍴⍴⍴⍴
There are strictly more than 3 functions, repeat.
Step 1: ⍴⍴⍴(⍴⍴⍴)
There are strictly more than 3 functions, repeat.
Step 2: ⍴(⍴⍴(⍴⍴⍴))
There are 3 or less functions, we're done.

Aquí está el mismo procedimiento aplicado a ⍴⍴⍴(⍴⍴)⍴(⍴⍴⍴⍴(⍴⍴⍴))⍴⍴:

Step 0: ⍴⍴⍴(⍴⍴)⍴(⍴⍴⍴⍴(⍴⍴⍴))⍴⍴
There are strictly more than 3 functions, repeat.
We have met a nested train, applying procedure to that first:
  Step 0: ⍴⍴⍴⍴(⍴⍴⍴)
  There are strictly more than 3 functions, repeat.
  We have met a nested train, applying procedure to that first:
    Step 0: ⍴⍴⍴
    There are 3 or less functions, we're done.
  Step 1: ⍴⍴(⍴⍴(⍴⍴⍴))
  There are 3 or less functions, we're done.
Step 1: ⍴⍴⍴(⍴⍴)⍴((⍴⍴(⍴⍴(⍴⍴⍴)))⍴⍴)
There are strictly more than 3 functions, repeat.
We have met a nested train, applying procedure to that first:
  Step 0: ⍴⍴
  There are 3 or less functions, we're done.
Step 2: ⍴⍴⍴((⍴⍴)⍴((⍴⍴(⍴⍴(⍴⍴⍴)))⍴⍴))
There are strictly more than 3 functions, repeat.
Step 3: ⍴(⍴⍴((⍴⍴)⍴((⍴⍴(⍴⍴(⍴⍴⍴)))⍴⍴)))
There are 3 functions or less, we're done.

Entrada

Para este desafío, la entrada se simplificará. Esto significa que puede elegir 2 caracteres diferentes para abrir y cerrar paréntesis y 1 carácter para funciones, diferentes de los elegidos para paréntesis. Los caracteres que elija deben ser consistentes. La entrada no estará vacía y no contendrá paréntesis sin contenido (es decir ()).

Salida

De nuevo, puede elegir 3 caracteres diferentes, 2 para paréntesis y 1 para funciones. Tenga en cuenta que no necesitan ser los mismos que los elegidos para la entrada, pero deben ser consistentes.

Reglas

  • Si hay paréntesis que solo encierran una función dentro de ellos en la entrada, debe eliminarlos en la salida. Es posible que su salida no contenga paréntesis innecesarios (es decir, que encierra solo una función o que encierra toda la salida).
  • No necesita implementar el algoritmo utilizado aquí, siempre que su solución sea válida para este desafío.
  • Entrada y salida son cadenas en el formato explicado en las secciones de Entrada y Salida. La entrada tendrá al menos un carácter.
  • El uso de las lagunas estándar está estrictamente prohibido.
  • Este es el , por lo que gana la respuesta más corta. Sin embargo, no habrá una respuesta aceptada, ya que esta es una competencia por idioma, y ​​para alentar la respuesta en idiomas en los que esta tarea resultaría en un código más largo en comparación con el código escrito en otros idiomas.

Casos de prueba

Los caracteres utilizados aquí son ()⍴, debe reemplazarlos con los caracteres elegidos.

⍴                          -> ⍴
⍴                          -> ⍴
⍴⍴                         -> ⍴⍴
⍴⍴⍴                        -> ⍴⍴⍴
⍴⍴⍴⍴                       -> ⍴(⍴⍴⍴)
⍴⍴⍴⍴⍴⍴⍴⍴⍴⍴⍴⍴⍴⍴⍴            -> ⍴⍴(⍴⍴(⍴⍴(⍴⍴(⍴⍴(⍴⍴(⍴⍴⍴))))))
⍴⍴⍴⍴⍴(⍴⍴⍴)⍴⍴(⍴(⍴⍴⍴)⍴⍴⍴)⍴⍴⍴ -> ⍴(⍴⍴(⍴⍴((⍴⍴⍴)⍴(⍴(⍴(⍴⍴⍴)(⍴⍴⍴))(⍴⍴⍴)))))
(⍴⍴⍴)(⍴⍴⍴)(⍴⍴⍴)            -> (⍴⍴⍴)(⍴⍴⍴)(⍴⍴⍴)
(⍴⍴⍴)(⍴⍴⍴)⍴⍴⍴              -> (⍴⍴⍴)(⍴⍴⍴)(⍴⍴⍴)
⍴⍴(⍴)⍴⍴                    -> ⍴⍴(⍴⍴⍴)
((⍴⍴))                     -> ⍴⍴
⍴⍴((⍴⍴))⍴⍴                 -> ⍴⍴((⍴⍴)⍴⍴)

Este desafío ha sido publicado en el Sandbox. Si tiene el privilegio requerido, puede ver la publicación de sandbox aquí .


2
Creo que Fully es un título mejor que Clearly .
Adám


@ Adám Esperaba esa respuesta de referencia, aunque no obtendrá muchos votos positivos;)
Erik the Outgolfer

@ Adám La parte claramente en el título se refiere al hecho de que debe eliminar los paréntesis innecesarios. Completamente es algo que debes hacer cuando respondes un desafío; p
Erik the Outgolfer

¿Es cierto que esta función siempre será idempotente?
Esolanging Fruit

Respuestas:


7

APL (Dyalog Classic) , 71 68 65 63 bytes

0{⍵≡⍕⍵:⍵⋄⍬≡⍵:'⍬'1=≢⍵:⍺∇⊃⍵⋄3≥≢⍵:⍺⌽')(',⍣⍺∊1∇¨⍵⋄⍺∇¯3(↓,∘⊂1∇↑)⍵}⍎

Pruébalo en línea!

Los personajes que he elegido para E / S son '(', ')'y '⍬'.

Esta solución es en sí misma un tren APL.

analiza la entrada como si fuera una matriz anidada: un árbol con vectores numéricos vacíos ( ) como hojas.

El dfn (es decir, lambda - { }) atraviesa el árbol de forma recursiva y lo convierte en una cadena entre paréntesis adecuada. El argumento de la izquierda controla si los paréntesis deben agregarse al nivel actual si es necesario.

El dfn maneja los siguientes casos basados ​​en el argumento correcto:

  • si ya es una cadena ( ⍵≡⍕⍵), devuélvala

  • si es así , devuelve el char'⍬'

  • si es un singleton, solo profundiza ( es el símbolo de una llamada recursiva)

  • si su longitud es ≤3, repita para cada uno de los elementos y rodee ()si es necesario

  • de lo contrario, recurse para la cola 3, anteponga todo menos la cola 3 y vuelva a recurrir


Parece 63 caracteres, la mayoría de ellos Unicode. ¿Qué codificación de caracteres produce 63 bytes para esto? Lo hago 141 bytes en UTF8.
Corey



@ Adám Gracias por eso. Miré pero no sabía qué buscar para obtener esa respuesta.
Corey

3

Python 2 , 224 208 204 bytes

-16 bytes gracias a Mr. Xcoder -4 bytes gracias a ovs

r=str.replace
p='p'
def c(l):
 while len(l)>3:l=l[:-3]+(l[-3:],)
 return l and map(c,l)or l
print r(r(r(r(r(`c(eval(r(r(r(input(),'(p)',p),p,'[],'),')','),')))`,'[]',p),*'[('),*'])'),' ',''),',','')[1:-1]

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

El código se puede dividir en 3 pasos principales:
convertir la entrada en una lista anidada y reemplazarla (p)->p. La única función pserá reemplazada por una lista vacía.

eval(r(r(r(input(),'(p)',p),p,'[],'),')','),'))

Una función recursiva para aplicar la regla "3 o menos" en la lista actual y llamarse a sí misma en todas las sublistas.

def c(l):
 while len(l)>3:l=l[:-3]+(l[-3:],)
 return l and map(c,l)or l

Muchos reemplazos para formatear al formato de salida deseado

r(r(r(r(r(`c(...)`,'[]',p),*'[('),*'])'),' ',''),',','')[1:-1]


1
Esto no simplifica ((pp))(o p((pp))p).
Martin Ender

2

CJam , 56 bytes

Beats APL!

lW%~]]]{{_,{K_,({~}|}&}%{_,3>}{3/(aa\+:~}w}:K~~`1>W<W%S/

Pruébalo en línea!

Esto funciona (creo) y no tengo idea de por qué ...

Los caracteres de entrada son ][Tpara ()⍴, y los caracteres de salida son ][0para ()⍴(sí, esto significa que están invertidos de lo que cabría esperar; por ejemplo, podría pasar TTT]TT[T]TTTT]TTT[[TT).

Resumen de alto nivel

El programa funciona con la entrada al revés, porque es más conveniente. Para analizar la entrada, aprovechamos el analizador de CJam: invertir y ejecutar la entrada proporciona la forma analizada (hacia atrás) de la entrada.

Luego definimos un procedimiento K. Krealiza la mayor parte del trabajo para nuestra presentación, y funciona de la siguiente manera:

  • La matriz de entrada será una mezcla de ceros y sub-matrices no vacías. Identifique los subconjuntos y aplíquelos recursivamente K. El resultado debería ser otra matriz, y si esta matriz consiste en un solo elemento, descomprímalo (esto elimina los paréntesis redundantes).
  • Mientras el resultado tenga más de tres elementos, agrupe los primeros tres (no los últimos tres; recuerde que la entrada se está procesando hacia atrás) en una sola lista.
  • Devuelve el resultado.

Al aplicar Ka la entrada, obtenemos la forma correctamente entre paréntesis de la entrada (lo único que se debe tener en cuenta es que en realidad envolvemos la entrada en una lista singleton y la desenvolvemos después; la razón de esto es que queremos el fragmento que desempaque los singletons para aplicar al programa de nivel superior, y no solo a sus sub-matrices). Luego, solo aplicamos un formato mínimo para obtener nuestro resultado.

Alguna explicación para los bits de golf

El golf del que estoy más orgulloso está usando ,para realizar la verificación entre enteros y matrices.

  • Si la parte superior de la pila es un número entero n , ,genera el rango [0..n) . Como el único número entero que encontraremos es 0, esto siempre nos da la lista vacía [], que es falsey.
  • Si la parte superior de la pila es una matriz, ,toma su longitud. Como todas las matrices que encontramos no estarán vacías, esto siempre nos da un número entero positivo, que es verdad.

Otro golf que podría ser interesante es el método que uso para agrupar los primeros tres elementos de la matriz; es algo similar a mi presentación "Turing complete language interprete code golf" . CJam no tiene una forma corta de dividir una matriz en dos partes (puede intentar cortar la primera parte y luego la otra parte mientras mantiene la matriz original y el índice en la pila, pero eso no funciona muy bien) , así que lo que hago es usar 3/, que agrupa una matriz en bloques de 3. Luego puedo extraer el primer elemento (, envolver la matriz dos veces aay luego volver al principio de la lista \+. La razón por la que envolvemos la matriz dos veces es porque tenemos que quitar una capa :~, ya que también agrupamos el resto de la matriz en secciones.


Nitpick: esto supera a APL sin incorporar .
Erik the Outgolfer

@EriktheOutgolfer Bastante justo.
Esolanging Fruit

0

JavaScript (ES6), 149 146 bytes

i='a';f=s=>s==(s=s[R='replace'](/\((\w+)\)/,(q,t)=>(f[q=i+=0]=f(t),q)))&&s==(s=s[R](/(?!^)((a0+|p){3})$/,"($1)"))?s[R](/a0+/g,t=>`(${f[t]})`):f(s)
<textarea cols=80 id=I>ppp(pp)p(pppp(ppp))pp</textarea><br>
<button onclick=O.innerText=f(I.value)>Run</button><br>
<pre id=O></pre>

Usos ()p, aunque para usar una letra diferente, solo puede cambiar la letra phacia el final.

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.