Zeruj z pierwszych liczb n

15

Wyzwanie

Wyzwanie polega na napisaniu kodu, który przyjmuje dodatnią liczbę całkowitą n jako dane wejściowe i wyświetla wszystkie możliwe sposoby zapisywania liczb od 1 - n, ze znakiem dodatnim lub ujemnym pomiędzy, tak że ich suma wynosi równa zero. Pamiętaj, że możesz używać tylko dodawania lub odejmowania.

Na przykład, jeśli wartością wejściową jest 3, wówczas istnieją 2 sposoby, aby suma 0:

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

Zauważ, że liczby są w porządku, zaczynając od 1 do n (w tym przypadku jest to 3). Jak widać z przykładu, znak pierwszej liczby może być również ujemny, więc bądź ostrożny.

Teraz 3 było bardzo proste. Wymieńmy wszystkie sposoby, biorąc pod uwagę liczbę 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

Mamy więc tutaj 8 możliwych sposobów.


Wejście i wyjście

Jak wspomniano wcześniej, wejście będzie dodatnią liczbą całkowitą . Twój wynik powinien zawierać wszystkie możliwe sposoby, w jakie liczby dają sumę zero. Jeśli nie ma możliwości zrobienia tego samego, możesz wypisać cokolwiek chcesz.

Ponadto, można wydrukować dane wyjściowe w dowolnym formacie chcesz . Ale powinno to być zrozumiałe . Na przykład możesz wydrukować go jak w powyższym przykładzie. Lub możesz po prostu wydrukować znaki liczb w kolejności. W przeciwnym razie możesz również drukować „0” i „1” w kolejności, gdzie „0” wyświetla znak ujemny, a „1” wyświetla znak dodatni (lub odwrotnie).

Na przykład możesz przedstawić 1 + 2-3 = 0, używając:

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

Jednak dla uproszczenia zaleciłbym użycie jednego z trzech pierwszych formatów. Możesz założyć, że wszystkie dane wejściowe są prawidłowe.


Przykłady

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

Punktacja

To jest , więc wygrywa najkrótszy kod!

Manish Kundu
źródło
Należy pamiętać, że nie jest to duplikat codegolf.stackexchange.com/questions/8655/... , ponieważ to wyzwanie ma na celu przyjmowanie tylko n jako danych wejściowych i używanie wszystkich liczb 1-n w kolejności.
Manish Kundu
Czy możemy reprezentować +jako Ni -jako -N, czy to za daleko? (np. 3-> [[-3,-3,3], [3,3,-3]])
Jonathan Allan
@JonathanAllan Czy nie wymieniono tego na liście formatów wyjściowych? A może źle zinterpretowałem twoje pytanie?
Manish Kundu
Mam na myśli opcję 0i 1, ale używając Ni -N(patrz moja edycja powyżej)
Jonathan Allan
2
@JonathanAllan Tak, to z pewnością dozwolone. Pamiętaj, aby wspomnieć o tym w odpowiedzi.
Manish Kundu

Odpowiedzi:

5

Galaretka , 9 bajtów

1,-ṗ×RSÐḟ

Wypróbuj 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.

Galaretka , 9 bajtów

Sugestia Jonathana Allana , wypisz listę znaków.

1,-ṗæ.ÐḟR

Wypróbuj online!

użytkownik202729
źródło
1
Co powiesz na (ab?) Używając formatu wyjściowego Lax z ,Nṗæ.ÐḟR?
Jonathan Allan
Lub alternatywnie, to wyjście pomnoży wyjścia n.
user202729,
NI -Nwyjście Zasugerowałem została dopuszczona, dzięki czemu oszczędza jeden bajt :) (wystarczy wspomnieć format odpowiedź)
Jonathan Allan
5

Python 2 , 62 bajty

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

Wypróbuj online!

Pan Xcoder zapisał 4 bajty przy użyciu sprytnego użycia argumentów oznaczonych gwiazdką.

xnor
źródło
1
62 bajtów używając *lzamiastl=[]
pana Xcoder
3

Perl, 37 36 bajtów

