Più breve di una frazione di secondo!


16

Sfida

Il compito di questa domanda è quello di dividere un array di input di numeri interi alla seconda occorrenza di ogni numero intero in quel array.

Non abbastanza chiaro? Ecco un esempio per aiutare

Matrice di input:

[2 1 1 2 3 2 2 4 5 6 7 3 7 0 5]

Produzione:

[[2 1] [] [3 2 2 4 5 6 7] [] [0] []]

Spiegazione:

Ecco l'array con solo il secondo elemento evidenziato in grassetto:

[2 1 1 2 3 2 2 4 5 6 7 3 7 0 5 ]

Ora mettiamo i blocchi dell'array di divisione attorno a queste seconde occorrenze:

[2 1] 1 [] 2 [3 2 2 4 5 6 7] 3 [] 7 [0] 5 []

e avvolgi questi array divisi in un array per ottenere il finale

[[2 1] [] [3 2 2 4 5 6 7] [] [0] []]

Si noti che quando si verificano seconde occorrenze adiacenti, ci saranno array vuoti.

Regole

Come al solito, è necessario scrivere un programma completo o una funzione prendendo l'array di input tramite STDIN, ARGV o argomento della funzione.

Ingresso

L'input consiste in qualsiasi formato di array conveniente (o simile a array) di numeri interi.

Ad esempio, sarebbe accettabile una delle seguenti condizioni:

2 1 1 1 4 5 6
[2 1 1 1 4 5 6]
[2, 1, 1, 1, 4, 5, 6]

Produzione

Quando si invia a STDOUT, l'array può anche essere stampato in qualsiasi formato di array conveniente (nidificato), ad esempio uno di

[[2 1] [1 4 5 6]]
[[2, 1], [1, 4, 5, 6]]
{{2, 1}, {1, 4, 5, 6}}

(Questa sarà in genere la rappresentazione di stringhe native degli array nella tua lingua.)

Si noti inoltre che gli array vuoti finali devono essere stampati come parte dell'array.

punteggio

Questo è quindi il codice più breve in byte vince!


@PeterTaylor molte domande consentono diversi formati di array sia in output che in inputl.
Ottimizzatore

5
Qual è il punto di consentire ""come array vuoto? Questo profuma di favourismo verso un linguaggio golfistico specifico.
John Dvorak,

@JanDvorak Dopo la discussione in chat, l'intenzione era in realtà di essere più inclusiva e in generale consentire alle lingue di usare la loro rappresentazione nativa. Ho modificato il testo ora per renderlo più chiaro.
Martin Ender

1
Posso solo emettere 2 1, 1 4 5 6?
jimmy23013,

@ user23013 dipende dalla lingua che hai scelto.
Ottimizzatore

Risposte:


6

25 APL

1↓¨(1,∨⌿<\2=+\∘.=⍨a)⊂1,a←

Esempio:

]display 1↓¨(1,∨⌿<\2=+\∘.=⍨a)⊂1,a←2 1 1 2 3 2 2 4 5 6 7 3 7 0 5
┌→──────────────────────────────────────┐
│ ┌→──┐ ┌⊖┐ ┌→────────────┐ ┌⊖┐ ┌→┐ ┌⊖┐ │
│ │2 1│ │0│ │3 2 2 4 5 6 7│ │0│ │0│ │0│ │
│ └~──┘ └~┘ └~────────────┘ └~┘ └~┘ └~┘ │
└∊──────────────────────────────────────┘

Vecchia:

{1↓¨(1,(⍳⍴⍵)∊,{1↑1↓⍵}⌸⍵)⊂1,⍵}

Questa è una bella domanda per l'operatore chiave (⌸) introdotto con Dyalog APL v14. Prende la funzione dell'argomento sinistro ({1 ↑ 1 ↓ ⍵}) e fornisce per ogni argomento univoco, gli indici nel vettore per quell'argomento. Qui sto prendendo il secondo indice, quindi controllo quale degli indici è presente in questo elenco ((⍳⍴⍵) ∊) e uso il booleano risultante per dividere il vettore originale.

Può essere provato online qui:

http://tryapl.org


Dannazione. Ancora non meno di 24?
Ottimizzatore il

@Optimizer: 25 ... ci sto provando ;-)
Moris Zucca il

Accettare questo invece della mia soluzione :)
Ottimizzatore

Solo 24 e una funzione adeguata:1↓¨{1,∨⌿<\2=+\∘.=⍨⍵}⊂1∘,
Adám,

