Haskell tiene tuplas que se pueden escribir como
(a,b,c)
Sin embargo, esto es solo azúcar sintáctico para
(,,)a b c
En general, se puede formar una n tupla con n-1 ,
s entre (
... )
seguido de sus elementos separados por espacios. Por ejemplo, la 7-tupla, (1,2,3,4,5,6,7)
puede estar formada por
(,,,,,,)1 2 3 4 5 6 7
Como Haskell no tiene 1-tuplas, no se pueden formar. Tampoco será responsable de las tuplas vacías.
Las tuplas anidadas se pueden formar usando parens para anular el orden de las operaciones.
((1,2),3) == (,)((,)1 2)3
Como parte de nuestra búsqueda para eliminar todo el azúcar sintáctico de Haskell, le pediré que escriba un programa que elimine también el azúcar sintáctico de las tuplas de Haskell.
Su programa debe tomar una tupla, una matriz o una cadena que represente una tupla azucarada y debe generar una cadena que represente una tupla "sin azúcar". Las tuplas de entrada solo contendrán enteros positivos u otras tuplas.
Como estamos jugando al golf aquí, su rendimiento debe ser corto. No debe contener innecesarios
Espacios Los espacios deben usarse solo para separar los argumentos de las funciones de una tupla y no deben aparecer después de un
)
o antes de un(
Paréntesis. Los paréntesis deben usarse solo al formar funciones de tupla o al anidar tuplas.
Esta es una pregunta de código de golf , por lo que las respuestas se puntuarán en bytes con menos bytes mejor.
Casos de prueba
(1,2) -> (,)1 2
(1,2,3) -> (,,)1 2 3
((1,2),3) -> (,)((,)1 2)3
(1,2,3,4) -> (,,,)1 2 3 4
(1,(2,3)) -> (,)1((,)2 3)
(10,1) -> (,)10 1
,
((1,(2,3)),4,(5,6))
y(1,(2,3),4)
.Respuestas:
Haskell ,
169148bytesPruébalo en línea! Toma la tupla como una cuerda.
init.tail.fst.([]%)
Es la función principal anónima. Úselo a, por ejemplo,f
y use likef "(3,(14,1),4,7)"
, que produce"(,,,)3((,)14 1)4 7"
.¿Por qué no se proporciona la entrada como una tupla de Haskell? Como Haskell está fuertemente tipado, una tupla
(1,2)
tiene tipo(Int,Int)
1 y una tupla(1,(2,3))
tiene tipo(Int,(Int,Int))
. Por lo tanto, una función que acepta el primer tipo de tupla no se puede aplicar al segundo tipo, y especialmente no puede haber ninguna función que tome una tupla 2 arbitraria .Explicación:
p:k="(,"
es una forma corta para asignarp
a'('
yk
a","
.(%)
es la función de análisis y conversión recursiva. El primer argumento es una lista de entradas de tuplas ya analizadas, el segundo argumento es el resto de la cadena original. Cada llamada devuelve una tupla de la tupla convertida actual (como una cadena y entre paréntesis) y el resto de la cadena.l%('(':r)
Si la cadena comienza con un corchete de apertura, debemos analizar una nueva entrada de tupla.(y,x:s)<-[]%r
Aplicamos recursivamente%
y obtenemos una entrada de tuplay
y la cadena restante se divide en el siguiente carácterx
y el resto de la cadenas
.m<-y:l
Agregamos la nueva entraday
a la lista actual de entradas ya encontradasl
y llamamos al resultadom
.x
ahora es una coma,
o un corchete de cierre)
. Ellast$ <B> :[ <A> |x<',']
es solo una forma más corta de escribirif x == ')' then <A> else <B>
.,
es el siguiente, debemos analizar de manera recursiva la siguiente entrada:m%(p:s)
anteponemos un corchete de apertura para terminar en el caso correcto y pasar la lista de entradas ya encontradasm
.x == ')'
, terminamos la tupla actual y necesitamos hacer la transformación requerida:(p:p:(l>>k)++x:foldl(\r x->x++[' '|x>k,r>k]++r)[x]m,s)
p:p:(l>>k)++x:
Si hemos encontrado n entradas, entoncesm
tiene n elementos yy
, la lista antes de agregar el elemento encontrado más recientemente, tiene n-1 entradas. Esto es útil ya que necesitamos n-1,
para unan
tupla de elemento yl>>k
funciona en listas como "concatenar la listak
consigo mismo tantas veces comoy
tenga elementos" . Por lo tanto, esta primera parte produce una cadena como"((,,,)"
.foldl(\r x->x++[' '|x>k,r>k]++r)[x]m
concatena los elementos dem
(en orden inverso, porque al agregar nuevas entradas al frentem
mismo se construyó en orden inverso) al tiempo que agrega solo espacios entre dos elementos si ambos son números:[' '|x>k,r>k]
verificamos si las entradas actualesx
y losr
números se comparan lexicográficamente que","
- si no son los números, que ya son una representación tupla encerrada entre paréntesis, y'(' < ','
las bodegas.l%('(':r)
desde el principio falla, entonces terminamos en la última línea:l%r=lex r!!0
. Esto significa que necesitamos analizar un número y devolver el número y el resto de la cadena. Afortunadamente, existe lalex
función que hace exactamente eso (analiza el siguiente token válido de Haskell, no solo los números). Sin embargo, la tupla resultante está envuelta en una lista, por lo que usamos!!0
para obtener el primer elemento de la lista.init.tail.fst.([]%)
es la función principal que toma una cadena y se aplica%
con una lista vacía. Por ejemplo, para una entrada"(1,2)"
, aplicando([]%)
rendimientos("((,)1 2)","")
, por lo que la tupla externa y los corchetes deben eliminarse.fst
obtiene el primer elemento de la tupla,tail
quita el soporte de cierre yinit
el de apertura.Editar: ¡ Muchas gracias a @ Ørjan Johansen por jugar al golf un total de 21 bytes !
1 En realidad, el tipo es (Num t1, Num t) => (t, t1) , pero esa es una historia diferente.
2 Ignorando las funciones polimórficas como id , que en realidad no pueden funcionar con su entrada.
fuente
Desugarable
, pero habría que declarar instanciasInt
y todos los tipos de tuplas.g
se puede acortarfoldr1(\x r->x++[' '|x>k,r>k]++r)
e inlinear.show (1,2,3,4,5,6,7,8,9,0,1,2,3,4,5)
en GHCi, luego agregue un,6
al final e intente nuevamente.)m<-y:l
, doble a la izquierda en lugar de a la derecha y use[x]
como valor inicial. Pruébalo en línea!f
puede ser anónima:init.tail.fst.([]%)
.Haskell
141 bytes138 bytes (Gracias a Ørjan Johansen)f
tiene tipoExp -> String
.Entrada: una resistencia de plantilla de Haskell
Exp
(es decir, la representación AST estándar de valores de Haskell de tipo arbitrario, básicamente, código de Haskell analizado antes de la verificación de tipo); debe representar una tupla que contenga solo números enteros no negativos y otras tuplas similares.Salida: una cadena que contiene la sintaxis desugared para esa expresión de tupla.
Manifestación:
fuente
")"++
a')':
dos lugares y guardar el espacio despuéstail
de moverlo fuera del paréntesis.Haskell , 119 bytes
Pruébalo en línea! Utiliza un tipo de datos personalizado
T
para representar tuplas, es decir, una tupla((1,2),3)
se representa comoU[U[I 1,I 2],I 3]
. Ejemplo de uso:init.tail.f $ U[U[I 1,I 2],I 3]
rendimientos(,)((,)1 2)3
.fuente
Python 2 , 110 bytes
Pruébalo en línea!
Toma a
tuple
.fuente
GNU sed,
14982 + 2 = 84 bytes+2 bytes para la
-r
bandera.Pruébalo en línea!
Explicación
fuente
((1,(2,3)),4,(5,6))
y(1,(2,3),4)
.JavaScript, 75 bytes
Matriz de entrada de número | matriz, cadena de salida.
Gracias a Neil, ahorre 2 bytes
fuente
(1/t?' ':0)+v
puede ser1/t?' '+v:v
.Mathematica, 94 bytes
Contiene una función
U+F4A1
incorporada no imprimibleFunction
.Toma un
List
número enteroString
s. Si esto no está permitido, esto se puede solucionar agregando 10 bytes más (esta versión toma unaList
deList
s /Integer
s):fuente
Pip , 45 bytes
Esta es una función que toma una lista como argumento. Pruébalo en línea!
Versión comentada
fuente
JavaScript (ES6),
8884 bytesToma una matriz de enteros y matrices. Editar: se guardó 1 byte usando en
s+=
lugar de dos usos separados des+
. Ahorré otros 3 bytes ahora que puedo simplificar el ternario interno. Si robo las ideas de @ tsh, puedo reducirlo a 76 bytes:fuente
Your program should take either a tuple or a string representing a sugary tuple
Supongo que una matriz de matrices / enteros debería estar bien.R, 316 bytes?
(Tengo que salir y no estoy seguro de la forma correcta de contar bytes ... además, no es una gran solución, pero quería publicarlo ya que pasé el tiempo haciéndolo ...)
Casos de prueba:
fuente
JavaScript (ES6), 72 bytes
Entrada: matriz que contiene números y / o matrices
Salida: cadena
Uso: f ([...])
Completa todos los casos de prueba, las mejoras son bienvenidas
fuente
C, 308 o 339 bytes
308 o 339 bytes, dependiendo de si se permite o no pasar un puntero al final de la cadena de entrada; la última línea solo está allí para permitir pasar un literal de cadena directamente sin tener que calcular su longitud.
Explicación
Un algoritmo bastante simple. Cuenta el número de comas en la profundidad actual, las imprime como un constructor de tuplas, luego sigue con los argumentos de la tupla, escapado (espacios entre números, tuplas anidadas entre paréntesis), recursivamente.
Casos de prueba y aplicación
fuente