Costruisci i numeri naturali con i set


17

Questa costruzione è un modo di rappresentare i numeri naturali.

In questa rappresentazione, 0 è definito come l'insieme vuoto e per tutti gli altri numeri, n è l'unione di {0} e {n-1}.

Ad esempio per costruire 3 possiamo seguire l'algoritmo:

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

Compito

Come avrai intuito, il tuo compito è quello di prendere un numero naturale (incluso zero) e produrre la sua costruzione.

È possibile generare come stringa o oggetto impostato se la lingua scelta supporta tali oggetti.

Se si sceglie di emettere come stringa, è necessario rappresentare un set con parentesi graffe ( {}). Puoi facoltativamente rappresentare l'insieme vuoto come ø(altrimenti dovrebbe essere un insieme senza voci {}). Puoi anche scegliere di aggiungere virgole e spazi bianchi tra e dopo le voci nel set.

L'ordine non è importante, tuttavia potresti non avere elementi ripetuti negli insiemi che produci (ad es. {ø,ø})

Questo è quindi l'obiettivo è quello di avere il minor numero di byte

Casi test

Ecco alcuni casi di test con alcuni output di esempio.

0 -> {}
1 -> {{}}
2 -> {{}{{}}}
3 -> {{}{{}{{}}}}
4 -> {{}{{}{{}{{}}}}}

4
@ mbomb007 Non importa se la definizione è "sbagliata" o no. È ancora una bella sfida (e una diversa).
Martin Ender,


4
@ mbomb007 I casi di test e la definizione forniti in questa sfida coincidono e sono diversi dall'altra sfida. Semmai, il collegamento potrebbe essere migliorato, ma non credo che il collegamento sia rilevante per la sfida stessa.
Martin Ender,

La chiamò la costruzione di Von Neumann, tuttavia, e non è questa la sfida. Ecco cos'è il dup. Ne consegue che ogni numero naturale è uguale all'insieme di tutti i numeri naturali inferiore ad esso
mbomb007

1
Possiamo restituire un oggetto simile a un set come un elenco di elenchi da una funzione o stampare la rappresentazione della nostra lingua su STDOUT?
Dennis,

Risposte:


12

Python , 28 byte

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

Provalo online!

Questa è una soluzione piuttosto blanda al problema. Per numeri maggiori di zero è possibile ottenere la rappresentazione con la formula di stringa "{{}"*x+"}"*x. Tuttavia, questo non funziona per zero dove si trova la stringa vuota. Possiamo usare questo fatto per cortocircuitare ore restituire il set vuoto.

Volevo usare gli oggetti set predefiniti di Python per risolvere questo problema, ma sfortunatamente:

TypeError: unhashable type: 'set'

Non è possibile inserire set all'interno di set in Python.


2
È possibile spostare il xper "{{}"*x+x*"}"orsalvare un byte
Rod

1
f=potrebbe essere rimosso.
Yytsi


Non c'è, frozensetma nessuno ha byte per quello ...
Esolanging Fruit,

9

Haskell , 37 byte

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

Provalo online!

Fino a 10 minuti fa una risposta come questa non avrebbe avuto senso per me. Tutti i crediti vanno a questa risposta suggerimenti .

Fondamentalmente, usiamo >>come concat $ replicate(ma passandogli un elenco di n elementi anziché semplicemente n) e =<<asconcatMap , replicando quindi n volte ciascuna delle stringhe nell'elenco e concatenando il risultato in una singola stringa.

Il 0caso viene trattato separatamente in quanto restituirebbe una stringa vuota.


@Laikoni Ho provato anche una cosa del genere, ma f 1per far funzionare correttamente avresti bisogno anche di un caso speciale
Leo

Infatti. Quindi mi piace ancora di più la tua versione.
Laikoni

6

JavaScript, 28 byte

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

Rappresenta i set utilizzando gli array. Soluzione non ricorsiva a 38 byte:

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

Restituisce le stringhe di output di esempio.


6

Mathematica, 27 byte

Ho due soluzioni con questo numero di byte:

Nest[{{}}~Union~{#}&,{},#]&
Union//@Nest[{{},#}&,{},#]&

1
Mancata collisione a 32 byte: #//.{1->{{}},x_/;x>1->{{},x-1}}&. Anche se immagino che rovini l'input 0
Greg Martin

5

Perl 6 , 37 byte

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

Provalo

Allargato:

{   # 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
}

Ti manca un terminatore di preventivo :o è qualcosa di nuovo in Perl 6?
CraigR8806

@ CraigR8806 Non puoi usare i due punti per delimitare i costrutti di quotazione in Perl 6 perché sono usati per gli avverbi. (guarda la versione estesa)
Brad Gilbert b2gills


4

Retina , 22 byte

.+
$*
\`.
{{}
{

^$
{}

Provalo online!

Spiegazione

.+
$*

Converti l'input in unario.

\`.
{{}

Sostituisci ogni cifra unaria con {{}e stampa il risultato senza un trascinamento di riga ( \).

{

Rimuovere le aperture di apertura {, in modo che le rimanenti }siano esattamente quelle che è ancora necessario stampare per chiudere tutti i set. Tuttavia, la procedura sopra descritta non riesce per l'input 0, in cui non si stampa nulla. Così...

^$
{}

Se la stringa è vuota, sostituirla con il set vuoto.


Mi chiedevo come ripetere i ntempi di una stringa in Retina ...
Neil

4

Brain-Flak , 135 byte

Include +1 per -A

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

Provalo online!

(({}())<                 # 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 byte

Lri{]La|}*p

Stampa un oggetto simile a un set costituito da elenchi di elenchi. CJam stampa gli elenchi vuoti come stringhe vuote, poiché gli elenchi e le stringhe sono quasi intercambiabili.

Provalo online!

Spiegazione

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

Vecchia risposta, 21 18 byte

Questo era prima che fosse confermato che era OK stampare una struttura di elenco nidificata. Utilizza l'algoritmo di ripetizione stringa.

Salvato 3 byte grazie a Martin Ender!

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

Spiegazione

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

Gelatina , 6 byte

⁸,⁸Q$¡

Questo è un collegamento niladico che legge un numero intero da STDIN e restituisce una matrice irregolare.

Provalo online!

Come funziona

⁸,⁸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

Cardinale , 51 50 byte

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

Provalo online!

Spiegazione

%:#
x

Ricevi input e invia in basso e a sinistra dal #

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

Stampa "{" una volta, quindi stampa "{} {" n-1 volte se n> 1 quindi stampa "{}" se n> 0

       #

v <8/ ?<
>  8\

Tenere premuto il valore di input fino al completamento del primo loop

v"}"<
>?-?^

Stampa "}" una volta, quindi ripeti n-1 volte se n> 1


2

AHK, 55 byte

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

Non è la risposta più breve, ma mi è piaciuto questo perché le idiosincrasie di AutoHotkey fanno sembrare questo metodo di ricorsione super sbagliato. Ife le Loopaffermazioni presuppongono che la riga successiva sia l'unica cosa inclusa se le parentesi non vengono utilizzate. Le parentesi graffe sono caratteri di escape, quindi devi evitarle con altre parentesi graffe per usarle come testo. Inoltre, la variabile 1è il primo argomento passato. Quando leggo il codice senza conoscere quei bocconcini, la logica appare così:

  • Se 1 = 0, imposta suguale alla risposta sbagliata
  • Ripeti e aggiungi un gruppo di parentesi all'inizio e alcune alla fine ogni volta
  • Ritorna inviando la stringa risultante alla finestra corrente

Senza tutti i caratteri di escape della parentesi, sarebbe simile al seguente:

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

1

JavaScript 50 byte

g=n=>n==0?"":"{{}"+g(n-1)+"}"
z=m=>m==0?"{}":g(m)

quando un numero è uguale a 0 è un valore errato per JavaScript. Quindi puoi rimuovere == 0 se inverti le espressioni ternarie
f 6nɛtɪk

1

tinylisp , 52 byte

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

Provalo online! (collaudare l'imbragatura).

Spiegazione

Si noti che (cons x (cons y nil))è così che si crea un elenco contenente xe yin Lisp.

(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



1

dc , 46 byte

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

Provalo online!

Input su stdin, output su stdout.

Funziona calcolando una formula per l'output desiderato come numero base-256. Il comando P in cc viene quindi utilizzato per stampare il numero base-256 come stringa.


Ulteriori spiegazioni:

Sia n l'ingresso n. Il programma dc calcola la somma di

A = piano (256 ^ n / 255) * 125 (BF è interpretato da dc come 11 * 10 + 15 = 125)

e

B = piano ((256 ^ n) ^ 3 / (8 ^ 8-1)) * 8092541 * (256 ^ n).

 

Per un:

Osserva che 1 + 256 + 256 ^ 2 + ... + 256 ^ (n-1) è uguale a (256 ^ n-1) / 255, secondo la formula per una progressione geometrica, e questo è uguale a floor (256 ^ n / 255 ). Quindi questo è il numero composto da n 1 nella base 256.

Quando lo moltiplichi per 125 per ottenere A, il risultato è il numero costituito da n 125 nella base 256 (125 è ovviamente una singola cifra nella base 256). Probabilmente è meglio scrivere le cifre nella base 256 come numeri esadecimali; 125 è esadecimale 7D, quindi A è il numero base-256 costituito da n 7D di fila.

 

B è simile:

Questa volta osserva che 1 + 16777216 + 16777216 ^ 2 + ... + 16777216 ^ (n-1) è uguale (16777216 ^ n - 1) / 16777215, e questo è uguale a piano (16777216 ^ n / 16777215).

Ora, 256 ^ 3 = 16777216 e 8 ^ 8-1 = 16777215, quindi questo è ciò che stiamo calcolando come floor ((256 ^ n) ^ 3 / (8 ^ 8-1)).

Dalla rappresentazione della serie geometrica, questo numero nella base 256 è 100100100 ... 1001 con n delle cifre pari a 1 e il resto delle cifre pari a 0.

Questo è moltiplicato per 8092541, che è 7B7B7D in esadecimale. Nella base 256, questo è un numero di tre cifre composto dalle cifre 7B, 7B e 7D (scrivendo quelle cifre in esadecimale per comodità).

Ne consegue che il prodotto scritto nella base 256 è un numero di 3 cifre composto da 3 cifre 7B 7B 7D ripetute n volte.

Questo viene moltiplicato per 256 ^ n, risultando in un numero base-256 di 4n cifre, costituito dalle 3 cifre 7B 7B 7D ripetute n volte, seguite da n 0. Questo è B.

 

Aggiungendo A + B ora si ottiene il numero base-256 a 4 cifre composto da 3 cifre 7B 7B 7D ripetute n volte, seguite da n 7D. Poiché 7B e 7D sono i codici ASCII per {e }, rispettivamente, questa è la stringa composta da n copie {{}seguite da n copie di }, che è esattamente ciò che vogliamo per n> 0. Il comando P in cc stampa un numero base-256 come una stringa, proprio come abbiamo bisogno.

Sfortunatamente, n = 0 deve essere trattato come un caso speciale. Il calcolo sopra riportato produce un risultato di 0 per n = 0; in tal caso, ho appena codificato la stampa della stringa {}.


Questo è un approccio molto interessante che utilizza il comportamento meno noto di quel comando di stampa. Ben fatto! Una spiegazione di come funziona migliorerebbe la risposta.
seshoumara,

@seshoumara Grazie - Ho aggiunto una spiegazione dettagliata.
Mitchell Spector


0

Lotto, 88 byte

@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 byte

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

(newline per l'estetica) Dato che è brainf ***, accetta input come codici carattere ASCII (input "a" corrisponde a 96)

Braineasy, 60 byte

Inoltre, nel mio linguaggio personalizzato (basato su brainf **, interprete qui ):

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

Devi codificare l'input del programma nell'interprete perché sono pigro.


Benvenuti nel sito! Perché c'è un []? Sembra che potrebbe essere rimosso
Post Rock Garf Hunter

Se non lo possiedi, alla fine verrà emesso un ulteriore {} (loop infinito).
internet_user

0

05AB1E , 5 3 byte

F¯)

Provalo online!

Questa versione è dopo che ha chiarito che i set vanno bene.

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

Vecchia versione (che utilizza ø):

05AB1E , 5 4 byte

FX¸)

Provalo online!

Dove 1è equivalente a ø.

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.
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.