Esse valor pode ser obtido com moedas e / ou notas exclusivas?


29

Escreva um programa que calcule se um valor monetário inserido, como um inteiro, pode ser representado por uma combinação única de moedas e / ou notas, o que significa que a mesma moeda / nota não pode ser usada mais de uma vez.

Seu programa deve ter um valor como entrada e pode obter uma lista de valores de moedas / notas via entrada ou pelo equivalente no idioma de uma matriz. A lista de moedas / notas deve poder ser alterada; portanto, verifique se é claro onde isso está definido se você estiver usando uma constante.

Seu programa deve gerar qualquer valor de verdade / falsidade, respectivamente.

Observe que não é necessário exibir a lista de moedas / notas que compõem o valor .

EXEMPLO

Usando a libra esterlina, (£ 1,00 = 100 e 420,69 = 42069)

coins = [1, 2, 5, 10, 20, 50, 100, 200, 500, 1000, 2000, 5000]

A seguinte saída será verdadeira:

6 (1, 5)
15 (10, 5)
88 (1, 2, 5, 10, 20, 50)
512 (500, 10, 2)
7003 (5000, 2000, 2, 1)

A seguir, o resultado será falso:

4
209
8889
4242424242
[ANYTHING ABOVE 8888]

DADOS ALTERNATIVOS DO ENSAIO (dólar americano)

coins = [1, 5, 10, 25, 50, 100, 200, 500, 1000, 2000, 5000, 10000]

Boa sorte!


4
Eu gostaria que têm mais recém-chegados como você ...
Leaky Nun


2
Você deve adicionar alguns casos de teste usando um conjunto diferente de moeda
Leaky Nun

2
Eu sugeriria adicionar casos de teste que não podem ser resolvidos com a heurística gananciosa de pegar a maior moeda não utilizada que seja, no máximo, o valor restante. Também seria bom ter aqueles em que a entrada não é classificada e onde um valor pode ser feito de mais de uma maneira. Geralmente é bom para os casos de teste evitar a possibilidade de alguém fazer uma tentativa razoável do problema que funciona para os casos de teste sem estar certo em tudo.
xnor

2
Relacionado . Também relacionado . A pergunta anterior é sem dúvida uma duplicata, mas essa pergunta é melhor projetada pela IMO e, se quisermos fechar uma como duplicada, prefiro fechar a mais antiga.

Respostas:


13

Braquilog 2 (TIO Nexus), 2 bytes

⊇+

Experimente online!

Pega a lista de moedas via entrada padrão ou anexa-a ao início do programa como uma matriz literal (ou funcionará, então você decide como você se sente "mais legítimo"; a primeira é permitida por padrão Regras do PPCG, este último especificamente permitido pela questão); e pega o valor a ser produzido como argumento da linha de comando.

Explicação

Este programa utiliza detalhes de implementação do funcionamento do wrapper do TIO Nexus para Brachylog; especificamente, ele permite que você forneça um argumento de linha de comando para dar entrada via Saída. (Isso não estava previsto no design original do Brachylog; no entanto, as linguagens são definidas por sua implementação no PPCG e, se surgir uma implementação que faz o que eu preciso, posso tirar vantagem disso.) programa se parece com isso:

⊇+
⊇   Some subset of {standard input}
 +  sums to {the first command-line argument}

Como um programa completo, ele retorna um valor booleano; true.se todas as asserções do programa puderem ser satisfeitas simultaneamente ou false.se não puderem.

(Um lembrete ou para pessoas que ainda não sabem: o Brachylog 2 usa sua própria codificação de caracteres, com um único byte de comprimento.)


Você disse que ⊇ é um único byte no Brachylog, por que não cola os bytes aqui? Aposto que há uma razão para isso, estou apenas interessado, um pouco como um nó de codificação de caracteres.
theonlygusti

11
Eles estão codificados no disco como 08 2B(você pode procurar as codificações aqui em cima ). A razão de eu não listar a codificação específica é que é irrelevante; o que realmente importa é que o Brachylog não use mais que 256 caracteres únicos, para que cada um possa ser representado em um único byte. Isso geralmente é feito por idiomas de golfe para tornar o código mais legível; eles poderiam usar uma codificação como a página de código 437, mas se você fizesse isso, ninguém seria capaz de lê-la .

10

05AB1E , 4 bytes

æOså

Explicação:

æ      Calculate the powerset of the first input
 O     Sum each element
  s    Put the second input at the top of the stack
   å   Check whether the input is in the powerset sum.

