Brainf *** Golfer

32

Jednym z najłatwiejszych kodów napisanych przez język programowania jest program wypisujący ciąg znaków (np. „Witaj, świecie!”). Jednak s o m e e e o t e r i c języki programowania takie jak brainfuck , nawet ta najprostsza kod jest dość irytujące pisać.

Twoim zadaniem jest napisanie programu (nie musisz pisać w pieprzony mózg), który wypisze (minimalnej długości) program Brainfuck drukujący podany tekst.

Wkład

Sekwencja znaków (między 1i 255) jest podana w dowolnym formacie (zmienna, argument, stdin, plik, ...).

Wydajność

Dane wyjściowe to prawidłowy (bez niepasujących [i ]) kod pieprzony mózg (zakładamy niepodpisaną 8-bitową komórkę zawijającą i nieograniczoną liczbę komórek po lewej i prawej stronie) drukującą dokładnie ciąg podany jako dane wejściowe.

Na przykład jednym z możliwych danych wejściowych Ajest ++++++++[<++++++++>-]<+..

>2mUruchomienie programu nie powinno zająć dużo czasu ( ).

Uruchomienie programu BF nie powinno zająć dużo czasu ( >10s).

Punktacja

(Uwaga: obecna metoda punktacji może ulec zmianie, ponieważ obliczenie nie jest łatwe ...)

Długość samego programu (generującego kod BF) nie ma znaczenia. Jednak kodowanie na stałe kodów BF w kodzie programu jest nieprawidłowe. Tylko dopuszczalny zakres (ex kod BF drukowania pojedynczego znaku. 0x01: +.) Kodów BF mogą być zakodowane.

Wynik jest sumą długości kodów BF drukujących te ciągi.

  • Ciąg Hello, world!dołączany z pojedynczym 0x0A( \n) (tj. Programem „Witaj, świecie!”)
  • Pojedynczy znak od 0x01~0xFF
    • Suma długości tych 255 kodów BF jest mnożona 1/16, zaokrąglana i dodawana do wyniku.
  • Lista pierwszych 16 ciągów, wygenerowanych przez podzielenie losowej sekwencji bajtów wygenerowanych 11-11-11 przez 0x00usunięcie wszystkich ciągów o zerowej długości.
  • Lenna.png , usuwając wszystkie 0x00s.
  • Tekst piosenki 99 butelek piwa , począwszy od 99 bottles~nowych linii 0x0A, akapity są oddzielone dwoma 0x0As, a na końcu nie ma znaku nowej linii.
  • Inne ciągi, które możesz podać.

Twój program może obejmować obliczanie wyniku samego siebie.

Oczywiście zwycięży kod o najniższym wyniku.

JiminP
źródło
Duplikat (choć lepiej sformułowany) codegolf.stackexchange.com/questions/3450/…
skopiuj
4
Wydaje się to raczej trudne do obliczenia wyników. Jest wiele różnych plików, które musimy wyśledzić i uruchomić. Jaki jest sens „Innych ciągów, które możesz podać”. Dlaczego miałbym dodawać więcej, jeśli będzie to dodawać do mojego wyniku?
captncraig
1
Lenna.pngzdominuje wynik, ponieważ jest to zdecydowanie największy wkład. Może znormalizować trochę według rozmiaru?
Keith Randall,
1
Kod minimalnej długości dla „A” to ---- [----> + <]> ++.
Scony
1
OP oczywiście nie przejmuje się tym wyzwaniem. Zmieńmy reguły punktacji na coś sensownego? Obecnie tylko jedna odpowiedź (bezskutecznie) próbowała użyć tych reguł, więc zmiana reguł nie unieważni odpowiedzi.
anatolyg

Odpowiedzi:

15

W Javie oblicza krótki fragment kodu BF, który może konwertować dowolną liczbę na dowolną inną. Każdy bajt wyjściowy jest generowany przez przekształcenie ostatniego bajtu wyjściowego lub świeżego 0 na taśmie.

Fragmenty są generowane na trzy sposoby. Najpierw przez proste powtórzenia +i -(np. ++++Konwertuje 7 na 11), łącząc znane fragmenty (np. Jeśli A konwertuje 5 na 50, a B konwertuje 50 na 37, a następnie AB konwertuje 5 do 37) i proste mnożenia (np. [--->+++++<]Mnoży bieżącą liczbę przez 5/3). Proste mnożenie wykorzystuje przewijanie do generowania niezwykłych wyników (np. --[------->++<]>Generuje 36 z 0, gdzie pętla wykonuje się 146 razy, w sumie 4 zawijanie malejące i 1 rosnące zawijanie).

Jestem zbyt leniwy, aby obliczyć mój wynik, ale wykorzystuje on około 12,3 operacji BF na bajt 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]);
    }
}
Keith Randall
źródło
Wiem, że jestem około dwa i pół roku spóźniony i to nie jest golf, ale metodą powtarzania może być po prostu zwrócenie nowego ciągu (nowy znak [długość]). ReplaceAll ("\ 0", str);
Loovjo,
13

Cóż, oto najgorsze możliwe rozwiązanie, chociaż dość ładne w samym Brainfuck:

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

