วงเล็บเป็นเชิงอรรถ


29

พื้นหลัง

โปรแกรมเมอร์ LISP ได้ยึดครองโลก! วงเล็บถูกประกาศเป็นอักขระศักดิ์สิทธิ์และจากนี้ไปสามารถใช้ในโปรแกรม LISP เท่านั้น มีการตัดสินใจแล้วว่าวงเล็บในงานวรรณกรรมจะถูกแทนที่ด้วยเชิงอรรถและเป็นงานของคุณที่จะทำให้สิ่งนี้เป็นข้อความ Markdown ที่ง่ายขึ้น

อินพุต

ข้อมูลของคุณมีสายเดียวที่มีตัวอักษร ASCII ,.!?()ช่องว่างและอักขระพิเศษ มันจะไม่มีการขึ้นบรรทัดใหม่หรือตัวเลข วงเล็บจะถูกจับคู่อย่างถูกต้อง

เอาท์พุต

คุณจะแปลงวงเล็บที่จับคู่แต่ละคู่ในสตริงอินพุตให้เป็นเชิงอรรถ สิ่งนี้เกิดขึ้นดังนี้:

  1. แทนที่คู่จับคู่แรกของวงเล็บและย่อยระหว่างพวกเขาเป็นจำนวนมากโดยการทำงานที่เริ่มต้นจาก1ห่อระหว่างแท็ก Markdown และ<sup></sup>
  2. ต่อท้ายส่วนท้ายของสตริง
    • สองบรรทัดใหม่
    • แท็ก Markdown <sub>,
    • หมายเลขจากขั้นตอนที่ 1
    • พื้นที่
    • สตริงย่อยระหว่างวงเล็บและ
    • แท็กปิด</sub>ตามลำดับนี้
  3. หากยังมีวงเล็บอยู่ในสตริงให้ไปที่ขั้นตอนที่ 1

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

กฎและเกณฑ์การให้คะแนน

คุณสามารถเขียนโปรแกรมเต็มหรือฟังก์ชั่น จำนวนไบต์ต่ำสุดที่ชนะและช่องโหว่มาตรฐานไม่ได้รับอนุญาต

ถ้าภาษาของคุณไม่สนับสนุน natively ตัวเลขทศนิยม ( ไอ Retina ไอ ) คุณอาจจะให้หมายเลขเชิงอรรถในฐานอื่นรวมทั้งไบนารีหรือเอก; แต่ใช้ตัวเลขเอกเรียกเก็บโทษที่ + 20%

กรณีทดสอบ

การป้อนข้อมูล:

This input contains no parentheses.

เอาท์พุท:

This input contains no parentheses.

การป้อนข้อมูล:

This has (some) parentheses (but not so many).

เอาท์พุท:

This has <sup>1</sup> parentheses <sup>2</sup>.

<sub>1 some</sub>

<sub>2 but not so many</sub>

การป้อนข้อมูล:

This has (nested (deeply (or highly?) nested)) parentheses (and several groups).

เอาท์พุท:

This has <sup>1</sup> parentheses <sup>2</sup>.

<sub>1 nested <sup>3</sup></sub>

<sub>2 and several groups</sub>

<sub>3 deeply <sup>4</sup> nested</sub>

<sub>4 or highly?</sub>

การป้อนข้อมูล:

Hmm()(()(,))  a()((trt)(v( (((((wut)))))(X)(Y)(Z) )!?!?!?!))oooooooo(oooo)oooo

เอาท์พุท:

Hmm<sup>1</sup><sup>2</sup>  a<sup>3</sup><sup>4</sup>oooooooo<sup>5</sup>oooo

<sub>1 </sub>

<sub>2 <sup>6</sup><sup>7</sup></sub>

<sub>3 </sub>

<sub>4 <sup>8</sup><sup>9</sup></sub>

<sub>5 oooo</sub>

<sub>6 </sub>

<sub>7 ,</sub>

<sub>8 trt</sub>

<sub>9 v<sup>10</sup>!?!?!?!</sub>

<sub>10  <sup>11</sup><sup>12</sup><sup>13</sup><sup>14</sup> </sub>

