Symuluj obracanie tablicy

14

Wprowadzenie

Grasz w pasującą grę, w której monety są wkładane u góry i opadają na dno (na górną monetę) z powodu grawitacji.

Więc to

O <- inserting this coin

OO O
OOOOO

stanie się tym

O
OO O
OOOOO

Teraz wyobraź sobie, że ktoś obraca tablicę zgodnie z ruchem wskazówek zegara. Staną się następujące zdarzenia:

1. Tablica jest obrócona

OOO
OO
O
OO
O

2. Monety spadają z powodu grawitacji

O
O
OO
OO
OOO

Twoje zadanie

Twoim zadaniem jest symulacja obrotu tablicy, pisząc program lub funkcję. Dla uproszczenia mamy do czynienia tylko z jednym rodzajem monety (nie jest to zbyt ekscytująca gra polegająca na dopasowywaniu, prawda?). Możesz założyć, że grawitacja jest stosowana dopiero po zakończeniu obrotu. Płyta jest obracana zgodnie z ruchem wskazówek zegara.

Wejście

Dane wejściowe będą ciągiem znaków, który zawiera 3 typy znaków:

  • O (kapitał o) LUB 0 (zero) - moneta (Ty decydujesz, które obsługuje Twoje rozwiązanie)
  • (spacja) - puste pole
  • \ n (nowa linia) - koniec wiersza

Dane wejściowe reprezentują stan płyty. Możesz założyć, że dane wejściowe są dobrze uformowane i zawierają prawidłowy stan planszy (nie płyną żadne monety). Wejście może być parametrem funkcji lub może być odczytane ze standardowego wejścia lub z pliku.

Wynik

Wyjście to nowy stan płytki po obrocie. Dane wyjściowe zawierają te same 3 typy znaków co dane wejściowe. Dane wyjściowe mogą zostać zwrócone z funkcji lub zapisane na standardowym wyjściu lub w pliku.

Próba

Wejście 1:

O
OO O
OOOOO

Wyjście 1:

O
O
OO
OO
OOO

Input2:

O O
O O

Wyjście 2:

OO
OO

Możesz użyć dowolnego języka i standardowej biblioteki wybranego języka. Najkrótszy program w bajtach wygrywa.

David Frank
źródło
Czy krótsze linie są wypełnione spacjami?
Ventero
Jeśli potrzebujesz, to tak.
David Frank
Jakie są wymagania dotyczące rozmiaru płyty? Czy mogę wybrać rozsądny maksymalny rozmiar, czy aplikacja / funkcja musi działać dla wszystkich możliwych rozmiarów?
Fors
2
Jeśli grawitacja zostanie zastosowana po obrocie, w jaki sposób Input2 staje się Output2? Myślałem, że spadnie górne monety w dół, ale nie poziomo?
Matt
2
@Matt Zauważ, że nie ma pustych wierszy na Input2, ani na Output2 (SE wyświetla margines między wierszami).
David Frank

Odpowiedzi:

16

GolfScript, 14 12 znaków

' '-n%zip$n*

Dane wejściowe należy podać na STDIN, znakiem dla monet mogą być dowolne znaki spacje. Spróbuj tutaj . Dzięki Peterowi za zwrócenie uwagi na redukcję dwóch postaci.

Howard
źródło
Och, czego bym nie dał za transposeRuby, które poradzi sobie z tablicami o różnych długościach ...
Ventero
@Ventero Większość czasu używam tego hacky wersję: ([nil]*a.map(&:size).max).zip(*a). Nie nadaje się do gry w golfa.
Howard
Można zapisać 2 znaków: ponieważ najdłuższe linie zawsze kończy się na dole, można zastąpić -1%z $.
Peter Taylor
@PeterTaylor Masz rację - możemy zapisywać znaki. Dziękuję Ci.
Howard
1
@PeterTaylor Cóż, dodałem alias jednoznakowy dla " ".
Aditsu zrezygnowało, ponieważ SE ma EVIL
6

JavaScript (E6) 103

Pierwsza próba, tylko operacje na macierzach. Każdy wiersz w ciągu wejściowym musi być wypełniony.
Całkiem niewygodny.

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

Pseudo kod

  1. string -> tablica wierszy
  2. odwrotna tablica góra / dół
  3. każdy wiersz -> tablica znaków
  4. posortuj każdy rząd (monety „spadają” w prawo)
  5. transponować
  6. każda tablica znaków w rzędzie -> ciąg
  7. łączyć tablicę -> pojedynczy ciąg
