Golf-me algum dinheiro no caixa eletrônico

26

A tarefa é simples. Tirem-me alguns 1000, 500e 100notas.

Como ? você pode perguntar. Não se preocupe, não há necessidade de roubar um banco, pois há um caixa eletrônico nas proximidades que aceita seu cartão de crédito. Mas seu limite de crédito é suficiente para a tarefa, portanto, você deve ter cuidado com as retiradas.

Desafio

Dado o número de 1000, 500e 100notas necessário, calcular os levantamentos específicos necessários para obter, pelo menos aquelas muitas notas. Em cada retirada, o caixa eletrônico pode cuspir cada uma das notas com base nas seguintes regras:

  • O valor retirado ( A) é menor que5000
    • Se A%1000 == 0, o ATM cospe 1 500nota, 5 100notas e 1000notas de repouso
    • Else if A%500 == 0, a ATM cospe 5 100notas, descansar 1000notas
    • Caso contrário A%1000 < 500, o ATM cospe floor(A/1000) 1000notas e 100notas de repouso
    • Caso contrário A%1000 > 500, o ATM cospe floor(A/1000) 1000notas, 1 500e 100notas de repouso
  • O valor retirado é maior que igual a 5000
    • Se A%1000 == 0, então, o ATM cospe 2 500notas e restantes 1000notas
    • Caso contrário A%500 == 0, o ATM cospe 1 500nota e outras 1000notas
    • Caso contrário A%1000 < 500, o ATM cospe floor(A/1000) 1000notas e 100notas de repouso
    • Caso contrário A%1000 > 500, o ATM cospe floor(A/1000) 1000notas, 1 500e 100notas de repouso

Para esclarecimento, segue uma tabela completa de notas retiradas para todos os valores possíveis até 7000(você pode retirar mais, mas o padrão não muda posteriormente). A ordem é <1000> <500> <100>:

 100 => 0 0 1                  2500 => 2 0 5                   4800 => 4 1 3
 200 => 0 0 2                  2600 => 2 1 1                   4900 => 4 1 4
 300 => 0 0 3                  2700 => 2 1 2                   5000 => 4 2 0
 400 => 0 0 4                  2800 => 2 1 3                   5100 => 5 0 1
 500 => 0 0 5                  2900 => 2 1 4                   5200 => 5 0 2
 600 => 0 1 1                  3000 => 2 1 5                   5300 => 5 0 3
 700 => 0 1 2                  3100 => 3 0 1                   5400 => 5 0 4
 800 => 0 1 3                  3200 => 3 0 2                   5500 => 5 1 0
 900 => 0 1 4                  3300 => 3 0 3                   5600 => 5 1 1
1000 => 0 1 5                  3400 => 3 0 4                   5700 => 5 1 2
1100 => 1 0 1                  3500 => 3 0 5                   5800 => 5 1 3
1200 => 1 0 2                  3600 => 3 1 1                   5900 => 5 1 4
1300 => 1 0 3                  3700 => 3 1 2                   6000 => 5 2 0
1400 => 1 0 4                  3800 => 3 1 3                   6100 => 6 0 1
1500 => 1 0 5                  3900 => 3 1 4                   6200 => 6 0 2
1600 => 1 1 1                  4000 => 3 1 5                   6300 => 6 0 3
1700 => 1 1 2                  4100 => 4 0 1                   6400 => 6 0 4
1800 => 1 1 3                  4200 => 4 0 2                   6500 => 6 1 0
1900 => 1 1 4                  4300 => 4 0 3                   6600 => 6 1 1
2000 => 1 1 5                  4400 => 4 0 4                   6700 => 6 1 2
2100 => 2 0 1                  4500 => 4 0 5                   6800 => 6 1 3
2200 => 2 0 2                  4600 => 4 1 1                   6900 => 6 1 4
2300 => 2 0 3                  4700 => 4 1 2                   7000 => 6 2 0
2400 => 2 0 4

Lista fornecida por Martin

A pegada

Como o limite de crédito no seu cartão de crédito é apenas o suficiente, você precisa garantir que o valor total retirado entre as retiradas seja o mínimo possível para a entrada / requisito especificado de notas.

Entrada

A entrada pode estar em qualquer formato favorável para três números correspondentes ao número de notas necessárias para o valor 1000, 500e 100. Não necessariamente nesta ordem.

Saída

Saída é a quantia a ser retirada em cada transação separada por uma nova linha.

Exemplos

Entrada (formato <1000> <500> <100>):

3 4 1

