Recientemente, alguien propuso límites más estrictos para la longitud de línea predeterminada de Python:
Claramente, ningún programa debería usar más de 80 caracteres por línea, por una gran cantidad de razones. En primer lugar, para facilitar la lectura y la mantenibilidad, es importante tener un estándar sólido, para que podamos ajustar el ancho de nuestros editores de texto de manera adecuada. Como beneficio secundario, el código se puede transferir fácilmente a medios que pueden tener restricciones, y donde agregar saltos de línea puede ser una distracción, como imprimir páginas para revisar en una reunión o tarjetas perforadas.
¿Pero son 80 caracteres demasiado altos? Algunos sugieren 79, o incluso tan bajo como 75, para permitir que una terminal de 80 caracteres de ancho se ajuste al código con unas pocas columnas dedicadas a números de línea. Claramente, en última instancia, más bajo es mejor, ya que los límites más bajos permiten que el código se use en más situaciones sin volver a formatear.
Su objetivo es encontrar y demostrar la longitud mínima de línea requerida por su idioma favorito escribiendo una variante de FizzBuzz con el menor número de caracteres en cualquier línea.
Entrada
Un número entero, n , a través de cualquier método deseado.
Salida
Imprima los números del 1 al n , ( n ≥ 1, n ∈ ℤ) separados por saltos de línea, excepto:
- para múltiplos de 3 imprimir "Apple"
- para múltiplos de 5 imprimir "Pie"
- para múltiplos de 3 y 5 imprime "ApplePie"
Tanteo
La longitud máxima de línea en bytes, sin incluir el salto de línea (Cr, CrLf, Lf u otro salto estándar del sistema, especifique, según lo desee), y la longitud total del código en bytes como un desempate.
Reglas
Todos los saltos de línea deben ser significativos. Deben eliminarse los saltos de línea que se pueden eliminar y las líneas adyacentes directamente concatenadas sin un impacto en la salida .
Respuestas:
> <> , 1 byte por línea,
243161135 bytes-26 bytes gracias a Jo King!
Lenguajes 2D FTW! Aunque escribir bucles y ramas usando instrucciones goto en lugar de la estructura 2D no es divertido.
Pruébalo en línea! , o míralo en el parque de peces !
El pez nada hacia abajo a lo largo del código, usando gotos condicionales para saltar cosas dependiendo de lo que divide el acumulador.
Creo que esto cumple con las especificaciones: cualquiera que sea la eliminación de las nuevas líneas, el pez siempre golpea la inicial
v
(la única instrucción de cambio de dirección presente), por lo que el pez siempre nada hacia abajo en la primera columna. Por lo tanto, eliminar una nueva línea tiene el efecto de simplemente eliminar el siguiente personaje del camino del pez, y no creo que pueda eliminar ninguno de los caracteres sin cambiar la salida.fuente
Haskell , 3 bytes / línea,
494 471 470 463 453 450461 bytesEDITAR:
-1+x
ax-1
.--
línea extra despuésx-
.f
uso enc 47:[]
lugar de[c 47&0]
.w
.a="Apple"
yp="Pie"
dentro,#
y use una recursión ficticia para el caso 15.w
en líneaf
. Eliminar redundantes--
entrex
y15
.%
función. Finalmente realicé algunas pruebas automatizadas para asegurarse de que no hubiera más sorpresas.f
toma unInt
y devuelve unString
.Pruébalo en línea!
¡Pruebe las restricciones de fuente! (La línea 70 se excluye de la prueba porque eliminar su nueva línea provoca un bucle infinito sin salida).
Versión con los trucos de compresión más importantes eliminados:
Cómo funciona
{}
. Como en realidad estoy definiendo una función en lugar de un programa completo, no estoy muy seguro de cómo contar bytes; Elegí contar defensivamente tanto el{}
s como un;
separador de declaración adicional (este último suele ser una nueva línea en el modo normal de Haskell).--
comentarios de línea, que hacen que la siguiente nueva línea no sea removible, y también una nueva línea anterior en el caso de que la línea anterior termine en un carácter de operador (que no es parte de un comentario de línea) .\
barras invertidas en literales de cadena, sangrados para continuar las líneas con posible sangría. Un espacio de cadena con delimitadores se elimina de la cadena analizada."Apple"
y"Pie"
esto se muestra directamente en la salida. For"8"
y"9"
una coincidencia de patrón se usa para dar un error si la cadena tiene más de un carácter.&
y%
, que permiten forzar que una línea termine en un carácter de operador para el primer truco. Necesitamos esto para finalizar los literales de cadena, porque\"
es demasiado ancho para agregar--
.&
es el general, definido de tal manera quex&y=x
.%
se define de tal manera que le[a]%y=a
permite reemplazar!!0
y hacer cumplir simultáneamente que su argumento de cadena debe tener una longitud 1.\n
parece imposible encajar en un literal de cadena con solo 3 bytes en la línea.c x=["9"%0,"8"%0..]!!x
se utiliza para convertir de unInt
carácter a otro, contando desde el dígito'9'
hacia abajo.show
tiene cuatro caracteres, la salida del número debe implementarse a mano.d
es una lista de las cadenas de dígitos"1".."9"
.n
es una lista infinita de representaciones numéricas["1","2","3",...]
definidas de forma recursivad
.#
convierte anInt
x
en su formulario ApplePie dado un primer argumento adicional que es elgcd
dex
con 15.fuente
Haskell , 7 bytes / línea, 339 bytes
El requisito de que los saltos de línea sean significativos lo convierte en un desafío no trivial en Haskell. Casi no hay formas de insertar saltos de línea que no se puedan eliminar, por lo que todo debe hacerse con declaraciones legítimamente pequeñas.
Pruébalo en línea!
fuente
Gelatina ,
32 bytes / línea,1068056 bytesLas filas y columnas del literal de cadena se transponen, por lo que eliminar las nuevas líneas desordena su orden.
Las líneas restantes son enlaces / funciones separadas y contienen llamadas a funciones (
¢
), por lo que solo se pueden concatenar si también se eliminan las llamadas a funciones.Pruébalo en línea!
fuente
TI-BASIC, 4 bytes por línea
Dado que el objetivo es solo minimizar la longitud máxima de la línea, algunas de las líneas son más largas de lo necesario, pero la más pequeña que pude hacer, la línea más larga fue de 4 bytes. Por lo tanto, sentí que facilitaría la lectura del código si fusionaba las líneas que se podían combinar sin exceder los 4 bytes.
Sin golf
Sobre el lenguaje y las limitaciones
TI-BASIC es un lenguaje tokenizado y, en este caso, cada uno de los tokens tiene 1 byte con la excepción de las
StrN
variables, que son 2 bytes. Además, puede dejar de paréntesis de cierre la mayor parte del tiempo. Laremainder(
función es de 2 bytes, por lo que su uso requeriría al menos 5 bytes (uno para la función, dos para los argumentos y uno para la comaremainder(I,3
). En cambio, utilicé las funcionesfPart(
ynot(
para hacerlo más corto, que son ambos tokens de 1 byte. Además, puede ver que uséAns
bastante la variable incorporada , ya que cualquier expresión que se evalúa en una línea por sí misma se almacena automáticamente en ella. Entonces, puedo guardar algunos bytes dividiendo las expresiones y las asignaciones.Otra estrategia era obviamente minimizar las asignaciones de cadenas. Mi método para hacerlo dependía de la longitud máxima de la línea en el resto del código. Una vez que determiné que era de 4 bytes, pude agrupar la mayor cantidad posible de cada cadena en la misma línea para minimizar la cantidad de tareas que necesitaba. Hice esto en aras de la legibilidad.
Los factores limitantes en este código son las asignaciones a variables de cadena y la concatenación con variables de cadena. Las líneas
Ans→Str1
yStr1+Ans
ambas son de 4 bytes en total. Tendría que encontrar una manera de eliminar completamente las variables de cadena para minimizar aún más la longitud máxima de línea en mi código. Todo lo demás se puede acortar a un máximo de 3 bytes o menos por línea.El problema allí radica en las asignaciones a variables numéricas, como
1→I
. No puede seguir jugando al golf sin llegar a una solución sin variables que no superen los 2 bytes en la longitud de la línea. Eso resulta imposible para este desafío.Los operadores binarios como
+
requieren el símbolo del operador y los argumentos izquierdo y derecho. Entonces, sin esto, no podría concatenar cadenas. Sin la concatenación de cadenas, no habría forma de mostrar las cadenas requeridas para que este programa complete el desafío sin exceder los 2 bytes en la longitud de la línea. Por lo tanto, el límite teórico para este desafío en este lenguaje sería de 3 bytes por línea, que no pude alcanzar.fuente
If A and B
Ans
token es 1 byte, mientras que los tres caracteres consecutivosAns
son 1, 2 y 2 bytes respectivamente para un total de 5. No es una cadena ASCII, es literalmente el token cuando lo escribe en la calculadora.C (gcc) , 2 bytes por línea,
374368320310262 bytesSupongo que se puede jugar un poco más. Las barras invertidas que escapan de las nuevas líneas lo hacen algo trivial.
Pruébalo en línea!
fuente
&&
.Python 3 , 4 bytes / línea, 113 bytes
Pruébalo en línea!
fuente
PHP 7, 2 bytes por línea
fuente
Aceto , 1 byte por línea, 230 bytes
Bueno, eso no fue divertido de escribir. Como fungoide, las estructuras de control de Aceto dependen en gran medida de su naturaleza 2D, pero podemos solucionarlo con muchos, muchos escapes condicionales (
`
). El único problema con esos es que afectan el siguiente comando, independientemente de su presencia (todos los programas de Aceto son cuadrados, internamente), por lo que debemos alinear el programa en algunos lugares insertando líneas vacías en algunos puntos.Los literales de cadena no se pueden usar realmente, pero los literales char sí se pueden (en algunos lugares; nuevamente, necesitamos alinearlos).
Llamado con
20
, esto imprime:Este nunca es el caso aquí porque se ejecuta desde abajo hacia arriba.
Hay al menos un lugar donde podemos guardar 2 bytes (reemplazando el
`X
con a|
o#
), pero lo mantuve como está debido al costo de tiempo de ejecución asociado con la ejecución de una curva de Hilbert relativamente grande.También ignoré el requisito implícito de usar
\r
o\r\n
líneas nuevas porque creo que es un error involuntario del OP. Si hay una edición o un comentario que refuerza este requisito, puedo cambiarlo sin muchos problemas para utilizar nuevas líneas CR en su lugar.El bytecount se basa en la codificación codegolfing de Aceto; Latin-7, en el que
£
hay un solo byte.fuente
Perl 5 , 2 bytes por línea, 182 bytes
Pruébalo en línea!
La sintaxis de Perl es muy indulgente, por lo que se pueden agregar muchas lagunas al código y agregar comentarios, lo que hace que la idea central sea bastante sencilla. El objetivo principal con este código es construir una cadena que contenga el código que queremos ejecutar, y
eval
esto. En Perl, es posible llamar a una función usando una cadena o variable con la&{...}
notación, desafortunadamente,eval
no es invocable en esta forma, pero loevalbytes
es, siempre que lo llame a través delCORE::
espacio de nombres. Construir esa cadena fue bastante sencillo y el programa se pasa directamente a esta llamada. Las cadenas se crean utilizando las nuevas líneas como parte de XOR, para construirlas utilicé este script. Para mantener esto válido, algunos lugares han tenido que tener comentarios colocados, de modo que eliminar las nuevas líneas resultaría en un código que no funciona.La rutina FizzBuzz fue tomada de la excelente respuesta de primo .
Perl 5 , 1 byte por línea, 172 bytes
Entonces, (ahora) sé que esto no es válido , porque se pueden eliminar muchas líneas nuevas, pero dado que este era mi enfoque original del problema, lo estoy agregando. ¡Fue divertido ver hasta dónde puede llegar la sintaxis de Perl! Disfruté este problema por mérito propio, aunque no es válido.
Pruébalo en línea!
fuente
SmileBASIC,
97 bytes por línea,159155154152 bytesEste fue un desafío muy divertido. Desafortunadamente, la regla contra saltos de línea innecesarios causa algunos problemas (aunque afortunadamente no afecta la longitud máxima de la línea aquí). Tuve que agregar comentarios entre líneas como
A%=I/3
yA=A%*3
, ya queA%=I/3A=A%*3
se analiza correctamente en SB. Yo era capaz de utilizar un truco para dejar de lado algunos comentarios, ya que la sustituciónA
conE
marcas que no es válida la línea (Tiene algo que ver con los números escritos usandoE
la notación, creo.3E
Se considera un número no válido en lugar de un número y un nombre de variable).La mayor limitación aquí es recibir aportes.
INPUT x
es la forma más sencilla permitida, la alternativa es definir una función con un valor de entrada comoDEF F x
pero que todavía tiene 7 caracteres. Hacer una declaración condicional también es difícil; No se me ocurre nada más corto queWHILE x
.fuente
A%=I/3A=A%*3
es sintácticamente válido pero lógicamente roto, no necesita el comentario char.A%=I/3
yA=A%*3
, por lo que se requiere el comentario.JavaScript (ES6), 3 bytes por línea
Utiliza la variable global
top
para acceder alwindow
objeto, de donde tomamoseval
el siguiente código:Tendrá que ejecutarlo en la consola ya que
top
es inaccesible desde un Fragmento de pila sandbox.fuente
C #, 9 bytes por línea,
248 242230 bytesDado que C # no se preocupa por los saltos de línea, necesita un comentario en línea al final de casi (gracias Ørjan Johansen) cada línea para cumplir con las reglas. Este programa espera n como argumento de línea de comando. Aquí hay tantas líneas nuevas no eliminables como sea posible:
Pero como la línea más larga es de 9 bytes, otras líneas también pueden alargarse tanto, lo que reduce algunos bytes:
fuente
//
entre tokens que se fusionen, comostatic
yvoid
.var
s="";if//
(i%3==0//
)s+=//
"Apple"//
;if(i%5//
.A
de la primera a la segunda línea.Python 2, 5 bytes / línea, 93 bytes
El estándar max6 ya está obsoleto.
Pruébalo en línea!
Python 2 y 3, 5 bytes / línea, 100 bytes
Pruébalo en línea!
fuente
JavaScript, máximo de 6 bytes / línea, 528 bytes
Idea arrancada de aquí .
Código arrancado desde aquí .
Gracias a Anders Kaseorg por
g=eval
guardar un byte por línea.Sin separar:
fuente
a=""+\n"f"+\n"o"+ ...
y terminar coneval(\na)
es un poco más cortof=eval
yf(a)
.PHP, 4 bytes / línea
Pruébalo en línea!
fuente
APL (Dyalog) , 5 bytes por línea
Pruébalo en línea!
fuente
Retina , 4 bytes / línea
Pruébalo en línea!
fuente
R , 10 bytes por línea, 800 bytes
La regla de "saltos de línea significativos" hizo que esto fuera un desafío. Actualmente, esto solo explica el código fizzbuzz en una cadena y luego lo ejecuta.
Pruébalo en línea!
Aquí está el código concatenado ApplePie (adaptado del golf de MickyT aquí ).
Y la versión no codificada del código de análisis:
Aquí uso
toString
para concatenar la lista de símbolosa
en una sola cadena. Sin embargo, el comportamiento predeterminado es separar cada símbolo con,
, por lo que llamamosgsub
para reemplazarlos por nulos. Luego lo pasamosparse
yeval
hacemos el trabajo sucio.Es posible que haya un enfoque que no utiliza este método de cadena de análisis y justo hacia arriba implementos FizzBuzz, pero me parece que el uso
for
o elwhile
o la definición de unafunction
necesidades líneas más largas que el enfoque actual.fuente
Ruby,
105 bytes / línea,354214 bytes-140 bytes del puntaje bruto de @NieDzejkob.
Cómo funciona
Ruby concatenará automáticamente secuencias de literales de cadena (excepto literales de un solo carácter como
?a
) en la misma declaración. Eso significa quex = "a" 'b' "c" %q{d}
es equivalente ax = "abcd"
. Usamos esto para dividir el código similar a FizzBuzz en cadenas mucho más pequeñas para llamareval
, ya+
que invalidará el programa debido a la regla de eliminación de líneas nuevas, ¡pero\
causará errores de sintaxis si se eliminan las líneas nuevas!fuente
eval
línea inicial es más larga que el resto, ¿verdad?Julia 0.6 , 5 bytes por línea, 168 bytes en total
Pruébalo en línea!
Esto
print
trae esto inevitablemente (afaict) a los 5 bytes por territorio de línea.Sin golf:
*
es el operador de concatenación de cadenas, por lo quea*p*"\n"
forma "ApplePie \ n".|>
es el operador de encadenamiento de funciones (/ piping), por lo que la cadena elegida se envía como argumento aprint
. Elsin
no se usa, solo está allí porqueprint
debe estar en una matriz para tener un espacio en blanco significativo después (usar el#
truco después de que llevará el recuento máximo de bytes por línea a 6).Si simplemente se permite devolver la salida como una matriz, se puede hacer con 4 bytes como máximo por línea:
Julia 0.6 , 4 bytes por línea, 152 bytes en total
Pruébalo en línea!
Una función que toma n y devuelve una matriz que contiene la salida esperada. La longitud máxima de la línea aquí está limitada por
n->
: Julia necesita eso en una sola línea para analizarlo correctamente como el inicio de una lambda.fuente
Pascal (FPC)
-Sew
, 6 bytes por línea,348320 bytesPruébalo en línea!
Utiliza FPC para obtener 6 bytes por línea; sin él, el resultado sería mucho peor. Este es el ancho de línea más pequeño posible ya que después
write
debe ser;
o(
(o espacios en blanco innecesarios), por lo que se inserta un comentario especial para evitar esto. Las características de FPC que influyeron en esta respuesta son://
- comenzando comentarios de una línea.{$<something>...}
son directivas del compilador. Si la directiva no existe, FPC emitirá una advertencia (y{$ ...}
también). En este programa,{
y$
se separan con una nueva línea que emitirá la advertencia cuando se elimine.-Sew
- El compilador también se detiene después de las advertencias, por lo que se unió{
y$
detuvo la compilación.fuente
Japt , 3 bytes por línea
Casi logró reducirlo a dos bytes por línea, pero el retorno del mapa se rompe si es seguido por una nueva línea.
La implementación de FizzBuzz en sí es del hilo canónico de FizzBuzz .
Pruébalo en línea!
fuente
LOLCODE ,
188 bytes por línea, 303 bytes en totalPruébalo en línea!
-10 bytes por línea usando el carácter de continuación de línea
…
, ¡gracias a Ørjan Johansen!fuente
Python 2 , 5 bytes / línea
Pruébalo en línea!
fuente
'z\"'
significa lo mismo que'z\
⏎"'
, por lo que la regla de nueva línea redundante significa que no puede iniciar una línea de continuación dentro de la cadena con"
.r'...'
ahoraSyntaxError
.FizzBuzz
a usarApplePie
.JavaScript (ECMAScript6), 2 bytes por línea
Larga explicación
La forma en que podemos acortar las líneas es transformando el código en una cadena y escapando de los extremos de la línea, esto impondrá un límite de 2bytes por línea.
Entonces se
alert(1)
conviertePero ahora su código es una cadena, por lo que debemos ejecutar la cadena como código. Sé al menos 4 formas en que puede ejecutar una cadena como código:
eval(
onclick=""
atributo, pero no pude hacer que la creación del elemento sea breve.Todas las funciones nativas de vida dentro de la ventana de objeto y en JavaScript puede acceder a las propiedades del objeto utilizando la notación de puntos por lo
eval()
convierte enwindow.eval()
, o se puede acceder a las propiedades utilizando el notación de corcheteswindow['eval']()
. Puede aprovechar esto para dividir eleval
en varias líneas utilizando el método descrito anteriormente. Pero aún tiene que escribir la ventana , un truco es que si no está dentro de un marco, la variable superior también es ventana, por lo que window.eval se convierte en top.eval (3 bytes menos).Entonces esto hará que el código sea mínimo de 3 bytes. Para hacer el código de 2 bytes, utilicé el
new Function(/*string*/);
constructor, pero tuve que ser creativo para acceder a él sin tener que escribirlo.Primero, el constructor de funciones le permite llamarlo como una función omitiendo la nueva palabra clave, esto reduce 4 bytes, pero también es importante por otra razón. Llamando al constructor como una función todavía devuelve una instancia de esta nos permite convertir
new Function(code)
aFunction(code)
. Otra cosa importante es que el constructor de funciones tiene uncall
método que le permite llamar a cualquier función pero anulando esta referencia, y el constructor de funciones en sí es una función a la que puede llamar un métodoFunction.call(null, code)
.Todas las funciones nativas son instancias del constructor de funciones, y todos los objetos en javascript tienen una propiedad de constructor . Por lo tanto, puede tener acceso al constructor de funciones en cualquier función nativa como
alert.constructor
, y utilizando el método de llamada podemos ejecutar el constructor como una función. Ahora tenemos alert.constructor.call (nulo, código) devuelve una función.combinando los thechiniques anteriores podemos convertirlo en
alert['constructor']['call'](null, code)
Ahora solo necesitamos encontrar una función o método con nombre corto, así que elijo el método big () dentro del constructor de cadenas. Entonces puedo acceder directamente desde una cadena vacía
"".big
Luego rompí todo en 2 bytes
Breve er explicación (TLDR)
Estoy accediendo al nuevo constructor de Función (código) para analizar la cadena en lugar de evaluar (código) . Este constructor está disponible en todas las funciones nativas haciendo anyFunction. constructor , como
alert.constructor===Function
. Estoy usando una función / método dentro del String.prototype.bigString.prototype.big.constructor.call(null, /*string*/)
Pero accediendo directamente desde un literal de cadena"".big
y lo convertí en notación de corchetes .""['big']['constructor']['call'](0, CODE)
para poder romperlo usando el\
.fuente
'
y]
se puede eliminar y el programa aún se ejecutará con éxito.Pip , 3 bytes por línea, 72 bytes en total
Pruébalo en línea!
Pip es extremadamente flexible sobre los espacios en blanco, por lo que la única estrategia que parece factible es crear una cadena, modificarla de una manera que requiera que las nuevas líneas no se alteren y evaluarla.
Creamos una cadena donde cada otro carácter es una nueva línea, y tomamos todos los demás caracteres usando
UW
(destejer) y unario@
(obtener el primer elemento):El resultado
@UW
debería ser nuestro código ApplePie, adaptado de la solución FizzBuzz aquí . Si se eliminan líneas nuevas en la cadena, esto no dará como resultado el código completo, dando un error de sintaxis o una salida incorrecta.Todavía hay dos nuevas líneas fuera de la cadena. Hicimos esto obligatorio mediante el uso del
Y
operador (yank), que aquí actúa como no operativo, junto con la forma en que Pip analiza corridas de letras mayúsculas:Entonces, si se eliminan estas nuevas líneas, el programa se analiza de manera diferente y no hace lo que se supone que debe hacer.
fuente
Java 8, 7 bytes por línea, 171 bytes
Un lambda vacío tomando un
int
. Sospecho que esto obedece el requisito con respecto a las nuevas líneas, pero no puedo probarlo, y verificarlo por la fuerza bruta tomaría aproximadamente un mes en mi computadora. Así que va.Pruébalo en línea
Bastante aburrido debido a los comentarios de línea. Lo único interesante aquí es el uso de una
System
referencia nula , que parece ser necesaria para imprimir a estándar en menos de 8 bytes por línea. Tenga en cuenta también que laprint
llamada al método es el cuello de botella.Ungolfed sin comentarios:
fuente