Misteri di carta igienica


36

Oggi devi risolvere un problema molto pratico: di quanti anelli hai bisogno per avere un certo numero di fogli sul tuo rotolo di carta igienica? Diamo un'occhiata ad alcuni fatti:

  • Il diametro di un cilindro di carta igienica nudo è di 3,8 cm
  • La lunghezza di un foglio di carta igienica è di 10 cm.
  • Lo spessore di un foglio di carta igienica è di 1 mm.

Prima di avvolgere il cilindro per la prima volta, ha una circonferenza in cm di 3,8 * pi. Ogni volta che avvolgi un foglio attorno al cilindro, il suo raggio aumenta di 0,1, quindi la sua circonferenza aumenta di 0,2 PI. Usa queste informazioni per scoprire quanti anelli ci vogliono per adattarsi a n fogli di carta igienica. (Nota: utilizzare un'approssimazione di Pi che sia almeno accurata come 3.14159).

Casi di prova :

n = 1 :

  • 10 / (3.8 * pi) = .838 loop

n = 2 :

  • (Quanti loop completi possiamo fare?) 1 loop completo = 3.8 * pi = 11.938.
  • (Quanto ci resta dopo il 1 ° ciclo?) 20-11.938 = 8.062
  • (Quanto di un secondo giro fa il pezzo rimanente?) 8.062 / (4 * pi) = .642 cicli
  • Risposta: 1.642 loop

n = 3 :

  • 1 ° ciclo completo = 3,8 * pi = 11,938, 2 ° ciclo completo = 4 * pi = 12,566
  • 30 - 11.938 - 12.566 = 5.496
  • 5.496 / (4.2 * pi) = .417
  • Risposta: 2.417 loop

n = 100 => 40.874


35
Accidenti! 1 mm di spessore? Sei sicuro di usare carta igienica e non cartone?
Trauma digitale

11
@DigitalTrauma Chiaramente non sai di triplo strato: p
geokavel,

2
Partendo dal presupposto che la carta igienica non fa passi ma aumenta continuamente il raggio, è possibile ottenere un'approssimazione del modulo chiuso al risultato richiesto. È abbastanza buono? nloops = sqrt(n+11.34)*0.0564189 - 0.19
flawr

2
Caso di prova proposto: 100->40.874
Dennis

1
Cartone a tre strati ?! Ora che è di spessore!
mbomb007,

Risposte:


13

Pyth, 27 23 byte

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

Provalo online. Suite di test.

Spiegazione

                            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)

spiegazione, per favore?
Conor O'Brien,

@ CᴏɴᴏʀO'Bʀɪᴇɴ Aggiunto. Spiegare Pyth è sempre così divertente.
PurkkaKoodari,

2
La tua spiegazione sembra un potenziale risultato per Surfin 'Word
geokavel,

10

Haskell, 59 46 44 byte

Viene applicato un fattore di scala di 5 / pi, in modo che un cilindro di carta abbia una circonferenza di 19,20,21 ... cm e un foglio sia di 50 / pi cm.

Salvato 2 byte grazie a xnor, usando una funzione senza nome.

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

Un metodo piuttosto ricorsivo. Nota che le funzioni senza nome sono consentite anche quando hai altre linee (nonostante Haskell non le supporti), quindi l'ultima riga può essere priva di punti come (19!).(50/pi*).
xnor

Wow, soffia il mio approccio fuori dall'acqua!
CR Drost,


5

Haskell, 97 byte

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

Potrebbe essere in grado di golf ulteriormente spostando il filtro &dall'operatore in una takeWhiledichiarazione, ma dato che non è un linguaggio da golf questo sembra relativamente competitivo.

Spiegazione

Il flusso di lunghezze di carta igienica che comprende anelli completi viene inizialmente calcolato come scanl (+) 0 (map (* pi) [0.38, 0.4 ..]]. Comprimiamo questi con il numero di giri completi, che raccoglierà Doubleimplicitamente anche il tipo . Lo passiamo al &numero corrente che vogliamo calcolare, chiamandolo p.

&elabora l'elenco di (Double, Double)coppie alla sua destra (a) saltando in avanti fino a quando snd . head . tailè maggiore di p, a quel punto snd . headè minore di p.

Per ottenere la proporzione di questa riga che viene riempita, la calcola (p - x)/(y - x),e la aggiunge alla quantità complessiva di loop che sono stati realizzati finora.


