Wyświetl * wszystkie * krotki!


35

Napisz program, podając dane wejściowe n , wygeneruje wszystkie możliwe n-krotki przy użyciu liczb naturalnych.

n=1
(1),(2),(3),(4),(5),(6)...

n=2
(1,1),(1,2),(2,1),(2,2),(1,3),(3,1),(2,3),(3,2),(3,3)...

n=6
(1,1,1,1,1,1) (1,1,1,1,2,1) (1,1,1,2,1,1)... 
  • Dane wyjściowe mogą być w dowolnej kolejności, która nie łamie żadnych innych reguł.
  • Program musi być napisany, aby działał wiecznie i teoretycznie wypisał wszystkie odpowiednie krotki dokładnie raz.
    • W rzeczywistości Twój program osiągnie limit typu liczby całkowitej i zawiesi się. Jest to dopuszczalne, o ile program działałby nieskończenie długo, gdyby tylko liczba całkowita była nieograniczona.
    • Każda poprawna krotka musi być wymieniona w skończonym czasie, jeśli tylko program mógł działać tak długo.
  • Dane wyjściowe mogą, według twojego wyboru, zawierać zera oprócz liczb naturalnych.
  • Możesz wybrać format wyjściowy programu dla swojej wygody, pod warunkiem, że separacja krotek i liczb w każdej krotce jest wyraźna i spójna. (Na przykład jedna krotka na linię.)
  • Wejście (n) jest liczbą całkowitą od jednego do sześciu. Wymagane zachowanie jest niezdefiniowane dla danych wejściowych poza tym zakresem.
  • Obowiązują zasady gry w golfa, wygrywa najkrótszy program.

Dzięki „Artemis Fowl” za opinie podczas fazy piaskownicy.


Zakładam, że jest to poprawne, jeśli gdy program się zawiesi, oprócz krotek wydrukowanych do tej pory, generuje jakieś dodatkowe dane wyjściowe, prawda?
Luis Mendo

1
Czy musimy wypisywać na bieżąco, czy funkcja wystarczająca do uzyskania nieskończonej listy pod koniec czasu wystarczy?
Jonathan Allan

6
„Możesz wybrać format wyjściowy programu dla swojej wygody, o ile separacja między krotkami i liczbami w każdej krotce jest wyraźna i spójna” - czy możemy wyprowadzać różne (choć konsekwentnie różne) separacje (np. Takie )?
Jonathan Allan

@JonathanAllan Musiałbym dołączyć wynik nieskończonej zawartości tego obiektu jako część programu.
billpg

1
Powiązane (liczby całkowite zamiast liczb naturalnych)
Esolanging Fruit

Odpowiedzi:


24

Łuska , 2 bajty

πN

Wypróbuj online!

Wyjaśnienie

