Papier toilette mystères

36

Aujourd'hui, vous devez résoudre un problème très pratique: combien de boucles avez-vous besoin d'un certain nombre de feuilles sur votre rouleau de papier toilette? Regardons quelques faits:

  • Le diamètre d'un cylindre de papier toilette nu est de 3,8 cm
  • La longueur d'une feuille de papier toilette est de 10 cm.
  • L'épaisseur d'une feuille de papier toilette est de 1 mm.

Avant d’enrouler le cylindre pour la première fois, sa circonférence en cm est de 3,8 * pi. Chaque fois que vous enroulez une feuille autour du cylindre, son rayon augmente de 0,1; sa circonférence augmente donc de 0,2 * PI. Utilisez ces informations pour déterminer le nombre de boucles nécessaires pour insérer n feuilles de papier toilette. (Remarque: utilisez une approximation de Pi au moins aussi précise que 3.14159).

Cas de test :

n = 1 :

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

n = 2 :

  • (Combien de boucles complètes pouvons-nous créer?) 1 boucle complète = 3,8 * pi = 11,938.
  • (Combien nous reste-t-il après la 1ère boucle?) 20 - 11,938 = 8,062
  • (Combien d'une 2ème boucle la pièce restante fait-elle?) 8.062 / (4 * pi) = .642 boucles
  • Réponse: 1.642 boucles

n = 3 :

  • 1ère boucle complète = 3,8 * pi = 11,938, 2ème boucle complète = 4 * pi = 12,566
  • 30 - 11,938 - 12,566 = 5,496
  • 5,496 / (4,2 * pi) = 0,417
  • Réponse: 2.417 boucles

n = 100 => 40,874

geokavel
la source
35
Phew! 1mm d'épaisseur? Êtes-vous sûr que vous utilisez du papier toilette et non du carton?
Digital Trauma
11
@ DigitalTrauma Il est clair que vous ne connaissez pas la triple couche: p
geokavel le
2
En supposant que le papier toilette ne fait pas d' étapes mais augmente continuellement le rayon, vous pouvez obtenir une approximation sous forme fermée du résultat demandé. Est-ce suffisant? nloops = sqrt(n+11.34)*0.0564189 - 0.19
mardi
2
Cas de test proposé: 100->40.874
Dennis
1
Carton triple couche?! Maintenant c'est épais!
mbomb007

Réponses:

13

Pyth, 27 23 octets

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

Essayez-le en ligne. Suite de tests.

Explication

                            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
la source
explication, s'il vous plaît?
Conor O'Brien
@ CᴏɴᴏʀO'Bʀɪᴇɴ Ajouté. Expliquer Pyth est toujours aussi amusant.
PurkkaKoodari
2
Votre explication ressemble à une sortie potentielle pour Surfin 'Word
geokavel le
10

Haskell, 59 46 44 octets

Un facteur d'échelle de 5 / pi est appliqué, de sorte qu'un cylindre de papier ait une circonférence de 19,20,21 ... cm et une feuille de 50 / pi cm.

Sauvegardé 2 octets grâce à xnor, en utilisant une fonction sans nom.

x!s|s>x=1+(x+1)!(s-x)|1>0=s/x
(19!).(50/pi*)
Damien
la source
Une jolie méthode récursive. Notez que les fonctions non nommées sont autorisées même lorsque vous avez d'autres lignes (bien que Haskell ne les prenne pas en charge), de sorte que la dernière ligne peut être exempte de points (19!).(50/pi*).
XNOR
Wow, souffle mon approche hors de l'eau!
CR Drost
5

Haskell, 97 octets

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

Peut-être serait-il en mesure de jouer plus loin en déplaçant le filtrage de l' &opérateur dans une takeWhiledéclaration, mais étant donné que ce n'est pas une langue de golf, cela semble relativement compétitif.

Explication

Le flux de longueurs de papier hygiénique comprenant des boucles complètes est d'abord calculé comme suit scanl (+) 0 (map (* pi) [0.38, 0.4 ..]]. Nous les compressons avec le nombre de révolutions complètes, ce qui ramènera Doubleimplicitement le type . Nous passons cela à &avec le nombre actuel que nous voulons calculer, appelez-le p.

&traite la liste des (Double, Double)paires à sa droite en (a) sautant vers l’avant jusqu’à ce qu’elle snd . head . tailsoit supérieure à p, à quel point snd . headest inférieur à p.

Pour obtenir la proportion de cette ligne qui est remplie, il calcule (p - x)/(y - x),et l'ajoute au nombre total de boucles effectuées jusqu'à présent.

CR Drost
la source
4

C ++, 72 octets

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

J'ai utilisé C ++ ici car il supporte les arguments de fonction par défaut, nécessaires ici pour initialiser le rayon.

La récursivité semble produire un code plus court que l’utilisation d’une forboucle. En outre, autoau lieu de float- 1 octet de moins!

anatolyg
la source
1
Vous m'avez presque dupé, en utilisant dpour l' radius ...
Toby Speight
3

Lua, 82 octets

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)

