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.