Monday Mini-Golf # 7: ทำให้การตรวจวัดส่วนผสมง่ายขึ้น


12

Monday Mini-Golf:ชุดของความท้าทายสั้น ๆโพสต์ (หวังว่า!) ทุกวันจันทร์
ขอโทษที่มาสาย ฉันตระหนักถึง 90% ของวิธีการผ่านการเขียนความคิดที่แตกต่างออกไปว่ามันซ้ำซ้อน

ครอบครัวของฉันค่อนข้างใหญ่ดังนั้นเราจึงกินอาหารมากมาย เรามักจะต้องทำสองเท่าสามเท่าหรือสี่เท่าเพื่อทำอาหารให้พอ! แต่การทวีคูณการวัดอาจเป็นความเจ็บปวดมันคงจะดีถ้ามีโปรแกรมที่ทำสิ่งนี้ให้เรา

ท้าทาย

ความท้าทายของคุณคือการสร้างโปรแกรมหรือฟังก์ชั่นที่ใช้วัดเป็นตัวเลขNและตัวอักษรLและคืนค่าการวัดเดียวกันให้ง่ายขึ้นมากที่สุด นี่คือหน่วยการวัดที่จำเป็น (ทั้งหมดเป็นแบบอเมริกันเช่นครอบครัวของฉัน) และตัวอักษรที่เกี่ยวข้อง:

1 cup (c) = 16 tablespoons (T) = 48 teaspoons (t)
1 pound (l) = 16 ounces (o)
1 gallon (g) = 4 quarts (q) = 8 pints (p) = 128 fluid ounces (f)

"ง่ายที่สุดเท่าที่จะทำได้" หมายถึง:

  • ใช้หน่วยการวัดที่ใหญ่ที่สุดเท่าที่จะเป็นไปได้ แต่ละหน่วยสามารถมีส่วนที่เหลือ 1/4, 1/3, 1/2, 2/3 หรือ 3/4
  • เปลี่ยนผลลัพธ์เป็นตัวเลขผสมหากจำเป็น

ตัวอย่างเช่น4 oสี่ออนซ์ซึ่งจะกลายเป็น1/4 lหนึ่งในสี่ปอนด์ 8 t8 2 2/3 Tช้อนชากลายเป็น

รายละเอียด

  • อินพุตอาจถูกนำไปใช้ในรูปแบบที่สมเหตุสมผล เช่นเดียวกันกับการส่งออก ( 1 t, 1,"t", 1\ntฯลฯ )
  • ตรวจสอบให้แน่ใจว่าได้จัดการส่วนที่เป็นเศษส่วนอย่างเหมาะสม ( ไม่อนุญาตให้11/4แทนที่1 1/4)
  • จำนวนมักจะมีจำนวนผสมและมักจะมีตัวหารของ2, 3หรือ4(หรือไม่มี) (ไม่1 1/8 Tไม่1.5 Tฯลฯ )
  • จากผลข้างต้นจึงไม่จำเป็นต้องมีการแปลง (เช่นถ้วยเป็นช้อนโต๊ะ)
  • จดหมายจะเป็นตัวอักษรตัวใดตัวหนึ่งที่มีรายชื่ออยู่ด้านบน ( Tcfglopqt)

การทดสอบกรณี

นี่คือรายการขนาดใหญ่หวังว่าจะครอบคลุมทุกกรณี

Input   | Output
--------+--------
1/2 t   | 1/2 t
3/4 t   | 1/4 T
1 t     | 1/3 T
1 1/2 t | 1/2 T
2 t     | 2/3 T
2 1/4 t | 3/4 T
2 1/2 t | 2 1/2 t
3 t     | 1 T
10 t    | 3 1/3 T
16 t    | 1/3 c
5 1/3 T | 1/3 c
8 T     | 1/2 c
16 T    | 1 c
36 T    | 2 1/4 c
1/4 c   | 1/4 c
1024 c  | 1024 c
1 o     | 1 o
4 o     | 1/4 l
5 1/3 o | 1/3 l
5 2/3 o | 5 2/3 o
8 o     | 1/2 l
28 o    | 1 3/4 l
28 l    | 28 l
2 f     | 2 f
4 f     | 1/4 p
8 f     | 1/4 q
16 f    | 1/2 q
32 f    | 1/4 g
64 f    | 1/2 g
128 f   | 1 g
2/3 p   | 1/3 q
1 1/3 p | 2/3 q
2 p     | 1/4 g
1 q     | 1/4 g

