กระดาษชำระลึกลับ


36

วันนี้คุณต้องแก้ปัญหาในทางปฏิบัติมาก: คุณต้องวนกี่แผ่นในม้วนกระดาษชำระของคุณ? ลองดูข้อเท็จจริงบางอย่าง:

  • เส้นผ่าศูนย์กลางของกระบอกกระดาษชำระเปลือยคือ 3.8 ซม
  • กระดาษชำระหนึ่งแผ่นมีความยาว 10 ซม.
  • ความหนาของกระดาษชำระหนึ่งแผ่นคือ 1 มม.

ก่อนที่คุณจะพันรอบกระบอกสูบครั้งแรกมันจะมีเส้นรอบวงเป็นซม. 3.8 * pi ทุกครั้งที่คุณห่อแผ่นหนึ่งรอบ ๆ กระบอกสูบรัศมีของมันจะเพิ่มขึ้นเป็น 0.1 ดังนั้นเส้นรอบวงของมันจะเพิ่มขึ้นโดย. 2 * PI ใช้ข้อมูลนี้เพื่อดูว่าต้องใช้กี่ลูปเพื่อใส่กระดาษชำระnแผ่น (หมายเหตุ: ใช้การประมาณของ Pi ที่อย่างน้อยก็แม่นยำเท่ากับ 3.14159)

กรณีทดสอบ :

n = 1 :

  • 10 / (3.8 * pi) = .838 ลูป

n = 2 :

  • (เราสามารถสร้างลูปได้กี่ครั้ง) 1 full loop = 3.8 * pi = 11.938
  • (เราเหลือหลังจากวงที่ 1 ไปเท่าใด) 20 - 11.938 = 8.062
  • (ชิ้นส่วนที่เหลือทำ 2 วงเท่าไหร่?) 8.062 / (4 * pi) = .642 ลูป
  • คำตอบ: 1.642 ลูป

n = 3 :

  • วงเต็มครั้งที่ 1 = 3.8 * pi = 11.938, วงเต็มวงที่สอง = 4 * pi = 12.566
  • 30 - 11.938 - 12.566 = 5.496
  • 5.496 / (4.2 * pi) = .417
  • คำตอบ: 2.417 ลูป

n = 100 => 40.874


35
วุ้ย หนา 1 มม. คุณแน่ใจหรือว่าคุณกำลังใช้กระดาษชำระไม่ใช่กระดาษแข็ง?
บาดเจ็บทางดิจิทัล

11
@DigitalTrauma เห็นได้ชัดว่าคุณไม่ทราบเกี่ยวกับสามชั้น: p
geokavel

2
ภายใต้สมมติฐานที่ว่ากระดาษชำระไม่ได้ทำตามขั้นตอนแต่เพิ่มรัศมีอย่างต่อเนื่องคุณสามารถได้รับการประมาณรูปแบบปิดเพื่อผลลัพธ์ที่ร้องขอ ดีพอหรือไม่ nloops = sqrt(n+11.34)*0.0564189 - 0.19
ข้อบกพร่อง

2
กรณีทดสอบที่เสนอ: 100->40.874
Dennis

1
กระดาษแข็งสามชั้น! ตอนนี้มันหนาแล้ว!
mbomb007

คำตอบ:


13

Pyth, 27 23 ไบต์

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

ลองออนไลน์ ชุดทดสอบ

คำอธิบาย

                            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)

กรุณาอธิบาย
Conor O'Brien

เพิ่ม @ CᴏɴᴏʀO'Bʀɪᴇɴแล้ว การอธิบาย Pyth สนุกมากเสมอ
PurkkaKoodari

2
คำอธิบายของคุณดูเหมือนผลลัพธ์ที่เป็นไปได้สำหรับSurfin 'Word
geokavel

10

Haskell, 59 46 44 ไบต์

ใช้ตัวคูณสเกล 5 / pi เพื่อให้กระบอกกระดาษมีเส้นรอบวง 19,20,21 ... ซม. และแผ่นหนึ่งคือ 50 / pi ซม.

