Список * всех * кортежей!

35

Напишите программу с заданным значением n , которая сгенерирует все возможные n-кортежи, используя натуральные числа.

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)... 
  • Вывод может быть в любом порядке, который не нарушает никаких других правил.
  • Программа должна быть написана так, чтобы она работала вечно и теоретически перечисляла все соответствующие кортежи ровно один раз.
    • В действительности ваша программа достигнет предела целочисленного типа и вылетит. Это приемлемо, если программа будет работать бесконечно долго, если только ваш целочисленный тип будет неограниченным.
    • Каждый допустимый кортеж должен быть указан в течение конечного времени, если только программе разрешено запускаться так долго.
  • Вывод может, по вашему выбору, включать нули в дополнение к натуральным числам.
  • Вы можете выбрать формат вывода вашей программы для вашего удобства, если разделение между кортежами и числами внутри каждого кортежа является четким и последовательным. (Например, один кортеж на строку.)
  • Ввод (n) является целым числом от одного до шести. Требуемое поведение не определено для входов за пределами этого диапазона.
  • Применяются правила Code-golf, выигрывает самая короткая программа.

Спасибо "Artemis Fowl" за отзывы на этапе песочницы.

billpg
источник
Я предполагаю, что это действительно, если при сбое программы она выдает какой-то посторонний вывод в дополнение к напечатанным на данный момент кортежам, верно?
Луис Мендо
1
Должны ли мы выводить данные по ходу или будет достаточной функция, которая в конце времени выдаст бесконечный список?
Джонатан Аллан
6
«Вы можете выбрать выходной формат вашей программы для вашего удобства, если разделение между кортежами и числами внутри каждого кортежа является четким и последовательным» - можем ли мы вывести различное (хотя и последовательно различающееся) разделение (например, вот так )?
Джонатан Аллан
@JonathanAllan Я должен был бы включить вывод бесконечного содержимого этого объекта как часть программы.
billpg
1
Связанный (целые числа вместо натуральных чисел)
Esolanging Fruit

Ответы:

24

Шелуха , 2 байта

πN

Попробуйте онлайн!

объяснение

Nэто бесконечный список натуральных чисел [1,2,3,4,... πэто декартова сила. Результатом является бесконечный список списков. Каждый список желаемой длины встречается ровно один раз, потому что πэто круто. Ввод и вывод неявные.

Zgarb
источник
1
Вау, и это тоже не подходит [1,1, n]. Есть ли шаблон порядка, который он выводит?
billpg
1
@billpg Он рекурсивно строит кортежи: n- кортежи получают, беря декартово произведение исходного списка и списка n-1кортежей в порядке возрастания суммы индексов.
Згарб
«В порядке возрастания суммы индексов» - Вы можете это уточнить? Мне трудно понять, почему, например, 2,2,2приходит после 4,1,2и 5,1,1.
Иона
2
@Jonah Рекурсия работает так. Вы начинаете с 1-го кортежа N. Для 2-х кортежей берется декартово произведение с Nупорядоченным по сумме показателями. В обоих списках каждое число nимеет индекс, nпоэтому для длины 2 результат упорядочивается по сумме. Для получения 3-кортежей вы берете декартово произведение Nи список 2-кортежей, упорядоченный по сумме индексов элементов в этих списках. Он не смотрит на сумму кортежа, он смотрит на свою позицию в списке кортежей.
Згарб
2
«Выясните различные измерения бесконечности в этой задаче и найдите шаблон, который сводит его к счетной бесконечности, а затем напишите программу, которая выполняет итерацию по этому шаблону». - "Эй, у меня есть встроенный для этого!"
Фабиан Релинг
10

Haskell , 62 байта

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

Попробуйте онлайн!

n!sгенерирует все nкортежи, которые суммируются с s.

Тогда ответ ([1..]>>=).(!), то есть \n -> [t | s<-[1..], t<-n!s].

Это функция, отображающая целое число nв бесконечный ленивый список кортежей (списков целых чисел).

Линн
источник
5

Haskell , 50 байтов

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

Попробуйте онлайн!

Списки- nкортежи отсортированы по сумме. mapMвыполняет тяжелую работу для генерации всех nнаборов чисел от 0 до k. <$fТрюк объясняется здесь .

Haskell , 51 байт

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

Попробуйте онлайн!

Рекурсивно растягивает все n-1кортежи на все nкортежи, разбивая первое число aкаждого n-1кортежа на два числа, a-k,kкоторые суммируются с ним всеми возможными способами.

XNOR
источник
4

Pyth - 9 байт

Спасибо @FryAmTheEggman за гольф

Перебирает все x и принимает [1..x] ^ n. Это делает дубликаты, поэтому сохраняются только те, которые являются новыми для этого x, то есть содержат в них x. Форматирование немного странное, но его можно сделать стандартным с помощью еще одного байта,.V1j}#b^Sb

