Brainf *** Golfista


32

Uno de los códigos más fáciles escritos por un lenguaje de programación es una secuencia de caracteres de impresión de programas (por ejemplo, "¡Hola, mundo!"). Sin embargo, s o m e e s o t e r i c lenguajes de programación como Brainfuck , incluso el código más simple es bastante molesto para escribir.

Su tarea es escribir un programa (no tiene que escribirlo en brainfuck), que imprime un programa Brainfuck (longitud mínima) que imprime el texto dado.

Entrada

Una secuencia de caracteres (entre 1y 255) viene dada por cualquier formato (variable, argumento, stdin, archivo, ...).

Salida

La salida es un código válido (sin coincidencias [y ]) brainfuck (suponga una celda de ajuste de 8 bits sin signo y un número ilimitado de celdas a izquierda y derecha) que imprime la cadena exacta que se proporcionó como entrada.

Por ejemplo, una salida posible para la entrada Aes ++++++++[<++++++++>-]<+..

Su programa no debería tardar mucho tiempo ( >2m) en ejecutarse.

El programa BF no debería tardar mucho tiempo ( >10s) en ejecutarse.

Tanteo

(Aviso: el método de puntuación actual puede cambiar, ya que no es fácil de calcular ...)

La longitud del programa (que genera el código BF) en sí misma no importa. Sin embargo, la codificación de códigos BF en el código del programa no está bien. Sólo rango aceptable (por ejemplo, un código de BF impresión de un solo carácter. 0x01: +.) De los códigos de BF podría ser modificable.

La puntuación es la suma de la longitud de los códigos BF que imprimen estas cadenas.

  • Una cadena Hello, world!añadida con un solo 0x0A( \n) (es decir, el programa "¡Hola, mundo!")
  • Solo personaje de 0x01~0xFF
    • La suma de la longitud de estos 255 códigos BF se multiplica por 1/16, se redondea y se agrega a la puntuación.
  • Lista de primeros 16 cuerdas, generados por la división de una secuencia aleatoria de bytes generada en 11-11-11 por 0x00, la eliminación de todas las cadenas de longitud cero.
  • Lenna.png , eliminando todos los 0x00s.
  • La letra de la canción 99 botellas de cerveza , comenzando con 99 bottles~líneas nuevas 0x0A, los párrafos están separados por dos 0x0Asy ningún carácter de línea nueva al final.
  • Otras cadenas que puede proporcionar.

Su programa puede incluir el cálculo de la puntuación de sí mismo.

Por supuesto, el código de puntaje más bajo será el ganador.


Duplicado (aunque mejor redactado) de codegolf.stackexchange.com/questions/3450/…
copie el

44
Esto parece bastante difícil de calcular los puntajes. Hay muchos archivos diferentes que necesitamos rastrear y ejecutar. ¿Cuál es el punto de 'Otras cadenas que puede proporcionar'? ¿Por qué agregaría más si se agrega a mi puntaje?
captncraig

1
Lenna.pngva a dominar el puntaje, ya que es, con mucho, el mayor aporte. ¿Quizás normalizar un poco por tamaño?
Keith Randall el

1
El código de longitud mínima para 'A' es ---- [----> + <]> ++.
Scony

1
A OP obviamente no le importa este desafío. ¿Vamos a editar las reglas de puntuación a algo sensato? Actualmente, solo una respuesta (sin éxito) intentó utilizar estas reglas, por lo que cambiar las reglas no invalidará las respuestas.
anatolyg

Respuestas:


15

En Java, calcula un fragmento BF corto que puede convertir cualquier número a cualquier otro número. Cada byte de salida se genera transformando el último byte de salida o un nuevo 0 en la cinta.

Los fragmentos se generan de tres maneras. Primero mediante simples repeticiones de +y -(por ejemplo, ++++convierte 7 a 11), combinando fragmentos conocidos (por ejemplo, si A convierte de 5 a 50 y B convierte de 50 a 37, luego AB convierte de 5 a 37) y multiplicaciones simples (por ejemplo, [--->+++++<]multiplica el número actual por 5/3). Las multiplicaciones simples aprovechan la envoltura para generar resultados inusuales (por ejemplo, --[------->++<]>genera 36 a partir de 0, donde el ciclo se ejecuta 146 veces, con un total de 4 envolturas descendentes y 1 ascendente).

