Stwórz symulator owijania bąbelków


23

Folie bąbelkowe to rozrywka na najwyższym poziomie. Każdy może się na to zgodzić.

Teraz sprawisz, że nawet komputery będą cieszyć się bąbelkami.

Okular

Otrzymasz dwie liczby całkowite, w i h. (Każda ma odpowiednio szerokość i wysokość)

Twój program powinien wypisać wszystkie fazy w * h, czekając 1 sekundę między nimi i zakończyć.

Każde zawijanie bąbelków zaczyna się od wypełnienia wszystkich komórek.

Na przykład zawijanie bąbelków 4 * 6 zaczyna się tak:

O_O_
_O_O
O_O_
_O_O
O_O_
_O_O

I w każdej fazie wyskakuje losowa, niepopuszczona komórka. Na przykład:

O_O_
_O_O
O_X_
_O_O
O_O_
_O_O

Program powinien zakończyć się, gdy wszystkie komórki zostaną usunięte. znany jako.

X_X_
_X_X
X_X_
_X_X
X_X_
_X_X

Przykłady

(4,6)
(5,5)
(6,2)
(10,10)
(7,9)

Czy możemy użyć 1i 0zamiast Oi X?
Pavel

1
NEEDZ BUBBLEZ pls wyślij pomoc
Christopher

3
Czy dopuszczalne jest, (1,1)aby nie mieć bąbelków (np. Górna lewa „komórka” jest zawsze podkreśleniem)?
Jonathan Allan,

1
@JathanathanAllan Tak.
Matthew Roh,

1
@KevinCruijssen To nie musi być pełny program.
Matthew Roh

Odpowiedzi:


7

C (Windows), 260 248 bajtów

#import<windows.h>
i,j,l,r;b(w,h){char*s=malloc(l=w*h+h);for(i=h;i--;*s++=10)for(j=w;j--;*s++=i%2^j%2?79:45);*(s-1)=0;s-=l;for(srand(time(0));j>system("cls")+puts(s)-2;j>-1?s[j]=88:0)for(Sleep(1000),r=rand(),j=-2,i=r+l*2;--i-r;j=s[i%l]==79?i%l:j);}

enter image description here


Zauważ, że w bibliotece wątków znajduje się funkcja uśpienia, która jest zawarta w C ++ 11.
Matthew Roh,

@MatthewRoh Tak, ale jest on krótszy i system("cls")jest również specyficzny dla systemu Windows, więc kod nie byłby bardziej przenośny z biblioteką wątków. A w C ++ musiałbym również dołączyć iostreamlub cstdio.
Steadybox

przy okazji nie trzeba resetować ekranu. dzięki temu będzie krótszy.
Matthew Roh,

5

Python 3 , 222 220 bajtów

To moja pierwsza odpowiedź, więc proszę, bądź łagodny (i wskaż błędy, które popełniłem).