perl -E 'map eval||say,glob join"{+,-}",0..<>' <<< 7
Ton Hospel
źródło
Ładnie wykonane. Można upuścić -ni <<<jeśli zastąpi $_się pop. To tak naprawdę nie poprawia twojego wyniku, ale sprawia, że ​​ogólna ekspresja jest krótsza;)
Chris
2

05AB1E , 11 bajtów

®X‚¹ãʒ¹L*O_

Wypróbuj online!

Format wyjściowy dla np. Danych wejściowych 3to:

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

Oznacza to, że -1-2+3, 1+2-3.

Erik the Outgolfer
źródło
2

Łuska , 10 bajtów

fo¬ΣΠmSe_ḣ

Wypróbuj online!

Wyjaśnienie

Niezbyt skomplikowane.

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
źródło
2

Python 3 , 105 bajtów

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

Wypróbuj online!

ovs
źródło
1

Szybki , 116 bajtów

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})}

Wypróbuj online!

Wyjaśnienie

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.
źródło
1

Python 2 , 91 bajtów

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]

Wypróbuj online!

Zwraca listę satysfakcjonujących list (np. F (3) = [[- 1, -2,3], [1,2, -3]])

Chas Brown
źródło
1

C (gcc) , 171 bajtów

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);}

Wypróbuj online! Używa znaków 0ujemnych i 2dodatnich.

Jonathan Frech
źródło
1

Czysty , 79 bajtów

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

Wypróbuj online!

Obrzydliwe
źródło
1

Python 3 + numpy, 104 103 bajty

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]

Wyjście wynosi [-1, 1] odpowiadające znakowi.

użytkownik2699
źródło
Możesz usunąć spację wcześniej ifdla -1 bajtów
ov
0

JavaScript (ES6), 69 61 bajtów

Zaoszczędzono 8 bajtów, pozbywając się k , jak sugeruje @Neil

Wyświetla wszystkie rozwiązania za pomocą alert () .

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

Przypadki testowe

Korzystanie z console.log () zamiast alert () w celu ułatwienia obsługi.

Arnauld
źródło
Czy trzeba k? Coś w tym stylu:f=(n,o='')=>n?['+','-'].map(c=>f(n-1,c+n+o)):eval(o)||alert(o)
Neil
@ Neil Naprawdę nie ... Dzięki.
Arnauld
0

Siatkówka , 73 bajty

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

_+
$.&

Wypróbuj online! Wyjaśnienie:

.+
*

Przekształć dane wejściowe w jednoargumentowe.

_
=_$`

Konwertuj liczbę na listę =liczb z prefiksem.

+0`=
-$%"+

Zastąp każdy =po kolei zarówno -i+ , za każdym razem duplikując liczbę linii.

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

Osobno policz liczbę _s po -s i+ s. To sumuje liczby ujemne i dodatnie.

G`(=.+)\1=

Zachowaj tylko te wiersze, w których -s i +s anulują się.

=.*

Usuń liczby.

_+
$.&

Konwertuj na dziesiętny.

Neil
źródło
0

Perl 6 , 43 bajtów

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

Spróbuj
Zwraca sekwencję list

Rozszerzony:

{  # 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
źródło
0

J , 35 30 bajtów

-5 bajtów dzięki FrownyFrog!

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

Wypróbuj online!

Oryginalny:

J , 35 bajtów

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

Jak to działa

Mnożę listę 1..n przez wszystkie możliwe listy współczynników 1 / -1 i znajduję te, które sumują się do zera.

                    (             ) - 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   

Wypróbuj online!

Alternatywnie spróbowałem jawnego czasownika, używając podejścia iloczynu kartezjańskiego +/-:

J , 37 bajtów

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

{(<"1@,.-) znajduje na przykład produkty kartezjańskie:

{(<"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│
└───────┴────────┘

Szkoda, że ​​zawiera wynik, więc wydałem trochę bajtów na rozpakowanie wartości

Wypróbuj online!

Galen Iwanow
źródło
@FrownyFrog Dziękuję, nie byłem zadowolony z prawej strony mojego kodu.
Galen Iwanow