Nto nieskończona lista liczb naturalnych [1,2,3,4,... πto potęga kartezjańska. Rezultatem jest nieskończona lista list. Każda lista pożądanej długości występuje dokładnie raz, ponieważ πjest fajna. Dane wejściowe i wyjściowe są niejawne.


1
Wow, a to też nie robi [1,1, n]. Czy istnieje wzorzec kolejności wysyłania?
billpg

1
@billpg Buduje rekurencyjnie krotki: n- krotki są uzyskiwane przez pobranie iloczynu kartezjańskiego z oryginalnej listy i listy n-1-tuple, w porządku rosnącym sumy indeksów.
Zgarb

„rosnąca kolejność sum wskaźników” - czy możesz to wyjaśnić? Mam problem ze zrozumieniem, dlaczego np. 2,2,2Przychodzi po 4,1,2i 5,1,1.
Jonasz

2
@Jonah Rekurencja działa w ten sposób. Zaczynasz z 1-krotkami od początku N. W przypadku 2-krotek bierzesz produkt kartezjański z Nuporządkowaną według sumy indeksów. Na obu listach każda liczba nma indeks, nwięc dla długości 2 wynik jest uporządkowany według sumy. Aby otrzymać 3-krotki, bierzesz iloczyn kartezjański Ni listę 2-krotek uporządkowanych według sumy wskaźników elementów na tych listach. Nie patrzy na sumę krotki, patrzy na jej pozycję na liście krotek.
Zgarb

2
„W tym zadaniu poznaj różne wymiary nieskończoności i znajdź wzór, który redukuje go do policzalnej nieskończoności, a następnie napisz program, który iteruje po tym wzorcu”. - „Hej, mam do tego wbudowane!”
Fabian Röling

10

Haskell , 62 bajty

([1..]>>=).(!)
0!s=[[]|s<1]
n!s=[a:p|a<-[1..s],p<-(n-1)!(s-a)]

Wypróbuj online!

n!sgeneruje wszystkie npary, które sumują się s.

Zatem odpowiedź brzmi ([1..]>>=).(!), tj \n -> [t | s<-[1..], t<-n!s].

Jest to funkcja mapująca liczbę całkowitą nna nieskończoną leniwą listę krotek (listy liczb całkowitych).


5

Haskell , 50 bajtów

f n=[l|k<-[0..],l<-mapM([0..k]<$f)[0..n],sum l==k]

Wypróbuj online!

Listy n-tuki posortowane według sumy. mapMwykonuje podnoszenie ciężarów w celu wygenerowania wszystkich nliczb od 0 do k. <$fSztuką jest wyjaśnione tutaj .

Haskell , 51 bajtów

f 1=pure<$>[0..]
f n=[a-k:k:t|a:t<-f$n-1,k<-[0..a]]

Wypróbuj online!

Rekurencyjnie rozciąga wszystkie- n-1pary na wszystkie- npary, dzieląc pierwszą liczbę akażdego n-1-tuszy na dwie liczby, a-k,kktóre sumują się na nią, w każdy możliwy sposób.


4

Pyth - 9 bajtów

Dzięki @FryAmTheEggman za golfa

Pętle przechodzą przez wszystkie x i przyjmują [1..x] ^ n. Powoduje to tworzenie duplikatów, więc zachowuje tylko te, które są nowe w tym x, czyli w nich x. Formatowanie jest trochę dziwne, ale można je ujednolicić o jeszcze jeden bajt,.V1j}#b^Sb

.V1}#b^Sb

Wypróbuj online .


1
f}bT-> }#bPonadto liczba bajtów wydaje się w tej chwili niepoprawna?
FryAmTheEggman

@FryAmTheEggman czekaj, dlaczego to jest niepoprawne? Jeśli mówisz o łączu TIO, który obejmuje formatowanie za pomocą j(b). Dziękuję również za golfa.
Maltysen

Ach, to mnie pomyliło, przepraszam!
FryAmTheEggman

3

Brachylog (v2), 9 bajtów

~l.ℕᵐ+≜∧≜

Wypróbuj online!

Jest to nieskończony generator, który generuje wszystkie możliwe krotki. Łącze TIO ma nagłówek, który używa generatora do wygenerowania 1000 elementów i wydrukowania ich (ale generator mógłby kontynuować w nieskończoność, gdybym o to poprosił; liczby całkowite Brachylog są nieograniczone).

Wydaje się, że powinien istnieć bardziej zwięzły sposób, ale istnieje wiele ograniczeń i to jest najkrótsze, w jakim mogę je zmieścić w jednym programie.

Wyjaśnienie

~l.ℕᵐ+≜∧≜
  .        Generate
        ≜  all explicit
~l         lists whose length is {the input}
    ᵐ      for which every element
   ℕ       is non-negative
     +     and whose sum
      ≜    is used to order the lists (closest to zero first)
       ∧   [remove unwanted implicit constraint]

Nawiasem mówiąc, wydaje mi się interesujące, jak różne są moje objaśnienia , pomimo tego, że robią dokładnie to samo z punktu widzenia Brachyloga. Pierwszy to pierwszy niedeterministyczny predykat w programie, więc ustala kolejność wyników; w tym przypadku oblicza wszystkie możliwe jawne wartości dla sumy listy w kolejności 0, 1, 2, 3… i jest używany do zapewnienia, że ​​listy są wyprowadzane w kolejności według ich sumy (zapewnia to, że każda możliwa lista pojawia się po skończonej ilości danych wyjściowych). Drugi służy do obliczenia wszystkich jawnych możliwości listy (zamiast formułowania formuły określającej, w jaki sposób elementy listy odnoszą się do siebie).


↰₁ẉ⊥jest również dobrym nagłówkiem do drukowania w nieskończoność.
Niepowiązany ciąg

Chociaż wydaje mi się, że może to nie być pełna odpowiedź, ponieważ każde pojedyncze niezależne wywołanie tego predykatu po prostu wygeneruje zera , a część „generuj wszystko” jest wykonywana przez lub w nagłówku.
Niepowiązany ciąg