Soy demasiado vago para calcular mi puntaje, pero utiliza aproximadamente 12.3 operaciones BF por byte Lenna.png.

import java.io.*;

class shortbf {
    static String repeat(String s, int n) {
        StringBuilder b = new StringBuilder();
        for (int i = 0; i < n; i++) b.append(s);
        return b.toString();
    }

    // G[x][y]: BF code that transforms x to y.                                                     
    static String[][] G = new String[256][256];
    static {
        // initial state for G[x][y]: go from x to y using +s or -s.                                
        for (int x = 0; x < 256; x++) {
            for (int y = 0; y < 256; y++) {
                int delta = y - x;
                if (delta > 128) delta -= 256;
                if (delta < -128) delta += 256;

                if (delta >= 0) {
                    G[x][y] = repeat("+", delta);
                } else {
                    G[x][y] = repeat("-", -delta);
                }
            }
        }

        // keep applying rules until we can't find any more shortenings                             
        boolean iter = true;
        while (iter) {
            iter = false;

            // multiplication by n/d                                                                
            for (int x = 0; x < 256; x++) {
                for (int n = 1; n < 40; n++) {
                    for (int d = 1; d < 40; d++) {
                        int j = x;
                        int y = 0;
                        for (int i = 0; i < 256; i++) {
                            if (j == 0) break;
                            j = (j - d + 256) & 255;
                            y = (y + n) & 255;
                        }
                        if (j == 0) {
                            String s = "[" + repeat("-", d) + ">" + repeat("+", n) + "<]>";
                            if (s.length() < G[x][y].length()) {
                                G[x][y] = s;
                                iter = true;
                            }
                        }

                        j = x;
                        y = 0;
                        for (int i = 0; i < 256; i++) {
                            if (j == 0) break;
                            j = (j + d) & 255;
                            y = (y - n + 256) & 255;
                        }
                        if (j == 0) {
                            String s = "[" + repeat("+", d) + ">" + repeat("-", n) + "<]>";
                            if (s.length() < G[x][y].length()) {
                                G[x][y] = s;
                                iter = true;
                            }
                        }
                    }
                }
            }

            // combine number schemes                                                               
            for (int x = 0; x < 256; x++) {
                for (int y = 0; y < 256; y++) {
                    for (int z = 0; z < 256; z++) {
                        if (G[x][z].length() + G[z][y].length() < G[x][y].length()) {
                            G[x][y] = G[x][z] + G[z][y];
                            iter = true;
                        }
                    }
                }
            }
        }
    }
    static void generate(String s) {
        char lastc = 0;
        for (char c : s.toCharArray()) {
            String a = G[lastc][c];
            String b = G[0][c];
            if (a.length() <= b.length()) {
                System.out.print(a);
            } else {
                System.out.print(">" + b);
            }
            System.out.print(".");
            lastc = c;
        }
        System.out.println();
    }

    static void genFile(String file) throws IOException {
        File f = new File(file);
        int len = (int)f.length();
        byte[] b = new byte[len];
        InputStream i = new FileInputStream(f);
        StringBuilder s = new StringBuilder();
        while (true) {
            int v = i.read();
            if (v < 0) break;
            if (v == 0) continue; // no zeros                                                       
            s.append((char)v);
        }
        generate(s.toString());
    }
    public static void main(String[] args) throws IOException {
        genFile(args[0]);
    }
}

Sé que llego unos dos años y medio tarde y esto no es golf, pero el método de repetición podría ser simplemente devolver una nueva cadena (nuevo carácter [longitud]). ReplaceAll ("\ 0", str);
Loovjo

13

Bueno, aquí está la peor solución posible, aunque una muy bonita en Brainfuck:

++++++[>+++++++>+++++++++++++++>+++++++<<<-]>++++>+>+>,[[<.>-]<<<.>.>++.--<++.-->>,]

