Diese Frage basiert auf dem Zahlenrätsel Towers (auch Wolkenkratzer genannt), das Sie online spielen können . Ihr Ziel ist es, eine Lösung für das Rätsel zu finden und die Hinweise zu ermitteln - die Anzahl der Türme, die in jeder Zeile und Spalte sichtbar sind. Dies ist Codegolf, so dass nur wenige Bytes gewinnen.
Wie funktioniert Towers?
Die Lösung für ein Türme-Puzzle ist ein lateinisches Quadrat - ein n*n
Raster, in dem jede Zeile und Spalte eine Permutation der 1
durchgehenden Zahlen enthält n
. Ein Beispiel für n=5
ist:
4 3 5 2 1
5 4 1 3 2
1 5 2 4 3
2 1 3 5 4
3 2 4 1 5
Jede Zeile und Spalte ist an jedem Ende mit einem Hinweis versehen:
2 3 1 4 5
v v v v v
2 > 4 3 5 2 1 < 3
1 > 5 4 1 3 2 < 4
2 > 1 5 2 4 3 < 3
3 > 2 1 3 5 4 < 2
3 > 3 2 4 1 5 < 1
^ ^ ^ ^ ^
2 2 2 2 1
Jeder Hinweis ist eine Zahl von 1
bis n
, die angibt, wie viele Türme Sie entlang der Reihe / Spalte aus dieser Richtung "sehen", wenn die Zahlen als Türme mit dieser Höhe behandelt werden. Jeder Turm blockiert kürzere Türme dahinter. Mit anderen Worten, die Türme, die Sie sehen können, sind höher als jeder Turm vor ihnen.
Schauen wir uns zum Beispiel die erste Reihe an.
2 > 4 3 5 2 1 < 3
Es hat einen Hinweis von 2
links, weil Sie das 4
und das sehen können 5
. Das 4
blockiert die 3
Sicht und das 5
blockiert alles andere. Von der rechten Seite können Sie sehen , 3
Türme: 1
, 2
, und 5
.
Programmanforderungen
Schreiben Sie ein Programm oder eine Funktion, die das Zahlenraster aufnimmt und die Hinweise ausgibt oder druckt, und zwar im Uhrzeigersinn von oben links.
Eingang
Ein n*n
lateinisches Quadrat mit 2<=n<=9
.
Das Format ist flexibel. Sie können eine beliebige Datenstruktur verwenden, die ein Raster oder eine Liste mit Zahlen oder Ziffern darstellt. Möglicherweise benötigen Sie ein Trennzeichen zwischen den Zeilen oder gar kein Trennzeichen. Einige Möglichkeiten sind eine Liste, eine Liste von Listen, eine Matrix, eine durch Token getrennte Zeichenfolge wie
43521 54132 15243 21354 32415,
oder eine Zeichenfolge ohne Leerzeichen.
Sie werden nicht n
als Teil der Eingabe angegeben.
Ausgabe
Geben Sie die Hinweise von links oben im Uhrzeigersinn zurück oder drucken Sie sie aus. Also, zuerst lesen die oberen Hinweise nach rechts, dann lesen die rechten Hinweise nach unten, dann lesen die unteren Hinweise nach links, die linken Hinweise nach oben.
Dies wäre 23145 34321 12222 33212
für das vorherige Beispiel
2 3 1 4 5
v v v v v
2 > 4 3 5 2 1 < 3
1 > 5 4 1 3 2 < 4
2 > 1 5 2 4 3 < 3
3 > 2 1 3 5 4 < 2
3 > 3 2 4 1 5 < 1
^ ^ ^ ^ ^
2 2 2 2 1
Ebenso wie für die Eingabe können Sie eine Liste, eine Zeichenfolge oder eine beliebige geordnete Struktur verwenden. Die vier "Gruppen" können in einer verschachtelten oder flachen Struktur getrennt sein oder nicht. Das Format muss jedoch für jede Gruppe gleich sein.
Beispiel Testfälle:
(Ihr Eingabe- / Ausgabeformat muss nicht mit diesen identisch sein.)
>> [[1 2] [2 1]]
[2 1]
[1 2]
[2 1]
[1 2]
>> [[3 1 2] [2 3 1] [1 2 3]]
[1 2 2]
[2 2 1]
[1 2 3]
[3 2 1]
>> [[4 3 5 2 1] [5 4 1 3 2] [1 5 2 4 3] [2 1 3 5 4] [3 2 4 1 5]]
[2 3 1 4 5]
[3 4 3 2 1]
[1 2 2 2 2]
[3 3 2 1 2]
>> [[2 6 4 1 3 7 5 8 9] [7 2 9 6 8 3 1 4 5] [5 9 7 4 6 1 8 2 3] [6 1 8 5 7 2 9 3 4] [1 5 3 9 2 6 4 7 8] [3 7 5 2 4 8 6 9 1] [8 3 1 7 9 4 2 5 6] [9 4 2 8 1 5 3 6 7] [4 8 6 3 5 9 7 1 2]]
[4 2 2 3 3 3 3 2 1]
[1 3 3 2 2 2 2 3 3]
[4 3 2 1 2 3 3 2 2]
[3 1 2 4 3 3 2 2 5]
Der Einfachheit halber finden Sie hier dieselben Testfälle im Flat-String-Format.
>> 1221
21
12
21
12
>> 312231123
122
221
123
321
>> 4352154132152432135432415
23145
34321
12222
33212
>> 264137589729683145597461823618572934153926478375248691831794256942815367486359712
422333321
133222233
432123322
312433225
≢¨∪¨↓⌈\(⍉⍪⌽⍪⍉∘⌽∘⊖⍪⊖)
Python 2, 115 Bytes
Da ist eine Menge Liste drin.
Nimmt die Eingabe als verschachtelte Liste (z
T([[4,3,5,2,1],[5,4,1,3,2],[1,5,2,4,3],[2,1,3,5,4],[3,2,4,1,5]])
. B. Anruf mit ). Die Ausgabe ist eine einzelne flache Liste.Ungolfed:
Alternative 115:
Ich habe keine Ahnung, warum dies mit einem Listenverständnis funktioniert, aber wirft ein
NameError
mit einem Mengenverständnis ...Ein bisschen zu lang, aber wenn es jemanden interessiert - ja, es ist möglich, dies auf ein Lambda zu bringen!
Pyth , 25 Bytes
Obligatorischer Pyth-Port.
Geben Sie die Liste über STDIN ein, z
[[4, 3, 5, 2, 1], [5, 4, 1, 3, 2], [1, 5, 2, 4, 3], [2, 1, 3, 5, 4], [3, 2, 4, 1, 5]]
.Online ausprobieren ... würde ich sagen, aber aus Sicherheitsgründen erlaubt der Online-Interpreter die Verwendung von eval in geschachtelten Klammern nicht. Probieren Sie
JcQ5V4=J_CJ~Yml{meS<dhkUd_J)Y
stattdessen den Umgehungscode aus und geben Sie ihn als abgeflachte Liste wie folgt ein[4, 3, 5, 2, 1, 5, 4, 1, 3, 2, 1, 5, 2, 4, 3, 2, 1, 3, 5, 4, 3, 2, 4, 1, 5]
.(Danke an @isaacg, der ein paar Bytes beim Golfen geholfen hat)
quelle
<
und>
sind die einseitigen Slice-Operatoren,:d0hk
die sich also verwandeln lassen<dhk
.U
auf Sammlungseingaben ist das gleiche wieUl
,Uld
kann also in verwandelt werdenUd
.CJam,
2927 BytesEingabe wie
Ausgabe wie
Wie es funktioniert
Die Grundidee ist, dass der Code entlang der Zeilen arbeitet und das Raster viermal gegen den Uhrzeigersinn dreht. Um die Türme zu zählen, hebe ich jeden Turm so weit an, dass es keinen "visuellen Unterschied" macht (dh ändere ihn nicht, wenn er sichtbar ist, oder ziehe ihn auf die gleiche Höhe des Turms vor es), und dann zähle ich verschiedene Höhen.
quelle
APL, 44
Hier getestet.
quelle
J, 35 Zeichen
Beispiel:
Probieren Sie es hier aus.
quelle
Haskell, 113
quelle
Mathematica,
230,120,116,113,110 BytesVerwendung:
quelle
a[[y]][[x]]
ista[[y,x]]
. Und mitArray
könnte kürzer sein alsTable
.JavaScript,
335264256213In der JavaScript-Konsole des Browsers auswerten (ich habe Firefox 34.0 verwendet, scheint in Chrome 39 nicht zu funktionieren?) Testen mit:
Hier ist die aktuelle Inkarnation des ungolfed Codes - es wird schwieriger zu folgen:
Ich habe absichtlich keine der anderen Antworten angeschaut, ich wollte sehen, ob ich selbst etwas ausarbeiten kann. Mein Ansatz bestand darin, die Eingabearrays auf ein eindimensionales Array zu reduzieren und die Offsets für die Zeilen aus allen vier Richtungen vorab zu berechnen. Dann habe ich mit der Umschalttaste nach rechts getestet, ob der nächste Turm falsch war, und wenn ja, den Zähler für jede Zeile erhöht.
Ich hoffe, es gibt viele Möglichkeiten, dies zu verbessern, vielleicht die Offsets nicht vorab zu berechnen, sondern eine Art Überlauf / Modulo auf dem 1D-Eingangsarray zu verwenden. Und vielleicht meine Schleifen kombinieren, funktionaler werden, deduplizieren.
Anregungen wäre dankbar!
Update Nr. 1 : Fortschritt, wir haben die Technologie! Ich war in der Lage, die vorberechneten Offsets loszuwerden und sie in Übereinstimmung mit aneinander gereihten ternären Operatoren auszuführen. War auch in der Lage, meine if-Anweisung loszuwerden und die for-Schleifen in whiles umzuwandeln.
Update Nr. 2 : Das ist ziemlich frustrierend. Keine Pizza Party für mich. Ich dachte, funktionstüchtig zu werden und Rekursion zu verwenden, würde viele Bytes einsparen, aber meine ersten Versuche endeten damit, dass sie um bis zu 100 Zeichen größer waren! In meiner Verzweiflung habe ich mich voll und ganz darauf konzentriert, ES6-Fettpfeilfunktionen zu verwenden, um es wirklich zu reduzieren. Dann habe ich mich daran gemacht, boolesche Operatoren durch arithmetische zu ersetzen und Parens, Semikolons und Leerzeichen zu entfernen, wo immer ich konnte. Ich habe sogar aufgehört, meine Variablen zu deklarieren, und den globalen Namespace mit meinen lokalen Symbolen verschmutzt. Dreckig, dreckig. Nach all diesen Anstrengungen habe ich meine Punktzahl für Update 1 um satte 8 Zeichen auf 256 geschlagen. Blargh!
Wenn ich die gleichen skrupellosen Optimierungen und ES6-Tricks auf meine Update Nr. 1-Funktion anwenden würde, würde ich diese Punktzahl um eine Meile übertreffen. Ich kann ein Update # 3 durchführen, um zu sehen, wie das aussehen würde.
Update Nr. 3 : Es stellte sich heraus, dass der rekursive Ansatz mit fetten Pfeilen viel mehr Leben in sich birgt. Ich musste nur direkt mit der zweidimensionalen Eingabe arbeiten, anstatt sie zu verflachen, und mich besser mit der Nutzung der Schließbereiche befassen. Ich habe die Berechnung des inneren Array-Offsets zweimal umgeschrieben und dabei die gleiche Punktzahl erhalten, sodass dieser Ansatz möglicherweise kurz vor der Minimierung steht.
quelle
Nur Java
352350325 Bytes ...Eingabe wie
43521 54132 15243 21354 32415
Ausgabe wie:
23145343211222233212
Eingerückt:
Alle Tipps wäre sehr dankbar!
quelle
for
Schleifenfor(;i<n;i++)
zufor(;++i<n;)
und initialisiereni
zu-1
. Dann benutze diese, um Sachen zu machen. Sie können dasselbe auch mit der anderen Schleife tun.a[i].charAt(j)-'0'
anstelle des expliziten Parsens verwenden. Dies erfordert auch keine Begrenzer in der Eingabe (macht das Eingabeformat eher wie das Ausgabeformat).for
-loops immer etwas Nützliches in den Teil "loop increment" einfügen. Dadurch wird der Code dunkler und ein Semikolon wird entfernt. Zum Beispiel:for(j=n;j-->0;System.out.print(c))
.Python 2 - 204 Bytes
Dies ist wahrscheinlich ein sehr schlechtes Golf. Ich fand das Problem interessant und beschloss, es anzugehen, ohne die Lösung eines anderen zu suchen. Während ich diesen Satz schreibe, muss ich mir noch die Antworten auf diese Frage ansehen. Es würde mich nicht wundern, wenn jemand anderes bereits ein kürzeres Python-Programm gemacht hätte;)
E / A-Beispiel
Sie können optional Leerzeichen in die Eingabe einfügen. Ehrlich gesagt so ziemlich überall. Solange du es kannst
eval()
, wird es funktionieren.Erläuterung
Der einzig interessante Teil dieses Programms ist die erste Zeile. Es definiert eine Funktion
f(l)
, die angibt, wie viele Türme in einer Reihe zu sehen sind, und der Rest des Programms wendet diese Funktion nur auf jede mögliche Position an.Beim Aufruf wird die Länge von ermittelt
l
und in einer Variablen gespeichertn
. Dann erstellt es eine neue Variablek
mit diesem ziemlich monströsen Listenverständnis:Es ist nicht so schlimm, wenn du es kaputt machst. Da
n==len(l)
steht alles vor demif
Gerechtenl
. Mit könnenif
wir jedoch einige Elemente aus der Liste entfernen. Wir konstruieren eine Liste mit([0]+list(l))
, die nur "l
mit einem0
am Anfang angefügten" ist (ignorieren Sie den Aufruf vonlist()
, das ist nur dort, weil manchmall
ein Generator ist und wir sicherstellen müssen, dass es tatsächlich eine Liste hier ist).l[c]
wird nur in die endgültige Liste aufgenommen, wenn sie größer als ist([0]+list(l))[c]
. Das macht zwei Dinge:l[c]
wirdc+1
. Wir vergleichen effektiv jedes Element mit dem Element links davon. Wenn es größer ist, ist es sichtbar. Andernfalls wird es ausgeblendet und aus der Liste entfernt.[0]+
Unsinn und nur im Vergleichl[c]
zul[c-1]
, würde Python den ersten Turm bis zum letzten vergleichen (können Sie Index in eine Liste von dem Ende mit-1
,-2
etc.), so dass , wenn der letzte Turm höher war als die Als erstes würden wir das falsche Ergebnis bekommen.Wenn alles gesagt und getan ist,
l
enthält es einige Türme undk
enthält jeden der Türme , der nicht kürzer ist als sein unmittelbarer Nachbar links. Wenn keiner von ihnen war (zB fürf([1,2,3,4,5])
), dannl == k
. Wir wissen, dass es nichts mehr zu tun und zurückzukehren gibtn
(die Länge der Liste). Inl != k
diesem Fall wurde diesmal mindestens einer der Türme entfernt, und möglicherweise ist noch mehr zu tun. Also kehren wir zurückf(k)
. Gott, ich liebe Rekursion. Interessanterweisef
taucht immer eine Ebene tiefer auf, als es unbedingt "notwendig" ist. Wenn die Liste, die zurückgegeben wird, generiert wird, kann die Funktion dies zunächst nicht wissen.Als ich anfing, diese Erklärung zu schreiben, war dieses Programm 223 Bytes lang. Während ich die Dinge erklärte, wurde mir klar, dass es Möglichkeiten gibt, Zeichen zu speichern. Ich bin froh, dass ich das geschrieben habe! Das größte Beispiel ist, dass
f(l)
es ursprünglich als Endlosschleife implementiert wurde, die beim Ausführen der Berechnung ausgebrochen wurde, bevor mir klar wurde, dass eine Rekursion funktionieren würde. Es zeigt nur, dass die erste Lösung, an die Sie denken, nicht immer die beste sein wird. :)quelle
Matlab,
(123)(119)wie folgt verwendet:
C # bis 354 ...
Anderer Ansatz als TheBestOne.
quelle
\n
sieht so aus, als würden Sie anstelle von Zeilenumbrüchen einen Computer einfügen. Ich habe sie nur durch Leerzeichen ersetzt, sodass der Code sofort ausgeführt wird, wenn jemand ihn kopiert. Und ich habe mir erlaubt, die letzte zu löschenend
(die die Funktion schließt, was nicht notwendig ist), die zusätzliche 4 Zeichen speichert, ich hoffe, das war ok =)end
, danke :)