Toilettenpapier-Geheimnisse

36

Heute müssen Sie ein sehr praktisches Problem lösen: Wie viele Schleifen benötigen Sie, um eine bestimmte Anzahl von Blättern auf Ihrer Toilettenpapierrolle zu haben? Schauen wir uns einige Fakten an:

  • Der Durchmesser eines bloßen Toilettenpapierzylinders beträgt 3,8 cm
  • Die Länge eines Blattes Toilettenpapier beträgt 10 cm.
  • Die Dicke eines Blattes Toilettenpapier beträgt 1 mm.

Bevor Sie den Zylinder zum ersten Mal umwickeln, hat er einen Umfang in cm von 3,8 * pi. Jedes Mal, wenn Sie ein Blatt um den Zylinder wickeln, vergrößert sich sein Radius um 0,1, daher vergrößert sich sein Umfang um 0,2 * PI. Verwenden Sie diese Informationen, um herauszufinden, wie viele Schlaufen für n Blatt Toilettenpapier erforderlich sind. (Hinweis: Verwenden Sie eine Näherung von Pi, die mindestens so genau wie 3.14159 ist.)

Testfälle :

n = 1 :

  • 10 / (3,8 * pi) = 0,838 Schleifen

n = 2 :

  • (Wie viele Vollschleifen können wir machen?) 1 Vollschleife = 3,8 * pi = 11,938.
  • (Wie viel haben wir nach der 1. Runde übrig?) 20 - 11.938 = 8.062
  • (Wie viel von einer zweiten Schleife macht das verbleibende Stück?) 8.062 / (4 * pi) = .642 Schleifen
  • Antwort: 1.642 Schleifen

n = 3 :

  • 1. volle Schleife = 3,8 * pi = 11,938, 2. volle Schleife = 4 * pi = 12,566
  • 30 - 11,938 - 12,566 = 5,496
  • 5,496 / (4,2 * pi) = 0,417
  • Antwort: 2.417 Schleifen

n = 100 => 40,874

Geokavel
quelle
35
Puh! 1mm dick? Sind Sie sicher, dass Sie Toilettenpapier und keinen Karton verwenden?
Digitales Trauma
11
@DigitalTrauma Natürlich wissen Sie nichts über Triple-Ply: p
Geokavel
2
Unter der Annahme, dass das Toilettenpapier keine Schritte macht, sondern den Radius kontinuierlich vergrößert, können Sie eine geschlossene Formularannäherung an das angeforderte Ergebnis erhalten. Ist das gut genug nloops = sqrt(n+11.34)*0.0564189 - 0.19
Fehler
2
Vorgeschlagener Testfall: 100->40.874
Dennis
1
Dreifachkarton ?! Nun das ist dick!
mbomb007

Antworten:

13

Pyth, 27 23 Bytes

+fg0=-QJc*.n0+18T50)cQJ

Probieren Sie es online aus. Testsuite.

Erläuterung

                            Q = input number (implicit)
 f                 )        increment T from 1, for each T:
             +18T             add 18 to T, get radius
         *.n0                 multiply by pi to, get half the circumference
        c        50           divide by 50, get circumference in sheets
       J                      save it to J
    =-Q                       decrement Q by it
  g0                          use this T if Q is now <= 0
+                           add
                     Q        Q (now <= 0)
                    c J       divided by J (the last circumference)
                            and print (implicit)
PurkkaKoodari
quelle
erklärung bitte
Conor O'Brien
@ CᴏɴᴏʀO'Bʀɪᴇɴ Hinzugefügt. Pyth zu erklären macht immer so viel Spaß.
PurkkaKoodari
2
Ihre Erklärung sieht aus wie eine mögliche Ausgabe für Surfin 'Word
Geokavel
10

Haskell, 59 46 44 Bytes

Ein Skalierungsfaktor von 5 / pi wird angewendet, so dass ein Papierzylinder einen Umfang von 19,20,21 ... cm hat und ein Bogen 50 / pi cm ist.

2 Bytes dank xnor mit einer unbenannten Funktion eingespart.

x!s|s>x=1+(x+1)!(s-x)|1>0=s/x
(19!).(50/pi*)
Damien
quelle
Eine ziemlich rekursive Methode. Beachten Sie, dass unbenannte Funktionen auch dann zulässig sind, wenn Sie andere Zeilen haben (obwohl Haskell dies nicht unterstützt), sodass die letzte Zeile als ohne Punkt angegeben werden kann (19!).(50/pi*).
Xnor
Wow, bläst meine Annäherung aus dem Wasser!
CR Drost
5