บันทึก 2 ไบต์ต้องขอบคุณ xnor โดยใช้ฟังก์ชั่นที่ไม่มีชื่อ

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

วิธีการเวียนเกิดที่ค่อนข้างสวย โปรดทราบว่าฟังก์ชั่นที่ไม่มีชื่อจะได้รับอนุญาตแม้เมื่อคุณมีสายอื่น ๆ (แม้จะ Haskell ไม่สนับสนุนมัน) ดังนั้นบรรทัดสุดท้ายที่สามารถ pointfree (19!).(50/pi*)เป็น
xnor

ว้าวเป่าวิธีการของฉันออกจากน้ำ!
CR Drost


5

Haskell, 97 ไบต์

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

อาจจะสามารถเล่นกอล์ฟต่อไปได้โดยการย้ายตัวกรองจาก&ผู้ปฏิบัติงานไปยังtakeWhileแถลงการณ์ แต่เนื่องจากไม่ใช่ภาษากอล์ฟสิ่งนี้จึงดูค่อนข้างแข่งขัน

คำอธิบาย

scanl (+) 0 (map (* pi) [0.38, 0.4 ..]]กระแสของความยาวของกระดาษชำระที่ประกอบด้วยลูปเต็มรูปแบบจะมีการคำนวณครั้งแรกในฐานะ เราซิปเหล่านี้ด้วยจำนวนการปฏิวัติเต็มรูปแบบซึ่งจะรับประเภทDoubleโดยนัย เราผ่านนี้จะมีจำนวนปัจจุบันที่เราต้องการคำนวณเรียกว่า&p

&ประมวลผลรายชื่อของ(Double, Double)คู่ด้านขวาของตนโดย (ก) การกระโดดข้ามไปข้างหน้าจนกว่าจะsnd . head . tailมีค่ามากกว่าpจุดที่มีค่าน้อยกว่าsnd . headp

เพื่อให้ได้สัดส่วนของแถวนี้ที่เต็มไปจากนั้นจะคำนวณ(p - x)/(y - x),และเพิ่มลงในจำนวนลูปโดยรวมที่ทำไปแล้ว


4

C ++, 72 ไบต์

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

ฉันใช้ C ++ ที่นี่เพราะมันรองรับอาร์กิวเมนต์ของฟังก์ชั่นเริ่มต้นจำเป็นต้องใช้ที่นี่เพื่อเริ่มต้นรัศมี

ดูเหมือนว่าการเรียกซ้ำจะสร้างรหัสที่สั้นกว่าการใช้for-loop นอกจากนี้autoแทนfloat- น้อยกว่า 1 ไบต์!


1
คุณเกือบจะหลอกฉันใช้dสำหรับradius ...
Toby Speight

3

Lua, 82 ไบต์

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)

ไม่เลวสำหรับภาษาที่ใช้ทั่วไป แต่ไม่สามารถแข่งขันกับภาษากอล์ฟโดยเฉพาะได้ ค่าคงที่จะถูกกำหนดด้วย pi เพื่อความแม่นยำที่ระบุไว้


OP ไม่ได้เฉพาะเจาะจงเกี่ยวกับประเภทของข้อมูลที่จะยอมรับดังนั้นฉันจึงออกจากการเริ่มต้นnแต่ส่วนที่เหลือจะทำงานตามที่เป็นอยู่ ไม่ว่าในกรณีใดก็ตามตอนนี้รับnจากบรรทัดคำสั่ง เช่นสำหรับ 3 lua tp.lua 3แผ่นเรียกว่ามันเป็น
criptych ย่อมาจาก Monica

มันไม่ใช่กฎของคำถามนี้อย่างชัดเจน แต่เป็นนโยบายทั่วไป เว้นแต่คำถามที่ว่ามิฉะนั้น hardcoding การป้อนข้อมูลที่ทำให้การส่งตัวอย่างซึ่งจะไม่ได้รับอนุญาตโดยค่าเริ่มต้น ข้อมูลเพิ่มเติมเกี่ยวกับค่าเริ่มต้นทั่วทั้งไซต์สามารถพบได้ในรหัสแท็กกอล์ฟวิกิพีเดีย
Dennis

