Przeanalizuj listę podpisanych jednoznacznych liczb


16

Liczby jednoargumentowe zwykle reprezentują tylko nieujemne liczby całkowite, ale możemy je rozszerzyć tak, aby reprezentowały wszystkie liczby całkowite w następujący sposób:

  • Dodatnia liczba całkowita N jest reprezentowana przez N 1:5 -> 11111
  • Ujemna liczba całkowita -N jest reprezentowana 0przez następującą po niej literę N 1:-5 -> 011111
  • Zero jest reprezentowane jako 0

Następnie możemy jednoznacznie przedstawić listę tych liczb, jeśli użyjemy 0jako separatora:

3,-2,0,1
111,011,0,1
111 0 011 0 0 0 1
11100110001

Twoje zadanie: weź ciąg reprezentujący taką listę podpisanych liczb jednoargumentowych i przetłumacz go na listę liczb dziesiętnych.

Detale

Możesz założyć, że dane wejściowe to pełna lista podpisanych liczb jednoargumentowych. W szczególności twój program nie będzie musiał obsługiwać 1) pustych danych wejściowych lub 2) danych wejściowych, które kończą się separatorem.

Możesz założyć, że wielkość każdej liczby nie przekroczy 127. W przypadku języków o maksymalnych rozmiarach ciągów lub list możesz założyć, że dane wejściowe i wyjściowe będą pasować do struktur danych Twojego języka, ale Twój algorytm powinien teoretycznie działać dla listy dowolny rozmiar.

Twój program lub funkcja może wykonywać operacje we / wy na dowolny ze standardowych sposobów . Dane wejściowe mogą być ciągiem lub listą znaków, ciągami jednoznakowymi, liczbami całkowitymi lub wartościami logicznymi. Możesz użyć dowolnych dwóch znaków do przedstawienia 1i 0; jeśli nie używasz 1i 0, określ, jakich znaków używasz.

Dane wyjściowe muszą być liczbami dziesiętnymi w dowolnym rozsądnym formacie listy (w szczególności musi istnieć pewnego rodzaju separator między liczbami). Liczby ujemne powinny być oznaczone znakiem minus, chociaż jeśli twój język ma inny format ujemnych liczb całkowitych, również to zaakceptuję. Zero może być reprezentowane na wyjściu jako 0lub -0.

Przypadki testowe

1 -> 1
0 -> 0 (or -0, and similarly for the other test cases)
011 -> -2
1101 -> 2,1
1100 -> 2,0
11001 -> 2,-1
110001 -> 2,0,1
11100110001 -> 3,-2,0,1
00000001 -> 0,0,0,-1
01111011111111001111111111111110111111111111111100111111111111111111111110111111111111111111111111111111111111111111 -> -4,8,-15,16,-23,42
01111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 -> -127

2
Nitpick: Ponieważ zawiera '0's, nie jest to technicznie jednoznaczne. Dobre wyzwanie!
DJMcMayhem

4
@DJMcMayhem Nitpick do nitpick: Technicznie nigdy nie powiedziałem, że to jednoargumentowe. To rozszerzenie unarskiego, które nazywam „podpisanym unarskim”. ;)
DLosc

@DJMcMayhem IMO, wyzwanie polega na tym, że separator ( 0) i przedrostek znaku ujemnego ( 0) są takie same, chociaż nadal są jednoznaczne, ponieważ nie można mieć znaków ujemnych w środku liczby (czy 182--693-1liczba? Nie, i żadne nie jest 1111011000101111z tego samego powodu).
Erik the Outgolfer,

Czy jest w porządku, jeśli lista wyjściowa jest w odwrotnej kolejności do wejścia?
DJMcMayhem

technicznie dziesiętny też nie jest dziesiętny, ponieważ używa symbolu „-”
Unlambder

Odpowiedzi:


10

Python 2 , 73 70 bajtów

Funkcja, która pobiera ciąg jako dane wejściowe i zwraca ciąg reprezentujący listę w języku Python. Zero może być reprezentowane zarówno przez, jak 0i -0(gdy jest ostatnie):

lambda s:`map(len,s.split('0'))`.replace('0, ','-').replace('--','0,')

Wyjaśnienie

  1. splitciąg wejściowy sna zerach.
  2. Weź długość każdego łańcucha na wynikowej liście (używając map).