Haskell, 97 Bytes

p&((m,x):(n,y):z)|y<p=p&((n,y):z)|1>0=m+(p-x)/(y-x)
t=(&zip[0..](scanl(+)0$map(*pi)[0.38,0.4..]))

Könnte es weiter verbessern, indem die Filterung vom &Bediener in eine takeWhileAussage verschoben wird. Da es sich jedoch nicht um eine Golfsprache handelt, scheint dies relativ wettbewerbsfähig zu sein.

Erläuterung

Der Strom von Toilettenpapierlängen, die volle Schleifen umfassen, wird zuerst mit berechnet scanl (+) 0 (map (* pi) [0.38, 0.4 ..]]. Wir zippen diese mit der Anzahl der vollen Umdrehungen, wodurch auch der Typ Doubleimplizit erfasst wird. Wir übergeben dies &mit der aktuellen Nummer, die wir berechnen möchten, nennen es p.

&verarbeitet die Liste der (Double, Double)Paare auf der rechten Seite, indem (a) vorwärts gesprungen wird, bis snd . head . tailgrößer ist als p, und an diesem Punkt snd . headkleiner ist als p.

Um den Anteil dieser Zeile zu ermitteln, der gefüllt ist, wird er berechnet (p - x)/(y - x),und zur Gesamtanzahl der bisher durchgeführten Schleifen addiert.

CR Drost
quelle
4

C ++, 72 Bytes

float f(float k,int d=19){auto c=d/15.9155;return k<c?k/c:1+f(k-c,d+1);}

Ich habe hier C ++ verwendet, weil es Standardfunktionsargumente unterstützt, die hier zum Initialisieren des Radius benötigt werden.

Rekursion scheint kürzeren Code zu erzeugen als die Verwendung einer for-Loop. Auch autoanstelle von float- 1 Byte weniger!

anatolyg
quelle
1
Du hast mich fast reingelegt und dfür den rAdius benutzt ...
Toby Speight
3

Lua, 82 Bytes

n=... l,c,p=10*n,11.938042,0 while l>c do l,c,p=l-c,c+.628318,p+1 end print(p+l/c)

Nicht schlecht für eine Allzwecksprache, aber natürlich nicht sehr konkurrenzfähig gegen engagierte Golfsprachen. Die Konstanten werden mit pi mit der angegebenen Genauigkeit vormultipliziert.

Criptychon steht bei Monica
quelle
OP war nicht spezifisch, welche Art von Eingabe zu akzeptieren war, daher habe ich die Initialisierung von weggelassen n, aber der Rest wäre so gelaufen, wie er ist (wie er war?). In jedem Fall dauert es jetzt nvon der Kommandozeile; zB für 3 Blatt laufen sie als lua tp.lua 3.
Criptychon steht mit Monica
Es ist nicht gerade eine Regel dieser Frage, sondern eine allgemeine Politik. Sofern in der Frage nichts anderes angegeben ist, wird die Übermittlung durch Hardcodierung der Eingabe zu einem Snippet, das standardmäßig nicht zulässig ist . Weitere Informationen zu den standortweiten Standardeinstellungen finden Sie im Code-Golf-Tag-Wiki .
Dennis
Ich kannte den Teil "Gesamtes Programm oder Funktion", wusste aber nicht, dass "das Hardcodieren der Eingabe die Einreichung zu einem Snippet macht". Danke fürs klarstellen. Ich denke das wäre eigentlich länger als eine Funktion!
Criptychon steht mit Monica
3

JavaScript, 77 Byte

function w(s,d,c){d=d||3.8;c=d*3.14159;return c>s*10?s*10/c:1+w(s-c/10,d+.2)}

Ross Bradbury
quelle
3
Willkommen bei PPCG! Wenn Sie möchten, können Sie JavaScript ES6 verwenden und dies auf 55 Bytes bringen:w=(s,d=3.8,c=d*3.14159)=>c>s*10?s*10/c:1+w(s-c/10,d+.2)
Downgoat
3

C 87 Bytes

float d(k){float f=31.831*k,n=round(sqrt(f+342.25)-19);return n+(f-n*(37+n))/(38+2*n);}

Verwendet eine explizite Formel für die Anzahl der ganzen Schleifen:

floor(sqrt(100 * k / pi + (37/2)^2) - 37/2)