import time,random as t
def f(c,r):
 p=print;a='0_'*c;d=((a[:c]+'\n'+a[1:c+1]+'\n')*r)[:-~c*r]
 for i in[1]*((r*c+r%2*c%2)//2):
  p(d);k=1
  while d[k]!='0':k=t.randrange(len(d))
  d=d[:k]+'X'+d[k+1:];time.sleep(1)
 p(d)

Wypróbuj online!

Jak to działa:

  1. Połącz wiele „0 _” razem
  2. Posiekaj na części „0_0 _... \ n” i „_0_0 ... \ n” i połącz
  3. Generuj losowe indeksy, aż znak w indeksie wyniesie „0”
  4. Utwórz nowy ciąg znaków z wygenerowanym indeksem i zastąpiony przez „X” (cholera, python, ciągi niemodyfikowalne!)
  5. Powtórz r*c+r%2*c%2czasy: r*cwe wzorze są bąbelki, chyba że r i c są nieparzyste, w takim przypadku są r*c+1.

1
Witamy w PPCG!
AdmBorkBork

1
Jest to raczej niewielkie, ale szerokość i wysokość są odwrócone. Świetna odpowiedź! (Po prostu zmień na, f(c,r)a wszystko będzie dobrze).
rassar

@rassar Woops, dziękuję!
Nile

4

MATL , 37 bajtów

:!i:+o`T&Xxt3:q'_OX'XEcD2y1=ft&v1Zr(T

Lewy górny róg jest zawsze znakiem podkreślenia (dozwolonym przez wyzwanie).

Ekran jest czyszczony między fazami. Mógłbym zapisać bajt, nie czyszcząc ekranu, ale w ten sposób wygląda lepiej.

Program kończy pracę z błędem ( domyślnie dozwolonym ) po wyświetleniu wszystkich faz.

Wypróbuj w MATL Online! (Jeśli nie działa po kilku sekundach, odśwież stronę i spróbuj ponownie).


4

Matematyka (145 bajtów)

Funkcja anonimowa, bierze wysokość i szerokość jako wejścia (w tej kolejności - jeśli to jest problem, wymień {##}się {#2,#}w środku kodu za dodatkowe 2 bajty).

Kod:

Monitor[Do[Pause@1,{i,NestList[RandomChoice@StringReplaceList[#,"O"->"X"]&,""<>Riffle["_"["O"][[Mod[#+#2,2]]]&~Array~{##},"
"],Floor[##/2]]}],i]&

Wyjaśnienie:

  • ""<>Riffle[Array["_"["O"][[Mod[#+#2,2]]]&,{##}],"\n"] tworzy początkowe, nieopakowane zawijanie bąbelków, tworząc tablicę znaków „_” i „O”, a następnie łącząc je między znakami nowej linii.
  • NestList[RandomChoice@StringReplaceList[#,"O"->"X"]&,..., Floor[##/2]]wielokrotnie wybiera jedno z „O”, aby zastąpić je „X”, tyle razy, ile jest „O” (czyli Floor [szerokość * wysokość / 2] - dzięki @JonathanAllan za pomysł wprowadzenia „_ „zamiast„ O ”w lewym górnym rogu, w przeciwnym razie byłoby to Ceilingzamiast tego i 2 bajty więcej).
  • Monitor[Do[Pause@1,{i,...}],i]powoduje ipobranie wartości z listy, którą właśnie obliczyliśmy, przez 1 sekundę i dynamicznie drukuje i.

Przykładowe dane wyjściowe:

GIF z Mathematica wyskakujący z bąbelków


3

Galaretka , 30 29 bajtów

=”OTX
+þ⁹++µị⁾_OYµṄœS1”XǦµÐL

Przykładowy przebieg

Wywołuje link jako diad z argumentami programu, a następnie kończy działanie z komunikatem (dla którego kodu jest çṛ“\'=ṙMḋḌẓ(ėo»)

Niuans: „komórka” w prawym dolnym rogu zawsze będzie bąbelkiem (a nie w lewym górnym rogu, jak w przykładzie w pytaniu), aby zapewnić, że gdy wszystkie bąbelki zostaną wyskakujące, losowy wybór zwraca 0, która będzie "X"na koniec listy - zastąpienie tego nie powoduje zmiany wartości i przerywa pętlę.

Uwaga: nie usuwa ekranu (nie określono i nie jestem pewien, jak to zrobić).

W jaki sposób?

=”OTX - Link 1, choose a random O index or 0: string   e.g. "_O_\nX_O"
 ”O   - "O"
=     - equals (vectorises over the string)            e.g. [0,1,0,0,0,0,1]
   T  - truthy indexes                                 e.g. [2,7]
    X - random choice (if empty this returns 0)

+þ⁹++µị⁾_OYµṄœS1”XǦµÐL - Main link: w, h              e.g. 3, 2
                        - left argument (implicit), w  e.g. 3
  ⁹                     - right argument, h            e.g. 2
 þ                      - outer product with
+                       -     addition                 e.g. [[2,3,4],[3,4,5]]
                        - left argument (implicit), w  e.g. 3
   +                    - add                          e.g. [[5,6,7],[6,7,8]]
                        - right argument (implicit), h e.g. 2
    +                   - add                          e.g. [[7,8,9],[8,9,10]]
     µ                  - monadic chain separation
       ⁾_O              - "_O"
      ị                 - index into (1-based & mod)   e.g. [['_','O','_'],['O','_','O']]
                        -     note: the additions above assure the last entry is an 'O'.
          Y             - join with line feeds         e.g. ['_','O','_','\n','O','_','O']
           µ        µ   - monadic chain separations
                     ÐL - loop until the results are no longer unique:
            Ṅ           -     print with a trailing line feed and yield
             œS1        -     sleep for 1 second and yield
                   ¦    -     apply to index
                  Ç     -         given by calling the last link (1) as a monad 
                        -                 (a random O index or 0 if none exists)
                ”X      -         an "X"  (      ... which will be an X already)

@ ГригорийПерельман napisał to.
Jonathan Allan,

2

Scala , 764 bajty

object B{
  def main(a: Array[String]):Unit={
    val v=false
    val (m,l,k,r,n)=(()=>print("\033[H\033[2J\n"),a(0)toInt,a(1)toInt,scala.util.Random,print _)
    val e=Seq.fill(k, l)(v)
    m()
    (0 to (l*k)/2-(l*k+1)%2).foldLeft(e){(q,_)=>
      val a=q.zipWithIndex.map(r => r._1.zipWithIndex.filter(c=>
        if(((r._2 % 2) + c._2)%2==0)!c._1 else v)).zipWithIndex.filter(_._1.length > 0)
      val f=r.nextInt(a.length)
      val s=r.nextInt(a(f)._1.length)
      val i=(a(f)._2,a(f)._1(s)._2)
      Thread.sleep(1000)
      m()
      val b=q.updated(i._1, q(i._1).updated(i._2, !v))
      b.zipWithIndex.map{r=>
        r._1.zipWithIndex.map(c=>if(c._1)n("X")else if(((r._2 % 2)+c._2)%2==0)n("O")else n("_"))
        n("\n")
      }
      b
    }
  }
}

Jak to działa

Algorytm najpierw wypełnia sekwencję 2D fałszywymi wartościami. Określa liczbę iteracji (otwartych pól) na podstawie wprowadzonych argumentów wiersza poleceń. Tworzy fałd z tą wartością jako górną granicą. Wartość całkowita zwijania jest używana domyślnie tylko jako sposób na zliczenie liczby iteracji, dla których algorytm powinien działać. Wypełniona sekwencja, którą wcześniej utworzyliśmy, jest sekwencją początkową składania. Służy to do generowania nowej sekwencji 2D fałszywych wartości z ich współodpowiedzialnymi indecies.

Na przykład,

[[false, true],
 [true, false],
 [true, true]]

Zostanie zamieniony w

[[(false, 0)], [(false, 1)]]

Zauważ, że wszystkie listy, które są całkowicie prawdziwe (mają długość 0) są pomijane na liście wyników. Algorytm następnie pobiera tę listę i wybiera losową listę z listy najbardziej oddalonych. Losowa lista jest wybrana jako losowy rząd, który wybieramy. Z tego losowego wiersza ponownie znajdujemy losową liczbę, indeks kolumny. Kiedy znajdziemy te dwa losowe wskaźniki, uśpimy wątek, w którym jesteśmy, przez 1000 milisekund.

Po snu wyczyścimy ekran i utworzymy nową tablicę z truewartością zaktualizowaną w losowych indeksach, które stworzyliśmy.

Aby wydrukować to poprawnie, używamy mapi kompresujemy ją wraz z indeksem mapy, abyśmy mieli to w swoim kontekście. Używamy prawdziwej wartości sekwencji, aby sprawdzić, czy powinniśmy wydrukować Xalbo czy Oalbo _. Aby wybrać ten drugi, używamy wartości indeksu jako naszego przewodnika.

Ciekawe rzeczy do odnotowania

Aby dowiedzieć się, czy należy wydrukować an, Oczy an _, ((r._2 % 2) + c._2) % 2 == 0używa się warunkowej . r._2odnosi się do bieżącego indeksu wierszy, a c._2odnosi się do bieżącej kolumny. Jeśli jeden jest w nieparzystym rzędzie, r._2 % 2będzie wynosił 1, a zatem zostanie przesunięty c._2o jeden w warunkowym. Zapewnia to, że w nieparzystych wierszach kolumny są przesuwane o 1 zgodnie z przeznaczeniem.

Wydrukowanie łańcucha "\033[H\033[2J\n", zgodnie z przeczytaną odpowiedzią Stackoverflow, czyści ekran. Pisze bajty do terminala i robi fajne rzeczy, których tak naprawdę nie rozumiem. Ale uważam, że jest to najłatwiejszy sposób, aby to zrobić. Jednak nie działa na emulatorze konsoli Intellij IDEA. Będziesz musiał uruchomić go za pomocą zwykłego terminala.

Innym równaniem, które może wydawać się dziwne, gdy patrzymy na ten kod po raz pierwszy, jest (l * k) / 2 - (l * k + 1) % 2. Najpierw odmytajmy nazwy zmiennych. lodnosi się do pierwszych argumentów przekazanych do programu, podczas gdy kodnosi się do drugiego. Aby przetłumaczyć go (first * second) / 2 - (first * second + 1) % 2. Celem tego równania jest wymyślenie dokładnej liczby iteracji potrzebnych do uzyskania sekwencji wszystkich X-ów. Za pierwszym razem, gdy to zrobiłem, zrobiłem to, co miało (first * second) / 2to sens. Dla każdego nelementu w każdej podlistie są n / 2bąbelki, które możemy otworzyć. Jednak to się psuje, gdy mamy do czynienia z takimi danymi wejściowymi jak(11 13). Musimy obliczyć iloczyn dwóch liczb, uczynić go nieparzystym, jeśli jest parzysty, a nawet jeśli jest nieparzysty, a następnie przyjąć mod tego o 2. Działa to, ponieważ nieparzyste wiersze i kolumny będą wymagały jednej mniej iteracji aby dojść do końcowego wyniku.

mapjest używany zamiast a, forEachponieważ ma mniej znaków.

Rzeczy, które prawdopodobnie można poprawić

Jedną z rzeczy, które naprawdę mnie denerwują w tym rozwiązaniu, jest częste używanie zipWithIndex. Zajmuje tak wiele postaci. Próbowałem to zrobić, aby móc zdefiniować własną funkcję jednoznakową, która po prostu działałaby zipWithIndexz przekazaną wartością. Okazuje się jednak, że Scala nie pozwala, aby funkcja anonimowa miała parametry typu. Jest prawdopodobnie inny sposób robienia tego, co robię bez użycia, zipWithIndexale nie myślałem zbyt wiele o sprytnym sposobie zrobienia tego.

Obecnie kod działa w dwóch przebiegach. Pierwszy generuje nową planszę, podczas gdy drugie przejście drukuje ją. Myślę, że gdyby połączyć te dwa przejścia w jedno przejście, zaoszczędziłoby to kilka bajtów.

To pierwszy kod golfowy, jaki zrobiłem, więc jestem pewien, że jest wiele do zrobienia. Jeśli chcesz zobaczyć kod, zanim zoptymalizuję jak najwięcej bajtów, oto jest.


1

JavaScript (ES6), 246 229 bajtów

document.write(`<pre id=o></pre>`)
setInterval(_=>{(a=o.innerHTML.split(/(O)/))[1]?a[Math.random()*~-a.length|1]=`X`:0;o.innerHTML=a.join``},1e3)
f=(w,h)=>o.innerHTML=[...Array(h)].map((_,i)=>`O_`.repeat(w+h).substr(i,w)).join`
`
<div oninput=f(+w.value,+h.value)><input id=w type=number min=1><input id=h type=number min=1>


Szerokość nie była wyrażona w komórkach, ale obejmowała puste (podkreśla) spacje.
Matthew Roh,

@MatthewRoh Przepraszam, pamiętam, żeby to naprawić dla wysokości, ale zapomniałem sprawdzić szerokość.
Neil

Hmm .. nie można tej części: `${`_O`.repeat(w).slice(w)} ${`O_`.repeat(w).slice(w)}jakoś połączyć? Może logiczna-flag, aby najpierw ustalić, _Oczy O_, a następnie wykonać .repeat(w).slice(w)?
Kevin Cruijssen

1
@KevinCruijssen Straciłem 16 bajtów z powodu szybkiej poprawki błędów, której nie miałem wtedy czasu na grę w golfa. Od tego czasu spojrzałem jeszcze raz i wymyśliłem oszczędność 17 bajtów,
Neil

1

Python - 290 bajtów

Nigdy wcześniej tego nie robiłem - więc każda konstruktywna krytyka byłaby mile widziana :)

