Simular rotar una tabla

14

Introducción

Estás jugando un juego de combinación, en el que las monedas se insertan en la parte superior y caen al fondo (sobre la moneda superior) debido a la gravedad.

Así que esto

O <- inserting this coin

OO O
OOOOO

se convertirá en esto

O
OO O
OOOOO

Ahora imagine que alguien gira el tablero en el sentido de las agujas del reloj. Lo siguiente sucederá:

1. El tablero gira

OOO
OO
O
OO
O

2. Las monedas caen debido a la gravedad

O
O
OO
OO
OOO

Tu tarea

Su tarea es simular la rotación de la pizarra escribiendo un programa o una función. En aras de la simplicidad, solo estamos tratando con un tipo de moneda (no es un juego de combinación demasiado emocionante, ¿verdad ...?). Puede suponer que la gravedad se aplica solo después de que se completa la rotación. El tablero se gira en sentido horario.

Entrada

La entrada va a ser una cadena, que contiene 3 tipos de caracteres:

  • O (capital o) O 0 (cero): una moneda (usted decide cuál es su solución)
  • (espacio) - un campo vacío
  • \ n (nueva línea) - fin de fila

La entrada representa el estado de la placa. Puede suponer que la entrada está bien formada y contiene un estado válido del tablero (no hay monedas flotantes). La entrada puede ser un parámetro de función, o puede leerse desde la entrada estándar o desde un archivo.

Salida

La salida es el nuevo estado de la placa después de la rotación. La salida contiene los mismos 3 tipos de caracteres que la entrada. La salida se puede devolver desde su función o se puede escribir en la salida estándar o en un archivo.

Muestra

Entrada1:

O
OO O
OOOOO

Salida1:

O
O
OO
OO
OOO

Entrada2:

O O
O O

Salida2:

OO
OO

Puede usar cualquier idioma y la biblioteca estándar del idioma elegido. El programa más corto en bytes gana.

David Frank
fuente
¿Las líneas más cortas se rellenan con espacios finales?
Ventero
Si lo necesitas, entonces sí.
David Frank
¿Cuáles son los requisitos para el tamaño del tablero? ¿Puedo elegir un tamaño máximo razonable o la aplicación / función necesita funcionar para todos los tamaños posibles?
Fors
2
Si se aplica la gravedad después de la rotación, ¿cómo se convierte Input2 en Output2? ¿Pensé que dejaría caer las monedas superiores pero no horizontalmente?
Matt
2
@ Matt Tenga en cuenta que no hay filas vacías en Input2, ni en Output2 (SE muestra el margen entre las filas).
David Frank

Respuestas:

16

GolfScript, 14 12 caracteres

' '-n%zip$n*

La entrada debe darse en STDIN, el carácter para las monedas puede ser cualquier carácter que no sea un espacio en blanco. Tratar aquí . Gracias a Peter por señalar una reducción de dos caracteres.

Howard
fuente
Oh, lo que no daría por un transposeRuby que puede manejar matrices con diferentes longitudes ...
Ventero
@Ventero La mayoría de las veces que utilice esta versión hacky: ([nil]*a.map(&:size).max).zip(*a). Aunque no es bueno para jugar al golf.
Howard
Puede guardar 2 caracteres: dado que las líneas más largas siempre terminan en la parte inferior, puede reemplazar -1%con $.
Peter Taylor
@PeterTaylor Tienes razón: podemos guardar en caracteres. Gracias.
Howard
1
@PeterTaylor Bueno, incluí un alias de un carácter para " ".
Aditsu renunció porque SE es MAL
6

Javascript (E6) 103

Primer intento, solo operaciones matriciales. Cada fila en la cadena de entrada debe ser rellenada.
Bastante prolijo.

R=t=>(x=t.split('\n').reverse().map(x=>[...x].sort()),x.map((c,i)=>x.map(r=>r[i]).join('')).join('\n'))

Pseudocódigo

  1. cadena -> conjunto de filas
  2. matriz inversa arriba / abajo
  3. cada fila -> matriz de caracteres
  4. ordenar cada fila (las monedas "caen" a la derecha)
  5. transponer
  6. cada conjunto de caracteres en una fila -> una cadena
  7. unir matriz -> cadena única
edc65
fuente
¡Vaya, la clasificación es inteligente (+1)! ¿Te importa si lo robo?
seequ
Nunca he visto la sintaxis [...x]antes. Como se llama
ComFreek
2
@ edc65 Has roto tu propio enlace con paréntesis. Aquí está el enlace correcto
Chris Cirefice
6

Ruby 2.0, 59 caracteres

puts$<.map(&:chars).reverse.transpose.sort[1,50].map &:join

Entrada a través de stdin, supone que todas las líneas tienen la misma longitud Esto es probablemente mucho más largo de lo necesario. Pero al menos es legible ...

Ventero
fuente
Creo que puedes usar $<.mapen su lugar.
Howard
@Howard Eso es algo que siempre olvido. ¡Gracias!
Ventero
1
¿Qué está haciendo [1,50] allí?
No es que Charles
1
@Charles Omite la primera fila, que contiene todas las líneas nuevas de la entrada. David mencionó en un comentario que 50x50 es el tamaño máximo posible, por lo que en lugar de seleccionar todos menos la primera fila ( 1..-1), solo selecciono 50 filas comenzando con la segunda ( 1,50).
Ventero
@Ventero lo entendió. frio. ¡Gracias!
No es que Charles
3

