(A [l (t [e (r) n] e) s] t) 문자열!


36

Alternesting 은 문자열을 가져 와서 대괄호 안에 중첩시키는 행위입니다. 다음은 문자열 을 대체 하는 방법 입니다.

  • 길이가 N 인 문자열의 경우 가운데 N 문자를 사용하고 괄호로 묶습니다. 문자열이 Hello world!(12 자)라면

    (Hello world!)
    
  • 그런 다음 나머지 중심 n-2문자를 가져 와서 대괄호로 묶으십시오. 이 경우 가운데 10자는 ello world입니다. 다음 반복은 다음과 같습니다.

    (H[ello world]!)
    
  • 문자열 중간에 문자가 두 개 이상 남아있는 경우 마지막 두 단계를 반복하여 ()와 사이를 번갈아 가십시오 []. 마지막 단계는 다음과 같습니다.

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

    마지막 반복에서 중간에 두 문자 만 남았으므로 중지합니다. 마지막 줄은

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

    가운데 괄호에 두 문자가 어떻게 나타나는지 참고하십시오. 이것은 입력이 짝수 길이 일 때 발생합니다. 입력이 홀수 길이 인 경우 (예 Hello, world!: 쉼표가 추가 된 경우) 중간에 하나의 문자 만 있습니다.

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

오늘날의 과제를 해결하려면 문자열을 입력으로 사용하고이를 대체하여 새 문자열을 출력하는 프로그램이나 함수를 작성해야합니다. 원하는 형식으로 입력 및 출력 할 수 있습니다. 입력은 항상 하나 이상의 문자 길이이며 인쇄 가능한 ASCII 만 포함합니다. 입력에 괄호 나 대괄호가 포함 되지 않는다고 가정 할 수도 있습니다. 전통적인 언어의 경우이 문제는 그다지 중요하지 않지만 일부 난해한 언어에서는 더 쉬울 수 있습니다.

평소와 마찬가지로 이것은 경쟁이므로 선택한 언어로 가능한 한 짧은 답변을 작성하십시오. 즐기세요!

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)


항상 괄호 ( ())로 시작해야 하거나 대괄호 ( [])로 시작할 수 있습니까?
완전히 인간적인

@totallyhuman 항상 괄호로 시작해야합니다()
DJMcMayhem

제안 된 테스트 케이스 : HelloWorld.
Outgolfer Erik

또한 후행 공백이 허용됩니까?
Outgolfer Erik

답변:



9

C, 143 (137) 135 바이트

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

온라인으로 사용해보십시오!

설명:

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

C를 올바르게 기억하면 전역 적으로 선언 된 변수가로 초기화됩니다 0. 따라서을 필요로하지 않아야합니다 k=i=0,. 내가 틀렸을지도 모른다. 참조 이 SO 답변
TAS

@Tas 실제로는 정확하지만 함수는 유효한 제출물 로 재사용 할 수 있어야하므로 함수 내에서 변수를 초기화해야합니다.
Steadybox

7

레티 나 , 52 바이트

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

온라인으로 사용해보십시오! 첫 번째 단계는 각 입력 문자 쌍 사이에 괄호 쌍을 삽입하는 반면 두 번째와 세 번째 단계는 대체 괄호를 대괄호로 수정합니다.



6

자바 스크립트 (ES6), 69 68 바이트

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

테스트 사례


5

V , 25 26 25 바이트

@DJMcMayhem 덕에 1 2 바이트 할인

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

온라인으로 사용해보십시오!

@udioca의 아이디어 중 일부를 차용했습니다 . 마지막으로 V에 포함 된 서라운드 플러그인을 사용하여 답을 구했습니다. 플러그인을 사용하고 싶지 않습니다.

16 진 덤프 :

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

설명:

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

와, 잘 했어! 나는 29 바이트에 붙어 있었지만 많은 경우가 빠져있었습니다. 이것은 꽤 달콤한 답변입니다. ;마지막 f) 온라인
DJMcMayhem

그것은 실제로 때문에 공간의 지금 생겼습니다, 나는 삭제 및 수정거야
nmjcman101

@DJMcMayhem 29 바이트를 볼 수 있습니까? 당신은 내가 :)에 대해 놀라지 않을 것이다 저와 경쟁에서 골프를, 계획이 아니라면
nmjcman101

작동하지 않으므로 표시하지 않아도됩니다. tio.run/##K/v//… 오, 그리고 BTW : chat.stackexchange.com/transcript/message/38434285#38434285 :)
DJMcMayhem