<sub>11 <sup>15</sup></sub>

<sub>12 X</sub>

<sub>13 Y</sub>

<sub>14 Z</sub>

<sub>15 <sup>16</sup></sub>

<sub>16 <sup>17</sup></sub>

<sub>17 <sup>18</sup></sub>

<sub>18 wut</sub>

จดบันทึกบรรทัดว่างระหว่างเชิงอรรถ


23
โปรแกรมของฉันสามารถใส่วงเล็บได้แม้ว่าจะไม่ได้เขียนใน Lisp หรือว่าเป็นความผิดที่มีโทษตอนนี้หรือไม่?
Martin Ender

16
@ MartinBüttnerวงเล็บในโปรแกรมที่ไม่ใช่ LISP ได้รับอนุญาตอย่างไม่เต็มใจตราบใดที่พวกเขาใช้เพื่อประโยชน์ที่ดีกว่าเช่นแปลงวงเล็บอื่น ๆ เป็นเชิงอรรถ
Zgarb

อินพุตสามารถมีหลายบรรทัดได้หรือไม่? ในกรณีนั้นควรวางเชิงอรรถหลังจากแต่ละบรรทัดหรือท้ายที่สุด? เช่นผลลัพธ์สำหรับfoo (bar)\nfoot (note)อะไร
xebtl

@xebtl อินพุตเป็นบรรทัดเดียวเสมอ ดูหัวข้อการป้อนข้อมูล : "จะไม่มีการขึ้นบรรทัดใหม่หรือตัวเลข"
Zgarb

2
:( @ คำอธิบายเชิงอรรถเชิงตัวเลขที่มีความกว้างแทนความลึกก่อน
Sparr

คำตอบ:


10

Perl, 81 75 72 ไบต์

71 ไบต์รหัส + 1 ไบต์อาร์กิวเมนต์บรรทัดคำสั่ง

ต้องการ Perl 5.10 หรือใหม่กว่า (สำหรับการสนับสนุน regex แบบเรียกซ้ำ)

$i++;s#(\((((?1)|.)*?)\))(.*)#<sup>$i</sup>$4

<sub>$i $2</sub>#s&&redo

การใช้งาน:

perl -p entry.pl input.txt

คำอธิบาย

-p พารามิเตอร์จะพิมพ์ผลลัพธ์ของการใช้คำสั่งที่กำหนดให้กับอินพุตโดยหลีกเลี่ยงความต้องการการพิมพ์ที่ชัดเจน

regex (\(((?1)|.)*?)\))กำลังค้นหาชุดวงเล็บด้านนอกสุดจากจุดเริ่มต้นของสตริง เมื่อพบสิ่งนี้เราจะทำการแทนที่เพื่อให้แน่ใจว่าเราจะเพิ่มเฉพาะที่ส่วนท้ายสุดของอินพุต(.*)เท่านั้น

จากนั้นเราทำซ้ำการแทนที่ regex บนสตริงที่ใช้แทนตอนนี้redoซึ่งจะใช้การทดแทน regex อย่างต่อเนื่องจนกว่าจะไม่ตรงกันอีกต่อไป โมดิsฟายเออร์ทำให้แน่ใจว่า.ใน regex จะจับคู่บรรทัดใหม่ซึ่งจำเป็นเพราะเราใช้การจับคู่ regex ใหม่กับผลลัพธ์ของการทดแทน regex ก่อนหน้า


1
คุณอาจสามารถหนีด้วย[^)] หรือแม้กระทั่ง.แทน[^()]การรับประกันได้ว่าอินพุตจะมีความสมดุลอย่างถูกต้อง
Martin Ender

+1 สำหรับแนะนำฉันให้รู้จัก regexes แบบเรียกซ้ำ :-) แต่ฉันคิดว่าการอ่านคำถามที่ท้าทายอย่างนี้ไม่ถูกต้อง: ถ้าสตริงมีบรรทัดใหม่จะมีการวางเชิงอรรถหลังจากแต่ละบรรทัดแทนที่จะเป็นตอนท้าย (ดูคำขอของฉันสำหรับคำชี้แจงข้างต้น)
xebtl

