Trova la "dimensione da scartare" di un elenco


12

Definiamo la funzione "dimensione da scartare" udi un elenco nidificato l(contenente solo elenchi) dalle seguenti regole:

  • Se lè vuoto, allora u(l)è 1.
  • Se lnon è vuoto, u(l)è uguale alla somma delle dimensioni non imballate di ogni elemento in l, più uno.

Il tuo compito è scrivere un programma (o una funzione) che accetta un elenco come input e restituisce (o restituisce) le dimensioni non incluse dell'elenco.

Casi test:

[]                                           ->  1
[[[]],[]]                                    ->  4
[[[]],[[[[]],[]]],[[[]],[[[[]],[[],[[]]]]]]] -> 19
[[[[]]]]                                     ->  4

Questo è , quindi vince il programma più breve (in byte).


2
L'input può essere considerato come una stringa, ovvero racchiuso tra virgolette? Possiamo usare ()invece di []?
Luis Mendo,

possiamo prendere input in questo formato [[[]][]]anziché in questo [[[]],[]]secondo esempio?
Mukul Kumar,

Qual è la dimensione di ["This is some text [with square brackets in] ...[& maybe more than one pair]"]?
Jonathan Allan,


2
@DrMcMoylex Non sono d'accordo. Mentre contare il numero di ]sembra essere la soluzione più breve in molte lingue, ci sono anche molte risposte che risolvono effettivamente questa sfida attraverso la manipolazione di elenchi, e almeno negli esolang che contano le occorrenze di un carattere fisso è anche abbastanza diverso dal conteggio le occorrenze di un carattere di input.
Martin Ender,

Risposte:


23

Retina , 1 byte

]

Provalo online! (La prima riga abilita una suite di test separata da avanzamento riga.)

Per impostazione predefinita, Retina conta il numero di corrispondenze della regex specificata nell'input. La dimensione non imballata è semplicemente uguale al numero di []coppie nell'input e quindi al numero di ].


1
Lo strumento giusto per il lavoro!
Cyoce,

@MartinEnder aggiungi mai nuove funzioni alla tua lingua per salvare byte in una domanda di codegolf?
lois6b,

5
@ lois6b non retroattivamente, ma ogni tanto migliora il linguaggio per renderlo più potente per usi futuri. Detto questo, questa risposta avrebbe funzionato nella primissima versione di Retina da quando era semplicemente un modo per eseguire una singola regex (/ sostituzione) contro l'input senza sovraccarico sintattico.
Martin Ender,

11

Mathematica, 9 byte

LeafCount

Si scopre che c'è un built-in per quello ...

Si noti che ciò non funzionerebbe se gli elenchi contenessero effettivamente elementi non di elenco. Ciò LeafCountche fa veramente è contare il numero di sottoespressioni atomiche. Per l'input {{}, {{}}}, l'espressione in realtà legge:

List[List[], List[List[]]]

Qui le sottoespressioni atomiche sono in realtà le teste List .


1
Mathematica ha un built-in per tutto ...
kirbyfan64sos

2
@ Challenger5 Oy, plagio. : P
Martin Ender,

7

Brainfuck, 71 61 59 byte

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

Prende input da STDIN nel formato indicato nella domanda e genera il carattere il cui codice ASCII è la "dimensione non imballata" dell'elenco.

Sono ancora un dilettante completo in Brainfuck, quindi molto probabilmente ci sono molte ottimizzazioni che possono ancora essere fatte.

Provalo online!

Ungolfed:

read input to tape
>>+[>,]<
current tape: (0 0 1 a b *c)
where abc represents input and * is IP

now we loop over each character (from the end)
this loops assumes we are starting on the (current) last char
and it zeroes the entire string by the time it finishes
[

  subtract 91 from this character
  technically we only subtract 85 here and correct the answer
  with the 6 minus signs below
  >-[<->---]
  current tape: (0 0 1 a b cminus91 *0)

  invert the result and put that in the next cell
  +<------[->[-]<]>
  current tape: (0 0 1 a b 0 *c==91)

  move that result back to the original cell
  [-<+>]<
  current tape: (0 0 1 a b *c==91)

  if the result is true we found a brace
  increment the very first cell if so
  [-<[<]<+>>[>]]<
  current tape: (count 0 1 a *b)

]
current tape: (count *0)

<.

5

JavaScript (ES6), 29 27 byte

f=([x,...a])=>x?f(x)+f(a):1

mi piace quando una ricorsione risulta così chiara. Questa è sostanzialmente una ricerca approfondita dell'input, aggiungendo 1 ogni volta che viene raggiunta la fine di un array.

