Minify Brainfuck


22

Ваша задача - минимизировать код Brainfuck в соответствии с этими правилами:

  • Удалите все, что не является одним из +-><[].,.
  • Для любой группы подряд +или -символов, если сумма+ s и -s одинаково, удалите их.
  • Сделайте то же, что и выше, но с >и< .
  • Удалить последовательности +-><символов, если они ничего не делают. Например, вы должны удалить +>-<->+<. (Это может быть самым сложным и сложным для реализации.) Убедитесь, что вы не получите никаких ложных срабатываний, например +>-<+>-<, которые не должны быть удалены.

Тестовые случаи:

вход

++++++[->++++++<]>.   prints a $
[-]<                  resets tape
>,[>,]<[.<]           reverses NUL terminated input string
++-->><<              does nothing

Выход

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

вход

Should disappear: ++>>+<+++<->-->-<<->-<
Should disappear: +++>-<--->+<
Should stay: +++>-<+>---<

Выход

+++>-<+>---<

Вы можете принимать ввод и вывод, как вам угодно - stdin / stdout, функция и т. Д., Но ввод может быть не закодирован.

Это , поэтому победит самый короткий код в количестве символов.


4
Я знаю, что это старая проблема, но контрольные примеры неадекватны. ++>>++<<--должен выводить >>++<<, и это не было покрыто. Пожалуйста, добавьте больше тестовых случаев.
— mbomb007

@ mbomb007 ты проверял последний контрольный пример +++>-<+>---<? Его можно сократить, чтобы избежать ненужного перемещения указателя, но ожидаемый результат оставляет его неизменным. Мое понимание, основанное на рассмотрении как вопроса, так и ответов, заключается в том, что дверная ручка хороша, если спецификация принимается свободно; мы должны исключить любые непрерывные неактивные +-><последовательности, как указано явным образом, кроме того, разрешено выполнять дополнительное минимизацию, как в вашем примере ++>>++<<--, и мы также можем выполнять перестановки, если они не изменяют функциональность кода, например, >+<+в +>+<,
— Митч Шварц

@MitchSchwartz "Удаляйте последовательности символов + -> <, если они ничего не делают. Например, вы должны удалить +>-<->+<. (Это может быть самым сложным и сложным для реализации.) Убедитесь, что вы не получаете ложных срабатываний, например +>-<+>-<, который не должен быть удален ". - это немного расплывчато
— mbomb007

@ mbomb007 А вторая и третья маркированные точки являются избыточными и ненужными, поскольку они включены в четвертую маркированную точку. Ну и что? Это классная задача. Мой комментарий должен был быть конструктивным и давать разъяснения, а не нападать на вас. Пожалуйста, примите это так, как я хотел, или скажите, как я должен был сказать это иначе. Потому что вы на самом деле не обратились к тому, что я написал; просто кажется, что ты пытаешься защитить себя, не будучи действительно конструктивным. Каким образом вы находите это расплывчатым? Как бы вы переписали это? Хотите отредактировать вопрос? Хотите спросить ручку двери?
— Митч Шварц

1
О, так что мы должны только удалить смежные последовательности?
— mbomb007

Ответы:


10

REBEL - 104

_/^_$/$</([^][<>.,+-]|\+-|-\+|<>|><)//((?<X>(<|>))+[+-]+(?!\2)(?<-X><|>)+(?(X)(?!)))([+-]+)/$3$1/.+/$>$&

Использование:

Ввод: читает одну строку из стандартного ввода.

Вывод: печатает одну строку в стандартный вывод.

Аномалии *:

  • Ввод _приводит к прочтению и использованию другой строки, а не к выводу ничего.
  • Второй тест выводит ++++>----<вместо +++>-<+>---<. Но это нормально, верно? ;)
  • >-<+и т. д. заменены на +>-<и т. д.

Спойлер:

Реализация аномалии № 3 делает вещи довольно тривиальными.

* Это не ошибка, это особенность!


"это не ошибка, это особенность" +1!
— Рохан Джунджхунвала

36

Brainfuck, 579 байтов

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

С форматированием и некоторыми комментариями:

,
[
  <<+>> >>+<<
  [
    [<+> >+<-]
    ++++++[>-------<-]
    >-
    [
      not plus
      -
      [
        not comma
        -
        [
          not minus
          -
          [
            not period
            --------------
            [
              not less than
              --
              [
                not greater than
                <+++++[>------<-]>+
                [
                  not open bracket
                  --
                  [
                    not close bracket
                    <<[-]>>-
                  ]
                ]
                <
              ]
              >
              [
                greater than
                >>-<<
                <<<[-]<[<]<<<[<]
                >>>>>>>>[<]
                <-[+>]
                +[->+]
                >>>>+>[<-]
                <[>+<-<]
                >
              ]
              <
            ]
            >
            [
              less than
              <<<[-]-[<]
              >>>> >>>>>>>[<]
              <<<<<<[<]
              <-[+>]
              +[-<+]
              <<<+<[>-<<<]
              >[-<+<]
            ]
          ]
          <
        ]
        >
        [
          minus
          +>[-<]
          <[<<]
          <[-]>>
        ]
      ]
      <
    ]
    +>
    [
      plus
      -[<-]
      <[>+>+<<-<]
      <[-]>+>
    ]
    <<
    [
      comma or period or bracket
      >-
    ]
    >[,>]
    <
  ]
  comma or period or bracket or eof
  <+<
  [
    start and end same cell
    >
  ]
  >
  [
    >>>
    [
      <<<<[-<]<<<
    ]
    >>>+>>>>
    [
      start right of end
      <<<<->>>>
      [>>>[-<]>>>>]
    ]
  ]
  >
  [
    <<<
    [
      <+[-->>]
    ]
    >[-[.[-]]]
    >[<]
    >
    [
      <<++++++[>+++++++<-]>+>>
      [<<.>>-]
      <<++>-[<.>-]
      +++[<+++++>-]
      +<<<<< <+>
      [
        <<
        [
          go left
          >->>>>>.
          [[-]<<<<]
          <<<+>>>
        ]
        >
        [
          toggle left right
          ->->>>>[-]
        ]
      ]
      <
      [
        toggle right left
        ->+[>>>>>]>>[<]
        <<<<<<<<
        [
          [-]<
        ]
        >
        [
          go right
          ++.[-]
          >>>>>>>
        ]
        <
      ]
    ]
    >>
  ]
  <[>>>>>>>]
  +[-<<<<<[-]<<]
  ,
]

Это использует тот же подход, что и решение Кейта Рэндалла, минимизируя все смежные последовательности +-<>оптимально путем симуляции. Например, +++>-<+>---<становится ++++>----<и >+<+<<+>+<->>>>становится+<+>>+> .

Попробуйте онлайн. (Если абсолютное значение моделируемой ячейки приближается к 256, возникнут проблемы переполнения.)

Общая структура

while not EOF:
  while not EOF and next char not in ",.[]":
    process char
  print minified sequence (followed by the char in ",.[]" if applicable)

Лента разделена на 7-элементные узлы; в начале внутреннего цикла макет памяти

0 s 0 c 0 a b

где s- логический флаг для начальной ячейки, cтекущий символ, aотрицательная часть значения моделируемой ячейки (плюс один), иb положительная часть имитируемого значения ячейки.

Когда минимизированная последовательность печатается, макет памяти

d n e 0 0 a b

где dэто логический флаг для направления, aи bэто , как и раньше (но становится одним / ноля при печати), а также nи eтолько отлична от нуля для конечного узла; nсвязано с тем, сколько раз узел был замечен, иe является значением символа, который остановил внутренний цикл (плюс один).

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

При печати минимизированной последовательности и принятии решения о том, как перемещать симулируемый указатель, мы можем выбрать общий подход: начать с удаления от конечного узла (в произвольном направлении, если начальный и конечный узлы совпадают), развернуться в крайнем левом и правом краях узлы и остановка в зависимости от того, сколько раз был замечен конечный узел: 3 раза, если начальный и конечный узлы совпадают, в противном случае 2.


2
Источник: Brainfuck. Цель: мозговой трах. +1
— Эрик Outgolfer


