(A [l (t [e (r) n] e) s] t) ciąg!

36

Alternesting to czynność polegająca na wzięciu łańcucha i zagnieżdżeniu go w naprzemiennych nawiasach. Oto jak zmienić ciąg.

  • W przypadku ciągu o długości N weź środkowe N znaków i otocz je nawiasami. Więc jeśli nasz ciąg miał Hello world!(12 znaków), to skończymy

    (Hello world!)
    
  • Następnie weź pozostałe środkowe n-2postacie i otocz je nawiasami kwadratowymi. W tym przypadku środkowych 10 znaków to ello world, więc następna iteracja to:

    (H[ello world]!)
    
  • Dopóki na środku ciągu pozostaną więcej niż dwa znaki, powtórz ostatnie dwa kroki, naprzemiennie między ()i []. Oto ostatnie kroki:

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

    Ponieważ na ostatniej iteracji na środku pozostały tylko dwie postacie, zatrzymujemy się. Nasz ostatni ciąg to

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

    Zwróć uwagę, że w środkowych nawiasach znajdują się dwa znaki. Dzieje się tak, gdy wejście ma równą długość. Gdyby dane wejściowe miały nieparzystą długość (na przykład Hello, world!z dodanym przecinkiem), mielibyśmy tylko jeden znak pośrodku:

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

W dzisiejszym wyzwaniu musisz napisać program lub funkcję, która pobiera ciąg znaków jako dane wejściowe i zmienia go, generując nowy ciąg. Możesz pobierać dane wejściowe i wyjściowe w dowolnym rozsądnym formacie. Dane wejściowe zawsze będą miały co najmniej jeden znak i będą zawierać tylko drukowalne ASCII. Możesz również założyć, że dane wejściowe nie będą zawierać nawiasów ani nawiasów kwadratowych. W przypadku języków tradycyjnych nie powinno to mieć większego znaczenia, ale może to ułatwić niektóre języki ezoteryczne.

Jak zwykle są to zawody z , więc postaraj się udzielić możliwie najkrótszej odpowiedzi w wybranym języku. Baw się dobrze!

Przetestuj 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)
DJMcMayhem
źródło
Powiązane
DJMcMayhem
Czy zawsze musimy zaczynać od nawiasów ( ()), czy możemy zaczynać od nawiasów ( [])?
totalnie ludzki,
@totallyhuman Zawsze powinno zaczynać się od nawiasów()
DJMcMayhem
Proponowane testcase: HelloWorld.
Erik the Outgolfer,
Czy dozwolone są również spacje końcowe?
Erik the Outgolfer

Odpowiedzi:

20

Python 3 , 70 69 65 bajtów

-1 bajtów dzięki @Uriel
-4 bajtów dzięki @xnor

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

Wypróbuj online!

ovs
źródło
9

C, 143 137 135 135 bajtów

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

Wypróbuj online!

Wyjaśnienie:

// 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(")");}
Steadybox
źródło
Jeśli dobrze pamiętam C, zmienne deklarowane globalnie są inicjalizowane 0. Dlatego nie powinieneś potrzebować k=i=0,. Mogę się mylić. Zobacz tę SO odpowiedź
Tas
@Tas Rzeczywiście masz rację, ale funkcje muszą być wielokrotnego użytku, aby były poprawnymi przesłaniami, więc zmienne należy zainicjować wewnątrz funkcji.
Steadybox
7

Siatkówka , 52 bajty

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

Wypróbuj online! Pierwszy etap wstawia pary nawiasów między każdą parą znaków wejściowych, natomiast drugi i trzeci etap korygują naprzemienne nawiasy w nawiasach.

Neil
źródło
6

Sed, 78

Wynik obejmuje +1 dla -ropcji przekazanej do sed.

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

Wypróbuj online .

Cyfrowa trauma
źródło
6

JavaScript (ES6), 69 68 bajtów

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

Przypadki testowe

Arnauld
źródło
5

V , 25 26 25 bajtów

1 2 bajty wyłączone dzięki @DJMcMayhem

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

Wypróbuj online!

Pożyczył niektóre pomysły @ udioca. W końcu użyłem też wtyczki surround zawartej w V jako odpowiedzi, choć może nie był to najlepszy sposób, kto wie. Wtyczka NIE chce być używana.

Hexdump:

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

Wyjaśnienie:

-> |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
nmjcman101
źródło
Wow, niezła robota! Utknąłem przy 29 bajtach, ale brakowało mi kilku skrzynek. To całkiem słodka odpowiedź. Możesz zapisać jeden bajt, używając ;zamiast ostatniego f) Wypróbuj online!
DJMcMayhem
Obecnie jest zepsuty z powodu spacji, zamierzam go usunąć i naprawić
nmjcman101
@DJMcMayhem Czy mogę zobaczyć twój 29 bajtowy? Chyba że planujesz grać w golfa pode mną i konkurować, co nie byłbym zaskoczony :)
nmjcman101
To nie działa, więc nie mam nic przeciwko, aby ci to pokazać : tio.run/##K/v///… Aha i BTW: chat.stackexchange.com/transcript/message/38434285#38434285 :)
DJMcMayhem
:( robi na przemian ()i []jest bajt krótszy, ale o wiele mniej fajny
nmjcman101
5

Haskell , 96 91 81 79 77 bajtów

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

Wypróbuj online!

bartavelle
źródło
1
Możesz porzucić rodziców (x:y)i (init y). k==""=""jest krótszy jak k==""=k.
Laikoni
1
Zaoszczędź więcej bajtów, zmieniając cycle["()","[]"]na "()[]": Wypróbuj online!
Laikoni
@Laikoni świetne sugestie, dzięki
bartavelle
1
Dobry chwyt, że trzymanie cyclejest jeszcze krótsze. Nadal możesz usunąć nawias wokół (init y).
Laikoni
1
Możesz przenieść skrzynkę k==""=kna koniec i zmienić ją na 0<1=k.
Zgarb
2

Rubinowy , 79 77 bajtów

-2 bajty dzięki @Value Ink

->s{z=s.size
(z/2+z%2).times{|i|s.insert k=i*2,'(['[i%2]
s[~k]+=')]'[i%2]}
s}

Wypróbuj online!

Alex
źródło
s.insert k=i*2,'(['[i%2];s[~k]+=')]'[i%2]aby zapisać 2 bajty. Wypróbuj online!
Wartość tuszu
2

JavaScript (ES6) 110 105 bajtów

Dzięki @powelles za przypomnienie mi x%y<1.

Dzięki @Luke za 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``


Pierwszą rzeczą w zrozumieniu tej bestii jest jej odkrycie:

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

Prawie każda linia jest częścią wersji golfowej, więc krok po kroku:

Wiersz 1: Instrukcja funkcji staje się funkcją strzałki , zmieniając inputjej nazwę na i. Staje i=>.

Wiersz 2: Array.from to nowy, właściwy sposób konwersji łańcucha na tablicę i to, czego używamy w tej linii. Jednak wraz z nim operator rozprzestrzeniania jest tańszym sposobem niż stary .split(''), aby to zrobić, co jest używane w wersji golfowej. Kończy jako [...i].

Wiersz 3: .map zapętla tablicę, podając trzy argumenty: item( aw golfie) index,; grał w golfa jako bi baseArraylub c. Chociaż dbamy tylko o itemi index, zachowaliśmy baseArray(dlaczego w linii 4). Golfy do .map((a,b,c,...)=>....

Wiersz 4: Zmienna middle, lub argument dw wersji golfowej jest tworzony, aby zapisać kilka bajtów, gdy zostanie powtórzony. Argument cmusiał zostać zachowany, daby powstał argument . Jest konwertowany na (...,d=i.length/2-1,...).

Wiersz 5 : Zmienna alternatelub argument esłuży do sprawdzenia, jaki znak znajdował się na „(” lub „[” lub jeśli przekroczył środek, „)” i „]”. b%2<1jest równa, b%2==0ponieważ nie może być mniejsza niż 1, ale w tym przypadku 0. Równa (...,e=b%2<1).

Linia 6: Zmienna pomocnika A do pozwala mi przekonwertować ternary operatorsdo ifsprawozdania. Nie ma nic w prawdziwym codegolfie.

Linie 7-8 : Jeśli indeks jest mniejszy niż środek ciągu, ustaw symbol na przemian „[” i „(” d>b?e?'[':'(':....

Linie 9-12 : W przeciwnym razie (jeśli indeks jest większy niż środek), sprawdź, czy środek jest liczbą całkowitą, jeśli tak, zmień alternatywę. Następnie ustaw symbol na przemian „)” i „]”. Zaciemniony do (d%1==0?!e:e)?')':']'.

Linie 13-15 : Jeśli w środku ustaw symbol na pusty ciąg. Nie dotyczy to dziwnych alternesterów, ponieważ środek ma przecinek dziesiętny. Postać: d==b?'':....

Wiersz 16 : Łączy tablicę znaków z powrotem w ciąg. Odpowiada .join``.

Wiersz 17 : zwraca symbol początkowy „(” i wynik. Koreluje z '('+....

David Archibald
źródło
Dla niektórych prostych zwycięstw mógł zmienić %2==0się %2<1i używać [...i]zamiasti.split
powelles
1
Dzięki @powelles Pracowałem nad wyjaśnieniem bardziej niż w pełni golfową odpowiedzią, więc nie znalazłem się jeszcze w edycji. Miałem już [..i] idea, ale zapomniałem o %2<1podziękowaniach.
David Archibald
b%2<1może zostać zastąpiony przez!b%2
Luke
Również d==b?x:ymoże stać się d-b?y:xi d%1==0może stać się !d%1.
Luke
Niestety z powodu kolejności operacji !d%1działa tylko z nawiasami: !(d%1)i nie goli żadnych bajtów. Zapomniałem, że 0 to jedyna liczba fałszów, z jakiegoś powodu myślałem, że -1 to fałsz. Popraw mnie, jeśli coś jest nie tak z drugim.
David Archibald
2

Galaretka , 23 21 bajtów

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

Wypróbuj 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 bajty dzięki @EricTheOutgolfer

fireflame241
źródło
Możesz usunąć linię i przesunąć do linku pomocnika na -2, w ten sposób:LHĊRị¶ç⁾)]żUFUż@ç⁾([$
Erik Outgolfer
1

SCALA, 140 138 znaków, 140 138 bajtów

Przepraszam, że nie mogłem nic lepszego ... Jestem pewien, że istnieje wiele sposobów, aby to poprawić. Nadal:

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

Wypróbuj online!

Dzięki za to wyzwanie, było to dla mnie dość trudne.

EDYCJA: -2 bajty dzięki Mar Dev.

PS: Zapytam jednak o coś. Rozumiem, dlaczego ten kod utrzymuje powielenie centralny char mojego ciąg jeśli mam nieparzystej długości (po prostu nie sprawdzić i dodać go dwukrotnie, w obu li rsmyczki). Ale dlaczego dostaję parę nawiasów, gdy próbuję je poprawić TAK ? W ogóle nie rozumiem.

V. Courtois
źródło
1
Można zmienić i%2==0, aby i%2<1zapisać dwa bajty.
Mario Ishac
1

Perl, 77 74 (73 + 1) bajtów

Wyrażenia regularne to chwalebne rzeczy. Uruchom z -pflagą wiersza poleceń.

$x=qr/[^]()[]/;$z=qr/(^|$x)\K($x+)($|$x)/;s/$z/[$2]$3/ while s/$z/($2)$3/
Silvio Mayolo
źródło
1

05AB1E , 31 bajtów

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

Wypróbuj online!

Wyjaśnienie

Z przykładami danych wejściowych: 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
Emigna
źródło
1

C ++ 14, 154 145 bajtów

[Rekurencyjny]

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 bajtów

[Wielokrotny]

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;}
Robert Andrzejuk
źródło
0

Pyth , 42 (!) Bajtów

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

Przetestuj online! Dane wejściowe należy zacytować.

Objaśnienia

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

Zasadniczo więc stopniowo usuwam nagłówek i koniec litery H (która jest łańcuchem wejściowym na początku), jednocześnie łącząc nawiasy / nawiasy. G to po prostu wartość logiczna, która pamięta, czy muszę używać nawiasów lub nawiasów.

Jim
źródło
0

05AB1E , 49 42 bajtów

g;îD„([×s£©"s‚.Bøvy¬ðQi¦}}JR"DU.V®D∞sKRX.V

Wypróbuj online!

Erik the Outgolfer
źródło
0

PowerShell, 125 119 111 bajtów

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

Wypróbuj online!

Poprzednia wersja*

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

* Dzięki @ uraz cyfrowy.

Andrei Odegov
źródło
0

QuadR , 82 bajty

(81 bajtów +1 dla flagi)

(\(.)([^[])(.+?)([^\]])(.\))
(\(.)(..?)(.\))
^[^\(].*
\1[\2(\3)\4]\5
\1[\2]\3
(&)

Wypróbuj online!

TwiNight
źródło
0

AWK, 118 bajtów

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

Testowane z gawk, ale powinno działać z każdym zgodnym tłumaczem awk

$ awk -f alternesting.awk <<< 'abc'
(a[b]c)
Dan Andreatta
źródło
0

JavaScript, 101 bajtów

Nie był zwycięzcą, ale interesujące było wypróbowanie tego replacepodejścia. Można to zdecydowanie poprawić, ale szybko wymknęło się spod kontroli ...

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)
jrich
źródło