J - 49 31 24 bytes

Creo que puede haber rotaciones innecesarias allí, pero de lo contrario funciona bien. Es una función que toma la entrada como se especifica, las monedas sonO . No se requiere espacio en blanco final en la entrada.

Nueva versión, inspirada en la respuesta Javascript de edc65 :

f=:[:|."1@|:[:/:~"1,;._2

Explicación:

f=:[:|."1@|:[:/:~"1,;._2
                   ,;._2 Split the string at every fret, which is the last character in the string (newline).
              /:~"1      Sort every row separately.
     |."1@|:             Rotate the array clockwise.

Versión antigua:

f=:[:|:((#~=&' '),=&'O'#])"1@|:@(|."1@|:)@(,;._2)

Explicación:

f=:[:|:((#~=&' '),=&'O'#])"1@|:@(|."1@|:)@(,;._2)
                                          (,;._2) Split the string at every fret, which is the last character in the string (newline).
                                (|."1@|:)@        Rotate the array clockwise.
                             |:@                  Reverse the axes (columns become rows and vice-versa).
       ((#~=&' '),=&'O'#])"1                      Function that applies the "gravity"
                          "1                       Apply to every row separately:
                  =&'O'#]                           Get the O's in the row.
       (#~=&' ')                                    Get the spaces in the row.
                ,                                   Join them, spaces come first.
  [:|:                                            Reverse axes again.

Ejemplos (tenga en cuenta que las cadenas multilínea comienzan con 0 : 0y terminan con un paréntesis):

   f 0 : 0
O
OO O
OOOOO
) NB. output starts now
O  
O  
OO 
OO 
OOO
   f 0 : 0
O O
O O
) NB. Output starts now.

OO
OO
seequ
fuente
Si puede, ordene antes de rotar
edc65
@ edc65 Eres un hombre inteligente.
seequ
2

Haskell - 86

Solo estoy aprendiendo, así que estoy seguro de que esto se puede mejorar.

import Data.List
c=putStr.unlines.filter(/="").sort.map(filter(/=' ')).transpose.lines

Entrada de muestra:

let a = "O    \nOO O \nOOOOO"
let b = " O O \n O O "
c a
c b

Salida de muestra:

O
O
OO
OO
OOO

OO
OO
OI
fuente
2

Pitón 2 (69) (79)

for c in sorted(zip(*raw_input().split("\\n"))):print''.join(c[::-1])

Toma entradas rellenadas con espacios para que todas las líneas tengan la misma longitud. El splitcrea un arrat de cada línea. El ziptranspone efectivamente el array. Luego, sortedordena las tuplas en orden lexicográfico, haciendo que todas las monedas caigan al fondo. Finalmente, imprimimos cada línea, convirtiéndola nuevamente en una cadena, aunque primero debemos invertirla. Hacer print'O'*c.count('O')es equivalente y usa el mismo número de caracteres.

Ejemplo de ejecución:

>> O    \nOO O \nOOOOO
O
O
OO
OO
OOO
xnor
fuente
1

C, 167 119 bytes

Esta versión más corta es (¿desafortunadamente?) Mucho más clara que la original también.

m;j;b[99];r;main(){while(j=getchar()+1)j-11?m+=j-33&&++b[r]>m:++r;for(j=r;m+1;putchar(j--?m<b[j]?79:32:(j=r,m--,10)));}
j_random_hacker
fuente
0

Raqueta: 130

(let l((a'()))(let((b(sort(string->list(read-line))char<?)))(if
(null? b)(apply map(λ x(map display x)(newline))a)(l(cons b a)))))

Requiere que rellenes con espacios para que las líneas tengan la misma longitud.

Sylwester
fuente
0

C # - 209 174 bytes

Bien, tengo que probar este código de golf en algún momento, creo. Creó una función (r) que rota el tablero y lo imprime. Supongo que estoy haciendo trampa un poco cuando imprimo mi matriz de caracteres, pero si no puedes entender por qué no deberías estar enojado :)

Gracias a ProgramFOX por los consejos :)

void r(string s){int x=s.IndexOf('\n'),j,i=-1,k,z=x+1;var y=new char[x*x+x];for(;++i<x;y[z*(i+1)-1]='\n')for(k=j=x;j>0;)if(s[i*z+--j]=='0')y[k--*z-i-2]='0';Console.Write(y);}

Engañar

new char[x*x+x]llena la matriz con '\0'y no' '

WozzeC
fuente
1
Eliminar las nuevas líneas y eliminar el espacio entre char[]y yreducirá el recuento de caracteres a 192 caracteres. Además, no es realmente necesario proporcionar la palabra clave statical publicar una respuesta aquí. Eliminarlo reducirá el número de personajes a 185 caracteres.
ProgramFOX
También pude eliminar 'ref' que se olvidó allí desde un intento anterior.
WozzeC