Se un array vuoto fosse errato in JS, questo potrebbe essere di 24 byte:

f=a=>a?f(a.pop())+f(a):1

Ma ahimè, non lo è. Altri tentativi:

f=a=>a.reduce((n,x)=>n+f(x),1) // Works, but 3 bytes longer
f=a=>a.map(x=>n+=f(x),n=1)&&n  // Works, but 2 bytes longer
f=a=>(x=a.pop())?f(x)+f(a):1   // Works, but 1 byte longer
f=a=>a[0]?f(a.pop())+f(a):1    // Works, but same byte count
f=a=>a+a?f(a.pop())+f(a):1     // Doesn't work on any array containing 1 sub-array
f=a=>a-1?f(a.pop())+f(a):1     // Same

Funzionerebbe f=a=>a[0]?f(a.pop())+f(a):1? (Stesso numero di byte però.)
Neil

@Neil Sì, questa è una delle soluzioni che ho già provato. Non credo sia possibile abbreviare ...
ETHproductions

(A proposito, sarei andato per lo stravagante f=a=>a.reduce((n,a)=>n+f(a),1). Ora, f=(n,a)=>n+a.reduce(f,1)sono solo 24 byte, ma purtroppo i parametri sono nell'ordine sbagliato.)
Neil

@Neil In realtà l'ho fatto prima, tranne accorciandolo di 1 byte:f=a=>a.map(a=>n+=f(a),n=1)&&n
ETHproductions

Ah, scusa, non avevo pensato di sfogliare la cronologia delle modifiche.
Neil,

4

Perl, 9 8 7 + 1 = 8 byte

Richiede la -pbandiera

$_=y;[;

Grazie a @Dada per i salvataggi a due byte (adoro questo exploit punto e virgola tra l'altro)


1
-pper salvare 1 byte;)
Dada,

Puoi usare y;[;per salvare un altro byte
Dada,

4

CJam , 7 5 byte

Grazie a Peter Taylor per aver rimosso 2 byte! ( e=invece di f=:+)

r'[e=

Provalo online!

r         e# Read input
 '[       e# Push open bracket char
   e=     e# Count occurrences. Implicit display

3

05AB1E , 4 byte

I'[¢

I    Get input as a string
 '[¢ Count the opening square brackets and implicitly print them

Provalo online!

Penso che si possa giocare più a golf ma che 'I' è obbligatorio, altrimenti l'input è considerato un array reale anziché una stringa


2
"[[[]],[[[[]],[]]],[[[]],[[[[]],[[],[[]]]]]]]"nell'input rimuove tale Irequisito, anche se non so se sia consentito.
Magic Octopus Urn

1
@carusocomputing: al momento non è consentito, ma potrebbe cambiare (vedo Luis che fa la stessa domanda
all'OP

Dang, 14 ore prima di me.
Oliver Ni,

3

Labirinto , 8 byte

&-
#,(/!

Provalo online!

Spiegazione

Questo conta le parentesi di apertura tramite un po 'di magia bit a bit. Se consideriamo i risultati dei codici di carattere della AND bit per bit di [, ,e ]con 2, otteniamo:

[ , ]
2 0 0

Quindi, se riassumiamo semplicemente il risultato di questa operazione per ciascun personaggio, otteniamo il doppio del valore che vogliamo.

Per quanto riguarda il codice stesso, il blocco 2x2 all'inizio è un piccolo ciclo. Nella prima iterazione &-non si fa davvero nulla tranne che mettono uno zero esplicito in cima a quelli impliciti nella parte inferiore dello stack. Questo sarà il totale parziale (e in realtà sarà negativo salvare un byte in seguito). Quindi il ciclo procede come segue:

,   Read character. At EOF this gives -1 which causes the instruction pointer to
    leave the loop. Otherwise, the loop continues.
#   Push the stack depth, 2.
&   Bitwise AND.
-   Subtract from running total.

Una volta lasciato il ciclo, viene eseguito il seguente bit lineare:

(   Decrement to turn the -1 into a -2.
/   Divide negative running total by -2 to get desired result.
!   Print.

L'IP quindi colpisce un morto e si gira. Quando tenta di eseguire /nuovamente, il programma termina a causa del tentativo di divisione per zero.


3

Python 3 2, 36 23 byte

lambda x:`x`.count("[")

Ho notato che u(l)è uguale al numero di [nella rappresentazione in stringa di l, quindi questo programma cerca di farlo. Probabilmente potrebbe essere ulteriormente golfato trovando un altro modo per farlo, anche se ...


6
23 byte:lambda x:`x`.count("[")
acrolito il


2

C #, 46 41 byte

int u(string l){return l.Count(c=>c=='[');}

l è la stringa dell'elenco nidificato. Provalo qui .


Usa i 4 spazi (prima del codice) per formattarlo in un blocco di codice
user41805

@KritixiLithos oops, ho dimenticato di farlo correttamente. Grazie per averlo segnalato :)
Ave,

E questo deve essere un programma o una funzione, questo non è nessuno dei due.
user41805

@KritixiLithos oops, grazie per averlo sottolineato, l'ho appena risolto.
Ave,

2
È possibile rilasciare le parentesi graffe e returnusando un'espressione corposa funzione. Inoltre chargetta implicitamente intin modo da poter utilizzare 91al posto di '[': int u(string l)=>l.Count(c=>c==91);Inoltre, si potrebbe cadere la firma della funzione e utilizzare un metodo di lambda: l=>l.Count(c=>c==91);.
latte


2

Rubino, 13 (+1) byte

p $_.count ?[

Chiamato con -nargomento:

ruby -ne 'p $_.count ?['

EDIT: modificato per stampare effettivamente la risposta


Questo non sembra stampare nulla. (A meno che questa non sia una risposta REPL, nel qual caso la lingua dovrebbe essere specificata come Ruby REPL.)
Martin Ender

@Martin Ender ♦ La specifica consentiva di restituire il valore invece di stamparlo.
Lee W,

Ciò si riferisce all'invio di funzioni. Ad esempio ->s{s.count ?[}sarebbe una presentazione valida.
Martin Ender,

È una regola generale?
Lee W,



2

Brain-Flak , 63 , 61 byte

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

Provalo online! 58 byte di codice e +3 per il -aflag che abilita l'ingresso ASCII.

Versione / spiegazione leggibile:

#While non-empty:
{

    #subtract
    ({}[

    #91
    (((()()()){}){}()){({}[()])}{}

    ])

    #if non-zero
    {

        # Remove the difference
        {}

        #Increment the counter on the other stack
        (<>{}())

        #Push a zero onto the main stack
        (<>)
    }

    #pop the left-over zero
    {}

#endwhile
}

#Move back to the stack with the counter, implicitly display
<>



1

PHP, 35 byte

<?=preg_match_all('/\[/',$argv[1]);

preg_match_all trova tutte le istanze corrispondenti dell'espressione regolare e restituisce un numero, motivo per cui sono necessari i tag di eco brevi.

Come la maggior parte delle risposte, conta il numero di [input e output quel numero


1
Se usi ]invece di [, non dovrai scappare.
Martin Ender,

2
count_chars()[91];fa più o meno la stessa cosa ma è più breve.
user59178

1

Racchetta 82 byte

(define n 0)(let p((l l))(if(null? l)(set! n(+ 1 n))(begin(p(car l))(p(cdr l)))))n

Ungolfed:

(define (f l)
  (define n 0)
  (let loop ((l l))
    (if (null? l)
        (set! n (add1 n))
        (begin (loop (first l))
               (loop (rest l)))))
  n)

test:

(f '[]) 
(f '[[[]] []]) 
(f '[[[]] [[[[]] []]] [[[]] [[[[]] [[] [[]]]]]]]) 
(f '[[[[]]]])  

Produzione:

1
4
19
4

1

V , 10 byte

ÓÛ
ÒC0@"

Provalo online!

Questo contiene alcuni caratteri non stampabili, ecco la versione leggibile:

ÓÛ
Ò<C-a>C0<esc>@"

<C-a>rappresenta "ctrl-a" (ASCII 0x01) e <esc>rappresenta il tasto Esc (ASCII 0x1b).

ÓÛ              " Remove all '['s
                "
Ò<C-a>          " Replace what's left with '<C-a>' (the increment command)
      C         " Delete this line
       0<esc>   " And replace it with a '0'
             @" " Run what we just deleted as V code (A bunch of increment commands

Più divertente, versione meno golfy:

o0kòf]m`jòd

Provalo online!

o0<esc>                     " Put a '0' on the line below us
       k                    " Move back up a line
        ò               ò   " Recursively:
         f]                 "   Move to a right-bracket
           m`               "   Add this location to our jumplist
             j              "   Move down a line
              <C-a>         "   Increment this number
                   <C-o>    "   Move to the previous location
                         d  " Delete the bracket line
                            " Implicitly display

1

Scala, 15 byte

s=>s.count(92<)

Ungolfed:

s=>s.count(c=>92<c)

countconta quanti elementi soddisfano un predicato, in questo caso 92<, che è il metodo <di 92.


1

O , 15 byte

i~{1\{nJ+}d}J;J

Provalo qui!

Nell'input, eventuali virgole devono essere rimosse o sostituite da spazi.

Spiegazione

i~{1\{nJ+}d}J;J
i                Read a line of input.
 ~               Evaluate it.
  {        }J;   Define a function and save it into the `J` variable.
                 Currently, the input array is at the top of the stack.
   1\            Push 1 and swap it with the input array.
     {   }d      For each element in the array...
                 Because the array was popped by `d`, 1 is at the TOS.
      nJ+        Recurse and add the result to 1.
              J  Initiate the function call.
                 The result is printed implicitly.

Se ci è permesso di lavorare su una stringa: 10 byte

ie\']-e@-p

1

> <> , 21 20 18 byte

0i:0(90.;n?|3%0=+!

Modifica: punteggio 1 per le dichiarazioni goto!

Modifica 2: Apparentemente> <> differisce da Befunge in quanto consente un offset IP diverso da zero dopo il wrapping (in altre parole, usando un'istruzione trampolino, posso passare a (1, 0) invece di (0, 0)). Interessante.

TryItOnline!


1

Brainfuck, 28 byte

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

Provalo online.

Questo conta il numero di caratteri di input divisibile per 3, cioè il numero di ]caratteri.

Soluzione alternativa a 34 byte che conta i [caratteri direttamente e si basa su celle a 8 bit:

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

1

C, 48 46 byte

Salvati due byte grazie a kirbyfan64sos

i;f(char*v){for(i=0;*v;i+=*v++==91);return i;}

i;f(char*v){for(i=0;*v;*v++^91?0:i++);return i;}

Codice di prova

main()
{
    printf("%d\n", f("[]"));
    printf("%d\n", f("[[[]] []]"));
    printf("%d\n", f("[[[]] [[[[]] []]] [[[]] [[[[]] [[] [[]]]]]]]"));
}

Casi test

a.exe
1
4
19

Passare *v++^91?0:i++a i+=*v==91per salvare 3 byte.
kirbyfan64sos,

@Kirbyfan64sos Grazie! Ho ancora bisogno di incrementare v ma posso usare i+=*v++==91per salvare due byte.
Cleblanc,

1

tinylisp sostitu , 39 byte

(d u(q((L)(i L(s(u(h L))(s 0(u(t L))))1

Definisce una funzione uche può essere chiamata come (u (q ((())()) ))(per il secondo caso di test). Farlo in sostituzione consente di risparmiare 4 byte a causa di parentesi chiuse automaticamente.

Spiegazione

(d u                                      )  Define u as
    (q                                   )    the following, unevaluated
      (                                 )     list (which acts as a function in tinylisp):
       (L)                                   Given arglist of one element, L, return:
          (i L                         )     If L (is nonempty):
              (s(u(h L))             )        Call u on head of L and subtract
                        (s 0        )          0 minus
                            (u(t L))           call u on tail of L
                                      1      Else, 1

Il x-(0-y)costrutto è necessario perché tinylisp non ha una funzione di addizione integrata, ma solo sottrazione.



1

Haskell, 20 19 17 byte

f s=sum[1|']'<-s]

Provalo online!

Prende l'elenco come stringa e inserisce un 1in un elenco per ciascuno ], quindi somma tutti 1i messaggi.


Versione senza punti: (19 byte)

length.filter(>'[')

I presupposti , [ ]sono gli unici caratteri nella stringa. Filtra l'elenco per ottenere tutti i caratteri maggiori di [, che sono tutti ]e restituisce la lunghezza.

Uso:

Prelude> length.filter(=='[')$"[[[]],[[[[]],[]]],[[[]],[[[[]],[[],[[]]]]]]]"
19

0

Bash + coreutils, 29 byte

f()(echo $1|tr -d -c [|wc -c)

Puoi rimuovere la maggior parte di questo e basta tr -d -c [|wc -c, che per impostazione predefinita leggerà l'elenco dall'input standard.
Kirbyfan64sos,

0

DASH , 14 byte

(ss[len;!> ="]

Conta semplicemente quello ]. Uso:

(ss[len;!> ="]"])"[[]]"

Soluzione bonus, 15 byte

a\@+1sum ->#a#0

Questo conta ricorsivamente da una lista reale. Uso:

(f\@+1sum ->#f#0)[[]]
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.