.V1}#b^Sb

Попробуйте онлайн .

Maltysen
источник
1
f}bT-> }#bКроме того, ваш счетчик байтов сейчас кажется неверным?
FryAmTheEggman
@FryAmTheEggman подожди, почему это неправильно? Если вы говорите о ссылке TIO, это включает форматирование с помощью j(b). Также спасибо за гольф.
Maltysen
Ах, вот что меня смутило, извините!
FryAmTheEggman
3

Brachylog (v2), 9 байт

~l.ℕᵐ+≜∧≜

Попробуйте онлайн!

Это бесконечный генератор, который генерирует все возможные кортежи. Ссылка TIO имеет заголовок, который использует генератор, чтобы сгенерировать 1000 элементов и распечатать их (но генератор мог бы работать бесконечно, если бы я попросил об этом; целые числа Брахилога не ограничены).

Такое ощущение, что должен быть более краткий путь, но есть много ограничений, и это самое короткое, что я могу вписать их в одну программу.

объяснение

~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]

Между прочим, меня удивляет, насколько разные мои объяснения двух , несмотря на то, что они делают одно и то же с точки зрения Брахилога. Первый - это первый недетерминированный предикат в программе, поэтому он устанавливает порядок результатов; в этом случае он вычисляет все возможные явные значения для суммы списка в порядке 0, 1, 2, 3… и используется для обеспечения вывода списков в порядке их суммы (это гарантирует, что каждое возможное список появляется после конечного количества вывода). Второй используется для вычисления всех явных возможностей для списка (вместо вывода формулы, определяющей, как элементы списка связаны друг с другом).

ais523
источник
↰₁ẉ⊥также хороший заголовок, для печати бесконечно.
Несвязанная строка
Хотя я чувствую, что на самом деле это может быть не полный ответ, так как любой отдельный независимый вызов этого предиката будет просто генерировать нули , а часть «сгенерировать все» выполняется заголовком или в заголовке.
Несвязанная строка
1
@UnrelatedString Ваш код, тем не менее, не использует предикат в качестве генератора. У нас есть явные правила, разрешающие вывод списка с использованием генератора . То, что вы делаете в своей ссылке TIO, - это вызов предиката в цикле для получения 1000 различных генераторов, а затем получение первого вывода от каждого из них; это действительно неестественная операция для генераторов, и она не позволит вам увидеть другие элементы, которые они могут генерировать.
ais523
Ах, так что я только что неверно истолковал семантику того, что такое предикат брахилога - все это время - моя идея «генератора» застряла на Python. Теперь, когда это прямо у меня в голове, я думаю, я пойду побриться на три байта от некоторых моих старых ответов.
Несвязанная строка
2

Perl 6 , 37 байт

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

Попробуйте онлайн!

По сути, выполняется polymodс таким количеством записей, сколько необходимо, где модуль всегда больше, чем вход, т. Е. 0.polymod (1,1,1), 1.polymod (2,2,2) и т. Д. Таким образом, цифра всегда находится в пределах диапазон. Perl6 не позволит мне по модулю бесконечности ...

Фил Х
источник
5
Это не перечисляет каждый кортеж ровно один раз (например, (0, 1, 0, 0)не указан).
BB94
2

C # (интерактивный компилятор Visual C #) , 148 байт

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

Попробуйте онлайн!

-3 байта благодаря @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);
}
Dana
источник
как ты вообще это сделал
Stackstuck
прямой перенос этого на .NET Core, вероятно, все равно сэкономит мне много байтов.
Stackstuck
Самый большой трюк здесь - рекурсия. Большинство техник, которые я видел, чтобы генерировать «перестановки», используют его. Я планирую добавить объяснение.
Дана
Writeс eg '<literal tab>'или |имеет одинаковую длину и занимает намного меньше строк: P
только ASCII
1
AW , 151
только ASCII
1

