(A [l (t [e (r) n] e) s] t) una stringa!


36

Alternare , è l'atto di prendere una stringa e annidarla tra parentesi alternate. Ecco come alternare una stringa.

  • Per una stringa di lunghezza N , prendi i caratteri N centrali e racchiudili tra parentesi. Quindi se la nostra stringa fosse Hello world!(12 caratteri), finiremo con

    (Hello world!)
    
  • Quindi, prendi i restanti n-2caratteri centrali e racchiudili tra parentesi quadre. In questo caso, i 10 caratteri centrali sono ello world, quindi la prossima iterazione è:

    (H[ello world]!)
    
  • Finché sono rimasti più di due caratteri nel mezzo della stringa, ripetere gli ultimi due passaggi, alternando tra ()e []. Ecco gli ultimi passaggi:

    (Hello world!)
    (H[ello world]!)
    (H[e(llo worl)d]!)
    (H[e(l[l(o[ w]o)r]l)d]!)
    

    Poiché nell'ultima iterazione sono rimasti solo due caratteri nel mezzo, ci fermiamo. La nostra stringa finale è

    (H[e(l[l(o[ w]o)r]l)d]!)
    

    Nota come ci sono due caratteri tra parentesi centrali. Questo accade quando l'ingresso ha una lunghezza uniforme. Se l'input avesse una lunghezza dispari (ad esempio, Hello, world!con una virgola aggiunta), avremmo un solo carattere nel mezzo:

    (H[e(l[l(o[,( )w]o)r]l)d]!)
    

Per la sfida di oggi, è necessario scrivere un programma o una funzione che accetta una stringa come input e la alterna, producendo la nuova stringa. Puoi prendere input e output in qualsiasi formato ragionevole che ti piace. L'input avrà sempre almeno un carattere e conterrà solo ASCII stampabile. Puoi anche presumere che l'input non conterrà parentesi o parentesi quadre. Per le lingue tradizionali, questo non dovrebbe importare troppo, ma potrebbe rendere più semplice alcune lingue esoteriche.

Come al solito, si tratta di una competizione di , quindi cerca di fare la risposta più breve possibile nella lingua che preferisci. Divertiti!

Test IO

#Input                      #Output

"Alternesting is fun!"  --> (A[l(t[e(r[n(e[s(t[in]g) ]i)s] )f]u)n]!)
"PPCG"                  --> (P[PC]G)
"Code-golf"             --> (C[o(d[e(-)g]o)l]f)
"4 8 15 16 23 42"       --> (4[ (8[ (1[5( [1]6) ]2)3] )4]2)
"a"                     --> (a)
"ab"                    --> (ab)
"abc"                   --> (a[b]c)


Dobbiamo sempre iniziare tra parentesi (() ) o possiamo iniziare con parentesi ( [])?
totalmente umano il

@totallyhuman Dovrebbe sempre iniziare tra parentesi ()
DJMcMayhem

Testcase proposto: HelloWorld .
Erik the Outgolfer,

Inoltre, sono consentiti spazi finali?
Erik the Outgolfer,

Risposte:


20

Python 3 , 70 69 65 byte

-1 byte grazie a @Uriel
-4 byte grazie a @xnor

f=lambda s,b=0:s and'(['[b]+s[0]+f(s[1:-1],~b)+s[1:][-1:]+')]'[b]

Provalo online!


9

C, 143 137 135 byte

i,l,k;f(char*s){for(k=i=0,l=strlen(s);*s;printf("%c%c","([])"[i++%2+2*(i>l/2+!k)],*s++))i>l/2-1&&l&1^1&&putchar(*s++,k=++l);puts(")");}

Provalo online!

Spiegazione:

// Function (and variable) declaration.
i,l,k;f(char*s){

// Start the loop and initialize the variables. The loop terminates
// when the NUL-terminator of the string is reached.
for(k=i=0,l=strlen(s);*s;<this part saved for later>)

// Check if we have reached the middle of the string. Because of the
// short-circuiting of the conditions, we don't need to use an 'if'
// statement here; if a condition is false, no further conditions
// are evaluated.
i>l/2-1&&

// Equivalent to '!(l%2)', but one byte shorter. Checks if the length
// of the string is even.
l&1^1

// If we have reached the middle and the length of the string is even, 
// we'll need to skip one bracket, so we'll print the current character
// of the string and increment the pointer. Also we increment 'l' to
// avoid this getting done more than once, and give 'k' a non-zero
// value.
&&putchar(*s++,k=++l);

// The following is inside the 'increment' part of the 'for' loop.
// We print two characters. The first one is a bracket and the second
// one is the current character in the string.
printf("%c%c","([])"[i++%2+2*(i>l/2+!k)],*s++)

// The type of bracket is  chosen depending on the value of 'i'. A 
// character from the string "([])" is selected with the index 'i%2 + 2', 
// if we have reached the  middle of the string, and with index 'i%2', if
// we haven't.

// The exact part where this change happens depends on the parity of 
// the string length, so we use 'k' to signal if the length is even or 
// odd. If the length is odd, 'k==0', so '+!k' is the same as '+1'.  
// Otherwise 'k' is non-zero, so '+!k' is the same as '+0'.

// Output the final ')'.
puts(")");}

Se ricordo correttamente C, vengono inizializzate le variabili dichiarate a livello globale 0. Pertanto, non dovresti aver bisogno di k=i=0,. Potrei sbagliarmi. Vedi questa risposta SO
Tas,

@Tas In effetti hai ragione, ma le funzioni devono essere riutilizzabili per essere invii validi, quindi le variabili devono essere inizializzate all'interno della funzione.
Steadybox,

7

Retina , 52 byte

+`(?<!\()[^()]+(?!\))
($&)
(\(.)\(
$1[
r`\)(.\))
]$1

Provalo online! Il primo stadio inserisce coppie di parentesi tra ciascuna coppia di caratteri di input, mentre il secondo e il terzo stadio correggono le parentesi alternate tra parentesi.


6

Sed, 78

Il punteggio include +1 per l' -ropzione passata a sed.

s/.*/(&)/
:
s/(\(.)([^][]+)(.\))/\1[\2]\3/
t
s/(\[.)([^)(]+)(.\])/\1(\2)\3/
t

Provalo online .


6

JavaScript (ES6), 69 68 byte

f=([c,...s],i,l=s.pop())=>'[('[i^=1]+c+(s[0]?f(s,i)+l:l||'')+'])'[i]

Casi test


5

V , 25 26 25 byte

1 2 byte di sconto grazie a @DJMcMayhem

òC()Pé
%llòÍî
òF)%r[r];

Provalo online!

Ho preso in prestito alcune delle idee di @ udioca. Alla fine ho anche usato il plugin surround incluso in V per una risposta, anche se potrebbe non essere stato il modo migliore, chi lo sa. Il plug-in NON vuole essere utilizzato.

hexdump:

00000000: e3e1 0a6b f2e9 286c 6ce9 5b6c 6cf2 6af2  ...k..(ll.[ll.j.
00000010: e129 6868 e15d 6868 f2cd ce              .)hh.]hh...

Spiegazione:

-> |abcdefg      (the input, where | is the cursor)
ò              ' recursively
 C()           ' (C)hange from the cursor to the end of the line to '()'
-> (|)    (where | is the cursor)
     P         ' (P)aste the changed bit (what was there) left of the cursor
-> (abcdef|g)
      é        ' nsert a newline
-> (abcdef
   |g)
%              ' Goto the previous matching parenthese
-> |(abcdef
   g)
 ll            ' Move two characters right
-> (a|bcdef
   g)
   ò           ' End recursive loop (it will break on ll when there are no characters left
-> (a(b(c
   d)
   e)
   f)
    Íî         ' Remove all newlines
-> (a(b(cd)e)f|)
ò              ' Recursively
 F)            ' Go backwards to the next )
-> (a(b(cd)e|)f)
   %r[         ' Go to the matching paren and (r)eplace it with [
-> (a|[b(cd)e)f)
               ' Go back to the previous cursor location
-> (a[b(cd)e|)f)
       r]      ' (r)eplace this paren with ]
-> (a[b(cd)e|]f)
         ;     ' repeat F)