edc65
źródło
O rany, sortowanie jest sprytne (+1)! Czy mogę to ukraść?
patrz
Nigdy wcześniej nie widziałem tej składni [...x]. Jak to jest nazywane?
ComFreek
2
@ edc65 Złamałeś własny link w nawiasach. Oto poprawny link
Chris Cirefice
6

Ruby 2.0, 59 znaków

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

Wejście przez stdin, zakłada, że ​​wszystkie linie mają tę samą długość. Jest to prawdopodobnie znacznie dłużej niż to konieczne. Ale przynajmniej jest czytelny ...

Ventero
źródło
Myślę, że możesz $<.mapzamiast tego użyć .
Howard
@ Howard To jedna rzecz, o której zawsze zapominam. Dzięki!
Ventero
1
co tam robi [1,50]?
Nie to, że Charles
1
@Charles Pomija pierwszy wiersz, który zawiera wszystkie nowe wiersze z wejścia. David wspomniał w komentarzu, że 50 x 50 jest maksymalnym możliwym rozmiarem, więc zamiast wybierać wszystkie oprócz pierwszego wiersza ( 1..-1), po prostu wybieram 50 wierszy, zaczynając od drugiego ( 1,50).
Ventero
@Ventero ma to. chłodny. dzięki!
Nie to, że Charles
3

J - 49 31 24 bajtów

Myślę, że mogą tam występować niepotrzebne obroty, ale w przeciwnym razie działa dobrze. Jest to funkcja, która pobiera dane wejściowe zgodnie z opisem, monety są O. Wejście nie wymaga spacji końcowych.

Nowa wersja, zainspirowana odpowiedzią JavaScript edc65 :

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

Wyjaśnienie:

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.

Stara wersja:

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

Wyjaśnienie:

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.

Przykłady (zauważ, że ciągi wielowierszowe zaczynają się 0 : 0i kończą na nawiasie):

   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
patrz
źródło
Jeśli możesz, posortuj przed obróceniem
edc65
@ edc65 Jesteś mądrym człowiekiem.
patrz
2

Haskell - 86

Właśnie się uczę, więc jestem pewien, że można to poprawić.

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

Przykładowe dane wejściowe:

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

Przykładowe dane wyjściowe:

O
O
OO
OO
OOO

OO
OO
OI
źródło
2

Python 2 (69) (79)

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

Pobiera dane wypełnione spacjami, aby wszystkie linie miały jednakową długość. splitTworzy arrat każdej linii. zipSkutecznie transpozycję macierzy. Następnie sortedsortuje krotki w porządku leksykograficznym, powodując, że wszystkie monety spadają na dno. Na koniec drukujemy każdą linię, zamieniając ją z powrotem w ciąg znaków, jednak najpierw musimy ją odwrócić. Działanie print'O'*c.count('O')jest równoważne i wykorzystuje tę samą liczbę znaków.

Przykładowy przebieg:

>> O    \nOO O \nOOOOO
O
O
OO
OO
OOO
xnor
źródło
1

C, 167 119 bajtów

Ta krótsza wersja jest (niestety?) Znacznie bardziej przejrzysta niż oryginał.

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
źródło
0

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

Wymaga padania spacjami, aby linie były równe długości.

Sylwester
źródło
0

C # - 209 174 bajtów

Racja, muszę spróbować golfa Code w pewnym momencie. Utworzono funkcję (r), która obraca tablicę i drukuje ją. Chyba trochę oszukuję, kiedy drukuję swoją tablicę znaków, ale jeśli nie możesz zrozumieć, dlaczego nie powinnaś być zła :)

Dzięki ProgramFOX za wskazówki :)

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

Oszukać

new char[x*x+x]wypełnia tablicę '\0'i nie' '

WozzeC
źródło
1
Usuwając nowe linie i usuwanie przestrzeń pomiędzy char[]i yzmniejszy liczbę znaków do 192 znaków. Ponadto, nie jest tak naprawdę konieczne podanie słowa kluczowego staticpodczas zamieszczania odpowiedzi tutaj. Usunięcie go zmniejszy liczbę twoich postaci do 185 znaków.
ProgramFOX
Mogłem również usunąć „ref”, który został tam zapomniany od czasu wcześniejszej próby.
WozzeC