1
Я позволю этому привлечь некоторое внимание и наградить награду через день или два
— lirtosiast

1
@MitchSchwartz Вы проверяли свой код на соответствие вашему коду? Вы можете сократить его! #meta
— WallyWest

1
@WallyWest (это, кажется, экономит 7 байт!) Не имеет значения, код в постоянной ссылке имеет разрывы строк.
— Деннис

7

Питон, 404 символа

Этот код делает идеальную оптимизацию всех подпоследовательностей +-<>. Чуть больше, чем вы просили, но вы идете.

M=lambda n:'+'*n+'-'*-n                                                           
def S(b):                                                                         
 s=p=0;t=[0];G,L='><'                                                             
 for c in b:                                                                      
  if'+'==c:t[p]+=1                                                                
  if'-'==c:t[p]-=1                                                                
  if G==c:p+=1;t+=[0]                                                             
  if L==c:s+=1;t=[0]+t                                                            
 if p<s:k=len(t)-1;t,p,s,G,L=t[::-1],k-p,k-s,L,G                                  
 r=[i for i,n in enumerate(t)if n]+[s,p];a,b=min(r),max(r);return(s-a)*L+''.join(M(n)+G for n in t[a:b])+M(t[b])+(b-p)*L                                           
s=b=''                                                                            
for c in raw_input():                                                             
 if c in'[].,':s+=S(b)+c;b=''                                                     
 else:b+=c                                                                        
print s+S(b) 

Он работает путем имитации +-<>операций на ленте t. sэто начальная позиция на ленте и pтекущая позиция. После моделирования он вычисляет степень, с [a,b]которой необходимо работать, и выполняет все +/- за один оптимальный проход.


1

CoffeeScript - 403 397

i=prompt().replace /[^\]\[,.+-><]/g,''
x=(c)->
 t={};p=n=0
 for d in c
  t[p]?=0;switch d
   when'+'then n=1;t[p]++;when'-'then n=1;t[p]--;when'<'then p--;when'>'then p++
 (n=0if v!=0)for k,v of t;n
s=e=0;((e++;(i=(i.substr 0,s)+i.substr e;e=s=0)if x (i.substr s,e-s).split "")while(i[e]||0)!in['[',']',0];e=++s)while s<=i.length
r=/(\+-|-\+|<>|><|^[<>]$)/g
i=i.replace r,'' while r.test i
alert i

Демо (пожалуйста, прости использование bit.ly здесь, весь URL сломал бы уценку)

Несжатая версия (с отладочным кодом):

console.clear()
input = """Should disappear: ++>>+<+++<->-->-<<->-<
Should disappear: +++>-<--->+<
Should stay: +++>-<+>---<"""

input = input.replace /[^\]\[,.+-><]/g, ''
console.log input

execute = (code) ->
  stack = {}
  item = 0
  console.log code
  nop = false
  for char in code
    switch char
      when '+' then nop = true; stack[item]?=0;stack[item]++
      when '-' then nop = true; stack[item]?=0;stack[item]--
      when '<' then item--
      when '>' then item++
  console.debug stack
  (nop = false if v != 0) for k,v of stack
  nop
start = 0
end = 0

while start <= input.length
 while input.charAt(end) not in [ '[', ']', '' ]
  end++
  if execute (input.substring start, end).split("")
    input = (input.substring 0, start) + input.substring end
    end = start = 0
    console.log input
 end = ++start
input = input.replace /(\+-|-\+|<>|><|^(<|>)$)/g, '' while /(\+-|-\+|<>|><)/.test input
console.log 'Result: ' + input

Альтернативный способ размещения демоверсий Coffeescript - использование JSFiddle . В левом поле находится панель конфигурации «Языки», которая позволяет использовать CoffeeScript вместо JS.
— Питер Тейлор

@PeterTaylor Спасибо, я знал о JSFiddle раньше, но не то, чтобы он мог использовать CoffeeScript
— TimWolla

Это терпит неудачу >+.-<, производя пустую строку вместо того, чтобы оставить это неизменным.
— Митч Шварц
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.