purtroppo non funziona ... l'omega nel dfn non è la stessa di "a"
Moris Zucca,

9

APL (Dyalog 14) (31)

{1↓¨(1,(⍳⍴⍵)∊2⍳⍨¨↓+\∘.=⍨⍵)⊂0,⍵}

Questa è una funzione che accetta un array e restituisce un array nidificato.

Test:

      +V← {1↓¨(1,(⍳⍴⍵)∊2⍳⍨¨↓+\∘.=⍨⍵)⊂0,⍵} 2 1 1 2 3 2 2 4 5 6 7 3 7 0 5
┌───┬┬─────────────┬┬─┬┐
│2 1││3 2 2 4 5 6 7││0││
└───┴┴─────────────┴┴─┴┘
      ⍝ this return value is a real nested array:
      ⎕←'Length: ',⍴V ⋄ (⍳⍴V){⎕←'Array #',⍺,': (', ⍵, ')'}¨V 
Length:  6
Array # 1 : ( 2 1 )
Array # 2 : ()
Array # 3 : ( 3 2 2 4 5 6 7 )
Array # 4 : ()
Array # 5 : ( 0 )
Array # 6 : ()

Spiegazione:

  • 0,⍵: Aggiungi a 0nella parte anteriore di , per un'elaborazione più semplice. (Non conta come un evento.)
  • (... )⊂: dividere l'array in base alla maschera di bit fornita. Un nuovo gruppo inizia da ciascuno 1nella maschera di bit.
    • +\∘.=⍨⍵: per ogni valore in (l'originale) , trova tutte le occorrenze in . Quindi fai una somma parziale per ogni valore, dando una matrice quadrata che mostra per ogni posizione in quanti di ciascun valore sono già avvenuti.
    • : Dividere la matrice per le sue righe, fornendo per ogni valore un array che mostra il numero di volte in cui si è verificato per ogni posizione.
    • 2⍳⍨¨: In ciascuno di questi array, trova l'indice del primo 2.
    • (⍳⍴⍵)∊: Per ogni possibile indice in , vedere se è contenuto nell'elenco degli indici delle seconde occorrenze. (Questi iniziano ogni gruppo, tranne il primo.)
    • 1,: Aggiungi un 1in primo piano, segnando l'inizio del primo gruppo.
  • 1↓¨: Rimuove il primo elemento da ciascun gruppo. (Questi sono l'aggiunta 0e la seconda occorrenza di ciascun valore.)

8

J, 28 24 caratteri

Un ringraziamento speciale a randomra .

(1&,<;._1~1,2=+/@(={:)\)

Funziona così. Su tutti i prefissi ( \) dell'array di input, esaminiamo quanti ( +/@) elementi del prefisso sono uguali all'ultimo elemento ( ={:) di quel prefisso. Quando questo numero è 2, sappiamo che questa è la seconda occorrenza di quell'elemento nella matrice, quindi abbiamo diviso la matrice lì usando <;._1.

   a=.2 1 1 2 3 2 2 4 5 6 7 3 7 0 5
   (={:)\ a
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
0 1 1 0 0 0 0 0 0 0 0 0 0 0 0
1 0 0 1 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 1 0 0 0 0 0 0 0 0 0 0
1 0 0 1 0 1 0 0 0 0 0 0 0 0 0
1 0 0 1 0 1 1 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 1 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 1 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 1 0 0 0 0
0 0 0 0 1 0 0 0 0 0 0 1 0 0 0
0 0 0 0 0 0 0 0 0 0 1 0 1 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 1 0
0 0 0 0 0 0 0 0 1 0 0 0 0 0 1
   +/@(={:)\ a
1 1 2 2 1 3 4 1 1 1 1 2 2 1 2

Vecchio cosa usando trucchi di ordinamento: (1&,<;._1~1,1=i.~(]-{)/:@/:).


(1&,<;._1~1,2=+/@(={:)\)è di 4 byte più breve e molto più semplice. ( /:@/:è un bel trucco però.)
randomra

7

Mathematica, 58 51 49 byte

Rest/@SplitBy[(f@#=0;#)&/@{a}~Join~#,++f[#]==3&]&

Questa è una funzione senza nome che accetta un elenco come

Rest/@SplitBy[(f@#=0;#)&/@{a}~Join~#,++f[#]==3&]&[{2,1,1,2,3,2,2,4,5,6,7,3,7,0,5}]

e restituisce un elenco nidificato come

{{2, 1}, {}, {3, 2, 2, 4, 5, 6, 7}, {}, {0}, {}}

Come funziona

Questo usa una magia piuttosto oscura con SplitBy .

Sto tenendo traccia delle occorrenze di ciascun numero in una funzione f . In Mathematica, puoi definire il valore di una funzione per ciascun input separatamente e non è necessario specificare il valore per tutti gli input possibili (è più simile a una tabella di hash sugli steroidi).

Quindi inizio inizializzando fa 0 per i valori che sono presenti nell'input con(f@#=0;#)&/@ .

Ora SplitByprende un elenco e una funzione e "divide l'elenco in elenchi secondari costituiti da esecuzioni di elementi successivi che danno lo stesso valore quando fviene applicato" (nota che SplitBynon rimuove alcun elemento). Ma la cattura (non documentata) è, che fviene chiamata due volte su ciascun elemento, quando viene confrontata con il suo predecessore e il suo successore. Quindi se lo facciamo

 SplitBy[{1,2,3,4},Print]

non riceviamo solo un numero una volta, ma invece questo stampa

 1
 2
 2
 3
 3
 4

che è 6 chiede 3 confronti.

Possiamo dividere l'elenco prima di ogni seconda occorrenza, se scriviamo una funzione che ritorna sempre Falsema che ritorna Truequando una seconda occorrenza viene confrontata con l'elemento precedente. Questo è il terzo controllo su quell'elemento (due controlli sulla prima occorrenza, più il primo controllo sulla seconda occorrenza). Quindi, usiamo ++f[#]==3&. La cosa bella è che questo ritorna già di Falsenuovo al secondo controllo della seconda occorrenza, in modo che io possa tornare Trueper occorrenze secondarie consecutive, ma ancora diviso tra di loro . Allo stesso modo, questo non si divide dopo le seconde occorrenze, poiché la funzione ritorna di Falsenuovo al secondo controllo.

Ora, la domanda vuole che rimuoviamo anche quelle seconde occorrenze, quindi eliminiamo il primo elemento da ogni elenco, con Rest/@. Ma ovviamente, non vogliamo rimuovere il primo elemento nell'input, quindi iniziamo effettivamente aggiungendo un elemento aall'inizio dell'elenco con {a}~Join~#. aè una variabile indefinita, che Mathematica considera semplicemente sconosciuta, quindi non influirà su nessun altro valore di f. Ciò garantisce anche che il primo elemento effettivo nell'input ottenga i suoi due controlli come ogni altro elemento.


È abbastanza intelligente. Inoltre, in realtà non è necessario Boole.
Swish,

@swish Ah, grazie per avermelo ricordato ... L'ho notato mentre ero sul cellulare, ma volevo provarlo prima di cambiarlo.
Martin Ender,

5

Python, 148 byte

def s(a):z=len(a);x=[-1]+sorted({[i for i in range(z)if a[i]==n][1]for n in a if a.count(n)>1})+[z];return[a[x[i]+1:x[i+1]]for i in range(len(x)-1)]

Soluzione piuttosto orrenda. Deve esserci un modo migliore ...

Chiama con s([2, 1, 1, 1, 4, 5, 6]) .

Versione Ungolfed

def split(array):
  indices = [-1]
  second_occurrences = set()

  for n in array:
      if array.count(n) > 1:
          occurrences = [i for i in range(len(array)) if array[i] == n]
          second_occurrences.add(occurrences[1])

  indices += sorted(second_occurrences)
  indices += [len(array)]

  return [array[indices[i]+1:indices[i+1]] for i in range(len(indices)-1)]

1
Che cosa ... Potresti modificare in una versione senza golf? XD 148 personaggi è una linea molto lunga;)
Sean Allred,

1
@SeanAllred Non volevo pubblicare una spiegazione poiché ero sicuro di poter fare di meglio, ma dato che ho problemi, ho pubblicato la versione non controllata: P
Sp3000,

5

Haskell, 115 113 106 88

f?(x:s)|1<-f x=[]:x%f?s|a:b<-x%f?s=(x:a):b
f?x=[x]
(x%f)h=sum$f h:[1|x==h]
r s=(\_->0)?s

questo immagazzina la quantità che ogni elemento è apparso in una funzione dagli elementi al loro rispettivo importo, il che è un trucco interessante.

funziona usando %, una funzione che ha dato una funzione f e un argomento xrestituisce una nuova funzione che ritorna fapplicata al suo argomento se è diverso da x, e 1 + f xaltrimenti.

per esempio, 3 % const 0è una funzione che restituisce 0 per ogni argomento tranne 3, per cui restituisce 1. update: ha fuso il foldlper ottenere un programma molto più piccolo.


Questo sembra interessante. Potresti fornire una versione non golfata?
Radomaj,

4

Demo di Ruby 66

f=->a{c=Hash.new 0
r=[[]]
a.map{|e|2==(c[e]+=1)?r<<[]:r[-1]<<e}
r}

Ruby stabby lambda che accetta un array come parametro e restituisce un array di array.


4

Python: 100 byte

def g(l):
 i=j=0;o=[]
 for e in l:
  if l[:i].count(e)==1:o+=[l[j:i]];j=i+1
  i+=1
 return o+[l[j:]]

Soluzione semplice. Esamino l'elenco, conto quante volte un personaggio è apparso prima e aggiungo la parte dall'ultimo controllo all'elenco di output.


3

Ruby, 66 anni

f=->a{s=Hash.new 0
r=[[]]
a.map{|e|(s[e]+=1)==2?r<<[]:r[-1]<<e}
r}

Spiegazione

  • eè un hash di occorrenza conta per ogni elemento, rè un array in cui è archiviato il risultato.
  • Passa attraverso l'input, incrementa il conteggio delle occorrenze per ciascun elemento di 1 .
    • Se il conteggio delle occorrenze è 2, dobbiamo suddividere. Aggiungi un vuoto Arrayal risultato.
    • Altrimenti aggiungi semplicemente l'elemento all'ultimo Arrayrisultato.

2
Cappello carino!! Oh aspetta.
Ottimizzatore

4
Che incredibile coincidenza! La risposta che ho pubblicato pochi secondi prima della tua è quasi identica. :)
Cristian Lupascu,

Oh mio Dio, è anche più corto di 1 carattere!
britishtea,

È un risparmio che puoi facilmente applicare al tuo. Penso sia fantastico che abbiamo avuto la stessa idea allo stesso tempo. : D
Cristian Lupascu,

3

CJam, 25 24 byte

q~{_L+:L1$a/,3=S@?}%Sa/p

Prende input da STDIN come

[ 2 1 2 1 0 2 2 1 1 3 4 3]

e uscite come

[[2 1] "" [0 2 2 1 1 3 4] ""]

Sto praticamente iterando su tutti gli elementi dell'array, uno per uno inserendoli in un altro array. Quindi ottengo il conteggio dell'elemento corrente nell'altro array. Se è 2, avvio un altro array da quella posizione. Questo tipo di avvio casuale dell'array può essere ottenuto solo in un linguaggio basato su stack.

Espansione del codice :

q~{_L+:L1$a/,3=S@?}%Sa/p
q~{               }%             "Evaluate the input array and map it on this block";
   _                             "Copy the current element in iteration";
    L+:L                         "Add the copy to an initially blank array L and update L";
        1$a/                     "Make another copy of the element and split L on it";
            ,3=                  "This checks if the splitted array is of length 3";
                                 "which indirectly means that L contains the element twice";
               S@?               "If the above is true, replace the element by space";
                    Sa/          "Split the final array on space. This final array contains";
                                 "second occurrence of every integer replaced by a space";
                       p         "Print the stringified version of the final nested array";

Provalo online qui

1 byte salvato dal suggerimento di Martin sulla chat


3

Rubino, 64 byte

s=->a{x=[];b=[[]];a.map{|e|x<<e;x.count(e)==2?b<<[]:b[-1]<<e};b}

3

Perl 5: 36

Non sono sicuro che ciò sia accettabile in quanto non si verifica alcuna divisione effettiva qui.

#!perl -pa
$x{$_}++-1or$_=']['for@F;$_="[[@F]]"

Esempio:

$ perl spl.pl <<<"2 1 1 2 3 2 2 4 5 6 7 3 7 0 5"
[[2 1 ][ ][ 3 2 2 4 5 6 7 ][ ][ 0 ][]]

Totalmente accettabile
Ottimizzatore il

Bella risposta. Ma la pratica standard, penso, è di contare -pacome due byte extra (perché "costa" solo due byte, dato che puoi scriverlo come -paeinvece di -e). Quindi sarebbe 38, non 36.
msh210

2

CJam, 28 byte

Lq~{1$1$a/,3=S2$?@++}/-2%S/`

Accetta input su STDIN come

[2 1 1 2 3 2 2 4 5 6 7 3 7 0 5]

e stampa l'output su STDOUT come

[[2 1] "" [3 2 2 4 5 6 7] "" [0] ""]

Si noti che le stringhe vuote e le matrici vuote sono la stessa cosa in CJam e sono visualizzate come "" impostazione predefinita (questo è la rappresentazione nativa delle matrici vuote).

(Ho iniziato a lavorarci un po 'prima che la sfida fosse pubblicata, perché stavamo discutendo di quanto sarebbe difficile la sfida.)

Spiegazione

Fondamentalmente, sto duplicando ogni elemento dell'array, a meno che non sia la seconda occorrenza, nel qual caso sostituisco la prima copia con uno spazio. Per motivi di golf, questo array modificato è costruito al contrario. Così[2 1 1 2 3 2 3] diventa

[3 S 2 2 3 3 2 S 1 S 1 1 2 2]

Quindi seleziono ogni secondo elemento dalla fine, che è l'array originale, ma con le seconde occorrenze sostituite da spazi, ad es

[2 1 S S 3 2 S]

Infine, ho semplicemente diviso l'array su spazi. Ecco una ripartizione del codice:

L                            "Push empty array.";
 q~                          "Read STDIN an evaluate.";
   {                }/       "For each element of the input.";
    1$1$                     "Copy the array and the element.";
        a/                   "Split the array by that element.";
          ,3=                "Check that it's split into 3 parts.";
             S2$?            "If so, push a space, else, copy the current number.";
                 @++         "Pull up the array from the bottom and add both to the beginning.";
                      -2%    "Pick every second element from the end.";
                         S/  "Split on spaces.";
                           ` "Get the string representation.";

Dato che questa è la mia sfida, per prima cosa sto dando una possibilità: P. Ho una soluzione Cjam da 25 byte con me.
Ottimizzatore

Non visualizza correttamente gli array vuoti - ovviamente non valido!
feersum

1
@feersum mostra array vuoti come ""è esplicitamente consentito nella prima revisione della domanda. L'attuale revisione afferma "qualsiasi formato utile ... di solito represtation di stringhe nativo di array".
John Dvorak,

2

Strumenti Unix, 100 byte

grep -o '[-0-9]*'|awk '{print(++A[$0]-2)?$0:"] ["}'|paste -sd' '|sed -e '/]/s/.*/[\0]/' -e's//[\0]/'

Esclude l'input tramite stdin. Praticamente sostituisce ogni secondo evento con "] [". Non funziona con stringhe vuote, []darà una stringa vuota, che penso sia una rappresentazione conveniente di un array vuoto :)


Bene, allora la risposta non è conforme alle specifiche, giusto? (su numeri interi negativi). Inoltre, che dire 11? verrà convertito in 1][?
Ottimizzatore

Funziona bene per 11, ma hai ragione sui numeri negativi, risolto questo, e ora accetta anche matrici singleton.
Pgy

2

APL, 42 caratteri

{'(',')',⍨⍵[(2=+/¨(↑=↓)¨⌽¨,\⍵)/⍳⍴⍵]←⊂')('}

Esempio:

{'(',')',⍨⍵[(2=+/¨(↑=↓)¨⌽¨,\⍵)/⍳⍴⍵]←⊂')('}2 1 1 2 3 2 2 4 5 6 7 3 7 0 5

Produzione:

( 2 1  )(   )(  3 2 2 4 5 6 7  )(   )(  0  )(  )

Testato qui.

Se devo emettere una stringa che viene interpretata esattamente come la giusta struttura in APL ... 49 caratteri

{'1↓1(',',⍬)',⍨⍵[(2=+/¨(↑=↓)¨⌽¨,\⍵)/⍳⍴⍵]←⊂',⍬)('}

Come viene effettivamente rappresentato un elenco nidificato in APL? Forse potresti non aver bisogno di manipolare le stringhe
Optimizer,

@Optimizer La stringa emessa è un elenco valido in un programma APL. Tuttavia non verrebbe nidificato se fosse presente un solo elenco. Preparare un 1↓1sembrava risolvere il problema, ma sembra troppo strano.
jimmy23013,

2

Java, 223

Funziona solo su Oracle o OpenJDK JRE, poiché utilizzo questa stranezza nella loro implementazione del quantificatore e del controllo della lunghezza nel look-behind per implementare il look-behind a lunghezza variabile.

class W{public static void main(String a[]){System.out.print("["+new java.util.Scanner(System.in).nextLine().replaceAll(" *\\b(\\d+)\\b(?=(.*))(?<=^(?=(.*\\b\\1\\b){2}\\2).*)(?<!^(?=(.*\\b\\1\\b){3}\\2).*) *","] [")+"]");}}

Gran parte del lavoro viene eseguito in regex, che viene mostrato di seguito in forma grezza:

 *\b(\d+)\b(?=(.*))(?<=^(?=(.*\b\1\b){2}\2).*)(?<!^(?=(.*\b\1\b){3}\2).*) *

Prima di esaminare il regex sopra, diamo un'occhiata al regex .NET equivalente, che è più semplice, poiché supporta direttamente il look-behind a lunghezza variabile (il look-behind .NET è probabilmente eseguito dalla modalità di corrispondenza da destra a sinistra) :

 *\b(\d+)\b(?<=(.*\b\1\b){2})(?<!(.*\b\1\b){3}) *
  •  *\b(\d+)\b e  * alla fine corrisponde a un numero e agli spazi circostanti (se presenti). I controlli associati servono a impedire la corrispondenza del numero parziale, poiché gli spazi su entrambi i lati sono opzionali. Cattura anche il numero per verificare se si tratta della 2a apparizione nella matrice.

  • (?<=(.*\b\1\b){2}) verifica che sia possibile trovare 2 istanze del numero acquisito sopra. (?<!(.*\b\1\b){3})verifica che non siano state trovate 3 istanze del numero acquisito. Entrambe le condizioni combinate affermano che finora ci sono solo 2 istanze del numero. I controlli associati sono lì per assicurarsi che l'intero numero sia testato.

Torna alla versione Java. Per implementare uno sguardo a lunghezza variabile, ci trasformiamo

(?<=var-length-pattern)

per

(?<=^(?=.*var-length-pattern).*)

Sto agitando un po 'la mano riguardo al fatto che .esclude i separatori di linea, ma può essere risolto facilmente e non voglio complicare ulteriormente la sintassi.

Il look-ahead ha sempre una lunghezza pari a 0 e il controllo della lunghezza passa a causa dell'implementazione del *quantificatore.

Non ^è necessario per farlo funzionare, ma è lì per far fallire più rapidamente il caso in errore. Il look-behind nell'implementazione Oracle / OpenJDK viene eseguito facendo un passo indietro della lunghezza minima del pattern, quindi abbinando, quindi sciacquando e ripetendo aumentando la lunghezza fino a quando non viene trovata una corrispondenza, o nel caso peggiore, alla lunghezza massima del pattern . Con^ , mi assicuro che la stringa del prefisso sia abbinata una sola volta.

Tuttavia, il look-ahead all'interno del look-behind non è limitato dal limite destro del look-behind, quindi può corrispondere fino alla fine della stringa. Per affermare il limite, catturo il resto della stringa in un altro gruppo di acquisizione all'interno di uno sguardo in avanti, e lo uso per limitare il regno del modello di lunghezza variabile.

(?=(.*))(?<=^(?=.*var-length-pattern\m).*)
   ^--^                              ^
   mth capturing group               m is the number of the capturing group marked

Poiché il mio modello inizia già con .*, non ho bisogno di aggiungerne un altro .*davanti.


1

Perl 108

map{$e[$_]==1?do{push@a,[@b];@b=();}:push@b,$_;$e[$_]++}split" ";push@a,[@b];s/.*/Data::Dumper->Dump(\@a)/e;

In azione:

perl -MData::Dumper -pe '
    $Data::Dumper::Terse = 1;
    $Data::Dumper::Indent = 0;
    @a=@b=@e=();
    map{$e[$_]==1?do{push@a,[@b];@b=();}:push@b,$_;$e[$_]++}split" ";
    push@a,[@b];
    s/.*/Data::Dumper->Dump(\@a)/e;
' <<<$'2 1 1 2 3 2 2 4 5 6 7 3 7 0 5\n2 1 1 1 4 5 6\n'"$(
    sed 's/./& /g;w/dev/stderr' <<< ${RANDOM}${RANDOM}${RANDOM}$'\n'${RANDOM}${RANDOM})"
2 4 4 7 7 2 9 8 8 4 6 0 1 8 
1 0 3 9 3 7 9 
[2,1][][3,2,2,4,5,6,7][][0][]
[2,1][1,4,5,6]
[2,4][7][][9,8][4,6,0,1,8]
[1,0,3,9][7][]

Nota: le due prime righe $Data::...sono lì solo per una presentazione migliore e la terza riga @a=@b=@e=();è lì per far funzionare lo strumento su più righe.


1

R, 76

y=scan();r=split(y,cumsum(ave(y,y,FUN=seq)==2));c(r[1],lapply(r[-1],"[",-1))

Output per l'esempio: un elenco di cinque elementi, inclusi tre vettori vuoti. ( numeric(0)).

$`0`
[1] 2 1

$`1`
numeric(0)

$`2`
[1] 3 2 2 4 5 6 7

$`3`
numeric(0)

$`4`
[1] 0

$`5`
numeric(0)

A proposito: il codice genera un messaggio di avviso che può essere ignorato.


1

awk 29

a[$1]++==1{print"-";next}1

Ciò richiede un po 'di libertà con i formati di input e output. L'ingresso "array" è verticale, un numero per riga. L'output è anche verticale, un numero per riga, con trattini che separano le matrici.

Ingresso:

2
1
1
2
3
2
2
4
5
6
7
3
7
0
5

Produzione:

2
1
–
–
3
2
2
4
5
6
7
–
–
0
–

1

Pyth 30 32

Questa è la mia prima volta a sperimentare con Pyth. È la stessa soluzione della mia soluzione Python.

VQIq/<QN@QN1~Y]:QZN=ZhN;+Y]>QZ

Puoi provarlo online: Pyth Compiler / Executor

Ad esempio, l'input

[2,1,1,2,3,2,2,4,5,6,7,3,7,0,5]

stamperà

[[2, 1], [], [3, 2, 2, 4, 5, 6, 7], [], [0], []]

Spiegazione:

                                 # Q = input(), Y = [], Z = 0
VQ                               # for loop: N iterates over the indices of Q
  I                              # if 
   q\<QN@QN1                     #    Q[N] appears exactly once in Q[:N]
            ~Y]:QZN              #         append the list [Q[Z:N]] to Y
                   =ZhN          #         and assign Z = N + 1
                       ;         # end if and for loop
                        +Y]>QZ   # print Y + [Q[Z:]]

C'è un'alternativa migliore per =Y+Y...?
Jakube,

questo è -~Y...
Ottimizzatore il

1

Python 2, 84

l=[[]];p=[]
for x in input():p+=[x];b=p.count(x)==2;l+=[[]]*b;l[-1]+=[x][b:]
print l

L'elenco lè l'output finora. Esaminiamo gli elementi. Se quello attuale è il secondo aspetto, iniziamo un nuovo sottoelenco vuoto; altrimenti, lo aggiungiamo all'elenco secondario più recente. L'elenco degli elementi visti finora è archiviato in p. Stranamente, ricostruire l'elenco sembra più breve che tagliare l'input.


1

Bash puro 111 94

81 per la sola divisione:

for i;do [ "${b[i]}" == 7 ]&&c+=("${d# }") d=||d+=\ $i;b[i]+=7;done;c+=("${d# }")
declare -p c

La seconda riga ha declare -p cappena scaricato la variabile

Campione:

splitIntFunc() {
    local b c d i
    for i;do
        [ "${b[i]}" == 7 ]&&c+=("${d# }") d=||d+=\ $i
        b[i]+=7
      done
    c+=("${d# }")
    declare -p c
}

Nota: la linea local b c d iè necessaria solo per eseguire la funzione più volte.

splitIntFunc 2 1 1 2 3 2 2 4 5 6 7 3 7 0 5
declare -a c='([0]="2 1" [1]="" [2]="3 2 2 4 5 6 7" [3]="" [4]="0" [5]="")'

splitIntFunc 2 1 1 1 4 5 6
declare -a c='([0]="2 1" [1]="1 4 5 6")'

splitIntFunc $(sed 's/./& /g;w/dev/stderr' <<<${RANDOM}${RANDOM}${RANDOM})
1 6 5 3 2 2 4 3 9 4 2 9 7 7 4 
declare -a c='([0]="1 6 5 3 2" [1]="4" [2]="9" [3]="2" [4]="7" [5]="4")'

splitIntFunc $(sed 's/./& /g;w/dev/stderr' <<<${RANDOM}${RANDOM}${RANDOM})
2 4 5 2 9 1 1 4 8 7 8 1 0 3 
declare -a c='([0]="2 4 5" [1]="9 1" [2]="" [3]="8 7" [4]="1 0 3")'

Per la presentazione più sexy (+26)

splitIntFunc() {
    local b c d i
    for i;do
        [ "${b[i]}" == 7 ]&&c+=("${d# }") d=||d+=\ $i
        b[i]+=7
      done
    c+=("${d# }")
    printf -v l "(%s) " "${c[@]}"
    echo "<$l>"

Renderà qualcosa del tipo:

splitIntFunc 2 1 1 2 3 2 2 4 5 6 7 3 7 0 5
<(2 1) () (3 2 2 4 5 6 7) () (0) () >

splitIntFunc $(sed 's/./& /g;w/dev/stderr' <<<${RANDOM}${RANDOM}${RANDOM})
4 3 8 1 4 5 7 9 2 7 8 4 0 
<(4 3 8 1) (5 7 9 2) () (4 0) >

splitIntFunc $(sed 's/./& /g;w/dev/stderr' <<<${RANDOM}${RANDOM}${RANDOM})
3 1 3 0 2 5 3 6 6 9 2 5 5 
<(3 1) (0 2 5 3 6) (9) () (5) >

splitIntFunc $(sed 's/./& /g;w/dev/stderr' <<<${RANDOM}${RANDOM}${RANDOM})
2 2 2 9 1 9 5 0 2 2 7 6 5 4 
<(2) (2 9 1) (5 0 2 2 7 6) (4) >


}

0

Scala, 122 111

Prendi la collezione di personaggi, stampa in forma di [21][][3224567][][0][], 122 111:

def s(a:Any*)=print((("[","")/:a){case((b,c),d)=>if(b.indexOf(d)==c.indexOf(d))(b+d,c)else(b+"][",c+d)}._1+"]")

... oppure prendi una raccolta di caratteri e restituisci elenchi nidificati, 135 129:

def s(a:Char*)=(("",List(List[Any]()))/:a){case((b,c),d)=>b+d->(if(b.count(d==)==1)List()::c else(c.head:+d)::c.tail)}._2.reverse

Sono sicuro che ci sono alcuni risparmi che potrei ottenere, non ho guardato troppo.


0

Python 220 byte

Il seguente è di 220 byte, il che non è eccezionale rispetto a molti altri, ma funziona abbastanza velocemente con numeri più grandi!

xlist = list(input()); result = []; x = 0
for i in range(len(xlist)):
    if xlist[0:i+1].count(xlist[i]) == 2: result.append(xlist[x:i]);x = i+1
    elif i == len(xlist)-1: result.append(xlist[x:])
print(result)

Ciao e benvenuto in PPCG! Tuttavia, il tuo codice non è abbastanza breve. Vedo alcuni posti dove puoi decisamente accorciarlo. Per favore, continua a giocare a golf.
Rɪᴋᴇʀ

Ciao! Se hai bisogno di aiuto golf, è possibile rimuovere gli spazi intorno =, il cambiamento xliste resultai nomi più brevi, e rimuovere gli spazi intorno ==, ;e :. Se hai bisogno di ulteriore aiuto, digita @NoOneIsHere(o qualsiasi nome utente) e io / l'utente proverò ad aiutarti.
NoOneIsHere il

-1

Java: 563 byte

nota che utilizza Java 8, pre-JDK8 sarebbe più lungo di qualche byte a causa del foreach.

import java.util.*;public class a{static String c(String[]b){List<String>d=new ArrayList<>(Arrays.asList(b));Set<String>e=new HashSet<>();Set<String>f=new HashSet<>();for(int i=0;i<Integer.MAX_VALUE;i++){String g;try{g=d.get(i);}catch(IndexOutOfBoundsException ex){break;}
if(e.contains(g)&&!f.contains(g)){d.remove(i);d.add(i,"]");d.add(i+1,"[");f.add(g);i++;}else{e.add(g);}}
d.add(0,"[[");d.add(d.size(),"]]");StringBuilder sb=new StringBuilder();d.forEach(sb::append);return sb.toString();}
public static void main(String[]args){System.out.println(c(args));}}

dove altro posso usare lambda? il looping fino alla lunghezza dell'array non è corretto perché l'elenco continua ad espandersi quando si aggiungono più "]" e "[".
PoweredByRice

incrementare la lunghezza ogni volta è tanto lungo quanto catturare l'eccezione, inoltre non penso che in Java sia possibile cambiare CEILING in (per i = 0; i <CEILING; i ++).
PoweredByRice


hmm non lo sapeva, grazie per averlo sottolineato.
PoweredByRice

Che dire di convertire Integer.MAX_VALUEin 2147483647? È lo stesso valore con meno byte. Inoltre, IndexOutOfBoundsExceptionpuò essere abbreviato inException
Charlie, il
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.