-> (a[b(cd|)e]f)
               ' implicitly end recursion

Wow, bel lavoro! Ero bloccato a 29 byte ma mancava un sacco di casi limite. Questa è una risposta piuttosto dolce. Puoi salvare un byte usando ;invece dell'ultimo f) Provalo online!
DJMcMayhem

In realtà è rotto in questo momento a causa degli spazi, ho intenzione di eliminare e correggere
nmjcman101

@DJMcMayhem Posso vedere il tuo 29 byte uno? A meno che tu non abbia intenzione di giocare a golf sotto di me e competere, di cui non sarei sorpreso :)
nmjcman101


:( si alterna ()ed []è un byte più breve ma molto meno cool
nmjcman101

5

Haskell , 96 91 81 79 77 byte

(cycle"()[]"!)
(l:r:a)!k|[x]<-k=[l,x,r]|x:y<-k=l:x:a!init y++[last y,r]|2>1=k

Provalo online!


1
Puoi far cadere i genitori (x:y)e (init y). k==""=""è più corto di k==""=k.
Laikoni,

1
Salva qualche altro byte cambiando cycle["()","[]"]in solo "()[]": provalo online!
Laikoni,

@Laikoni ottimi suggerimenti, grazie
bartavelle

1
Buona cattura che mantenere cycleè ancora più breve. È ancora possibile rimuovere la parentesi in giro (init y).
Laikoni,

1
Puoi spostare il caso k==""=kfino alla fine e cambiarlo in 0<1=k.
Zgarb,


2

Javascript (ES6) 110 105 byte

Grazie a @powelles per avermelo ricordato x%y<1.

Grazie @Luke per a-b?y:x

i=>'('+[...i].map((a,b,c,d=i.length/2-1,e=b%2<1)=>a+(d>b?e?'[':'(':d-b?(d%1==0?!e:e)?')':']'):'').join``


La prima cosa da capire in questa bestia è liberarla:

function alternest(input) { //input is i in the original
  let inputArray = Array.from(input); //the [...i] section
  let result = inputArray.map((item, index, baseArray) => { //result is an added helper variable
    let middle = input.length / 2 - 1, //the middle of the string
        alternate = index % 2 == 0; //should you alternate from '(' and '[' or ')' and ']'

    let symbol; //the alternating symbol

    if(middle > index) { //if its opening braces
      symbol = alternate ? '[' : '(';
    } else if(middle < index) {
      if(middle % 1 === 0) //if middle is a whole number
        alternate = !alternate; //reverse alternate
      symbol = alternate ? ')' : ']';
    } else { //if middle === index
      symbol = ''; //there's no symbol in the center for even alternests
    }
    return item + symbol; //convert the array item into the item and symbol
  }).join('');

  return '(' + result; //add the first symbol.
}

Quasi ogni linea fa parte della versione golfata, quindi passa in rassegna:

Riga 1: l'istruzione funzione diventa una funzione freccia , rinominandola inputin i. Diventa i=>.

Riga 2: Array.from è il nuovo modo corretto di convertire una stringa in un array e ciò che usiamo in questa riga. Tuttavia, insieme ad esso, l' operatore di diffusione è un modo più economico rispetto al vecchio .split('')modo, per farlo, che è ciò che viene utilizzato nella versione golfata. Finisce come [...i].

Linea 3: .map scorre in un array, dandoti tre argomenti: item( anel campo da golf) index,; golf come b, e baseArrayo c. Mentre ci preoccupiamo solo di iteme index, abbiamo continuato baseArray(vedere la riga 4 per il motivo). Golf a .map((a,b,c,...)=>....

Riga 4: la variabile middle, l'argomento o dnella versione golfata viene creata per salvare alcuni byte quando viene ripetuta. È cstato necessario mantenere l'argomento dper creare l' argomento . Viene convertito in (...,d=i.length/2-1,...).

Riga 5 : la variabile alternateo argomento eviene utilizzata per verificare su quale carattere si trovava "(" o "[" o se era oltre il centro, ")" e "]". b%2<1è uguale a b%2==0perché non può essere nulla di meno di 1, ma 0 in questo caso. Uguale (...,e=b%2<1).

Linea 6: variabile aiutante A mi permette di convertire la ternary operatorsa ifdichiarazioni. Non c'è niente nell'attuale codegolf.

Righe 7-8 : se l'indice è inferiore al centro della stringa, imposta il simbolo su un'alternanza di "[" e "(". Equivale a d>b?e?'[':'(':....

Righe 9-12 : Altrimenti (se l'indice è maggiore della metà), controlla se la metà è un numero intero, in tal caso cambia l'alternanza. Quindi impostare il simbolo su un'alternanza di ')' e ']'. Offuscato a (d%1==0?!e:e)?')':']'.

