Nani e monete


32

La situazione:

Diversi ( M) nani hanno trovato il forziere di un folletto con Nmonete d'oro e devono dividerle. A causa delle antiche regole che regolano l'assegnazione del bottino ai pirati in ordine di anzianità, il nano più anziano dovrebbe ottenere una moneta in più del prossimo nano più vecchio, e così via, in modo che il nano più giovane ottenga M-1meno monete del nano più vecchio. Inoltre, nessun nano deve lanciare alcuna moneta (cioè nessuna moneta negativa per nessun nano)

Aiuta i nani a dividere le monete in questo modo o dì loro che è impossibile.

Il codice del vincitore deve sempre rispondere correttamente (questa sfida è deterministica) e seguire le regole generali del .

Ingresso

Ti viene dato un numero intero N (3 ≤ N ≤ 1000) per il numero di monete e un numero intero M (3 ≤ M ≤ N) per il numero di nani, separati dallo spazio.

Produzione

Se è impossibile dividere le monete nel modo desiderato dai nani, stampa -1 (meno uno). Altrimenti, stampa il numero di monete che ogni nano riceverà, dal più vecchio al più giovane. Separare i numeri con spazi.

Campioni :

ingresso

3 3

produzione

2 1 0

ingresso

9 3

produzione

4 3 2

ingresso

7 3

produzione

-1

ingresso

6 4

produzione

3 2 1 0

4
Ti sei perso un "pirata".
Rawling


3
Buona scoperta, @Raystafarian. Forse quando l'insegnante ottiene un solutore generale per M nani anziché solo 3, riconoscerà che l'utente ha fatto il crowdsourcing della risposta :) - specialmente se quel risolutore è in J.
ProgrammerDan

Compiti a casa o no, è una buona domanda Puffo!
Level River St

Risposte:


18

J - 32 29 28 25

Non più corto di altra soluzione J, ma e usa un'idea diversa

(]{.[:i:-:@-.@]-%)/ ::_1:

La risposta per il numero di monete che ottiene lo gnomo di rango più alto è semplicemente N/M+(M-1)/2(se è un numero intero), costruiamo il negativo di questo -:@-.@]-%. Quindi i:crea un array come quello 2 1 0 _1 _2per argomento _2e prendiamo M elementi da esso.


1
+1 per un uso brillante di i:. Puoi salvare altri tre caratteri scrivendo %invece di [%], e usando -.@]invece di (1-]).
algoritmo

@algorithmshark Grazie amico appassionato J!
Swish

1
Non riesco a fare +1 come sembra @swish con gli gnomi che abbiamo appena derubato. ;)
TheConstructor il

11

J - 30 caratteri

Molto divertente da golf. Molte cose sono andate bene.

