Переключить, распечатать, повторить

17

Эта проблема свободно вдохновлен нереализованных esolang Пады .

Рассмотрим массив из 8 битов, все инициализированы нулем. Мы введем очень минималистичный набор команд для печати произвольных строк. Есть две инструкции, каждая из которых принимает параметр, Nкоторый является индексом бита:

  • t Nдля т oggle: Это изменяет значение бита N.
  • p Nдля р RINT: Это интерпретирует все 8 бит в качестве байта, начиная с бита Nи обертывания вокруг конца . Символ, соответствующий этому байту, печатается в STDOUT.

Давайте посмотрим пример. Мы хотим напечатать :=. Наивно мы достигаем этого следующим образом (0-битные индексы):

t 2    [0 0 1 0 0 0 0 0]
t 3    [0 0 1 1 0 0 0 0]
t 4    [0 0 1 1 1 0 0 0]
t 6    [0 0 1 1 1 0 1 0]
p 0    [0 0 1 1 1 0 1 0] == 58 == ':'
t 5    [0 0 1 1 1 1 1 0]
t 6    [0 0 1 1 1 1 0 0]
t 7    [0 0 1 1 1 1 0 1]
p 0    [0 0 1 1 1 1 0 1] == 61 == '='

Но вместо этого мы можем использовать циклическую функцию pи сохранить две инструкции:

t 2    [0 0 1 0 0 0 0 0]
t 3    [0 0 1 1 0 0 0 0]
t 4    [0 0 1 1 1 0 0 0]
t 6    [0 0 1 1 1 0 1 0]
p 0    [0 0 1 1 1 0 1 0] == 58 == ':'
t 1    [0 1 1 1 1 0 1 0]
p 7    [0 1 1 1 1 0 1 0] == [0 0 1 1 1 1 0 1] == 61 == '='
                      ^

Так что p 7просто начинается чтение значения байта с последнего бита, а не с первого.

Соревнование

Учитывая непустую строку печатаемых символов ASCII (от 0x20 до 0x7E включительно), создайте оптимальный список инструкций (одна строка на инструкцию), чтобы напечатать эту строку с помощью вышеуказанной системы. Если существует несколько оптимальных решений (что почти всегда будет так), генерируйте только одно из них.

Вы можете выбрать между 0 и 1 индексированием для битов, но, пожалуйста, укажите свой выбор.

Вы можете написать программу или функцию, принимая ввод через STDIN (или ближайшую альтернативу), аргумент командной строки или аргумент функции и выводя результат через STDOUT (или ближайшую альтернативу), возвращаемое значение функции или параметр функции (out). Если вы не печатаете результат в STDOUT, он все равно должен быть отдельной строкой, разделенной новой строкой.

Это код гольф, поэтому самый короткий ответ (в байтах) выигрывает.

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

Каждый тестовый пример - это отдельная строка, содержащая входную строку, за которой следует оптимальное количество инструкций и одно возможное решение.

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

?
7 instructions
t 2
t 3
t 4
t 5
t 6
t 7
p 0

:=
7 instructions
t 2
t 3
t 4
t 6
p 0
t 1
p 7

0123456789
26 instructions
t 2
t 3
p 0
t 7
p 0
t 6
t 7
p 0
t 7
p 0
t 5
t 6
t 7
p 0
t 7
p 0
t 6
t 7
p 0
t 7
p 0
t 2
t 3
p 3
t 2
p 3

9876543210
28 instructions
t 2
t 3
t 4
t 7
p 0
t 7
p 0
t 0
t 7
p 5
t 4
p 5
t 0
t 5
p 0
t 7
p 0
t 5
t 6
t 7
p 0
t 7
p 0
t 6
t 7
p 0
t 7
p 0

Hello, World!
39 instructions
t 1
t 4
p 0
t 3
t 7
p 2
t 1
t 6
p 2
p 2
t 0
t 1
p 2
t 0
t 1
t 3
p 2
t 6
t 7
p 2
t 0
t 2
t 6
t 7
p 1
t 0
t 1
t 5
p 0
t 2
t 7
p 3
t 2
t 6
p 0
t 4
p 0
t 1
p 3