Experimente online!


Parece que você tem enganado oficialmente todos para comprimir a lista; p
Leaky Nun

Depois de ter eliminado sua lista de comprimido e mudou-se para a entrada, eu vou apagar a minha resposta (porque no momento em nossas respostas seria o mesmo)
Leaky Nun

Esta comunidade é cheia de gênios.
Tobi

5

Mathematica, 25 bytes

!FreeQ[Tr/@Subsets@#,#2]&

Função pura pegando uma matriz de valores de moeda como o primeiro argumento e o número inteiro alvo como o segundo argumento e retornando Trueou False.



3

Retina , 52 31 bytes

\d+
$*
^((1+) |1+ )+(?<-2>\2)+$

Experimente online! Recebe a entrada como uma lista separada por espaços de moedas e notas, seguida pelo valor desejado. Edit: Salvo 18 bytes graças a @Kobi que depurou meu código. Explicação: As duas primeiras linhas simplesmente convertem de decimal para unário. A terceira linha captura a lista de moedas e notas. A alternância permite que o mecanismo volte atrás e opte por não capturar moedas / notas específicas. O grupo de balanceamento combina o valor com todos os sufixos da lista de captura (desnecessário, mas mais golfista).


A segunda opção não funciona porque o mecanismo não retorna em grupos de tamanho 0 (uma otimização irritante). Você pode usar ^((1+) )+(\2?(?<-2>)|){99}$(34 bytes, com limite no número de moedas) ou ^((1+) |1+ )+(\2?(?<-2>))+$(também 34 bytes).
Kobi

11
@Kobi Beautiful! Salvei 2 bytes de ambas as respostas porque esqueci que isso (?<-2>\2?)funciona, além de mais um byte da sua segunda resposta, porque ela ?não é mais necessária.
Neil


2

Java (OpenJDK 8) , 125 bytes

boolean f(int[]c,int n){int l=c.length;if(l<1)return n==0;int[]a=java.util.Arrays.copyOf(c,l-1);return f(a,n-c[l-1])|f(a,n);}

Experimente online!


Fazer isso em um lambda pode torná-lo mais curto.
Okx

@Okx É recursivo (por isso seria mais longo), mais eu não faço lambdas, mesmo que sejam mais curtos.
Freira vazando

11
A versão iterativa do seu algoritmo é bem menor à medida que você remove a necessidade de copiar a matriz: boolean f(int[]c,int n){for(int l=c.length;l-->0;n-=n<c[l]?0:c[l]);return n<1;}(79 bytes). Com o Java 8 e suas lambdas, ele pode ser reduzido ainda mais para 62 bytes. Com relação à sua resposta como está atualmente, o int l=c.length-1uso em lvez de l-1também é mais curto.
Olivier Grégoire


2

JavaScript (ES6), 81 69 67 64 bytes

Leva a lista de moedas ce a quantidade alvo ana sintaxe de curry (c)(a). Retorna 0ou true.

c=>g=(a,m=1)=>c.map((c,i)=>x-=c*(m>>i&1),x=a)&&!x||x-a&&g(a,m+1)

Casos de teste


Você tem permissão para levar a lista de moedas?
Leaky Nun

@LeakyNun "... e pode pegar uma lista de valores de moedas / notas ..."
Martin Ender

11
Então eu codificado lista para nada ...
Leaky Nun

@LeakyNun Parece que sim
Eddie Hart

2

Haskell , 28 bytes

A função do operador (#)pega um número inteiro e uma lista de números inteiros (ou, geralmente, qualquer Traversablecontêiner de números) e retorna a Bool.

Use como 6#[1, 2, 5, 10, 20, 50, 100, 200, 500, 1000, 2000, 5000].

c#l=elem c$sum<$>mapM(:[0])l

Experimente online!

Como funciona

  • cé o valor desejado e la lista de valores da moeda.
  • mapM(:[0])lmapas (:[0])mais l, emparelhando cada valor com 0, e depois constrói o produto cartesiano, dando listas onde cada elemento é ou seu valor correspondente em l, ou 0.
  • sum<$>soma cada combinação e elem c$verifica se cestá na lista resultante.

2

R, 88 bytes

-5 bytes graças a @Jarko Dubbeldam

retorna uma função anônima. Ele gera todas as combinações possíveis de moedas (usando expand.gridpares de T,F) e verifica se os valores estão presentes. ké moedas, já que cé uma palavra reservada em R. Pode verificar vários valores de uma só vez.

function(k,v)v%in%apply(expand.grid(Map(function(x)!0:1,k)),1,function(x)sum(k[x]))

Experimente online!


Você pode substituir c(T,F)por !0:1e rep(list(!0:1),length(k))porlapply(k,function(x)!0:1)
JAD

11
Na verdade, faça issoMap(function(x)!0:1,k)
JAD 10/10

1

Japonês , 7 bytes

à mx èN

Experimente online! Saídas 0para falsy, um número inteiro positivo para a verdade.

Explicação

à mx èN
          // Implicit: U = input array, V = input integer, N = array of all inputs
à         // Take all combinations of U.
  mx      // Map each combination to its sum.
     è    // Count the number of items in the result which also exist in
      N   //   the array of inputs.
          // This returns 0 if no combination sums to V, a positive integer otherwise.
          // Implicit: output result of last expression


1

Ruby , 39 bytes

Retorna nilcomo o valor falso e o menor valor da moeda na lista que compõe o número como verdade (todos os números são verdadeiros em Ruby).

f=->c,n{n!=0?c.find{|i|f[c-[i],n-i]}:1}

Porém, lembre-se de que esse algoritmo é incrivelmente lento, com O(C!)complexidade de tempo, onde Cestá o tamanho da lista de moedas. Eventualmente, ele termina, mas a maioria dos casos de teste atinge o tempo limite na maioria dos intérpretes online f(UK_POUND, 5).

Aqui está uma versão de 41 bytes que termina muito mais rapidamente adicionando uma condição de finalização extra e é muito mais difícil realmente atingir o tempo limite

f=->c,n{n>0?c.find{|i|f[c-[i],n-i]}:n==0}

Experimente online!


1

Utilitários Bash + GNU, 56 39

printf %$2s|egrep "^ {${1//,/\}? {}}?$"

A lista de denominações de entrada (sem classificação) é fornecida como uma lista separada por vírgulas. A lista de entrada e o valor são fornecidos como parâmetros de linha de comando.

Saída fornecida na forma do código de retorno do shell. Inspecione echo $?depois de executar o script. 0significa verdade, 1significa falsidade.

Experimente online .

  • printf %$2sgera uma sequência de valueespaços
  • "^ {${1//,/\}? {}}?$"é uma expansão de shell que expande a lista de denominação para um regex como ^ {1}? {2}? {5}? {10}? ... $. Acontece que o egrepmecanismo regex é inteligente o suficiente para corresponder corretamente a isso, independentemente da ordem em que as denominações estão
  • egrep verifica se a sequência de espaços corresponde à regex

1

C, 66 bytes

m;v;f(n){for(m=1e5;m/=10;)for(v=5;n-=n<v*m?0:v*m,v/=2;);return!n;}

Veja como funciona aqui .

C, 53 bytes

g(c,w,n)int*c;{for(;n-=n<c[--w]?0:c[w],w;);return!n;}

Essa variante pega a matriz de moedas, que anula o objetivo desse problema, porque se resume a uma simples subtração.

O primeiro argumento é a matriz de moedas, o segundo é a contagem de moedas e o terceiro é o valor.

C, 48 bytes

g(c,n)int*c;{for(;n-=n<*c?0:*c,*++c;);return!n;}

Uma alternativa para a variante anterior. Ele pressupõe que a matriz de moedas possa ser revertida e terminada em zero.



0

CJam , 18 17 bytes

q~_,2\m*\f.*::+#)

Experimente online!

Explicação

q~                  e# Read and eval input.
  _,                e# Duplicate the money list and take its length.
    2\m*            e# Take the (length)th Cartesian power of [0 1].
        \f.*        e# Element-wise multiplication of each set of 0's and 1's with the money
                    e#   list. This is essentially the powerset, but with 0s instead of 
                    e#   missing elements.
            ::+     e# Sum each set.
               #    e# Find the index of the desired amount in the list. (-1 if not found)
                )   e# Increment. -1 => 0 (falsy), anything else => nonzero (truthy)



0

Oitava, 39 bytes

 @(L,n)any(cellfun(@sum,powerset(L))==n)

Uma função anônima que pega uma matriz de valores de moeda como o primeiro argumento e o número inteiro de destino como o segundo argumento e retorna verdadeiro ou falso.

Experimente online!


0

Mathematica, 42 bytes

ListQ@NumberDecompose[#,Sort[#2,Greater]]&

entrada

[15, 10,5}]

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.