Построить натуральные числа с множествами

17

Эта конструкция является способом представления натуральных чисел.

В этом представлении 0 определяется как пустое множество, а для всех остальных чисел n является объединением {0} и {n-1}.

Например, чтобы построить 3 мы можем следовать алгоритму:

3 =
{ø, 2} =
{ø, {ø, 1}} =
{ø, {ø, {ø}}}

задача

Как вы уже догадались, ваша задача - взять натуральное число (включая ноль) и вывести его конструкцию.

Вы можете выводить как строку или как набор объектов, если ваш язык поддерживает такие объекты.

Если вы решили вывести в виде строки, вы должны представить набор с помощью фигурных скобок ( {}). При желании вы можете представить пустой набор как ø(иначе это должен быть набор без записей {}). Вы также можете добавить запятые и пробелы между и после записей в наборе.

Порядок не важен, однако у вас может не быть повторяющихся элементов в наборе, который вы выводите (например {ø,ø})

Это поэтому цель состоит в том, чтобы иметь наименьшее количество байтов

Контрольные примеры

Вот несколько тестовых примеров с некоторыми примерами выходных данных.

0 -> {}
1 -> {{}}
2 -> {{}{{}}}
3 -> {{}{{}{{}}}}
4 -> {{}{{}{{}{{}}}}}
Пост Рок Гарф Хантер
источник
4
@ mbomb007 Не имеет значения, является ли определение «неправильным» или нет. Это все еще прекрасный вызов (и другой).
Мартин Эндер
Тесно связаны
Мартин Эндер
4
@ mbomb007 Тестовые случаи и определения, приведенные в этом задании, совпадают и отличаются от других заданий. Во всяком случае, ссылка может быть улучшена, но я не думаю, что ссылка имеет отношение к самой проблеме.
Мартин Эндер
Однако он назвал это конструкцией фон Неймана, и это не та проблема. Вот что такое дуп Отсюда следует, что каждое натуральное число равно набору всех натуральных чисел, меньших его
mbomb007
1
Можем ли мы вернуть объект, подобный множеству, такой как список списков, из функции или вывести представление нашего языка в STDOUT?
Деннис

Ответы:

12

Python , 28 байт

lambda x:"{{}"*x+x*"}"or"{}"

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

Это довольно мягкое решение проблемы. Для чисел больше нуля вы можете получить представление с помощью строковой формулы "{{}"*x+"}"*x. Однако это не работает для нуля, где это пустая строка. Мы можем использовать этот факт для короткого замыкания и orвозврата пустого набора.

Я хотел использовать встроенные объекты Python для решения этой проблемы, но, к сожалению:

TypeError: unhashable type: 'set'

Вы не можете поместить наборы внутри наборов в Python.

Пост Рок Гарф Хантер
источник
2
Вы можете перейти xк "{{}"*x+x*"}"orсохранению байта
Rod
1
f=может быть удален
Yytsi
Никто frozensetне получил байты за это ...
Esolanging Fruit
9

Haskell , 37 байт

f 0="{}"
f n=([1..n]>>)=<<["{{}","}"]

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

До 10 минут назад такой ответ не имел для меня никакого смысла. Все кредиты перейдите к этому совету ответа .

По сути, мы используем >>как concat $ replicate(но передавая ему список из n элементов вместо просто n) и =<<как concatMap, затем реплицируем затем n раз каждую строку в списке и объединяем результат в одну строку.

0Случай рассматривается отдельно , как это будет возвращать пустую строку.

Лео
источник
@Laikoni Я тоже пробовал что-то подобное, но вам нужно было бы и особый случай, f 1чтобы он работал правильно
Лев
В самом деле. Тогда мне нравится ваша версия еще больше.
Лайкони
6

JavaScript, 28 байт

f=n=>n?--n?[[],f(n)]:[[]]:[]

Представляет наборы с использованием массивов. 38-байтовое нерекурсивное решение:

n=>'{{}'.repeat(n)+'}'.repeat(n)||'{}'

Возвращает пример выходных строк.

Нил
источник
6

Mathematica, 27 байт

У меня есть два решения на этот счет байтов:

