Misterios de papel higiénico

36

Hoy necesita resolver un problema muy práctico: ¿Cuántos bucles necesita para tener un cierto número de hojas en su rollo de papel higiénico? Veamos algunos hechos:

  • El diámetro de un cilindro de papel higiénico desnudo es de 3,8 cm.
  • La longitud de una hoja de papel higiénico es de 10 cm.
  • El grosor de una hoja de papel higiénico es de 1 mm.

Antes de envolver el cilindro por primera vez, tiene una circunferencia en cm de 3.8 * pi. Cada vez que envuelve una hoja alrededor del cilindro, su radio aumenta en .1, por lo tanto, su circunferencia aumenta en .2 * PI. Use esta información para averiguar cuántos bucles se necesitan para caber n hojas de papel higiénico. (Nota: utilice una aproximación de Pi que sea al menos tan precisa como 3.14159).

Casos de prueba :

n = 1 :

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

n = 2 :

  • (¿Cuántos bucles completos podemos hacer?) 1 bucle completo = 3.8 * pi = 11.938.
  • (¿Cuánto nos queda después del 1er ciclo?) 20 - 11.938 = 8.062
  • (¿Cuánto de un segundo bucle hace la pieza restante?) 8.062 / (4 * pi) = .642 bucles
  • Respuesta: 1.642 bucles

n = 3 :

  • 1.er ciclo completo = 3.8 * pi = 11.938, segundo ciclo completo = 4 * pi = 12.566
  • 30 - 11.938 - 12.566 = 5.496
  • 5.496 / (4.2 * pi) = .417
  • Respuesta: 2.417 bucles

n = 100 => 40.874

geokavel
fuente
35
¡Uf! 1 mm de espesor? ¿Estás seguro de que estás usando papel higiénico y no cartón?
Trauma digital
11
@DigitalTrauma Claramente no sabes sobre triple capa: p
geokavel
2
Bajo el supuesto de que el papel higiénico no realiza pasos pero aumenta continuamente el radio, puede obtener una aproximación de forma cerrada al resultado solicitado. ¿Es esto lo suficientemente bueno? nloops = sqrt(n+11.34)*0.0564189 - 0.19
flawr
2
Caso de prueba propuesto: 100->40.874
Dennis
1
¿Cartón de tres capas? Ahora que es grueso!
mbomb007

Respuestas:

13

Pyth, 27 23 bytes

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

Pruébalo en línea. Banco de pruebas.

Explicación

                            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
fuente
explicación, por favor?
Conor O'Brien el
@ CᴏɴᴏʀO'Bʀɪᴇɴ Añadido. Explicar Pyth siempre es muy divertido.
PurkkaKoodari
2
Su explicación parece una salida potencial para Surfin 'Word
geokavel
10

Haskell, 59 46 44 bytes

Se aplica un factor de escala de 5 / pi, de modo que un cilindro de papel tiene una circunferencia de 19,20,21 ... cm y una hoja es de 50 / pi cm.

Ahorró 2 bytes gracias a xnor, mediante el uso de una función sin nombre.

x!s|s>x=1+(x+1)!(s-x)|1>0=s/x
(19!).(50/pi*)
Damien
fuente
Un método bastante recursivo. Tenga en cuenta que las funciones sin nombre están permitidas incluso cuando tiene otras líneas (a pesar de que Haskell no lo admite), por lo que la última línea puede estar libre de puntos como (19!).(50/pi*).
xnor
¡Guau, me deja fuera del agua!
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..]))

Es posible que pueda jugar más al golf moviendo el filtro del &operador a una takeWhiledeclaración, pero dado que no es un lenguaje de golf, esto parece relativamente competitivo.

Explicación

El flujo de longitudes de papel higiénico que comprende bucles completos se calcula primero como scanl (+) 0 (map (* pi) [0.38, 0.4 ..]]. Comprimimos estos con el número de revoluciones completas, que también recogerá el tipo Doubleimplícitamente. Le pasamos esto al &número actual que queremos calcular, llámelo p.

&procesa la lista de (Double, Double)pares a su derecha (a) saltando hacia adelante hasta que snd . head . tailsea ​​mayor que p, en cuyo punto snd . heades menor que p.