Główną sztuczką jest po prostu irytujące zagnieżdżenie list. Mógłbym uratować kilka postaci, nie mając nowej linii między popami, ale to po prostu wygląda brzydko.

r=range
q=print
import random as n,time
def f(H,W):
    def p(b):
        q("\n".join(["".join(["O"if(i,j)in b else"X"if(i,j)in X else"_"for j in r(H)])for i in r(W)]));time.sleep(1);q()
    b=[(i,h)for h in r(H)for i in r(h%2,W,2)];n.shuffle(b);X=[]
    while len(b)>0:
        p(b);X+=[b.pop()]
    p(b)

Cześć, witamy w PPCG! Wyzwanie polegało na przyjęciu wejścia wi hjako danych wejściowych (poprzez STDIN, jako dane wejściowe funkcji lub coś podobnego) zamiast na stałe H=4 W=6. Ponadto, chociaż nigdy nie programowałem w Pythonie, myślę, że możesz zagrać w golfa w niektórych miejscach w swoim obecnym kodzie. Wskazówki dotyczące gry w golfa w Pythonie mogą być również interesujące, aby dać ci pomysły na dalsze gry w golfa. Miłego pobytu! :)
Kevin Cruijssen

Również w odniesieniu do twojego komentarza: „ Mógłbym uratować kilka postaci, nie mając nowej linii między popami, ale to po prostu wygląda brzydko. ” Bez względu na to, jak brzydkie lub jak nie zrobiono tego w prawdziwym programowaniu, codegolf polega na zapisywaniu jako jak najwięcej bajtów. Im krótszy i brzydszy, tym lepiej. ;)
Kevin Cruijssen