El puntaje es probablemente el peor que podemos ver sin intencionalmente hacerlo malo.

Trabajando en el cálculo de la puntuación real.


¿Podría explicar qué hace esto? Leer el código BF es bastante difícil.
BMac

3
Para cada byte de entrada, simplemente imprime N +'s y a.
captncraig

Con creo que a [-]para limpiar la celda entre cada personaje.
captncraig

8

Python 3.x

Bueno, no voy a ganar ningún premio por el código de salida más corto, pero tal vez por el programa para generar el código ...

x=input();o=''
for i in x:
 a=ord(i)
 o+="+"*a+".[-]"
print(o)

'¡Hola, mundo! \ N':

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.[-]++++
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+++++++++++++++++.[-]+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+++++++++++++++++++++++++++++++++++++++++++++++++.[-]+++++++++++++++++++++++++++
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+.[-]+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++++++++++++++++++++++++++++++++++++.[-]++++++++++++++++++++++++++++++++++++++++
++++.[-]++++++++++++++++++++++++++++++++.[-]++++++++++++++++++++++++++++++++++++
+++++++++++++++++++++++++++++++++++++++++++++++++++.[-]+++++++++++++++++++++++++
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++++++.[-]++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++++++++++++++++++++++++++++++++++++++++++++.[-]++++++++++++++++++++++++++++++++
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.[-]
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++++++++++++++++++++.[-]+++++++++++++++++++++++++++++++++.[-]++++++++++.[-]

1
Respondió accidentalmente a la respuesta de Madison. Generador más corto:print("".join(["+"*ord(i)+".[-]"for i in input()]))
FatalError

Puede jugar golf en su programa por 2 caracteres reemplazándolo .[-]con.>
MilkyWay90


8

No estoy seguro de lo bueno que es, pero me divertí escribiendo esto. (En Clojure ...)

(ns bf.core)
(def input "Hello world!")
(defn abs [x] (if (and (< x 0) (= (type x) (type 1))) (* x -1) x)) 
(defn sqrt? [x y] (if (= (* y y) x) true false) )
(defn sqrt [x] (for [y (range x) :when (sqrt? x y)] y) )
(defn broot [x]
;  Run this using trampoline, e.g., (trampoline broot 143)
  (if (< x 2) nil)
  (let [y (sqrt x)]
    (if (not= (seq y) nil)
      (first y)
      (broot (dec x) )
      )
    )
  )
(defn factor [x]
  (if (<= x 2) x)
  (for [y (range (- x 1) 1 -1)
        :when (= ( type (/ x y) ) (type 1) )
        ]
    y)
  )

(defn smallest_factors [x]
  (let [ facts (factor x) ]
  (if (= (count facts) 2) facts)
  (if (< (count facts) 2) (flatten [facts facts])
    (let [ y (/ (dec (count facts) ) 2)
          yy (nth facts y)
          z (inc y)
          zz (nth facts z)
          ]
      (if (= (* yy zz) x ) [yy zz] [yy yy])
      )
    )
    )
  )

(defn smallestloop [x]
  (let [ facts (smallest_factors x)
        fact (apply + facts)
        sq (trampoline broot x)
        C (- x (* sq sq) )]
    (if (and (< fact (+ (* 2 sq) C) ) (not= fact 0))
      facts
      [sq sq C])
    )
  )
(def lastx nil)
;Finally!
(defn buildloop [x]
  (if (nil? lastx)
     (let [pluses (smallestloop x)]
       (apply str
              (apply str (repeat (first pluses) \+))
              "[>"
              (apply str (repeat (second pluses) \+))
              "<-]>"
              (if (and (= (count pluses) 3) (> (last pluses) 0))
                (apply str(repeat (last pluses) \+))
              )
              "."
              )
    )
    (let [diff (abs (- x lastx) )]
      (if (< diff 10)
        (if (> x lastx)
          (apply str
               (apply str (repeat diff \+))
               "."
                 )
          (apply str
                 (apply str (repeat diff \-))
                 "."
                 )
          )
        (let [signs (smallestloop diff)]
          (apply str
             "<"
             (apply str (repeat (first signs) \+))
             "[>"
             (if (> x lastx)
               (apply str (repeat (second signs) \+))
               (apply str (repeat (second signs) \-))
             )
             "<-]>"
             (if (and (= (count signs) 3) (> (last signs) 0))
               (if (> x lastx)
                 (apply str(repeat (last signs) \+))
                 (apply str(repeat (last signs) \-))
               )
             )
             "."
           )
         )
        )
      )
    )
  )
