Tuvalet Kağıdı Gizemleri


36

Bugün çok pratik bir problemi çözmeniz gerekiyor: Tuvalet kağıdı rulonuzda belirli sayıda kağıt olması için kaç döngüye ihtiyacınız var? Bazı gerçeklere bakalım:

  • Çıplak tuvalet kağıdı silindirinin çapı 3.8 cm'dir
  • Bir yaprak tuvalet kağıdının uzunluğu 10 cm'dir.
  • Bir sayfa tuvalet kağıdının kalınlığı 1 mm'dir.

Silindirin etrafına ilk kez sarılmadan önce, cm 3,8 * pi'lik bir çevresi vardır. Bir tabakayı silindirin etrafına sardığınızda, yarıçapı 0,1, dolayısıyla çevresi 0,2 * PI artar. Kendisinin uygun için kaç döngüler öğrenmek için bu bilgileri kullanın n tuvalet kağıdı yaprak. (Not: En az 3.14159 kadar hassas bir Pi yaklaşımı kullanın).

Test Durumları :

n = 1 :

  • 10 / (3.8 * pi) = .838 döngü

n = 2 :

  • (Kaç döngü yapabiliriz?) 1 tam döngü = 3.8 * pi = 11.938.
  • (1. döngüden sonra geriye ne kadar kaldı?) 20 - 11.938 = 8.062
  • (Kalan parçada 2. devrenin ne kadarını yapar?) 8.062 / (4 * pi) = .642 döngü
  • Cevap: 1.642 döngüler

n = 3 :

  • 1. tam döngü = 3.8 * pi = 11.938, 2. tam döngü = 4 * pi = 12.566
  • 30 - 11.938 - 12.566 = 5.496
  • 5.496 / (4.2 * pi) = 4.417
  • Cevap: 2.417 döngüler

n = 100 => 40,874


35
Uf! 1 mm kalınlığında? Tuvalet kağıdı kullanıp karton kullanmadığından emin misin?
Dijital Travma,

11
@DigitalTrauma Açıkça üç katlı hakkında bir şey bilmiyorsunuz: p
geokavel

2
Tuvalet kağıdının adım atmadığı, ancak yarıçapı sürekli artırdığı varsayımı altında istenen sonuca kapalı bir form yaklaşımı elde edebilirsiniz. Bu yeterli mi? nloops = sqrt(n+11.34)*0.0564189 - 0.19
kusur,

2
Önerilen test durumu: 100->40.874
Dennis,

1
Üç katlı karton ?! Şimdi bu kalın!
mbomb007

Yanıtlar:


13

Pyth, 27 23 bayt

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

Çevrimiçi deneyin. Test odası.

açıklama

                            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)

açıklama lütfen?
Conor O'Brien,

@ CᴏɴᴏʀO'Bʀɪᴇɴ Eklendi. Pyth'ı açıklamak her zaman çok eğlenceli.
PurkkaKoodari

2
Açıklamanız Surfin 'Word
geokavel

10

Haskell, 59 46 44 bayt

5 / pi'lik bir ölçek faktörü uygulanır, böylece bir kağıt silindiri 19, 20, 21 ... cm'lik bir çevreye sahip olacak ve bir tabaka 50 / pi cm olacaktır.

Adsız bir işlev kullanarak xnor sayesinde 2 bayt kaydedildi.

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

Oldukça özyinelemeli bir yöntem. O Not Başka çizgiler varken isimsiz fonksiyonlar bile izin verilir (desteklememesi Haskell rağmen) son satır olarak pointfree olabilir, böylece (19!).(50/pi*).
xnor

Vay, yaklaşımımı sudan çıkardı!
CR Drost


5

Haskell, 97 bayt

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

Filtrelemeyi &operatörden bir takeWhileifadeye taşıyarak daha fazla golf oynayabilir, ancak bunun bir golf dili olmadığı göz önüne alındığında, bu nispeten rekabetçi görünüyor.

açıklama

Tam döngüler içeren tuvalet kağıdı uzunlukları akımı ilk olarak hesaplanır scanl (+) 0 (map (* pi) [0.38, 0.4 ..]]. Bunları tam devir sayısı ile sıkıştırıyoruz, bu da türü Doubleörtük olarak alacak . Bunu &hesaplamak istediğimiz şu anki numara ile aktarıyoruz, onu çağırıyoruz p.

&listesini işler (Double, Double)kadar ileri atlama (a) ile, sağ tarafındaki çiftleri snd . head . taildaha büyük olan pnokta, ki snd . headdaha az olan p.