Wynik jest prawdopodobnie najgorszy, jaki możemy zobaczyć, bez celowego pogorszenia.

Praca nad obliczeniem faktycznego wyniku.

captncraig
źródło
Czy możesz wyjaśnić, co to robi? Odczytywanie kodu BF jest raczej trudne.
BMac,
3
Dla każdego bajtu wejścia wypisuje po prostu N +i a.
captncraig
Uważam, że [-]aby wyczyścić komórkę między każdą postacią.
captncraig
8

Python 3.x

Cóż, nie zamierzam wygrywać żadnych nagród za najkrótszy kod wyjściowy, ale może program wygeneruje kod ...

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

„Witaj, świecie! \ N”:

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.[-]++++
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+++++++++++++++++.[-]+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+++++++++++++++++++++++++++++++++++++++++++++++++.[-]+++++++++++++++++++++++++++
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+.[-]+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++++++++++++++++++++++++++++++++++++.[-]++++++++++++++++++++++++++++++++++++++++
++++.[-]++++++++++++++++++++++++++++++++.[-]++++++++++++++++++++++++++++++++++++
+++++++++++++++++++++++++++++++++++++++++++++++++++.[-]+++++++++++++++++++++++++
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++++++.[-]++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++++++++++++++++++++++++++++++++++++++++++++.[-]++++++++++++++++++++++++++++++++
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.[-]
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++++++++++++++++++++.[-]+++++++++++++++++++++++++++++++++.[-]++++++++++.[-]
zmienne lodowe
źródło
1
Przypadkowo odpowiedział na odpowiedź Madisons. Krótszy generator:print("".join(["+"*ord(i)+".[-]"for i in input()]))
FatalError
Można golf swój program o 2 znaków zastępując .[-]z.>
MilkyWay90
47 bajtów
MilkyWay90
8

Nie jestem pewien, czy to dobrze, ale dobrze się pisałem. (W 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
   )
  )

Prawdopodobnie są bardziej wydajne i bardziej eleganckie rozwiązania, ale to podąża za moim myśleniem nieco liniowo, więc było to najłatwiejsze.

Marty
źródło
8

Wynik: 4787486 41439404086426 (bez losowo generowanych danych)

(4085639 z tego pochodzi z Lenna.png. To 99,98%)

Nie dostaję części z przypadkowymi danymi. Czy nie potrzebuję konta, za które muszę zapłacić, aby uzyskać dane?

Dość naiwny. Oto wygenerowany kod dla „1Aa” (49, 65, 97) z małą dokumentacją:

                   // 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"

Kod Java jest trochę brzydki, ale działa. Wygenerowany wskaźnik instrukcji na bajt wejściowy jest prawdopodobnie lepszy, im wyższa jest średnia wartość bajtu.

Jeśli chcesz go uruchomić, musisz umieścić Lenna.png w tym samym katalogu, co plik .class. Drukuje partyturę na konsolę i zapisuje wygenerowany kod BF w pliku o nazwie „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");
}

Wprowadzę drobne poprawki, ale prawdopodobnie niewiele. Gotowy.

IchBinKeinBaum
źródło
To jest zepsute, wygenerowane BF generuje NUL bajtów lub „?” znaki w zależności od ustawień regionalnych dla dowolnego znaku spoza 1..127. Zwykły ASCII (1-127) wydaje się być w porządku. Zauważenie, że (bajty) są podpisane i staranne wybranie lokalizacji powoduje, że jest ich dużo (biorąc wynik ponad 5800000), ale nadal istnieje kilka tysięcy NUL z konwersji bf Lenna.png. Więc jest coś jeszcze.
user3710044
4

BrainF ** k

Jestem całkiem złym programistą BF, więc ta odpowiedź jest prawdopodobnie dość nieefektywna. Nie jestem pewien co do wyniku, ale powinien on działać nieco lepiej niż istniejąca odpowiedź na przeciętnym tekście. Zamiast zerować komórkę po każdym znaku, ten „dostosuje” się do nowego znaku z odejmowaniem, jeśli poprzedni podany znak jest większy.

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

(Uwaga: jest to kod, który napisałem dawno temu i zmieniłem przeznaczenie na potrzeby tego konkursu. Mam szczerą nadzieję, że poprawnie wykonałem konwersję, ale jeśli nie powiedzie się to w przypadku jakiegokolwiek wejścia, daj mi znać.)

Wersja pokazująca stan taśmy w całym kodzie:

>>++++++[-<+++++++>]<+>             [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]

Wygenerowany kod dla Hello, World!:

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

To moja pierwsza odpowiedź na CG.SE! Jeśli coś spieprzyłem, daj mi znać!

BrainSteel
źródło
4

> <>

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

Napisałem to w odpowiedzi na pytanie oznaczone jako duplikat, i chociaż nie jest to najlepszy golf (przynajmniej w przypadku tego konkretnego pytania), pomyślałem, że byłoby to marnotrawstwem, jeśli nie podzielę się tym cała jego obrzydliwie bełkotliwa chwała. Naprawdę jestem zaskoczony, że nawet działa. Przyjmę wszelkie sugestie, aby zagrać w golfa, ponieważ był to mój główny cel w jego tworzeniu.

