Brainf *** Гольфіст


32

Один з найпростіших кодів, написаний мовою програмування, - це послідовність друку програм із символів (наприклад, "Привіт, світ!"). Тим НЕ менше, S про м е е з про т е р я з мов програмування , як Brainfuck , навіть цей простий код дуже дратує писати.

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

Вхідні дані

Послідовність символів (між 1і 255) задається у будь-якому форматі (змінна, аргумент, stdin, файл, ...).

Вихід

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

Наприклад, один можливий вихід для введення A- це ++++++++[<++++++++>-]<+..

Програма не повинна забирати багато часу ( >2m).

Програма BF не повинна тривати багато часу ( >10s).

Оцінка балів

(Зверніть увагу: поточний метод підрахунку може змінитися, оскільки його непросто обчислити ...)

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

Оцінка - це сума довжини BF-кодів, що друкують ці рядки.

  • Рядок, Hello, world!доданий до одного 0x0A( \n) (тобто програми "Привіт, світ!")
  • Одиночний символ від 0x01~0xFF
    • Сума довжини цих 255 кодів BF множиться на 1/16, округлюється та додається до оцінки.
  • Список перших 16 рядків, породжених розщепленням випадкової послідовності байт , вироблену на 11-11-11 шляхом 0x00, видаливши всі рядки нульової довжини.
  • Lenna.png , видаляючи всі 0x00s.
  • Тексти пісні 99 пляшок пива , починаючи з нових 99 bottles~рядків 0x0A, пункти розділені двома 0x0As, а в кінці немає символу newline.
  • Інші рядки, які ви можете надати.

Ваша програма може включати в себе підрахунок балів.

Звичайно, переможець буде найнижчим кодом.


Дублікат (хоча краще словосполучення
копія

4
Це здається досить важким для підрахунку балів. Для пошуку та проходження нам потрібно багато різних файлів. Що означає "Інші рядки, які ви можете надати". Чому я б додав більше, якщо це додасть до моєї оцінки?
captncraig

1
Lenna.pngбуде домінувати над оцінкою, оскільки це, безумовно, найбільший внесок. Може, нормалізувати трохи за розміром?
Кіт Рендалл

1
Код мінімальної довжини для "A" становить ---- [----> + <]> ++.
Scony

1
ОП, очевидно, не хвилює цю проблему. Давайте відредагуємо правила скорингу на щось розумне? Наразі лише одна відповідь (безуспішно) намагалася використовувати ці правила, тому зміна правил не призведе до недійсності відповідей.
anatolyg

Відповіді:


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]);
    }
}

Я знаю, що я запізнююсь на два з половиною роки, і це не гольф, але метод повторення може просто повернути новий String (новий знак [довжина]).
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. Тож є і щось інше.
користувач3710044

4

BrainF ** k

Я досить поганий програміст 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двома пробілами, якщо це полегшує читання. Мені не подобається бачити пробіли в моїх програмах, тому що це означає, що є простір (буквально). Це також є залишком одного з багатьох прототипів.

Те, як воно функціонує, насправді просте, і, чесно кажучи, мені важко було б придумати спосіб реалізації іншого алгоритму. Він друкує, однак, багато "+" s потрібно надрукувати для першого символу, а потім друкує більше "+" s або "-" s, як потрібно для кожного додаткового символу, розділяючи кожен розділ на періоди. Що мені здається цікавим у програмі, це те, що вона змінює власний вихідний код, щоб він надрукував "+" або "-" (він замінює "+" у рядку 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, оригінальна система балів має обробку зображень, що не стосується :( Привіт у світовому співвідношенні менше 9 (довжина BF / довжина оригінального тексту)
Пітер

1

Я щось побудував на Яві. Не підрахували рахунок. Тексти з 3 або меншими символами кодуються множенням на одну букву, наприклад "A" = ++++++++[>++++++++<-]>+.. Тексти, що містять більше 3 символів, кодуються розрахованим списком, який розділений на 3 області. Перша область х разів 49, потім плюс х разів 7 і нарешті плюс х. Наприклад, "A" дорівнює 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);
        }
    }
}

Наданий рядок "### ВСТАВКА ТЕКСТУ ТУТ ###" стає --->-->-->-->-->->->->->->->-->->->->->-->->->->->-->-->-->-->+[-[>+++++++<-]<+++]>---->++>++>++>+>>+>+>->+>++>+>++>->++>++>+>>->+>->+>++>++>++>+[-[>+++++++<-]<++++]>---->--->--->--->+>>-->+++>+++>++>--->+>--->+++>+>--->+>->+++>++>+++>+>--->--->--->+[-<++++]>[.>]

"Привіт Світ!" стає --->->>>>>-->-->->>>>>-->+[-[>+++++++<-]<+++]>---->>--->-->-->-->+++>+>++>-->->-->--->+>+[-[>+++++++<-]<++++]>---->->>>>+++>->+>>+++>->>->++>+[-<++++]>[.>]


1

Пітон 3

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

Це, по суті, лише дещо вдосконалена версія відповіді на зміну змін. (-1 байт від пшеничного майстра, -5 від FatalError, -2 від ядра)


Я вважаю, що це python 3. Якщо так, ви повинні включити його до свого заголовка. Якщо так, ви можете також усунути розрив лінії після вашого :. Можливо, це також можна зробити як розуміння списку для збереження байтів.
Пшеничний майстер

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

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

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