@KevinCruijssen Python3 jeden przede mną ma tylko funkcję w, h, czy to dozwolone?
Arya


1
Ok - uczyniłem to teraz funkcją H i W.
Arya

1

Węgiel drzewny , 49 46 39 bajtów (niekonkurencyjny)

UONNO_¶_OAKAαA№αOβHWψβ«A§α§⌕AαO‽βXA№αOβ

Gadatliwy

Oblong(InputNumber(), InputNumber(), "O_\n_O")
Assign(PeekAll(), a)
Assign(Count(a, "O"), b)
RefreshWhile (k, b) {
    AssignAtIndex(a, AtIndex(FindAll(a, "O"), Random(b)), "X")
    Assign(Count(a, "O"), b)
}

1

APL (Dyalog) , 61 59 bajtów

⎕←m'O_'[2|-/¨⍳⎕]
(b/,m)[?+/b'O'=,m]←'X'
DL 1
2/⍨'O'∊⎕←m

⎕← wyprowadza
m←m , gdzie m jest
'O_'[] te znaki indeksowane według…
2| dzielenia-reszty-kiedy-podzielonej-przez-dwóch
-/¨ różnic między każdym z
 wszystkich współrzędnych (indeksów) w tablicy danych
 liczbowych kształtu (liczba wierszy i kolumn )