Saída:

600
600
600
3600

mais alguns:

7 2 5
5000
3500

1 2 3
600
1700

21 14 2
600
600
600
1600
5000
5000
5000
5000
5000

Suposições

  • Você pode assumir que o caixa eletrônico possui um número infinito de notas de cada quantia.
  • Você também pode assumir que pode fazer qualquer número de transações.
  • Além disso, a solução para alguns valores de entrada pode não ser única, portanto, você pode produzir qualquer 1 da solução que atenda à quantidade mínima possível e que anote as condições necessárias.

Como de costume, você pode escrever uma entrada completa de leitura de programa via STDIN / ARGV e imprimir a saída em STDOUT ou uma função que recebe entrada por meio de argumentos e retorna uma lista de números inteiros correspondentes aos valores ou uma string com valores separados por uma nova linha.

Este é o código-golfe, pelo que o código mais curto em bytes vence.

Optimizer
fonte
@nutki de fato. Editado.
Optimizer
Existem restrições de velocidade? O último caso de teste deve ser 21 14 2concluído em um tempo razoável?
Jakube
1
@Jakube Em um tempo razoável - sim (diga menos de 5-6 horas). Mas, como tal, não há limite, pois isso é código-golfe.
Optimizer
Então, se eu retirar 0, ele me dará cinco notas 100?
precisa saber é o seguinte
@AJMansfield, claro que não. Você não pode retirar 0 valor
Optimizer

Respostas:

7

JavaScript, 184 148

function g(a,b,c){x=[];while(a>0||b>0||c>0){i=b<3||a<4?a:4;a-=i;if(i>3&&b>1){b-=2;i++}else{i+=(c--<b&&i>4?0:.1)+(b-->0?.5:0)}x.push(i*1e3)}return x}

http://jsfiddle.net/vuyv4r0p/2/

retorna uma lista de números inteiros correspondentes aos valores de retirada

hoffmale
fonte
Tente g(5,1,1). Uma solução melhor: 5600.
precisa saber é o seguinte
deve ser corrigido agora
hoffmale
g(5,1,0), Solução: 5500.
precisa saber é o seguinte
que devem agora também ser fixado ^^ obrigado por apontar isso, devo ser muito sono
hoffmale
g(5,2,0), Solução: 6000.
precisa saber é o seguinte
1

Perl 5: 223

Editar

Esta solução foi feita com a suposição errada de que 7K é o limite do ATM. Isso realmente tornou a tarefa mais interessante, pois exigia programação dinâmica (o padrão de movimentação era bastante regular, mas a codificação seria provavelmente mais longa do que o cálculo ao vivo como eu). Com qualquer quantia possível, o padrão de movimentação é tão regular que é trivial codificá-lo. Não sei se a solução do @hoffmale agora está correta, mas estará entre essas linhas. Por isso, infelizmente, será outra tarefa em que primeiro alguém vem com uma solução e depois é transportado para uma linguagem de golfe para uma vitória.

Um pouco mais lento que a solução original (mas ainda sub-segundo para parâmetros abaixo de 100).

#!perl -pa
$c{0,0}=$f=($a,$b,$c)=@F;for$i(0..$b){for$j(0..$a){
/.(?=.$)/>($n=$c{$i-$`,$j-$'})||${$r=\$c{$i,$j}}<($x=$n+$&)&&$$r
or$f=$$r="$x $n".($'.$&+5*$`)."00
"for 204..206,105,106,11..15,110..114}}$_=$f."100
"x($c-$f+3);s/.*\b3//

Solução 259 mais rápida.

#!perl -pa
$c{0,0}=($a,$b,$c)=@F;for$i(0..$b){for$j(0..$a){
/\B./<($%=$c{$i-$&,$j-$'}+$`)&&(!${$r=\$c{$i,$j}}||$$r>$%)and$d{$i,$j}=$_,$$r=$%for
qw/024 025 026 015 016/,101..105,110..114}}
$d{$b,$a}=~/\B./,$c-=$`,$b-=$&,$a-=$',print$'.$`+5*$&,"00
"while$a+$b;$_="100
"x$c

Usa STDIN:

$perl atm.pl <<<"21 14 2"
5000
5000
5000
5000
5000
600
600
600
1600
nutki
fonte
Tente 10 0 0. Solução melhor: 10100.
precisa saber é o seguinte
@ user23013 opa, eu entendi mal a pergunta. Presumi 7k é a quantidade máxima :( Espero ser capaz de corrigi-lo.
nutki