Simulasikan memutar papan

14

pengantar

Anda memainkan permainan yang cocok, di mana koin dimasukkan di bagian atas dan jatuh ke bawah (ke koin atas) karena gravitasi.

Jadi ini

O <- inserting this coin

OO O
OOOOO

akan menjadi ini

O
OO O
OOOOO

Sekarang bayangkan seseorang memutar papan searah jarum jam. Berikut ini akan terjadi:

1. Papan diputar

OOO
OO
O
OO
O

2. Koin jatuh karena gravitasi

O
O
OO
OO
OOO

Tugas Anda

Tugas Anda adalah mensimulasikan rotasi papan dengan menulis program atau fungsi. Demi kesederhanaan, kami hanya berurusan dengan satu jenis koin (itu bukan permainan yang cocok yang menarik, bukan ...). Anda dapat mengasumsikan bahwa gravitasi diterapkan hanya setelah rotasi selesai. Papan diputar searah jarum jam.

Memasukkan

Input akan berupa string, yang berisi 3 jenis karakter:

  • O (modal o) ATAU 0 (nol) - koin (Anda memutuskan solusi mana yang didukung)
  • (spasi) - bidang kosong
  • \ n (baris baru) - akhir baris

Input mewakili kondisi dewan. Anda dapat mengasumsikan, input terbentuk dengan baik dan berisi status board yang valid (tidak ada koin yang mengambang). Input dapat berupa parameter fungsi, atau dapat dibaca dari input standar atau dari file.

Keluaran

Output adalah keadaan baru dari papan setelah rotasi. Output berisi 3 jenis karakter yang sama dengan input. Output dapat dikembalikan dari fungsi Anda atau dapat ditulis ke output standar atau ke file.

Sampel

Input1:

O
OO O
OOOOO

Output1:

O
O
OO
OO
OOO

Input2:

O O
O O

Output2:

OO
OO

Anda dapat menggunakan bahasa apa pun dan perpustakaan standar dari bahasa yang dipilih. Program terpendek dalam byte menang.

David Frank
sumber
Apakah garis yang lebih pendek diisi dengan spasi tambahan?
Ventero
Jika Anda membutuhkannya maka ya.
David Frank
Apa persyaratan untuk ukuran papan? Dapatkah saya memilih ukuran maksimum yang masuk akal, atau apakah aplikasi / fungsi perlu bekerja untuk semua ukuran yang mungkin?
Fors
2
Jika gravitasi diterapkan setelah rotasi, bagaimana Input2 menjadi Output2? Saya akan berpikir itu akan menjatuhkan koin atas tetapi tidak secara horizontal?
Matt
2
@ Mat Catatan, bahwa tidak ada baris kosong di Input2, maupun di Output2 (SE menampilkan margin antara baris).
David Frank

Jawaban:

16

GolfScript, 14 12 karakter

' '-n%zip$n*

Masukan harus diberikan pada STDIN, karakter untuk koin dapat berupa karakter yang bukan spasi. Coba di sini . Terima kasih kepada Peter karena menunjukkan pengurangan dua karakter.

Howard
sumber
Oh, apa yang tidak akan saya berikan untuk transpose di Ruby yang dapat menangani array dengan panjang berbeda ...
Ventero
@Ventero Sebagian besar waktu saya menggunakan versi Hacky ini: ([nil]*a.map(&:size).max).zip(*a). Tidak bagus untuk bermain golf.
Howard
Anda dapat menyimpan 2 karakter: karena garis terpanjang selalu berakhir di bagian bawah, Anda dapat menggantinya -1%dengan $.
Peter Taylor
@PeterTaylor Anda benar - kita dapat menyimpan ke karakter. Terima kasih.
Howard
1
@PeterTaylor Yah, saya memang menyertakan alias satu karakter untuk " " .
Aditsu berhenti karena SE adalah JAHAT
6

Javascript (E6) 103

Coba pertama, hanya operasi matriks. Setiap baris dalam string input harus diisi.
Cukup bertele-tele.

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

Kode palsu

  1. string -> array baris
  2. array terbalik atas / bawah
  3. setiap baris -> array char
  4. urutkan setiap baris (koin 'jatuh' ke kanan)
  5. mengubah urutan
  6. setiap char array dalam satu baris -> sebuah string
  7. bergabung dengan array -> string tunggal
