Können Sie Golf spielen?


53

Sie müssen einen zufälligen 18-Loch-Golfplatz erstellen.

Beispielausgabe:

[3 4 3 5 5 4 4 4 5 3 3 4 4 3 4 5 5 4]

Regeln:

  • Ihr Programm muss eine Liste mit Lochlängen für genau 18 Löcher ausgeben
  • Jedes Loch muss eine Länge von 3, 4 oder 5 haben
  • Die Lochlängen müssen für den gesamten Platz 72 betragen
  • Ihr Programm muss in der Lage sein, jede mögliche Lochkonfiguration mit einer Wahrscheinlichkeit ungleich Null zu erstellen (die Wahrscheinlichkeiten jeder Konfiguration müssen nicht gleich sein, in diesem Fall können Sie jedoch zusätzliche Anerkennung einfordern).

3
Bitte bestätigen Sie, 44152809 Lösungen?
Baby-Kaninchen

1
Auch ich bin gespannt auf die genaue Anzahl der Lösungen, aber ich denke, es sollte mehr als 44 Millionen sein ... (Ich bin kein Mathematiker, aber: | 1 (5) / 1 (3) = 306 Möglichkeiten (17 * 18) | 2 (5) / 2 (3) = 69360 Poss (17 * 17 * 16 * 15) | 3 (5) / 3 (3) = 11182080 Poss (16 * 16 * 16 * 15 * 14 * 13) | das sieht richtig aus?
NRGdallas

11
@ Baby-Kaninchen: Ich kann 44.152.809 Lösungen durch Brute-Force-Aufzählung bestätigen. Auch kann es direkt auf diese Weise berechnet werden: da die durchschnittlichen genau ist 4, und die einzigen Möglichkeiten sind 3, 4oder 5die möglichen Lösungsklassen { no 3's or 5's, one 3 and one 5, two 3's and two 5's, ..., nine 3's and nine 5's}. Dies kann mit berechnet werden nCr(18,0)*nCr(18,0) + nCr(18,1)*nCr(17,1) + nCr(18,2)*nCr(16,2) + ... + nCr(18,9)*nCr(9,9) = 44,152,809. Dies bedeutet, dass ungefähr 11.4%alle möglichen Kombinationen gültige Lösungen sind (44,152,809 / 3^18).
Mellamokb

2
sum(factorial(18)/factorial(x)/factorial(y)/factorial(z) for x in range(25) for y in range(25) for z in range(25) if 3*x+4*y+5*z == 72 and x+y+z == 18)gibt44152809L
Sanjeev Murty

Antworten:


29

k ( 18 17 16 Zeichen)

Zurück zum ursprünglichen Ansatz, Dank an CS für die Verbesserung.

(+/4-){3+18?3}/0

Anderer Ansatz (17 Zeichen), gleiche Methode wie die J-Lösung, H / T zu CS

4+a,-a:9?2 -18?18

Alte Version:

(72-+/){18?3+!3}/0

Nicht anfällig für Stapelüberlauf und wird auf festem Platz ausgeführt.


Was ist H / T zu CS?
Gareth


Dieses Programm hat mir geholfen, einen Fehler in meinem K-Interpreter zu entdecken - danke! Bisher war mir nicht klar, dass Nilads auf ein einzelnes Argument angewendet werden können (das sie ignorieren).
JohnE


15

J, 20 18 17 Zeichen

(?~18){4+(,-)?9#2

Dies funktioniert genauso wie die vorherige Antwort, außer dass die 9 zufälligen Ziffern entweder 0 oder 1 sind und vor dem Anhängen negiert werden. Das heißt, es gibt so viele -1s wie es 1s gibt. Durch Hinzufügen von 4 erhalte ich eine Liste mit 3s, 4s und 5s, die jedes Mal 72 ergeben.

Vorherige Antwort:

({~?~@#)3+(,2-])?9#3

Erzeugt die ersten 9 Löcher nach dem Zufallsprinzip ?9#3, kopiert und invertiert sie (,2-])(wandelt eine 3 in eine 5 und eine 5 in eine 3 um), um die endgültige 9 zu erzeugen. Dies garantiert, dass die Gesamtsumme 72 beträgt (da jede 3 eine übereinstimmende 5 hat) Die durchschnittliche Gesamtsumme pro Loch beträgt 4 und 4x18 = 72). Das Ergebnis wird dann zufällig gemischt, ({~?~@#)um sicherzustellen, dass jede Kombination möglich ist.


Tatsächlich werden Sie {3,5,4,4,4 ...} nicht generieren. Sie sind besser dran, das gesamte Ergebnis zu mischen
Ratschenfreak

@ Rachetfreak Guter Punkt. Ich werde jetzt bearbeiten.
Gareth

13

16-Bit-x86-Computercode unter MS-DOS - 45 Byte

Hexdump:

0E5F576A12595188ECE44088C3E44130D8240374F400C4AAE2EF595E80FC2475DFAC0432CD29B020CD29E2F5C3

Base64-codierte Binärdatei:

Dl9XahJZUYjs5ECIw+RBMNgkA3T0AMSq4u9ZXoD8JHXfrAQyzSmwIM0p4vXD

Tatsächlicher Quellcode mit einigen Kommentaren:

 bits 16
 org 0x100

again:
 push cs               ; Save whatever CS we get.
 pop di                ; Use CS:DI as our course buffer..
 push di               ; Save for later use in the print loop
 push 18               ; We need 18 holes for our golf course.
 pop cx                ; ch = 0, cl = 18.
 push cx               ; Save for later use.
 mov ah, ch            ; Zero out ah.
generate_course:
 in al, 0x40           ; Port 0x40 is the 8253 PIT Counter 0.
 mov bl, al            ; Save the first "random" value in bl.
 in al, 0x41           ; Port 0x41 is the 8253 PIT Counter 1.
 xor al, bl            ; Add some more pseudo randomness.
 and al, 3             ; We only need the two lower bits.
 jz generate_course    ; If zero, re-generate a value, since we need only 3, 4, 5 holes.
 add ah, al            ; Sum in ah register.
 stosb                 ; Store in the course buffer.
 loop generate_course  ; Loop for 18 holes.
 pop cx                ; cx = 18.
 pop si                ; si = course buffer.
 cmp ah, 36            ; 72 holes?
 jne again             ; No, re-generate the whole course.

print:                 ; Yup, we have a nice course.
 lodsb                 ; Load the next hole.
 add al, '2'           ; Add ASCII '2' to get '3', '4' or '5'
 int 0x29              ; Undocumented MS-DOS print function.
 mov al, ' '           ; Print a space too for better readability.
 int 0x29              ; Print the character.
 loop print            ; Print the whole course.
 ret                   ; Return to the beginning of the PSP where a INT 0x20 happen to be.

Kompilieren Sie mit nasm 18h.asm -o 18h.comund führen Sie es unter MS-DOS (oder Dosbox) oder NTVDM von einer 32-Bit-Windows-Version aus.

Beispielausgabe:

4 5 4 5 4 5 3 4 3 4 3 4 4 5 4 3 5 3

3
Liebe Assembler ...
Woliveirajr

13

Mathematica 71 68 66 60

Mit 6 Zeichen nach Tallys Vorschlag gespeichert.

RandomSample@RandomChoice@IntegerPartitions[72, {18}, {3, 4, 5}]

{5, 4, 3, 3, 5, 3, 5, 5, 3, 3, 4, 5, 3, 5, 4, 4, 5, 3}

Alle möglichen Ergebnisse sind möglich, aber sie sind nicht gleich wahrscheinlich.


Analyse

IntegerPartitions[72, {18}, {3, 4, 5}]

Erzeugt alle 10 möglichen Partitionen (Kombinationen, keine Permutationen) von 72 in 18 Elemente, die aus 3, 4 und 5 bestehen.

Partitionen


RandomChoice wählt eine davon aus.

RandomSample gibt eine Permutation dieser Wahl zurück.


Hehe, ich wollte gerade fast die gleiche Antwort posten, nur mit RandomChoice anstelle von RandomInteger. Ich denke, Sie können sich auf diese Weise 4 weitere Charaktere rasieren.
Tally

Tally, danke. Ihr Vorschlag war hilfreich.
DavidC

8

R - 41

x=0;while(sum(x)!=72)x=sample(3:5,18,T);x

# [1] 5 3 5 3 3 3 3 3 5 4 5 4 5 4 4 5 5 3

Der Algorithmus ähnelt dem von @ sgrieve.


Dasselbe Problem wie bei @sgrieve oben - nichts hindert es daran, in 18 Löchern vorbeizugehen.
gt6989b

3
Das ist kein Problem, der Beispielbefehl generiert in diesem Fall immer 18 Werte.
sgrieve

8

GolfScript (26 Zeichen)

{;0{3rand.3+@@+(}18*])}do`

Es gibt einige offensichtliche Ähnlichkeiten mit der Lösung von Ilmari, aber auch einige offensichtliche Unterschiede. Insbesondere nutze ich die Tatsache, dass das durchschnittliche Par 4 ist.


Verdammt, aber das ist sicher ein kluger Trick mit der Schleifenbedingung. Ich habe {;0{3.rand+.@+}18*])72-}domir etwas ausgedacht, konnte aber nicht herausfinden, wie ich es von dort aus kürzer machen kann. +1.
Ilmari Karonen

7

Python 77

Code

from numpy.random import*;l=[]
while sum(l)!=72:l=randint(3,6,18)
print l

Ausgabe

[3 4 4 5 3 3 3 5 4 4 5 4 5 3 4 4 5 4]

Der Import macht diese Lösung wirklich kaputt. Mit numpy werden 18 Zahlen zwischen 3 und 5 generiert, und Listen werden so lange generiert, bis die Summe der Listen 72 ergibt.


Was hindert das Programm daran, 72 zu erreichen, bevor es 18 Löcher erzeugt? Was hindert es daran, 72 zu überspringen?
DavidC

3
Der Code generiert immer 18 Löcher und prüft dann, ob die Summe gleich 72 ist. Wenn die Summe nach 16 Löchern beispielsweise 72 ist, generiert er immer noch zwei weitere Löcher, indem er die Summe über 72 schiebt und den Test nicht besteht.
sgrieve

7

GolfScript, 27 Zeichen

{;18{3.rand+}*].{+}*72-}do`

Verwendet die gleiche Ablehnungsmethode wie die Python-Lösung von sgrieve. Somit ist jede gültige Ausgabe tatsächlich gleich wahrscheinlich.


7

Q (25 Zeichen)

Original (27)

while[72<>sum a:18?3 4 5];a

Beispielausgabe

4 4 3 3 4 5 4 3 4 5 5 3 5 5 5 4 3 3

Etwas kürzer (25)

{72<>sum x}{x:18?3 4 5}/0

7

JavaScript, 66 64 61 Zeichen

Stark inspiriert von TwoScoopsofPig (PHP) und Joe Tuskan (JS).

for(a=[s=0];s!=72;)for(s=i=0;i<18;s+=a[i++]=Math.random()*3+3|0);a

for(a=[s=0];s-72;)for(s=i=0;i<18;s+=a[i++]=Math.random()*3+3|0)a

for(a=s=[];s;)for(i=18,s=72;i;s-=a[--i]=Math.random()*3+3|0)a

2
s!=72kann sein s-72, ein Zeichen zu sparen. Und das letzte Semikolon ;awird auch nicht für einen anderen Buchstaben benötigt.
Joe Tuskan

Ich habe noch nie for(i=x;i;i--)zuvor gesehen, dass es 2 Zeichen spart for(i=0;i<x;i++), danke Mann!
Math Chiller

7

Python 2, 70 Bytes

from random import*
print sample(([3,5]*randint(0,9)+[4]*99)[:18],18)
bearbeiten:

Hier ist eine andere, ähnlich der Lösung von sgrieve:

Python 2, 73 Bytes + gleiche Wahrscheinlichkeit

from random import*
a=[]
while sum(a)-72:a=sample([3,4,5]*18,18)
print a

5

JavaScript, 116 99 65 Bytes

for(i=0,h=[];i<18;)h[i++]=5;while(h.reduce(function(a,b){return a+b})!=72){i=Math.random()*18|0;h[i]=[3,4,4][i%3]}h;

h=[0];while(h.reduce(function(a,b){return a+b})-72)for(i=0;i<18;h[i++]=[3,4,5][Math.random()*3|0])h

while(i%18||(a=[i=s=0]),s+=a[i++]=Math.random()*3+3|0,s-72|i-18)a

1
Wenn ich das in Chrome 21 starte, bekomme ich i is not defined.
Mellamokb

5

Python, 128 120 116 Zeichen

import random,itertools
random.choice([g for g in itertools.product(*(range(3,6)for l in range(18))) if sum(g)==72])

import Anweisungen sind immer noch Längenkiller (nur 23 Zeichen, um 2 Funktionen in den Namespace zu importieren)

Ich hoffe, dass Sie das Ergebnis in naher Zukunft nicht benötigen, da dieser Code zunächst alle möglichen Lösungen bewertet, bevor er eine zufällig auswählt. Vielleicht die langsamste Lösung für dieses Problem.

Ich fordere zusätzliches Lob für die gleiche Wahrscheinlichkeit jeder Konfiguration ...


4
import random,itertools
Grawity

Sie haben Recht, dass die Dinge ein bisschen verkürzen.
Adrien Plisson

Andere Tipps: import random as r,itertools as iVerwenden Sie dann rund ianstelle von randomund itertools. Verwenden Sie 18*[0]anstelle von range(18)und [3,4,5,6]anstelle von range(3,6):)
Alex L

ich benutze python 3: ein listenverständnis ist ein generator und hat keine länge, was seine verwendung mit der choice()funktion verbietet . das ist auch der Grund, warum dieser Code so langsam ist ...
Adrien Plisson

1
ooops, sorry, ich habe das Listenverständnis und den Generatorausdruck durcheinander gebracht (im Allgemeinen vermeide ich das Listenverständnis zugunsten des Generatorausdrucks, weil der Iterator eine bessere Leistung bringt). Selbst in Python3 kann ich noch einige Zeichen entfernen ... @Alex hat es richtig gemacht.
Adrien Plisson

4

PHP - 77 Zeichen

<?while(array_sum($a)!=72){for($i=0;18>$i;){$a[++$i]=rand(3,5);}}print_r($a);

Ähnlich wie bei der Lösung von sgrieve wird eine Liste mit 18 Löchern erstellt, das gesamte Par überprüft und entweder gedruckt oder abgelehnt und ein neuer Versuch unternommen. Seltsamerweise sind unsere beiden Lösungen gleich lang.

Eher ärgerlich ist, dass PHP keine Array-Funktionen mit einer kurzen Bezeichnung anbietet. Array_sum und print_r bringen mich um. Vorschläge sind willkommen.


1
Geschweifte Klammern werden hier nicht benötigt, und die Summe kann es sein +=. <?while($s!=72)for($s=$i=0;18>$i;$s+=$a[++$i]=rand(3,5));print_r($a);
Grawity

Das ist nützlich - ich hätte nie gedacht, die Logik in den for-Schleifenaufruf zu setzen (und ich fühle mich irgendwie dumm dafür, keinen Zähler für die Summe zu erhöhen).
TwoScoopsofPig

Danke - aber das ist eigentlich nicht das, was ich mit "nicht benötigten geschweiften Klammern" gemeint habe; Sie hätten sie auch im Originalcode entfernen können:while(array_sum($a)!=72)for($i=0;18>$i;)$a[++$i]=rand(3,5);
grawity

Nun, außer ich laufe gegen eine strengere php.ini als diese, weil ich auf der Arbeit Golf spiele. es klagt kein Ende über fehlende / nicht übereinstimmende Klammern. Normalerweise hätte ich.
TwoScoopsofPig

Das ist seltsam; 5.4.7 mit E_ALL | E_STRICT beschwert sich nie über fehlende {}(da die PHP-Syntax dies ausdrücklich zulässt).
Grawity

4

Ruby 1.9 (62 Zeichen)

a=Array.new(18){[3,4,5].sample}until(a||[]).inject(:+)==72
p a

Schienen (55 Zeichen)

In der $ rails cREPL (in einem beliebigen Rails-Ordner):

a=Array.new(18){[3,4,5].sample}until(a||[]).sum==72
p a

Hinweis: Es funktioniert mit Ruby 1.8, wenn Sie shuffle[0]statt verwenden sample.


2
Benötigen Sie Leerzeichen, bis?
Kaz

@ Kaz Du hast recht, es wird nicht benötigt. :) 62 Zeichen jetzt.
js-coder

1
Sie können verwenden (1..18).map{rand(3)+3}, um das zufällige Array zu erhalten;)
Epidemie