เกณฑ์การให้คะแนน

ห้องครัวของเรามีขนาดเล็กมากดังนั้นรหัสควรสั้นที่สุดเท่าที่จะเป็นไปได้เพื่อไม่ให้ครัวแคบขึ้น รหัสที่ถูกต้องสั้นที่สุดในไบต์ชนะ; tiebreaker ไปที่การส่งที่ถึงจำนวนไบต์สุดท้ายก่อน ผู้ชนะจะได้รับการคัดเลือกในวันจันทร์ที่ 9 พ.ย. โชคดี!

โปรดทราบว่าสิ่งที่ท้าทายนี้จะคล้ายกับ แต่ไม่ซ้ำกันของโลกบิ๊ก Dosa


เกี่ยวข้องอย่างใกล้ชิด
Alex A.

@AlexA อาใช่ฉันลืมเชื่อมโยงไปยังที่ IMHO มันแตกต่างกันพอสมควร: 1) ใช้รูปแบบอินพุตที่ต่างกัน 2) การส่งออกค่อนข้างแตกต่างกันเล็กน้อย 3) ต้องการประเภทการแปลงเพิ่มเติม 3a) การวัด 1/8 ไม่ได้ใช้
ETHproductions

@ETHproductions วิญญาณที่คล้ายกันนั้นเทียบเท่ากับซ้ำกัน
Akangka

9
สิ่งนี้จะไม่เกิดขึ้นอย่างถูกต้องขอโทษด้วยฉันหน่วยเมตริก)
Adriaan

5
สนามกอล์ฟของคุณกำลังมีขนาดเล็กลงเรื่อย ๆ
เดนนิส

คำตอบ:


2

Mathematica, 349 334 330 322 ไบต์

ส่วนคำตอบนี้รู้สึกเหงานิดหน่อย เอ่อนี่คือความพยายามของฉัน ควรป้อนข้อมูลให้ในกรณีทดสอบ

n=ToExpression@StringSplit@InputString[];i=#~Mod~1&;b=#&@@n;If[Length@n==3,{x,y,z}=n,{x,y,z}=If[IntegerQ@b,{b,0,Last@n},{0,b,Last@n}]];v={0,1/4,1/3,1/2,2/3,3/4};s=<|T->16,t->3,o->16,q->4,p->2,f->16|>;r=<|T->c,t->T,o->l,f->p,p->q,q->g|>;If[v~MemberQ~i[a=(x+y)/s@z],{x,y,z}={Floor@a,i@a,r@z}]~Do~3;Print@Row[{x,y,z}/. 0->""]

คำอธิบาย

nครั้งแรกที่ได้รับการป้อนข้อมูลของผู้ใช้แยกว่าข้อมูลเกี่ยวกับช่องว่างและกำหนดว่า i=#~Mod~1&สร้างฟังก์ชั่นที่ได้รับส่วนบางส่วนของตัวเลขด้วยการเอา mod 1. b=#&@@nก็จะได้รับรายการแรกในn; นั่นจะเป็นทุกสิ่งจนถึงพื้นที่แรก