(for [x (seq input)
  :let [y (buildloop (int x))]
      ]
  (do 
   (def lastx (int x))
   y
   )
  )

Probablemente hay soluciones más eficientes y más elegantes, pero esto sigue mi patrón de pensamiento de forma algo lineal, por lo que fue más fácil.


8

Puntuación: 4787486 41439404086426 (sin datos generados aleatoriamente)

(4085639 de eso son de Lenna.png. Eso es 99.98%)

No entiendo la parte con los datos aleatorios. ¿No necesito una cuenta que deba pagar para obtener los datos?

Bastante ingenuo. Aquí está el código generado para "1Aa" (49, 65, 97) con un poco de documentación:

                   // field 0 and 1 are loop counters.
                   // The fields 2, 3 and 4 are for "1", "A" and "a"
++++++++++[        // do 10 times
    >
    ++++++++++[    // do 10 times
        >          // "1" (49) is below 50 so we don't need to do anything here
        >+         // When the loops are done, this part will have increased the value of field 3 by 100 (10 * 10 * 1)
        >+         // same as above
        <<<-       // decrease inner loop counter
    ]
    >+++++         // this will add 50 (10 * 5) to field 2, for a total of 50
    >----          // subtract 40 from field 3, total of 60
    >              // Nothing done, value stays at 100
    <<<<-          // decrease outer loop counter
]
>>-.               // subtract 1 from field 2, total now: 49, the value for "1"
>+++++.            // add 5 to field 3, makes a total of 65, the value for "A"
>---.              // subtract 3 from field 4, total of 97, the value for "a"

El código de Java es un poco feo pero funciona. La instrucción generada por la relación de bytes de entrada es probablemente mejor cuanto mayor sea el valor promedio de bytes.

Si desea ejecutarlo, debe colocar Lenna.png en el mismo directorio que el archivo .class. Imprime el puntaje en la consola y escribe el código BF generado en un archivo llamado "output.txt".

import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Arrays;


public class BrainFuckGenerator {
    public static CharSequence generate(byte[] bytes) {
        final StringBuilder brainfuckBuilder = new StringBuilder();
        for(int j = 0; j<10; j++)
                brainfuckBuilder.append("+");

        brainfuckBuilder.append("[>");

        for(int j = 0; j<10; j++)
            brainfuckBuilder.append("+");

        brainfuckBuilder.append("[");

        final StringBuilder singles = new StringBuilder();
        final StringBuilder tens = new StringBuilder();
        final StringBuilder goBack = new StringBuilder();

        for(byte b: bytes) {
            brainfuckBuilder.append(">");
            for(int j=0; j<(b/100); j++) {
                brainfuckBuilder.append("+");
            }

            tens.append(">");
            if((b - (b/100)*100)/10 <= 5) {
                for(int j=0; j<(b - (b/100)*100)/10; j++) {
                    tens.append("+");
                }
            } else {
                brainfuckBuilder.append("+");
                for(int j=0; j<10 - (b - (b/100)*100)/10; j++) {
                    tens.append("-");
                }
            }

            singles.append(">");
            if(b%10 <= 5) {
                for(int j=0; j<b%10; j++) {
                    singles.append("+");
                }
            } else {
                tens.append("+");
                for(int j=0; j<10 - (b%10); j++) {
                    singles.append("-");
                }
            }
            singles.append(".");

            goBack.append("<");
        }
        goBack.append("-");

        brainfuckBuilder
            .append(goBack)
            .append("]")
            .append(tens)
            .append("<")
            .append(goBack)
            .append("]>")
            .append(singles);

        return brainfuckBuilder;
    }

