Herausforderung
Suchen Sie einen höchstens 100 Byte langen Ausdruck mit der längsten Typensignatur.
Regeln
- Jede statisch typisierte Sprache mit Typinferenz ist zulässig
- Der Typ muss nicht mehrdeutig sein, kann aber ansonsten Typen ohne definierte Instanzen enthalten. Zum Beispiel
Num [a]
undEq [a]
sind erlaubt, auch ohne definierte Instanz - Keine anderen Importe als das zum Kompilieren eines Programms mit STDIN / STDOUT erforderliche Minimum
- Unendliche Typen sind nicht erlaubt
- Wenn eine Antwort mehr als einen Ausdruck enthält, kann nur einer zur Bewertung beitragen. Obwohl die Typensignatur der Komposition
(.) :: (b -> c) -> (a -> b) -> a -> c
eine Punktzahl von 20 aufweist, hätte die Antwort mit 25 Kopien von(.)\n
beispielsweise eine Punktzahl von 20 und nicht von 500 - Der Ausdruck darf höchstens 100 Bytes umfassen
- Die Punktzahl gibt die Anzahl der Zeichen in der Typensignatur ohne den Namen der Funktion und Leerzeichen an. Zum Beispiel
f :: (a -> b) -> a -> b
hätte eine Punktzahl von 12 - Die höchste Punktzahl gewinnt!
Beispiele
Obwohl andere Sprachen zulässig sind, befinden sich die folgenden Beispiele in Haskell:
Score: 112
map.map.map.map.map.map.map.map.map.map.map.map.map.map.map.map.map.map.map.map.map.map.map.map.map
f :: (a -> b)
-> [[[[[[[[[[[[[[[[[[[[[[[[[a]]]]]]]]]]]]]]]]]]]]]]]]]
-> [[[[[[[[[[[[[[[[[[[[[[[[[b]]]]]]]]]]]]]]]]]]]]]]]]]
Score: 240
(.).(.).(.).(.).(.).(.).(.).(.).(.).(.).(.).(.).(.).(.).(.).(.).(.).(.).(.).(.).(.).(.).(.).(.).(.)
f :: (b->c)->(a->a1->a2->a3->a4->a5->a6->a7->a8->a9->a10->a11->a12->a13->a14->a15->a16->a17->a18->a19->a20->a21->a22->a23->a24->b)->a1->a2->a3->a4->a5->a6->a7->a8->a9->a10->a11->a12->a13->a14->a15->a16->a17->a18->a19->a20->a21->a22->a23->a24->c
Score: 313
foldl$foldl$foldl$foldl$foldl$foldl$foldl$foldl$foldl$foldl$foldl$foldl$foldl$foldl$foldl$foldl(.)
f :: (Foldable t, Foldable t1, Foldable t2, Foldable t3, Foldable t4,
Foldable t5, Foldable t6, Foldable t7, Foldable t8, Foldable t9,
Foldable t10, Foldable t11, Foldable t12, Foldable t13,
Foldable t14, Foldable t15) =>
(b -> c)
-> t (t1 (t2 (t3 (t4 (t5 (t6 (t7 (t8 (t9 (t10 (t11 (t12 (t13 (t14 (t15 (b
-> b))))))))))))))))
-> b
-> c
Score: 538
lex.show.foldl1.mapM.traverse.sum.mapM.sum.traverse.(.).mapM.scanl.zipWith3((.traverse).(.traverse))
(Num
(a -> ([[c]] -> t3 [[a1 -> f b]]) -> [[c]] -> t3 [[a1 -> f b]]),
Num
(([[c]] -> t3 [[a1 -> f b]])
-> t1 (t2 ([[c]] -> t3 [[a1 -> f b]]))
-> [[c]]
-> t3 [[a1 -> f b]]),
Show
(t (t1 (t2 ([[c]] -> t3 [[a1 -> f b]])))
-> t1 (t2 ([[c]] -> t3 [[a1 -> f b]]))),
Applicative f, Foldable t,
Foldable ((->) (t1 (t2 ([[c]] -> t3 [[a1 -> f b]])) -> a)),
Foldable
((->) (([[c]] -> t3 [[a1 -> f b]]) -> a -> t3 [a1 -> f b])),
Traversable t1, Traversable t2, Traversable t3, Traversable t4,
Traversable t5,
Traversable ((->) (t1 (t2 ([[c]] -> t3 [[a1 -> f b]])))),
Traversable ((->) ([[c]] -> t3 [[a1 -> f b]]))) =>
[(t5 (t4 a1) -> f (t5 (t4 b))) -> c -> a1 -> f b]
-> [(String, String)]
code-challenge
busy-beaver
functional-programming
Michael Klein
quelle
quelle
Antworten:
Haskell, ~ 2 ^ (2 ^ 18)
Bei jeder Anwendung wird die
f
Typensignatur ungefähr verdoppelt, indem die TypensignaturT
in umgewandelt wird(T,T)
. Zum Beispiel hat die vierfache Zusammensetzungf.f.f.f$0
einen TypJede Zeile vervierfacht die Anzahl der Bewerbungen
f
und gibt4^9 = 2^18
am Ende an. Die Typensignatur hat also eine Größe in der Größenordnung von2^(2^18)
.quelle
f x=(x,x,x)
auf Kosten von einemn.
in der letzten Zeile die optimale Punktzahl für diese Gesamtstruktur ergibt.n.
größer wird.2^18
vs, es3 * (2^16)
sei denn, ich habe einen Fehler bei der Berechnung der ursprünglichen Exponentiation gemacht:2^(4^9)
vs.3^((4^8)*3)
(,)
(oder(,,)
) kann verwendet werden, um einige Bytes zu speichern und die Punktzahl zu verbessern, indem mehrn
s verwendet werden.Java, Punktzahl 17301488
Erfordert die Methode
<T>java.util.Map<T,T>f(T t){return null;}
, die auf das 100-Byte-Limit angerechnet wurde.f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(1)))))))))))))))))))
Die Signatur dieses Typs zur Kompilierungszeit sollte mit dieser übereinstimmen .
quelle
Haskell mit Erweiterungen,⋙ A ( A ( A ( A ( 220 , 0 ) , 0 ) , 0 ) , 0 )
Probieren Sie es online!
Erfordert
-XDataKinds
,-XPolyKinds
,-XTypeOperators
,-XUndecidableInstances
, und-XTypeFamilies
.Vielen Dank an Ørjan Johansen, der erkannt hat, dass durch das Einfügen des natürlichen Zahlenkonstruktors und das etwas andere Bilden der Argumente zwei Bytes gespart wurden und gerade genug Platz für eine weitere Iteration von
#
.Offensichtlich gibt die Typprüfung den Versuch auf, dieses Programm zu prüfen. Um einen allgemeinen Eindruck davon zu bekommen, wie die Signatur aussehen würde (wenn sie klein genug wäre, um in das beobachtbare Universum zu passen), probieren Sie die viel kleinere aus
Erläuterung
DieEIN wird,
#
Typfamilie ist eng mit der Ackermann-Péter-Funktion verwandt , die üblicherweise als#
wächst jedoch erheblich schneller. Die Ackermann-Péter-Funktion ist definiert#
Andererseits können wirNur der zweite Fall ist anders. Der Abschlussnachweis ist identisch mit dem Standardnachweis fürEIN , und es sollte klar sein, dass B ( m , n ) ≥ A ( m , n ) für alle m und n .
Hier berechnen wir eine unäre Darstellung von
Durch direkte Berechnung wirdB ( B ( B ( B ( 0 , 0 ) , 0 ) , 0 ) , 0 ) = 220 , so
Man beachte , dassA ( A ( A ( A ( 0 , 0 ) , 0 ) , 0 ) , 0 ) ist nur5 , so dass wirDinge ein gutes Stück gestoßen haben aus zu starten. Ich habe keine klare Vorstellung davon, wie viel schnellerB wächst alsEIN , aber wenn man bedenkt, wie die Berechnung abläuft, ist es wahrscheinlich, dass esviel schnellerwächst.
Die Anzahl der Stellen in einem geradenA ( 6 , 0 ) ist zu groß, um praktisch als Dezimalzahl ausgedrückt zu werden. Das ist also ... ziemlich lächerlich.
Die Definition der natürlichen Zahlen
(?)
ist etwas ungewöhnlich. Um Platz zu sparen, verwenden wir(?)
sowohl einen natürlichen Zahlentyp (auf Typebene) als auch einen Proxy-Typ (auf Begriffsebene).Ich glaube, dass entweder
TypeFamilies
oder (ausführlicher und verschleierter)FunctionalDependencies
notwendig sind, um die Berechnung auf Typebene zu erhalten, die erforderlich ist, um wirklich große Typen zu erreichen.UndecidableInstances
wird benötigt, um die sehr primitive Terminierungsprüfung von Haskell zu umgehen. Die anderen Erweiterungen werden nur benötigt, um den Code auf den kleinen verfügbaren Platz zu komprimieren.quelle
#Z
Z
besser s vorne als mit zu beginnenS(S Z)#S Z
, oder dasselbe?#Z
am Ende sehr willkommen.?
das andere zu speichern, so dass Platz für zusätzliche Daten bleibt#Z
.A(m,1)
es nie größer war alsA(A(m,0),0)
und dass ich mich gerade dazu äußern wollte, aber dann haben Sie nur optimiert, bis die Optionen gleich waren. (Ist auchm+1
nie größer alsA(m,0)
.)Haskell, 9,2 663552-3 (≈ 1,02 · 10 199750 )
Eine kleine Verbesserung gegenüber xnors 5⋅2 262144 + 5 . Das sind 99 Bytes.
Wie es funktioniert
Wir haben
und so weiter, wobei sich die Länge für jeden ungefähr verdoppelt
(:)
. Der angegebene Ausdrucko.o.o
funktioniert(:).(:).(:).….(:)
mit 2 · 4 6 · 3 4 = 663552 Kopien von(:)
.Haskell mit
FlexibleContexts
undNoMonomorphismRestriction
(200 · 4 331776 + 75 · 331776 + 16) / 9 · 2,53 · 10 199750Eine kleine Verbesserung gegenüber Bubbler's 12 · 2 663552 + 9 · 663552 - 4 · 1,36 · 10 199750 , die ebenfalls auf diesen Erweiterungen beruht. Der Wortlaut der Herausforderung legt nahe, dass es in Ordnung sein könnte, sich auf sie zu verlassen („Zum Beispiel
Num [a]
undEq [a]
erlaubt, auch ohne definierte Instanz“). Ich bin mir nicht sicher. Das sind 100 Bytes.Wie es funktioniert
Wir haben
und so weiter, wobei sich die Länge für jedes ungefähr vervierfacht
(/).(:)
. Der angegebene Ausdruck-o.o.o
funktioniert-(/).(:).(/).(:).….(/).(:)
mit 4 6 · 3 4 = 331776 Kopien von(/).(:)
.quelle
Haskell, 12,2 663552 + 9 · 663552 - 4
Noch eine kleine Verbesserung gegenüber Anders Kaseorgs Antwort .
Wie es funktioniert
Gerade geänderte Funktionszusammensetzung
(.)
in Bruchteilung(/)
. DerFractional x
Teil in der Funktionssignatur explodiert zusammen mit dem Hauptteil und ergibt einen etwas höheren konstanten Multiplikator.quelle
C 979
f
hat die Unterschrift:quelle
C ++ 11, nicht konkurrierend
Ich kaum kann es unter 100 Bytes bringen, aber es ist so nah, dass ich dachte, ich könnte es trotzdem posten, in der Hoffnung, dass jemand eine Optimierung entdeckt.
Dies ist der Prolog, der 93 Bytes kostet:
Und der Ausdruck, 9 Bytes:
Um zu veranschaulichen:
Jedes Mal, wenn die Zahl zunimmt, wird sie ungefähr verdoppelt.
quelle
class
anstelle von verwendetentypename
. Ich frage mich, ob es irgendwo einen Compiler gibt, der diese Phrasierung aus Gründen der Abwärtskompatibilität noch unterstützt.C #, 363
Ausdruck:
Typ Unterschrift:
Probieren Sie es online!
quelle
Gehen Sie 1.0 ohne
reflect
98Go 1.x-Typen sind statisch definiert. Hier ist mein erster Versuch:
Auf dem Go-Spielplatz :
Go 1.9 mit Typ-Aliasnamen, 2389
Auf dem Go-Spielplatz :
Ergebnis:
Gehe 1 mit
reflect
, 65532Es gibt eine Grenze im Paket
reflect
von der Länge der Typennamen:len(name) <= 1<<16-1
Bisher konnte ich mit diesem Block einen Typnamen von 65532 Bytes erreichen:
Vollständiger Code auf dem Go-Spielplatz :
Anmerkungen:
x:=
wird nie gezählt.quelle
reflect
Import müsste gezählt werdenIdris,> hyper (hyper (hyper (hyper (999999999, 99, 99), 99,99), 99,99), 99,99)
Erläuterung:
Wir definieren eine Funktion f, wobei die Berechnung eines Typs f (0) nur der Einheitentyp ist, während f (S (n)) den Gleichheitstyp berechnet, der auf das Funktionsargument angewendet wird, das von sich aus "hypered" ist, und auf f, das auf n angewendet wird . Die letzte Zeile ist im Grunde eine Funktion, die einen Wert eines Typs wie (27 = (4 = (2 = (1 = ())))) (für n = 4) erwartet.
Einfaches Beispiel
quelle
:Type
?hyper
; könntest du erklären?hyper
enorm mehr als der Rest verstärkt wird, denke ich, dass Sie wollen, dass alle / die meisten von denen99
s9
s sind. (3) Angenommen, Idris$
arbeitet wie Haskell, ist die äußere Klammer nachf$
überflüssig. (4) Könnten Sie abkürzenhyper
oder würde dies eine Typensignatur selbst erfordern?Haskell, 782
Ausdruck:
Typ Unterschrift:
quelle
sum
dann ist(Num a, Foldable t) => t a -> a
Ceylon, 38843546786070481 (~ 4 · 10 16 )
Dies sind 49 verschachtelte Ein-Tupel mit einem leeren Tupel im Innersten. Der Kurzname dieses Typs entspricht in diesem Fall dem Wert, der vollständig erweiterte Name ist jedoch viel länger.
Der Ceylon-Compiler arbeitet ununterbrochen, wenn er versucht, dies zu kompilieren (der Compiler lief noch nach 180 Minuten). Ich muss versuchen, die theoretische Typlänge zu berechnen.
Das Problem hierbei ist, dass ein Ein-Element-Tupel-Typ
[X]
in Ceylons Typsystem tatsächlich dargestellt wird alsTuple<X, X, []>
(der erste Parameter ist ein Supertyp für alle Elementtypen, der zweite ist der Typ des ersten Elements und der dritte der Typ aller mit Ausnahme der ersten Elemente Dies ist hier ein leeres Tupel (dasempty
Objekt, die einzelne Instanz, die die Schnittstelle erfülltEmpty
).So
[]
istempty
,[[]]
istTuple<[], [], []>
=Tuple<empty, empty, empty>
,[[[]]]
istTuple<[[]], [[]], []>
=Tuple<Tuple<[], [], []>, Tuple<[], [], []>, []>
. Und der vollständige Name enthält die Paketnamen, so dass wir eigentlichceylon.language::Tuple<ceylon.language::Tuple<ceylon.language::empty, ceylon.language::empty, ceylon.language::empty>, ceylon.language::Tuple<ceylon.language::empty, ceylon.language::empty, ceylon.language::empty>, ceylon.language::empty>
nur für drei Ebenen haben. Und wir wollen zu 50 gehen.Da
ceylon.language::empty
22 Zeichen lang sind und jedesceylon.language::Tuple<?,?,ceylon.language::empty>
47 zu dem doppelten Ergebnis des vorherigen Schritts addiert, erhalten wirf(1) = 22
undf(n) = 2 · f(n-1) + 47
. Dies vereinfacht sichf(n) = 69 · 2^(n - 1) - 47
, und die Eingabe von 50 ergibt 38843546786070481. Natürlich ist dies viel größer als das, was in den Speicher meines Computers passen würde (8 · 10 9 Bytes).Natürlich könnte der Compiler klug sein und nicht versuchen, den gesamten Typnamen im Speicher zu haben, bis sein Name angefordert wird.
Hier ist das vollständige Programm, das versucht, den Typ zu drucken:
quelle
C # (Visual C # Interactive Compiler) , 99 Byte, Score 841
Probieren Sie es online!
Ausgänge
quelle