(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]!)
    
  • 限り、文字列の途中で左つ以上の文字があるとして、交互に、最後の2つの手順を繰り返します()[]。最後の手順は次のとおりです。

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

    最後の反復では、中央に2文字しか残っていないため、停止します。最後の文字列は

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

    中央の括弧に2つの文字があることに注意してください。これは、入力の長さが偶数の場合に発生します。入力の長さが奇数の場合(たとえば、Hello, world!コンマが追加されている場合)、中央に1文字しかありません。

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

今日の課題では、入力として文字列を受け取り、それを変更して新しい文字列を出力するプログラムまたは関数を作成する必要があります。任意の妥当な形式で入出力を行うことができます。入力は常に少なくとも1文字の長さで、印刷可能な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
エリックアウトゴルファー

また、末尾のスペースは許可されますか?
エリックアウトゴルファー

回答:



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確かに正しいのですが、関数は有効な送信のために再利用可能でなければならないため、関数内で変数を初期化する必要があります。
-Steadybox



6

JavaScript(ES6)、69 68バイト

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

テストケース


5

V25 26 25バイト

@DJMcMayhemのおかげで1 2バイトオフ

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

オンラインでお試しください!

@udiocaのアイデアの 一部を借りました。また、Vに含まれるサラウンドプラグインを最終的に使用して回答しましたが、それは最善の方法ではなかったかもしれません。プラグインは使用されません。

Hexdump:

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 /// ...ああ、ところで:chat.stackexchange.com/transcript/message/38434285#38434285 :)
DJMcMayhem

:(交互に行う()[]、バイトは短くなりますが、あまりクールではありません
-nmjcman101

5

Haskell96 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です。
ライコニ

1
変更することにより、いくつかのより多くのバイトを保存するcycle["()","[]"]だけに"()[]"それをオンラインお試しください!
ライコニ

@Laikoni素晴らしい提案、ありがとう
-bartavelle

1
保持cycleがさらに短くなることをよく理解してください。周りの括弧も削除でき(init y)ます。
ライコニ

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:あなたは3つの引数を与えて、配列をループitema、golfedに)index。としてゴルフbbaseArrayまたはc。我々が唯一気にしながらitemindex、我々は保たbaseArray(理由のための4行目を参照)。へのゴルフ.map((a,b,c,...)=>...

4行目:ゴルフバージョンの変数middle、引数、または引数dは、繰り返されるときに数バイトを節約するために作成されます。引数は、c引数に保たれていたd作成されます。に変換され(...,d=i.length/2-1,...)ます。

5行目:変数alternate、または引数eは、 "("または "["にある文字、または中間、 ")"および "]"を過ぎている文字を確認するために使用されます。b%2<1b%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感謝を忘れていました。
デビッドアーチボルド

b%2<1に置き換えることができます!b%2
ルーク

また、d==b?x:yなるかもしれないd-b?y:xd%1==0なる可能性があります!d%1
ルーク

あいにく、操作の順序のため、!d%1括弧でのみ機能します:!(d%1)、そしてバイトを削りません。私は0が唯一の偽の番号であることを忘れていました。何らかの理由で、-1が偽の番号だと思いました。2番目の問題について何か間違っている場合は修正してください。
デビッドアーチボルド

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ż@ç⁾([$
エリックOutgolfer

1

スカラ、 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バイト。

PS:私は何かを尋ねます。奇数の長さがある場合、このコードが文字列の中央の文字を複製し続ける理由を理解しています(両方lr文字列で2回チェックして追加しません)。しかし、それをTHATのように修正しようとすると、なぜかっこが表示されるのですか?まったくわかりません。


1
toを変更しi%2==0i%2<1、2バイトを節約できます。
マリオイシャック

1

Perl、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、154 145バイト

[再帰的]

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

JavaScript、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.