(A [l (t [e (r) n] e) s] t) uma string!


36

Alternar , é o ato de pegar uma corda e aninha-la entre colchetes. Aqui está como você alterna uma string.

  • Para uma sequência de comprimento N , pegue os caracteres N centrais e coloque-os entre parênteses. Portanto, se nossa string tiver Hello world!(12 caracteres), terminaremos com

    (Hello world!)
    
  • Em seguida, pegue os n-2caracteres centrais restantes e coloque-os entre colchetes. Nesse caso, os 10 caracteres centrais são ello world, portanto, a próxima iteração é:

    (H[ello world]!)
    
  • Enquanto houver mais de dois caracteres no meio da sequência, repita os dois últimos passos, alternando entre ()e []. Aqui estão os últimos passos:

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

    Como há apenas dois caracteres no meio na última iteração, paramos. Nossa string final é

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

    Observe como existem dois caracteres entre colchetes. Isso acontece quando a entrada tem um comprimento uniforme. Se a entrada tivesse um comprimento ímpar (por exemplo, Hello, world!com uma vírgula adicionada), teríamos apenas um caractere no meio:

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

Para o desafio de hoje, você deve escrever um programa ou função que use uma string como entrada e a alterne, produzindo a nova string. Você pode receber entrada e saída em qualquer formato razoável que desejar. A entrada sempre terá pelo menos um caractere e conterá apenas ASCII imprimível. Você também pode assumir que a entrada não conterá parênteses ou colchetes. Para idiomas tradicionais, isso não deve importar muito, mas pode facilitar para alguns idiomas esotéricos.

Como sempre, esse é um competição de , portanto, tente fazer a resposta mais curta possível no idioma de sua escolha. Diverta-se!

Teste de E / S

#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)


Devemos sempre começar com parênteses ( ()) ou podemos começar com colchetes ( [])?
totallyhuman

@totallyhuman Ele deve sempre começar com parênteses()
DJMcMayhem

Testcase proposta: HelloWorld.
Erik the Outgolfer

Além disso, são permitidos espaços à direita?
Erik the Outgolfer

Respostas:



9

C, 143 137 135 bytes

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(")");}

Experimente online!

Explicação:

// 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 bem me lembro de C, variáveis ​​declaradas globalmente são inicializadas para 0. Assim, você não deve precisar do k=i=0,. Eu posso estar errado. Veja esta resposta do SO
Tas

@Tas Você está realmente correto, mas as funções precisam ser reutilizáveis para serem válidas, portanto as variáveis ​​precisam ser inicializadas dentro da função.
Steadybox

7

Retina , 52 bytes

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

Experimente online! O primeiro estágio insere pares de parênteses entre cada par de caracteres de entrada, enquanto o segundo e o terceiro estágios corrigem parênteses alternados entre colchetes.



6

JavaScript (ES6), 69 68 bytes

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

Casos de teste


5

V , 25 26 25 bytes

1 2 bytes de desconto graças a @DJMcMayhem

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

Experimente online!

Emprestou algumas das idéias de @ udioca. Finalmente, também usei o plug - in surround incluído no V para uma resposta, embora possa não ter sido o melhor caminho, quem sabe. O plugin NÃO quer ser usado.

Hexdump:

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

Explicação:

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

Uau, bom trabalho! Eu estava preso em 29 bytes, mas faltando um monte de casos extremos. Esta é uma resposta bastante agradável. Você pode salvar um byte usando em ;vez do último f) Experimente online!
DJMcMayhem

É realmente quebrado agora, porque de espaços, eu vou apagar e correção
nmjcman101

@DJMcMayhem Posso ver o seu byte de 29 bytes? A menos que você pretende golf-lo debaixo de mim e competir, que eu não ficaria surpreso sobre :)
nmjcman101

Não funciona, por isso não me importo de mostrá-lo: tio.run/##K/v///… Ah, e BTW: chat.stackexchange.com/transcript/message/38434285#38434285 :)
DJMcMayhem

:( fazendo alternância ()e []é um byte mais curto, mas muito menos legal
nmjcman101

5

Haskell , 96 91 81 79 77 bytes

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

Experimente online!


1
Você pode deixar cair os pais (x:y)e (init y). k==""=""é mais curto como k==""=k.
Laikoni

1
Economize mais alguns bytes mudando cycle["()","[]"]para apenas "()[]": Experimente online!
Laikoni

Ótimas sugestões @Laikoni, graças
bartavelle

1
Boa captura que manter cycleé ainda mais curto. Você ainda pode remover os parênteses (init y).
Laikoni

1
Você pode mover o caso k==""=kpara o final e alterá-lo para 0<1=k.
Zgarb


2

Javascript (ES6) 110 105 bytes

Obrigado a @powelles por me lembrar x%y<1.

Obrigado @Luke por 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``


A primeira coisa a entender essa fera é destruí-la:

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.
}

Quase todas as linhas fazem parte da versão em golfe, portanto, passo a passo:

Linha 1: A instrução de função se torna uma função de seta , renomeando inputpara i. Torna-se i=>.