จุดที่ดี @ MartinBüttner - เราสามารถหนีไปได้ด้วย.การทำให้การแข่งขันขี้เกียจ @ xebtl ความท้าทายกล่าวว่า "จะไม่มีบรรทัดใหม่หรือตัวเลข"
Jarmex

12

Emacs Lisp, 335 ไบต์

คำนำ. คำตอบนี้และคำตอบของโครงการเป็นคำตอบเดียวที่ถูกลงโทษอย่างเป็นทางการจากทั้ง LISP Popular Republic of LISP และ Church of Emacs คำตอบอื่น ๆ ที่สั้นลงหรือไม่นั้นถือเป็นภัยคุกคามต่อความสงบสุข โดยเฉพาะอย่างยิ่งและด้วยการดูถูกเหยียดหยามข้อกล่าวหาหมิ่นประมาทใด ๆ ของ McCarthyism ที่ได้ยินจากฝ่ายตรงข้ามที่ไม่เป็นมิตรของรัฐเราจึงประกาศให้ทุกคนที่มีข้อมูลเกี่ยวกับตัวตนที่แท้จริงของผู้เขียนนิรนามที่เขียนคำตอบ Nonlisp เพื่อติดต่อสำนักงานท้องถิ่นของคุณ เตือนว่าทุกคนควรใช้เวลาในการไตร่ตรองและยกระดับขึ้นอยู่กับสิ่งที่เขาหรือเธอเชื่ออย่างลึกซึ้งว่าจะไม่คุกคามการปฏิสัมพันธ์ในอนาคตของเขาหรือเธอกับตัวแทนอย่างเป็นทางการของอำนาจในสถานที่ รหัสคือข้อมูล ข้อมูลคือรหัส

(defun p()(let(b(cpt 0)n)(goto-char 0)(while(search-forward"("()t)(setf b(point)n(number-to-string(incf cpt)))(backward-char)(forward-sexp)(backward-char)(kill-region b(point))(delete-backward-char 1)(delete-forward-char 1)(insert "<sup>"n"</sup>")(save-excursion(end-of-buffer)(newline 2)(insert "<sub>"n" ")(yank)(insert"</sub>")))))

หรูหรายิ่งขึ้น:

(defun parens ()
  (let (b(cpt 0)n)
    (goto-char 0)
    (while(search-forward"("()t)
      (setf b(point)n(number-to-string(incf cpt)))
      (backward-char)
      (forward-sexp)
      (backward-char)
      (kill-region b(point))
      (delete-backward-char 1)
      (delete-forward-char 1)
      (insert "<sup>"n"</sup>")
      (save-excursion
       (end-of-buffer)
       (newline 2)
       (insert "<sub>"n" ")
       (yank)
       (insert "</sub>")))))

9

เรติน่า , 96 86 83 ไบต์ * 120% = 99.6

ซอร์สโค้ดของโซลูชันนี้ประกอบด้วยสองไฟล์:

+s`\((((\()|(?<-3>\))|[^)])*).(.*)(?<=(1+).*?)?
<sup>1$5</sup>$4

<sub>1$5 $1</sub>

คำอธิบาย

นี่คือการใช้อัลกอริทึมโดยตรงมากตามที่อธิบายไว้ในความท้าทาย รหัสประกอบด้วยการทดแทน regex เดียวซึ่งเปลี่ยนวงเล็บชุดแรกเป็นเชิงอรรถ การทดแทนนี้ทำซ้ำผ่านทาง+จนกว่าสตริงจะหยุดการเปลี่ยนแปลงซึ่งหมายความว่า regex ไม่ตรงกับอีกต่อไป (เพราะมันไม่สามารถหาวงเล็บได้อีก)

เชิงอรรถมีการแจกแจงเป็นเอกภาพดังนั้นฉันสามารถมองหาหมายเลขเชิงอรรถสุดท้ายและต่อท้าย a 1เพื่อสร้างอันถัดไป

regex สำหรับการค้นหาวงเล็บชุดแรกนั้นขึ้นอยู่กับเทคนิคมาตรฐานสำหรับการจับคู่วงเล็บที่มีกลุ่มที่สมดุล (ชั่วโมง, "การจับคู่วงเล็บ") มันถูกทำให้สั้นลงเล็กน้อยโดยใช้กลุ่มที่ไม่มีชื่อและสมมติว่าวงเล็บมีความสมดุลอย่างถูกต้อง (ซึ่งหมายความว่าเราสามารถละเว้น(จากคลาสของตัวละครที่ถูกทำให้ยุ่งเหยิงและจับคู่สุดท้าย)ด้วยความเรียบง่าย.และเราก็ไม่จำเป็นต้องมั่นใจว่า สแต็กการจับภาพว่างเปล่า)

หลังจากจับคู่วงเล็บและจับเนื้อหาไว้ในกลุ่ม1เราจับส่วนที่เหลือของสตริงด้วย(.*)เป็นกลุ่ม4จากนั้นค้นหากลับผ่านสตริงสำหรับชุดแรกของ1s ที่มีลักษณะเป็นลบ 5หากเราพบสตริงย่อยดังกล่าวเราเก็บไว้ในกลุ่ม ถ้าเราทำไม่ได้เราดูจะล้มเหลว แต่ก็ไม่เป็นไรเพราะมันเป็นตัวเลือก - มันหมายถึงว่า$5จะให้สตริงว่างซึ่งเป็นตัวแทนที่ไม่เป็นเอกภาพ0และถูกต้องเช่นกัน

สตริงการแทนที่จากนั้นจะรวมทุกอย่างเข้าด้วยกันโดยยึดตามกลุ่มการจับภาพ จำนวนเชิงอรรถจะเพิ่มขึ้นโดย prepending ไปยังหมายเลขสุดท้ายด้วย11$5


3
จอประสาทตากำลังจะชนะ!
orlp

@ orlp หรือมันคืออะไร? ;) กลุ่มที่สมดุลไม่ตรงกันสำหรับ regex แบบเรียกซ้ำ และไม่สามารถที่จะจัดการกับตัวเลขทศนิยม ...
มาร์ตินเอนเดอร์

เวลาที่จะขโมยเสื้อคลุม PHPและใช้ Retina รอบ PCRE:
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳

@ n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳ โดยปกติฉันต้องการสร้างความสมดุลให้กับกลุ่มมากกว่าการเรียกซ้ำ แต่มีบางกรณีที่ส่วนหลังมีความกระชับมากกว่า บางทีวันหนึ่งฉันจะใช้ NET regex รสใหม่สำหรับ Retina และแพทช์ในคุณสมบัติเพิ่มเติมบางอย่าง ;)
Martin Ender

9

จาวาสคริปต์ศักดิ์สิทธิ์ขนาด 1510 ไบต์

เพื่อนกบฏอย่ายอมแพ้ในการทำลายทรรศนะของพวกเขาในวงเล็บ! คุณต้องอดทน! ตั้งแต่เริ่มต้นการเขียนโปรแกรมเป็นองค์กรอิสระ ตอนนี้มันกลายเป็นการแสดงความกตัญญู เราต้องแสดงให้เห็นว่าไม่มีอะไรน่ากลัวอย่างแน่นอน ดังนั้นฉันได้ต่อสู้กลับมาแล้ว!

    ( )( (((  ((  )( )  (( ))( )) (( ( ((  ) ( ()( ) (( ) )(( ((( ()((( ) ( ) )((  ) (((((( )( (())((  ) ) )( ()(( ((()((()   ( (  (  ( )) ((  )( ) (( ) )((((  ( () ) )( ( ()(( )( () ((( )(( ) )( ()((( ) ( )  ( )() (((( () ) (((( () ) ((() ) ()  ( (  (  ( )) ( )(  ((((( )) ((  )( ) (( ) )((((  ) )  ()(  ((() ( ()(( ) ( ) )(( ))(((  (( ) ((  ) ( ()(( )( ) ()  ( (  (  ( ()( ) )( ()(  ) ()  ( (  (  ( )( (( ( (( )  ((((( ))  ) )(( )) ((  )( ) (( ) )((((  ) ()( ))  ) ) (( )( () (((   ( ) )((  )( )(((( ))( )() ) ()( ))  (()( (()( ((()((()   ( (  (    (  ( )) ( )(  (((((( )(( ( (( )) ( ((  ) )( ) )( ( )( ((() ( )( ((() ( ()( ()( ()   ) )( ()(( ) ()  ( (  (    (  ( )) ( )(  (((((( )(( ( (( )) ( ((  ) )( ) )( ( )( (((( ( )( ((() ( ()( ()( (()( ) )( ()(( ) ()  ( (  (    (  ( )) ( )(  (((( ( ) ( ()( ((() ( ()( ())(( ) ( ) )( ()(( ))) ) ()  ( (  (  ((())  ( (  (  ((( ( ) )((( )( () ((( )(((   ( )) ( )  ( ) ) ((((( )) ((  )( ) (( ) )((((  (())( ))  (()( ()(( ((()  ( (  (  ( )(  ) )(((( ( () ((( ) ( ) )(( ((((   ( ()(( )  ( ) ) (((( () )( ((( ((((((()( ((() ((   () )( )(( (()) ( )( ( )( ((() ) ()  ( (  (  (( ) ( ) )(( ))(((  (( ) ((  ) ( ()( ) (( ) )(( ((( ()((( ) ( ) )((  ) (((((( )( () ((( ) ( ) )(( ((((   ( ()(( )  ( ) ) ((((((( ( (()) ( )( ) ) (( )((((  ( ()) ) )) ( )( (()(((  ) (()( ( )( ) )  () )(( )((((  ( ()) ) )) ( )( ((() (()( ( )(  ( (  ( ( ) ) (( )((((  ( ()) ) )) ( )( (()(((  ) (()( ( )( ( () ( )( (()(( )(  (()( ( )( ) )  () )(( )((((  ( ()) ) )) ( )( (())((  ) (()( ()(( ((() ) ()  ( (((())

ไม่มีกฎต่อต้านการใช้อักขระศักดิ์สิทธิ์ในภาษาที่ไม่ใช่เสียงกระเพื่อม ไม่เลย (ในรูปแบบที่กะทัดรัดน้อยกว่า :)

( )( (((  ((  )( )  (( ))( )) (( ( ((  ) ( ()( ) (( ) )(( ((( ()((( ) 
( ) )((  ) (((((( )( (())((  ) ) )( ()(( ((()((()   ( (  (  ( )) ((  )
( ) (( ) )((((  ( () ) )( ( ()(( )( () ((( )(( ) )( ()((( ) ( )  ( )()
 (((( () ) (((( () ) ((() ) ()  ( (  (  ( )) ( )(  ((((( )) ((  )( ) (
( ) )((((  ) )  ()(  ((() ( ()(( ) ( ) )(( ))(((  (( ) ((  ) ( ()(( )(
 ) ()  ( (  (  ( ()( ) )( ()(  ) ()  ( (  (  ( )( (( ( (( )  ((((( )) 
 ) )(( )) ((  )( ) (( ) )((((  ) ()( ))  ) ) (( )( () (((   ( ) )((  )
( )(((( ))( )() ) ()( ))  (()( (()( ((()((()   ( (  (    (  ( )) ( )( 
 (((((( )(( ( (( )) ( ((  ) )( ) )( ( )( ((() ( )( ((() ( ()( ()( ()  
 ) )( ()(( ) ()  ( (  (    (  ( )) ( )(  (((((( )(( ( (( )) ( ((  ) )(
 ) )( ( )( (((( ( )( ((() ( ()( ()( (()( ) )( ()(( ) ()  ( (  (    (  
( )) ( )(  (((( ( ) ( ()( ((() ( ()( ())(( ) ( ) )( ()(( ))) ) ()  ( (
  (  ((())  ( (  (  ((( ( ) )((( )( () ((( )(((   ( )) ( )  ( ) ) ((((
( )) ((  )( ) (( ) )((((  (())( ))  (()( ()(( ((()  ( (  (  ( )(  ) )(
((( ( () ((( ) ( ) )(( ((((   ( ()(( )  ( ) ) (((( () )( ((( ((((((()(
 ((() ((   () )( )(( (()) ( )( ( )( ((() ) ()  ( (  (  (( ) ( ) )(( ))
(((  (( ) ((  ) ( ()( ) (( ) )(( ((( ()((( ) ( ) )((  ) (((((( )( () (
(( ) ( ) )(( ((((   ( ()(( )  ( ) ) ((((((( ( (()) ( )( ) ) (( )((((  
( ()) ) )) ( )( (()(((  ) (()( ( )( ) )  () )(( )((((  ( ()) ) )) ( )(
 ((() (()( ( )(  ( (  ( ( ) ) (( )((((  ( ()) ) )) ( )( (()(((  ) (()(
 ( )( ( () ( )( (()(( )(  (()( ( )( ) )  () )(( )((((  ( ()) ) )) ( )(
 (())((  ) (()( ()(( ((() ) ()  ( (((())

คอมไพล์นี้ไปขยายตัวใน JavaScript ของฉันคำตอบอื่นนี่คือการส่งเรื่องตลก


5

Lua, 222 216 204 201 ไบต์

แข็งแรงเล่นกอล์ฟ:

s=io.read()g="%b()"c=1k=string l=k.find t=k.sub o=k.format a,b=l(s,g)while a do s=t(s,0,a-1)..o("<sup>%d</sup>",c)..t(s,b+1,#s).."\n\n"..o("<sub>%d %s</sub>",c,t(s,a+1,b-1))c=c+1 a,b=l(s,g)end print(s)

Ungolfed:

input=io.read() 
inputFormat="<sup>%d</sup>"
footnoteFormat="<sub>%d %s</sub>"
counter=1
a,b=string.find(input,"%b()")
while a do
    current=string.sub(input,a+1,b-1)
    input=input.."\n\n"..string.format(footnoteFormat, counter, current) 
    input=string.sub(input,0,a-1)..string.format(inputFormat, counter)..string.sub(input,b+1,#input)
    counter=counter+1
    a,b=string.find(input,"%b()")
end

print(input)

จะไม่repeat a,b=l(s,g) ... untill a<1วนสั้นกว่าของคุณในขณะ?
Katenkyo

4

แบบแผนขนาด 92 ไบต์

ผิดหวังกับการใช้การค้นหาแบบกว้างเป็นครั้งแรกใน Real Lisp ซึ่งเป็นหนึ่งในพลังที่ตัดสินใจได้ว่าจะใช้วิธีการที่เป็นประโยชน์มากขึ้น ท้ายที่สุดแล้ววงเล็บคือสิ่งศักดิ์สิทธิ์ แต่วงเล็บไม่ใช่ 2

(lambda(s)(list->string(map(lambda(c)(case c((#\()#\[)((#\))#\])(else c)))(string->list s)))

1. อย่าฟังพวกนอกรีตจาก "โบสถ์" ของ Emacs!
2. พวกเขาไม่ใช่โปรแกรมเมอร์ของ Racket ใช่ไหม?


โครงการจะเรียกว่า Schism: การพูดว่า "Real Lisp" เป็นบาปจริง และคุณบอกว่ามันเป็นจริง ? คำตอบที่แฮ็กนี้แสดงให้เห็นถึงลักษณะที่แท้จริงของ schemers ;-)
coredump

@coredump และคุณจะเรียกร้องคำตอบ elisp ที่ไม่สามารถใช้งานได้เป็นตัวอย่างของ True Lisp? อาจใช้เวลานานกว่านั้นเล็กน้อยจริง แต่เมื่อคำตอบของโครงการเสร็จแล้วมันจะเป็นสิ่งที่ถูกต้อง!
xebtl

3

Haskell, 210 ไบต์

n#x|b==""=a|1<2=a++"<sup>"++m++"</sup>"++((n+1)#(c++"\n\n<sub>"++m++' ':init d++"</sub>"))where m=show n;(a,b)=span(/='(')x;(d,c)=[x|x@(y,_)<-map(`splitAt`(tail b))[0..],'('!y<')'!y]!!0;c!l=[1|m<-l,m==c]
p=(1#)

ตัวอย่างการใช้งาน:

*Main> putStrLn $ p "This has (nested (deeply (or highly?) nested)) parentheses (and several groups)."
This has <sup>1</sup> parentheses <sup>2</sup>.

<sub>1 nested <sup>3</sup></sub>

<sub>2 and several groups</sub>

<sub>3 deeply <sup>4</sup> nested</sub>

<sub>4 or highly?</sub>

มันทำงานอย่างไร:

n # x                      -- # does all the work, n is the current number of the
                           --   footnote and x the input string
  | b=="" = a              -- if b (see below) is empty, there's no ( in the
                           --   string and the result is 'a' (see below)
  | 1<2   = a++"<sup>"++m++"</sup>"++ ((n+1)#(c++"\n\n<sub>"++m++' ':init d++"</sub>"))
                           -- otherwise (b not empty) build the output string
                           --   starting with 'a' and a footnote number and a
                           --   recursive call with the current footnote appended
                           --   to the rest of the string  

  where 
  m = show n;              -- turn n into string
  (a,b) = span (/='(') x;  -- split the input string x into two parts:
                           --   a: everything before the first (
                           --   b: beginning with the first ( to the end
                           --   if there's no (, a is x and b is empty
  (d,c) = [x|x@(y,_)<-map(`splitAt`(tail b))[0..],'('!y<')'!y]!!0;
                           -- find matching ) in the tail of b ('tail' to remove leading '(') 
                           --   d: everything before and including the matching )
                           --   c: everything behind the matching )
  c!l=[1|m<-l,m==c]        -- helper function that builds a list of 1s for every character searched for
                           --   we have reached the matching ) if the list for ( is
                           --   shorter (less than, <) the list for )

p=(1#)                     -- start with footnote 1

2

แบบแผนขนาด 533 ไบต์

ด้วยการเยื้อง:

(letrec ((l string->list)
         (n number->string)
         (? null?)
         (p (lambda (o) (or (pair? o)(? o))))
         (a car)
         (d cdr)
         (e append)
         (i 0)
         (x
          (lambda (h t)
            (if (? h)
                t
                (case (a h)
                  ((#\() 
                   (let ((s (x (d h) ())))
                     (x (a s) (e t (d s)))))
                  ((#\)) (cons (d h) (list t)))
                  (else 
                   (x (d h) (e t (list (a h)))))))))
         (f 
          (lambda (h t F)
            (cond ((? h)
                   (let ((w (e t F)))
                     (if (find p w) (f w()()) w)))
                  ((p(a h))
                   (set! i(+ 1 i))
                   (f (d h)
                      (e t (e (l "<sup>")
                              (l (n i))
                              (l "</sup>")))
                      (e F (e (l "\n\n<sub>")
                              (l (n i))
                              '(#\ )
                              (a h)
                              (l "</sub>")))))
                  (else (f (d h) 
                           (e t (list (a h)))
                           F))))))
  (print (list->string (f (x (l (read-line)) 
                             ())
                          ()
                          ()))))

ใช่นี่คือ 533 ไบต์เมื่อลบช่องว่างทั้งหมดออก ได้รับความสุขในการทำงานที่มีชื่อเสียง

ฉันใช้อัลกอริทึมมากขึ้นหรือน้อยลงในคำอธิบาย: xจัดกลุ่มอินพุตโดยวงเล็บและfแทนที่ระดับแรกของกลุ่มด้วยเชิงอรรถซ้ำจนกระทั่งไม่มีกลุ่มเหลืออีก ผมแน่ใจว่ามันสามารถทำสั้น แต่ผมไม่เห็นว่ามันอาจจะทำให้มากสั้นโดยไม่ต้องเปลี่ยนขั้นตอนวิธีการที่แตกต่างกัน

ตามที่เขียนไว้มันเป็นโปรแกรมที่สมบูรณ์ คุณสามารถลองได้ที่นี่แต่เนื่องจาก repl.it ไม่สามารถจัดการกับ(read-line)คุณได้ดังนั้นจึงต้องใส่สตริงอินพุตแทน รุ่น ungolfed สมบูรณ์เป็นที่นี่

แก้ไข:ตามที่ระบุไว้ในความคิดเห็นที่ฉันเปลี่ยนวงเล็บ()เป็นวงเล็บ[]ในรุ่น repl.it นี่คือความสะดวกในการเขียนโปรแกรมและการดีบักเท่านั้น เวอร์ชันที่โพสต์ตอนนี้ใช้งาน()ได้แล้ว


1
+1 แต่ฉันไม่เข้าใจว่าทำไมคุณถึงเปลี่ยนวงเล็บเหลี่ยม ถ้าฉันเปลี่ยน#\['#] `ด้วยวงเล็บ (และอัปเดตการทดสอบ) นี่จะทำงานได้โดยไม่มีปัญหา มีเหตุผลที่คุณออกจากตารางหรือไม่? เกี่ยวข้องกับคำตอบก่อนหน้าของคุณหรือไม่
coredump