หากnมีความยาว 3 องค์ประกอบนั่นหมายความว่าเรามีจำนวนเต็มเศษส่วนและหน่วย {x,y,z}=nจะกำหนดx, yและจะเป็นสามส่วนของz nอีกกรณีคือความnยาว 3 องค์ประกอบ; นั่นหมายความว่ามันจะมีความยาว 2 องค์ประกอบแทน เพื่อให้สอดคล้องกับข้างบนเราต้องการxเป็นส่วนจำนวนเต็มyเป็นเศษส่วนและzหน่วย ดังนั้นในกรณีนี้เราต้องตรวจสอบ:

  • ถ้าb(องค์ประกอบแรกของn) เป็นจำนวนเต็มแล้วx=b, y=0และz=Last@n(องค์ประกอบสุดท้ายของn)
  • หากbไม่ใช่จำนวนเต็มแสดงว่าเรามีเศษส่วนที่ไม่มีจำนวนเต็มเท่านั้น ดังนั้นเราจึงต้องการที่จะแลกเปลี่ยนxและyจากข้างต้น; แทนx=0, y=bและzเป็นเช่นเดียวกับข้างต้น

ตอนนี้เราต้องตั้งค่าบางรายการ:

v = {0, 1/4, 1/3, 1/2, 2/3, 3/4} เป็นรายการของเศษส่วนที่ยอมรับได้ตามที่ระบุในคำถาม

s = <|T -> 16, t -> 3, o -> 16, q -> 4, p -> 2, f -> 16|>คือการเชื่อมโยง (คู่คีย์ - ค่าเช่นพจนานุกรมใน Python) ที่แสดงถึงจำนวนเงินที่ต้องการของหน่วยที่กำหนดเพื่อให้ "ขึ้น" กับหนึ่งในหน่วยที่ใหญ่ที่สุดถัดไป ตัวอย่างเช่นo -> 16เป็นเพราะต้องการออนซ์ 16 ก่อนที่เราจะไปถึง 1 ปอนด์

r = <|T -> c, t -> T, o -> l, f -> p, p -> q, q -> g|>คือการเชื่อมโยงที่แสดงถึงสิ่งที่หน่วยถัดไปเป็นจริง ตัวอย่างเช่นT -> cหมายถึงหนึ่งหน่วยที่มีขนาดใหญ่กว่าช้อนโต๊ะคือถ้วย

If[v~MemberQ~i[a = (x + y)/s@z], {x, y, z} = {Floor@a, i@a, r@z}]~Do~3

ตอนนี้จำนวนครั้งสูงสุดที่เราต้องขึ้นหน่วยคือ 3; นั่นจะเป็นของเหลวออนซ์ (f) -> pints (p) -> quarts (q) -> แกลลอน (g) ดังนั้นตอนนี้เราทำ 3 ครั้งต่อไปนี้:

  • เพิ่มxและy, (ส่วนจำนวนเต็มและเศษส่วน)
  • จากการsเชื่อมโยงข้างต้นรับองค์ประกอบz; นั่นคือเข้าถึงหน่วยปัจจุบันและรับค่าที่เกี่ยวข้องในการเชื่อมโยงนั้น
  • หาร (x + y) ด้วยค่าที่เราได้รับไปแล้วกำหนดให้aจากนั้นรับส่วนที่เป็นเศษส่วน
  • ถ้าส่วนนั้นอยู่ในรายการvเราก็สามารถขึ้นหนึ่งหน่วย ชุดxที่จะaลงกลม (จำนวนเต็มบางส่วน) ตั้งyกับส่วนที่เป็นเศษส่วนของaจากนั้นเข้าสมาคมrกับหน่วยในปัจจุบันจะได้รับหน่วยถัดไปขึ้นและชุดที่zz
  • หากไม่ใช่ส่วนหนึ่งของvแทนเราจะไม่ทำอะไรเลยเพราะมันไม่สามารถทำให้ง่ายขึ้นได้

เมื่อเสร็จแล้ว 3 ครั้งเราจะพิมพ์ผลลัพธ์:

Print@Row[{x,y,z}/. 0->””]

สิ่งนี้จะพิมพ์ออกมา{x,y,z}เป็นแถว แต่แทนที่ศูนย์ใด ๆ (ถ้าไม่มีจำนวนเต็มหรือไม่มีเศษ) ด้วยสตริงว่างดังนั้นสิ่งเหล่านั้นจะไม่พิมพ์ออกมา

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