(... )[... ]←'X' przypisać postać X do jednego z ...
b/ odfiltrowanym ubocznego B (do określenia)
,m raveled elementów m, szczególnie ...
? element losowy (numer Lit.) w jednym obszarze do
+/ suma
b←b , gdzie b jest
'O'= logiczna gdzie litera jest równa
,m m, poszarpana

⎕DL 1re E L Ay jedna sekunda

→2 Przejdź do wiersza 2,
/⍨ jeśli (lit. Przefiltrowane przez),
'O'∊ czy list jest członkiem
⎕←m  wartości wyjściowej, gdzie wartość wyjściowa wynosi m

Wypróbuj online!


Od wersji 16.0 będzie on krótszy:

{0::→⋄'X'@(⊂(?∘≢⊃⊢)⍸'O'=⍵⊣⎕DL 1)⊢⎕←⍵}⍣≡'O_'[2|-/¨⍳⎕]


1

Python 3, 195 188 bajtów

import time,random
def f(w,h):
 a=bytearray(b'0-'*w*h);b=[*range(0,w*h,2)];random.shuffle(b);
 while 1:print(*(a.decode()[w*i:w*i+w]for i in range(h)),sep='\n');a[b.pop()]=88;time.sleep(1)

Używanie bytearrayi decodewydaje się być krótsze niż krojenie i ponowne składanie łańcucha a la a[:i]+'X'+a[i+1:].

