Dies ist eine Herausforderung im Internet, die Palantir Technologies in ihren Interviews gestellt hat .
Eine Gruppe von Landwirten verfügt über einige Höhendaten, und wir werden ihnen helfen, zu verstehen, wie der Niederschlag über ihr Ackerland fließt. Wir werden das Land als eine zweidimensionale Anordnung von Höhen darstellen und das folgende Modell verwenden, basierend auf der Idee, dass Wasser bergab fließt:
Wenn die vier benachbarten Zellen einer Zelle alle eine höhere Höhe haben, bezeichnen wir diese Zelle als Senke. wasser sammelt sich in waschbecken. Andernfalls fließt Wasser in die benachbarte Zelle mit der niedrigsten Höhe. Wenn eine Zelle keine Senke ist, können Sie davon ausgehen, dass sie einen eindeutigen niedrigsten Nachbarn hat und dieser Nachbar niedriger als die Zelle ist.
Zellen, die direkt oder indirekt in dasselbe Waschbecken abfließen, werden als Teil desselben Beckens bezeichnet.
Ihre Herausforderung besteht darin, die Karte in Becken zu unterteilen. Insbesondere sollte Ihr Code bei einer Karte mit Höhenangaben die Karte in Becken unterteilen und die Größe der Becken in absteigender Reihenfolge ausgeben.
Angenommen, die Höhenkarten sind quadratisch. Die Eingabe beginnt mit einer Zeile mit einer ganzen Zahl, S, der Höhe (und Breite) der Karte. Die nächsten S-Zeilen enthalten jeweils eine Zeile der Karte mit S-ganzen Zahlen - den Höhen der S-Zellen in der Zeile. Einige Landwirte haben kleine Grundstücke, wie in den folgenden Beispielen gezeigt, während andere größere Grundstücke haben. Ein Bauer wird jedoch in keinem Fall ein Grundstück haben, das größer als S = 5000 ist.
Ihr Code sollte eine durch Leerzeichen getrennte Liste der Beckengrößen in absteigender Reihenfolge ausgeben. (Nachgestellte Leerzeichen werden ignoriert.)
Einige Beispiele finden Sie unten.
Eingang:
3
1 5 2
2 4 7
3 6 9
Ausgabe:
7 2
Die mit A und B gekennzeichneten Becken sind:
A A B
A A B
A A A
Eingang:
1
10
Ausgabe:
1
In diesem Fall gibt es nur ein Becken.
Eingang:
5
1 0 2 5 8
2 3 4 7 9
3 5 7 8 9
1 2 5 4 2
3 3 5 2 1
Ausgabe:
11 7 7
Die mit A, B und C gekennzeichneten Becken sind:
A A A A A
A A A A A
B B A C C
B B B C C
B B C C C
Eingang:
4
0 2 1 3
2 1 0 4
3 3 3 3
5 5 2 1
Ausgabe:
7 5 4
Die mit A, B und C gekennzeichneten Becken sind:
A A B B
A B B B
A B B C
A C C C
quelle
Antworten:
Mathematica
Die Beckengrößenliste erhalten Sie von
Wo
m
sind die angegebenen Eingabedaten? Zur Anzeige kann eine Matrix wie die , die in der Frage ersetzen// Reverse@Sort@Part[Tally[Flatten@#], All, 2] &
mit/. {1 -> "A", 2 -> "B", 3 -> "C"} // MatrixForm
oder man kann es als Bild angezeigt werden, statt unter Verwendung//ImageAdjust//Image
.quelle
JavaScript - 673
707730751e=[],g=[],h=[],m=[],q=[];function r(){a=s,b=t;function d(d,A){n=a+d,p=b+A;c>e[n][p]&&(u=!1,v>e[n][p]&&(v=e[n][p],w=n,k=p))}c=e[a][b],u=!0,v=c,w=a,k=b;0!=a&&d(-1,0);a!=l&&d(1,0);0!=b&&d(0,-1);b!=l&&d(0,1);g[a][b]=w;h[a][b]=k;return u}function x(a,b,d){function c(a,b,c,k){g[a+b][c+k]==a&&h[a+b][c+k]==c&&(d=x(a+b,c+k,d))}d++;0!=a&&c(a,-1,b,0);a!=l&&c(a,1,b,0);0!=b&&c(a,0,b,-1);b!=l&&c(a,0,b,1);return d}y=$EXEC('cat "'+$ARG[0]+'"').split("\n");l=y[0]-1;for(z=-1;z++<l;)e[z]=y[z+1].split(" "),g[z]=[],h[z]=[];for(s=-1;s++<l;)for(t=-1;t++<l;)r()&&m.push([s,t]);for(z=m.length-1;0<=z;--z)s=m[z][0],t=m[z][1],q.push(x(s,t,0));print(q.sort(function(a,b){return b-a}).join(" "));
Testergebnisse (mit Nashorn):
Es würde wahrscheinlich Stapelprobleme für Karten der Größe 5000 geben (aber das ist ein Implementierungsdetail :).
Die ungeklärte Quelle in ihrer ganzen Flüchtigkeit:
Ich habe bessere Ergebnisse bei der Minimierung erzielt, indem ich die Elementobjekte in separate Arrays aufgeteilt, überall globalisiert und Nebenwirkungen berücksichtigt habe. NSFW.
Die Auswirkungen der Code-Minimierung:
Ich hätte fast 700 Bytes erreichen können, ohne den minimierten Code zu bearbeiten, wenn ich gewillt gewesen wäre, die ursprüngliche Quelle zu ändern. Aber ich habe es nicht getan, weil ich denke, es so zu belassen, wie es ist, gibt einen interessanten Blick vom Ausgangspunkt.
quelle
var e=[],g=[],h=[],l,m=[],q=[]
zue=g=h=l=m=q=[]
. Sie können wahrscheinlich auch andere Verwendungen desvar
Schlüsselworts beseitigen, wenn Sie keine globalen Variablen spiegeln.Python: 276
306 365BytesDies ist mein erster Golfversuch. Vorschläge werden geschätzt!
Bearbeiten: Importieren und Schließen von Dateien dauert zu viele Zeichen! Das Gleiche gilt für das Speichern von Dateien in Variablen und das Verstehen von verschachtelten Listen.
vollständig kommentiert (2130 Bytes ...)
quelle
open('a').read()
, denke ich.JavaScript (ECMAScript 6) - 226 Zeichen
Erläuterung
Vorherige Version - 286 Zeichen
Es wird davon ausgegangen, dass sich die Eingabe in einer Variablen befindet
S
.Erläuterung
Prüfung
Ausgänge:
[7, 2]
Ausgänge:
[11, 7, 7]
Ausgänge:
[5, 7, 4]
quelle
Julia, 315
Nur eine rekursive Funktion, die entweder die aktuelle Zelle bestimmt, ist eine Senke oder findet den Drain. Rufen Sie dies dann für jeden Satz von Indizes auf. Ich habe mich nicht darum gekümmert, den Input-Teil zu machen, da ich sowieso nicht gewinnen würde und dieser Teil keinen Spaß macht.
quelle
Haskell,
271–286Könnte noch ein Code sein, um hier Golf zu spielen.
Erläuterung
Grundidee: Finden Sie für jede Zelle (i, j) die unterste Zelle in der "Nachbarschaft". Dies ergibt einen Graphen [ (i, j) → (mi, mj) ]. Wenn eine Zelle die unterste Zelle selbst ist, dann ist (i, j) == (mi, mj) .
Dieses Diagramm kann iteriert werden: Ersetzen Sie es für jedes a → b im Diagramm durch a → c, wobei b → c im Diagramm steht. Wenn diese Iteration keine Änderungen mehr ergibt, zeigt jede Zelle im Diagramm auf die unterste Zelle, zu der sie fließt.
Um dies zu erreichen, wurden einige Änderungen vorgenommen: Erstens werden Koordinaten als Liste der Länge 2 und nicht als Paar dargestellt. Zweitens, sobald die Nachbarn gefunden wurden, werden die Zellen durch ihren Index in einem linearen Array der Zellen dargestellt, nicht in 2D-Koordinaten. Drittens muss der Graph, da es n * n Zellen gibt, nach n * n Iterationen stabil sein.
Ungolf'd
quelle
Rubin, 216
Es ist ein etwas anderer Ansatz, bei dem nur einmal "flow" für jedes Quadrat aufgerufen wird (die Leistung hängt von der Leistung von Array :: index ab). Es geht von der höchsten zur niedrigsten Erhebung, entleert jeweils eine Zelle in den untersten Nachbarn und markiert die erledigte Zelle (indem 1 zur Erhebung hinzugefügt wird), wenn sie erledigt ist.
Kommentiert und beabstandet:
Änderungsprotokoll:
216 - Besseres Abwählen von Out-of-Bounded-Indizes
221 - stellt sich heraus, "11" kommt vor "2" ... zurück
to_i
, aber sparen Sie etwas Platz auf unserengets
es.224 - Warum überhaupt deklarieren
s
? Undeach
=>map
229 - massiv Golf - Art der Erhebungen zunächst in
s
(und fällt dadurch diewhile
Klausel), verwenden Siemin_by
stattsort_by{...}[0]
, nicht die Mühe ,to_i
für Erhebungen, Verwendungflat_map
und schrumpftselect{}
Block271 - Größe der Wasserscheide in neues Array verschoben und sort_by verwendet
315 - Die Ergebnisse wurden in ein Array verschoben, das alle möglichen Vorteile bot, und die Liste der Nachbarn wurde verkürzt. gewann auch ein Zeichen im Index Lambda.
355 - Erstes Festschreiben
quelle
Python -
470 447 445 393 392 378 376 375 374369 BytesIch kann mich nicht aufhalten!
Keine gewinnbringende Lösung, aber es hat mir viel Spaß gemacht, sie zu erstellen. Diese Version setzt nicht voraus, dass die Eingabe irgendwo gespeichert wird, sondern liest sie stattdessen von stdin. Maximale Rekursionstiefe = größte Entfernung von einem Punkt zu seiner Senke.
Ich habe heute keine Zeit, es zu erklären, aber hier ist der ungolfed Code:Es ist eigentlich ganz anders als der ursprüngliche Code. Ich lese S-Zeilen aus dem Standard, teile sie auf, ordne sie den Ints zu und drücke die Listen zusammen, um das abgeflachte Feld zu erhalten. Dann durchlaufe ich einmal alle Kacheln (ich nenne sie Kacheln). Die Flow-Funktion prüft die benachbarten Kacheln und wählt die mit dem kleinsten Wert aus. Wenn es kleiner als der Wert der aktuellen Kachel ist, gehen Sie dorthin und wiederholen Sie den Vorgang. Ist dies nicht der Fall, handelt es sich bei der aktuellen Kachel um ein Waschbecken, und es wird ein neues Becken erstellt. Der Rückgabewert der Rekursion ist die ID des Beckens.
quelle
JavaScript (ES6) 190
203Bearbeiten Ein wenig mehr ES6ish (1 Jahr später ...)
Definieren Sie eine Funktion mit Eingabezeilen als Zeichenfolge, einschließlich Zeilenumbrüchen, und geben Sie die Ausgabe als Zeichenfolge mit nachgestellten Leerzeichen zurück
quelle
Perl 6,
419404Zeilenumbrüche zur Verdeutlichung hinzugefügt. Sie können sie sicher entfernen.
Alte Lösung:
Und doch werde ich von Python- und JavaScript-Lösungen geschlagen.
quelle