ฉันรู้เกี่ยวกับส่วน "ทั้งโปรแกรมหรือฟังก์ชั่น" แต่ไม่ทราบว่า "การเข้ารหัส hardcoding อินพุตทำให้การส่งตัวอย่าง" ขอบคุณสำหรับการชี้แจง ฉันคิดว่านี่จะเป็นหน้าที่อีกต่อไป!
criptych ย่อมาจาก Monica

3

JavaScript, 77 ไบต์

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! หากคุณต้องการคุณสามารถใช้ JavaScript ES6 และรับถึง 55 ไบต์: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 ไบต์

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

ใช้สูตรที่ชัดเจนสำหรับจำนวนลูปทั้งหมด:

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

ฉันแทนที่100 / piโดย31.831และแทนที่floorด้วยการroundเปลี่ยนหมายเลขที่น่ารำคาญในการทำความสะอาด-18.5-19

ความยาวของลูปเหล่านี้คือ

pi * n * (3.7 + 0.1 * n)

หลังจากลบความยาวนี้จากความยาวทั้งหมดรหัสจะหารส่วนที่เหลือด้วยเส้นรอบวงที่เหมาะสม


เพียงเพื่อให้ชัดเจน - โซลูชันนี้มีความซับซ้อนO(1)แตกต่างจากโซลูชันอื่น ๆ (ทั้งหมดหรือไม่) ดังนั้นมันจึงยาวกว่าลูปหรือการเรียกซ้ำอีกเล็กน้อย


2

C #, 113 ไบต์

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

ผล:

สำหรับ 1 แผ่น

0,837658302760201

สำหรับ 2 แผ่น

1,64155077524438

สำหรับ 3 แผ่น

2,41650110749198

สำหรับ 100 แผ่น

40,8737419532946


2

PHP, 101 ไบต์

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

ฉันรู้สึกว่าสิ่งนี้ทำได้สั้นกว่านี้เล็กน้อย แต่ฉันก็ไม่มีความคิด


2

Python 3, 114 109 99 ไบต์

ฟังก์ชั่นนี้ติดตามเส้นรอบวงของแต่ละชั้นจนกระทั่งผลรวมของเส้นรอบวงมากกว่าความยาวของจำนวนชีต เมื่อสิ่งนี้เกิดขึ้นคำตอบคือ:

  • หนึ่งเลเยอร์ที่คำนวณน้อยกว่า+ความยาวของชีตที่เหลือ/เส้นรอบวงของเลเยอร์ล่าสุด

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]

ปรับปรุง

  • -10 [16-05-09] เพิ่มประสิทธิภาพการคิดเลขของฉัน
  • -5 [16-05-04] จำนวนบรรทัดน้อยที่สุด

1

JavaScript ขนาด 44 ไบต์

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

ฉันใช้ความคิดของ Anatolyg และแปลรหัสเป็น JavaScript


1

> <>, 46 44 ไบต์

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

คาดว่าจำนวนชีตที่จะปรากฏบนสแต็กเมื่อเริ่มต้นโปรแกรม

สิ่งนี้ใช้การประมาณค่า pi ของ355/113 = 3.14159292...ซึ่งเก็บpi/5ในรีจิสเตอร์ เส้นรอบวงของการวนซ้ำปัจจุบันอยู่บนสแต็กและpi/5เพิ่มในการวนซ้ำแต่ละครั้ง

แก้ไข:สร้างใหม่เพื่อจัดเก็บเส้นรอบวงโดยตรง - รุ่นก่อนหน้าถูกจัดเก็บpi/10และเริ่มเส้นผ่านศูนย์กลาง38ซึ่งมีความยาว 2 ไบต์


0

PHP, 79 ไบต์

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

เรียกใช้รหัสใน Sandbox

ฉันมีเพียงคำตอบของรอสส์แบรดเบอรี่ที่แปลไว้เป็นจาวาสคริปต์ในฟังก์ชั่น PHP ซึ่งแปลซ้ำด้วย


กรุณาอย่าคัดลอกคำตอบอื่นเป็นภาษาอื่น
Rɪᴋᴇʀ
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.