Желе , 10 (9?) Байтов

9 если мы можем вывести с использованием непоследовательного разделения (о котором я спрашивал) - удаление .

‘ɼṗ³ċƇ®Ṅ€ß

Попробуйте онлайн!

Как?

‘ɼṗ³ċƇ®Ṅ€ß - 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
Основываясь на « пока разделение между кортежами и числами внутри каждого кортежа является четким и непротиворечивым. (Например, один кортеж на строку.) » Я предположил, что это не разрешено и требуется, но давайте подождем, что OP должен сказать.
Кевин Круйссен
1

05AB1E , 15 11 байт

[¼¾LIãvy¾å—

-4 байт путем создания порта @Maltysen Pyth ответа «s .

Попробуйте онлайн.

Объяснение:

[             # 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
Когда программа доберется до [1,2,1]? Помните, это должно быть в течение конечного времени.
billpg
@billpg Должно быть исправлено сейчас.
Кевин Круйссен
1

MATL , 16 байт

`@:GZ^t!Xs@=Y)DT

Кортежи упорядочены по возрастанию суммы, и в пределах заданной суммы они упорядочены лексикографически.

Попробуйте онлайн!

Луис Мендо
источник
1

Python 2 , 126 112 106 101 100 83 байта

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

Попробуйте онлайн!

5 байтов спасибо mypetlion ; 1 байт от орлиного глаза АрБо ; 17 байт из xnor !

Построить заказанные перегородки m в nбункеры, m = 0,1,2,3,...выбрав для двоичных чисел с n-1 0s и m 1s.

Час Браун
источник
if i==p:i=0;p*=2может стать i%=p;p<<=i<1экономить 5 байт.
Mypetlion
Я почти уверен, что место после print bне нужно: D
АрБо
Похоже, что i+pпросто подсчитывает 1, 2, 3 ... в запутанном виде и может быть просто одной переменной.
xnor
@xnor: Д'Ох! Я был настолько погружен в концепцию, что не мог видеть лес за деревьями.
Час Браун
1

C # (.NET Core) , 608 570 567 байт

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("]");}}}

Попробуйте онлайн!

Боже мой, что я сделал (так много петель, это то, что я сделал)

Это должно работать, хотя!

Если вы переместите цикл печати на одну скобку назад, он будет показывать вам список в том виде, в котором он был создан, каждый раз, когда он повторяется. (Я рекомендую добавить новую строку или что-то, чтобы отличить каждый цикл, если вы делаете.)

Честно много я потратил времени на борьбу с языком ... никаких красивых печатных массивов, различного поведения == ...

Надеюсь, эту версию легче читать.

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("]");
        }
    }
}
Stackstuck
источник
Я только что понял, что могу вставить цикл печати в оператор if, чтобы он печатался по ходу дела. лицевой импульс один момент.
Stackstuck
подождите, нет, не могу этого сделать
Stackstuck
... о боже, я не уверен, что этот код работает больше.
Stackstuck
ааааа и нет
Stackstuck
1
Удачи в этом :) Я начал кодировать решение в C # и понял, что это немного сложнее, чем я надеялся. Почему бы не использовать интерпретатор Visual C # Interactive? Это сэкономит кучу, просто не добавляя определение класса. В любом случае +1 от меня :)
Дана
1

Perl 6 , 50 байт

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

Попробуйте онлайн!

Блок анонимного кода, который возвращает ленивый бесконечный список. Это использует ту же стратегию, что и ответ Чаза Брауна .

Объяснение:

{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 байт

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

Понимание рекурсивных множеств с конкатенацией последовательностей.

Не на TIO, вы можете запустить в программе (если вы включите ограничения для типа nat или он не завершится):

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

Включает необязательные 0 в ответ, иначе это будет 52 байта привязки на nat1

Истек срок действия данных
источник
0

perl -M5.010 122 байта

$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}"

Добавлено несколько новых строк для удобства чтения (не учитывается при подсчете байтов)


источник
0

Python 2 , 120 байт

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

Попробуйте онлайн!

Чуть дольше, чем большинство других ответов, но мне понравилась идея, стоящая за этим.

ARBO
источник
0

JavaScript (V8) , 98 байт

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

Попробуйте онлайн!

Ура! Наконец получил его под 100 :) В основном это порт моего ответа 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)
}
Dana
источник