สตริงภูมิประเทศ


23

นี่คือตัวอย่างอินพุตดังนั้นฉันสามารถอธิบายได้ว่าปัญหาคืออะไร:

((1 2)(3 (4 5) moo)) (i (lik(cherries)e (woohoo)))

คิดว่าบรรทัดของข้อความนี้เป็นแผนที่ภูมิประเทศของภูเขาบางแห่ง วงเล็บแต่ละชุดแสดงความสูงหนึ่งหน่วย

หากเรา "ดู" สิ่งนี้จากด้านข้างเพื่อให้เราเห็นภูเขาในแนวตั้งเราจะเห็น:

          4 5                cherries    woohoo  
  1 2  3       moo       lik          e
                      i

เมื่อกำหนดหนึ่งในแผนที่ภูมิประเทศเหล่านี้ให้ส่งออกแผนที่ แต่ในระดับแนวตั้งเช่นผลลัพธ์ด้านบน แยกรายการต่าง ๆ ในแผนที่ด้วยจำนวนตัวอักษรไปยังรายการถัดไป ตัวอย่างเช่นมี 4 ช่องว่างในการส่งออกระหว่างและmoo iเช่นเดียวกันมี 4 ตัวอักษรในการป้อนข้อมูลระหว่างและmooi

รหัสที่ทำสิ่งนี้ในจำนวนอักขระน้อยที่สุดชนะ


มันปลอดภัยหรือไม่ที่จะสมมติว่าความสูงนั้นจะเป็นค่าบวกเสมอ? ตัวอย่างเช่นการป้อนข้อมูล((1 2))))))))))3ควรไม่ถูกต้องหากความสูงเชิงลบถูกห้าม
Cristian Lupascu

@ w0lf: ใช่วงเล็บจะจับคู่เสมอ
beary605

คำตอบ:


10

J, 87 79 72 70 67 57 56 ตัวอักษร