:( 교체 ()하고 []바이트는 짧지 만 덜 시원합니다
nmjcman101

5

하스켈 , 96 91 81 79 77 바이트

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

온라인으로 사용해보십시오!


1
당신은 주위에 부모를 놓을 수 있습니다 (x:y)(init y). k==""=""로 짧습니다 k==""=k.
Laikoni 2016 년

1
다음으로 변경 cycle["()","[]"]하여 더 많은 바이트를 절약하십시오 "()[]". 온라인으로 시도하십시오!
Laikoni 2016 년

@Laikoni 큰 제안, 감사합니다
bartavelle

1
cycle더 짧게 유지하는 것이 좋습니다 . 여전히 괄호를 제거 할 수 있습니다 (init y).
Laikoni

1
사례 k==""=k를 끝으로 이동하여로 변경할 수 0<1=k있습니다.
Zgarb


2

자바 스크립트 (ES6) 110 105 바이트

에 대해 알려주는 @powelles에게 감사합니다 x%y<1.

감사합니다 @Luke 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``


이 짐승을 이해하는 첫 번째 일은 그것을 풀고 있습니다.

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

거의 모든 라인은 골프 버전의 일부이므로 다음 단계를 수행하십시오.

1 행 : 함수 명령문이로 이름이 바뀌는 화살표 함수input됩니다 i. 가된다 i=>.

2 행 : Array.from 문자열을 배열로 변환하는 새롭고 적절한 방법이며이 행에서 사용하는 방법입니다. 그러나 그것과 함께 스프레드 연산자 는 이전 버전보다 저렴 .split('')합니다. 골프 버전에서 사용됩니다. 로 끝납니다 [...i].

행 3 : .map 배열을 통해 루프, 당신에게 세 가지 인수를주는 : item( agolfed에서) index; 같은 golfed b, 그리고 baseArrayc. 우리는 itemand 만 신경 index쓰지만 계속 유지했습니다 baseArray(이유는 4 행 참조). 에 골프 .map((a,b,c,...)=>....

4 행 : 골프 버전 의 변수 middle, 또는 인수 d는 반복 될 때 몇 바이트를 저장하기 위해 작성됩니다. 인수 cd작성 되려면 인수가 유지 되어야했습니다. 로 변환됩니다 (...,d=i.length/2-1,...).

5 행 : 변수 alternate또는 인수 e를 사용하여 "("또는 "["에있는 문자 또는 중간을 지나친 문자, ")"및 "]"를 확인합니다. b%2<1같은지 b%2==0가이 경우 1 이상의 것도 있지만, 0이 될 수 있기 때문이다. 같습니다 (...,e=b%2<1).

6 행 :ternary operators to if문 을 변환 할 수있는 도우미 변수 입니다. 실제 codegolf에는 아무것도 없습니다.

7-8 행 : 색인이 문자열의 중간보다 작 으면 기호를 "["및 "("의 대체로 설정하십시오 d>b?e?'[':'(':....

9-12 행 : 그렇지 않으면 (색인이 중간보다 큰 경우) 중간이 정수인지 확인하십시오. 그런 다음 기호를 ')'및 ']'의 대체로 설정하십시오. 난독 처리되었습니다 (d%1==0?!e:e)?')':']'.

13-15 행 : 중간에있는 기호를 빈 문자열로 설정합니다. 중간에는 십진수가 있으므로 홀수 대체 문자에는 적용되지 않습니다. 된다 : d==b?'':....

16 행 : 문자 배열을 다시 문자열로 결합합니다. 와 같습니다 .join``.

17 행 : 시작 기호 "("및 결과를 반환합니다 '('+....


몇 가지 간단한 승리를 위해 대신 다음 %2==0으로 변경 하여 %2<1사용할 수 있습니다.[...i]i.split
powelles

1
감사합니다 @powelles 나는 완전히 골프 답변보다 더 많은 설명을 위해 노력하고 있으므로 아직 편집하지 못했습니다. 나는 이미을 가지고 [..i] idea있었지만 %2<1감사를 잊었다 .
David Archibald

b%2<1!b%2
Luke

또한 d==b?x:y될 수 d-b?y:x있고 d%1==0될 수 !d%1있습니다.
Luke

불행하게도 연산 순서로 인해 !d%1괄호로만 작동하며 !(d%1)바이트를 제거하지 않습니다. 나는 0이 틀린 숫자라는 것을 잊었다. 어떤 이유로 나는 -1이 틀린 것이라고 생각했다. 두 번째 문제가 발생하면 바로 잡으십시오.
David Archibald

2

젤리 , 23 21 바이트

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

온라인으로 사용해보십시오!

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

@EricTheOutgolfer 덕분에 -2 바이트


라인을 제거하고 다음과 같이 -2의 도우미 링크 로 이동할 수 있습니다 .LHĊRị¶ç⁾)]żUFUż@ç⁾([$
Erik the Outgolfer

1

SCALA, (140 개) 138 문자, 140 138 바이트

더 잘할 수 없어서 죄송합니다. 개선 할 수있는 방법이 많이 있습니다. 아직도:

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

온라인으로 사용해보십시오!

이 도전에 감사드립니다.

편집 : Mar Dev 덕분에 -2 바이트.

추신 : 나는 뭔가를 물을 것입니다. 길이가 홀수 인 경우이 코드가 문자열의 중앙 문자를 계속 복제하는 이유를 이해 합니다 ( 문자열 lr문자열 모두에서 두 번 확인하고 추가하지 않음 ). 그러나 왜 그런 식으로 수정하려고하면 괄호 쌍이 생깁니 까? 나는 전혀 이해하지 못한다.


1
당신은을 변경할 수 있습니다 i%2==0위해 i%2<12 바이트를 저장합니다.
마리오 Ishac

1

펄, 77 74 (73 + 1) 바이트

정규 표현은 영광스러운 것입니다. -p명령 행 플래그로 실행하십시오 .

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

1

05AB1E , 31 바이트

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

온라인으로 사용해보십시오!

설명

입력 예 : 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, 154145 바이트

[재귀]

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 바이트

[반복적 인]

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 (!) 바이트

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

온라인으로 테스트하십시오! 입력을 인용해야합니다.

설명

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

따라서 기본적으로 괄호 / 괄호를 연결하면서 H의 머리와 끝을 처음부터 입력 문자열로 점차 제거합니다. G는 괄호 또는 괄호를 사용 해야하는지 기억하는 부울입니다.



0

PowerShell을 125 119 111 바이트

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

온라인으로 사용해보십시오!

이전 버전*

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

* @ Digital Trauma에게 감사합니다.



0

AWK, 118 바이트

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

gawk로 테스트되었지만 호환되는 awk 통역사와 작동해야합니다.

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

0

자바 스크립트, 101 바이트

승자는 아니지만 replace접근 방식 을 시도하는 것은 흥미로 웠습니다 . 이것은 확실히 향상 될 수 있지만 빨리 손에서 나왔습니다 ...

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)

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.