Tajemnice papieru toaletowego


36

Dziś musisz rozwiązać bardzo praktyczny problem: ile pętli potrzebujesz, aby mieć określoną liczbę arkuszy na rolce papieru toaletowego? Spójrzmy na kilka faktów:

  • Średnica gołego cylindra z papieru toaletowego wynosi 3,8 cm
  • Długość jednego arkusza papieru toaletowego wynosi 10 cm.
  • Grubość jednego arkusza papieru toaletowego wynosi 1 mm.

Przed pierwszym owinięciem cylindra ma on obwód w cm 3,8 * pi. Za każdym razem, gdy owijasz arkusz wokół cylindra, jego promień zwiększa się o .1, a zatem jego obwód wzrasta o .2 * PI. Skorzystaj z tych informacji, aby dowiedzieć się, ile pętli pasuje do n arkuszy papieru toaletowego. (Uwaga: należy użyć przybliżenia Pi, które jest co najmniej tak dokładne jak 3.14159).

Przypadki testowe :

n = 1 :

  • 10 / (3,8 * pi) = .838 pętli

n = 2 :

  • (Ile pełnych pętli możemy wykonać?) 1 pełna pętla = 3,8 * pi = 11,938.
  • (Ile pozostało po pierwszej pętli?) 20 - 11,938 = 8,062
  • (Ile drugiej pętli tworzy pozostały element?) 8.062 / (4 * pi) = .642 pętli
  • Odpowiedź: 1.642 pętle

n = 3 :

  • 1. pełna pętla = 3,8 * pi = 11,938, druga pełna pętla = 4 * pi = 12.566
  • 30 - 11,938 - 12,566 = 5,496
  • 5,496 / (4,2 * pi) = .417
  • Odpowiedź: 2.417 pętli

n = 100 => 40,874


35
Uff! 1 mm grubości? Czy na pewno używasz papieru toaletowego, a nie kartonu?
Cyfrowy uraz

11
@DigitalTrauma Najwyraźniej nie wiesz o triple-ply: p
geokavel

2
Zakładając, że papier toaletowy nie wykonuje kroków, ale stale zwiększa promień, można uzyskać przybliżone przybliżenie formularza do żądanego wyniku. Czy to wystarczy? nloops = sqrt(n+11.34)*0.0564189 - 0.19
flawr

2
Proponowany przypadek testowy: 100->40.874
Dennis

1
Karton trójwarstwowy ?! Teraz jest grubo!
mbomb007

Odpowiedzi:


13

Pyth, 27 23 bajtów

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

Wypróbuj online. Zestaw testowy.

Wyjaśnienie

                            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)

wyjaśnienie, proszę?
Conor O'Brien

@ CᴏɴᴏʀO'Bʀɪᴇɴ Dodano. Wyjaśnienie Pytha jest zawsze świetną zabawą.
PurkkaKoodari

2
Twoje wyjaśnienie wygląda jak potencjalny wynik dla Surfin 'Word
geokavel

10

Haskell, 59 46 44 bajtów

Zastosowano współczynnik skali 5 / pi, tak że walec papierowy ma obwód 19,20,21 ... cm, a arkusz ma 50 / pi cm.

Zaoszczędzono 2 bajty dzięki xnor, używając funkcji bez nazwy.

x!s|s>x=1+(x+1)!(s-x)|1>0=s/x
(19!).(50/pi*)

Dość rekurencyjna metoda. Zauważ, że funkcje bez nazwy są dozwolone, nawet jeśli masz inne linie (mimo że Haskell go nie obsługuje), więc ostatnia linia może być bezcelowa jak (19!).(50/pi*).
xnor

Wow, wydmuchuje moje podejście z wody!
CR Drost


5

Haskell, 97 bajtów

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..]))

Może być w stanie zagrać w golfa dalej, przenosząc filtrowanie od &operatora dotakeWhile się pograć w golfa, oświadczenie, ale biorąc pod uwagę, że nie jest to język golfa, wydaje się to stosunkowo konkurencyjne.

Wyjaśnienie

Strumień długości papieru toaletowego zawierającego pełne pętle oblicza się najpierw jako scanl (+) 0 (map (* pi) [0.38, 0.4 ..]]. Spakowujemy je liczbą pełnych obrotów, które pośrednio podniosą ten typ Double. Przekazujemy to &bieżącemu numerowi, który chcemy obliczyć, nazywamy go p.

&przetwarza listę (Double, Double)par po prawej stronie przez (a) przeskakiwanie do przodu, aż snd . head . tailbędzie większa niż p, w którym momencie snd . headjest mniejsza niż p.

Aby uzyskać część tego wiersza, która jest wypełniona, następnie oblicza (p - x)/(y - x),i dodaje ją do ogólnej liczby wykonanych do tej pory pętli.