Na marginesie, w drugim wierszu na początku .21można zastąpić trzy początkowe znaki, va następnie dwa spacje, jeśli to ułatwi czytanie. Nie lubię spacji w moich programach> <>, ponieważ oznacza to, że zmarnowane miejsce (dosłownie). Jest to także pozostałość jednego z wielu prototypów.

Sposób, w jaki działa, jest naprawdę prosty i, szczerze mówiąc, trudno byłoby mi znaleźć sposób na implementację innego algorytmu. Drukuje jednak wiele „+” trzeba wydrukować dla pierwszego znaku, a następnie drukuje więcej „+” lub „-” w razie potrzeby dla każdego dodatkowego znaku, oddzielając każdą sekcję kropkami. W moim programie fajne jest to, że modyfikuje własny kod źródłowy, tak aby drukował „+” lub „-” (zastępuje „+” w wierszu 3 odpowiednim znakiem po ustaleniu, czy bieżący znak jest większy niż lub mniej niż poprzedni).

Dane wyjściowe dla Hello, World!:

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

Mógłbym zdobyć to w sposób, w jaki miał być punktowany, ale jestem prawie pewien, że stracę i nie do końca wiem, jak czytać coś takiego jak lenna.png w> <>.

Jeśli ta odpowiedź cię interesuje i chciałbyś wyjaśnienia, z całą pewnością zapytaj, ale na razie zostawię je bez jednego tylko ze względu na to, jak kręte i kruche jest.

EDYCJA 1: Minęło trochę czasu, ale byłem w stanie zagrać w golfa z 2 bajtów z prawie całkowitym przeglądem sposobu, w jaki program decyduje, czy wydrukować plus czy minus. Jest to nieco rozczarowujący powrót do dużego remontu, ale przynajmniej działa.

kapusta
źródło
Ten bełkot stanowi kolejny bełkot! To najlepszy program, jaki kiedykolwiek widziałem!
Aequitas,
1

moje rozwiązanie JavaScript jest szybkie i brudne :)

wyjście dla Hello World\n

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

Źródło:

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);
}
Piotr
źródło
2
Witamy na stronie! Powinieneś dołączyć wynik do tytułu swojej odpowiedzi.
Wheat Wizard
Właśnie utworzyłem generator BF, oryginalny system punktowy ma przetwarzanie obrazu, co nie jest istotne :( Witaj, światowy stosunek jest mniejszy niż 9 (długość bf / długość oryginalnego tekstu)
Peter
1

Zbudowałem coś w Javie. Nie obliczył wyniku. Teksty zawierające 3 lub mniej znaków są kodowane przez pomnożenie na literę, np. „A” = ++++++++[>++++++++<-]>+.. Teksty zawierające więcej niż 3 znaki są kodowane za pomocą obliczonej listy podzielonej na 3 obszary. Pierwszy obszar to x razy 49, następnie plus x razy 7 i wreszcie plus x. Na przykład „A” to 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);
        }
    }
}

Dostarczony ciąg „### INSERT TEXT HERE ###” staje się --->-->-->-->-->->->->->->->-->->->->->-->->->->->-->-->-->-->+[-[>+++++++<-]<+++]>---->++>++>++>+>>+>+>->+>++>+>++>->++>++>+>>->+>->+>++>++>++>+[-[>+++++++<-]<++++]>---->--->--->--->+>>-->+++>+++>++>--->+>--->+++>+>--->+>->+++>++>+++>+>--->--->--->+[-<++++]>[.>]

"Witaj świecie!" staje się --->->>>>>-->-->->>>>>-->+[-[>+++++++<-]<+++]>---->>--->-->-->-->+++>+>++>-->->-->--->+>+[-[>+++++++<-]<++++]>---->->>>>+++>->+>>+++>->>->++>+[-<++++]>[.>]

dorycki
źródło
1

Python 3

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

Zasadniczo jest to tylko nieco ulepszona wersja odpowiedzi zmiennych lodowych. (-1 bajt z Kreatora pszenicy, -5 z FatalError, -2 z jez)

Madison Silver
źródło
Uważam, że jest to python 3. Jeśli tak, powinieneś dołączyć to w swoim nagłówku. Jeśli tak, możesz również usunąć podział linii po swoim :. Prawdopodobnie można to również zrobić w formie listy, aby zaoszczędzić bajty.
Wheat Wizard
-5 bajtów zprint("".join(["+"*ord(i)+".[-]"for i in input()]))
FatalError
-2 bajty: zgub nawiasy kwadratowe, więc wywołujesz join()wyrażenie generatora zamiast zrozumienia listy: print("".join("+"*ord(i)+".[-]"for i in input()))
jez
-2 bajty: możesz po prostu przejść do następnej komórki (pytanie mówi, że powinieneś założyć nieskończone pasmo w obu kierunkach print("".join("+"*ord(i)+".>"for i in input()))(to również zmniejsza wynik, ponieważ tracisz 2 bajty na wyjściu)
MegaIng