Linha 2: Array.from é a maneira nova e adequada de converter uma string em uma matriz e o que usamos nessa linha. No entanto, junto com ele, o operador de propagação é uma maneira mais barata do que a .split('')maneira antiga , de fazê-lo, que é o que é usado na versão de golfe. Termina como [...i].

Linha 3: .map percorre uma matriz, fornecendo três argumentos: item( ano campo de golfe) index,; jogou golfe como be baseArrayou c. Enquanto nos preocupamos apenas com , iteme indexcontinuamos baseArray(veja na linha 4 o porquê). Golfe para.map((a,b,c,...)=>... .

Linha 4: A variável middle, ou o argumento dna versão golfed é criada para salvar alguns bytes quando é repetida. O argumento cprecisava ser mantido para que o argumento dfosse criado. É convertido para (...,d=i.length/2-1,...).

Linha 5 : A variável alternateou argumento eé usada para verificar em que caractere estava "(" ou "[" ou se passou do meio ",") "e"] ". b%2<1é igual a b%2==0porque não pode ser menor que 1, mas 0 neste caso. Igual a (...,e=b%2<1).

Linha 6: Uma variável helper para permitir-me para converter o ternary operatorspara ifdeclarações. Não há nada no codegolf real.

Linhas 7-8 : Se o índice for menor que o meio da string, defina o símbolo como uma alternância de "[" e "(". Equivale a d>b?e?'[':'(':....

Linhas 9-12 : Caso contrário (se o índice for maior que o meio), verifique se o meio é um número inteiro; caso contrário, alterne a alternância. Em seguida, defina o símbolo como uma alternância de ')' e ']'. Ofuscado para (d%1==0?!e:e)?')':']'.

Linhas 13-15 : Se no meio, defina o símbolo como uma string vazia. Isso não se aplica a alternadores ímpares, porque o meio tem um decimal. Torna-se: d==b?'':....

Linha 16 : junta a matriz de caracteres novamente em uma sequência. Equivale a .join``.

Linha 17 : Retorna o símbolo inicial "(" e o resultado. Correlaciona para '('+....


Para algumas vitórias simples que você poderia mudar %2==0para %2<1e usar [...i]em vez dei.split
powelles

1
Obrigado @powelles. Eu tenho trabalhado em uma explicação mais do que em uma resposta completa, de modo que ainda não foi editada. Eu já tinha o [..i] idea, mas esqueci o %2<1obrigado.
David Archibald

b%2<1poderia ser substituído por!b%2
Luke

Além disso, d==b?x:ypoderia se tornar d-b?y:xe d%1==0poderia se tornar !d%1.
28617 Luke

Infelizmente, devido à ordem das operações, !d%1funciona apenas com parênteses:, !(d%1)e não retira nenhum bytes. Esqueci que 0 era o único número falso, por alguma razão eu pensei que -1 era o número falso. Corrija-me se estou entendendo algo errado sobre o segundo.
David Archibald

2

Geléia , 23 21 bytes

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

Experimente 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 bytes graças a @EricTheOutgolfer


Você pode remover uma linha e mover o link para o auxiliar para -2, desta forma:LHĊRị¶ç⁾)]żUFUż@ç⁾([$
Erik the Outgolfer

1

SCALA, 140 138 caracteres, 140 138 bytes

Me desculpe, eu não poderia fazer melhor ... Tenho certeza que existem muitas maneiras de melhorá-lo. Ainda:

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

Experimente online!

Obrigado por este desafio, foi muito difícil para mim.

EDIT: -2 ​​bytes graças a Mar Dev.

PS: Vou perguntar uma coisa. Eu entendo por que ESTE CÓDIGO continua duplicando o caractere central da minha string se eu tiver um comprimento ímpar (eu apenas não a verifico e a adiciono duas vezes, nas duas le nas rstrings). Mas por que eu obter um par de parênteses quando tento corrigi-lo como QUE ? Eu não entendo nada.


1
Você pode alterar i%2==0para i%2<1para salvar dois bytes.
Mario Ishac

1

Perl, 77 74 (73 + 1) bytes

Expressões regulares são coisas gloriosas. Execute com o -psinalizador de linha de comando.

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

1

05AB1E , 31 bytes

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

Experimente online!

Explicação

Com exemplos de entrada: 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 bytes

[Recursivo]

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 bytes

[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

Pitão , 42 (!) Bytes

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

Teste online! A entrada deve ser citada.

Explicações

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

Então, basicamente, removo progressivamente a cabeça e o final de H (sendo a string de entrada no início) enquanto concatenamos os parênteses / colchetes. G é apenas um booleano que lembra se devo usar colchetes ou parênteses.



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}

Experimente online!

Versão anterior*

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

* Obrigado @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}

Testado com gawk, mas deve funcionar com qualquer intérprete awk compatível

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

0

JavaScript, 101 bytes

Não é um vencedor, mas foi interessante tentar a replaceabordagem. Definitivamente, isso poderia ser melhorado, mas saiu rapidamente do controle ...

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)

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.