Mini-golfe de segunda-feira: Uma série de desafios curtos de código-golfe , 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 o
sã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/4
no lugar de1 1/4
não é permitido.) - O número será sempre um número misto, e terá sempre um denominador de
2
,3
, ou4
(ou nenhuns). (não1 1/8 T
, não1.5 T
etc.) - 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 .
fonte
Respostas:
Mathematica,
349 334330322 bytesEsta 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.
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 itemn
; isso seria tudo até o primeiro espaço.Se
n
tiver 3 elementos, significa que temos um número inteiro, uma fração e uma unidade.{x,y,z}=n
irá atribuirx
,y
ez
para ser as três partesn
. O outro caso é quen
não tem três elementos; isso significa que serão 2 elementos em vez disso. Para manter a consistência acima, queremosx
ser a parte inteira,y
a fração ez
a unidade. Portanto, neste caso, precisamos verificar:b
(o primeiro elemento den
) for um número inteiro, entãox=b
,y=0
ez=Last@n
(o último elemento den
).b
não for um número inteiro, isso significa que só temos uma fração sem número inteiro. Então, queremos trocarx
ey
de cima; em vez disso,x=0
,y=b
, ez
é 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 -> c
significa 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:
x
ey
, (as partes inteira e fracionária)s
associação acima, obtenha o elementoz
; ou seja, acesse a unidade atual e obtenha o valor correspondente nessa associação.a
e obtenha sua parte fracionária.v
, podemos subir uma unidade; definax
comoa
arredondado para baixo (parte inteira), definay
como a parte fracionária de ea
, em seguida, acesse a associaçãor
com a unidade atualz
para obter a próxima unidade e configure-a comoz
.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.fonte