Até a decimalização em 1971 , o dinheiro britânico era baseado na divisão da libra em 240 centavos. Um xelim custava 12 centavos, então 20 xelins ganhavam uma libra. A menor denominação era a de um quarto de centavo. Havia muitas outras denominações e apelidos para moedas, o que pode ser bastante confuso se você não estiver acostumado ao sistema.
Desafio
Escreva um programa ou função que possa converter (quase) qualquer denominação do antigo dinheiro inglês em qualquer outro. Para tornar mais fácil para o usuário, você precisa suportar plurais e apelidos.
Essas são as denominações e seus termos sinônimos que você deve apoiar. Por conveniência, seu valor em peões leva cada linha.
1: farthing, farthings
2: halfpence, halfpenny, halfpennies
4: penny, pennies, pence, copper, coppers
8: twopenny, twopennies, twopence, tuppence, half groat, half groats
12: threepence, threepenny, threepennies, threepenny bit, threepenny bits, thruppence, thrupenny, thrupennies, thrupenny bit, thrupenny bits
16: groat, groats
24: sixpence, sixpenny, sixpennies, sixpenny bit, sixpenny bits, tanner, tanners
48: shilling, shillings, bob
96: florin, florins, two bob bit, two bob bits
120: half crown, half crowns
240: crown, crowns
480: half sovereign, half sovereigns
504: half guinea, half guineas
960: pound, pounds, pounds sterling, sovereign, sovereigns, quid, quids
1008: guinea, guineas
(Eu não sou britânico, esta lista não é de modo algum autoritária, mas será suficiente para o desafio.)
Via stdin ou argumento de função, você deve usar uma string do formulário
[value to convert] [denomination 1] in [denomination 2]
e devolver ou imprimir
[value to convert] [denomination 1] is [converted value] [denomination 2]
onde [converted value]
é [value to convert]
unidades de denominação 1 convertido para denominação 2.
O [value to convert]
e [converted value]
são flutuadores positivos. Na saída, ambos devem ser arredondados ou truncados com 4 casas decimais. Se desejar, você pode assumir [value to convert]
sempre que tem um ponto decimal e zero ao inserir (por exemplo, em 1.0
vez de 1
).
As denominações 1 e 2 podem ser quaisquer dois termos da lista acima. Não se preocupe se são plurais ou não, trate todas as denominações e sinônimos da mesma forma. Você pode assumir que o formato e as denominações de entrada são sempre válidos.
Exemplos
1 pounds in shilling
→ 1 pounds is 20 shilling
(tudo 1.0000 pounds is 20.0000 shilling
bem)
0.6 tuppence in tanner
→ 0.6 tuppence is 0.2 tanner
24 two bob bits in pounds sterling
→ 24 two bob bits is 2.4 pounds sterling
144 threepennies in guineas
→ 144 threepennies is 1.7143 guineas
Pontuação
O código mais curto em bytes vence.
fonte
quid
équid
. Provavelmente isso teria sido o mesmo com o dinheiro antigo. Exemplo:Five quid a pint! Cor blimey guvnor
. Exceção: quids-inRespostas:
Pyth ,
146145Mais legível (novas linhas e recuos devem ser removidos para serem executados):
Atualização: Acontece que é 1 caractere menor (não é necessário espaço) para dividir a string em uma lista de 2 strings antes de executar a operação de índice de strings.
/x"string"<b2 2
->xc"string"2<b2
. Nada mais precisa ser mudado.Como funciona:
Isso usa a abordagem do @ xnor de procurar o valor da moeda usando suas duas primeiras letras, bem como o truque de detectar a inicial
half
outwo
removê-la e chamar a função novamente.Para pesquisar o valor dos dois primeiros caracteres, ele localiza o local das duas primeiras letras da moeda em uma sequência de caracteres, depois divide por 2 e assume o valor nesse índice na lista. Isso é muito mais curto que um ditado em pyth.
Usa o fato de que
x
(localizar na sequência de caracteres) retorna -1 em caso de falha para evitar colocarpo
(libras)qu
(quid) ouso
(soberanos) na sequência e simplesmente retorna o último elemento da lista, 960, por padrão.Reorganizando a ordem das moedas no sistema de pesquisa e inicializando com cuidado, com
K4
eJ24
, todos os espaços que seriam necessários para separar números na lista foram removidos.Usa o operador de atribuição dupla do pyth,,
A
na divisão de entradain
para obter o início e o fim da entrada em variáveis separadas.Faz essencialmente a mesma pesquisa no final, embora pyth não tenha
.split(_,1)
, por isso é um pouco mais complicado.Exemplos:
fonte
<
e>
trabalhei como operadores de string / list slice; isso é muito, muito melhor do que tomar na cabeça ou no final de uma costeleta :)Ruby,
345306302288287278273253252242232221202190 bytesPega a entrada de STDIN e imprime em STDOUT.
Estou usando expressões regulares curtas para corresponder apenas às denominações desejadas para cada valor. Existem duas matrizes, uma com expressões regulares e outra com valores, nos índices correspondentes. A matriz regex é uma literal de matriz delimitada por espaço e a matriz de valores é compactada em uma sequência de caracteres UTF-8.
Estou selecionando o índice nos valores pesquisando por uma regex que corresponda a cada denominação. Também estou padronizando o caso tuppence / half-groat (valor 8), porque isso exigia a maior expressão regular. Da mesma forma, alguns padrões assumem que outros valores já foram correspondidos por padrões anteriores, portanto, cada regex distingue apenas o valor desejado apenas dos demais. Usando isso, eu provavelmente poderia economizar mais alguns bytes reorganizando a ordem das denominações.
Agradeço ao Ventero por me ajudar a
vencer o Pyth,tornando-o mais curto!fonte
s[k]
) que substitui$1
etc. Você pode salvar alguns caracteres movendo o bloco de mapa para um lambda e chamando isso diretamente na última linha (que também permite que você descarte as atribuições de$1
e$2
). Também.index
é mais curto que.find_index
.Regexp.new k
→/#{k}/
e$><<gets.sub(/foo/){a=$3;...}
→gets[/foo/];a=$3;puts...
para um total de 221. E é claro que você pode usar o velho truque de empacotar a matriz int em uma string (using.pack("U*")
) e depois indexar nessa string. Você deve reduzir para 195 chars / 200 bytes.a=gets[/foo/,3]
Python 3:
264239 caracteresA função
f
obtém o valor de shilling da string da moedac
, imprimindo as duas primeiras letrasusando o dicionário, encontrando-as em uma string. Os prefixos "half" e "two" são detectados e contabilizados cortando o prefixo e o espaço e aplicando um multiplicador. Como "halfpenny" não possui espaço após "half", isso resulta em "enny", mas isso é tratado com uma entrada fictícia "en".Obrigado a @isaacg e @grc por muitas melhorias na pesquisa de dicionário.
fonte
2/4**(c<'t')
parte..get(c[:2],960)
para pesquisar o valor do dicionário e omitir aspo=960,so=960,qu=960,
entradas do dicionário.Python 2 - 345
358Requer que o número de entrada seja um float em python, isto é
144.1
Eu acho que isso pode ser reduzido em python 3 ...
... Confirmado graças a @xnor. Também confirmou que ter um algoritmo melhor é muito importante;)
fonte
q=raw_input().split(' in ')
porq,b=raw_input().split(' in ')
h+' gr':8
eh+' g':504
dependendo de quem é avaliado primeiro por meio grumosu
ao um guinéu ...Haskell - 315 bytes
fonte
JavaScript (ES5), 344
Fui com uma abordagem de função hash ... Acho que subestimei (relativamente) o quão complexo seria o processamento de entrada (sobre a abordagem regex, que não se importaria com o número).
fonte
Com base na resposta de @ FryAmTheEggMan, com uma maneira diferente de testar
str.startwith
:Python 2: 317
fonte
print
na string formatada. Você também pode reescrever o lambdas=lambda x:x and C.get(x,s(x[:-1]))or 0
para salvar um caractere (junto com os espaços). Esta é uma grande idéia, btw :)and/or
.u.split(' ')
dizer algou.split(' ',1)
para moedas que têm espaços, como "meio soberano"., 1
!x and y or 0
pode ser encurtado em geral parax and y
, uma vez que ambos avaliam0
ou equivalentementeFalse
quandox
é Falsey.JavaScript ES6, 264
273Mostrar snippet de código
Isso obtém o valor de cada moeda, comparando-a com várias regexes, começando pela mais ampla
/t/
; o valor será substituído se outra correspondência for encontrada. Pode haver uma maneira de economizar alguns bytes reordenando a string regex. Você pode testá-lo usando o trecho de código acima (ele está formatado apenas para usar caixas de diálogo e remover as funções de seta ES6 para que todos possam testar o código facilmente). Obrigado a Alconja pelas sugestões.fonte
't0sh|bo0^p....'.split(0)
, 4 mais, usando.map
, em vez de.forEach
e 3 mais chamandoc(0)
ec(1)
e fazendos[d].match