Doldurulan bu sıranın oranını elde etmek için, o zamana (p - x)/(y - x),kadar yapılan toplam döngü miktarını hesaplar ve ekler.


4

C ++, 72 bayt

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

C ++ 'ı burada kullandım çünkü yarıçapı başlatmak için gerekli olan varsayılan işlev değişkenlerini destekliyor.

Özyineleme, bir for-loop kullanmaktan daha kısa kod üretiyor gibi görünüyor . Ayrıca, autoyerine float- 1 bayt daha az!


1
Neredeyse beni kandırdın d, radius için ...
Toby Speight

3

Lua, 82 bayt

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)

Genel amaçlı bir dil için fena değil, fakat elbette özel golf dillerine karşı çok rekabetçi değil. Sabitler pi ile belirtilen hassasiyete önceden yerleştirilmiştir.


OP ne tür bir girdiyi kabul edeceğine dair net değildi, bu yüzden başlangıçtan vazgeçtim nama geri kalanlar olduğu gibi çalışacaktı (olduğu gibi?). Her durumda, şimdi nkomut satırından alır ; Örneğin 3 sayfa için olarak çalıştırın lua tp.lua 3.
criptych

Bu tam olarak bu sorunun bir kuralı değil, genel bir politikadır. Soru aksi belirtilmediği sürece, girdiyi kodlamak, gönderimi varsayılan olarak izin verilmeyen bir pasaj haline getirir . Site genelindeki varsayılanlar hakkında daha fazla bilgiyi wiki kod etiketinde bulabilirsiniz .
Dennis

"Bütün program veya fonksiyon" kısmını biliyordum ama "girdiyi kodlamanın gönderimi pasaj yaptığını" bilmiyordum. Aydınlattığın için teşekkürler. Bunun bir işlev olarak daha uzun olacağını düşünüyorum!
criptych, Monica

3

JavaScript, 77 bayt

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
PPCG'ye Hoşgeldiniz! İsterseniz, JavaScript ES6'yı kullanabilir ve bunu 55 bayta alabilirsiniz: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 bayt

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

Tüm döngü sayısı için açık bir formül kullanır:

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

Ben yerini 100 / pitarafından 31.831ve yerini floorile roundcan sıkıcı numarayı çevirerek, -18.5temiz için -19.

Bu halkaların uzunluğu

pi * n * (3.7 + 0.1 * n)

Bu uzunluğu tüm uzunluktan çıkardıktan sonra, kod kalanı uygun bir çevreye böler.


Sadece açıkça belirtmek için - bu çözüm O(1)birçok (tümü?) Diğer çözümlerin aksine karmaşıklığa sahiptir . Bu yüzden bir döngü veya özyineleme biraz daha uzun.


2

C #, 113 bayt

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

Sonuçlar:

1 sayfa için

0,837658302760201

2 sayfa için

1,64155077524438

3 sayfa için

2,41650110749198

100 sayfa için

40,8737419532946


2

PHP, 101 bayt

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

Bunun biraz daha kısa yapılabileceğini hissediyorum, ancak fikirlerin tükendi.


2

Python 3, 114 109 99 bayt

Bu işlev, çevre toplamı yaprak sayısının uzunluğundan büyük olana kadar her katmanın çevresini izler. Bu olduğunda, cevap şöyledir:

  • Hesaplanan katmanların sayısından daha az + kalan yaprakların uzunluğu / en son katmanın çevresi

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]

Güncelleştirme

  • -10 [16-05-09] Matematiğimi optimize ettim
  • -5 [16-05-04] En aza indirilmiş satır sayısı

1

JavaScript, 44 bayt

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

Anatolyg'in fikrini kullandım ve kodu JavaScript'e çevirdim.


1

> <>, 46 44 bayt

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

Program başlangıcında yığında bulunacak yaprak sayısını bekler.

Bu , kayıt defterinde 355/113 = 3.14159292...depolanan pi'nin yaklaşık bir değerini kullanır pi/5. Geçerli yinelemenin çevresi yığında yaşar ve pi/5her yinelemeye eklenir.

Düzenleme: Çevreyi doğrudan depolamak için yeniden tutturuldu - önceki sürüm depolandı pi/10ve çapı 382 bayt daha uzun olan başladı .


0

PHP, 79 bayt

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

Sandbox'ta kod çalıştır

Ross Bradbury'nin JavaScript konusundaki cevabını sadece özyinelemeli bir PHP fonksiyonuna çevirdim.


Lütfen başka bir cevabı başka bir dile kopyalamayın.
Rɪᴋᴇʀ
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.