((+/@s~i.[){ ::_1:s=.+/&i.&-)/

Spiegazione:

  • /- Prendi gli interi separati da spazio come argomento e fai scivolare la funzione tra loro. Vale a dire, considera N l'argomento sinistro della funzione tra parentesi (...)e M l'argomento giusto.

  • i.&-- Negate ( -) e quindi accetta numeri interi ( i.). Normalmente, quando fai qualcosa come i.5te 0 1 2 3 4. Ogni volta che i.riceve un numero negativo, tuttavia, inverte l'elenco di output. Quindi ad esempio i._5darà 4 3 2 1 0.

  • s=.+/&- Eseguire l'azione sopra descritta su ciascun argomento ( &) e quindi creare una tabella di addizione ( +/) da questi array. Ora abbiamo una tabella in cui ogni riga è una possibile distribuzione di monete a M nani, anche se forse non quando ci sono N monete. Infine, questo verbo per la creazione di tabelle è così utile che lo chiameremo se lo useremo di nuovo in seguito.

  • +/@s~- Ora usiamo di snuovo, ma scambiamo ( ~) l'ordine degli argomenti, in modo da trasporre la tabella. Questo è un modo golfy di prendere la somma di ogni riga dopo aver creato la tabella ( +/@), avendo a che fare con il modo in cui J somma le liste multidimensionali.

  • i.[ - In questo elenco di somme, cerchiamo l'argomento sinistro del verbo, ovvero N. Se N è un elemento, otteniamo quell'indice: altrimenti otteniamo la lunghezza dell'elenco, che in particolare è un indice non valido.

  • { ::_1:- Ora proviamo a utilizzare l'indice per estrarre una riga dalla tabella s. {genererà un errore di dominio se l'indice non era valido, quindi in tal caso rileviamo l'errore ( ::) e restituiamo -1 ( _1:). Questo gestisce tutto. Poiché utilizziamo in i.&-precedenza, la distribuzione delle monete sarà in ordine decrescente, come richiesto.

Uso:

   ((+/@s~i.[){ ::_1:s=.+/&i.&-)/ 9 3
4 3 2
   ((+/@s~i.[){ ::_1:s=.+/&i.&-)/ 7 3
_1
   ((+/@s~i.[){ ::_1:s=.+/&i.&-)/ 6 4
3 2 1 0
   ((+/@s~i.[){ ::_1:s=.+/&i.&-)/ 204 17
20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4

L'input 9 3dovrebbe tornare 4 3 2, no -1. Sembra che ci sia una trasposizione nel tuo esempio di utilizzo?
Programmatore:

@ProgrammerDan Grazie, non l'ho capito. Ho sbagliato a scrivere gli esempi. 9 34 3 2e 7 3_1, come previsto.
algoritmo

Ho visto la correzione e fatto +1 in modo appropriato: D. Dovrei guardare in J, sembra elegante.
Programmatore:

7

R - 71 70 67 66 65 caratteri

s=scan();m=s[2];x=s[1]-sum(1:m);cat(if(x%%m|-m>x)-1 else x/m+m:1)

Ungolfed:

s = scan()    # Reads N and M by stdin.
m = s[2]
x = s[1] - m*(m-1)/2
cat(if (x %% m | x < -m) -1 else x/m + m:1)

Soluzione:

Se M il numero di nani, la sequenza di oro pagato può essere scomposta in due serie singolari. Prima una serie che termina con zero: M-1, ..., 2, 1, 0 e una serie costante di c, c, ..., c. La somma della prima serie è sempre M * (M-1) / 2. Quindi, se il resto (x = N - M * (M-1) / 2) può essere diviso senza resto (modulo uguale a 0), ogni nano ottiene x / M più la parte della serie decrescente.

Uso:

> s=scan()
1: 10 4
3: 
Read 2 items
> m=s[2]
> x = s[1] - m*(m-1)/2
> cat(if (x %% m || x<0) -1 else x/m + (m-1):0)
4 3 2 1

-1, la domanda richiede di scrivere un programma completo e non una funzione. Vedi meta.codegolf.stackexchange.com/a/1146/8766
user80551

@ user80551 Hai ragione. Ora ho corretto lo snippet: ora accetta l'input separato da spazio; anche l'output non mostra più '[1]'.
lambruscoAcido

1
Puoi salvare un altro personaggio sostituendolo m*(m+1)/2consum(1:m)
Brian Diggs

@Brian Thx, modificherò il mio codice!
lambruscoAcido

4

PHP (187)

È il mio primo tentativo di giocare a golf e so che potrebbe essere migliore, ma comunque :)

golfed:

<?php
$b=fgets(STDIN);list($c,$d)=explode(' ',$b);if((($d&1)AND($c%$d==0))OR($c%$d==$d/2)){for($e=floor($c/$d)+floor($d/2);$e>floor($c/$d)-round($d/2);$e--){echo"$e ";}}else{die('-1');}?>

Ungolfed:

<?php
$a = fgets(STDIN);
list($coins, $dwarves) = explode(' ', $a);
if ((($dwarves & 1) AND ($coins % $dwarves == 0)) OR ($coins % $dwarves == $dwarves / 2)) {
    for (
        $i = floor($coins / $dwarves) + floor($dwarves / 2);
        $i > floor($coins / $dwarves) - round($dwarves / 2);
        $i--
    ) {
        echo "$i ";
    }
}
else { 
  die('-1');
}
?>

Eseguire in una shell

Idea base:

Le monete possono essere separate da queste regole, se una di queste è vera:

  1. I nani sono un numero dispari e le monete sono divisibili per i nani senza resti
  2. I nani sono numeri pari e le monete rimanenti dopo aver diviso le monete / i nani sono pari alla metà del numero dei nani

In tal caso, prendiamo come base le monete medie per nano (ACPD). Ma dobbiamo partire dal più alto e produrre fino a raggiungere il più basso. Quindi facciamo un ciclo con contatore a partire da ACPD + il conteggio del resto dei nani verso l'estremità superiore e proseguiamo fino a raggiungere l'ACPD - il conteggio del resto dei nani verso l'estremità inferiore.

È fondamentalmente lo stesso se i nani sono strani (cioè 5 nani - quello centrale è 3, e in entrambe le estremità rimangono 2), ma non se sono pari - motivo per cui ci affidiamo al pavimento e al giro.

Problemi finora: funziona con un numero di monete troppo basso, il che significa che alcuni nani saranno abbattuti e derubati dei loro preziosi guadagni. E questo è triste. O almeno se ti piacciono i nani.

Soluzione :

  1. Pensa a un modo per calcolare la quantità più bassa di monete in modo che il calcolo non finisca con i nani nella polvere.
  2. Progetta nani non così avidi.

Soluzione più intelligente :

Le monete sono in metallo. Fai sciogliere tutti i nani e poi gettali in quantità sempre più piccole di monete, in modo che siano divisibili in ogni caso.

La soluzione più intelligente :

Ruba la loro montagna, rinomina te stesso in Smaug e tienilo tutto per te. Dopotutto, perché devi preoccuparti dei nani scontrosi?


4

Python 3 (100)

Usando la stessa idea di @Geobits ma conforme ai requisiti di input e output.

n,m=map(int,input().split())
κ,ρ=divmod(n-m*(m-1)//2,m)
x=[-1]if ρ else range(κ,κ+m)[::-1]
print(*x)

Grazie per il testa a testa. Non ho notato la separazione dello spazio aggiunta alle richieste di input.
Geobits

Possono essere 100 caratteri, ma a causa dei nomi delle variabili greche, sono necessari 105 byte.
Jonathan Frech,

4

Python 3 - 109 107 103 102 90 93

Usando la stessa idea di Evpok, ma con una serie di miglioramenti.

n,m=map(int,input().split())
k=n/m+m/2
a=int(k)
print(*(range(a,a-m,-1),[-1])[k-a-.5or~a>-m])

I miglioramenti sono:

  1. Eliminare lo spazio dopo l'altro e prima ''. 1 personaggio
  2. Eliminare "" all'interno di split (), perché la divisione negli spazi è un valore predefinito. 3 personaggi
  3. Abbassando x di 1 modificando da -1 a +1 all'interno del divmod, quindi cambiando la funzione di intervallo per utilizzare l'opzione di ordine inverso dell'intervallo. 3 personaggi.
  4. MODIFICA: ... se ... altro ... modificato in ... e ... o ... 2 caratteri.
  5. EDIT: Divmod reso esplicito, r rimosso. 4 caratteri.
  6. EDIT: x rimosso, m // n usato esplicitamente. 1 personaggio
  7. EDIT: usato espressioni speciali invece di '' .join (map (str, ...)), aggiunto x per evitare di ripetere print (). 12 caratteri.
  8. EDIT: Mi sono reso conto che stavo permettendo ai Nani di consegnare un numero negativo di monete. Ho cambiato il codice per evitarlo.

Ben fatto, è stato istruttivo :) Ho cambiato la mia risposta per eliminare lo spazio non necessario, ma il tuo trucco per salvare [::-1]è migliore della mia soluzione. +1
Evpok

Forse mi manca qualcosa, ma ho contato 93 byte anziché 94.
Jonathan Frech,

3

Python 3 - 114

n,m=map(int,input().split(' '))
r=range(m);n-=sum(r)
if n%m<1:
 for x in r:print(m-x+n//m-1,end=' ')
else:print -1

Funziona controllando se N-(M*(M-1)/2)è uniformemente divisibile per M. Nuovo per Python, quindi ogni consiglio è apprezzato.

Esempio Ideone.com

Input:
735 30
Output:
39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10

Esiste mai una versione di Python 3 che supporta lo printstile di istruzione di Python 2 ? O in che modo l'ultima riga ( else:print -1) non provoca un errore?
Jonathan Frech,

3

C # - 322

using System;using System.Linq;namespace D{class P{static void Main(string[]args){int n=Convert.ToInt16(args[0]);int m=Convert.ToInt16(args[1]);bool b=false;int q=n/2+1;g:b=!b;int[]z=new int[m];for(int i=0;i<m;i++){z[i]=q-i;}if(z.Sum()==n)foreach(int p in z)Console.Write(p+" ");else{q--;if(b)goto g;Console.Write(-1);}}}}

Punteggio orribile ma ho adottato un approccio diverso e ho dovuto usare goto:)

Lo accorcerò più tardi.


1
Puoi sicuramente abbreviare tutte quelle Convert.ToInt16chiamate a just int.Parse. Puoi dichiarare qualsiasi variabile pre-assegnata con var(invece di es int[].). Non è necessario chiamare i parametri della riga di comando args. E puoi alias tipi usati di frequente come using C = Console. Penso anche che per una soluzione così lunga, è meglio presentare con interlinea piuttosto che salvare solo un paio di caratteri. Oh, e non sono davvero sicuro del perché qui gotosia meglio delle alternative ...
Aaronaught,

3

Java 210

class A { public static void main(String[] a){int d=Integer.parseInt(a[0]),c=Integer.parseInt(a[1]);if (2*c%d==0) for (int i=0;i<d;i++) System.out.print((((1+(2*c/d)-d)/2)+i)+" "); else System.out.print(-1);}}

2
Benvenuto in PPCG, vedo che hai molti spazi bianchi che possono essere rimossi.
user12205

Puoi spogliare molti più spazi per golfare ulteriormente la tua risposta, ad esempio class A{public static void main(String[]a)è valida e ti fa risparmiare 3 caratteri. Dopo ciascuna ife intorno a ciascuna for, rimuovi gli spazi bianchi ... ecc.
Programmatore:

È assurdo che la parte "vuoto statico pubblico principale (S" sia lunga quanto l'intera soluzione J :)
Robert Grant,

3

R: 77 73 70 caratteri

a=scan();r=a[2]:1-1;while((n=sum(r))<a[1])r=r+1;cat(`if`(n>a[1],-1,r))

Crea un vettore che va da (M-1) a 0 e aggiunge 1 a ciascun numero fino a quando la somma non è più inferiore a N. Se è superiore, l'output -1 altrimenti produce l'output del vettore.

Frastagliato e leggermente non golfato:

a=scan()   #Reads in stdin (by default numeric, space-separated)
r=a[2]:1-1 #Creates vector (M-1) to 0
while(sum(r)<a[1])r=r+1 #Increments all member of vector by 1 until sum is not inferior to N
cat( #Outputs to stdout
    `if`(sum(r)>a[1], -1, r) #If superior to N: impossible, returns -1
    )

Esempio di utilizzo:

> a=scan();r=a[2]:1-1;while((n=sum(r))<a[1])r=r+1;cat(`if`(n>a[1],-1,r))
1: 9 3
3: 
Read 2 items
4 3 2
> a=scan();r=a[2]:1-1;while((n=sum(r))<a[1])r=r+1;cat(`if`(n>a[1],-1,r))
1: 7 3
3: 
Read 2 items
-1
> a=scan();r=a[2]:1-1;while((n=sum(r))<a[1])r=r+1;cat(`if`(n>a[1],-1,r))
1: 204 17
3: 
Read 2 items
20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4

2

Julia, 45 anni

f(n,m)=(x=n/m-m/2+1/2;x%1==0?[x+m-1:-1:x]:-1)
julia> f(6,4)'
1x4 Array{Float64,2}:
 3.0  2.0  1.0  0.0

Solo un po 'di algebra, mi ha portato molto più tempo di quanto avrebbe dovuto.


2

JavaScript - 76

Osservare che k + (k - 1) + ... + (k - (M - 1)) = M (k - (M - 1) / 2) Impostando questo uguale a N si ottiene k = N / M + (M -1) / 2 per l'importo più elevato. Se questo è intero, allora k% 1 == 0 e gli importi che stiamo cercando sono k, k - 1, ..., k - (M - 1).

Probabilmente avrei potuto scrivere questo breve in un'altra lingua, ma non c'era ancora una soluzione JS, quindi eccola qui:

N=3;M=3;if((r=N/M+(M-1)/2)%1)console.log(-1);else while(M--)console.log(r--)

Esegui nella console.

Esempio di input:

N=3;M=3;if((r=N/M+(M-1)/2)%1)console.log(-1);else while(M--)console.log(r--)

Produzione:

3
2
1 

Ingresso:

N=6;M=4;if((r=N/M+(M-1)/2)%1)console.log(-1);else while(M--)console.log(r--)

Produzione:

3
2
1
0

Ingresso:

N=7;M=3;if((r=N/M+(M-1)/2)%1)console.log(-1);else while(M--)console.log(r--)

Uscita: -1

Peccato che console.log sia così lungo da pronunciare :) Purtroppo dichiarare l=console.log.bind(console)non lo rende più corto, e semplicemente l=console.lognon funziona.

Ingresso:

"N=3;M=3;if((r=N/M+(M-1)/2)%1)console.log(-1);else while(M--)console.log(r--)".length

Produzione:

76

Puoi usarlo c=consolee c.log()accorciarlo.
user2428118

2

Golfscript, 35

~:M.(*2/-.M%{;-1}{M/M+,-1%M<' '*}if

Come funziona

Nel seguente esempio, l'input è 9 3.

          # STACK: "9 3"
~         # Interpret the input string.
          # STACK: 9 3
:M        # Store the top of the stack (number of dwarves) in variable `M'.
.         # Duplicate the top of the stack.
          # STACK: 9 3 3
(         # Decrement the top of the stack.
          # STACK: 9 3 2
*         # Multiply the topmost elements of the stack.
          # STACK: 9 6
2/        # Divide the top of the stack by `2'.
          # STACK: 9 3
          # So far, we've transformed `M' into `M*(M-1)/2', which is the minimum amount of
          # coins all dwarves together will get. This number comes from the fact that the
          # youngest dwarf will get at least 0 coins, the next at least 1 coin, etc., and
          # 0 + 1 + ... + (M - 1) = M*(M-1)/2.
-         # Subtract the topmost elements of the stack.
          # STACK: 6
          # The remaining coins have to get reparted evenly to all dwarves.
.         # Duplicate the top of the stack.
          # STACK: 6 6
M%        # Calculate the top of the stack modulus `M'.
          # STACK: 6 0
{         # If the modulus is positive, the remaining coins cannot get reparted evenly.
    ;-1   # Replace the top of the stack by `-1'.
}
{         # If the modulus is zero, the remaining coins can get reparted evenly.
    M/    # Divide the top of the stack by `M'.
          # STACK: 2
          # This is the number of coins all dwarves will get after giving 1 to the second
          # youngest, etc.
    M+    # Add `M' to the top of the stack.
          # STACK: 5
    ,     # Replace the top of the stack by an array of that many elements.
          # STACK: [ 0 1 2 3 4 ]
          # The rightmost element is the number of coins the oldest dwarf will get.
    -1%   # Reverse the array.
          # STACK: [ 4 3 2 1 0 ]
    M<    # Keep the leftmost `M' elements.
          # STACK: [ 4 3 2 ]
          # There are only `M' dwarves.
    ' '*  # Join the array, separating by spaces.
          # STACK: "4 3 2"
}if

1

Delphi XE3 (176)

uses SysUtils;var d,c,i:integer;begin read(c,d);for I:=1to d-1do c:=c-i;if c mod d>0then writeln(-1)else begin c:=c div d;for I:=d-1downto 0do write(IntToStr(i+c)+' ');end;end.

Come funziona.

Legge 2 numeri interi, monete e nani.
Sottrae la differenza per nano.
Se il resto mod nana> 0 è impossibile.
Altrimenti ottiene la stessa quota per nano in un ciclo di nani da 1 a 0 e stampa nanoIndex + uguale condivisione

Ungolfed

uses SysUtils;
var
  d,c,i:integer;
begin
  read(c,d);
  for I:=1to d-1do
    c:=c-i;
  if c mod d>0then
    writeln(-1)
  else
  begin
    c:=c div d;
    for I:=d-1downto 0do
      write(IntToStr(i+c)+' ');
  end;
end.

1

Mathematica 65

La funzione, ggenera tutte le sequenze crescenti di una, di lunghezza m, da 0 a n e controlla se ognuna di esse somma a m. In caso di successo, la sequenza viene restituita; in caso contrario, viene restituito -1.

Le sequenze sono fatte da Partition ingingando la lista {0,1,2,3… m} in tutte le possibili liste secondarie di n numeri interi contigui.

Esistono, ovviamente, modi più efficienti per ottenere lo stesso effetto, ma quelli che ho trovato richiedono più codice.

n_~g~m_:=If[(s=Select[Partition[0~Range~n,m,1],Tr@#==n&])=={},-1,s]

Esempi

g[9, 3]

{{2, 3, 4}}


g[3, 3]

{{0, 1, 2}}


g[7, 3]

-1


g[705, 3]

{{234, 235, 236}}


g[840, 16]

{{45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60}}


g[839, 16]

-1


1

C 131

#include <edk.h>
main(int a,char **v){int j=atoi(*++v),k=atoi(*++v)-j*(j-1)/2;k<0||k%j?j=1,k=-1:k/=j;while(j--)printf("%d ",k+j);}

Ungolfed

#include <edk.h> //Shortest standard header including stdio.h and stdlib.h
main(int a,char **v)
{
    int j=atoi(*++v),k=atoi(*++v)-j*(j-1)/2;

    k<0||k%j?j=1,k=-1:k/=j;  // If youngest dwarf gets < 0 or amount not equally divisible then set values such that ...

    while(j--)printf("%d ",k+j); // ... loop prints out correct values
}

Questo viene compilato con un avviso perché main non ha tipo. Se questo non è valido nelle regole del golf, dovrei aggiungere cinque caratteri.


1

Cobra - 198

Sito Web Cobra

class P
    def main
        x,y=Console.readLine.split
        a,b=x to int,y to int
        l=[]
        t=n=0
        for i in b,t+=i
        while (t+=b)<=a,n+=1
        for i in b,l.insert(0,i+n)
        print if(t-b<>a,-1,l.join(" "))

Ha spiegato:

class P
    def main

Richiesto per l'esecuzione del codice

        x,y=Console.readLine.split
        a,b=x to int,y to int

Prende input e lo memorizza come aeb

        l=[]
        t=n=0

Inizializza l'elenco di output le inizializza il denaro totale richiesto te il numero di monete da aggiungere a ciascuna pila di nanin

        for i in b,t+=i

Trova il valore monetario più basso possibile che farà sì che tutti i nani abbiano un numero consentito di monete nella loro pila

        while (t+=b)<=a,n+=1

Determina quante monete aggiungere a ciascuna pila in modo che il denaro totale richiesto sia> = al totale denaro disponibile

        for i in b,l.insert(0,i+n)

Riempie l'elenco con pile di denaro di dimensioni diverse

        print if(t-b<>a,-1,l.join(" "))

Output -1o a lseconda che il denaro totale richiesto sia uguale al totale denaro disponibile



-1

Python ( 100 96 94):

Una bella risposta a punteggio pieno. Non più, ma ora è più breve.

def f(n,m):a=range(m)[::-1];b=n-sum(a);c=b/m;d=[i+c for i in a];return(d,-1)[-1in d or c*m!=b]

Ungolfed:

def f(n,m):
 a = range(m)[::-1]
 b = sum(a)
 c = (n-b)/m
 if c * m != n-b: return -1
 d = [i+c for i in a]
 return (d,-1)[-1 in d or c!=n-b]
 if -d in d or c*m!=n-b:
  return -1
 return d

Produzione:

def f(n,m):a=range(m)[::-1];b=sum(a);c=(n-b)/m;d=[i+c for i in a];return (d,-1)[-1 in d or c*m!=n-b]

f(3,3)
Out[2]: [2, 1, 0]

f(9,3)
Out[3]: [4, 3, 2]

f(7,3)
Out[4]: -1

f(6,4)
Out[5]: [3, 2, 1, 0]

2
Questo non segue i requisiti di input.
Austin Henley,

-1, la domanda richiede di scrivere un programma completo e non una funzione. Vedi meta.codegolf.stackexchange.com/a/1146/8766
user80551
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.