Monday Mini-Golf # 7: Simplifique as medições de ingredientes

12

Mini-golfe de segunda-feira: Uma série de desafios curtos de , publicados (espero!) Toda segunda-feira.
Desculpe, é tarde; Eu percebi 90% do caminho escrevendo uma ideia diferente de que era uma duplicata.

Minha família é bastante grande, então comemos muita comida. Normalmente, precisamos dobrar, triplicar ou até quadruplicar as receitas para fazer comida suficiente! Mas, como multiplicar as medições pode ser uma dor, seria bom ter um programa para fazer isso por nós.

Desafio

Seu desafio é criar um programa ou função que tome uma medida como um número N e uma letra L e retorne a mesma medida, simplificada ao máximo. Aqui estão as unidades de medida necessárias (todas são americanas, como minha família) e as letras correspondentes:

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 quanto possível" significa:

  • Usando a maior unidade de medida possível. Cada unidade pode ter um restante de 1/4, 1/3, 1/2, 2/3 ou 3/4.
  • Transformando o resultado em um número misto, se necessário.

Por exemplo, 4 osão quatro onças, que se tornam 1/4 l, um quarto de libra. 8 t, 8 colheres de chá, torna-se 2 2/3 T.

Detalhes

  • A entrada pode ser obtida em qualquer formato razoável; mesmo com saída. ( 1 t, 1,"t", 1\nt, Etc.)
  • Certifique-se de que qualquer parte fracionária seja tratada corretamente. ( 11/4no lugar de 1 1/4não é permitido.)
  • O número será sempre um número misto, e terá sempre um denominador de 2, 3, ou 4(ou nenhuns). (não 1 1/8 T, não 1.5 Tetc.)
  • Como resultado do exposto acima, nunca são necessárias conversões descendentes (por exemplo, xícaras para colheres de sopa).
  • A letra sempre será uma das letras listadas acima ( Tcfglopqt).

Casos de teste

Aqui está uma lista grande, espero que cubra todos os tipos 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

Pontuação

Nossa cozinha é muito pequena, portanto o código deve ser o mais curto possível, para não tornar a cozinha mais apertada. O menor código válido em bytes vence; O desempatador vai para o envio que atingiu sua contagem final de bytes primeiro. O vencedor será escolhido na próxima segunda-feira, 9 de novembro. Boa sorte!

Observe que esse desafio é semelhante, mas não uma duplicata, à World Dosa Grande .

ETHproductions
fonte
@AlexA. Ah, sim, eu esqueci de ligar para isso. IMHO, é suficientemente diferente: 1) é preciso um formato de entrada diferente. 2) a saída é um pouco diferente. 3) são necessários mais tipos de conversão. 3a) a medição 1/8 não é usada.
ETHproductions
O espírito semelhante do @ETHproductions é equivalente a duplicar.
Akangka
9
Isso nunca aconteceria em unidades métricas apropriadas; desculpe-me;);
Adriaan
5
Seus tacos estão ficando cada vez menos mini.
Dennis #

Respostas:

2

Mathematica, 349 334 330322 bytes

Esta seção de respostas parecia um pouco solitária. Então, aqui está a minha tentativa. A entrada deve ser fornecida como nos casos de teste.

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

Explicação

Primeiro obtenha a entrada do usuário, divida essa entrada em espaço em branco e atribua-a a n. i=#~Mod~1&cria uma função que obtém a parte fracionária de um número, usando o mod 1. b=#&@@n, simplesmente obtém o primeiro item n; isso seria tudo até o primeiro espaço.

Se ntiver 3 elementos, significa que temos um número inteiro, uma fração e uma unidade. {x,y,z}=nirá atribuir x, ye zpara ser as três partes n. O outro caso é que nnão tem três elementos; isso significa que serão 2 elementos em vez disso. Para manter a consistência acima, queremos xser a parte inteira, ya fração e za unidade. Portanto, neste caso, precisamos verificar:

  • Se b(o primeiro elemento de n) for um número inteiro, então x=b, y=0e z=Last@n(o último elemento de n).
  • Se bnão for um número inteiro, isso significa que só temos uma fração sem número inteiro. Então, queremos trocar xe yde cima; em vez disso, x=0, y=b, e zé o mesmo que acima.

Agora precisamos configurar algumas listas:

v = {0, 1/4, 1/3, 1/2, 2/3, 3/4} é a lista de frações aceitáveis, conforme indicado na pergunta.

s = <|T -> 16, t -> 3, o -> 16, q -> 4, p -> 2, f -> 16|>é uma associação (par de valores-chave, como um dicionário em Python) que representa a quantidade necessária de uma determinada unidade para "subir" para uma das próximas maiores unidades. Por exemplo, o -> 16é porque 16 onças são necessárias antes de subirmos 1 libra.

r = <|T -> c, t -> T, o -> l, f -> p, p -> q, q -> g|>é a associação que realmente representa qual é a próxima unidade. Por exemplo, T -> csignifica que uma unidade maior que colheres de sopa é copos.

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

Agora, o número máximo de vezes que precisamos subir uma unidade é 3; seriam onças fluidas (f) -> pintas (p) -> quartos (q) -> galão (g). Então, agora fazemos as seguintes três vezes:

  • Adicione xe y, (as partes inteira e fracionária)
  • A partir da sassociação acima, obtenha o elemento z; ou seja, acesse a unidade atual e obtenha o valor correspondente nessa associação.
  • Divida (x + y) pelo valor que obtivemos acima, atribua-o ae obtenha sua parte fracionária.
  • Se essa parte estiver na lista v, podemos subir uma unidade; defina xcomo aarredondado para baixo (parte inteira), defina ycomo a parte fracionária de e a, em seguida, acesse a associação rcom a unidade atual zpara obter a próxima unidade e configure-a como z.
  • Se não faz parte v, não fazemos nada, pois não pode ser simplificado.

Feito isso três vezes, imprimimos o resultado:

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

Isso simplesmente é impresso {x,y,z}em uma linha, mas substitui os zeros (se não houver número inteiro ou fração), por uma sequência vazia, para que eles não sejam impressos.

numbermaniac
fonte