Simula la rotazione di una tavola


14

introduzione

Stai giocando a un gioco di abbinamento, in cui le monete vengono inserite in alto e cadono in basso (sulla moneta in alto) a causa della gravità.

Così questo

O <- inserting this coin

OO O
OOOOO

diventerà questo

O
OO O
OOOOO

Ora immagina che qualcuno ruoti la tavola in senso orario. Succederà quanto segue:

1. La scheda viene ruotata

OOO
OO
O
OO
O

2. Le monete cadono a causa della gravità

O
O
OO
OO
OOO

Il tuo compito

Il tuo compito è simulare la rotazione della scheda scrivendo un programma o una funzione. Per semplicità, abbiamo a che fare solo con un tipo di moneta (non è un gioco di abbinamento troppo eccitante, vero ...). Si può presumere che la gravità sia applicata solo dopo il completamento della rotazione. La scheda viene ruotata in senso orario.

Ingresso

L'input sarà una stringa, che contiene 3 tipi di caratteri:

  • O (maiuscola o) O 0 (zero) - una moneta (decidi quale supporta la tua soluzione)
  • (spazio) - un campo vuoto
  • \ n (nuova riga) - fine della riga

L'ingresso rappresenta lo stato della scheda. Si può presumere che l'input sia ben formato e contenga uno stato valido del tabellone (nessuna moneta fluttua). L'input può essere un parametro di funzione oppure può essere letto dall'input standard o da un file.

Produzione

L'output è il nuovo stato della scheda dopo la rotazione. L'output contiene gli stessi 3 tipi di caratteri dell'input. L'output può essere restituito dalla tua funzione o può essere scritto nell'output standard o in un file.

Campione

input1:

O
OO O
OOOOO

output1:

O
O
OO
OO
OOO

Input2:

O O
O O

Output2:

OO
OO

È possibile utilizzare qualsiasi lingua e la libreria standard della lingua scelta. Vince il programma più breve in byte.


Le linee più corte sono riempite con spazi finali?
Ventero,

Se ne hai bisogno, allora sì.
David Frank,

Quali sono i requisiti per le dimensioni della scheda? Posso scegliere una dimensione massima ragionevole o l'applicazione / funzione deve funzionare per tutte le dimensioni possibili?
Fors,

2
Se la gravità viene applicata dopo la rotazione, in che modo Input2 diventa Output2? Avrei pensato che avrebbe lasciato cadere le monete in alto ma non in orizzontale?
Matt,

2
@Matt Si noti che non ci sono righe vuote in Input2, né in Output2 (SE visualizza il margine tra le righe).
David Frank,

Risposte:


16

GolfScript, 14 12 caratteri

' '-n%zip$n*

L'input deve essere dato su STDIN, il carattere per le monete può essere qualsiasi carattere non bianco. Prova qui . Grazie a Peter per aver sottolineato una riduzione di due personaggi.


Oh, cosa non darei per un transposein Ruby in grado di gestire array con diverse lunghezze ...
Ventero,

@Ventero maggior parte delle volte io uso questa versione hacky: ([nil]*a.map(&:size).max).zip(*a). Non va bene per giocare a golf.
Howard,

Puoi salvare 2 caratteri: poiché le righe più lunghe finiscono sempre in fondo, puoi sostituirle -1%con $.
Peter Taylor,

@PeterTaylor Hai ragione: possiamo salvare in caratteri. Grazie.
Howard,

1
@PeterTaylor Beh, ho incluso un alias di un carattere per " ".
Aditsu ha smesso perché SE è MALE il

6

Javascript (E6) 103

Primo tentativo, solo operazioni a matrice. Ogni riga nella stringa di input deve essere riempita.
Abbastanza prolisso.

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

Codice pseudo

  1. stringa -> matrice di righe
  2. matrice inversa su / giù
  3. ogni riga -> array di caratteri
  4. ordina ogni riga (le monete 'cadono' a destra)
  5. trasporre
  6. ogni array di caratteri in una riga -> una stringa
  7. join array -> stringa singola