To zajmuje nam długą drogę. Zera były przecież separatorami. A liczby były jedne, więc lenwygodnie zamienia je na dziesiętne. Ale teraz zawiedliśmy wszystkie zastosowania, które nie są separatorami 0. Na szczęście wszystkie zastosowania bez separatora były zerami wiodącymi, więc pojawiły się po separatorze zero i dały nam ciągi zerowej długości ('00'.split('0') == ['', '', ''] ). Te łańcuchy o zerowej długości stały się również 0spowodowane przez len.

  1. Zamień listę w ciąg znaków ( używając „odwrotnych cudzysłowów” ), aby łatwiej naprawić problem.
  2. replacekażde zero poprzedzające inną liczbę zamiast znaku minus na tej liczbie. To naprawia użycie0 znaku jako, ale łamie dosłowne zera. Dosłowne zera poprzedzone były również separatorem, więc teraz stały się parami dodatkowych myślników na następnej liczbie.
  3. replacekażdy z --powrotem do 0elementu na „liście”.

1
Witamy w PPCG!
Steadybox

To naprawdę kreatywne podejście! Możesz dodać krótkie wyjaśnienie, aby ci, którzy nie mówią w języku Python, również docenili twoją odpowiedź.
DLosc

@DLosc, dzięki, nie wiedziałem o backtick. Dodano również dziwne wyjaśnienie.
mercator,

8

Siatkówka , 23 21 bajtów

(.)0
$1 
01
-1
1+
$.&

Wypróbuj online!

Pierwszy etap (.)0<newline>$1<space>odpowiada dowolnej postaci, po której następuje 0. Dopasowanie zostanie zastąpione pierwszym znakiem, a następnie spacją. To dzieli ciąg na poszczególne liczby.

Drugi etap 01<newline>-1zamienia 0przed blokiem 1na -znak.

Ostatni etap 1+<newline>$.&dopasowuje wszystkie bloki 1i zastępuje je długością grupy.

Oto przykład z wynikami poszczególnych etapów.


Bardzo fajnie - wszystkie moje pomysły wydają się mieć 24 bajty ...
Neil

1
Czy możesz dodać wyjaśnienie? Nie mówię po siatkówce.
Daniel

@Dopapp dodał wyjaśnienie
ovs

7

Vim, 56 bajtów

:s/\v(0?1*)0?/\1\r/g|%s/0/-/|%s/1*$/\=len(submatch(0))
D

Wypróbuj online!

Jakiś czas nie pisałem w vimie. Najczęściej używam vima, ponieważ V jest czasem bólem. Ponieważcount polecenie, które idealnie nadaje się do uzyskania liczby „1” w linii, nadpisze wszelkie „0” w linii, więc nie możemy jej później zanegować.

Wyjaśnienie:

Jest to jeden bajt krótszy niż prosty sposób:

:s/\v(0?1*)0?/\1\r/g
:%s/0/-
:%s/1*$/\=len(submatch(0))
D

z powodu łączenia poleceń. Ponieważ ten rozdziela polecenia, użyję go do wyjaśnienia.

:s/                     " Substitute
                        " Search for...
   \v                   "   Enable 'magic'. This determines whether certain atoms require a backslash or not.
                        "   Without it we would have: '\(0\?1*\)0\?', which is 2 bytes longer
      0?                "   An optional 0
        1*              "   Followed by any number of '1's
     (    )             "   (call that group 1)
           0?           "   Followed by another optional 0
             /          " Replace it with...
              \1        "   Subgroup 1
                \r      "   A newline
                  /g    " Do this for every match on the current line.

Teraz każdy podpisany numer jednoargumentowy znajduje się w osobnej linii. Na przykładzie „11100110001” będziemy w tym momencie:

111
011
0
1

:%s/0   " Replace every 0
     /- " With a dash  

:%s/1*$/                    " Replace every run of 1's at the end of a line
        \=len(submatch(0))  " With the length of said run

Ponieważ dodawaliśmy nowe wiersze na końcu każdego meczu, przed uruchomieniem mieliśmy pustą linię. Po uruchomieniu tego otrzymamy „0” (ponieważ pasowało do serii 0 „1”). Więc po prostu dzwonimy, Daby usunąć tę linię, pozostawiając ją pustą