edc65
sumber
Oh wow, menyortir itu pintar (+1)! Keberatan jika aku mencurinya?
seequ
Saya belum pernah melihat sintaksis [...x]sebelumnya. Disebut apakah itu?
ComFreek
2
@ edc65 Anda memutuskan tautan sendiri dengan tanda kurung. Inilah tautan yang benar
Chris Cirefice
6

Ruby 2.0, 59 karakter

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

Input melalui stdin, menganggap semua saluran memiliki panjang yang sama. Ini mungkin jauh lebih lama dari yang diperlukan. Tapi setidaknya itu bisa dibaca ...

Ventero
sumber
Saya pikir Anda bisa menggunakannya $<.mapsebagai gantinya.
Howard
@Howard Itu satu hal yang selalu saya lupakan. Terima kasih!
Ventero
1
apa yang [1,50] lakukan di sana?
Bukan karena Charles
1
@Charles Melewati baris pertama, yang berisi semua baris baru dari input. David disebutkan dalam komentar bahwa 50x50 adalah ukuran maksimum yang mungkin, jadi alih-alih memilih semua kecuali baris pertama ( 1..-1), saya hanya memilih 50 baris dimulai dengan yang kedua ( 1,50).
Ventero
@Ventero mengerti. keren. Terima kasih!
Bukan berarti Charles
3

J - 49 31 24 byte

Saya pikir mungkin ada rotasi yang tidak perlu di sana, tetapi jika tidak berfungsi dengan baik. Ini adalah fungsi yang mengambil input seperti yang ditentukan, koin menjadiO . Tidak diperlukan spasi spasi tambahan di input.

Versi baru, terinspirasi oleh jawaban Javascript edc65 :

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

Penjelasan:

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 lama:

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

Penjelasan:

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.

Contoh (perhatikan bahwa string multiline dimulai dengan 0 : 0dan diakhiri dengan braket):

   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
sumber
Jika Anda bisa, urutkan sebelum memutar
edc65
@ edc65 Kamu pria yang pintar.
seequ
2

Haskell - 86

Baru belajar, jadi saya yakin ini bisa diperbaiki.

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

Input sampel:

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

Output sampel:

O
O
OO
OO
OOO

OO
OO
OI
sumber
2

Python 2 (69) (79)

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

Mengambil input yang diisi dengan spasi sehingga semua garis memiliki panjang yang sama. The splitmenciptakan arrat dari setiap baris. The zipefektif transposes array. Kemudian, sortedjenis tupel dalam urutan leksikografis, menyebabkan semua koin jatuh ke bawah. Akhirnya, kami mencetak setiap baris, mengubahnya kembali menjadi string, meskipun kami harus membaliknya terlebih dahulu. Melakukan print'O'*c.count('O')adalah setara dan menggunakan jumlah karakter yang sama.

Contoh dijalankan:

>> O    \nOO O \nOOOOO
O
O
OO
OO
OOO
Tidak
sumber
1

C, 167 119 byte

Versi yang lebih pendek ini (sayangnya?) Jauh lebih jelas daripada yang asli juga.

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
sumber
0

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

Ini mengharuskan Anda membuat pad dengan spasi sehingga garis-garisnya sama.

Sylwester
sumber
0

C # - 209 174 bytes

Benar, saya harus mencoba golf Kode ini di beberapa titik saya rasa. Menciptakan fungsi (r) yang memutar papan dan mencetaknya. Saya kira saya sedikit curang ketika saya mencetak array char saya, tetapi jika Anda tidak tahu mengapa Anda tidak boleh marah :)

Terima kasih kepada ProgramFOX untuk tipsnya :)

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

Curang

new char[x*x+x]mengisi array dengan '\0'dan tidak' '

WozzeC
sumber
1
Menghapus baris baru dan menghapus spasi di antara char[]dan yakan mengurangi jumlah karakter Anda menjadi 192 karakter. Juga, tidak benar-benar diperlukan untuk memberikan kata kunci staticsaat mengirim jawaban di sini. Menghapusnya akan mengurangi jumlah karakter Anda menjadi 185 karakter.
ProgramFOX
Saya juga dapat menghapus 'ref' yang telah dilupakan di sana sejak percobaan sebelumnya.
WozzeC