1
@UnrelatedString Twój kod nie używa predykatu jako generatora. Mamy wyraźne reguły zezwalające na wyświetlanie listy przy użyciu generatora . To, co robisz w łączu TIO, polega na wywołaniu predykatu w pętli, aby uzyskać 1000 różnych generatorów, a następnie pobrać pierwsze wyjście z każdego z nich; to naprawdę nienaturalna operacja na generatorach i nie pozwoli ci zobaczyć innych elementów, które mogą wygenerować.
ais523

Ach, więc właśnie źle interpretowałem semantykę tego, co predykat Brachylog jest przez cały ten czas - mój pomysł na „generator” utknął w Pythonie. Teraz, gdy mam to prosto w głowie, chyba zgolę trzy bajty z niektórych moich starych odpowiedzi.
Niepowiązany ciąg

2

Perl 6 , 37 bajtów

{$++.polymod(1+$++ xx $_-1).say xx *}

Wypróbuj online!

Zasadniczo działa polymodz tyloma wpisami, ile potrzeba, gdzie moduł jest zawsze większy niż wejście, tj. 0. polimod (1,1,1), 1. polimod (2,2,2) itd. W ten sposób cyfra jest zawsze w zakresie Zakres. Perl6 nie pozwoli mi modulo infinity ...


5
Nie wyświetla to każdej krotki dokładnie raz (na przykład (0, 1, 0, 0)nie ma jej na liście).
bb94


2

C # (interaktywny kompilator Visual C #) , 148 bajtów

n=>{var a=new int[n];int j=0;void g(int k){if(k<n)for(int i=0;i++<j;g(k+1))a[k]=i;else if(a.Sum()==j)WriteLine(string.Join(' ',a));}for(;;j++)g(0);}

Wypróbuj online!

-3 bajty dzięki @ASCIIOnly!

// n: size of tuples to generate
n=>{
  // a: current tuple workspace
  var a=new int[n];
  // j: target sum value
  int j=0;
  // recursive function that works on slot k
  void g(int k){

    // tuple is not fully generated,
    if(k<n)

      // try all values from (0,j]
      for(int i=0;i++<j;
        // recursive call - generates all
        // values from (0,j] in the next slot
        g(k+1)
      )
        // update the kth slot
        a[k]=i;

    // tuple is fully generated, however
    // we should only display if the sum
    // is equal to the target sum. tuples
    // are generated many times, this
    // let's us enforce that they are only
    // displayed once.
    else if(a.Sum()==j)
      WriteLine(string.Join(' ',a));
  }
  // increment the high value forever
  // while continually starting the
  // recursive function at slot 0
  for(;;j++)
    g(0);
}

jak to zrobiłeś
Stackstuck

prosto-up Porting to .NET Rdzenia zapewne jeszcze uratować mi dużo bajtów.
Stackstuck

Największą sztuczką jest tutaj rekurencja. Wykorzystuje go większość technik, które widziałem do generowania „permutacji”. Planuję dodać wyjaśnienie.
dana

Writez np. '<literal tab>'lub |ma tę samą długość i zajmuje dużo mniej wierszy: P
tylko ASCII


1

Galaretka , 10 (9?) Bajtów

9 jeśli możemy wyprowadzać dane przy użyciu niespójnej separacji (o którą pytałem) - usunięcie .

‘ɼṗ³ċƇ®Ṅ€ß

Wypróbuj online!

W jaki sposób?

‘ɼṗ³ċƇ®Ṅ€ß - Main Link: some argument, x (initially equal to n, but unused)
 ɼ         - recall v from the register (initially 0), then set register to, and yield, f(v)
‘          -   f = increment
           - (i.e. v=v+1)
   ³       - program's third command line argument (1st program argument) = n
  ṗ        - (implicit range of [1..v]) Cartesian power (n)
           - (i.e. all tuples of length n with items in [1..v])
     Ƈ     - filter keep those for which:
    ċ      -   count
      ®    -   recall from register
           - (i.e. keep only those containing v)
       Ṅ€  - print €ach
         ß - call this Link with the same arity
           - (i.e. call Main(theFilteredList), again the argument is not actually used)

1
Oparte na „ tak długo, jak separacja krotek od liczb w każdej krotce jest wyraźna i spójna. (Na przykład jedna krotka na linię.) ” Zakładałem, że nie jest to dozwolone i jest wymagane, ale poczekajmy, co OP musi zrobić mówić.
Kevin Cruijssen