import time,random
def f(w,h):
 x=[*range(1,h*w,2)];random.shuffle(x)
 while 1:
  for i in range(w*h):
   print('-X0'[(i%w%2!=i//w%2)+(i in x)],end='\n'[i%w<w-1:])
  print();time.sleep(1);x.pop()

0

Java 7, 317 bajtów

void c(int w,int h)throws Exception{String r="";int x=0,j=0,i;for(;j++<h;x^=1,r+="\n")for(i=0;i<w;r+=(i+++x)%2<1?"_":"O");for(System.out.println(r);r.contains("O");System.out.println(r=r.substring(0,x)+'X'+r.substring(x+1))){Thread.sleep(1000);for(x=0;r.charAt(x)!='O';x=new java.util.Random().nextInt(r.length()));}}

Wyjaśnienie:

void c(int w, int h) throws Exception{                     // Method with two integer parameters (throws Exception is required for the Thread.sleep)
  String r = "";                                           //  String we build to print
  int x=0, j=0, i;                                         //  Some temp values and indexes we use
  for(; j++<h;                                             //  Loop over the height 
      x^=1,                                                //    After every iteration change the flag `x` every iteration from 0 to 1, or vice-versa
      r += "\n")                                           //    And append the String with a new-line
    for(i=0; i<w;                                          //   Inner loop over the width
        r += (i++ + x)%2 < 1 ? "_" : "O")                  //    Append the String with either '_' or 'O' based on the row and flag-integer
    ;                                                      //   End inner width-loop (implicit / no body)
                                                           //  End height-loop (implicit / single-line body)
  for(                                                     //  Loop
    System.out.println(r);                                 //   Start by printing the starting wrap
    r.contains("O");                                       //   Continue loop as long as the String contains an 'O'
    System.out.println(r=                                  //   Print the changed String after every iteration
        r.substring(0,x)+'X'+r.substring(x+1))){           //    After we've replaced a random 'O' with 'X'
      Thread.sleep(1000);                                  //   Wait 1 second
      for(x=0; r.charAt(x) != 'O';                         //   Loop until we've found a random index containing still containing an 'O'
          x = new java.util.Random().nextInt(r.length()))  //    Select a random index in the String
      ;                                                    //   End loop that determines random index containing 'O' (implicit / no body)
  }                                                        //  End loop
}                                                          // End method

Test gif (4,6)

wprowadź opis zdjęcia tutaj


0

Perl, 148 bajtów

146 bajtów kodu + -plflagi.

$_=O x($x=$_+1);s/O\K./_/g;for$i(1..($y=<>)){$b.=($i%2?$_:_.s/.$//r).$/}}print$_="\e[H$b";while(/O/){$r=0|rand$y*$x+3;s/.{$r}\KO/X/s||redo;sleep 1

Aby uruchomić:

perl -ple '$_=O x($x=$_+1);s/O\K./_/g;for$i(1..($y=<>)){$b.=($i%2?$_:_.s/.$//r).$/}}print$_="\e[H$b";while(/O/){$r=0|rand$y*$x+3;s/.{$r}\KO/X/s||redo;sleep 1' <<< "6
4"

0

MATLAB (R2016b), 172 bajty

Kod:

x=input('');m=[eye(x(2),x(1)) ''];m(:)='O';m(1:2:end,2:2:end)='_';m(2:2:end,1:2:end)='_';o=find(m=='O');r=o(randperm(nnz(o)));disp(m);for i=r';pause(1);m(i)='X';disp(m);end

Zalecenia są zawsze mile widziane! Wypróbuj online!

Wyjście programu:

wprowadź opis zdjęcia tutaj

Wyjaśnienie:

x = input( '' );                    % Input
m = [ eye( x( 2 ), x( 1 ) ) '' ];   % Character Matrix
m( : ) = 'O';                       % Fill Matrix with "Bubbles"

m( 1:2:end, 2:2:end ) = '_';        % Alternate Spaces Between Bubbles (Part 1)
m( 2:2:end, 1:2:end ) = '_';        % Alternate Spaces Between Bubbles (Part 2)

o = find( m == 'O' );               % Index Bubble Locations
r = o( randperm( nnz( o ) ) );      % Randomize Bubble Locations

disp( m );                          % Display Initial Bubble Wrap Phase

for i = r'
    pause( 1 );                     % Pause for 1 Second
    m( i ) = 'X';                   % Pop Bubble
    disp( m );                      % Display Subsequent Bubble Wrap Phase
end
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.