Alternar, imprimir, repetir

17

Este desafío está inspirado libremente por el esolang Pada no implementado .

Considere una matriz de 8 bits, todos inicializados a cero. Introduciremos un conjunto de instrucciones muy minimalista para imprimir cadenas arbitrarias. Hay dos instrucciones, que toman un parámetro Nque es el índice de un bit:

  • t Nde t Oggle: Esto cambia el valor del bit N.
  • p Nfor p rint: Esto interpreta los 8 bits como un byte, comenzando desde el bit Ny envolviendo el final . El carácter correspondiente a este byte se imprime en STDOUT.

Veamos un ejemplo. Queremos imprimir :=. Ingenuamente lo logramos de la siguiente manera (índices de bits basados ​​en 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 == '='

Pero en cambio, podemos hacer uso de la función cíclica py guardar dos instrucciones:

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

Entonces, p 7simplemente comienza a leer el valor de byte del último bit en lugar del primero.

El reto

Dada una cadena no vacía de caracteres ASCII imprimibles (0x20 a 0x7E, inclusive), produzca una lista óptima de instrucciones (una línea por instrucción) para imprimir esa cadena con el sistema anterior. Si hay varias soluciones óptimas (que casi siempre será el caso), genere solo una de ellas.

Puede elegir entre indexación basada en 0 y basada en 1 para los bits, pero indique su elección.

Puede escribir un programa o función, tomando la entrada a través de STDIN (o la alternativa más cercana), argumento de línea de comando o argumento de función y generando el resultado a través de STDOUT (o la alternativa más cercana), el valor de retorno de la función o el parámetro de función (out). Si no imprime el resultado en STDOUT, aún debería ser una sola cadena separada por una nueva línea.

Este es el código de golf, por lo que gana la respuesta más corta (en bytes).

Casos de prueba

Cada caso de prueba es una sola línea que contiene la cadena de entrada, seguida del número óptimo de instrucciones, seguido de una posible solución.

Usted debe no la salida del cómputo de instrucciones en su solución - esto es sólo incluye aquí para que pueda comprobar la exactitud de su código si se imprime una lista de instrucciones 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

Los casos de prueba se generaron con esta implementación de referencia de CJam .

Martin Ender
fuente

Respuestas:

3

CJam, 67 bytes

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

Pruébalo en línea

Explicación:

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
fuente
5

Rubí, 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}

Una función Ruby que solo duplica el tamaño de la implementación de referencia. :)

Pruébelo en línea: http://ideone.com/ysYyFP

El programa es bastante sencillo: comienza con los 8 bits establecidos en 0 e itera a través de los caracteres. En cada paso, toma la ruta más corta desde el estado actual a un estado que permita imprimir el carácter. Devuelve una cadena en el formato especificado.

La versión inicial (menos golfizada) del programa está disponible aquí .

Cristian Lupascu
fuente
4

CJam, 81 76 bytes

Todavía mucho para el golf.

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

Pruébalo en línea .

Andrea Biondo
fuente