Ich habe ersetzt 100 / pidurch 31.831und ersetzt floordurch round, indem ich die nervige Nummer -18.5in eine saubere verwandelt habe -19.

Die Länge dieser Schleifen beträgt

pi * n * (3.7 + 0.1 * n)

Nach dem Subtrahieren dieser Länge von der gesamten Länge dividiert der Code den Rest durch den richtigen Umfang.


Nur um es klar zu machen - diese Lösung ist O(1)im Gegensatz zu vielen (allen?) Anderen Lösungen komplex. Es ist also etwas länger als eine Schleife oder Rekursion.

anatolyg
quelle
2

C #, 113 Bytes

double s(int n){double c=0,s=0,t=3.8*3.14159;while(n*10>s+t){s+=t;c++;t=(3.8+c*.2)*3.14159;}return c+(n*10-s)/t;}

Ungolfed:

double MysteryToiletPaper(int sheetNumber) 
    { 
        double fullLoops = 0, sum = 0, nextLoop = 3.8 * 3.14159; 

        while (sheetNumber * 10 > sum + nextLoop) 
        { 
            sum += nextLoop; 
            fullLoops++; 
            nextLoop = (3.8 + fullLoops * .2) * 3.14159; 
        } 

        return fullLoops + ((sheetNumber * 10 - sum) / nextLoop); 
    }

Ergebnisse:

für 1 Blatt

0,837658302760201

für 2 blätter

1,64155077524438

für 3 blätter

2,41650110749198

für 100 Blatt

40,8737419532946

ivaan
quelle
2

PHP, 101 Bytes

<?$p=pi();$r=3.8;$l=$argv[1]*10;$t=0;while($r*$p<$l){$t+=($l-=$r*$p)>0?1:0;$r+=.2;}echo$t+$l/($r*$p);

Ungolfed

<?
$pi = pi();
$radius = 3.8;
$length_left = $argv[1]*10;
$total_rounds = 0;
while ($radius * $pi < $length_left) {
    $total_rounds += ($length_left -= $radius * $pi) > 0 ? 1 : 0;
    $radius += .2;
}
echo $total_rounds + $length_left/( $radius * $pi );

Ich glaube, das könnte etwas kürzer sein, aber mir gingen die Ideen aus.

Samsquanch
quelle
2

Python 3, 114 109 99 Bytes

Diese Funktion verfolgt den Umfang jeder Schicht, bis die Summe der Umfänge größer ist als die Länge der Anzahl der Blätter. Sobald dies geschieht, lautet die Antwort:

  • Eine weniger als die Anzahl der berechneten Schichten + Länge der übrig gebliebenen Blätter / Umfang der letzten Schicht

def f(n):
    l,s=0,[]
    while sum(s)<n:s+=[.062832*(l+19)];l+=1
    return len(s)-1+(n-sum(s[:-1]))/s[-1]

Aktualisieren

  • -10 [16-05-09] Optimierte meine Mathematik
  • -5 [16-05-04] Minimierte Zeilenanzahl
NichtlinearFruit
quelle
1

JavaScript, 44 Bytes

w=(i,d=19,c=d/15.9155)=>i<c?i/c:1+w(i-c,d+1)

Ich habe Anatolygs Idee verwendet und den Code in JavaScript übersetzt.

ericw31415
quelle
1

> <>, 46 44 Bytes

a*0"Gq",:&a9+*\
?\:{$-{1+{&:&+>:{:})
;>{$,+n

Erwartet, dass die Anzahl der Blätter beim Programmstart auf dem Stapel vorhanden ist.

Dies verwendet eine Näherung von pi von 355/113 = 3.14159292..., die pi/5in dem Register gespeichert ist. Der Umfang der aktuellen Iteration befindet sich auf dem Stapel und pi/5wird bei jeder Iteration hinzugefügt.

Bearbeiten: Umgestaltet, um den Umfang direkt zu speichern - Vorgängerversion gespeichert pi/10und Durchmesser als gestartet 38, der 2 Bytes länger war.

Sok
quelle
0

PHP, 79 Bytes

function p($s,$d=3.8){$c=$d*pi();return $c>$s*10?$s*10/$c:1+p($s-$c/10,$d+.2);}

Führen Sie Code in Sandbox aus

Ich habe so ziemlich nur Ross Bradburys Antwort für JavaScript in eine PHP-Funktion übersetzt, die auch rekursiv ist.

Nick
quelle
Bitte kopieren Sie nicht einfach eine andere Antwort in eine andere Sprache.
10.