4

Lisp ( 78 69 Zeichen)

(do ((c () (mapcar (lambda (x) (+ 3 (zufällig 3))) (make-list 18))) ((= (apply '+ c) 72) c))

(do((c()(loop repeat 18 collect(+ 3(random 3)))))((=(apply'+ c)72)c))

Es ist der Python-Lösung von sgrieve ziemlich ähnlich.

Beginnen Sie mit c als NIL, prüfen Sie auf eine Summe von 72, die do"Inkrementierungsfunktion" für c erzeugt eine Liste von 18 Zahlen zwischen 3 und 5, prüfen Sie erneut auf 72, schäumen Sie auf, spülen Sie ab, wiederholen Sie.

Es ist erfrischend, zusammen Golf zu sehen dound loopschön zu spielen.


3

C (123 Zeichen) - Effizienzbemühungen

Pipe durch wc und es werden alle 44152809 Lösungen innerhalb von 10 Sekunden generiert ...

char s[19];g(d,t){int i;if(d--){for(i=51,t-=3;i<54;i++,t--)if(t>=3*d&&t<=5*d)s[d]=i,g(d,t);}else puts(s);}main(){g(18,72);}

Oh, nun - habe die Frage nicht richtig gelesen - aber da wir alle Lösungen generieren, ist es eine Scripting-Übung, eine zufällige mit gleicher Wahrscheinlichkeit auszuwählen: P


3

Clojure - 55

(shuffle(mapcat #([[4 4][3 5]%](rand-int 2))(range 9)))

Ein ganz lustiger Trick ... nutzt die mathematische Struktur des Problems aus, dass es genau so viele 3 Par-Löcher wie 5 Par-Löcher geben muss.


3

Python 83

import random as r;x=[]
while sum(x)!=72:x=[r.randint(3,5) for i in 18*[0]]
print x

Wie die Lösung von sgrieve, aber ohne Dummheit

Golf Adrien Plissons Lösung: 120-> 108 Zeichen

import random as r,itertools as i
r.choice([g for g in i.product(*([3,4,5,6]for l in 18*[0]))if sum(g)==72])

MATLAB 53

x=[];
while sum(x)~=72
x=3+floor(rand(1,18)*3);
end
x

Ausgabe :

x = 4 3 4 4 4 4 5 4 4 3 4 4 3 5 3 5 4 5


Nizza Ansatz, aber Sie können 4 Bytes sparen, indem Sie randi([3,5],1,18)anstelle von 3+floor(rand(1,18)*3)
eingeben

3

Java (61 Zeichen)

while(s!=72)for(i=0,s=0;i<18;i++)s+=3+(int)(Math.random()*3);

Beispielausgabe:

5 4 3 4 5 3 4 4 3 5 4 4 4 4 3 4 4 5

Ich bin kein Java-Experte, aber sollte es keine Deklaration von s und i und einen Aufruf von System # println (..) geben?
Hiergiltdiestfu

Dies ist nur ein Codeausschnitt, kein Programm. Und es sieht tatsächlich sehr nach der C-Version von @JoeIbanez aus.
Franz D.

2

C (94 Zeichen)

int h[18],s=0,i;
while(s!=72)for(i=s=0;i<18;s+=h[i++]=rand()%3+3);
while(i)printf("%d ",h[--i]);

Das s=0On-Line-1 ist möglicherweise nicht erforderlich, da die Wahrscheinlichkeit, dass ein nicht initialisiertes Int 72 ergibt, wie groß ist. Ich mag es einfach nicht, nicht initialisierte Werte in Straight C zu lesen. Dies erfordert wahrscheinlich auch das Setzen der rand()Funktion.

Ausgabe

3 3 3 4 5 5 3 3 4 5 5 4 3 4 5 5 5 3 

Im Grunde werden Sie zufällige Zeichenfolgen mit 18 Zahlen im Bereich von 3 bis 5 durchlaufen, bis eine 72 ergibt? Gute Sache Effizienz ist keine Voraussetzung.
KeithS

5
@KeithS Um fair zu sein, das ist es, was die Mehrheit der Antworten auf diese Frage tut.
Gareth

2

Bash-Shell-Skript (65 Zeichen)

shuf -e `for x in {0..8}
do echo $((r=RANDOM%3+3)) $((8-r))
done`

( shuf stammt aus dem GNU-Paket coreutils. Danke auch, Gareth.)


2

C # (143 ohne Leerzeichen):

()=>{
  var n=new Math.Random().Next(10);
  Enumerable.Range(1,18)
    .Select((x,i)=>i<n?3:i>=18-n?5:4)
    .OrderBy(x=>Guid.NewGuid())
    .ForEach(Console.Write);
}

new Guid()Erstellt eine leere GUID. Um eine eindeutige GUID zu generieren, müssen Sie eine statische Methode aufrufen Guid.NewGuid.
Rotsor

Und Sie haben zwei Fehler von eins zu eins (sozusagen): Die Vergleiche sollten i <n und i> = 18-n sein, nicht umgekehrt. Und Sie können die Größe reduzieren, indem Sie eine Konstante 3 anstelle von x-1 und 5 anstelle von x + 1 verwenden. Und dann könnten Sie Enumerable.Repeat durch Enumerable.Range ersetzen.
Mormegil

Bearbeitet; noch 143 Zeichen
KeithS

Es gibt kein Math.Random, es ist System.Random.
CodesInChaos

Ein weiterer C # -Ansatz (143 Zeichen):var r=new Random();for(;;){var e=Enumerable.Range(1,18).Select(i=>r.Next(3,6)).ToList();if(e.Sum()==72){e.ForEach(i=>Console.Write(i));break;}}
thepirat000


2

Perl, 74

{@c=map{3+int rand 3}(0)x18;$s=0;$s+=$_ for@c;redo unless$s==72}print"@c"

Alternative Lösung:

@q=((3,5)x($a=int rand 9),(4,4)x(9-$a));%t=map{(rand,$_)}(0..17);print"@q[@t{sort keys%t}]"

2

TXR (99 Zeichen)

@(bind g@(for((x(gen t(+ 3(rand 3))))y)(t)((pop x))(set y[x 0..18])(if(= [apply + y]72)(return y))))

Dieser Ausdruck erzeugt eine unendlich faule Liste von Zufallszahlen von 3 bis 5:

(gen t (+ 3(rand 3)))  ;; t means true: while t is true, generate.

Der Rest der Logik ist eine einfache Schleife, die prüft, ob die ersten 18 Elemente dieser Liste 72 ergeben. Andernfalls wird ein Element entfernt und erneut versucht. Dasfor Schleife enthält einen impliziten Block, der aufgerufen wird, nilund (return ...)kann daher zum Beenden der Schleife und zum Zurückgeben des Werts verwendet werden.

Beachten Sie, dass die Länge von 99 Zeichen eine abschließende neue Zeile enthält, die erforderlich ist.


Ich habe ein Commit eingegeben, mit dem das (t) durch () ersetzt werden kann. :)
Kaz

2

APL 12

4+{⍵,-⍵}?9⍴2

Beachten Sie, dass ich den Indexursprung auf 0 gesetzt habe, was bedeutet, dass Arrays bei 0 beginnen. Sie können dies mit festlegen ⎕IO←0.


Die Frage stellt ein Programm, das jede mögliche Konfiguration erzeugen kann. Ihre können simmetrische produzieren. Sie können zum Beispiel nicht 555455555333333343 produzieren, zumindest scheint es mir so.
Moris Zucca

2

R, 42 Bytes

a=0;while(sum(a)-72)a=sample(3:5,18,r=T);a

sampleZeichnet standardmäßig gleichmäßig unter den möglichen Werten (hier 3 4 5). r=Tsteht für replace=TRUEund ermöglicht Probe mit Ersatz.


2

CJam, 17 14 Bytes

CJam ist neuer als diese Herausforderung, aber dies ist ohnehin nicht die kürzeste Antwort, so dass das eigentlich egal ist.

Z5]Amr*I4e]mrp

Teste es hier.

Um die Gesamtzahl von 72 aufrechtzuerhalten, 3muss jeder mit gepaart werden 5. So funktioniert es:

Z5]            e# Push [3 5].
   Amr         e# Get a random number between 0 and 9.
      *        e# Repeat the [3 5] array that many times.
       I4e]    e# Pad the array to size 18 with 4s.
           mr  e# Shuffle the array.
             p e# Print it.
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.