Linee 13-15 : se al centro imposta il simbolo su una stringa vuota. Questo non si applica agli alternatori dispari, perché il centro ha un decimale. Diventa: d==b?'':....

Riga 16 : unisce nuovamente l'array di caratteri in una stringa. Equivale a .join``.

Riga 17 : restituisce il simbolo iniziale "(" e il risultato. Correlato a '('+....


Per alcuni semplici vittorie si potrebbe cambiare %2==0per %2<1e utilizzare [...i]al posto dii.split
powelles

1
Grazie @powelles Ho lavorato su una spiegazione più che su una risposta completamente golf, quindi non è ancora diventata una modifica. Ho già avuto il [..i] idea, ma ho dimenticato %2<1grazie.
David Archibald,

b%2<1potrebbe essere sostituito da!b%2
Luca,

Inoltre, d==b?x:ypotrebbe diventare d-b?y:xe d%1==0potrebbe diventare !d%1.
Luca,

Sfortunatamente, a causa dell'ordine delle operazioni, funziona !d%1solo con le parentesi: !(d%1)e non si elimina i byte. Ho dimenticato che 0 era l'unico numero errato, per qualche motivo ho pensato che -1 fosse il falso. Correggimi se sbaglio qualcosa nel secondo.
David Archibald,

2

Gelatina , 23 21 byte

