Брейнф *** Гольфист


32

Одним из самых простых кодов, написанных языком программирования, является последовательность печати символов программы (например, «Привет, мир!»). Тем не менее, S о м е е с о т е р я с языков программирования , как Brainfuck , даже этот простейший код очень раздражает писать.

Ваша задача - написать программу (не обязательно писать в brainfuck), которая печатает (минимальную длину) программу Brainfuck, печатая данный текст.

вход

Последовательность символов (между 1и 255) задается в любом формате (переменная, аргумент, стандартный ввод, файл, ...).

Выход

Выходными данными является действительный (без несоответствия [и ]) код brainfuck ( допустим, 8-битная ячейка без знака и неограниченное количество ячеек слева и справа), печатающая точную строку, заданную в качестве входных данных.

Например, один возможный выход для ввода Aявляется ++++++++[<++++++++>-]<+..

Ваша программа не должна занимать много времени ( >2m) для запуска.

Программа BF не должна занимать много времени ( >10s) для запуска.

счет

(Обратите внимание: текущий метод оценки может измениться, так как его нелегко вычислить ...)

Длина программы (генерирующей код BF) сама по себе не имеет значения. Однако жесткое кодирование кодов BF в программном коде не в порядке. Только приемлемый диапазон (например , БФ код печати одного символа. 0x01: +.) Из BF - кодов может быть жестко закодированы.

Счет представляет собой сумму длин BF-кодов, печатающих эти строки.

  • Строка, Hello, world!добавленная с помощью функции single 0x0A( \n) (т. Е. Программа «Hello, world!»)
  • Один символ из 0x01~0xFF
    • Сумма длин этих 255 кодов BF умножается на 1/16, округляется и добавляется к результату.
  • Список первых 16 строк, сгенерированных путем разбиения случайной последовательности байтов, сгенерированных 11-11-11 путем 0x00удаления всех строк нулевой длины.
  • Lenna.png , удалив все 0x00с.
  • Текст песни 99 бутылок пива , начиная с 99 bottles~новой строки 0x0A, параграфы разделяются двумя 0x0Aс, а в конце нет символа новой строки.
  • Другие строки вы можете предоставить.

Ваша программа может включать в себя подсчет очков.

Конечно, код с наименьшим количеством очков будет победителем.


Дубликат (хотя лучше сформулированный) кода codegolf.stackexchange.com/questions/3450/…
копия

4
Это кажется довольно сложным для подсчета очков. Это много разных файлов, которые нам нужно отследить и просмотреть. В чем смысл «других строк, которые вы можете предоставить». Зачем мне добавлять больше, если это добавит к моему счету?
captncraig

1
Lenna.pngбудет доминировать в счете, так как это безусловно самый большой вклад. Может нормализовать немного по размеру?
Кит Рэндалл

1
Код минимальной длины для «A»: ---- [----> + <]> ++.
балкон

1
ОП явно не волнует этот вызов. Давайте изменим правила подсчета очков на что-нибудь толковое? В настоящее время только один ответ (безуспешно) пытался использовать эти правила, поэтому изменение правил не сделает ответы недействительными.
Анатолий

Ответы:


15

В Java вычисляет короткий фрагмент BF, который может преобразовать любое число в любое другое число. Каждый выходной байт генерируется путем преобразования последнего выходного байта или нового 0 на ленте.

Фрагменты создаются тремя способами. Сначала с помощью простых повторений +и -(например, ++++преобразует 7–11), путем объединения известных фрагментов (например, если A преобразует 5–50, а B преобразует 50–37, затем AB преобразует 5–37) и простых умножений (например, [--->+++++<]умножает текущее число на 5/3). Простые умножения используют преимущества обтекания для генерации необычных результатов (например, --[------->++<]>генерирует 36 из 0, где цикл выполняется 146 раз, всего 4 нисходящих и 1 восходящих обтеканий).

Я слишком ленив, чтобы вычислить мой счет, но он использует около 12,3 операций BF на байт 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]);
    }
}