Nest[{{}}~Union~{#}&,{},#]&
Union//@Nest[{{},#}&,{},#]&
Мартин Эндер
источник
1
Рядом промах в 32 байт: #//.{1->{{}},x_/;x>1->{{},x-1}}&. Хотя я предполагаю, что это
Грег Мартин
5

Perl 6 , 37 байт

{('{}','{{}}',{q:s'{{}$_}'}...*)[$_]}

Попытайся

Expanded:

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

  (
    # generate a sequence

    '{}',   # seed it with the first two values
    '{{}}',

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

      q         # quote
      :scalar   # allow scalar values

      '{{}$_}'  # embed the previous value 「$_」 in a new string

    }

    ...         # keep using that code block to generate values

    *           # never stop

  )[ $_ ] # get the value at the given position in the sequence
}
Брэд Гилберт b2gills
источник
Вам не хватает терминатора кавычек :или это что-то новое для Perl 6?
CraigR8806
@ CraigR8806 Нельзя использовать двоеточия для разграничения конструкций в кавычках в Perl 6, потому что они используются для наречий. (посмотрите на расширенную версию)
Брэд Гилберт b2gills
5

05AB1E , 6 5 байт

Код

ƒ)¯sÙ

Использует кодировку CP-1252 . Попробуйте онлайн! или проверьте все контрольные примеры! ,

объяснение

ƒ       # For N in range(0, input + 1)..
 )      #   Wrap the entire stack into an array
  ¯     #   Push []
   s    #   Swap the two top elements
    Ù   #   Uniquify the array
Аднан
источник
F¯)разве это не работает?
Волшебный Осьминог Урна
@carusocomputing Я не думаю, что это работает n=0, так как вывод пустой (не пустой набор).
Аднан
4

Сетчатка , 22 байта

.+
$*
\`.
{{}
{

^$
{}

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

объяснение

.+
$*

Преобразовать ввод в унарный.

\`.
{{}

Замените все одинарные цифры на {{}и напечатайте результат без завершающего перевода строки ( \).

{

Удалите отверстия {s, чтобы оставшиеся }были именно теми, которые нам еще нужно распечатать, чтобы закрыть все наборы. Однако вышеприведенная процедура не подходит для ввода 0, где мы ничего не печатали бы. Так...

^$
{}

Если строка пуста, замените ее пустым набором.

Мартин Эндер
источник
Мне было интересно, как повторить строку nвремени в сетчатке ...
Нил
4

Brain-Flak , 135 байтов

Включает +1 для -A

(({}())<{({}[()]<((((((()()()()()){}){}){}())()){}{})>)}{}({}[()()])>)(({})<{({}[()]<(((({}()())[()()])))>)}{}>[()]){(<{}{}{}>)}{}{}{}

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

(({}())<                 # Replace Input with input + 1 and save for later
  {({}[()]<              # For input .. 0
    (...)                # Push '}'
  >)}{}                  # End for and pop counter
  ({}[()()])             # change the top '}' to '{'. This helps the next stage
                         # and removes the extra '}' that we got from incrementing input
>)                       # Put the input back on

(({})<                   # Save input
  {({}[()]<              # For input .. 0
    (((({}()())[()()]))) # Replace the top '{' with "{{{}"
  >)}{}                  # end for and pop the counter
>[()])                   # Put down input - 1
{(<{}{}{}>)}             # If not 0, remove the extra "{{}"
{}{}{}                   # remove some more extras
Райли
источник
4

CJam , 11 байт

Lri{]La|}*p

Печатает подобный множеству объект, состоящий из списков списков. CJam печатает пустые списки как пустые строки, так как списки и строки почти взаимозаменяемы.

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

объяснение

L            Push an empty array 
 ri          Read an integer from input
   {    }*   Run this block that many times:
    ]          Wrap the entire stack in an array
     La        Wrap an empty list in an array, i.e. [[]]
       |       Set union of the two arrays
          p  Print the result

Старый ответ, 21 18 байт

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

Сохранено 3 байта благодаря Мартину Эндеру!

ri{{}}`3/f*~_{{}}|

объяснение