LHĊRị
ç⁾)]żUFUż@ç⁾([$

Provalo online!

LHĊRị           - helper function. Takes inputs of the input string and list of brace types
L                 - length of the input string
 HĊ               - number of parenthesis/brackets facing a single direction
   R              - range
    ị             - indexed into right argument: list of brace types ')]' or '(['

ç⁾)]żUFUż@ç⁾([$ - main function 
ç⁾)]              - get list of left-facing parentheses/brackets
    żU            - zip to the end (U) of the input string
      FU          - move the beginning of the string back to the beginning
        ż@        - zip with (to the start of the string):
          ç⁾([$   -the list of right-facing parentheses/brackets to the beginning

-2 byte grazie a @EricTheOutgolfer


È possibile rimuovere una linea e spostare il collegamento al supporto per -2, in questo modo:LHĊRị¶ç⁾)]żUFUż@ç⁾([$
Erik the Outgolfer

1

SCALA, 140 138 caratteri, 140 138 byte

Mi dispiace di non poter fare di meglio ... Sono sicuro che ci sono molti modi per migliorarlo. Ancora:

val n=s.length-1
var l=""
var r=""
for(i<-0 to n/2){l+=(if(i%2<1)"("else"[")
if(i!=n-i)l+=""+s(i)
r=""+s(n-i)+(if(i%2<1)")"else"]")+r}
l+r

Provalo online!

Grazie per questa sfida, è stato abbastanza difficile per me.

EDIT: -2 ​​byte grazie a Mar Dev.

PS: Chiederò qualcosa però. Capisco perché QUESTO CODICE continua a duplicare il carattere centrale della mia stringa se ho una lunghezza dispari (semplicemente non controllo e lo aggiungo due volte, in entrambe le in rstringhe). Ma il motivo per cui faccio ad avere un paio di parentesi quando provo correggerla come CHE ? Non capisco affatto.


1
È possibile modificare i%2==0in i%2<1per salvare due byte.
Mario Ishac,

1

Perl, 77 74 (73 + 1) byte

Le espressioni regolari sono cose gloriose. Esegui con il -pflag della riga di comando.

$x=qr/[^]()[]/;$z=qr/(^|$x)\K($x+)($|$x)/;s/$z/[$2]$3/ while s/$z/($2)$3/

1

05AB1E , 31 byte

2ä`Rð«„)]Ig©×øRJ®Èƒ¦}s„([®×søJì

Provalo online!

Spiegazione

Con esempi di input: abcd/abcde

2ä`                              # split input to 2 separate parts on stack
                                 # RESULT: 'ab','cd' / 'abc', 'de'
   R                             # reverse the second part
    ð«                           # append a space
      „)]                        # push the string ")]"
         Ig©×                    # repeat it len(input) times
             ø                   # zip with the second part of the input string
              RJ                 # reverse and join to string
                                 # RESULT:  ' )c]d)' /  ' )d]e)'
                ®Èƒ¦}            # remove the first (1,2) chars for (odd,even) length input
                                 # RESULT: 'c]d)' / ')d]e)'
                     s           # swap the first part of the input string to top of stack
                      „([®×      # repeat the string "([" len(input) times
                           sø    # zip with first part of input string
                                 # RESULT: ['(a', '[b'] / ['(a', '[b', '(c']
                             Jì  # join to string and prepend to the second part

1

C ++ 14, 154 145 byte

[Ricorsivo]

auto L(string i,bool b=1){int l=i.length();string o=b?"(":"[";auto c=b?")":"]";if(l<3)return o+i+c;return o+i[0]+L(i.substr(1,l-2),!b)+i[l-1]+c;}

C ++ 14, 177 byte

[Iterativo]

auto l(string s){int z=s.length();string r(z*2+z%2,'-');int i=0;for(;i<z;i+=2)r[i]=i/2%2?'[':'(',r[i+1]=s[i/2];for(i=z;i<2*z;i+=2)r[i]=s[i/2],r[i+1]=(i+1)/2%2?')':']';return r;}

0

Pyth , 42 (!) Byte

M?!lHH+@,\[\(G++hHg!GPtH+?qlH1keH@,\]\)Gg1

Provalo online! L'ingresso deve essere citato.

spiegazioni

M                                             # Define a function g with arguments G and H
 ?!lHH                                        # If len(H) == 0, return H. Otherwise...
      +@,\[\(G                                # Concatenate [ or ( to...
               +hHg!GPtH                      # ...to H[0] concatenated to g(not(G), H[1:-1]), itself concatenated...
              +          ?qlH1keH             # ...to H[-1] if len(H) != 1, otherwise to "" (that's for odd length input strings)...
                        +        @,\]\)G      # ...and to that concatenate ] or ).
                                        g1    # Call g(True, Q). Q is implicit input

Quindi sostanzialmente rimuovo progressivamente la testa e la fine di H (essendo la stringa di input all'inizio) concatenando le parentesi / parentesi. G è solo un booleano che ricorda se devo usare parentesi o parentesi.



0

PowerShell, 125 119 111 bytes

{param($s)for($p='()[]';($f,$s,$g=$s-split'(?<=.)(.+)(?=.)')[0]){$l+=$p[$i++]+$f;$r=$g+$p[$i++]+$r;$i%=4}$l+$r}

Try it online!

Previous version*

{for($s="($args)";$s-ne($t=$s-replace'(\(.)([^][]+)(.\))','$1[$2]$3'-replace'(\[.)([^)(]+)(.\])','$1($2)$3')){$s=$t}$s}

*Thanks @Digital Trauma.



0

AWK, 118 bytes

{b=")";for(j=l=length(c=$0);j>0;){x=substr(c,j--,1);b=(j>l/2?(((d=!d)?"]":")")x):j==l/2?x:((d=!d)?"(":"[")x)b}print b}

Tested with gawk, but it should work with any compliant awk interpreters

$ awk -f alternesting.awk <<< 'abc'
(a[b]c)

0

JavaScript, 101 bytes

Not a winner, but it was interesting to try the replace approach. This could definitely be improved, but it got out of hand quick...

s=>"("+s.replace(/./g,(a,b)=>a+(l%2|b*2+2!=l?")][("[3*(c=l>(b+=l%2-1)*2+2)+(b-c*l)%2]:""),l=s.length)

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.