Mistérios do papel higiênico

36

Hoje, você precisa resolver um problema muito prático: quantas voltas você precisa para ter um certo número de folhas no rolo de papel higiênico? Vejamos alguns fatos:

  • O diâmetro de um cilindro de papel higiênico é de 3,8 cm
  • O comprimento de uma folha de papel higiênico é de 10 cm.
  • A espessura de uma folha de papel higiênico é de 1 mm.

Antes de envolver o cilindro pela primeira vez, ele possui uma circunferência em cm de 3,8 * pi. Toda vez que você enrola uma folha ao redor do cilindro, seu raio aumenta em .1, portanto, sua circunferência aumenta em .2 * PI. Use essas informações para descobrir quantos loops são necessários para encaixar n folhas de papel higiênico. (Nota: use uma aproximação de Pi que seja pelo menos tão precisa quanto 3,14159).

Casos de teste :

n = 1 :

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

n = 2 :

  • (Quantos loops completos podemos fazer?) 1 loop completo = 3,8 * pi = 11,938.
  • (Quanto nos resta após o 1º loop?) 20 - 11,938 = 8,062
  • (Quanto de um segundo loop faz a peça restante?) 8.062 / (4 * pi) = 0,664 loops
  • Resposta: 1.642 loops

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) = 0,417
  • Resposta: 2.417 loops

n = 100 => 40.874

geokavel
fonte
35
Ufa! 1mm de espessura? Tem certeza de que está usando papel higiênico e não papelão?
Digital Trauma
11
@DigitalTrauma É claro que você não sabe sobre triple-ply: p
geokavel
2
Supondo que o papel higiênico não faça etapas, mas aumente continuamente o raio, é possível obter uma aproximação de formulário fechado ao resultado solicitado. Isso é bom o suficiente? nloops = sqrt(n+11.34)*0.0564189 - 0.19
flawr
2
Caso de teste proposto: 100->40.874
Dennis
1
Papelão com dobra tripla ?! Agora isso é grosso!
mbomb007

Respostas:

13

Pitão, 27 23 bytes

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

Experimente online. Suíte de teste.

Explicação

                            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
fonte
explicação por favor?
Conor O'Brien
@ CᴏɴᴏʀO'Bʀɪᴇɴ Adicionado. Explicar Pyth é sempre muito divertido.
PurkkaKoodari
2
Sua explicação parece uma saída potencial para Surfin' Palavra
geokavel
10

Haskell, 59 46 44 bytes

Um fator de escala de 5 / pi é aplicado, de modo que um cilindro de papel tenha uma circunferência de 19,20,21 ... cm e uma folha seja 50 / pi cm.

Economizou 2 bytes graças ao xnor, usando uma função sem nome.

x!s|s>x=1+(x+1)!(s-x)|1>0=s/x
(19!).(50/pi*)
Damien
fonte
Um método bastante recursivo. Observe que funções sem nome são permitidas mesmo quando você tem outras linhas (apesar de Haskell não a suportar), portanto, a última linha pode ser sem pontos como (19!).(50/pi*).
Xnor
Uau, sopra minha abordagem fora da água!
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..]))

Pode ser capaz de avançar ainda mais, movendo a filtragem do &operador para uma takeWhiledeclaração, mas, como não é uma linguagem de golfe, isso parece relativamente competitivo.

Explicação

O fluxo de pedaços de papel higiênico que compreende loops completos é primeiro calculado como scanl (+) 0 (map (* pi) [0.38, 0.4 ..]]. Nós as compactamos com o número de rotações completas, que também escolherão o tipo Doubleimplicitamente. Passamos isso para &o número atual que queremos calcular, chame-o p.

&processa a lista de (Double, Double)pares à sua direita (a) avançando até que snd . head . tailseja maior que p, nesse ponto snd . headmenor que p.

Para obter a proporção dessa linha que é preenchida, ela calcula (p - x)/(y - x),e a adiciona à quantidade geral de loops que foram feitos até agora.

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

Eu usei C ++ aqui porque ele suporta argumentos de função padrão, necessários aqui para inicializar o raio.

A recursão parece produzir um código mais curto do que o uso de um forloop. Além disso, em autovez de float- 1 byte a menos!

anatolyg
fonte
1
Você quase me enganou, utilizando dpara o radius ...
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)

Nada mal para um idioma de uso geral, mas não muito competitivo em relação aos idiomas dedicados ao golfe, é claro. As constantes são pré-multiplicadas com pi, com a precisão declarada.

criptych fica com Monica
fonte
O OP não era específico sobre que tipo de entrada aceitar, então deixei de fora a inicialização de n, mas o resto teria funcionado como está (como estava?). De qualquer forma, agora é preciso nda linha de comando; por exemplo, para 3 folhas, execute-o como lua tp.lua 3.
Criptych fica com Monica
Não é precisamente uma regra desta questão, mas uma política geral. A menos que a pergunta diga o contrário, a codificação codificada da entrada torna o envio um snippet, que não é permitido por padrão . Mais informações sobre os padrões do site podem ser encontradas no wiki da tag de golfe de código .
Dennis
Eu sabia sobre a parte "programa inteiro ou função", mas não sabia que "codificar a entrada faz do envio um trecho". Agradeço por ter esclarecido. Eu acho que isso realmente seria mais longo em função!
Criptych fica com Monica
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
fonte
3
Bem-vindo ao PPCG! Se desejar, você pode usar o JavaScript ES6 e obter isso para 55 bytes: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);}

Usa uma fórmula explícita para o número de loops inteiros:

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

I substituído 100 / pipor 31.831, e substituídos floorcom round, virando o número irritante -18.5para um ambiente limpo-19 .

O comprimento desses loops é

pi * n * (3.7 + 0.1 * n)

Depois de subtrair esse comprimento de todo o comprimento, o código divide o restante pela circunferência adequada.


Apenas para deixar claro - esta solução tem complexidade O(1), diferente de muitas (todas?) Outras soluções. Portanto, é um pouco mais longo que um loop ou recursão.

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

Resultados:

para 1 folha

0,837658302760201

para 2 folhas

1,64155077524438

para 3 folhas

2,41650110749198

para 100 folhas

40,8737419532946

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

Sinto que isso poderia ser feito um pouco mais curto, mas fiquei sem ideias.

Samsquanch
fonte
2

Python 3, 114 109 99 bytes

Esta função rastreia a circunferência de cada camada até que a soma das circunferências seja maior que o comprimento do número de folhas. Quando isso acontece, a resposta é:

  • Um a menos que o número de camadas calculadas + comprimento das folhas restantes / circunferência da camada mais 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]

Atualizar

  • -10 [16-05-09] Otimizei minha matemática
  • -5 [16-05-04] Número minimizado de linhas
NonlinearFruit
fonte
1

JavaScript, 44 bytes

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

Usei a ideia de anatolyg e traduzi o código para JavaScript.

ericw31415
fonte
1

> <>, 46 44 bytes

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

Espera o número de folhas que estão presentes na pilha no início do programa.

Isso usa uma aproximação de pi de 355/113 = 3.14159292..., armazenando pi/5no registro. A circunferência da iteração atual fica na pilha e pi/5é adicionada a cada iteração.

Editar: Refatorado para armazenar a circunferência diretamente - a versão anterior armazenava pi/10e iniciava o diâmetro como 38, que era 2 bytes mais longo.

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

Executar código no Sandbox

Traduzi apenas a resposta de Ross Bradbury para JavaScript em uma função PHP, que também é recursiva.

usuario
fonte
Por favor, não copie outra resposta para outro idioma.
Rɪᴋᴇʀ