Esta pregunta es parte de una serie de desafíos de cumpleaños de Brain-flak diseñados para celebrar el primer cumpleaños de Brain-Flak. Puede encontrar más información sobre el cumpleaños de Brain-Flak aquí .
¡Hoy es el primer cumpleaños de Brain-Flak! Así que pensé que sería una fiesta sorpresa de cumpleaños. Así que en tu idioma favorito imprime
Surprise!
Happy Birthday, Brain-Flak!
(Se permite el espacio en blanco al final)
Como siempre, los programas deben jugar golf. Sin embargo, dado que los programas Brain-Flak están hechos de paréntesis, no contará ningún paréntesis en su fuente en su contra. (Los caracteres ()[]<>{}
no cuentan para el total de bytes), pero deben estar equilibrados para no alterar Brain-Flak.
Reglas
Aquí hay un desglose de las reglas.
Los corchetes en su fuente deben estar equilibrados. Esos son los paréntesis de su programa que deben abarcar la siguiente gramática:
S -> SS | (S) | [S] | <S> | {S} | E
¿Dónde
E
está la cadena vacía?Es decir que una cadena balanceada es la concatenación de dos cadenas balanceadas, llaves alrededor de una cadena balanceada o la cadena vacía.
La puntuación de un programa es el número de bytes sin paréntesis.
Su objetivo debe ser minimizar su puntaje en el idioma que elija.
Se aplican reglas estándar, por lo que puede escribir un programa completo o una función.
en caso de empate, el recuento de bytes crudos actúa como un desempate
Ciertamente habrá soluciones de cero bytes en ciertos idiomas ( Paréntesis Infierno , Paréntesis , Glifo , Lenguage ). Trate de encontrar formas de jugar bien al golf en idiomas donde esta no sea una tarea trivial.
fuente
><
considera equilibrado o los frenos deben estar en el orden correcto (<>
)?Respuestas:
Python 2 ,
39373634 bytes-1 gracias a dzaima
-2 gracias a Erik the Outgolfer
Pruébalo en línea!
Personajes relevantes:
Explicación
Este programa construye la cadena:
Lo hace convirtiendo una larga cadena de paréntesis en códigos de caracteres. Una vez que la cadena está construida, la ejecuta.
Construye la cadena con el esqueleto:
Esto divide la cadena a lo largo
{}
y asigna cada sección al código de caracteres correspondiente a su longitud. Entonces podemos construir la cadena completa de parens por un costo de cero bytes.fuente
()
alrededorx
para ahorrar 2.Haskell (antes de GHC 8.4), (
10119 7767 76267540 bytes), puntaje15 1410Pruébalo en línea!
La última línea define una función anónima
(<>)'y'pred(:)
. Llame con(<>)'y'pred(:)()
para ceder la cuerda.Editar: ¡ Muchas gracias a @ Ørjan Johansen por sugerir pasar las funciones auxiliares como parámetros en lugar de declararlas, ahorrando cuatro bytes de puntuación!
Los bytes sin paréntesis son
¿Como funciona?
Una cadena
"wxy"
en Haskell es el azúcar sintáctica para una lista de caracteres['w','x','y']
, que a su vez es el azúcar sintáctica para la posterior construcción con el operador contras:
y la lista vacía:'w':'x':'y':[]
. Al definir,(<<>>)=(:)
producimos la misma cadena escribiendo'w'<<>>('x'<<>>('y'<<>>[]))
.Debido a que los caracteres están ordenados, podemos calcular el predecesor de cada carácter con una función llamada
pred
. Usando solo el carácter'y'
ypred
, la cadena se conviertepred(pred 'y')<<>>(pred 'y'<<>>('y'<<>>[]))
. Al definir(<>)=pred
y(<><>)='y'
podemos representar la cadena usando solo corchetes balanceados:(<>)((<>)(<><>))<<>>((<>)(<><>)<<>>((<><>)<<>>[]))
Sin embargo, al final no queremos una cadena, sino una función que devuelva una cadena, por lo que definimos nuestro operador contras en su
(<<>>) x xs ()=x:xs
lugar. (Por supuesto, conx
yxs
reemplazados por identificadores usando solo corchetes balanceados:)(<<>>)(<>)(<><>)()=(<>):(<><>)
. De esta manera,((<>)((<>)(<><>))<<>>((<>)(<><>)<<>>((<><>)<<>>[])())())
es una función de tipo
() -> String
y agregar un final()
produce la cadena original:((<>)((<>)(<><>))<<>>((<>)(<><>)<<>>((<><>)<<>>[])())())()
Usando este método se consigue una solución con puntuación de 15. Sin embargo, podemos condensar las tres declaraciones en uno declarando una función que toma cuatro argumentos:
'z'
,pred
,(:)
y()
para llamar.La siguiente función
encode
codifica una cadena con caracteres más pequeños o iguales de'y'
esta manera: (¿y
Por qué ? Porque es el carácter más grande"Surprise!\nHappy Birthday, Brain-Flak!"
y, por lo tanto, produce la representación más corta. Gracias de nuevo a Ørjan Johansen por señalar esto).Pruébalo en línea!
fuente
'z'
que en realidad no ocurre en la cadena de meta, creo que puede reducir el interruptor de recuento de bytes mediante el uso en su'y'
lugar.(<<<>>>)(<><>)(<>)(<<>>)()=...;(<<<>>>)'y'pred(:)
Retina , 59-24 = 35 bytes
Pruébalo en línea! En comparación, la solución aburrida toma 38 bytes.
fuente
Jalea ,
76 bytesDentro de lo
“”
que necesita para poner la salida de este programa Jelly:-1 byte gracias a Jonathan Allan (nueva línea permitida)
Hay 53127666317289661939246122975355844970973062889031671423309402549417051416384149 80886139013 (llamaremos a esto
n
)()
entre“”
.Explicacion :
fuente
Lenguaje , 0 bytes
Sólo 10024793746353848520175158940670214213802394805963081469362831141755126591573942436182287015467334956253918417576118983828148929806934751198148656645940502264502520032312455157880058174845907554602116807351044784410936407102892289953027884533102082518964744402664917253792543505897552998982122997648280947470217067174451441654554437678556775097996646071948 bytes hechos de soportes equilibradas.
Programa Python 3 para generar mi versión favorita, dado suficiente tiempo y memoria:
fuente
Haskell , (
1200613485 bytes), puntaje1817EDITAR:
toEnum
versión funcionara sin extensiones moviendo la funcióntoEnum
a la función principal, a costa de a$
.Usar como
putStrLn$(<<>>)()
.Pruébalo en línea!
donde
...
es la cadena de resultado de la siguiente expresión:Los únicos caracteres no equilibrados son
La siguiente variante (13484 bytes) tiene una puntuación de 16, excepto que necesita la
ExtendedDefaultRules
extensión de GHC , por lo que solo funciona en GHCi de forma predeterminada. (A menos que te gusten los montones de advertencias, también quieres-fdefer-type-errors
y-Wno-deferred-type-errors
por alguna razón).Pruébalo en línea!
Cómo funciona
<>
son caracteres de operador legales. Además, si están entre paréntesis, se pueden usar para cualquier valor, no solo para funciones de dos argumentos.(<<>>)
en la segunda línea está la función principal, toma un solo argumento ficticio()
y devuelve la cadena final.<>
toma dos listas y antepone la longitud de la segunda a la primera (en la segunda versión, también convierte primero la longitud a un carácter). Los operadores se dejan asociativos por defecto, por lo que esto encadena fácilmente.[]
con<>
.()<>[]
caracteres equilibrados , y luego (en la versión principal) mapeotoEnum
sobre la lista resultante.fuente
Japt ,
1914131098 bytesdonde la cadena al principio es:
El recuento total de bytes es "solo"
669433943354, por lo que puede probarlo en línea.Explicación
El método real utilizado se explica en otras respuestas: dividir
<>
, mapear cada ejecución de parenschr(len(x))
, unirse nuevamente en la cadena vacía. Aquí, el golf es la parte divertida.Antes de "jugar al golf", el código original podría verse así
que es una descripción bastante literal:
"...".split("<>").map(Z => Z.length.toChar()).join("")
ahora tenemos que minimizar los caracteres no entre paréntesis. ¿Cómo? Bueno, primero podemos practicar golf:Esto representa más o menos
"...".split("<>").map(Z => Z.length).map(Z => Z.toChar()).join()
.Ahora podemos abusar de la forma confusa en que Japt trata los paréntesis.
(
representa subir un nivel, como en la mayoría de los idiomas, pero)
representa bajar dos niveles (un espacio baja un nivel), lo que significa que podemos optimizar el código para:Este código actúa igual que el anterior, pero utiliza dos caracteres menos sin paréntesis.
Además, si un operador es la primera entrada a una función, se convierte en una cadena para que la función pueda decidir qué hacer con ella. Esto significa que podemos evitar las comillas si solo reducimos cada corrida de paréntesis 1 byte y, en su
>
lugar , lo dividimos (con un arreglo inteligente para cancelar>)
el código resultante ):Esto nos ahorra otros dos bytes, ya que eliminamos dos comillas.
fuente
Haskell , (
1965 313118073 bytes), puntaje31 2319Pruébalo en línea! Uso: La última línea es una función anónima. Atadlo a eg
f
y llama conf()
.Los 19 bytes sin paréntesis son
más una nueva línea final.
Versión de puntuación 23 (3131 bytes):
Pruébalo en línea! Los 23 bytes sin paréntesis son
Versión de puntuación 31 (1965 bytes):
Pruébalo en línea!
Después de eliminar todos los corchetes, estos 31 bytes permanecen:
¿Como funciona?
['\n'..'~']
produce la lista de todos los caracteres de la nueva línea~
que incluye todos los caracteres ASCII imprimibles.(<<>>)
es un identificador elegido para tener cero bytes bajo la regla de puntuación dada.(<<>>)=['\n'..'~']++(<<>>)
así se obtiene una repetición infinita de la lista de caracteres.En la segunda línea,
zip"> ... "(<<>>)
comprime una larga cadena de corchetes con la cadena infinita, produciendo una lista de tuplas con un corchete de caracteres en el primer componente y algunos caracteres ASCII en el segundo. Para cada tupla en esta lista, verificamos si coincide con el patrón('{'{-}-},(<>))
, es decir, si tiene un{
paréntesis como primer componente.{- ... -}
es un comentario en línea en Haskell, por lo que'{'{-}-}
es una versión equilibrada de'{'
. Si la coincidencia es exitosa, el segundo componente de la tupla se une al identificador(<>)
y se agrega a la construcción de la cadena a través de la comprensión de la lista. FinalmenteputStr
imprime la cuerda.putStr[(<>)|('{'{-}-},(<>))<-zip"> ... "(<<>>)]
La impresión directa de la cadena es de 46 bytes:
fuente
HTML, 37 bytes
fuente
<br>
etiqueta como esta:Surprise!<br>Happy Birthday, Brain-Flak!
<br>
es un byte más largo ya<p>
que lo he probado antes de publicar. Se ve un poco mejor. No uso ninguna etiqueta de cierre<p>
.05AB1E , 24 bytes
Utiliza la codificación 05AB1E . Pruébalo en línea!
fuente
Pyth,
4⃠3⃠2 bytesTachado 4 no es normal 4 si usas magia Unicode de
zalgoGracias a Roman Gräf y Neil por guardar 1 byte.
El código es
Cl(()()()
...()()())
donde el paréntesis externo contiene41505989310382548390036033574496753883572705382055993299460470741732071419050117038172961
copias concatenadas de()
. (Stack Exchange no me permitió publicar el código completo).Crea una tupla (
(
...)
) de tuplas vacías (()
), toma la longitud (l
) y la convierte en una cadena base-256 (C
).fuente
h
simplemente agregar otro par de paréntesis?h
dos posiciones a la derecha y aún funcionaría perfectamente ;-)Japt , 6687 bytes, puntaje 5
Pruébalo en línea!
Esto está en una línea similar a mi otra respuesta de Japt , pero usa matrices anidadas en lugar de una cadena. Lo bueno de las matrices anidadas (además del hecho de que definirlas no toma ningún byte) es que están preorganizadas, por lo que no tiene que hacer ninguna división elegante en la
<>
magia, o decodificar desde una gran número base 256, o algo así. La lógica real es justa.map(X => X.length).map(X => String.fromCharCode(X)).join("")
.fuente
Chip , 553 + 3 = 556 bytes, puntaje 127 + 3 = 130
+3 para arg
-w
. Pruébalo en línea!Los bytes sin paréntesis son
Sin golf / desequilibrado:
Como puede ver, el código original usa solo corchetes del lado derecho, por lo que todos los corchetes del lado izquierdo son solo para equilibrar. En el transcurso de la búsqueda de esta solución, encontré una representación de cadena mucho más densa en Chip que había tenido para mis respuestas anteriores, por ejemplo, hola mundo , y también las actualicé.
Cómo funciona:
El bit que cuelga de la izquierda produce un pulso de 1 ciclo para comenzar las cosas. Este pulso viaja a lo largo del
Z
's a una velocidad de 1 por ciclo, lo que proporciona el tiempo. Cuando cada unoZ
está alimentado, el mismo de la correspondiente columna produce el código ASCII del carácter en ese índice, que entonces se pone de salida por los elementosa
a través deg
(una por bit del byte de salida, excepto el bit altoh
que siempre es 0). Cuando finaliza,t
finaliza la ejecución.La codificación ascii es sencilla:
)
significa 1 yx
significa 0. Sin embargo, las 5 filas inferiores son principalmentex
, por lo que invierto esos bits en la solución final, intercambiando efectivamente los dos símbolos.¿Es este el mejor puntaje posible?
Lo dudo. En el mínimo absoluto, creo que necesitamos la siguiente: 1 cada uno
a
a través deg
, ya que esos son los bits de salida activos, 1*
o similares para proporcionar una señal de salida, 1t
para terminar la ejecución, 36Z
s oz
S para el tiempo de espera cada letra, y el comando arg-w
. Todo esto suma un puntaje de 48.Por encima de ese mínimo teórico, mi solución tiene 7 líneas nuevas, un segundo
*
, un extraZ
y 73x
s.fuente
C, 9265 bytes, puntaje 37
Véalo trabajar en línea .
C, 8589934626 bytes, puntaje 34
Donde
STRING
es el mismo literal de cadena grande que se usó en el ejemplo anterior, excepto que tiene dos diferencias en el medio de la cadena donde hay una subcadena<>
. Justo antes<
, hay 4294962688[
caracteres adicionales , y justo después>
hay 4294962688]
caracteres adicionales .El programa funcionará bajo los siguientes supuestos:
INT_MAX es 2 ^ 31-1, e INT_MIN es -2 ^ 31.
Compilado con comportamiento de envoltura para aritmética firmada. (-fwrapv)
La función strspn es capaz de procesar 4294962689 caracteres a la vez.
El compilador es capaz de compilar un literal de cadena compuesto por 8589934592 caracteres.
Esos supuestos son posibles en arquitecturas modernas de 64 bits, donde el tipo int es de 4 bytes y el tipo size_t es de 8 bytes. La función strspn devuelve el tipo size_t, y el mismo tipo está relacionado con el límite interno para el tamaño máximo del objeto. Escriba size_t con 8 bytes satisfaría los dos últimos supuestos.
Esta diferencia en esta versión es que la variable i no tiene que restablecerse a 0, ya que se ajusta a 0 después de que se imprime el último carácter.
fuente
Haskell , 9735 bytes, puntaje 9
Pruébalo en línea!
Los 9 bytes de puntuación son
Esto funciona en las versiones actuales de Haskell (GHC 8.4 o más reciente) donde
(<>)
estáPrelude
. Gracias a Ørjan Johansen por señalar que esto rompe mi solución anterior pero permite guardar otro byte de puntuación.Explicación
Como
(<>)
en dos listas es lo mismo(++)
, podemos representar una cadena"abc"
como en su"a"<>"b"<>"c"
lugar. Las cadenas son listas de caracteres, por lo que['a']<>['b']<>['c']
denota la misma cadena. Ahora, como en la respuesta anterior, sólo queremos una sola literal carácter, por lo que nos quedamos con uno más alto'c'
y representamos a los otros como predecesores del mismo:[pred(pred 'c')]<>[pred 'c']<>['c']
. Por último, mediante la sustitución'c'
con(<><>)
que es un identificador válido ypred
con(<<>>)
, obtenemos una codificación de la cadena"abc"
que sólo consta de paréntesis equilibrada:[(<<>>)((<<>>)(<><>))]<>[(<<>>)(<><>)]<>[(<><>)]
.La siguiente función codifica una cadena arbitraria de esta manera:
Pruébalo en línea!
fuente
(<<>>)
se usa tantas veces, creo que ahorrará muchos bytes si intercambias su nombre con el de<>
(pasando el último como un parámetro adicional).C # interactivo, 45 bytes
Lo sé, es un poco aburrido, pero si se ejecuta en C # interactivo, produce el resultado deseado, y en realidad dudo que haya una forma más pequeña de resolver esto en C #.
Sin embargo, hay una forma más difícil:
Pero esto es 145 Bytes grande.
Con saltos de línea se ve así:
Esto interpreta los corchetes como valores booleanos y luego como una cadena.
En realidad no soy un golfista de código avanzado, por lo que cualquier sugerencia es apreciada.
fuente
.Select(s =>
cumplir conS -> <S>
, usted podría cambiarlo a.Select(/*<*/s =>
C# Interactive
, también creo que se interpreta en C # interactivo, no compilado, pero todavía se considera un programa \ scriptCJam , 6683 bytes, puntaje 3
Acorté el código aquí para no saturar demasiado la página. Puede ver el código completo en el enlace TIO. Los únicos caracteres sin corchetes son
,c%
.Pruébalo en línea!
Explicación
El programa comienza empujando una matriz de matrices de matrices vacías. Cada submatriz contiene una serie de matrices vacías que corresponden a un valor ASCII de un carácter en la cadena deseada. Luego, para cada submatriz (
{...}%
), obtiene la longitud de la matriz (,
) y convierte esa longitud en un carácter (c
).La cadena resultante se imprime implícitamente.
fuente
C,
6964 bytesProbar en línea
Como lo hice
*
con{}
,>
con<>
y<
con[]
para que no cuenten, así que ahora este recuento de códigos es 1 debido al carácter inicialS
.<>
, resta[]
, imprime la suma actual{}
y termina al final de la cadena\0
.C, 49 bytes Probar en línea
fuente
p
para guardar algunos bytes?Lua 5.3, 108097107033101 bytes, puntaje
2827Aquí,
REPLACE
se reemplaza por una cadena de caracteres libres 108097107033034 de longitud. La cadena codifica los datos al colocarlos{}
en ciertas posiciones clave. El primerogsub
reemplazará la cadena por los índices de la{}
s (a través del grupo de captura vacío()
). El segundogsub
divide esta cadena resultante en bloques de 3 dígitos y reemplaza cada bloque por su representación ASCII.Tenga en cuenta que la sintaxis para las cadenas sin formato en Lua es (básicamente)
[[string contents]]
, lo cual es bastante útil para reducir la puntuación.La cadena (sin escape) que estoy generando es
print"Surprise!\nHappy Birthday, Brain-Flak!"
. Reemplazar cada carácter con su código ASCII decimal de 3 dígitos da112114105110116034083117114112114105115101033092110072097112112121032066105114116104100097121044032066114097105110045070108097107033034
. El código que uso solo puede generar secuencias de números naturales crecientes (al menos 2 separados) que no comienzan con ceros iniciales. Entonces, este número se divide en11, 2114, 105110, 1160340, 83117114, 112114105, 1151010330, 9211007209, 71121121210, 320661051141, 1610410009712, 10440320661140, 97105110045070, 108097107033034
. (Este último número es exactamente la longitud delREPLACE
valor, ya que la última coincidencia del patrón dará el índice de la final}
, observando que los índices Lua comienzan en 1. Si el último número fuera impar, entonces el patrón y la cadena tendrían modificarse ligeramente, aunque no es difícil.)En realidad, no generé y ejecuté este programa porque es demasiado grande (aunque en teoría podría funcionar en una máquina de 64 bits, no cabría en mi disco duro).
Como prueba de concepto, aquí hay un pequeño programa que imprime
3
utilizando el mismo principio:Esto genera la cadena de código a
p"3"
través del número a112034051034
través de la división11, 203, 405, 1034
.fuente
Pip , 6681 bytes, puntaje 3
(con muchos paréntesis y algunos corchetes redactados). Pruébalo en línea!
Construimos una lista de listas, cada una de las cuales contiene
()
(nula) varias veces.#*
asigna el operador de longitud, lo que resulta en una lista de números.C
toma cada número como un código ASCII y lo convierte en un carácter. La lista resultante de caracteres se concatena automáticamente y se imprime.¡Feliz cumpleaños tardío, Brain-Flak!
fuente
Mathematica, 40 bytes
Función anónima. No realiza ninguna entrada y devuelve una cadena como salida.
fuente
Jalea ,
1921 bytesAquí no hay nada inteligente, solo un diccionario + compresión de cadena del texto más una nueva línea final para eliminar una incomparable
<
.Para un enfoque verdaderamente golfista, vea esta respuesta de Erik the Outgolfer.
Pruébalo en línea!
fuente
PHP, 42 bytes
Pruébalo en línea!
-5 bytes la solución aburrida
PHP, 60 bytes
Pruébalo en línea!
fuente
<?=""?>
Apilado , puntaje 23
¿Dónde
...
está la cadena omitida? (Esto se puede generar con esto ).Pruébalo en línea!
Sí, no tan creativo. Obtiene el número de todos los
<>
s y los convierte en códigos de caracteres.fuente
Perl 5 , 3304 bytes, 16 puntaje
Pruébalo en línea!
Utiliza la codificación de longitud de ejecución del texto de la solución Python de @ HeebyJeebyMan.
fuente
Java, 140 bytes
Probar en línea
fuente
C, 52 bytes, puntaje 46
Versión ingenua Aquí está la versión optimizada .
fuente
Carbón , 37 bytes
Pruébalo en línea!
Solo imprime la cuerda.
fuente