Faça zero a partir dos primeiros números 'n'

15

Desafio

O desafio é escrever um código que use um número inteiro positivo 'n' como entrada e exiba todas as maneiras possíveis pelas quais os números de 1 - n podem ser escritos, com sinal positivo ou negativo entre eles, de forma que sua soma seja igual a zero. Lembre-se de que você só pode usar adição ou subtração.

Por exemplo, se a entrada for 3, existem 2 maneiras de fazer a soma 0:

 1+2-3=0
-1-2+3=0

Observe que os números estão em ordem, começando de 1 até n (que é 3 neste caso). Como é evidente no exemplo, o sinal do primeiro número também pode ser negativo, portanto, tenha cuidado.

Agora, 3 era praticamente simples. Vamos listar todas as maneiras quando consideramos o número 7.

 1+2-3+4-5-6+7=0
 1+2-3-4+5+6-7=0
 1-2+3+4-5+6-7=0
 1-2-3-4-5+6+7=0
-1+2+3+4+5-6-7=0
-1+2-3-4+5-6+7=0
-1-2+3+4-5-6+7=0
-1-2+3-4+5+6-7=0

Então aqui temos um total de 8 maneiras possíveis.


Entrada e saída

Como afirmado anteriormente, a entrada seria um número inteiro positivo . Sua saída deve conter todas as formas possíveis pelas quais os números dão uma soma de zero. Caso não exista uma maneira possível de fazer o mesmo, você pode produzir o que quiser.

Além disso, você pode imprimir a saída em qualquer formato que desejar . Mas, deve ser compreensível . Por exemplo, você pode imprimi-lo como no exemplo acima. Ou você pode apenas imprimir os sinais dos números em ordem. Caso contrário, você também pode imprimir '0 e' 1 'em ordem, onde' 0 'exibirá sinal negativo e' 1 'exibirá sinal positivo (ou vice-versa).

Por exemplo, você pode representar 1 + 2-3 = 0 usando:

1+2-3=0
1+2-3
[1,2,-3]
++-
110
001    

No entanto, eu recomendaria o uso de qualquer um dos três primeiros formatos para simplificar. Você pode assumir que todas as entradas são válidas.


Exemplos

7 ->

 1+2-3+4-5-6+7=0
 1+2-3-4+5+6-7=0
 1-2+3+4-5+6-7=0
 1-2-3-4-5+6+7=0
-1+2+3+4+5-6-7=0
-1+2-3-4+5-6+7=0
-1-2+3+4-5-6+7=0
-1-2+3-4+5+6-7=0

4 ->

 1-2-3+4=0
-1+2+3-4=0

2 -> -

8 ->

 1+2+3+4-5-6-7+8=0
 1+2+3-4+5-6+7-8=0
 1+2-3+4+5+6-7-8=0
 1+2-3-4-5-6+7+8=0
 1-2+3-4-5+6-7+8=0
 1-2-3+4+5-6-7+8=0
 1-2-3+4-5+6+7-8=0
-1+2+3-4+5-6-7+8=0
-1+2+3-4-5+6+7-8=0
-1+2-3+4+5-6+7-8=0
-1-2+3+4+5+6-7-8=0
-1-2+3-4-5-6+7+8=0
-1-2-3+4-5+6-7+8=0
-1-2-3-4+5+6+7-8=0

Pontuação

Isso é , então o código mais curto vence!

Manish Kundu
fonte
Observe que este não é um truque do codegolf.stackexchange.com/questions/8655/… , porque esse desafio deve levar apenas n como entrada e usar todos os números 1-n em ordem.
Manish Kundu
Podemos representar +como Ne -como -N, ou isso está levando isso longe demais? (eg 3-> [[-3,-3,3], [3,3,-3]])
Jonathan Allan
@ JonathanAllan Isso não é mencionado na lista de formatos de saída? Ou interpretei erroneamente sua pergunta?
Manish Kundu
Quero dizer como a opção 0e, 1mas usando Ne -N(veja minha edição acima)
Jonathan Allan
2
@ JonathanAllan Sim, isso certamente é permitido. Certifique-se de mencionar isso na resposta.
Manish Kundu

Respostas:

5

Geléia , 9 bytes

1,-ṗ×RSÐḟ

Experimente online!

Exp