Pas mal pour une langue d'usage général, mais pas très compétitif par rapport aux langues de golf dédiées bien sûr. Les constantes sont prémultipliées avec pi, à la précision indiquée.

Criptych se tient avec Monica
la source
OP ne spécifiait pas le type d’entrée à accepter, j’ai donc omis l’initialisation de n, mais le reste aurait fonctionné tel quel (tel quel). Dans tous les cas, cela prend maintenant à npartir de la ligne de commande; par exemple, pour 3 feuilles, exécutez-le comme lua tp.lua 3.
Criptych debout avec Monica
Ce n'est pas précisément une règle de cette question, mais une politique générale. Sauf indication contraire de la question, le codage en dur de l'entrée fait de la soumission un extrait, qui n'est pas autorisé par défaut . Pour plus d’informations sur les valeurs par défaut applicables à l’ensemble du site, consultez le code wiki golf tag .
Dennis
Je connaissais la partie "programme ou fonction" mais je ne savais pas que "coder en dur l'entrée fait de la soumission un extrait". Merci de clarifier. Je pense que ce serait effectivement plus long en tant que fonction!
Criptych est avec Monica
3

JavaScript, 77 octets

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
la source
3
Bienvenue chez PPCG! Si vous le souhaitez, vous pouvez utiliser JavaScript ES6 et l'obtenir sur 55 octets:w=(s,d=3.8,c=d*3.14159)=>c>s*10?s*10/c:1+w(s-c/10,d+.2)
Date
3

C, 87 octets

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

Utilise une formule explicite pour le nombre de boucles entières:

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

J'ai remplacé 100 / pipar 31.831, et remplacé floorpar round, en tournant le nombre ennuyeux -18.5à un clean -19.

La longueur de ces boucles est

pi * n * (3.7 + 0.1 * n)

Après avoir soustrait cette longueur de toute la longueur, le code divise le reste par la circonférence appropriée.


Soyons clairs: cette solution est complexe O(1), contrairement à beaucoup d’autres solutions. C'est donc un peu plus long qu'une boucle ou une récursivité.

anatolyg
la source
2

C #, 113 octets

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

Résultats:

pour 1 feuille

0,837658302760201

pour 2 feuilles

1,64155077524438

pour 3 feuilles

2,41650110749198

pour 100 feuilles

40,8737419532946

ivaan
la source
2

PHP, 101 octets

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

Je pense que cela pourrait être fait un peu plus court, mais je suis à court d’idées.

Samsquanch
la source
2

Python 3, 114 109 99 octets

Cette fonction suit la circonférence de chaque couche jusqu'à ce que la somme des circonférences soit supérieure à la longueur du nombre de feuilles. Une fois que cela se produit, la réponse est:

  • Un de moins que le nombre de couches calculées + la longueur des feuilles restantes / la circonférence de la couche la plus récente

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]

Mise à jour

  • -10 [16-05-09] Optimisé mes calculs
  • -5 [16-05-04] Nombre de lignes minimisé
Fruit non linéaire
la source
1

JavaScript, 44 octets

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

J'ai utilisé l'idée d'Anatolyg et traduit le code en JavaScript.

ericw31415
la source
1

> <>, 46 44 octets

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

Attend que le nombre de feuilles soit présent sur la pile au début du programme.

Ceci utilise une approximation de pi de 355/113 = 3.14159292..., stockant pi/5dans le registre. La circonférence de l'itération actuelle réside sur la pile et pi/5est ajoutée à chaque itération.

Éditer: Refactorisé pour stocker directement la circonférence - la version précédente était stockée pi/10et le diamètre commençait tel 38quel, ce qui était plus long de 2 octets.

Sok
la source
0

PHP, 79 octets

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

Exécuter le code dans le bac à sable

J'ai à peu près uniquement traduit la réponse de Ross Bradbury pour JavaScript dans une fonction PHP, qui est également récursive.

Entaille
la source
S'il vous plaît, ne copiez pas simplement une autre réponse dans une autre langue.
Rɪᴋᴇʀ