Monday Mini-Golf # 7: Simplifique las mediciones de ingredientes

12

Mini golf de lunes: una serie de desafíos de corto , publicados (¡con suerte!) Todos los lunes.
Lo siento, es tarde; Me di cuenta del 90% del camino al escribir una idea diferente de que era un duplicado.

Mi familia es bastante grande, por lo que comemos mucha comida. ¡Por lo general, necesitamos duplicar, triplicar o incluso cuadruplicar recetas para hacer suficiente comida! Pero como multiplicar las medidas puede ser un fastidio, sería bueno tener un programa que haga esto por nosotros.

Desafío

Su desafío es crear un programa o función que tome una medida como un número N y una letra L , y devuelva la misma medida, simplificada lo más posible. Aquí están las unidades de medida requeridas (todas son estadounidenses, como mi familia), y sus letras correspondientes:

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)

"simplificado tanto como sea posible" significa:

  • Usando la unidad de medida más grande posible. Cada unidad puede tener un resto de 1/4, 1/3, 1/2, 2/3 o 3/4.
  • Convertir el resultado en un número mixto, si es necesario.

Por ejemplo, 4 oson cuatro onzas, que se convierten en 1/4 lun cuarto de libra. 8 t, 8 cucharaditas, se convierte 2 2/3 T.

Detalles

  • La entrada puede tomarse en cualquier formato razonable; Lo mismo con la salida. ( 1 t, 1,"t", 1\nt, Etc.)
  • Asegúrese de que cualquier parte fraccional se trate correctamente. (11/4 en lugar de 1 1/4no está permitido)
  • El número será siempre un número mixto, y siempre tendrá un denominador de 2, 3o 4(o ninguno). (no 1 1/8 T, no1.5 T , etc.)
  • Como resultado de lo anterior, nunca se necesitan conversiones descendentes (por ejemplo, tazas a cucharadas).
  • La letra siempre será una de las letras enumeradas anteriormente ( Tcfglopqt).

Casos de prueba

Aquí hay una lista grande, con suerte cubriendo todo tipo de casos:

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

Puntuación

Nuestra cocina es muy pequeña, por lo que el código debe ser lo más corto posible, para no hacer que la cocina sea más pequeña. El código válido más corto en bytes gana; El desempate se envía primero a la sumisión que alcanzó su conteo final de bytes. El ganador será elegido el próximo lunes 9 de noviembre. ¡Buena suerte!

Tenga en cuenta que este desafío es similar pero no un duplicado de World Big Dosa .

ETHproductions
fuente
@AlexA. Ah, sí, olvidé vincular eso. En mi humilde opinión, es lo suficientemente diferente: 1) toma un formato de entrada diferente. 2) la salida es bastante diferente. 3) se requieren más tipos de conversión. 3a) no se utiliza la medida 1/8.
ETHproductions
@ETHproductions espíritu similar es equivalente a duplicar.
Akangka
99
Esto nunca sucedería de manera adecuada, disculpe, unidades métricas;)
Adriaan el
55
Sus campos de golf son cada vez menos pequeños.
Dennis

Respuestas:

2

Mathematica, 349 334 330 322 bytes

Esta sección de respuestas se sintió un poco sola. Entonces, aquí está mi intento. La entrada debe darse como en los casos de prueba.

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

Explicación

Primero obtenga la entrada del usuario, divídala en espacios en blanco y asígnela n. i=#~Mod~1&crea una función que obtiene la parte fraccionaria de un número, al tomarla mod 1. b=#&@@nsimplemente obtendrá el primer elemento enn ; eso sería todo hasta el primer espacio.

Si ntiene 3 elementos de largo, eso significa que tenemos un número entero, una fracción y una unidad. {x,y,z}=nasignará x, yy zpara ser las tres partes de n. El otro caso es que nno tiene 3 elementos de largo; eso significa que tendrá 2 elementos de largo en su lugar. Para mantener la coherencia con lo anterior, queremos xser la parte entera, yser la fracción y zla unidad. Entonces, en este caso, debemos verificar:

  • Si b(el primer elemento de n) es un entero, entonces x=b, y=0y z=Last@n(el último elemento de n).
  • Si bno es un número entero, eso significa que solo tenemos una fracción sin número entero. Por eso queremos intercambiar xy ydesde arriba; en cambio, x=0, y=b, y zes el mismo que el anterior.

Ahora tenemos que configurar algunas listas:

v = {0, 1/4, 1/3, 1/2, 2/3, 3/4} es la lista de fracciones aceptables, como se indica en la pregunta.

s = <|T -> 16, t -> 3, o -> 16, q -> 4, p -> 2, f -> 16|>es una asociación (par clave-valor, como un diccionario en Python) que representa la cantidad necesaria de una unidad dada para "subir" a una de las siguientes unidades más grandes. Por ejemplo, o -> 16es porque se requieren 16 onzas antes de subir a 1 libra.

r = <|T -> c, t -> T, o -> l, f -> p, p -> q, q -> g|>es la asociación que realmente representa cuál es la siguiente unidad. Por ejemplo, T -> csignifica que una unidad más grande que Cucharadas es tazas.

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

Ahora, el número máximo de veces que necesitamos subir una unidad es 3; eso sería onzas líquidas (f) -> pintas (p) -> cuartos de galón (q) -> galón (g). Entonces, ahora hacemos las siguientes 3 veces:

  • Agregar xyy , (las partes enteras y fraccionarias)
  • De la sasociación anterior, obtenga el elementoz ; es decir, acceda a la unidad actual y obtenga el valor correspondiente en esa asociación.
  • Divida (x + y) por el valor que obtuvimos arriba, asígnelo a a luego obtenga su parte fraccionaria.
  • Si esa parte está en la lista v, entonces podemos subir una unidad; establecer xen aredondeado hacia abajo (parte entera), establecer yen la parte fraccionaria de a, luego acceder a la asociación rcon la unidad actual zpara obtener la siguiente unidad, y establecer eso enz .
  • Si no forma parte v, no hacemos nada, ya que no se puede simplificar.

Una vez hecho esto 3 veces, imprimimos el resultado:

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

Esto simplemente se imprime {x,y,z}en una fila, pero reemplaza los ceros (si no hay un número entero o una fracción), con una cadena vacía, por lo que no se imprimen.

numbermaniac
fuente