    public static void main(String[] args) {
        /* Hello, World! */
        int score = score("Hello, world!"+((char)0xA));

        /* 255 single chars */
        int charscore = 0;
        for(char c=1; c<=0xff; c++)
            charscore += score(String.valueOf(c));

        score += Math.round(((double)charscore)/16);

        /* Lenna */
        final File lenna = new File("Res/Lenna.png");
        final byte[] data = new byte[(int)lenna.length()];
        int size = 0;
        try(FileInputStream input = new FileInputStream(lenna)) {
            int i, skipped=0;
            while((i = input.read()) != -1)
                if(i == 0)
                    skipped++;
                else
                    data[size++ - skipped] = (byte)(i&0xff);
        } catch (IOException e) {
            e.printStackTrace();
        }

        score += score(Arrays.copyOf(data, size), "Lenna");

        /* 99 Bottles */
        final StringBuilder bottleBuilder = new StringBuilder();
        for(int i=99; i>2; i--) {
            bottleBuilder
                .append(i)
                .append(" bottles of beer on the wall, ")
                .append(i)
                .append(" bottles of beer.")
                .append((char) 0xa)
                .append("Take one down and pass it around, ")
                .append(i-1)
                .append(" bottles of beer on the wall.")
                .append((char) 0xa)
                .append((char) 0xa);

        }

        bottleBuilder
            .append("2 bottles of beer on the wall, 2 bottles of beer.")
            .append((char) 0xa)
            .append("Take one down and pass it around, 1 bottle of beer on the wall.")
            .append((char) 0xa)
            .append((char) 0xa)
            .append("No more bottles of beer on the wall, no more bottles of beer. ")
            .append((char) 0xa)
            .append("Go to the store and buy some more, 99 bottles of beer on the wall.");

        score(bottleBuilder.toString(), "99 Bottles");
        System.out.println("Total score: "+score);
    }

    private static int score(String s) {
        return score(s, null);
    }

