Das Taubenschlagprinzip besagt das
Wenn N Artikel in M Felder mit N > M gestellt werden , muss mindestens ein Feld mehr als einen Artikel enthalten.
Für viele hat dieses Prinzip einen besonderen Stellenwert im Vergleich zu anderen mathematischen Aussagen. Wie EW Dijkstra schrieb ,
Es ist von Mystik umgeben. Proofs, die es verwenden, werden oft als etwas Besonderes, als etwas besonders Geniales angesehen.
Die Herausforderung
Der Zweck dieser Herausforderung ist die Veranschaulichung des Pigeonhole-Prinzips anhand von ASCII-Darstellungen. Speziell:
- Nehmen Sie als Eingabe
N
(Anzahl der Elemente) undM
(Anzahl der Felder), mitN
nicht-negativen undM
positiven.N
kann kleiner sein alsM
(auch wenn der Grundsatz in diesem Fall nicht gilt). - Wählen Sie zufällig eine der möglichen Zuordnungen von Elementen zu Feldern aus. Jede Aufgabe sollte mit einer Wahrscheinlichkeit ungleich Null ausgewählt werden.
Erstellen Sie eine ASCII-Grafikdarstellung der Zuweisung wie folgt:
- Es gibt
M
Linien, die jeweils einem Kästchen entsprechen. - Jede Zeile beginnt mit einem Nicht-Leerzeichen wie z
|
. - Nach diesem Zeichen folgt ein anderes Nicht-Leerzeichen, das z. B.
#
so oft wiederholt wird, wie sich Elemente in diesem Feld befinden.
- Es gibt
Betrachten Sie zum Beispiel N = 8
, M = 5
. Wenn die ausgewählte Zuordnung von Elementen zu Feldern " 4
," 1
, " 0
ist 3
, 0
ist die Darstellung"
|####
|#
|
|###
|
Ein anderer Lauf (der zu einer anderen Zuweisung führt) desselben Programms könnte ergeben
|#
|##
|#
|#
|###
Es gibt eine gewisse Flexibilität in Bezug auf die Darstellung; siehe unten.
Spezifische Regeln
Der Code sollte theoretisch für alle Werte von N
und ausgeführt werden M
. In der Praxis kann es durch Einschränkungen der Speichergröße oder des Datentyps eingeschränkt sein.
Da das Beobachten der Ausgabe nicht ausreicht, um zu bestimmen, ob alle Zuweisungen eine Wahrscheinlichkeit ungleich Null haben , sollte jede Einreichung erläutern, wie der Code dies erreicht, wenn nicht offensichtlich.
Folgende Darstellungsvarianten sind zulässig:
- Es kann ein beliebiges Paar verschiedener Zeichen ohne Leerzeichen ausgewählt werden. Sie müssen über die Programmausführungen hinweg konsistent sein.
- 90-Grad-Drehungen der Darstellung sind zulässig. Auch hier muss die Auswahl konsistent sein.
- Nachgestellte oder führende Leerzeichen sind zulässig.
Als ein Beispiel mit einem anderen Darstellungsformat, für N = 15
, M = 6
könnten die Ergebnisse von zwei Ausführungen des Programms sein
VVVVVV
@@@@@@
@@ @@@
@ @@
@
oder
VVVVV
@@@ @
@@@ @
@ @ @
@ @ @
@
Ebenso N = 5
, M = 7
könnte geben, eine andere Variation der Darstellung verwendet wird ,
*
* * * *
UUUUUUU
oder
*** **
UUUUUUU
oder
*
* *
* *
UUUUUUU
Beachten Sie, wie das Prinzip in diesem Fall nicht anwendbar ist, weil N
< M
.
Allgemeine Regeln
Programme oder Funktionen sind in jeder Programmiersprache zulässig . Standardlücken sind verboten.
Die Eingabe kann auf jede vernünftige Weise erfolgen . und mit jedem Format, z. B. einem Array aus zwei Zahlen oder zwei verschiedenen Zeichenfolgen.
Ausgabemittel und Format sind ebenfalls flexibel. Die Ausgabe kann beispielsweise eine Liste von Zeichenfolgen oder eine Zeichenfolge mit Zeilenumbrüchen sein. wird als Funktionsausgabeargument zurückgegeben oder in STDOUT angezeigt. Im letzteren Fall ist es nicht erforderlich, sich um Zeilenumbrüche zu kümmern, die durch eine begrenzte Anzeigebreite verursacht werden.
Kürzester Code in Bytes gewinnt.
Antworten:
Gelee ,
98 BytesDies ist eine dyadische Verknüpfung, die M als linkes und N als rechtes Argument verwendet. Die Ausgabe ist ein Array von Ganzzahlen, wobei 0 für Tauben und 1 für Löcher steht.
Probieren Sie es online!
Wie es funktioniert
quelle
Mathematica, 68 Bytes
Eine unbenannte Funktion, die zwei ganzzahlige Argumente akzeptiert, die Anzahl der Felder, gefolgt von der Anzahl der Elemente.
Es berechnet zunächst alle möglichen Partitionen von
N+M
in genauM
positive Teile und subtrahiert anschließend1
von jeder Partition. Dies gibt uns alle möglichen PartitionenN
inM
nicht negative Teile (dieIntegerPartitions
sonst nicht erzeugt würden). Wähle dann eine zufällige Partition und mische sie. Dies garantiert, dass alle möglichen geordneten Partitionen mit Nullen zulässig sind. Schließlich wird jedes Fach der mit einer Ausgangsleitung Partition konvertieren , indem 10 auf die entsprechende Potenzierung (so dass jede Zeile wird1000...
mitk
Nullen). Eine Beispielausgabe könnte folgendermaßen aussehen:quelle
PadRight
würde nicht zuM
Nullen auffüllen, wennN
<M
.PadRight
die Nicht-Listbarkeit würde es viel länger machen.PadRight
wäreIntegerPartitions[#,{#2},0~Range~#]
.Python 2,
7786 BytesErzeugt eine Zahl in [0, n], druckt so viele Elemente und subtrahiert sie von n. Das macht es m-mal.
Dies macht es sehr unwahrscheinlich, dass irgendetwas es bis zur letzten Box schafft, aber die Frage stellte nur, dass jede Ausgabe möglich und nicht gleich wahrscheinlich ist .
quelle
Batch, 164 Bytes
Ich denke, 7 aufeinanderfolgende
%
Zeichen könnten eine neue persönliche Bestleistung sein! Hinweis: Dies führt zu einer ungeraden Ausgabe, sollte der gleichen Box jemals mehr als 9 Elemente zugewiesen werden. Wenn das ein Problem ist, dann für 180 Bytes:Ja, das sind insgesamt 28
%
Sekunden in der zweiten Zeile.quelle
C 102 Bytes
Übernimmt Eingaben über stdin, zB:
Erzeugt nicht jede Ausgabe mit gleicher Wahrscheinlichkeit, kann aber alle möglichen Kombinationen erzeugen.
Nervenzusammenbruch:
Beruht auf GCCs Handhabung des undefinierten Verhaltens von
%0s
- Füllt normalerweise%0
eine Ganzzahl oder einen Gleitkommawert mit Null auf, kann jedoch nur aufgefüllt (nie abgeschnitten) werden, sodass kein Leerzeichen gedruckt werden kann. Das Verhalten für Zeichenfolgen ist jedoch nicht definiert, und GCC hat beschlossen, das Auffüllen mit Nullen auf die gleiche Weise vorzunehmen. Daher füllt dieses Auffüllen eine leere Zeichenfolge mit Nullen auf, um in der Lage zu sein, null oder mehr zu schreiben0
.quelle
a(b,c){...}
anstelle vonmain
und verwendenscanf
.Python 2,
102999790 Bytesm-1
wähle mal einen zufälligen Betragx
zwischen0
undn
, inklusive und subtrahiere ihn von n. Dann drucken Sie ein1
und'0'*x
.Schließlich drucken
1
und der Rest von0
s. Nicht bei allen gleichen Chancen, aber alle Konfigurationen sind möglich.(Wiederverwendeter Code aus der kaputten Python-Antwort.)
quelle
Haskell,
11494 BytesEin bisschen wie ein Brute-Force-Ansatz: Erzeugt eine unendliche Liste von Zufallszahlen, nimmt n Zahlen vom Anfang der Liste, summiert sie und prüft, ob sie gleich m sind. Wenn nicht, nimm das erste Element von der Liste und wiederhole es.
Probieren Sie es online!
Hinweis: 73 Bytes ohne den Import
BEARBEITEN: Einige Bytes mit dem 10 ^ Trick gespeichert ( Neue Version online testen! )
quelle
REXX, 74 Bytes
Ausgabe (8 5):
Ausgabe (8 5):
quelle
C
175138 BytesVielen Dank an @ Dave für das Speichern von 37 Bytes!
Probieren Sie es online!
quelle
calloc
Sie erhalten 0-initialisierten Speicher (Sie müssen nicht alle 0en selbst setzen),strchr
können das Ende einer Zeichenfolge finden, Komma kann Operationen verketten, die Notwendigkeit vermeiden{}
undx[0] == *x
. Pass auch auf; Sie haben nichtmalloc
genügend Speicher, wenn sich alle Elemente in derselben Box befinden.AHK, 66 Bytes
Ich folgte demselben Prinzip wie orlp, indem ich Zufallszahlen von 0 bis N verwendete und diese dann von N subtrahierte. Leider konnte ich keine Bytes mit 10 ^ r speichern, da die Sendefunktion so funktioniert. Ach und ach. Hier sind einige Ausgaben für n = 8, m = 5:
quelle
CJam,
303121 BytesEingabe sind zwei Zahlen
n m
auf dem Stapel. Verwendet1
für das Spaltenzeichen und0
für das wiederholte Zeichen.Erläuterung:
quelle
Röda , 79 Bytes
Probieren Sie es online!
Dadurch wird ein Array von Nullen erstellt und an zufälligen Stellen inkrementiert.
quelle
PHP, 100 Bytes
Nervenzusammenbruch :
Ausgänge für
m=7
undn=5
:Erste Ausführung:
Zweite Ausführung:
Probieren Sie es online!
quelle
[,$m,$n]=$argv;
PHP 7.1 verwenden, um ein paar Zeichen zu speichern. Sie können durch\n
einen tatsächlichen Zeilenumbruch ersetzen , um 1 Byte zu sparen. Mit können Siefor(;$m-->0;)$a[rand(0,$n-1)].=a;
die Pausen, ein$m
und ein Semikolon speichern .[,$m,$n]=$argv;$a=array_fill(0,$n,z);for(;$m-->0;)$a[rand()%$n].=a;echo join("\n",$a);
85 Byte[,$m,$n]=$argv;for(;$m--;)${rand()%$n}.=a;for(;$n--;)echo"z${$n}\n";
67 Byte noch weiter .[,$m,$n]=$argv;
auf anderen Code-Golfs gesehen, konnte sie aber weder in meiner Entwicklungsumgebung noch auf eval.inJavaScript, 105 Bytes
Probieren Sie es online!
Aufgrund der Methode zum Zuweisen der Zeilen wird dies tendenziell eher nach unten verlegt, obwohl die Wahrscheinlichkeit gering ist, dass die Oberseite etwas davon erhält.
quelle
Ruby, 52 Bytes
Erstellt eine anonyme Funktion, die zwei Ganzzahlen als Argumente verwendet und ein Array von Strings zurückgibt:
quelle
Python 2, 81 Bytes
Gibt eine Liste von Zeichenfolgen zurück.
quelle
Javascript (ES7), 75 Byte
Ich dachte, ich wäre schlau genug, um auf die Idee der Potenz 10 zu kommen, nur um zu erkennen, dass die meisten Antworten dies bereits benutzten.
quelle
AWK, 78 Bytes
Nimmt 2 Argumente auf, zuerst die Anzahl der Elemente, dann die Anzahl der Felder. Beginnt mit dem Setzen des Zufallszahlengenerators, sodass jeder Lauf anders ist. Dann baut man einfach Strings in einem Array auf.
quelle
MATLAB,
10394 BytesMit der Formatierung
Beispielausgabe
Es gibt nachgestellte Leerzeichen, da jeder Array-Eintrag mit einem Tabulator dazwischen angezeigt wird. Dies sollte jedoch gemäß den Spezifikationen akzeptabel sein.
Dies scheint mir eine sehr vereinfachte Implementierung zu sein, daher bin ich mir sicher, dass dies verbessert werden könnte.
Danke an @Luis Mendo für die Vorschläge.
quelle
d=@(p)disp(char([1,~(1:p)]+48));for i=1:m-1;p=randi([0,n]);d(p);n=n-p;end;d(n)
a=
. In diesem Fall können Sie dies im Prinzip nicht tun, da anonyme Funktionen keine Schleifen enthalten können. Aber Sie könnten den Trick gebrauchen, alles hinein zu setzeneval('...')
. Übrigens, das wird in Matlab normalerweise als hässlich und schlecht angesehen, aber hier missbrauchen wir gerne Sprachen :-)Oktave ,
6254 BytesAnonyme Funktion, die zwei Zahlen annimmt und ein 2D-Array von Zeichen mit ausgibt
>
für Boxen und*
für Objekte . Alle Ergebnisse sind gleich wahrscheinlich.Probieren Sie es online!
quelle
TI-Basic,
6362 BytesDieses Kriterium erleichterte das Schreiben des Programms erheblich.
Beispiel I / O:
Erläuterung:
quelle
MATLAB,
736458 BytesUpdate Nr. 3
Ich brauche die Sortierung anscheinend, da ich sonst negative ganze Zahlen bekomme. Ich habe ersetzen
disp(sprintf(...))
mitfprintf(...)
jetzt, obwohl, so dass die Antwort 58 Bytes bleibt.Update Nr. 2:
Mir wurde klar, dass ich das Array nicht sortieren musste, und tatsächlich würde das Sortieren den Durchschnitt der Zahlen im Array reduzieren. Also habe ich das
sort(...)
Teil gelöscht . Beachten Sie, dass die Ausgabe dieselbe bleibt, sodass ich die "Beispielausgabe" nicht aktualisiere.Endlich die Oktavantwort von Luis! : D
Update Nr. 1:
Anstatt in einen String zu konvertieren, zeige ich nur Zahlen direkt an. Ich könnte auf 58 Bytes reduzieren, indem
disp(...)
ich das entferne , aber dann bekomme ich das Extraans =
mit nur sprintf und weiß nicht, ob das akzeptabel ist.Anfangscode:
Dank einiger Vorschläge von Luis habe ich die Schleife in meiner vorherigen Antwort losgeworden . Jetzt erstelle ich ein vertikales Array von
m
Zufallszahlen, die zusammenn
(diff([0;sort(randi(n,m-1,1));n])
) , verwende sie dann als Exponenten von 10, konvertiere sie in eine Zeichenfolge, bündige sie linksbündig und zeige sie an.Ich könnte das disp (...) technisch loswerden, um weitere 6 Bytes zu sparen, aber dann wird ein "ans" gedruckt, das möglicherweise gegen die Spezifikationen verstößt. Es kann auch eine Möglichkeit geben, sie in Zeichenfolge und linksbündig zu ändern, um das gewünschte Endformat zu erhalten. Daher bin ich offen für Vorschläge.
Beispielausgabe:
Hinweis : Aufgrund von Vorschlägen habe ich hier meine Funktion in eine anonyme Funktion geändert. In der Beispielausgabe habe ich das zugewiesen,
a
um zu demonstrieren. Ich hoffe, dies verstößt nicht gegen die Spezifikationen, aber wenn doch, lassen Sie es mich bitte wissen und ich werde es ändern.quelle
m
zufällige Ganzzahlen zu erstellen , die sich summierenn
, da ich lange Zeit an diesem Teil festgehalten habe . (Ich kann immer noch nicht mehr als 2 Links in meine Antworten einfügen, also auch nicht in einem Kommentar)Gestapelt , 29 Bytes
Probieren Sie es online!
Verhält sich, indem ein Array von
M
Singletons erstellt wird, die Folgendes enthalten'|'
, und dann'#'
zu zufällig ausgewählten Array-N
Zeiten hinzugefügt wird .quelle
randin
intern der Fisher-Yates-Algorithmus verwendet wird. (Dies ist derselbe Algorithmus, den die CJam-Antwort mit FWIW verwendet)Python 2 ,
80 95 8988 BytesProbieren Sie es online!
quelle
Holzkohle , 19 Bytes
Probieren Sie es online! Link ist eine ausführliche Version des Codes. Erläuterung:
quelle