'( ) 'charsub|.|:(+/\@('('&=-')'&=)(],~' '$~[)"0])1!:1[1

ใช้อินพุตจากคีย์บอร์ด ตัวอย่าง:

   '( ) 'charsub|.|:(+/\@('('&=-')'&=)(],~' '$~[)"0])1!:1[1
((1 2)(3 (4 5) moo)) (i (lik(cherries)e (woohoo)))
          4 5                cherries    woohoo
  1 2  3       moo       lik          e
                      i

คำอธิบาย:

คำอธิบายนี้เป็นไปตามโปรแกรมเวอร์ชันแรกของฉัน:

|.|:('( ) 'charsub x)((' '$~{.@]),[{~{:@])"1(('('&([:+/=)-')'&([:+/=))\,.i.@#)x=.1!:1[1

x=.1!:1[1นำข้อมูลจากคีย์บอร์ดและนำไปใช้ในxภายหลัง

(('('&([:+/=)-')'&([:+/=))\,.i.@#)สร้างรายการของ indeces ทั้งหมดลงใน string ( i.@#) และ stitches ( ,.) พร้อมกับผลลัพธ์ของ(('('&([:+/=)-')'&([:+/=))\คำกริยา

(('('&([:+/=)-')'&([:+/=))\คำกริยานี้ถูกนำไปใช้คำนำหน้าของสตริงทั้งหมด (เพื่อให้การป้อนข้อมูลhelloก็จะนำไปใช้กับh, he, hel, hellและhello. มันเป็นทางแยกซึ่งนับจำนวนของวงเล็บเปิด('('&([:+/=)แล้วหักจำนวนวงเล็บปิด')'&([:+/=). นี้ทำให้ผมรายการ ของ indeces ลงในสายอักขระและระดับอักขระที่ดัชนีนั้นควรอยู่ที่ผลลัพธ์ในการป้อนข้อมูลแบบง่ายนี้ทำให้ฉันมีดังต่อไปนี้:

   (('('&([:+/=)-')'&([:+/=))\,.i.@#)x=.1!:1[1
(one(two(three)))
1  0
1  1
1  2
1  3
2  4
2  5
2  6
2  7
3  8
3  9
3 10
3 11
3 12
3 13
2 14
1 15
0 16

((' '$~{.@]),[{~{:@])"1นี่เป็นคำกริยาที่นำรายการที่ฉันเพิ่งสร้างและเอาท์พุทของ('( ) 'charsub x)(ซึ่งจะทำการแทนที่สตริงเพื่อแทนที่วงเล็บทั้งหมดด้วยช่องว่างในx) มันต้องใช้หางของรายการของรายการแต่ละและใช้มันเป็นดัชนีเป็นสตริงที่จะได้รับตัวละคร{:@] [{~{:@]จากนั้นก็จะนำหน้ามันกับจำนวนของช่องว่างตามที่ระบุโดยหัวของแต่ละรายการในรายการ, (' '$~{.@])จากตัวอย่างก่อนหน้านี้ทำให้ฉัน:

   ('( ) 'charsub x)((' '$~{.@]),[{~{:@])"1(('('&([:+/=)-')'&([:+/=))\,.i.@#)x=.1!:1[1
(one(two(three)))

 o
 n
 e

  t
  w
  o

   t
   h
   r
   e
   e

จากนั้นฉันจะย้ายอาเรย์|:และย้อนกลับ|.เพื่อรับเอาต์พุตที่ต้องการ


6

GolfScript 69

0:§;{.'()'?))3%(.§+:§' ':s*\@s\if\n}%n/.{,}%$)\;:μ;{.,μ\-s*\+}%zip n*

ออนไลน์สาธิตที่นี่

คำอธิบาย:

0:§;                # declare the variable §, representing the 
                    # current vertical level and initialize it at 0

{                   # iterate for each char in the string:

    .'()'?))3% (    # add on the stack the amount by which
                    # the current vertical level should be 
                    # adjusted:
                    #   * +1 if the character is '('
                    #   * -1 if the character is ')'
                    #   * 0 otherwise

    .§+:§           # adjust the value of §

    ' ':s*          # add as many spaces as § tells us
                    # and save the space in variable s

    \@s\if\         # return current char, if it's printable,
                    # or a space if it's '(' or ')'

    n               # add a newline char

}%

n/                  # split by newline char; now we have 
                    # an array of strings on the stack.
                    # Each string is a vertical line of the
                    # final output.

.{,}%$)\;:μ;        # Iterate through the strings and find the
                    # maximum length

{
    .,μ\-s*\+       # Add spaces at the end to make all the strings 
                    # the same length
}%

zip                 # Transpose the strings

n*                  # Join the transposed strings by newline characters

@ Gareth ใช่พวกเราทั้งคู่ทำ :)
Cristian Lupascu

สนใจเพิ่มคำอธิบายวิธีการใช้งานหรือไม่
Timwi

@Timwi ฉันได้แก้ไขคำตอบของฉันเพื่อรวมคำอธิบาย
Cristian Lupascu

5

APL (59)

⊖↑{⊃,/T\¨⍨⍵×P=0}¨R∘=¨(⍴T)∘⍴¨⍳⌈/R←1++\P←+/¨1 ¯1∘ר'()'∘=¨T←⍞

ฉันสันนิษฐานว่า 'ฐาน' จำเป็นต้องใช้งานได้เช่นกัน (เช่น(a(b))c(d)ถูกต้อง) หากไม่จำเป็นสามารถบันทึกสองอักขระได้

คำอธิบาย:

  • T←⍞: เก็บสายอินพุตใน T
  • '()'∘=¨T: สำหรับอักขระแต่ละตัวใน T ดูว่าเป็นวงเล็บเปิดหรือปิด นี่เป็นรายการของบูลีน
  • 1 ¯1∘ר: คูณองค์ประกอบที่สองในแต่ละรายการเหล่านี้ด้วย -1 (ดังนั้นวงเล็บเปิดคือ 1, หนึ่งปิดคือ -1 และอักขระอื่น ๆ คือ 0)
  • +/¨: นำผลรวมของแต่ละรายการภายใน ตอนนี้เรามีค่า ∆y สำหรับตัวละครแต่ละตัว
  • P←: เก็บใน P
  • R←1++\P: ใช้ผลรวม P ที่ให้ความสูงสำหรับตัวละครแต่ละตัว เพิ่มหนึ่งตัวต่ออักขระเพื่อให้อักขระที่อยู่นอกวงเล็บอยู่ในบรรทัดแรก
  • (⍴T)∘⍴¨⍳⌈/R: สำหรับค่า y ที่เป็นไปได้แต่ละรายการให้ทำตราบใดที่ T ซึ่งประกอบด้วยค่านั้นเท่านั้น (เช่น 1111 ... , 2222 .... , ฯลฯ )
  • R∘=¨: สำหรับแต่ละองค์ประกอบในรายการนี้ดูว่ามันเท่ากับ R (สำหรับแต่ละระดับตอนนี้เรามีรายการของศูนย์และคนที่สอดคล้องกับว่าอักขระควรปรากฏในระดับนั้นหรือไม่)
  • ⍵×P=0: สำหรับแต่ละรายการตั้งค่าเป็นศูนย์ถ้า P ไม่เป็นศูนย์ ณ จุดนั้น นี่เป็นการกำจัดอักขระที่ไม่ใช่เดลต้า -y ที่ไม่เป็นศูนย์ดังนั้นมันจึงกำจัดวงเล็บ
  • ⊃,/T\¨⍨: สำหรับแต่ละความลึกให้เลือกจาก T อักขระที่ควรปรากฏ
  • ⊖↑: สร้างเมทริกซ์และวางด้านขวาขึ้น

คุณกำลังใช้การใช้ APL ใด ฟรีหรือเปล่า
FUZxxl

@FUZxxl ฉันใช้ Dyalog APL แล้วเวอร์ชั่น Windows สามารถดาวน์โหลดได้ฟรี
marinus

5

Tcl, 50

puts \33\[9A[string map {( \33\[A ) \33\[B} $argv]

ชนิดของการโกง แต่ก็ดี ..

ฉันใช้ ascii escape sequences เพื่อให้ได้ความแตกต่างของบรรทัด^[[Aหมายถึงย้ายเคอร์เซอร์ 1 บรรทัดขึ้นไป^[[Bคือย้ายเคอร์เซอร์ 1 บรรทัดลง


5

APL, 41 ตัวอักษร / ไบต์ *

{⊖⍉⊃(↑∘''¨-⌿+/¨p∘.=,\⍵),¨⍵/⍨1-2×⍵∊p←'()'}

ทดสอบกับ Dyalog ด้วยสภาพแวดล้อม⎕IO←1และ ⎕ML←3มันเป็นฟังก์ชั่นที่รับอินพุตที่ต้องการและส่งคืนเอาต์พุต ด้วยถ้อยคำของคำถามฉันเชื่อว่ามันเป็นที่ยอมรับ ในกรณีที่ไม่ใช่นี่คือรุ่นที่อ่านจาก stdin และเขียนไปยัง stdout สำหรับ 4 chars more:

⍞←⊖⍉⊃(↑∘''¨-⌿+/¨'()'∘.=,\a),¨a/⍨1-2×'()'∊⍨a←⍞

คำอธิบาย :

{                                 p←'()'}  p is the string made of two parentheses
                                ⍵∊ ______  check which characters from ⍵ are parens
                            1-2× ________  -1 for every par., 1 for every other char
                         ⍵/⍨ ____________  replace () with spaces in the orig. string
    (                 ),¨ _______________  append every char to the following items
                   ,\⍵ _____________________  for every prefix of the original string
               p∘.= ________________________  check which chars are '(' and which ')'
            +/¨ ____________________________  sum: compute the number of '(' and ')'
          -⌿ _______________________________  subtract the no. of ')' from that of '('
     ↑∘''¨ _________________________________  generate as many spaces as that number
 ⊖⍉⊃ ____________________________________  make it into a table, transpose and flip

ตัวอย่าง:

topo '((1 2)(3 (4 5) moo)) (i (lik(cherries)e (woohoo)))'
          4 5                cherries    woohoo   
  1 2  3       moo       lik          e           
                      i                           

 

topo 'a  (  b ( c(d)e ) f  )  g'
            d            
          c   e          
      b           f      
a                       g

*: APL สามารถบันทึกในชุดอักขระไบต์เดียวแบบดั้งเดิมที่จับคู่สัญลักษณ์ APL กับ 128 ไบต์ด้านบน ดังนั้นเพื่อจุดประสงค์ในการเล่นกอล์ฟโปรแกรมที่ใช้อักขระ ASCII และสัญลักษณ์ APL เท่านั้นจึงจะได้คะแนนเป็น chars = bytes


ฉันค้นหาชุดอักขระ APL ที่นี่และฉันไม่พบสัญลักษณ์ ดูเหมือนว่าการรวมกันของ¨และ~ตัวละคร?
Gareth

สวัสดี @Gareth ไม่มันไม่ได้อยู่ใน IBM APL2 คุณสามารถค้นหาได้ในDyalog (ในเชิงพาณิชย์ แต่มีรุ่น nagware ฝังอยู่ในเว็บไซต์ของพวกเขาและที่ดีพอสำหรับการเล่นกอล์ฟ; IMHO APL ที่ดีที่สุดที่มีอยู่ในปัจจุบัน) Nars2000 (ที่ดีที่สุด APL เปิดแหล่งที่มา) GNU APLและAPL NGN ของหมู่ คนอื่น ๆ
Tobia

@Gareth แบบกราฟิกเป็นการรวมกันของ~และ¨ถึงแม้ว่ามันจะเป็นตัวละครที่แตกต่างจากทั้งคู่ มันเป็นผู้ประกอบการที่เรียกว่าการเดินทาง ในรูปแบบ dyadic มันพลิกข้อโต้แย้งของฟังก์ชัน dyadic ที่ใช้กับ: (5-2)=(2-⍨5). ในฐานะผู้ประกอบการ monadic มันจะเปลี่ยนฟังก์ชั่น dyadic เป็น monadic โดยทำซ้ำอาร์กิวเมนต์ที่ถูกต้อง: (2*2)=(*⍨2). ส่วนใหญ่จะใช้เพื่อเขียนฟังก์ชั่นสตรีมอย่างต่อเนื่องจากขวาไปซ้ายโดยไม่ต้องใส่เครื่องหมายวงเล็บในการแสดงออกขนาดใหญ่และกระโดดดวงตาของคุณไปรอบ ๆ พวกเขา ในการเล่นกอล์ฟมันมีประโยชน์เพราะ3*⍨1-2มีถ่านน้อยกว่า(1-2)*3:-)
Tobia

2
ดังนั้นมันจึงเทียบเท่ากับ~ใน J แล้ว
Gareth

3

J, 56 ตัวอักษร

'( ) 'charsub|.|:((,~#&' ')"0[:+/\1 _1 0{~'()'&i.)1!:1]1

อีก 56 ตัวอักษร J แก้ปัญหา ... ฉันนับลึกโดยการแปล(ลงใน⁻1, )แบ่งออกเป็น 1 และตัวละครอื่น ๆ ทั้งหมดลงใน 0 [: +/\ 1 _1 0 {~ '()'&i.แล้วการรวมการทำงานของนี้: ส่วนที่เหลือคล้ายกับโซลูชันของ @ Gareth


2

Python 161 ตัวอักษร

S=raw_input()
R=range(len(S))
H=[S[:i].count('(')-S[:i].count(')')for i in R]+[0]
for h in range(max(H),0,-1):print''.join((' '+S[i])[H[i]==H[i+1]==h]for i in R)

2

Python, 130

a=[""]*9
l=8
i=0
for c in raw_input():o=l;l+=c==')';l-=c=='(';a[l]=a[l].ljust(i)+c*(o==l);i+=1
print"\n".join(filter(str.strip,a))

2

ทับทิม 1.9 (129)

อ่านจาก stdin

l=0
$><<gets.split('').map{|c|x=[?(]*99;x[l+=c==?(?-1:c==?)?1:0]=c;x}.transpose.map(&:join).*(?\n).tr('()',' ').gsub(/^\s+\n/,'')

3
ดี! คุณค้นพบข้อบกพร่องใน
ปากกา

ฉันทดสอบแล้วและการไฮไลต์ SQL ทำงานได้ดีขึ้นสำหรับโปรแกรมของคุณ
Cristian Lupascu

@ w0lf ฮ่าคุณพูดถูก ฉันเปลี่ยนวิธี//การ''ที่ทำให้ตัวละครนับเหมือนกันและหลีกเลี่ยงข้อผิดพลาดในปากกาเน้นข้อความ
Paul Prestidge

2

C, 132 ตัวอักษร

char*p,b[999];n;
main(m){for(p=gets(memset(b,32,999));*p;++p)*p-41?*p-40?p[n*99]=*p:++n>m?m=n:0:--n;
for(;m;puts(b+m--*99))p[m*99]=0;}

คำอธิบายล้มเหลวในการระบุว่าต้องยอมรับการป้อนข้อมูลจำนวนเท่าใดเพื่อที่จะยอมรับดังนั้นฉันจึงตัดสินด้วยข้อ จำกัด ที่สอดคล้องกับความต้องการกอล์ฟของฉันมากที่สุด (ในขณะที่ยังคงทำงานกับอินพุตตัวอย่างที่กำหนด) ให้ฉันได้ใช้โอกาสนี้เพื่อเตือนผู้คนว่าบ่อยครั้งที่มันเป็นความคิดที่ดีที่จะระบุจำนวนสูงสุดต่ำสุดในคำอธิบายการท้าทายของคุณ

มีสองลูปหลักในรหัส ลูปแรกจะแสดงอักขระที่ไม่ใช่วงเล็บทั้งหมดไปยังบรรทัดเอาต์พุตที่เหมาะสมและลูปที่สองจะพิมพ์แต่ละบรรทัด


1

C, 149 ตัวอักษร

#define S for(i=0;c=v[1][i++];)h+=a=c-'('?c-')'?0:-1:1,
c,i,h=0,m=0;main(int a,char**v){S m=h>m?h:m;for(;m;m--){S putchar(a||h-m?32:c);putchar(10);}}

วิ่งด้วยอ้าง ARG, egaout "((1 2) (3 (4 5) หมู่)) (i (lik (เชอร์รี่)) e (woohoo))"


0

อ็อกเทฟ 128

คล้ายกับคำตอบสุดท้ายของฉัน ...

p=1;x=[0];y=input(0);for j=1:numel(y);p-=(y(j)==")");x(p,j)=y(j);p+=(y(j)=="(");end;x(x==40)=x(x==41)=x(x==0)=32;char(flipud(x))

ทดสอบ

การป้อนข้อมูล: "((1 2)(3 (4 5) moo)) (i (lik(cherries)e (woohoo)))"

เอาท์พุท:

          4 5 เชอร์รี่วู่ว   
  1 2 3 หมู่ชอบ e           
                      ผม                           

0

C #, 229 ไบต์

หากไม่มีข้อ จำกัด เกี่ยวกับพื้นที่แนวตั้งนำหน้าคุณสามารถใช้สิ่งนี้ (เยื้องเพื่อความชัดเจน) มันจะเริ่มต้นเคอร์เซอร์ลงหนึ่งบรรทัดสำหรับทุก ๆ ที่(พบก่อนพิมพ์จากนั้นเลื่อนเคอร์เซอร์ขึ้นและลงเมื่ออ่านเครื่องหมายวงเล็บ

using C=System.Console;
class P{
    static void Main(string[]a){
        int l=a[0].Length,i=l;
        while(i>0)
            if(a[0][--i]=='(')C.CursorTop++;
        while(++i<l){
            char c=a[0][i];
            if(c=='('){
                c=' ';
                C.CursorTop--;
            }
            if(c==')'){
                c=' ';
                C.CursorTop++;
            }
            C.Write(c);
        }
    }
}

0

PowerShell , 120 119 ไบต์

(($h=($c=$args|% t*y)|%{($l+=(1,-1)[$_-40])})|sort)[-1]..0|%{$x=0;$y=$_
-join($c|%{"$_ "[$h[$x++]-ne$y-or$_-in40,41]})}

ลองออนไลน์!

ผลข้างเคียง: ตัวอักษร&และ'การเปลี่ยนแปลงความสูงเป็น(และ)แต่แสดง เปรียบเทียบผลลัพธ์สำหรับ:

&$f "((1 2)(3 (4 5) moo)) (i (lik(cherries)e (woohoo)))"
&$f "&&1 2'&3 &4 5' moo'' &i &lik&cherries'e &woohoo'''"

หักกอล์ฟ:

$chars=$args|% toCharArray

$heights=$chars|%{
    $level+=(1,-1)[$_-40]       # 40 is ASCII for '(', 41 is ASCII for ')'
    $level
}

$maxHeight=($heights|sort)[-1]

$maxHeight..0|%{
    $x=0;$y=$_
    $line=$chars|%{
        "$_ "[$heights[$x++]-ne$y -or $_-in40,41]
    }
    -join($line)
}

-1

VB.net (สำหรับ S&G)

ไม่ใช่รหัสที่สวยที่สุด

Module Q
 Sub Main(a As String())
  Dim t = a(0)
  Dim h = 0
  For Each m In (From G In (t.Select(Function(c)
                                     h += If(c = "(", 1, If(c = ")", -1, 0))
                                     Return h
                                   End Function).Select(Function(y, i) New With {.y = y, .i = i}))
             Group By G.y Into Group
             Order By   y Descending
            Select Group.ToDictionary(Function(x) x.i)
               ).Select(Function(d) New String(
                          t.Select(Function(c,i)If(d.ContainsKey(i),If(c="("c Or c=")"c," "c,c)," "c)).ToArray))
   Console.WriteLine(m)
  Next
 End Sub
End Module
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.