ri                  Read an integer from input
  {{}}`             Push the string "{{}}"
       3/           Split it into length-3 subtrings, gives ["{{}" "}"]
         f*         Repeat each element of that array a number of times equal to the input
           ~_       Dump the array on the stack, duplicate the second element
             {{}}|  Pop the top element, if it's false, push an empty block, which gets 
                      printed as "{}". An input of 0 gives two empty strings on the 
                      repetition step. Since empty strings are falsy, we can correct the 
                      special case of 0 with this step.
Бизнес Кот
источник
4

Желе , 6 байт

⁸,⁸Q$¡

Это нильадная ссылка, которая читает целое число из STDIN и возвращает рваный массив.

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

Как это устроено

⁸,⁸Q$¡  Niladic link.

⁸       Set the return value to [].
    $   Combine the three links to the left into a monadic chain.
 ,⁸     Pair the previous return value with the empty array.
   Q    Unique; deduplicate the result.
     ¡  Read an integer n from STDIN and call the chain to the left n times.
Деннис
источник
3

Кардинал , 51 50 байт

%:#>"{"#? v
x  ^?-"}{"<
v <8/ ?<
>  8\
v"}"<
>?-?^

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

объяснение

%:#
x

Получите ввод и отправьте вниз и влево от #

   >"{" ? v
   ^?-"}{"<

Выведите «{» один раз, затем выведите «{} {» n-1 раз, если n> 1, затем выведите «{}», если n> 0

       #

v <8/ ?<
>  8\

Удерживайте входное значение до завершения первого цикла

v"}"<
>?-?^

Выведите «}» один раз, затем повторите n-1 раз, если n> 1

fənɛtɪk
источник
2

AHK, 55 байт

IfEqual,1,0
s={{}{}}
Loop,%1%
s={{ 2}{}}%s%{}}
Send,%s%

Это не самый короткий ответ, но мне понравилось, потому что особенности AutoHotkey заставляют этот метод рекурсии выглядеть супер неправильно. Ifи Loopоператоры предполагают, что следующая строка - единственное, что включено, если скобки не используются. Вьющиеся скобки - это экранирующие символы, поэтому вы должны избегать их с другими вьющимися скобками, чтобы использовать их в качестве текста. Кроме того, переменная 1является первым переданным аргументом. Когда я читаю код, не зная этих лакомых кусочков, логика выглядит так:

  • Если 1 = 0, тогда установите s равным неправильный ответ
  • Зациклите и добавьте несколько скобок в начале и несколько в конец каждый раз
  • Возврат, отправив полученную строку в текущее окно

Без всех escape-символов в скобках это будет выглядеть так:

IfEqual,1,0
   s={}
Loop,%1%
   s={{}%s%}
Send,%s%
Инженер Тост
источник
1

JavaScript 50 байт

g=n=>n==0?"":"{{}"+g(n-1)+"}"
z=m=>m==0?"{}":g(m)
Кемсдейл Никл
источник
когда число равно 0, это ложное значение для JavaScript. Таким образом, вы можете удалить == 0, если вы измените свои троичные выражения
fəˈnɛtɪk
1

тинилисп , 52 байта

(d f(q((n)(i n(i(e n 1)(c()())(c()(c(f(s n 1))())))(

Попробуйте онлайн! (испытательный жгут).

объяснение

Обратите внимание, что (cons x (cons y nil))именно так вы строите список, содержащий xи yв Лиспе.

(d f           Define f to be
 (q(           a quoted list of two items (which acts as a function):
  (n)           Arglist is a single argument n
  (i n          Function body: if n is truthy (i.e. nonzero)
   (i(e n 1)     then if n equals 1
    (c()())       then cons nil to nil, resulting in (())
    (c            else (if n > 1) cons
     ()            nil to
     (c            cons
      (f(s n 1))    (recursive call with n-1) to
      ())))         nil
   ()))))        else (if n is 0) nil
DLosc
источник
1

постоянный ток , 46 байт

[[{}]]sx256?^dd3^8d^1-/8092541**r255/BF*+d0=xP

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

Вход на стандартный вывод, вывод на стандартный вывод.

Это работает путем вычисления формулы для желаемого выхода в виде числа 256. Затем команда P в dc используется для вывода числа base-256 в виде строки.


Дальнейшее объяснение:

Пусть n будет входом n. Программа dc вычисляет сумму

A = floor (256 ^ n / 255) * 125 (BF интерпретируется dc как 11 * 10 + 15 = 125)

и

B = этаж ((256 ^ n) ^ 3 / (8 ^ 8-1)) * 8092541 * (256 ^ n).

 

Для:

Заметьте, что 1 + 256 + 256 ^ 2 + ... + 256 ^ (n-1) равно (256 ^ n-1) / 255 по формуле геометрической прогрессии, и это равно полу (256 ^ n / 255 ). Так что это число, состоящее из n 1 в базе 256.

Когда вы умножаете его на 125, чтобы получить A, результатом является число, состоящее из n 125 в базе 256 (конечно, 125 - это одна цифра в базе 256). Вероятно, лучше записать цифры в базе 256 в виде шестнадцатеричных чисел; 125 - это шестнадцатеричное 7D, поэтому A - это число 256, состоящее из n 7D в ряду.

 

B похож:

На этот раз обратите внимание, что 1 + 16777216 + 16777216 ^ 2 + ... + 16777216 ^ (n-1) равно (16777216 ^ n - 1) / 16777215, и это равно полу (16777216 ^ n / 16777215).

Теперь 256 ^ 3 = 16777216 и 8 ^ 8-1 = 16777215, так что это то, что мы вычисляем как пол ((256 ^ n) ^ 3 / (8 ^ 8-1)).

Из представления геометрической серии это число в базе 256 равно 100100100 ... 1001, где n цифр равно 1, а остальные цифры равны 0.

Это умножается на 8092541, то есть 7B7B7D в шестнадцатеричном формате. В базе 256 это трехзначное число, состоящее из цифр 7B, 7B и 7D (для удобства записи эти цифры в шестнадцатеричном формате).

Отсюда следует, что произведение, записанное в базе 256, представляет собой 3-значное число, состоящее из 3 цифр 7B, 7B, 7D, повторенных n раз.

Это умножается на 256 ^ n, в результате получается 4-значное число с 256-значным числом, состоящее из 3 цифр 7B 7B 7D, повторенных n раз, за ​​которыми следуют n 0. Это Б.

 

Добавление A + B теперь приводит к получению 4-значного числа Base-256, состоящего из 3 цифр 7B 7B 7D, повторенных n раз, за ​​которыми следуют n 7D. Поскольку 7B и 7D являются кодами ASCII для {и }, соответственно, это строка, состоящая из n копий, за {{}которыми следуют n копий }, что в точности соответствует тому, что мы хотим при n> 0. Команда P в dc печатает число base-256 как строка, так же, как нам нужно.

К сожалению, n = 0 следует рассматривать как особый случай. Вышеприведенные вычисления дают результат 0 при n = 0; в этом случае я просто жестко запрограммировал печать строки {}.

Митчелл Спектор
источник
Это очень интересный подход, использующий менее известное поведение этой команды печати. Красиво сделано! Объяснение того, как это работает, улучшит ответ.
Сешумара
@seshoumara Спасибо - я добавил подробное объяснение.
Митчелл Спектор
0

Пакетная, 88 байтов

@set s={}
@if %1 gtr 0 set s=&for /l %%i in (1,1,%1)do @call set s={{}%%s%%}
@echo %s%
Нил
источник
0

Brainf *** , 99 байт

>+>+>+>+<[>[-<+++++>]<-<]>--[->+>+<<]
>[-<+>]>++<,[[->>+>+<<<]>>[-<<<..>>.>]>[-<<.>>]+[]]<.>>.

(новая строка для эстетики) Поскольку это brainf ***, он принимает ввод в виде кодов символов ascii (ввод "a" соответствует 96)

Braineasy, 60 байт

Кроме того, на моем собственном языке (на основе brainf **, переводчик здесь ):

#123#[->+>+<<]>++<,[[-<+<+>>]<[->>>..<.<<]<[->>>.<<<]!]>>.<.

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

internet_user
источник
Добро пожаловать на сайт! Почему есть []? Кажется, что его можно удалить
Post Rock
Если у вас его нет, он выдаст дополнительный {} в конце (он бесконечно зацикливается).
internet_user
0

05AB1E , 5 3 байта

F¯)

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

Эта версия после того, как он уточнил, что наборы в порядке.

F   # From 1 to input...
 ¯  # Push global array (default value is []).
  ) # Wrap stack to array.

Старая версия (которая использует ø):

05AB1E , 5 4 байта

FX¸)

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

Где 1эквивалентно ø.

F    # From 1 to input...
 X   # Push value in register X (default is 1).
  ¸  # Wrap pushed value into an array.
   ) # Wrap whole stack into an array.
     # Implicit loop end (-1 byte).
     # Implicit return.
Урна волшебного осьминога
источник