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


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" за отзывы на этапе песочницы.


Я предполагаю, что это действительно, если при сбое программы она выдает какой-то посторонний вывод в дополнение к напечатанным на данный момент кортежам, верно?
Луис Мендо

1
Должны ли мы выводить данные по ходу или будет достаточной функция, которая в конце времени выдаст бесконечный список?
Джонатан Аллан

6
«Вы можете выбрать выходной формат вашей программы для вашего удобства, если разделение между кортежами и числами внутри каждого кортежа является четким и последовательным» - можем ли мы вывести различное (хотя и последовательно различающееся) разделение (например, вот так )?
Джонатан Аллан

@JonathanAllan Я должен был бы включить вывод бесконечного содержимого этого объекта как часть программы.
billpg

1
Связанный (целые числа вместо натуральных чисел)
Esolanging Fruit

Ответы:


24

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

πN

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

объяснение

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


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которые суммируются с ним всеми возможными способами.


4

Pyth - 9 байт

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

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

.V1}#b^Sb

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


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… и используется для обеспечения вывода списков в порядке их суммы (это гарантирует, что каждое возможное список появляется после конечного количества вывода). Второй используется для вычисления всех явных возможностей для списка (вместо вывода формулы, определяющей, как элементы списка связаны друг с другом).


↰₁ẉ⊥также хороший заголовок, для печати бесконечно.
Несвязанная строка

Хотя я чувствую, что на самом деле это может быть не полный ответ, так как любой отдельный независимый вызов этого предиката будет просто генерировать нули , а часть «сгенерировать все» выполняется заголовком или в заголовке.
Несвязанная строка

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

как ты вообще это сделал
Stackstuck

прямой перенос этого на .NET Core, вероятно, все равно сэкономит мне много байтов.
Stackstuck

Самый большой трюк здесь - рекурсия. Большинство техник, которые я видел, чтобы генерировать «перестановки», используют его. Я планирую добавить объяснение.
Дана

Writeс eg '<literal tab>'или |имеет одинаковую длину и занимает намного меньше строк: P
только 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

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

Я только что понял, что могу вставить цикл печати в оператор 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

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

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



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)
}
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.