4

C ++, 72 byte

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

Ho usato C ++ qui perché supporta argomenti di funzione predefiniti, necessari qui per inizializzare il raggio.

La ricorsione sembra produrre un codice più breve rispetto all'uso di for-loop. Inoltre, autoinvece di float- 1 byte in meno!


1
Mi hai quasi ingannato, usando dper l' radius ...
Toby Speight,

3

Lua, 82 byte

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)

Non male per un linguaggio generico, ma non molto competitivo rispetto alle lingue golfistiche dedicate. Le costanti vengono premoltiplicate per pi, alla precisione dichiarata.


OP non era specifico su quale tipo di input accettare, quindi ho omesso l'inizializzazione di n, ma il resto avrebbe funzionato così com'è (com'era?). In ogni caso, ora prende ndalla riga di comando; ad es. per 3 fogli eseguirlo come lua tp.lua 3.
criptych sta con Monica il

Non è precisamente una regola di questa domanda, ma una politica generale. A meno che la domanda non dica diversamente, la codifica rigida dell'input rende l'invio uno snippet, che non è consentito per impostazione predefinita . Ulteriori informazioni sui valori predefiniti a livello di sito sono disponibili nel wiki del codice golf tag .
Dennis,

Conoscevo la parte "intero programma o funzione" ma non sapevo che "codificare in modo rigido l'input rende l'invio uno snippet". Grazie per il chiarimento. Penso che questo sarebbe effettivamente più lungo in funzione!
criptych sta con Monica il

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


3
Benvenuti in PPCG! Se lo desideri, puoi utilizzare JavaScript ES6 e ottenere questo a 55 byte:w=(s,d=3.8,c=d*3.14159)=>c>s*10?s*10/c:1+w(s-c/10,d+.2)
Scarica il

3

C, 87 byte

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

Utilizza una formula esplicita per il numero di loop interi:

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

Ho sostituito 100 / pida 31.831, e lo ha sostituito floorcon round, trasformando il numero fastidioso -18.5per un ambiente pulito-19 .

La lunghezza di questi anelli è

pi * n * (3.7 + 0.1 * n)

Dopo aver sottratto questa lunghezza dall'intera lunghezza, il codice divide il resto per la circonferenza corretta.


Giusto per chiarire: questa soluzione ha complessità O(1), a differenza di molte altre (tutte?) Altre soluzioni. Quindi è un po 'più lungo di un ciclo o ricorsione.


2

C #, 113 byte

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

risultati:

per 1 foglio

0,837658302760201

per 2 fogli

1,64155077524438

per 3 fogli

2,41650110749198

per 100 fogli

40,8737419532946


2

PHP, 101 byte

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

Sento che questo potrebbe essere fatto un po 'più breve, ma ho finito le idee.


2

Python 3, 114 109 99 byte

Questa funzione tiene traccia della circonferenza di ogni strato fino a quando la somma delle circonferenze è maggiore della lunghezza del numero di fogli. Una volta che ciò accade, la risposta è:

  • Uno in meno del numero di strati calcolati + lunghezza dei fogli rimanenti / circonferenza del livello più recente

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]

Aggiornare

  • -10 [16-05-09] Ottimizzato i miei calcoli matematici
  • -5 [16-05-04] Numero ridotto di righe

1

JavaScript, 44 byte

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

Ho usato l'idea di Anatolyg e tradotto il codice in JavaScript.


1

> <>, 46 44 byte

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

Si aspetta che il numero di fogli sia presente nella pila all'avvio del programma.

Questo utilizza un'approssimazione di pi di 355/113 = 3.14159292..., memorizzandola pi/5nel registro. La circonferenza dell'iterazione corrente vive nello stack e pi/5viene aggiunta ad ogni iterazione.

Modifica: Rifattorizzato per memorizzare direttamente la circonferenza: la versione precedente è stata archiviata pi/10e ha iniziato il diametro come 38, che era di 2 byte più lungo.


0

PHP, 79 byte

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

Esegui il codice in Sandbox

Ho praticamente tradotto solo la risposta di Ross Bradbury per JavaScript in una funzione PHP, che è anche ricorsiva.


Per favore, non basta copiare un'altra risposta in un'altra lingua.
Rɪᴋᴇʀ
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.