4

C ++, 72 bajty

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

Użyłem tutaj C ++, ponieważ obsługuje domyślne argumenty funkcji, potrzebne tutaj do zainicjowania promienia.

Wydaje się, że rekurencja generuje krótszy kod niż przy użyciu forpętli. Ponadto autozamiast float- 1 bajt mniej!


1
Prawie mnie oszukać, używając ddo radius ...
Toby Speight

3

Lua, 82 bajty

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)

Nieźle jak na język ogólnego przeznaczenia, ale oczywiście niezbyt konkurencyjny w stosunku do dedykowanych języków golfowych. Stałe są wstępnie mnożone przez pi z określoną dokładnością.


OP nie precyzowało, jakiego rodzaju dane wejściowe należy zaakceptować, więc pominąłem inicjalizację n, ale reszta działałaby w stanie, w jakim się znajduje (jak było?). W każdym razie teraz pobiera nz wiersza poleceń; np. dla 3 arkuszy uruchom jako lua tp.lua 3.
cryptych stoi z Monicą

Nie jest to reguła tego pytania, ale ogólna polityka. O ile pytanie nie mówi inaczej, kodowanie danych wejściowych powoduje, że przesyłanie jest fragmentem kodu, który domyślnie nie jest dozwolony . Więcej informacji na temat wartości domyślnych dla całej witryny można znaleźć w wiki wiki kodu golf tag .
Dennis

Wiedziałem o części „cały program lub funkcja”, ale nie wiedziałem, że „twarde kodowanie wejścia sprawia, że ​​przesłanie jest fragmentem”. Dzięki za wytłumaczenie. Myślę, że tak naprawdę byłoby to dłużej jako funkcja!
cryptych stoi z Monicą

3

JavaScript, 77 bajtów

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)}


3
Witamy w PPCG! Jeśli chcesz, możesz użyć JavaScript ES6 i uzyskać to do 55 bajtów:w=(s,d=3.8,c=d*3.14159)=>c>s*10?s*10/c:1+w(s-c/10,d+.2)
Zejdź

3

C, 87 bajtów

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

Używa jawnej formuły dla liczby całych pętli:

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

Wymieniłem 100 / piprzez 31.831i zastąpione floorzround zwracając liczbę irytujących -18.5do czysta-19 .

Długość tych pętli wynosi

pi * n * (3.7 + 0.1 * n)

Po odjęciu tej długości od całej długości kod dzieli resztę przez odpowiedni obwód.


Żeby było jasne - to rozwiązanie ma złożoność O(1), w przeciwieństwie do wielu (wszystkich?) Innych rozwiązań. Jest to więc nieco dłużej niż pętla lub rekurencja.


2

C #, 113 bajtów

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;}

Nie golfowany:

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); 
    }

Wyniki:

za 1 arkusz

0,837658302760201

na 2 arkusze

1 64155077524438

na 3 arkusze

2 41650110749198

na 100 arkuszy

40,8737419532946


2

PHP, 101 bajtów

<?$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);

Bez golfa

<?
$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 );

Wydaje mi się, że można to zrobić trochę krócej, ale zabrakło mi pomysłów.


2

Python 3, 114 109 99 bajtów

Ta funkcja śledzi obwód każdej warstwy, dopóki suma obwodów nie będzie większa niż długość liczby arkuszy. Gdy tak się stanie, odpowiedź brzmi:

  • O jeden mniej niż liczba obliczonych warstw + długość pozostałych arkuszy / obwód najnowszej warstwy

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]

Aktualizacja

  • -10 [16-05-09] Zoptymalizowałem moją matematykę
  • -5 [16-05-04] Zminimalizowana liczba linii

1

JavaScript, 44 bajty

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

Wykorzystałem pomysł anatolyga i przetłumaczyłem kod na JavaScript.


1

> <>, 46 44 bajtów

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

Oczekuje, że liczba arkuszy będzie obecna na stosie podczas uruchamiania programu.

Wykorzystuje to przybliżenie liczby pi 355/113 = 3.14159292..., zapisywanie pi/5w rejestrze. Obwód bieżącej iteracji trwa na stosie i pi/5jest dodawany przy każdej iteracji.

Edycja: Przeprojektowano w celu bezpośredniego przechowywania obwodu - poprzednia wersja zapisała pi/10i rozpoczęła średnicę jako 38, która była o 2 bajty dłuższa.


0

PHP, 79 bajtów

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

Uruchom kod w piaskownicy

Prawie przetłumaczyłem tylko odpowiedź Ross'a Bradbury'a na JavaScript na funkcję PHP, która również jest rekurencyjna.


Nie kopiuj tylko innej odpowiedzi na inny język.
Rɪᴋᴇʀ
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.