Lundi Mini-Golf # 7: Simplifiez les mesures des ingrédients

12

Monday Mini-Golf: Une série de courts défis de , affichés (espérons-le!) Tous les lundis.
Désolé, il est tard; J'ai réalisé 90% du chemin en écrivant une idée différente qu'il s'agissait d'un doublon.

Ma famille est assez grande, donc nous mangeons beaucoup de nourriture. Nous devons généralement doubler, tripler ou même quadrupler les recettes pour faire suffisamment de nourriture! Mais comme multiplier les mesures peut être pénible, ce serait bien d'avoir un programme pour le faire pour nous.

Défi

Votre défi consiste à créer un programme ou une fonction qui prend une mesure sous la forme d'un nombre N et d'une lettre L , et renvoie la même mesure, simplifiée autant que possible. Voici les unités de mesure requises (toutes sont américaines, comme ma famille), et leurs lettres correspondantes:

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)

"simplifié autant que possible" signifie:

  • Utilisation de la plus grande unité de mesure possible. Chaque unité peut avoir un reste de 1/4, 1/3, 1/2, 2/3 ou 3/4.
  • Transformer le résultat en un nombre mixte, si nécessaire.

Par exemple, 4 oest de quatre onces, ce qui devient 1/4 l, un quart de livre. 8 t, 8 cuillères à café, devient 2 2/3 T.

Détails

  • L'entrée peut être prise dans n'importe quel format raisonnable; idem avec sortie. ( 1 t, 1,"t", 1\nt, Etc.)
  • Assurez-vous que toute partie fractionnaire est traitée correctement. ( 11/4à la place de 1 1/4n'est pas autorisé.)
  • Le nombre sera toujours un nombre mixte, et aura toujours un dénominateur 2, 3ou 4(ou pas). (non 1 1/8 T, non 1.5 T, etc.)
  • En conséquence de ce qui précède, aucune conversion à la baisse (par exemple des tasses en cuillères à soupe) n'est jamais nécessaire.
  • La lettre sera toujours l'une des lettres répertoriées ci-dessus ( Tcfglopqt).

Cas de test

Voici une grande liste, couvrant, espérons-le, tous les types de cas:

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

Notation

Notre cuisine est très petite, donc le code doit être aussi court que possible, afin de ne pas rendre la cuisine plus exiguë. Le code valide le plus court en octets gagne; tiebreaker va à la soumission qui a atteint son nombre d'octets final en premier. Le gagnant sera choisi lundi prochain, le 9 novembre. Bonne chance!

Veuillez noter que ce défi est similaire, mais pas un double de, World Big Dosa .

ETHproductions
la source
Étroitement liés .
Alex A.
@AlexA. Ah, oui, j'ai oublié de faire un lien avec ça. À mon humble avis, c'est suffisamment différent: 1) il faut un format d'entrée différent. 2) la sortie est assez différente. 3) davantage de types de conversion sont nécessaires. 3a) la mesure 1/8 n'est pas utilisée.
ETHproductions
@ETHproductions esprit similaire équivaut à dupliquer.
Akangka
9
Cela ne se produirait jamais correctement, excusez-moi, unités métriques;)
Adriaan
5
Vos golfs deviennent de moins en moins mini.
Dennis

Réponses:

2

Mathematica, 349 334 330 322 octets

Cette section de réponse était un peu solitaire. Alors euh, voici ma tentative. L'entrée doit être donnée comme dans les cas de test.

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

Explication

Obtenez d'abord l'entrée utilisateur, divisez cette entrée sur un espace blanc et affectez-la à n. i=#~Mod~1&crée une fonction qui obtient la partie fractionnaire d'un nombre, en le prenant mod 1. b=#&@@nva simplement obtenir le premier élément n; ce serait tout jusqu'au premier espace.

Si nest long de 3 éléments, cela signifie que nous avons un entier, une fraction et une unité. {x,y,z}=nattribuera x, yet zd'être les trois parties n. L'autre cas est qu'il nne fait pas 3 éléments; cela signifie que ce sera 2 éléments à la place. Pour rester cohérent avec ce qui précède, nous voulons xêtre la partie entière, yla fraction et zl'unité. Dans ce cas, nous devons donc vérifier:

  • Si b(le premier élément de n) est un entier, alors x=b, y=0et z=Last@n(le dernier élément de n).
  • Si bn'est pas un entier, cela signifie que nous n'avons qu'une fraction sans entier. Nous voulons donc échanger xet yd'en haut; au contraire, x=0, y=bet zest le même que ci - dessus.

Maintenant, nous devons mettre en place quelques listes:

v = {0, 1/4, 1/3, 1/2, 2/3, 3/4} est la liste des fractions acceptables, comme indiqué dans la question.

s = <|T -> 16, t -> 3, o -> 16, q -> 4, p -> 2, f -> 16|>est une association (paire clé-valeur, comme un dictionnaire en Python) qui représente la quantité nécessaire d'une unité donnée pour «monter» à l'une des unités les plus grandes suivantes. Par exemple, o -> 16c'est parce que 16 onces sont nécessaires avant de passer à 1 livre.

r = <|T -> c, t -> T, o -> l, f -> p, p -> q, q -> g|>est l'association qui représente réellement la prochaine unité. Par exemple, T -> csignifie qu'une unité plus grande que cuillères à soupe est des tasses.

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

Maintenant, le nombre maximum de fois où nous devons monter d'une unité est de 3; ce serait des onces liquides (f) -> pintes (p) -> quarts (q) -> gallon (g). Donc, nous faisons maintenant les 3 opérations suivantes:

  • Ajouter xet y, (les parties entières et fractionnaires)
  • De l' sassociation ci-dessus, obtenez l'élément z; c'est-à-dire accéder à l'unité actuelle et obtenir la valeur correspondante dans cette association.
  • Divisez (x + y) par la valeur ci-dessus, affectez-la a, puis obtenez sa partie fractionnaire.
  • Si cette partie est dans la liste v, alors nous pouvons remonter d'une unité; défini xsur aarrondi vers le bas (partie entière), défini ysur la partie fractionnaire de a, puis accédez à l'association ravec l'unité actuelle zpour obtenir l'unité suivante et définissez-la sur z.
  • Si c'est pas une partie de la vplace, nous ne faisons rien, car il ne peut être simplifiée.

Une fois cela fait 3 fois, nous imprimons le résultat:

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

Cela s'imprime simplement {x,y,z}dans une rangée, mais remplace tous les zéros (s'il n'y a pas d'entier, ou pas de fraction), par une chaîne vide, donc ceux-ci ne s'impriment pas.

engourdi
la source