Monday Mini-Golf # 7: Uprość pomiary składników

12

Poniedziałek Mini-Golf: Seria krótkich wyzwań, opublikowanych (miejmy nadzieję!) W każdy poniedziałek.
Przepraszam, że jest późno; Uświadomiłem sobie, że w 90% przypadków napisałem inny pomysł, że jest to duplikat.

Moja rodzina jest raczej duża, więc jemy dużo jedzenia. Zwykle musimy podwoić, potroić, a nawet czterokrotnie przepisy, aby przygotować wystarczającą ilość jedzenia! Ale ponieważ pomnożenie pomiarów może być uciążliwe, dobrze byłoby mieć program, który to dla nas zrobi.

Wyzwanie

Wyzwanie polega na utworzeniu programu lub funkcji, która przyjmuje pomiar jako liczbę N i literę L i zwraca ten sam pomiar, maksymalnie uproszczony. Oto wymagane jednostki miary (wszystkie są amerykańskie, podobnie jak moja rodzina) i odpowiadające im litery:

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)

„maksymalnie uproszczone” oznacza:

  • Korzystanie z największej możliwej jednostki miary. Każda jednostka może mieć resztę 1/4, 1/3, 1/2, 2/3 lub 3/4.
  • W razie potrzeby zamieniając wynik na liczbę mieszaną.

Na przykład 4 owynosi cztery uncje, co staje 1/4 lsię ćwierć funta. 8 t, 8 łyżeczek do herbaty 2 2/3 T.

Detale

  • Dane wejściowe mogą być pobierane w dowolnym rozsądnym formacie; to samo z wyjściem. ( 1 t, 1,"t", 1\ntEtc.)
  • Upewnij się, że każda część ułamkowa jest odpowiednio traktowana. ( 11/4w miejsce 1 1/4nie jest dozwolone.)
  • Liczba zawsze będzie liczba mieszany i zawsze mają mianownik 2, 3albo 4(lub brak). (nie 1 1/8 T, nie 1.5 Titp.)
  • W wyniku powyższego nie są nigdy potrzebne konwersje w dół (np. Kubki na łyżki stołowe).
  • Litera zawsze będzie jedną z liter wymienionych powyżej ( Tcfglopqt).

Przypadki testowe

Oto duża lista obejmująca wszystkie typy spraw:

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

Punktacja

Nasza kuchnia jest bardzo mała, więc kod powinien być tak krótki, jak to możliwe, aby nie utrudniać kuchni. Najkrótszy prawidłowy kod w bajtach wygrywa; tiebreaker przechodzi do przesyłania, które jako pierwsze osiągnęło końcową liczbę bajtów. Zwycięzca zostanie wybrany w poniedziałek, 9 listopada. Powodzenia!

Pamiętaj, że to wyzwanie jest podobne do World Big Dosa , ale nie jest jego duplikatem .

ETHprodukcje
źródło
Blisko spokrewnione .
Alex A.,
@AlexA. Ach, tak, zapomniałem link do tego. IMHO, jest wystarczająco inny: 1) przyjmuje inny format wejściowy. 2) wyjście jest nieco inne. 3) wymaganych jest więcej typów konwersji. 3a) pomiar 1/8 nie jest używany.
ETHprodukcje
@ETHproductions podobny duch jest równoważny duplikatowi.
Akangka
9
To się nigdy nie zdarzyło we właściwych, przepraszam, jednostkach metrycznych;)
Adriaan
5
Twoje golfa stają się coraz mniejsze.
Dennis

Odpowiedzi:

2

Mathematica, 349 334 330 322 bajtów

Ta sekcja odpowiedzi była trochę samotna. Oto moja próba. Dane wejściowe należy podawać jak w przypadkach testowych.

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

Wyjaśnienie

Najpierw uzyskaj dane użytkownika, podziel je na białe znaki i przypisz je do n. i=#~Mod~1&tworzy funkcję, która pobiera ułamkową część liczby, przyjmując ją mod 1. b=#&@@npo prostu pobierze pierwszy element n; to byłoby wszystko do pierwszej przestrzeni.

Jeśli nma 3 elementy, oznacza to, że mamy liczbę całkowitą, ułamek i jednostkę. {x,y,z}=nprzydzieli x, ya zza trzy części n. Innym przypadkiem jest to, że nnie ma 3 elementów; oznacza to, że zamiast tego będą miały 2 elementy. Aby zachować zgodność z powyższym, chcemy xbyć częścią całkowitą, ybyć ułamkiem i zjednostką. W takim przypadku musimy sprawdzić:

  • Jeśli b(pierwszy element z n) jest liczbą całkowitą, a x=b, y=0a z=Last@n(ostatni element n).
  • Jeśli bnie jest liczbą całkowitą, oznacza to, że mamy tylko ułamek bez liczby całkowitej. Chcemy więc zamienić xi yz góry; Zamiast tego x=0, y=bi zjest taka sama, jak powyżej.

Teraz musimy skonfigurować kilka list:

v = {0, 1/4, 1/3, 1/2, 2/3, 3/4} to lista dopuszczalnych frakcji, jak podano w pytaniu.

s = <|T -> 16, t -> 3, o -> 16, q -> 4, p -> 2, f -> 16|>to skojarzenie (para klucz-wartość, jak słownik w Pythonie), które reprezentuje ilość potrzebną danej jednostce, aby przejść do jednej z następnych największych jednostek. Na przykład o -> 16dlatego , że zanim przejdziemy do 1 funta, potrzeba 16 uncji.

r = <|T -> c, t -> T, o -> l, f -> p, p -> q, q -> g|>to skojarzenie, które faktycznie reprezentuje to, co jest następną jednostką w górę. Na przykład T -> coznacza , że jedna jednostka większa niż łyżki to kubki.

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

Teraz maksymalna liczba potrzebna do przejścia o jednostkę to 3; byłyby to uncje płynu (f) -> litry (p) -> kwarty (q) -> galon (g). Tak więc teraz wykonujemy 3 razy:

  • Dodaj xi y, (liczby całkowite i ułamkowe)
  • Z spowyższego powiązania pobierz element z; to znaczy uzyskaj dostęp do bieżącej jednostki i uzyskaj odpowiednią wartość w tym powiązaniu.
  • Podziel (x + y) przez tę wartość, którą otrzymaliśmy powyżej, przypisz ją a, a następnie uzyskaj jej część ułamkową.
  • Jeśli ta część znajduje się na liście v, możemy przejść o jedną jednostkę w górę; ustaw xna azaokrągloną w dół (część całkowita), ustaw yna ułamkową część a, a następnie uzyskaj dostęp do powiązania rz bieżącą jednostką, zaby uzyskać następną jednostkę w górę, i ustaw ją na z.
  • Jeśli nie jest to częścią v, nic nie robimy, ponieważ nie można tego uprościć.

Po wykonaniu tego 3 razy wydrukujemy wynik:

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

To po prostu drukuje {x,y,z}w rzędzie, ale zastępuje wszelkie zera (jeśli nie ma liczb całkowitych lub ułamków) pustym łańcuchem, więc nie są drukowane.

NumberManiac
źródło