Понедельник Мини-гольф № 7: Упростите измерения ингредиентов


12

Мини-гольф по понедельникам: серия коротких соревнований по , публикуемых (надеюсь!) Каждый понедельник.
Извините, что уже поздно; Я осознал 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 t, 8 чайных ложек, становится 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

счет

Наша кухня очень маленькая, поэтому код должен быть как можно короче, чтобы не сделать кухню более тесной. Самый короткий действительный код в байтах выигрывает; Тайбрейкер переходит к представлению, которое первым достигло конечного числа байтов. Победитель будет выбран в следующий понедельник, 9 ноября. Удачи!

Обратите внимание, что этот вызов похож, но не дублирует World Big Dosa .



@AlexA. Ах, да, я забыл сослаться на это. ИМХО, он достаточно отличается: 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&создает функцию, которая получает дробную часть числа, взяв ее мод 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) -> пинты (p) -> кварты (q) -> галлон (g). Итак, теперь мы делаем следующие 3 раза:

  • Добавить xи y, (целые и дробные части)
  • Из приведенной sвыше ассоциации получите элемент z; то есть получить доступ к текущему модулю и получить соответствующее значение в этой ассоциации.
  • Разделите (x + y) на то значение, которое мы получили выше, назначьте его a, а затем получите его дробную часть.
  • Если эта часть находится в списке v, то мы можем подняться на одну единицу; установите округление xв aменьшую сторону (целочисленная часть), установите yдробную часть a, затем получите доступ к ассоциации rс текущим модулем, zчтобы получить следующий модуль, и установите для него значение z.
  • Если это не часть v, мы ничего не делаем, так как это нельзя упростить.

Как только это будет сделано 3 раза, мы распечатываем результат:

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

Это просто печатает {x,y,z}в строке, но заменяет любые нули (если нет целых или дробных) пустой строкой, чтобы они не распечатывались.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.