Oh wow, l'ordinamento è intelligente (+1)! Ti dispiace se lo rubo?
Seequ,

Non ho mai visto la sintassi [...x] prima. Come si chiama?
ComFreek,


2
@ edc65 Hai rotto il tuo link con parentesi. Ecco il link corretto
Chris Cirefice

6

Ruby 2.0, 59 caratteri

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

Input tramite stdin, presuppone che le linee abbiano tutte la stessa lunghezza. Questo è probabilmente molto più lungo del necessario. Ma almeno è leggibile ...


Penso che tu possa usare $<.mapinvece.
Howard,

@Howard Questa è una cosa che dimentico sempre . Grazie!
Ventero,

1
cosa ci fa [1,50]?
Non che Charles il

1
@Charles Salta la prima riga, che contiene tutte le nuove righe dall'input. David ha menzionato in un commento che 50x50 è la dimensione massima possibile, quindi invece di selezionare tutto tranne la prima riga ( 1..-1), seleziono solo 50 righe a partire dalla seconda ( 1,50).
Ventero,

@Ventero l'ha capito. freddo. Grazie!
Non che Charles il

3

J - 49 31 24 byte

Penso che potrebbero esserci delle rotazioni non necessarie, ma per il resto funziona bene. È una funzione che accetta l'input come specificato, essendo le monete O. Non è richiesto spazio vuoto finale nell'input.

Nuova versione, ispirata alla risposta Javascript di edc65 :

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

Spiegazione:

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.

Vecchia versione:

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

Spiegazione:

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.

Esempi (notare che le stringhe multilinea iniziano con 0 : 0e terminano con una parentesi):

   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

Se puoi, ordina prima di ruotare
edc65,

@ edc65 Sei un uomo intelligente.
Seequ,

2

Haskell - 86

Sto solo imparando, quindi sono sicuro che questo può essere migliorato.

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

Input di esempio:

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

Uscita campione:

O
O
OO
OO
OOO

OO
OO

2

Pitone 2 (69) (79)

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

Accetta input riempiti di spazi in modo che tutte le linee abbiano la stessa lunghezza. Il splitcrea un arrat di ogni riga. Il ziptraspone efficacemente l'array. Quindi, le sortedspecie si agitano in ordine lessicografico, facendo cadere tutte le monete sul fondo. Infine, stampiamo ogni riga, trasformandola in una stringa, anche se prima dobbiamo invertirla. Fare print'O'*c.count('O')è equivalente e usa lo stesso numero di caratteri.

Esempio di esecuzione:

>> O    \nOO O \nOOOOO
O
O
OO
OO
OOO

1

C, 167 119 byte

Questa versione più corta è (purtroppo?) Molto più chiara dell'originale.

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)));}

0

Racchetta: 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)))))

Richiede un pad con spazi, quindi le linee sono uguali.


0

C # - 209 174 byte

Bene, devo provare questo codice golf ad un certo punto, credo. Creata una funzione (r) che ruota la scheda e la stampa. Immagino che stia barando un po 'quando sto stampando il mio array di caratteri, ma se non riesci a capire perché non dovresti essere arrabbiato :)

Grazie a ProgramFOX per i suggerimenti :)

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);}

Truffare

new char[x*x+x]riempie l'array con '\0'e non' '


1
Rimuovere le nuove righe e rimuovere lo spazio tra char[]e yridurrà il conteggio dei caratteri a 192 caratteri. Inoltre, non è davvero necessario fornire la parola chiave staticquando si pubblica una risposta qui. Rimuoverlo ridurrà il conteggio dei personaggi a 185 caratteri.
Programma FOX il

Sono stato anche in grado di rimuovere 'ref' che era stato dimenticato lì da un tentativo precedente.
WozzeC,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.