Para obtener la proporción de esta fila que se llena, luego la calcula (p - x)/(y - x),y la agrega a la cantidad total de bucles que se han realizado hasta ahora.

CR Drost
fuente
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);}

Usé C ++ aquí porque admite argumentos de función predeterminados, necesarios aquí para inicializar el radio.

La recursión parece producir un código más corto que el uso de un forbucle. Además, en autolugar de float- ¡1 byte menos!

anatolyg
fuente
1
Casi me engañas, usándote dpara el radio ...
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)

No está mal para un lenguaje de propósito general, pero no es muy competitivo contra los idiomas de golf dedicados, por supuesto. Las constantes se premultiplican con pi, con la precisión indicada.

críptico se encuentra con Mónica
fuente
OP no era específico acerca de qué tipo de entrada aceptar, por lo que omití la inicialización de n, pero el resto se habría ejecutado tal cual (¿tal cual?). En cualquier caso, ahora toma nde la línea de comando; Por ejemplo, para 3 hojas ejecutarlo como lua tp.lua 3.
Criptych está con Monica
No es precisamente una regla de esta cuestión, sino una política general. A menos que la pregunta diga lo contrario, codificar la entrada hace que el envío sea un fragmento, que no está permitido de forma predeterminada . Puede encontrar más información sobre los valores predeterminados de todo el sitio en el wiki de código de golf .
Dennis
Sabía sobre la parte de "todo el programa o función" pero no sabía que "codificar la entrada hace que el envío sea un fragmento". Gracias por aclararlo. ¡Creo que esto sería más largo como una función!
Criptych está con Monica el
3

JavaScript, 77 bytes

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
fuente
3
Bienvenido a PPCG! Si lo desea, puede usar JavaScript ES6 y w=(s,d=3.8,c=d*3.14159)=>c>s*10?s*10/c:1+w(s-c/10,d+.2)
llevarlo
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);}

Utiliza una fórmula explícita para la cantidad de bucles completos:

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

Reemplacé 100 / pipor 31.831, y reemplacé floorpor round, convirtiendo el molesto número -18.5en limpio -19.

La longitud de estos bucles es

pi * n * (3.7 + 0.1 * n)

Después de restar esta longitud de la longitud total, el código divide el resto por la circunferencia adecuada.


Solo para dejarlo claro: esta solución tiene complejidad O(1), a diferencia de muchas (¿todas?) Otras soluciones. Entonces es un poco más largo que un bucle o una recursión.

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

Sin golf:

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

Resultados:

para 1 hoja

0,837658302760201

para 2 hojas

1,64155077524438

para 3 hojas

2,41650110749198

para 100 hojas

40,8737419532946

ivaan
fuente
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);

Sin golf

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

Siento que esto podría hacerse un poco más corto, pero se me acabaron las ideas.

Samsquanch
fuente
2

Python 3, 114 109 99 bytes

Esta función rastrea la circunferencia de cada capa hasta que la suma de las circunferencias sea mayor que la longitud del número de hojas. Una vez que esto sucede, la respuesta es:

  • Uno menos que el número de capas calculadas + longitud de las hojas sobrantes / circunferencia de la capa más reciente

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]

Actualizar

  • -10 [16-05-09] Optimicé mis cálculos
  • -5 [16-05-04] Número de líneas minimizado
Fruta no lineal
fuente
1

JavaScript, 44 bytes

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

Usé la idea de anatolyg y traduje el código a JavaScript.

ericw31415
fuente
1

> <>, 46 44 bytes

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

Espera el número de hojas que estarán presentes en la pila al inicio del programa.

Esto usa una aproximación de pi de 355/113 = 3.14159292..., almacenando pi/5en el registro. La circunferencia de la iteración actual vive en la pila y pi/5se agrega en cada iteración.

Editar: refactorizado para almacenar la circunferencia directamente: la versión anterior se almacenó pi/10y comenzó el diámetro como 38, que era 2 bytes más largo.

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

Ejecutar código en Sandbox

Prácticamente solo traduje la respuesta de Ross Bradbury para JavaScript en una función PHP, que también es recursiva.

Mella
fuente
Por favor, no copie otra respuesta a otro idioma.
Rɪᴋᴇʀ