1

05AB1E , 15 11 bajtów

[¼¾LIãvy¾å—

-4 bajty, tworząc port odpowiedzi Pyth @Maltysen .

Wypróbuj online.

Wyjaśnienie:

[             # Start an infinite loop:
 ¼            #  Increase the counter_variable by 1 (0 by default)
  ¾L          #  Create a list in the range [1, counter_variable]
    Iã        #  Take the cartesian power of this list with the input
      v       #  Loop over each list `y` in this list of lists:
       y¾å    #   If list `y` contains the counter_variable:
             #    Print list `y` with trailing newline

2
Kiedy program dotrze do [1,2,1]? Pamiętaj, że musi to nastąpić w określonym czasie.
billpg

@billpg Należy teraz naprawić.
Kevin Cruijssen


1

Python 2 , 126 112 106 101 100 83 bajtów

n=input()
i=1
while 1:
 b=map(len,bin(i)[3:].split('0'));i+=1
 if len(b)==n:print b

Wypróbuj online!

5 bajtów dzięki mypetlionowi ; 1 bajt z orła oka ArBo ; 17 bajtów od xnor !

Skonstruuj uporządkowane partycje mw nprzedziały dla m = 0,1,2,3,..., wybierając liczby binarne za pomocą n-1 0s i m 1s.


if i==p:i=0;p*=2można i%=p;p<<=i<1zapisać 5 bajtów.
mypetlion

Jestem prawie pewien, że miejsce po print bnie jest potrzebne: D
ArBo

Wygląda na i+pto, że po prostu zlicza 1, 2, 3 ... w zawiły sposób i może być tylko jedną zmienną.
xnor

@xnor: D'oh! Byłem tak pochłonięty koncepcją, że nie widziałem lasu dla drzew.
Chas Brown

1

C # (.NET Core) , 608 570 567 bajtów

using C=System.Console;using L=System.Collections.Generic.List<int[]>;class A{static void Main(){L x=new L(),y=new L(),z=new L();int i=int.Parse(C.ReadLine()),j=0,k,l,m;x.Add(new int[i]);while(i>0){j++;for(m=0;m++<i;){foreach(var a in y)x.Add(a);y=new L();foreach(var a in x){for(k=0;k<i;){int[] t=new int[i];System.Array.Copy(a,t,i);t[k++]=j;var b=true;z.AddRange(x);z.AddRange(y);foreach(var c in z){for(l=0;l<i;l++)if(c[l]!=t[l])break;if(l==i)b=false;}if(b)y.Add(t);}}}}for(k=0;k<x.Count;k++){C.Write("[ ");for(l=0;l<i;l++)C.Write(x[k][l]+" ");C.WriteLine("]");}}}

Wypróbuj online!

mój Boże, co ja zrobiłem (tyle pętli, to właśnie zrobiłem)

Powinno jednak działać!

Jeśli przesuniesz pętlę drukowania o jeden nawias, wyświetli się lista w takiej postaci, w jakiej jest budowana, za każdym razem, gdy się zapętla. (Jeśli tak, zalecam dodanie nowego wiersza lub czegoś, co pozwoli odróżnić każdą pętlę).

Szczerze mówiąc, dużo czasu spędziłem na walce z językiem ... brak ładnych tablic, różne zachowania == ...

Mam nadzieję, że ta wersja jest łatwiejsza do odczytania.

using C=System.Console;
using L=System.Collections.Generic.List<int[]>;
class A{
    static void Main(){
        L x=new L(),y=new L(),z=new L();
        int i=int.Parse(C.ReadLine()),j=0,k,l,m;
        x.Add(new int[i]);
        while(i>0){
            j++;
            for(m=0;m++<i;){
                foreach(var a in y) x.Add(a);
                y=new L();
                foreach(var a in x){
                    for(k=0;k<i;){
                        int[] t=new int[i];
                        System.Array.Copy(a,t,i);
                        t[k++]=j;
                        var b=true;
                        z.AddRange(x);
                        z.AddRange(y);
                        foreach(var c in z){
                            for(l=0;l<i;l++) if(c[l]!=t[l])break;
                            if(l==i)b=false;
                        }
                        if(b)y.Add(t);
                    }
                }
            }
        }
        for(k=0;k<x.Count;k++){
            C.Write("[ ");
            for(l=0;l<i;l++)C.Write(x[k][l]+" ");
            C.WriteLine("]");
        }
    }
}

Ja po prostu sobie sprawę, mogę trzymać pętlę drukowania w if tak drukuje jak to idzie. twarz przez chwilę.
Stackstuck

poczekaj, nie mogę tego zrobić
Stackstuck

... och kochanie, nie jestem pewien, czy ten kod już działa.
Stackstuck

aaaaa i nie.
Stackstuck

1
Powodzenia :) Zacząłem kodować rozwiązanie w języku C # i zdałem sobie sprawę, że było to trochę trudniejsze, niż się spodziewałem. Dlaczego nie skorzystać z interpretera „Visual C # Interactive”? Pozwoliłoby to zaoszczędzić sporo, po prostu nie dołączając definicji klasy. W każdym razie +1 ode mnie :)
dana

1

Perl 6 , 50 bajtów

{grep $_,{S/.//.split(0)>>.chars}($++.base(2))xx*}

Wypróbuj online!

Anonimowy blok kodu, który zwraca leniwą nieskończoną listę. Wykorzystuje tę samą strategię, co odpowiedź Chasa Browna .

Wyjaśnienie:

{grep $_,{S/.//.split(0)>>.chars}($++.base(2))xx*}
{                                                } # Anonymous code block
                                              xx*  # Repeat indefinitely
                                 ($++        )     # From the current index
                                     .base(2)      # Get the binary form
         {S/.//                 }   # Remove the first digit
               .split(0)            # And split by zeroes
                        >>.chars    # And get the length of each section
 grep   ,   # From this infinite list, filter:
      $_      # The groups with length the same as the input

0

VDM-SL , 51 bajtów

g(i)==if i=0then{}else{[x]^y|x:nat,y in set g(i-1)}

Zrozumienie zestawu rekurencyjnego z konkatenacją sekwencji.

Nie w TIO, możesz uruchomić w programie (jeśli włączysz limity dla nat lub nie zakończy się):

functions 
g:nat->set of ?
g(i)==if i=0then{}else{[x]^y|x:nat,y in set g(i-1)}

Uwzględnia opcjonalne 0 w odpowiedzi, w przeciwnym razie byłoby to wiązanie 52 bajtów na nat1



0

perl -M5.010 122 bajty

$n=shift;
$s.="for\$x$_(1..\$m){"for 1..$n;
$t.="\$x$_ "for 1..$n;
$u.='}'x$n;
eval"{\$m++;$s\$_=qq' $t';/ \$m /&&say$u;redo}"

Dodano kilka nowych wierszy ze względu na czytelność (nie liczone w liczbie bajtów)


0

Python 2 , 120 bajtów

from random import*
m=n=input()
a=()
while 1:
 m+=len(a)==m**n;t=[randint(1,m)for _ in[1]*n]
 if(t in a)<1:a+=t,;print t

Wypróbuj online!

Trochę dłużej niż większość innych odpowiedzi, ale podobał mi się pomysł.


0

Stax , 6 bajtów

£ƒ$↔┬ï

Uruchom i debuguj

nProcedura wprowadzania danych jest z grubsza

for i in [0..infinity]:
    get all the distinct n length arrays of positive integers that sum to i
    for each
        join with spaces
        implicitly output

0

JavaScript (V8) , 98 bajtów

n=>{for(a=[],b=[j=1];;b.push(++j))(g=k=>k<n?b.map(i=>(a[k]=i)|g(k+1)):a.includes(j)&&print(a))(0)}

Wypróbuj online!

Brawo! W końcu mam poniżej 100 :) Zasadniczo port mojej odpowiedzi w języku C # .

// n: length of tuples to generate
n=>{
  // a: workspace for current tuple
  // b: range of numbers that grows
  //     - iteration 1: [1]
  //     - iteration 2: [1,2]
  //     - iteration 3: [1,2,3]
  // j: largest number in b
  for(a=[],b=[j=1];;b.push(++j))
    // g: recursive function to build tuples
    // k: index of slot for current recursive call
    (g=k=>
       // current slot less than the tuple size? 
       k<n?
         // tuple generation not complete
         // try all values in current slot and
         // recurse to the next slot
         b.map(i=>(a[k]=i)|g(k+1)):
         // tuple generation complete
         // print tuple if it contains the
         // current high value
         a.includes(j)&&print(a)
    // start recursive function at slot 0
    )(0)
}
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.