1,-ṗ×RSÐḟ  Main link. Input = n. Assume n=2.
1,-        Literal list [1, -1].
   ṗ       Cartesian power n. Get [[1, 1], [1, -1], [-1, 1], [-1, -1]]
    ×R     Multiply (each list) by Range 1..n.
       Ðḟ  ilter out lists with truthy (nonzero)
      S      Sum.

Geléia , 9 bytes

A sugestão de Jonathan Allan apresenta uma lista de sinais.

1,-ṗæ.ÐḟR

Experimente online!

user202729
fonte
1
Que tal (ab?) Usar o formato de saída lax com ,Nṗæ.ÐḟR?
Jonathan Allan
Ou, alternativamente, essa saída é multiplicada pelas saídas n.
user202729
O Ne -Nsaída sugeri foi permitido, de modo que economiza um byte :) (apenas preciso mencionar o formato da resposta)
Jonathan Allan
5

Python 2 , 62 bytes

f=lambda n,*l:f(n-1,n,*l)+f(n-1,-n,*l)if n else[l]*(sum(l)==0)

Experimente online!

O Sr. Xcoder economizou 4 bytes com um uso bacana de argumentos estrelados.

xnor
fonte
1
62 bytes usando em *lvez del=[]
Sr. Xcoder 03/02
3

Perl, 37 36 bytes

perl -E 'map eval||say,glob join"{+,-}",0..<>' <<< 7
Ton Hospel
fonte
Bem feito. Você pode soltar -ne <<<se substituir $_por pop. Na verdade, não melhorar a sua pontuação, mas faz a expressão geral mais curto;)
Chris
2

05AB1E , 11 bytes

®X‚¹ãʒ¹L*O_

Experimente online!

O formato de saída para, por exemplo, entrada 3é:

[[-1, -1, 1], [1, 1, -1]]

Isto é -1-2+3, 1+2-3.

Erik, o Outgolfer
fonte
2

Casca , 10 bytes

fo¬ΣΠmSe_ḣ

Experimente online!

Explicação

Não é muito complicado.

fo¬ΣΠmSe_ḣ  Implicit input, say n=4
         ḣ  Range: [1,2,3,4]
     m      Map over the range:
      Se     pair element with
        _    its negation.
            Result: [[1,-1],[2,-2],[3,-3],[4,-4]]
    Π       Cartesian product: [[1,2,3,4],[1,2,3,-4],..,[-1,-2,-3,-4]]
f           Keep those
   Σ        whose sum
 o¬         is falsy (equals 0): [[-1,2,3,-4],[1,-2,-3,4]]
Zgarb
fonte
2

Python 3 , 105 bytes

lambda n:[k for k in product(*[(1,-1)]*n)if sum(-~n*s for n,s in enumerate(k))==0]
from itertools import*

Experimente online!

ovs
fonte
1

Rápido , 116 bytes

func f(n:Int){var r=[[Int]()]
for i in 1...n{r=r.flatMap{[$0+[i],$0+[-i]]}}
print(r.filter{$0.reduce(0){$0+$1}==0})}

Experimente online!

Explicação

func f(n:Int){
  var r=[[Int]()]                         // Initialize r with [[]]
                                          // (list with one empty list)
  for i in 1...n{                         // For i from 1 to n:
    r=r.flatMap{[$0+[i],$0+[-i]]}         //   Replace every list in r with the list
  }                                       //   prepended with i and prepended with -i
  print(r.filter{$0.reduce(0){$0+$1}==0}) // Print all lists in r that sums to 0
}
Herman L
fonte
1

Python 2 , 91 bytes

lambda x:[s for s in[[~j*[1,-1][i>>j&1]for j in range(x)]for i in range(2**x)]if sum(s)==0]

Experimente online!

Retorna uma lista de listas satisfatórias (por exemplo, f (3) = [[- 1, -2,3], [1,2, -3]])

Chas Brown
fonte
1

C (gcc) , 171 bytes

k,s;f(S,n,j)int*S;{if(j--)S[j]=~0,f(S,n,j),S[j]=1,f(S,n,j);else{for(s=k=0;k<n;k++)s+=S[k]*-~k;if(!s&&puts(""))for(k=0;k<n;)printf("%d",S[k++]+1);}}F(n){int S[n];f(S,n,n);}

Experimente online! Usa 0para 2sinais negativos e positivos.

Jonathan Frech
fonte
1

Limpo , 79 bytes

import StdEnv
$n=[k\\k<-foldr(\i l=[[p:s]\\s<-l,p<-[~i,i]])[[]][1..n]|sum k==0]