Я знаю, что опоздал примерно на два с половиной года, и это не гольф, но метод повтора мог бы просто вернуть new String (new char [length]). ReplaceAll ("\ 0", str);
Loovjo

13

Ну, вот о худшем из возможных решений, хотя в самом Brainfuck это выглядит довольно красиво:

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

Оценка, вероятно, худшая, которую мы, вероятно, увидим, без преднамеренного ухудшения.

Работаем над подсчетом фактического балла.


Не могли бы вы объяснить, что это делает? Чтение BF-кода довольно сложно.
BMac

3
Для каждого входного байта он просто печатает N +'s и a.
captncraig

Я считаю, [-]чтобы очистить ячейку между каждым персонажем.
Captncraig

8

Python 3.x

Ну, я не собираюсь выигрывать призы за самый короткий выходной код, но, может быть, за программу, чтобы сгенерировать код ...

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

«Привет, мир! \ N»:

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

1
Случайно ответили Мэдисону на ответ. Короче генератор:print("".join(["+"*ord(i)+".[-]"for i in input()]))
FatalError

Вы можете сыграть в гольф свою программу на 2 символа, заменив .[-]на.>
MilkyWay90


8

Я не уверен, насколько это хорошо, но мне было весело писать это. (В 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
   )
  )

Возможно, есть более эффективные и более изящные решения, но они следуют моему шаблону мышления несколько линейно, так что это было проще всего.


8

Гол: 4787486 41439404086426 (без случайно сгенерированных данных)

(4085639 из этого от Lenna.png. Это 99,98%)

Я не получаю часть со случайными данными. Разве мне не нужен аккаунт, за который я должен заплатить, чтобы получить данные?

Довольно наивно. Вот сгенерированный код для "1Aa" (49, 65, 97) с небольшой документацией:

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

Код Java немного уродлив, но работает. Сгенерированная инструкция на входной байтовый коэффициент, вероятно, тем лучше, чем выше среднее значение байта.

Если вы хотите запустить его, вы должны поместить Lenna.png в тот же каталог, что и файл .class. Он выводит партитуру на консоль и записывает сгенерированный код BF в файл с именем «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");
}

Я собираюсь сделать небольшие улучшения, но, вероятно, не очень. Выполнено.


Это не работает, сгенерированный BF выводит NUL байтов или '?' символы в зависимости от локали для любого символа не в 1..127. Простая ASCII (1-127), кажется, все же хорошо. Заметив, что (байты) подписаны и при тщательном выборе локали их много (с результатом более 5800000), но все еще есть несколько тысяч NUL от bf-преобразования Lenna.png. Так что есть еще кое-что.
user3710044

4

BrainF ** к

Я довольно плохой программист BF, поэтому этот ответ, вероятно, довольно неэффективен. Я не уверен в счете, но он должен работать немного лучше, чем существующий ответ на ваш средний текст. Вместо того, чтобы обнулять ячейку после каждого символа, этот «приспособится» к новому символу с вычитанием, если предыдущий данный символ больше.

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

(Обратите внимание, это код, который я написал давным-давно и повторно использовал для этого конкурса. Я искренне надеюсь, что я сделал преобразование правильно, но если он потерпит неудачу для любого ввода, дайте мне знать.)

Версия, показывающая состояние ленты во всем коде:

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

Сгенерированный код для Hello, World!:

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

Это мой первый ответ на CG.SE! Если я что-то напортачил, дайте мне знать!


4

> <>

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

Я написал это в ответ на вопрос, помеченный для дубликата, и хотя это не самый лучший гольф (по крайней мере, для этого конкретного вопроса), я подумал, что это будет пустая трата, если я не поделюсь этим вся его отвратительно бредовая слава. На самом деле, я немного удивлен, что это даже работает. Я приму любые предложения, чтобы сыграть в гольф, так как это было моей главной целью при создании.

Как примечание: во второй строке начинающиеся три символа .21можно заменить vна два пробела, если это облегчает чтение. Я не люблю видеть пробелы в моих> <> программах, потому что это означает, что есть свободное место (буквально). Это также остаток от одного из многих прототипов.

