Monday Mini-Golf # 7: Menyederhanakan pengukuran bahan

12

Monday Mini-Golf: Serangkaian tantangan pendek , diposting (semoga!) Setiap hari Senin.
Maaf sudah terlambat; Saya menyadari 90% dari cara menulis ide yang berbeda bahwa itu adalah duplikat.

Keluarga saya agak besar, jadi kami makan banyak makanan. Kita biasanya perlu menggandakan, membuat tiga, atau bahkan empat kali lipat resep untuk membuat makanan yang cukup! Tetapi karena mengalikan ukuran bisa menyebalkan, alangkah baiknya memiliki program untuk melakukan ini bagi kita.

Tantangan

Tantangan Anda adalah membuat program atau fungsi yang menggunakan pengukuran sebagai angka N dan huruf L , dan mengembalikan pengukuran yang sama, disederhanakan sebanyak mungkin. Inilah unit pengukuran yang diperlukan (semua orang Amerika, seperti keluarga saya), dan surat-surat yang sesuai:

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)

"disederhanakan sebanyak mungkin" berarti:

  • Menggunakan unit pengukuran terbesar mungkin. Setiap unit dapat memiliki sisa 1/4, 1/3, 1/2, 2/3, atau 3/4.
  • Mengubah hasilnya menjadi angka campuran, jika perlu.

Misalnya, 4 oadalah empat ons, yang menjadi 1/4 l, seperempat pon. 8 t, 8 sendok teh, menjadi 2 2/3 T.

Detail

  • Masukan dapat diambil dalam format apa pun yang wajar; sama dengan output. ( 1 t, 1,"t", 1\nt, Dll)
  • Pastikan setiap bagian pecahan ditangani dengan benar. ( 11/4di tempat 1 1/4tidak diizinkan.)
  • Jumlah tersebut akan selalu menjadi nomor campuran, dan akan selalu memiliki penyebut 2, 3atau 4(atau tidak). (tidak 1 1/8 T, tidak 1.5 T, dll.)
  • Sebagai hasil dari hal di atas, tidak ada konversi ke bawah (misalnya cangkir ke sendok makan) yang pernah diperlukan.
  • Surat itu akan selalu menjadi salah satu surat yang tercantum di atas ( Tcfglopqt).

Kasus uji

Berikut daftar besar, semoga mencakup semua jenis kasus:

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

Mencetak gol

Dapur kami sangat kecil, sehingga kodenya harus sesingkat mungkin, agar tidak membuat dapur lebih sempit. Kode valid terpendek dalam byte menang; tiebreak pergi ke pengiriman yang mencapai jumlah byte terakhirnya terlebih dahulu. Pemenang akan dipilih Senin depan, 9 November. Semoga beruntung!

Harap dicatat bahwa tantangan ini mirip dengan, tetapi bukan duplikat dari, World Big Dosa .

Produksi ETH
sumber
Berhubungan erat .
Alex A.
@AlexA. Ah, ya, saya lupa menautkan itu. IMHO, ini cukup berbeda: 1) dibutuhkan format input yang berbeda. 2) outputnya sedikit berbeda. 3) diperlukan lebih banyak jenis konversi. 3a) pengukuran 1/8 tidak digunakan.
ETHproduk
@ETHproductions roh serupa sama dengan duplikat.
Akangka
9
Ini tidak akan pernah terjadi dengan tepat, permisi, satuan metrik;)
Adriaan
5
Golf Anda semakin kecil.
Dennis

Jawaban:

2

Mathematica, 349 334 330 322 byte

Bagian jawaban ini terasa agak sepi. Jadi uh, ini usahaku. Masukan harus diberikan seperti pada kasus uji.

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->""]

Penjelasan

Pertama-tama dapatkan input pengguna, bagi input itu di spasi, dan tetapkan itu n. i=#~Mod~1&menciptakan fungsi yang mendapatkan bagian fraksional dari angka, dengan mengambilnya mod 1. b=#&@@nhanya akan mendapatkan item pertama di n; itu akan menjadi segalanya hingga ruang pertama.

Jika npanjangnya 3 elemen, itu artinya kita memiliki bilangan bulat, pecahan, dan satuan. {x,y,z}=nakan menetapkan x, ydan zmenjadi tiga bagian dari n. Kasus lainnya adalah bahwa ntidak 3 elemen panjang; itu berarti akan menjadi 2 elemen saja. Agar tetap konsisten dengan di atas, kami ingin xmenjadi bagian integer, ymenjadi fraksi, dan zunit. Jadi dalam hal ini, kita perlu memeriksa:

  • Jika b(elemen pertama n) adalah bilangan bulat, maka x=b, y=0dan z=Last@n(elemen terakhir dari n).
  • Jika bbukan bilangan bulat, itu artinya kita hanya memiliki sebagian kecil tanpa bilangan bulat. Jadi kami ingin bertukar xdan ydari atas; sebaliknya, x=0, y=b, dan zadalah sama seperti di atas.

Sekarang kita perlu mengatur beberapa daftar:

v = {0, 1/4, 1/3, 1/2, 2/3, 3/4} adalah daftar fraksi yang dapat diterima, sebagaimana dinyatakan dalam pertanyaan.

s = <|T -> 16, t -> 3, o -> 16, q -> 4, p -> 2, f -> 16|>adalah asosiasi (pasangan nilai kunci, seperti kamus dengan Python) yang mewakili jumlah yang dibutuhkan unit tertentu untuk naik "ke" ke salah satu unit terbesar berikutnya. Sebagai contoh, o -> 16ini karena 16 ons diperlukan sebelum kita naik ke 1 pound.

r = <|T -> c, t -> T, o -> l, f -> p, p -> q, q -> g|>adalah asosiasi yang sebenarnya mewakili apa unit berikutnya. Misalnya, yang T -> cberarti satu unit lebih besar dari sendok makan adalah cangkir.

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

Sekarang, jumlah maksimum yang kita perlukan untuk naik satu unit adalah 3; itu akan menjadi ons cairan (f) -> pint (p) -> liter (q) -> galon (g). Jadi, sekarang kita lakukan 3 kali berikut:

  • Tambah xdan y, (bagian bilangan bulat dan pecahan)
  • Dari sasosiasi di atas, dapatkan elemen z; yaitu, akses unit saat ini, dan dapatkan nilai yang sesuai di asosiasi itu.
  • Bagi (x + y) dengan nilai yang kita dapatkan di atas, tetapkan a, kemudian dapatkan bagian fraksinya.
  • Jika bagian itu ada dalam daftar v, maka kita bisa naik satu unit; diatur xke adibulatkan ke bawah (bagian integer), atur yke bagian fraksional a, kemudian akses asosiasi rdengan unit saat ini zuntuk mendapatkan unit berikutnya naik, dan atur itu z.
  • Jika itu bukan bagian dari vgantinya, kami tidak melakukan apa-apa, karena itu tidak dapat disederhanakan.

Setelah selesai 3 kali, kami mencetak hasilnya:

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

Ini hanya mencetak {x,y,z}berturut-turut, tetapi mengganti nol apa pun (jika tidak ada bilangan bulat, atau tidak ada fraksi), dengan string kosong, jadi itu tidak dicetak.

numbermaniac
sumber