Herausforderung
Origami (Faltpapier) ist eine kreative Kunstform. Soweit ich weiß, bevorzugt der Meister von Origami Karopapier. Beginnen wir von vorne - wandeln Sie ein rechteckiges Papier in ein quadratisches um.
Das Papier ist also in Quadrate unterteilt. Schritt für Schritt entfernen wir das größte Quadrat, das eine kürzere Kante mit der aktuellen Form teilt (siehe Bild unten). Wenn der verbleibende Teil nach einem Schritt kleiner oder gleich ist 0.001 * (area of the original paper)
, kann das Papier nicht weiter geteilt werden. Es ist möglich, dass endlich nichts mehr übrig bleibt.
Ihre Aufgabe ist es, zu berechnen, wie viele Quadrate während des Prozesses erstellt werden. Das Quadrat im letzten Schritt, durch das das Papier nicht mehr geteilt werden kann, wird in die Ausgabe einbezogen.
Beispiel (ein Papier mit 1.350
Breite / Höhe), Ausgabe ist 10:
Ein- und Ausgang
Eingabe: Breiten- / Höhenverhältnis für das rechteckige Papier, eine Dezimalstelle (oder eine Ganzzahl ohne Punkt) von 1.002
bis 1.999
mit einem minimalen Schritt von 0.001
. Sie können auch jedes andere vernünftige Format verwenden, das das Verhältnis beschreibt. Erwähne es einfach in deiner Antwort.
Ausgabe: Quadratzahl, eine ganze Zahl.
Beispiel I / O
Ein Zuordnungsformat wird verwendet, um die Seite aufgeräumt zu halten, während Ihr Code weder eine Listeneingabe unterstützen noch eine Zuordnungsfunktion sein muss.
1.002 => 251
1.003 => 223
1.004 => 189
1.005 => 161
1.006 => 140
1.007 => 124
1.008 => 111
1.009 => 100
Dank @LuisMendo sehen Sie hier die Antwortgrafik.
Bemerkungen
- Dies ist ein Code-Golf, also gewinnt der kürzeste Code
- Achten Sie auf Standardlücken
- Sie können frei entscheiden, wie Sie mit Ein- und Ausgängen umgehen möchten, sie sollten jedoch den Standardbeschränkungen folgen.
Apropos...
- Kommentar, wenn Sie etwas Unklares über die Herausforderung haben
- Persönlich würde ich vorschlagen, dass Ihre Antwort eine Erklärung enthält, wenn Sie eine Golfsprache verwenden
- Dank @ GregMartin, lesen Sie seine Antwort für eine gute mathematische Erklärung für die Herausforderung.
Beispielcode
Hier ist eine ungolfed Version von C ++ Code:
#include <iostream>
#include <utility>
int f (double m)
{
double n = 1, k = 0.001;
int cnt = 0;
k *= m; // the target minimum size
while(m*n >= k)
{
m -= n; // extract a square
if(n > m)
std::swap(n, m); // keep m > n
++ cnt;
}
return cnt;
}
int main()
{
double p;
std::cin >> p;
std::cout << f(p);
return 0;
}
Alle im Beispielcode enthaltenen Berechnungen benötigen eine Genauigkeit von 6 Dezimalstellen, die in behandelt wird float
.
Antworten:
MATL , 19 Bytes
Die Eingabe ist ein Array, in dem die beiden Zahlen das ursprüngliche Verhältnis definieren, z
[1, 1.009]
. (Es ist nicht erforderlich, dass die Nummern sortiert sind oder dass eine davon 1 ist.)Probieren Sie es online!
Erläuterung
quelle
Haskell ,
71 70 65 63 62 61 5856 BytesVielen Dank an @xnor für einige geniale Verbesserungen!
Probieren Sie es online!
quelle
m==n
am Ende sein,1>0
weil es die einzige verbleibende Möglichkeit ist. Oder vielleicht könnten die Fälle neu angeordnet werden, um hier eine Bindung zu ermöglichen.n>m
erweitertn>=m
und der erste Scheck geschriebene>m*n*1000
wird, sollte dies1
für Gleichheit sorgen.(n#m)e|e>n*m*1e3=0|n<m=m#n$e|d<-n-m=(d#m)e+1;n!m=n#m$n*m
d<-n-m
wie esotherwise
ist wirklich ordentlich !!!JavaScript (ES6),
59-58BytePrüfung
Code-Snippet anzeigen
quelle
Mathematica, nicht konkurrierend (21 Bytes)
Diese Antwort ist nicht konkurrierend, da sie die tatsächlich gestellte Frage nicht beantwortet! Aber es beantwortet eine Variante der Frage und liefert eine Entschuldigung, um einige interessante Mathematik aufzuzeigen.
Symbolische Funktion, die eine positive rationale Zahl als Eingabe verwendet (deren Zähler und Nenner die Abmessungen des Originalpapiers darstellen) und eine positive ganze Zahl zurückgibt. Zum Beispiel
Tr@*ContinuedFraction[1350/1000]
kehrt zurück10
. (ContinuedFraction
Wirkt aufgrund von Genauigkeitsproblemen anders auf Gleitkommazahlen, weshalb in diesem Kontext eine rationale Zahl als Eingabe benötigt wird.)Eine interessante Interpretation des in dem Problem beschriebenen geometrischen Verfahrens (wiederholtes Abschneiden von Quadraten von einem Rechteck) ist, dass es sich um eine Implementierung des euklidischen Algorithmus handelt, um die größten gemeinsamen Teiler zu finden! Betrachten Sie das Beispiel in der Frage selbst mit Verhältnis
1.35
, die durch ein Stück Papier mit den Maßen (1350, 1000) modelliert werden könnte. Jedes Mal, wenn ein Quadrat abgeschnitten wird, wird die kleinere Zahl von der größeren Zahl abgezogen. Die resultierenden Rechtecke in diesem Beispiel haben also die Dimensionen (350, 1000), dann (350, 650), dann (350, 300), dann (50, 300), dann (50, 250) und (50, 200) und (50, 150) und (50, 100) und (50, 650). 50) und auch (50,0), sobald wir das letzte Quadrat von sich wegnehmen. Genau so funktioniert der euklidische Algorithmus (Modulo der Differenz zwischen Division und wiederholter Subtraktion), und tatsächlich sehen wir, dass 50 tatsächlich die GCD von 1350 und 1000 ist.Typischerweise verfolgt man im euklidischen Algorithmus diese Zwischendimensionen und verwirft die Anzahl der Subtraktionen. Man kann jedoch abwechselnd aufzeichnen, wie oft wir eine Zahl von der anderen subtrahiert haben, bevor die Differenz zu klein wird, und wir müssen umschalten, was wir subtrahieren. Diese Aufzeichnungsmethode ist genau der fortgesetzte Bruchteil einer rationalen Zahl. (Fortgesetzte Brüche von irrationalen Zahlen, die niemals enden, sind auch super cool, aber hier nicht relevant.) Zum Beispiel haben wir im Beispiel 1350/1000 1000-
1
mal, dann 350-2
mal, dann 300-1
mal, dann 50-6
mal subtrahiert ; daher ist der fortgesetzte Bruchteil von 1350/1000{1,2,1,6}
. Mathematisch haben wir 1350/1000 umgeschrieben als1
+ 1 / (2
+ 1 / (1
+ 1 /6
)), die Sie überprüfen können.Wenn Sie für dieses Problem nicht anhalten, wenn die Quadrate kleiner als ein bestimmter Schwellenwert werden, sondern einfach alle endlich vielen Quadrate zählen, bevor sie anhalten, entspricht die Gesamtzahl der Quadrate der Gesamtzahl der Subtraktionen die Summe aller ganzen Zahlen im fortgesetzten Bruch - und genau das
Tr@*ContinuedFraction
berechnet die Zusammensetzung der Funktionen ! (Für das gegebene Beispiel 1.35 erhält es die Antwort, die das OP wünscht, weil das letzte Quadrat groß genug ist, dass alle Quadrate gezählt wurden. AberTr@*ContinuedFraction[1001/1000]
zum Beispiel ergibt es1001
, weil es das eine große Quadrat und alle 1000 der kleinen 1x1000 Quadrate zählt .)quelle
Mathematica,
6453 BytesEine Imperativlösung (C-Stil) hat genau die gleiche Länge:
quelle
C (GCC / Clang),
6159 BytesDie Eingabe erfolgt über zwei Ganzzahlen (Breite und Höhe) ohne Punkt, z
f(1999,1000)
.Ich hoffe, jemand konnte ein Byte speichern, indem er C in den 58-Byte-Club drückte. ;)
quelle
m-=n
C 59 Bytes
Probieren Sie es online
Die Eingabe ist eine Ganzzahl, die das Verhältnis von Breite zu Höhe in Tausendstel angibt (z. B. 1002 für 1.002: 1).
Ungolfed-Version
quelle