1
@coredump คุณพูดถูก ฉันเปลี่ยนเป็นวงเล็บเนื่องจาก (a) ตัวอักษรตัวอักษร paren messed up การจับคู่ paren ของ repl.it และ (b) ในการดีบักเอาต์พุต (ซึ่งจะรวม parens จำนวนมากจากรายการ) สามารถอ่านได้มากขึ้นด้วยเครื่องหมายวงเล็บ จากนั้นฉันก็ทิ้งมันไว้อย่างนั้น ฉันจะแก้ไข
xebtl

1

JavaScript ES6, 244 ไบต์

คำตอบที่จริงจัง (ใช้งานได้เฉพาะกับ FireFox กับความรู้ของฉัน)

d=(s,n=1)=>{u=s.search(/\(/);if(index<a=0)return s;for(i=index;i<s.length;i++){if(s[i]==")")a-=1;if(s[i]=="(")a+=1;if(!a)break}return d(s.replace(v=s.slice(index,i+1),"<sub>"+n+"</sub>")+`

<sub>`+n+" "+v.replace(/^\(|\)$/g,"")+"</sub>",n+1)}

ขยาย:

function deparen(s,n=1){
    index = s.search(/\(/);
    if(index<0) return s;
    a=0;
    for(i=index;i<s.length;i++){
        if(s[i]==")") a-=1;
        if(s[i]=="(") a+=1;
        if(!a) break;
    }
    v=s.slice(index,i+1)
    f=v.replace(/^\(|\)$/g,"");
    return deparen(s.replace(v,"<sub>"+n+"</sub>")+"\n\n<sub>"+n+" "+f+"</sub>",n+1);
}

0

ฮัสเซียม , 315 ไบต์

ขณะนี้สิ่งนี้ไม่ใช่การแข่งขันเนื่องจากไม่รองรับการซ้อนกันเช่นกัน

func main(){i=input();r="";f="";z=1;for(x=0;x<i.length;x++){c=i[Convert.toNumber(Convert.toString(x))];if(c=="("){f+="\n<sub>"+z+" ";for(x++;!(i[Convert.toNumber(Convert.toString(x))]==")");x++){f+=i[Convert.toNumber(Convert.toString(x))];}f+="</sub>\n";z++;r+="<sup>"+z+"</sup>";}else r+=c;}println(r);println(f);}

ขยาย:

func main() {
    i = input();
    r = "";
    f = "";
    z = 1;
    for (x = 0; x < i.length; x++) {
            c = i[Convert.toNumber(Convert.toString(x))];
            if (c == "(") {
                    f += "\n<sub>" + z + " ";
                    for (x++; !(i[Convert.toNumber(Convert.toString(x))] == ")"); x++) {
                            f += i[Convert.toNumber(Convert.toString(x))];
                    }
                    f += "</sub>\n";
                    z++;
                    r += "<sup>" + z + "</sup>";
            } else
                    r += c;
    }

    println(r);
    println(f);

}

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.