Принцип его работы очень прост, и, откровенно говоря, мне было бы трудно подумать о том, как реализовать другой алгоритм. Однако он печатает много «+» для первого символа, а затем печатает больше «+» или «-» по мере необходимости для каждого дополнительного символа, разделяя каждый раздел точками. Что мне нравится в программе, так это то, что она изменяет свой собственный исходный код так, чтобы печатать «+» или «-» (вместо «+» в строке 3 соответствующий символ после определения, является ли текущий символ больше или меньше, чем предыдущий).

Выход для Hello, World!:

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

Я мог бы забить это так, как это было задумано, но я почти уверен, что проиграл, и я не совсем знаю, как читать что-то вроде lenna.png в> <>.

Если этот ответ вас заинтересует, и вы хотели бы получить объяснение, во что бы то ни стало спросите, но сейчас я оставлю его без ответа только из-за его извращенности и извращенности.

РЕДАКТИРОВАТЬ 1: Это было некоторое время, но я смог отыграть 2 байта с почти полным пересмотром способа, которым программа решает, печатать ли плюс или минус. Это несколько разочаровывающее возвращение для капитального ремонта, но по крайней мере это работает.


Эта бессмысленная программа делает еще одну бессмысленную программу! Это самая лучшая программа, которую я когда-либо видел!
Aequitas

1

мое решение JavaScript это быстро и грязно :)

выход для Hello World\n

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

Источник:

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
Добро пожаловать на сайт! Вы должны включить оценку в заголовок вашего ответа.
Пшеничный волшебник

я только что сделал генератор bf, в системе оригинальных партитур есть обработка изображений, что не имеет значения :( Соотношение Hello World меньше 9 (длина bf / длина исходного текста)
Peter

1

Я построил что-то на Java. Не рассчитать счет. Тексты с 3 или менее символами кодируются с умножением на букву, например, «A» = ++++++++[>++++++++<-]>+.. Тексты с более чем 3 символами кодируются с вычисляемым списком, который разделен на 3 области. Первая область х раз 49, затем плюс х раз 7 и, наконец, плюс х. Например, «А» это 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);
        }
    }
}

Предоставленная строка "### INSERT TEXT HERE ###" становится --->-->-->-->-->->->->->->->-->->->->->-->->->->->-->-->-->-->+[-[>+++++++<-]<+++]>---->++>++>++>+>>+>+>->+>++>+>++>->++>++>+>>->+>->+>++>++>++>+[-[>+++++++<-]<++++]>---->--->--->--->+>>-->+++>+++>++>--->+>--->+++>+>--->+>->+++>++>+++>+>--->--->--->+[-<++++]>[.>]

"Привет, мир!" становится --->->>>>>-->-->->>>>>-->+[-[>+++++++<-]<+++]>---->>--->-->-->-->+++>+>++>-->->-->--->+>+[-[>+++++++<-]<++++]>---->->>>>+++>->+>>+++>->>->++>+[-<++++]>[.>]


1

Python 3

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

По сути, это всего лишь слегка улучшенная версия ответа icedvariables. (-1 байт от Волшебника Пшеницы, -5 от FatalError, -2 от Jez)


Я считаю, что это Python 3. Если это так, вы должны включить это в свой заголовок. Если это так, вы также можете удалить разрыв строки после вашего :. Это также может быть сделано для понимания списка для сохранения байтов.
Пшеничный волшебник

-5 байт сprint("".join(["+"*ord(i)+".[-]"for i in input()]))
FatalError

-2 байта: теряйте квадратные скобки, так что вы вызываете join()выражение генератора, а не понимание списка: print("".join("+"*ord(i)+".[-]"for i in input()))
Jez

-2 байта: вы можете просто перейти к следующей ячейке (вопрос гласит, что вы должны предполагать бесконечную полосу в обоих направлениях print("".join("+"*ord(i)+".>"for i in input()))(это также уменьшает счет, поскольку вы теряете 2 байта на выходе)
MegaIng
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.