Alternar, Imprimir, Repetir

17

Esse desafio é pouco inspirado pelo esolang Pada não implementado .

Considere uma matriz de 8 bits, todos inicializados em zero. Introduziremos um conjunto de instruções muito minimalista para imprimir seqüências arbitrárias. Existem duas instruções, ambas com um parâmetro Nque é o índice de um bit:

  • t Npara t oggle: Isso muda o valor de bit N.
  • p Nfor p rint: interpreta todos os 8 bits como um byte, começando do bit Ne passando pelo final . O caractere correspondente a este byte é impresso em STDOUT.

Vamos dar um exemplo. Queremos imprimir :=. Ingenuamente, conseguimos isso da seguinte maneira (índices de bits baseados em 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 == '='

Mas, em vez disso, podemos usar o recurso cíclico pe salvar duas instruções:

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 == '='
                      ^

Então, p 7basta começar a ler o valor do byte do último bit em vez do primeiro.

O desafio

Dada uma sequência não vazia de caracteres ASCII imprimíveis (0x20 a 0x7E, inclusive), produza uma lista ideal de instruções (uma linha por instrução) para imprimir essa sequência no sistema acima. Se houver várias soluções ótimas (que quase sempre serão o caso), gere apenas uma delas.

Você pode escolher entre indexação com base em 0 e com base em 1 para os bits, mas indique sua escolha.

Você pode escrever um programa ou função, recebendo entrada via STDIN (ou alternativa mais próxima), argumento da linha de comando ou argumento da função e emitindo o resultado via STDOUT (ou alternativa mais próxima), valor de retorno da função ou parâmetro da função (saída). Se você não imprimir o resultado em STDOUT, ainda deverá ser uma única sequência separada por nova linha.

Isso é código de golfe, então a resposta mais curta (em bytes) vence.

Casos de teste

Cada caso de teste é uma única linha que contém a sequência de entrada, seguida pelo número ideal de instruções, seguido por uma solução possível.

Você não deve emitir a contagem de instruções em sua solução - isso é incluído apenas aqui, para que você possa verificar a correção do seu código se ele imprimir uma lista de instruções diferente.

?
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

Os casos de teste foram gerados com esta implementação de referência do CJam .

Martin Ender
fonte

Respostas:

3

CJam, 67 bytes

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

Experimente online

Explicação:

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.
Reto Koradi
fonte
5

Ruby, 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}

Uma função Ruby que tem apenas o dobro do tamanho da implementação de referência. :)

Experimente online: http://ideone.com/ysYyFP

O programa é bem direto: começa com os 8 bits definidos como 0 e itera através dos caracteres. Em cada etapa, ele leva a rota mais curta do estado atual para um estado que permita imprimir o caractere. Retorna uma string no formato especificado.

A versão inicial (menos golfe) do programa está disponível aqui .

Cristian Lupascu
fonte
4

CJam, 81 76 bytes

Ainda muito para jogar golfe.

0]8*q{i2b8Te[8,\fm>:X\_@\f.=::+_$W=#:YX=_@.{=M['tSUN]?U):U;}o0:U;['pSYN]o}/;

Experimente online .

Andrea Biondo
fonte