    private static int score(String s, String description) {
        final CharSequence bf = generate(s.getBytes());
        try(FileWriter writer = new FileWriter("Res/output.txt", true)) {
            writer.write((description == null ? s : description));
            writer.write(NL);
            writer.write("Code:");
            writer.write(NL);
            writer.write(bf.toString());
            writer.write(NL+NL);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return bf.length();
    }

    private static int score(byte[] bytes, String description) {
        final CharSequence bf = generate(bytes);
        try(FileWriter writer = new FileWriter("Res/output.txt", true)) {
            if(description != null) {
                writer.write(description);
                writer.write(NL);
            }
            writer.write("Code:");
            writer.write(NL);
            writer.write(bf.toString());
            writer.write(NL+NL);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return bf.length();
    }

    private static final String NL = System.getProperty("line.separator");
}

Voy a hacer algunas pequeñas mejoras, pero probablemente no muchas. Hecho.


Esto está roto, el BF generado genera bytes NUL o '?' caracteres según la configuración regional para cualquier carácter que no esté en 1..127. Sin embargo, ASCII simple (1-127) parece estar bien. Al darse cuenta de que los (byte) están firmados y elegir cuidadosamente un entorno local, se obtienen muchos de ellos (tomando la puntuación por encima de 5800000), pero todavía hay varios miles de NUL de la conversión bf de Lenna.png. Entonces hay algo más también.
user3710044

4

BrainF ** k

Soy un programador de BF bastante malo, por lo que esta respuesta es probablemente bastante ineficiente. No estoy seguro de la puntuación, pero debería funcionar ligeramente mejor que la respuesta existente en su texto promedio. En lugar de poner a cero la celda después de cada carácter, este se "ajustará" a un nuevo carácter con resta si el carácter anterior dado es más grande.

>>++++++[-<+++++++>]<+>>+++++[-<+++++++++>]>+++++[-<+++++++++>]<+>>,[-<+>>>>>>+<<<<<]<[-<<<.>>>]<.>>+>,[[-<<+>>>+>>+<<<]>>>>[-<<+>>]<[->+<]<<[->-[>]<<]<[->->[-<<<<<<.>>>>>>]<<]>+[-<<->>>[-<<<<<<.>>>>>>]<]<<<[>]<<.>[-]>+>,]

(Tenga en cuenta que este es un código que escribí hace mucho tiempo y que he reutilizado para esta competencia. Sinceramente espero haber realizado la conversión correctamente, pero si falla alguna entrada, hágamelo saber).

Una versión que muestra el estado de la cinta en todo el código:

>>++++++[-<+++++++>]<+>             [0 '+' 0]
                                           ^
>+++++[-<+++++++++>]                [0 '+' '-' 0]
                                               ^
>+++++[-<+++++++++>]<+>             [0 '+' '-' '.' 0]
                                                   ^
>,[-<+>>>>>>+<<<<<]                 [0 '+' '-' '.' a 0 0 0 0 0 a]
                                                     ^
<[-<<<.>>>]<.>>+>                   [0 '+' '-' '.' 0 1 0 0 0 0 a]
                                                       ^
,[[-<<+>>>+>>+<<<]                  [0 '+' '-' '.' b 1 0 b 0 b a]
                                    [b is not 0]       ^
>>>>[-<<+>>]<[->+<]                 [0 '+' '-' '.' b 1 0 b a 0 b]
                                                             ^    
<<[->-[>]<<]

<[->->[-<<<<<<.>>>>>>]<<]           

>+[-<<->>>[-<<<<<<.>>>>>>]<]        [0 '+' '-' '.' b 0 0 0 0 0 b]
                                                       ^|^
                                    [OUTPUT ONE CHARACTER BY THIS POINT]
<<<[>]<<.>[-]>                      [0 '+' '-' '.' 0 0 0 0 0 0 b]
                                                     ^
+>,]                                [End when b == 0]
                                    [GOAL: '+' '-' '.' b 1 0 b a 0 a]

Código generado para Hello, World!:

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.+++++++++++++++++++++++++++++.+++++++..+++.-------------------------------------------------------------------.------------.+++++++++++++++++++++++++++++++++++++++++++++++++++++++.++++++++++++++++++++++++.+++.------.--------.-------------------------------------------------------------------.

Esta es mi primera respuesta en CG.SE! Si he arruinado algo, ¡avísame!


4

> <>

i:&v
.21<>i:0(?;:&:@(4g62p$:&-01-$:@0(?*l2=?~02.
>:?!v"+"o1-
"."~<.15o
+-

Escribí esto en respuesta a una pregunta marcada para un duplicado, y aunque este no es el mejor golf (al menos para esta pregunta específica), pensé que sería un desperdicio si no lo compartía toda su asquerosamente galimatizante gloria. Realmente, estoy medio sorprendido de que incluso funcione. Tomaré cualquier sugerencia para jugar golf ya que ese era mi objetivo principal en su creación.

Como nota al margen, en la segunda línea los tres primeros caracteres .21podrían reemplazarse porv seguidos de dos espacios si eso facilita la lectura. No me gusta ver espacios en mis programas> <> porque eso significa que hay espacio desperdiciado (literalmente). También es un remanente de uno de los muchos prototipos.

La forma en que funciona es realmente simple y, francamente, me resultaría difícil pensar en una forma de implementar otro algoritmo. Imprime sin embargo, se deben imprimir muchos "+" para el primer carácter, y luego imprime más "+" o "-" según sea necesario para cada carácter adicional, separando cada sección con puntos. Lo que me parece genial del programa es que modifica su propio código fuente para que imprima "+" o "-" (reemplaza el "+" en la línea 3 con el carácter apropiado después de determinar si el carácter actual es mayor que o menos que el anterior).

Salida para Hello, World!:

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.+++++++++++++++++++++++++++++.+++++++..+++.-------------------------------------------------------------------.------------.+++++++++++++++++++++++++++++++++++++++++++++++++++++++.++++++++++++++++++++++++.+++.------.--------.-------------------------------------------------------------------.

Podría puntuar esto de la forma en que estaba destinado a ser puntuado, pero estoy casi seguro de que perdería y no sé completamente cómo leer algo como lenna.png en> <>.

Si esta respuesta le interesa y desea una explicación, pregunte por todos los medios, pero por ahora la dejaré sin una solo por lo retorcida y excitante que es.

EDITAR 1: Ha pasado un tiempo, pero pude jugar golf 2 bytes con una revisión casi completa de la forma en que el programa decide si imprime un más o un menos. Es un retorno algo decepcionante para una gran revisión, pero al menos funciona.


¡Este programa de galimatías hace otro programa de galimatías! ¡Este es el mejor programa que he visto!
Aequitas

1

mi solución de JavaScript es rápida y sucia :)

salida para Hello World\n

++++++++++[>+++++++>++++++++++>+++++++++++>+++>+++++++++>+<<<<<<-]>++.>+.>--..+++.>++.>---.<<.+++.------.<-.>>+.>>.

Fuente:

BfGen("Hello World!\n");
// ++++++++++[>+++++++>++++++++++>+++++++++++>+++>+++++++++>+<<<<<<-]>++.>+.>--..+++.>++.>---.<<.+++.------.<-.>>+.>>.
// Length of BF code: 115
// Score: 8.846153846153847


function BfGen(input) {
    function StringBuilder() {
        var sb = {};

        sb.value = '';
        sb.append = (txt) => sb.value += txt;

        return sb;
    }

    function closest (num, arr) {
        var arr2 = arr.map((n) => Math.abs(num-n))
        var min = Math.min.apply(null, arr2);
        return arr[arr2.indexOf(min)];
    }

    function buildBaseTable(arr) {
        var out = StringBuilder();
        out.append('+'.repeat(10));
        out.append('[')
        arr.forEach(function(cc) {
            out.append('>');
            out.append('+'.repeat(cc/10));    
        });
        out.append('<'.repeat(arr.length));
        out.append('-');

        out.append(']');
        return out.value;
    }

    var output = StringBuilder();

    var charArray = input.split('').map((c) =>c.charCodeAt(0));
    var baseTable = charArray.map((c) => Math.round(c/10) * 10).filter((i, p, s) => s.indexOf(i) === p);

    output.append(buildBaseTable(baseTable));

    var pos = -1;
    charArray.forEach(function (charCode) {
        var bestNum = closest(charCode, baseTable);
        var bestPos = baseTable.indexOf(bestNum);

        var moveChar = pos < bestPos? '>' : '<';
        output.append(moveChar.repeat(Math.abs(pos - bestPos)))
        pos = bestPos;

        var opChar = baseTable[pos] < charCode? '+': '-';
        output.append(opChar.repeat(Math.abs(baseTable[pos] - charCode)));
        output.append('.');
        baseTable[pos] = charCode;
    });

    console.log(output.value)
    console.log('Length of BF code: ' + output.value.length);
    console.log('Score: ' + output.value.length / input.length);
}

2
Bienvenido al sitio! Debe incluir el puntaje en el título de su respuesta.
Wheat Wizard

Acabo de hacer el generador de bf, el sistema de puntuación original tiene un procesamiento de imágenes que no es relevante :( Hello World ratio es menor que 9 (longitud de bf / longitud del texto original)
Peter

1

Construí algo en Java. No calculé el puntaje. Los textos con 3 o menos caracteres están codificados con una multiplicación por letra, por ejemplo, "A" = ++++++++[>++++++++<-]>+.. Los textos con más de 3 caracteres están codificados con una lista calculada que se divide en 3 áreas. La primera área es x veces 49, luego más x veces 7 y finalmente más x. Por ejemplo, "A" es 1 * 49 + 2 * 7 + 2

public class BFbuilder {
    public static void main(String[] args) {
        String text = "### INSERT TEXT HERE ###";

        if (text.length()<=3){
            String result = "";
            for (char c:text.toCharArray()) {
                result += ">";
                if (c<12) {
                    for (int i=0;i<c;i++) {
                        result += "+";
                    }
                    result += ".>";
                } else {
                    int root = (int) Math.sqrt(c);
                    for (int i = 0; i<root;i++) {
                        result += "+";
                    }
                    result += "[>";
                    int quotient = c/root;
                    for (int i = 0; i<quotient;i++) {
                        result += "+";
                    }
                    result += "<-]>";
                    int remainder = c - (root*quotient);
                    for (int i = 0; i<remainder;i++) {
                        result += "+";
                    }
                    result += ".";
                }
            }
            System.out.println(result.substring(1));
        } else {
            int[][] offsets = new int[3][text.length()];
            int counter = 0;
            String result = "---";

            for(char c:text.toCharArray()) {
                offsets[0][counter] = c/49;
                int temp = c%49;
                offsets[1][counter] = temp/7;
                offsets[2][counter] = temp%7;
                counter++;
            }

            for (int o:offsets[0]) {
                switch (o) {
                case 0: result+=">--";
                break;
                case 1: result+=">-";
                break;
                case 2: result+=">";
                break;
                case 3: result+=">+";
                break;
                case 4: result+=">++";
                break;
                case 5: result+=">+++";
                break;
                }
            }
            result += ">+[-[>+++++++<-]<+++]>----";
            for (int o:offsets[1]) {
                switch (o) {
                case 0: result+=">---";
                break;
                case 1: result+=">--";
                break;
                case 2: result+=">-";
                break;
                case 3: result+=">";
                break;
                case 4: result+=">+";
                break;
                case 5: result+=">++";
                break;
                case 6: result+=">+++";
                break;
                }
            }
            result += ">+[-[>+++++++<-]<++++]>----";
            for (int o:offsets[2]) {
                switch (o) {
                case 0: result+=">---";
                break;
                case 1: result+=">--";
                break;
                case 2: result+=">-";
                break;
                case 3: result+=">";
                break;
                case 4: result+=">+";
                break;
                case 5: result+=">++";
                break;
                case 6: result+=">+++";
                break;
                }
            }
            result += ">+[-<++++]>[.>]";
            System.out.println(result);
        }
    }
}

La cadena proporcionada "### INSERT TEXT AQUÍ ###" se convierte --->-->-->-->-->->->->->->->-->->->->->-->->->->->-->-->-->-->+[-[>+++++++<-]<+++]>---->++>++>++>+>>+>+>->+>++>+>++>->++>++>+>>->+>->+>++>++>++>+[-[>+++++++<-]<++++]>---->--->--->--->+>>-->+++>+++>++>--->+>--->+++>+>--->+>->+++>++>+++>+>--->--->--->+[-<++++]>[.>]

"¡Hola Mundo!" se convierte --->->>>>>-->-->->>>>>-->+[-[>+++++++<-]<+++]>---->>--->-->-->-->+++>+>++>-->->-->--->+>+[-[>+++++++<-]<++++]>---->->>>>+++>->+>>+++>->>->++>+[-<++++]>[.>]


1

Python 3

print("".join("+"*ord(i)+".[-]"for i in input()))

Esta es esencialmente una versión ligeramente mejorada de la respuesta de icedvariables. (-1 Byte de Wheat Wizard, -5 de FatalError, -2 de jez)


Creo que esto es Python 3. Si es así, debe incluirlo en su encabezado. Si es así, también puede eliminar el salto de línea después de su :. Esto probablemente también se podría hacer como una lista de comprensión para guardar bytes.
Wheat Wizard

-5 bytes conprint("".join(["+"*ord(i)+".[-]"for i in input()]))
FatalError

-2 bytes: pierden los corchetes, por lo que invocan join()una expresión generadora en lugar de una comprensión de la lista: print("".join("+"*ord(i)+".[-]"for i in input()))
jez

-2 bytes: simplemente puede pasar a la siguiente celda (la pregunta indica que debe asumir una banda infinita en ambas direcciones print("".join("+"*ord(i)+".>"for i in input())) (esto también reduce la puntuación ya que pierde 2 bytes en la salida)
MegaIng
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.