Experimente online!

Furioso
fonte
1

Python 3 + numpy, 104 103 bytes

import itertools as I,numpy as P
lambda N:[r for r in I.product(*[[-1,1]]*N)if sum(P.arange(N)*r+r)==0]

A saída é [-1, 1] correspondente ao sinal.

user2699
fonte
Você pode remover o espaço anterior ifpara -1 byte
ovs 03/02
0

JavaScript (ES6), 69 61 bytes

Economizou 8 bytes ao se livrar de k , como sugerido por @Neil

Imprime todas as soluções com alerta () .

f=(n,o='')=>n?f(n-1,o+'+'+n)&f(n-1,o+'-'+n):eval(o)||alert(o)

Casos de teste

Usando console.log () em vez de alert () para facilidade de uso.

Arnauld
fonte
Você precisa k? Algo parecido com isto: #f=(n,o='')=>n?['+','-'].map(c=>f(n-1,c+n+o)):eval(o)||alert(o)
Neil
@ Neil eu realmente não ... Obrigado.
Arnauld
0

Retina , 73 bytes

.+
*
_
=_$`
+0`=
-$%"+
(-(_)+|\+(_)+)+
$&=$#2=$#3=
G`(=.+)\1=
=.*

_+
$.&

Experimente online! Explicação:

.+
*

Converta a entrada para unário.

_
=_$`

Converta o número em uma lista de =números prefixados.

+0`=
-$%"+

Substitua cada um =por um -e ambos +, duplicando o número de linhas a cada vez.

(-(_)+|\+(_)+)+
$&=$#2=$#3=

Conte separadamente o número de _s após -s e +s. Isso soma os números negativos e positivos.

G`(=.+)\1=

Mantenha apenas as linhas em que os -es e os +cancelam.

=.*

Exclua as contagens.

_+
$.&

Converta para decimal.

Neil
fonte
0

Perl 6 , 43 bytes

{grep *.sum==0,[X] (1..$_ X*1,-1).rotor(2)}

Tente
Retorna uma sequência de listas

Expandido:

{  # bare block lambda with implicit parameter 「$_」

  grep              # only return the ones
    *.sum == 0,     # that sum to zero

    [X]             # reduce with cross meta operator

      (
          1 .. $_   # Range from 1 to the input

        X*          # cross multiplied by

          1, -1

      ).rotor(2)    # take 2 at a time (positive and negative)
}

1..$_ X* 1,-1(1, -1, 2, -2)
(…).rotor(2)((1, -1), (2, -2))
[X] …((1, 2), (1, -2), (-1, 2), (-1, -2))

Brad Gilbert b2gills
fonte
0

J , 35 30 bytes

-5 bytes graças ao FrownyFrog!

>:@i.(]#~0=1#.*"1)_1^2#:@i.@^]

Experimente online!

Original:

J , 35 bytes

[:(#~0=+/"1)>:@i.*"1(_1^[:#:@i.2^])

Como funciona

Multiplico a lista 1..n por todas as listas possíveis de coeficientes 1 / -1 e encontro as que somam zero.

                    (             ) - the list of coefficients
                             i.     - list 0 to 
                               2^]  - 2 to the power of the input
                     _1^[:          - -1 to the power of 
                          #:@       - each binary digit of each number in 0..n-1 to 
                 *"1                - each row multiplied by
            >:@i.                   - list 1..n
  (#~      )                        - copy those rows
     0=+/"1                         - that add up to 0
[:                                  - compose   

Experimente online!

Como alternativa, tentei um verbo explícito, usando a abordagem do produto cartesiano de +/-:

J , 37 bytes

3 :'(#~0=+/"1)(-y)]\;{(<"1@,.-)1+i.y'

{(<"1@,.-) encontra os produtos cartesianos, por exemplo:

{(<"1@,.-) 1 2 3
┌───────┬────────┐
│1 2 3  │1 2 _3  │
├───────┼────────┤
│1 _2 3 │1 _2 _3 │
└───────┴────────┘

┌───────┬────────┐
│_1 2 3 │_1 2 _3 │
├───────┼────────┤
│_1 _2 3│_1 _2 _3│
└───────┴────────┘

Pena que ele caixas o resultado, então eu gastei alguns bytes para desmarcar os valores

Experimente online!

Galen Ivanov
fonte
@FrownyFrog Obrigado, eu não estava feliz com o lado direito do meu código.
Galen Ivanov