Ugh. :%s/1+$/dałby ci jeden bajt krótszy, gdyby nie potrzeba odwrotnego ukośnika +:(
NieDzejkob

@NieDzejkob Nie rozumiem, dlaczego byłoby to krótsze. Dałoby to -zamiast 0lub-0
DJMcMayhem

Chciałem w ten sposób wyeliminować ostatnią linię: P, nieważne.
NieDzejkob,

7

Haskell , 68 66 bajtów

f(x:r)|(a,b)<-span(>0)r=([(0-),(1+)]!!x$sum a):[z|_:t<-[b],z<-f t]

Wypróbuj online! Pobiera dane wejściowe jako listę zer i jedynek. Przykładowe użycie: f [0,0,0,1,1]daje [0,-2].

Wyjaśnienie:

Dopasowanie wzorca w f(x:r)|(a,b)<-span(>0)rwiąże xsię z pierwszym elementem danych wejściowych, a(potencjalnie pustą) listą kolejnych 1s oraz bz resztą danych wejściowych. Biorąc pod uwagę wejście [0,1,1,1,0,0,1], otrzymujemy x=0,a=[1,1,1] ib=[0,0,1] .

Bieżąca liczba jest wówczas albo sumą azanegowanego if x=0, albo sumą aplus jeden if x=1. Osiąga się to poprzez indeksowanie z xdo listy zawierającej funkcję negacji i przyrost i zastosowanie uzyskanego funkcji sumy a: [(0-),(1+)]!!x$sum a.

Lista reszty bjest pusta lub zawiera oddzielające zero i następną liczbę. Zrozumienie listy [z|_:t<-[b],z<-f t]próbuje dopasować bsię do wzorca _:t, to znaczy zapomnieć o elemencie head i powiązać resztę listy t. Jeśli bjest puste, to dopasowanie kończy się niepowodzeniem, a interpretacja listy ocenia [], co jest podstawowym przypadkiem rekurencji. W przeciwnym razie funkcja fjest rekurencyjnie stosowana, ta interpretacja listy ocenia wszystkie elementy zz wyniku f t.


3

Wolfram Language (Mathematica) , 80 bajtów

StringCases[#<>"0",x_~~Shortest@y___~~"0":>(If[x=="0",-#,#+1]&)@StringLength@y]&

Wypróbuj online!

Nadużywa mechaniki StringCases , ponieważ nie sprawdza nakładających się wzorów. Ponieważ szukamy od lewej do prawej, bez nakładania się, zawsze otrzymujemy tylko liczby całkowite, których potrzebujemy.

Wyjaśnienie

#<>"0"

Dodaj zero na końcu

StringCases

Znajdź wszystkie następujące wzory ...

x_~~Shortest@y___~~"0"

Pojedynczy znak (nazwij go x), po którym następuje możliwie najkrótszy ciąg o zerowej długości lub dłuższy (nazwij go y), po którym następuje zero.

(If[x=="0",-#,#+1]&)@StringLength@y

Zastosuj do pasującego wzoru: weź długość y. Gdybyx wynosi zero, zaneguj wartość. W przeciwnym razie, zwiększ o jeden.

Obejmuje to 00również, ponieważ ybyłby to pusty ciąg znaków i obliczalibyśmy -0( == 0).


3

Brain-Flak , 94 (70?) Bajtów

([]){{}({(<()>)()}{}(<>)<>{<([{}]<>{})><>})
{{}<>([{}])(<>)}{}{}([])}{}<>([]){{}({}<>)<>([])}<>

Wypróbuj online!

Jest to w rzeczywistości zaskakująco zwięzłe, jeśli chodzi o atak mózgu.

Oto skomentowana / czytelna wersja:

([])

{

    #Pop the Stack height
    {}

    (
        #If there isn't a leading 0, evaluate to 1...
        {
            (<()>)

            ()
        }

        #Pop the 0
        {}

        #Push a 0 onto the alternate stack
        (<>)
        <>

        #Run of '1's
        {
            #Decrement the alternate stack
            <([{}]<>{})>
            <>
        }

        #And push it here
    )

    #Was there a not leading 0?

    {
        {}

        #Invert the value on the alternate stack
        <>([{}])(<>)
    }

    #Pop 2 zeros
    {}{}


    ([])

}{}<>

#Push stack height
([])

#Reverse the stack
{

    {}

    ({}<>)

    <>([])

}<>

Jeśli wyjście może być odwrócone, możemy to zrobić dla 70 zamiast tego:

([]){{}({(<()>)()}{}(<>)<>{<([{}]<>{})><>}){{}<>([{}])(<>)}{}{}([])}<>

Ten mój tip jest prawie idealny na tę sytuację. Ale to nie do końca działa, ponieważ musimy nacisnąć 0 przed wykonaniem operacji (licząc „1”), a operacja odbywa się w pętli. Najkrótsze, jakie mogłem wymyślić z wykorzystaniem tej wskazówki, to:

([]){{}({(<()>)()}{}(<>)<>{<([{}]<>{})><>})
{{}<>([{}])(<>)}{}{}(<>())<>([])}{}<>{{}({}<>)<>}<>

który jest również 94 bajtami.



3

Łuska , 20 18 17 15 14 bajtów

Γ~:?Σṁ_Πȯ₀tΣġ/

Wypróbuj online!

Wyjaśnienie

Γ~:?Σṁ_Πȯ₀tΣġ/  Input is a list, say x = [0,1,1,0,0,0,1,1]
            ġ   Group by
             /  division.
                This splits x right before each 0: [[0,1,1],[0],[0],[0,1,1]]
Γ               Deconstruct into head y = [0,1,1] and tail z = [[0],[0],[0,1,1]]
   ?Σṁ_Π        Apply to y:
       Π         Product: 0
   ?Σ            If that is nonzero, take sum of y,
     ṁ_          else take sum of negated elements of y: u = -2
        ȯ₀tΣ    Apply to z:
           Σ     Concatenate: [0,0,0,1,1]
          t      Drop first element: [0,0,1,1]
         ₀       Recurse: [0,2]
 ~:             Tack u to the front: [-2,0,2]

Podział działa w ten sposób. ġ/dzieli swój argument na każdą parę elementów, w a,bprzypadku której /a bwystępuje fałsz. /a bto podział z odwróconymi argumentami, więc bpodzielony przez a. Odpowiednie wartości w tym programie to:

  • /1 1daje 1(prawda).
  • /1 0daje 0(fałsz).
  • /0 1daje Inf(pozytywna nieskończoność, prawda).
  • /0 0daje Any(specjalna wartość podobna do NaN, fałsz).

3

Acc !! , 252 237 bajtów

N
Count i while _/48 {
Count n while 48/_ {
Write 45
50+N
}
_+49/_*50
Count u while _%50/49 {
_+100-_%50+N
}
_/50-1
Count h while _/200 {
Write _/200+48
_%200+1
}
Count t while _/20+_%2 {
Write _/20+48
_%20-_%2
}
Write _/2+48
Write 9
N
}

Zastosowania -0. Wyświetla liczby oddzielone znakami tabulacji z tabulatorem końcowym. Wypróbuj online!

Ilość czasu na zapisanie faktycznego algorytmu: 20 minut. Czas debugowania mojego dziesiętnego kodu wyjściowego: 45 minut. : ^ P

Z komentarzami

Nie wiem, czy te komentarze bardzo dobrze wyjaśniają kod - opierają się na moich notatkach do siebie, gdy go pisałem, więc zakładają, że rozumieją, jak Acc !! Pracuje. Jeśli coś wymaga więcej wyjaśnień, daj mi znać, a postaram się to wyjaśnić.

# We partition the accumulator _ as [number][flag][nextchar]
# [flag] is a 2-value slot and [nextchar] a 50-value slot
# So [nextchar] is _%50, [flag] is _/50%2, [number] is _/100
# [flag] is 1 if we're in the middle of reading a number, 0 if we're between numbers
# It is also used for outputting as decimal (see below)
# Possible input characters are 0, 1, and newline, so [nextchar] is 48, 49, or 10

# Read the first character
N
# Loop while the character we just read is 0 or 1 and not newline
Count i while _/48 {
  # What we do in the loop depends on the combination of [flag] and [nextchar]:
  # 0,48 (start of number, read 0) => write minus sign, [flag] = 1, read another char
  # _,49 (read 1) => increment [number], [flag] = 1, read another char
  # 1,48 (middle of number, read 0) => write/clear [number], status = 0, read another
  #      char
  # 1,10 (middle of number, read <cr>) => ditto; the next read will be 0 for eof, which
  #      means the acc will be less than 48 and exit the loop

  # Process leading 0, if any
  Count n while 48/_ {
    # acc is 48: i.e. [number] is 0, [flag] is 0, [nextchar] is 48 (representing a 0)
    # Output minus sign
    Write 45
    # Set [flag] to 1 (thereby exiting loop) and read [nextchar]
    50+N
  }
  # If number starts with 1, then we didn't do the previous loop and [flag] is not set
  # In this case, acc is 49, so we add (50 if acc <= 49) to set [flag]
  _+49/_*50

  # Process a run of 1's
  Count u while _%50/49 {
    # [nextchar] is 49 (representing a 1)
    # Increment [number] and read another
    _+100-_%50+N
  }

  # At this stage, we know that we're at the end of a number, so write it as decimal
  # This is "easier" (ha) because the number has at most three digits
  # We shift our partitioning to [number][flag] and set [flag] to 0
  _/50-1

  # Output hundreds digit if nonzero
  # Since [number] is _/2, the hundreds digit is _/200
  Count h while _/200 {
    Write _/200+48
    # Mod 200 leaves only tens and units; also, set [flag] to 1
    _%200+1
  }
  # Output tens digit (_/20) if nonzero OR if there was a hundreds digit
  # In the latter case, [flag] is 1
  Count t while _/20+_%2 {
    Write _/20+48
    # Mod 20 leaves only units; clear [flag] if it was set
    _%20-_%2
  }
  # Write units unconditionally
  Write _/2+48

  # Write a tab for the separator
  Write 9
  # Read another character
  N
}


2

R 119 bajtów

function(x){n=nchar
y=regmatches(x,regexec("(0?)(1*)0?([01]*)",x))[[1]]
cat((-1)^n(y[2])*n(y[3]),"")
if(y[4]>0)f(y[4])}

Wypróbuj online!

Kod korzysta z tego rozwiązania z przepełnienia stosu do pokrewnego problemu (dzięki jeales za pomysł). Dane wyjściowe to łańcuch rozdzielany spacjami, drukowany na standardowym wyjściu.


2

Galaretka ,  19  18 bajtów

Musi być lepszy sposób ...

®ḢN$Ḣ©?ṄEȧ
ṣ0L€ÇL¿

Pełny program drukujący każdą liczbę, a następnie wysuw linii.

Wypróbuj online!

W jaki sposób?

®ḢN$Ḣ©?ṄEȧ - Link 1, print first number and yield next input: list of numbers, X
           -                              e.g. [8,0,15,16,...] or [0,4,8,0,15,16,...]
      ?    - if...
    Ḣ      - condition: yield head and modify  8([0,15,16,...])   0([4,8,0,15,16,...])  
     ©     -            (copy to register)     8                  0
®          - then: recall from the register    8
   $       - else: last two links as a monad:
 Ḣ         -         yield head and modify                        4([8,0,15,16,...])
  N                  negate                                      -4
       Ṅ   - print that and yield it           8                 -4
        E  - all equal (to get 0 to be truthy) 1                  1
         ȧ - AND the (modified) input          [0,15,16,...]      [8,0,15,16,...]
           -   (ready to be the input for the next call to this link)

ṣ0L€ÇL¿ - Main link: list e.g. [0,1,0,0,0,0,1,1]
ṣ0      - split at zeros       [[],[1],[],[],[],[1,1]
  L€    - length of €ach       [0,1,0,0,0,2]
      ¿ - while...
     L  - condition: length                           1  1  1  0  ([0,1,0,0,0,2], [0,0,0,2], [0,2], [])
    Ç   - action: call the last link (1) as a monad  -1  0 -2     ( - 1            - 0        - 2)

1

QBasic, 88 86 bajtów

1u$=INPUT$(1)
z=u$<"1
IF n*z THEN?(1-2*s)*(n-s):s=0:n=0ELSE s=s-z:n=n+1
IF"!"<u$GOTO 1

To było fajne. Wiele poprawek, począwszy od wersji 107-bajtowej, zaowocowało jednym z najbardziej zaciemnionych fragmentów QBasic, o których myślę, że kiedykolwiek napisałem.(Edycja: Co dziwne, byłem w stanie zagrać w golfa 2 bajty, czyniąc kod jaśniejszym.)

Uwaga: ten program odczytuje wprowadzane przez użytkownika po jednym znaku bez echa na ekranie (wynik użycia INPUT$(1)zamiast zwykłej INPUTinstrukcji). Podczas pisania nie zobaczysz jedynek i jedynek, ale liczby dziesiętne pojawią się w miarę ich obliczania. Pamiętaj, aby trafićEnter na końcu wejścia, aby zobaczyć ostatni numer i zakończyć program.

Wersja bez golfa

sign = 0
num = 0
DO
  digit$ = INPUT$(1)
  isZero = (digit$ < "1")
  IF num > 0 AND isZero THEN
    PRINT (1 - 2 * sign) * (num - sign)
    sign = 0
    num = 0
  ELSE
    IF isZero THEN sign = 1
    num = num + 1
  END IF
LOOP WHILE "!" < digit$

Wyjaśnienie

(AKA „Co? To wciąż nie ma sensu!”)

Podstawową strategią jest uruchomienie pętli, która za INPUT$(1)każdym razem chwyta jedną postać , robi z nią rzeczy i utrzymuje pętlę, dopóki postać ma wartość ASCII większą niż wartość! (tj. Nie była nową linią).

Śledzimy bieżące liczby za pomocą dwóch zmiennych. numto liczba znaków w bieżącej podpisanej liczbie jednoargumentowej (w tym dowolne początkowe zero). signjest, 1jeśli liczba miała wiodące zero, 0jeśli nie. Oba muszą zostać zainicjowane0 , co jest świetne dla wersji golfowej, ponieważ zmienne numeryczne w QBasic są automatycznie inicjowane 0.

Ilekroć czytamy postać, pierwszą rzeczą jest ustalenie, czy jest ona, 1czy też 0. Wykorzystamy ten wynik dwa razy, więc przechowujemy go isZero. Technicznie nazwa ta wprowadza w błąd, ponieważ wartość będzie również prawdziwa, jeśli postać będzie nową linią. Zauważ, że prawda w QBasic jest-1 i falsey jest0 .

Teraz, gdy jesteśmy w trakcie czytania liczby ( num > 0) i osiągamy zero lub koniec wejścia ( isZero), musimy obliczyć, którą liczbę już przeczytaliśmy.

  • signprzechowuje 0pozytywne, 1negatywne. Aby uzyskać 1pozytywne i -1negatywne, potrzebujemy 1-2*sign.
  • numprzechowuje poprawną jasność dla pozytywów, ale o jedną więcej niż jasność dla negatywów (ponieważ zawiera znacznik znaku). Możemy więc użyć num-signtej wielkości.

Pomnóż je razem i wydrukuj; następnie zresetuj signi numdo 0w ramach przygotowań do odczytania następnego numeru.

W przeciwnym razie (jeśli nie osiągnęliśmy zera lub jeśli osiągnęliśmy zero na początku liczby), aktualizujemy signi numpostępujemy następująco:

  • signstaje się, 1gdy patrzymy na wiodące zero; w przeciwnym razie, jeśli patrzymy na jednego, pozostaje on na tym, czym już był. Kod do gry w golfa jest s=s-ztaki sam:
    • Jeśli jest to zero wiodące, zto jest -1. Ponieważ sgwarantowane jest 0(ponieważ jest to początek nowego numeru), s-zbędzie1 .
    • Jeśli to jest jeden, zto jest 0. Następnie s-zpozostaje na dowolnej swcześniejszej wartości .
  • num jest zwiększany.

Otóż ​​to!


0

JavaScript (ES6), 60 bajtów

Zwraca rozdzieloną spacjami listę liczb całkowitych.

s=>(0+s).replace(/00?1*/g,s=>(l=s.length,+s[1]?l-1:2-l)+' ')

Przypadki testowe


0

Lua , 58 bajtów

(...):gsub("(0?)(1*)0?",function(s,n)print(#n-2*#s*#n)end)

Wypróbuj online!

Pełny program, pobiera dane z wiersza poleceń i wypisuje liczby na standardowe oddzielone nowymi liniami.

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.