The quick brown fox jumps over the lazy dog.
150 instructions
t 1
t 3
t 5
p 0
t 1
t 2
p 1
t 1
t 3
t 7
p 0
t 1
t 5
t 7
p 0
t 1
t 3
t 7
p 0
t 5
p 0
t 3
t 4
t 5
p 0
t 4
t 6
p 0
t 4
p 0
t 1
t 4
t 6
t 7
p 0
t 1
t 6
p 0
t 3
p 0
t 0
t 5
p 4
t 0
t 7
p 0
t 1
p 1
t 3
t 5
t 6
t 7
p 0
t 1
t 5
t 6
p 0
t 4
t 7
p 0
t 1
t 2
p 3
t 5
t 6
t 7
p 2
t 1
t 2
t 6
p 0
t 0
p 7
t 0
t 7
p 5
t 3
t 4
t 6
t 7
p 0
t 6
t 7
p 0
t 1
t 3
t 6
t 7
p 0
t 1
t 4
t 5
t 6
t 7
p 0
t 4
p 4
t 6
p 0
t 1
t 6
p 4
t 5
t 6
t 7
p 0
t 1
t 3
t 5
p 0
t 1
p 1
t 1
t 3
t 7
p 0
t 1
t 5
t 7
p 0
t 1
t 4
t 5
p 0
t 1
p 3
t 3
t 7
p 1
t 1
t 5
p 0
t 1
t 3
t 4
t 7
p 0
t 1
t 5
p 0
t 4
t 6
t 7
p 0
t 4
p 0
t 1
t 4
t 7
p 0

Тестовые случаи были созданы с помощью этой эталонной реализации CJam .

Мартин Эндер
источник

Ответы:

3

CJam, 67 байт

U]8*l{i2b8Ue[8,{1$m>2$.^:+}$0=_@m>@1$.^ee{~{"t "op}{;}?}/"p "o\p}/;

Попробуйте онлайн

Объяснение:

U]8*    Build start bit array [0 0 0 0 0 0 0 0].
l       Get input.
{       Start loop over input characters.
  i       Convert character to integer.
  2b      Convert to binary array.
  8Ue[    Pad to 8 entries with leading 0.
  8,      Generate list of possible rotation amounts.
  {       Start of sort function block.
    1$      Get bit array of character.
    m>      Rotate by rotation amount.
    2$      Get previous bit array.
    .^      Element-wise xor to get different bits.
    :+      Add elements in result to get count of different bits.
  }$      Sort possible rotations by count of different bits.
  0=      Get first rotation amount in sorted list, which is the one with the
          one that results in the smallest count of different bits.
  _       Copy count. Will use original for "p" output later.
  @       Get the character bit array to top of stack.
  m>      Rotate it, to get optimal rotated bit array.
  @       Get previous bit array to top of stack.
  1$      Copy rotated bit array, will need the original as starting point
          for next character.
  .^      Element-wise xor to get different bits.
  ee      Enumerate array to get pairs of index and bit value.
  {       Loop over bits.
    ~       Unpack index bit pair.
    {       Start of if block for bit value.
      "t "o   Output "t ".
      p  Output index and newline.
    }       End of if block.
    {       Start of else block.
      ;       Pop the index value.
    }?      End of ternary if.
  }/      End loop over bits.
  "p "o   Output "p ".
  \       Swap rotation amount to top.
  p       Print rotation amount and newline.
}/      End loop over input characters.
;       Ppp current bit array off stack to prevent extra output.
Рето Коради
источник
5

Руби, 171

->w{s=[0]*8
w.chars.flat_map{|c|z=0..7
*m,i=z.map{|j|z.select{|k|s[k]!=z.map{|i|c.ord[i]}.rotate(j)[k]}<<j}.min_by &:size
m.map{|m|s[m]=1-s[m];"t #{7-m}"}+["p #{i}"]}*?\n}

Функция Ruby, которая только вдвое больше эталонной реализации. :)

Попробуйте онлайн: http://ideone.com/ysYyFP

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

Начальная (менее гольфовая) версия программы доступна здесь .

Кристиан Лупаску
источник