Rule of Thumb สำหรับการใช้อักษรตัวพิมพ์ใหญ่


30

ตามที่เว็บไซต์นี้เป็นกฎทั่วไปที่แนะนำโดยรัฐบาลสหรัฐสไตล์สำนักงานการพิมพ์คู่มือการใช้งานคือ

ใช้ประโยชน์จากคำทั้งหมดในชื่อเรื่องของสิ่งพิมพ์และเอกสารยกเว้น, a, the, at, โดย, สำหรับ, ใน, จาก, บน, บน, ขึ้น, และ, เป็น, แต่, หรือ, และและหรือ

สิ่งนี้อาจไม่เป็นจริงเพราะฉันไม่สามารถหาคำแนะนำดังกล่าวได้ในคู่มือสไตล์แต่ลองใช้กฎนี้ต่อไป


ความท้าทาย

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

  • คำแรกและสุดท้ายเป็นตัวพิมพ์ใหญ่
  • ทุกคำอื่น ๆ ที่มีทุนยกเว้น, , , ที่ , โดย , สำหรับ , ใน , ของ , บน , เพื่อ , ขึ้น , และ , เป็น , แต่ , หรือและมิได้

สายป้อนจะมีอย่างน้อยหนึ่งคำแต่ละคำมีตัวอักษรอย่างน้อยหนึ่งและตัวอักษรจากไปaz

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

Testcases

"the rule of thumb for title capitalization" -> "The Rule of Thumb for Title Capitalization"
"programming puzzles and code golf" -> "Programming Puzzles and Code Golf"
"the many uses of the letter a" -> "The Many Uses of the Letter A"
"title" -> "Title"
"and and and" -> "And and And"
"a an and as at but by for in nor of on or the to up" -> "A an and as at but by for in nor of on or the to Up"
"on computable numbers with an application to the entscheidungsproblem" -> "On Computable Numbers With an Application to the Entscheidungsproblem"

1
ควรเริ่มต้น / สิ้นสุดคำด้วยตัวพิมพ์ใหญ่แม้ว่าจะอยู่ในรายการยกเว้นหรือไม่ ตัวอย่างของคุณบอกว่าใช่ แต่สเป็คเพียงพูดว่าใช้ตัวอักษรพิมพ์ใหญ่คำเว้นแต่จะอยู่ในรายการและไม่มีอะไรเกี่ยวกับคำแรก / คำสุดท้าย โปรดทราบว่าความเป็นไปได้ทั้งสองนั้นแตกต่างกันอย่างชัดเจนหนึ่งในนั้นเป็นตัวกรองอย่างง่ายและตัวที่สองต้องการพฤติกรรมพิเศษในกรณีขอบ (ตัวอักษร)
CAD97

3
@ CAD97 กฎสำหรับการใช้อักษรตัวพิมพ์ใหญ่คือสัญลักษณ์แสดงหัวข้อย่อยสองตัวไม่ใช่การอ้างอิง และสัญลักษณ์แสดงหัวข้อแรกบอกว่า "คำแรกและสุดท้ายเป็นตัวพิมพ์ใหญ่" และคำที่สองพูดว่า "คำอื่น ๆ ทั้งหมดเป็นตัวพิมพ์ใหญ่ยกเว้น ... " ความหมายคำแรกและคำสุดท้ายจะเป็นตัวพิมพ์ใหญ่เสมอ
Laikoni

ฉันคิดถึงมันอย่างใด ยังคงขอบคุณสำหรับการชี้แจง
CAD97

ฉันไม่แน่ใจว่าจำเป็นต้องระบุว่าแต่ละคำมีตัวอักษรอย่างน้อยหนึ่งตัว :)
David Conrad

คำตอบ:


11

Python 2, 118 ไบต์

ดูสิไม่มี regex!

for w in`input()`.split():print[w.title(),w][`w`in"'a'an'and'as'at'the'by'but'for'nor'in'of'on'or'to'up'"].strip("'"),

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

คำอธิบาย

ลองทำอินพุตa or anเป็นตัวอย่างของเรา

ใช้งูหลาม 2 `x`ทางลัดสำหรับเราห่อป้อนข้อมูลในเครื่องหมายคำพูดเดียว:repr 'a or an'จากนั้นเราแยกช่องว่างและวนซ้ำคำ

ภายในวงที่เราใช้เวลาอีกครั้งrepr สำหรับคำแรกและครั้งสุดท้ายนี้จะช่วยให้และ"'a" "an'"สำหรับคำอื่น ๆ 'or'ที่จะช่วยให้ เราต้องการหลีกเลี่ยงการใช้ตัวพิมพ์ใหญ่หากคำเหล่านั้นเหมาะสมกับรูปแบบหลังและอยู่ในรายการคำศัพท์สั้น ๆ ดังนั้นเราสามารถแสดงรายการคำเป็นสตริง"'a'an'...'up'"และรู้ว่าreprคำศัพท์สั้น ๆ จะเป็นสตริงย่อย

`w` in "..."ให้ค่าบูลีนซึ่งเราสามารถรักษาเป็น0หรือเพื่อวัตถุประสงค์ในการจัดทำดัชนีลงไปในรายการ1 [w.title(), w]ในระยะสั้นเราชื่อกรณีคำว่ามันเป็นที่จุดเริ่มต้นในตอนท้ายหรือไม่ในรายการของคำสั้น ๆ มิฉะนั้นเราจะทิ้งมันไว้ตามลำพัง โชคดีที่ยังคงทำงานตามที่คาดไว้ด้วยการป้อนข้อมูลเช่นtitle()'a

ในที่สุดเราจะตัดคำพูดใด ๆ จากคำและพิมพ์ด้วยช่องว่างต่อท้าย


8

05AB1E , 68 61 ไบต์

บันทึกแล้ว 7 ไบต์ขอบคุณAdnan

™ð¡Dg<UvyN__NXQ_“a€¤€€€›€‹€‡€†€‚€‰€„€¾€ƒ€œ€³€—š¯“#™yå&&il})ðý

ลองออนไลน์!

คำอธิบาย

“a€¤€€€›€‹€‡€†€‚€‰€„€¾€ƒ€œ€³€—š¯“a an the at by for in of on to up and as but or norเป็นสตริงพจนานุกรมแปลว่า

™                          # title case input string
ð¡                         # split on spaces
Dg<U                       # store index of last word in X

vy                         # for each word
  N__                      # is it not first index?
     NXQ_                  # is it not last index
         “...“             # the compressed string 
              #            # split on spaces
               ™           # convert to title case
                yå         # is current word in this list?
                  &&       # and the 3 previous conditions together
                    il     # if all are true, convert to lower case
                      }    # end loop
)ðý                        # wrap stack in list and join by spaces

2
มันไม่เคยปล่อยให้ฉันประหลาดใจในสิ่งที่คุณจัดการเพื่อให้บรรลุด้วยสตริงสั้น ๆ ของตัวละครที่มองไม่เห็นทั้งหมด ดูเหมือนว่าจะใช้งานได้แล้ว :) +1
ElPedro

Bah! ฉันสนิทกันมากและหาวิธีกำจัดบุคลิกไม่ออก
mbomb007

@ mbomb007: รีบเร็วขึ้นก่อนที่ Jelly, MATL หรือภาษาอื่น ๆ ที่สามารถใช้ฟังก์ชั่นเพื่อดัชนีมาแล้วชนะ :) ฉันดูเหมือนจะจำภาษาที่มีการบีบอัด regex ด้วย แต่ไม่สามารถจำสิ่งที่เรียกว่า นี่มันนานพอที่มันจะยังสามารถเล่นกอล์ฟได้เช่นกัน
Emigna

1
สำหรับ62 ไบต์ :)
Adnan

@Adnan: ฉันเริ่มต้นเช่นนั้น แต่มีเพียงคำ 3-char (ซึ่งจบลงด้วยความยาว) แต่ฉันไม่ได้พิจารณาที่จะใช้คำ 2-char เช่นกัน ... aแทนที่จะ€…บันทึกไบต์เพิ่มเติมเช่นกันหากนำไปสู่ ด้วย :) ขอบคุณ!
Emigna

7

GNU sed 81 74 73 Bytes

รวม +1 สำหรับ -r

s/\b./\u&/g
:;s/.(And?|A[st]?|The|By|But|[FN]or|In|O[fnr]|To|Up) /\L&/;t

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

ลองออนไลน์!


6

เรติน่า69 69ไบต์

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

T`l`L`\b.
+T`L`l` (And?|A[st]?|The|By|But|[FN]or|In|O[fnr]|To|Up) 

ลองออนไลน์

นอกจากนี้ยังใช้งานได้.แทนที่จะเป็นช่องว่างแรก

มี regexes จำนวนมากที่มีความยาวเท่ากัน แต่ฉันไม่สามารถหาวิธีที่จะตัดมันได้อีกต่อไป ...


(วิธีนี้ยังเป็น 69 ไบต์ใน Pip แต่ฉันไม่สามารถใช้+เคล็ดลับที่จะร่นมัน.)
DLosc

@DLosc ขอบคุณ IDK ทำไมฉันไม่เห็นอย่างนั้น ฉันสนิท
mbomb007

3

JavaScript (ES6), 141 138 135 133 ไบต์

บันทึก 3 ไบต์ขอบคุณ mbomb007

s=>s.replace(/(\w+)( ?)/g,(a,w,n,i)=>i&&n&&/^(a[nst]?|the|by|in|of|on|to|up|and|but|[fn]?or)$/.exec(w)?a:a[0].toUpperCase()+a.slice(1))

กรณีทดสอบ


3

เยลลี่ , 58 ไบต์

“Ð/ṃƇ¬þṄẊƙ€,⁽ṙƬ®OṪJ"ɦ3×kf3Ṙç%ġu’b26ịØaṣ”z
e€¢¬T;2Ḷ¤
ḲŒtǦK

TryItOnline! หรือเรียกใช้การทดสอบทั้งหมด

อย่างไร?

สตริงที่ถูกบีบอัดที่มีช่องว่างคั่นคำจะเป็น47ไบต์แบ่งเป็น1ไบต์เป็น48ไบต์

สตริงที่ถูกบีบอัดสองคำที่ไม่แยกกันของคำที่มีความยาว2และ3(ที่มี 'a' ที่ส่วนท้ายของหนึ่ง) ตามลำดับจะเป็น40ไบต์บวก2เพื่อแยกแต่ละรายการและ1เข้าร่วมสำหรับ45ไบต์

หนึ่งฐาน 250 หมายเลขตามที่อธิบายไว้ด้านล่างคือ32ไบต์จากนั้น3แปลงเป็นฐาน 26 3เพื่อทำดัชนีเป็นตัวอักษรตัวพิมพ์เล็กและ3แบ่งเป็นอักขระที่ไม่ได้ใช้'z'งานเป็น41ไบต์

ดังนั้นการค้นหาคำที่ไม่ใช้ประโยชน์:
“Ð/ṃƇ¬þṄẊƙ€,⁽ṙƬ®OṪJ"ɦ3×kf3Ṙç%ġu’
ถูกสร้างขึ้นเช่น:

ใช้คำเหล่านั้นและเข้าร่วมกับตัวแยก:
s="a an the at by for in of on to up and as but or nor"

ป้ายถัดไป'a'เป็น1, 'b'เป็น2กับแยกเป็น0:

alpha = ' abcdefghijklmnopqrstuvwxyz'
x = [alpha.index(v) for v in s]
x
[1,0,1,14,0,20,8,5,0,1,20,0,2,25,0,6,15,18,0,9,14,0,15,6,0,15,14,0,20,15,0,21,16,0,1,14,4,0,1,19,0,2,21,20,0,15,18,0,14,15,18]

แปลงเป็น26เลขฐาน(ตัวอักษรตัวสุดท้ายที่ใช้คือ'y'บวกหลักสำหรับตัวแยกรหัส Python สำหรับสิ่งนี้คือ:
n=sum(v*26**i for i,v in enumerate(x[::-1]))

แปลงเป็น250ตัวเลขฐาน(ใช้รายการสำหรับหลัก):

b=[]
while n:
    n,d = divmod(n,250)
    b=[d]+b
b
[16,48,220,145,8,32,202,209,162,13,45,142,244,153,9,80,207,75,35,161,52,18,108,103,52,205,24,38,237,118]

ค้นหาตัวละครที่ดัชนีเหล่านั้นในเพจรหัสของเยลลี่:

codepage = '''¡¢£¤¥¦©¬®µ½¿€ÆÇÐÑ×ØŒÞßæçðıȷñ÷øœþ !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQR TUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~¶°¹²³⁴⁵⁶⁷⁸⁹⁺⁻⁼⁽⁾ƁƇƊƑƓƘⱮƝƤƬƲȤɓƈɗƒɠɦƙɱɲƥʠɼʂƭʋȥẠḄḌẸḤỊḲḶṂṆỌṚṢṬỤṾẈỴẒȦḂĊḊĖḞĠḢİĿṀṄȮṖṘṠṪẆẊẎŻạḅḍẹḥịḳḷṃṇọṛṣṭụṿẉỵẓȧḃċḋėḟġḣŀṁṅȯṗṙṡṫẇẋẏż«»‘’“”'''
r=''.join(codepage[i-1] for i in b)
r
'Ð/ṃƇ¬þṄẊƙ€,⁽ṙƬ®OṪJ"ɦ3×kf3Ṙç%ġu'

(หมายเหตุ: เนื่องจากการใช้งานจริงนั้นเป็น bijective หากbมี0ตัวเลขใดที่หนึ่งจะต้องดำเนินการก่อน)

ส่วนที่เหลือ:

ḲŒtǦK - Main link: title string
Ḳ      - split on spaces
    ¦  - apply to indexes
   Ç   -     given by calling the last link (1) as a monad (with the split title string)
 Œt    -     title case (first letter of each (only) word to upper case)
     K - join on spaces

e€¢¬T;2Ḷ¤ - Link 1, find indexes to capitalise: split title string
e€        - is an element of, for €ach
  ¢       - the result of calling the last link (2) as a nilad
   ¬      - logical not
    T     - get the truthy indexes (indexes of words that are not in the list)
     ;    - concatenate with
        ¤ - nilad followed by link(s) as a nilad
      2Ḷ  - range(2) -> [0,1]
                (we always want to capitalise the first index, 1, and the last index, 0)

“Ð/ṃƇ¬þṄẊƙ€,⁽ṙƬ®OṪJ"ɦ3×kf3Ṙç%ġu’b26ịØaṣ”z - Link 2, make the word list: no arguments
“Ð/ṃƇ¬þṄẊƙ€,⁽ṙƬ®OṪJ"ɦ3×kf3Ṙç%ġu’          - the base 250 number
                                b26       - convert to base 26
                                   ị      - index into
                                    Øa    - lowercase alphabet
                                      ṣ   - split on
                                       ”z - literal 'z' (the separator 0 indexes into `z`)

2

PHP, 158 ไบต์

บันทึก 10 ไบต์โดย@Titus

foreach($w=explode(" ",$argv[1])as$k=>$v)echo" "[!$k],$k&&$k+1<count($w)&&preg_match("#^(a[snt]?|and|[fn]or|up|by|but|the|to|in|o[rnf])$#",$v)?$v:ucfirst($v);

PHP รุ่นก่อนหน้า, 174 ไบต์

foreach($w=explode(" ",$argv[1])as$k=>$v)$k&&$k+1<count($w)&&in_array($v,[a,an,the,at,by,"for",in,of,on,to,up,"and","as",but,"or",nor])?:$w[$k]=ucfirst($v);echo join(" ",$w);

การสะท้อนในลูปจะช่วยประหยัด 10 ไบต์:foreach(...)echo" "[!$k],(condition)?$v:ucfirst($v);
ติตัส

2

TI-Basic, 295 + 59 + 148 = 502 ไบต์

ตอนนี้คุณสามารถใช้ประโยชน์จากเครื่องคิดเลขของคุณ ดีสำหรับโรงเรียน :)

โปรแกรมหลักขนาด 295 ไบต์

โดยทั่วไปเคล็ดลับการจับคู่กับคำดังนั้นสิ่งที่Aไม่ได้กลายเป็นaคือการใส่ที่มีช่องว่างเช่นแทนที่ด้วย" A " " a "สิ่งนี้ยังทำให้เป็นไปโดยอัตโนมัติเพื่อให้คำแรกและคำสุดท้ายยังคงเป็นตัวพิมพ์ใหญ่อยู่เพราะพวกเขาไม่มีช่องว่างทั้งสองด้านและจะไม่ตรงกับคำใด ๆ (อัจฉริยะใช่ไหมและยาวมากเพราะตัวอักษรตัวพิมพ์เล็กแต่ละตัวมีสองไบต์ ... )

"("+Ans+")→Str1
"@A ~ a@An ~ an@The ~ the@At ~ at@By ~ by@For ~ for@In ~ in@Of ~ of@On ~ on@To ~ to@Up ~ up@And ~ and@As ~ as@But ~ but@Or ~ or@Nor ~ nor@→Str2
For(I,2,length(Ans
If "@"=sub(Str2,I-1,1
Then
" "+Str1+"~"+sub(Str2,I,inString(Str2,"@",I)-I)+" "
prgmQ
Ans→Str1
End
End

โปรแกรมย่อย ( prgmQ), 59 ไบต์:

Ans→Str9
inString(Ans,"~
sub(Str9,Ans,length(Str9)-Ans+1→Str8
Str9
prgmR
Repeat Str9=Ans+Str8
Ans+Str8→Str9
prgmR
End

โปรแกรมย่อย ( prgmR), 148 ไบต์:

Ans→Str0
inString(Ans,"~→Z
inString(Str0,"~",Ans+1→Y
inString(sub(Str0,1,Z-1),sub(Str0,Z+1,Ans-Z-1→X
sub(Str0,1,-1+inString(Str0,"~
If X
sub(Str0,1,X-1)+sub(Str0,Y+1,length(Str0)-Y)+sub(Str0,X+length(sub(Str0,Z+1,Y-Z-1)),Z-X-length(sub(Str0,Z+1,Y-Z-1

PS ~หมายถึงโทเค็น0x81และ@แสดงถึง0x7Fเรียนรู้เพิ่มเติมที่นี่


2

Java 7, 271 259 258 ไบต์

String c(String x){String a[]=x.split(" "),s=" ",r=w(a[0])+s;for(int i=0,l=a.length-1;i<l;r+=(!s.matches("^(a[nst]?|the|by|in|of|on|to|up|and|but|[fn]?or)$")|i==l?w(s):s)+" ")s=a[++i];return r;}String w(String w){return(char)(w.charAt(0)-32)+w.substring(1);}

Ungolfed & รหัสการทดสอบ:

ลองที่นี่

class M{
  static String c(String x){
    String a[] = x.split(" "),
           s = " ",
           r = w(a[0]) + s;
    for(int i = 0, l = a.length-1; i < l; r += (!s.matches("^(a[nst]?|the|by|in|of|on|to|up|and|but|[fn]?or)$") | i == l
                                                 ? w(s)
                                                 : s)   + " "){
      s = a[++i];
    }
    return r;
  }

  static String w(String w) {
    return (char)(w.charAt(0) - 32) + w.substring(1);
  }

  public static void main(String[] a){
    System.out.println(c("the rule of thumb for title capitalization"));
    System.out.println(c("programming puzzles and code golf"));
    System.out.println(c("the many uses of the letter a"));
    System.out.println(c("title"));
    System.out.println(c("and and and"));
    System.out.println(c("a an and as at but by for in nor of on or the to up"));
    System.out.println(c("on computable numbers with an application to the entscheidungsproblem"));
  }
}

เอาท์พุท:

The Rule of Thumb for Title Capitalization 
Programming Puzzles and Code Golf 
The Many Uses of the Letter A 
Title 
And and And 
A an and as at but by for in nor of on or the to Up 
On Computable Numbers With an Application to the Entscheidungsproblem 

1

Groovy, 131 129

บันทึกสองไบต์ด้วย carusocomputing

{it.split()*.with{a->a in "a an the at by for in of on to up and as but or nor".split()?a:a.capitalize()}.join(" ").capitalize()}

นีซฉันอายุ 137 ปี คุณชนะ. ลบออกi->และใช้itเพื่อบันทึก 2 ไบต์ {it.split()*.with{a->a in "a an the at by for in of on to up and as but or nor".split()?a:a.capitalize()}.join(" ").capitalize()}
Magic Octopus Urn

1
ฉันไม่รู้จัก Groovy แต่นี่จะใช้ประโยชน์จากคำแรกและคำสุดท้ายใช่หรือไม่
Emigna

@Emigna ตัวพิมพ์ใหญ่สุดท้ายครอบคลุมเริ่มต้นด้วยคำใดคำหนึ่ง
Magic Octopus Urn

@Emigna ไม่จริงฉันพลาดข้อกำหนดนั้นไป (คำสุดท้ายนั้นต้องเป็นตัวพิมพ์ใหญ่) ฉันจะต้องปรับ anwser ของฉัน
Krzysztof Atłasik

การใช้งานสองครั้งใช้.capitalize()เวลามากถึงไบต์ มีวิธีสั้น ๆ ที่คุณสามารถสร้างนามแฝงได้.capitalize()หรือไม่
Cyoce

1

C #, 305 ไบต์

ยังมีห้องพักสำหรับการปรับปรุงมากมาย แต่ที่นี่คุณไป:

s=>{;var b=s.Split(' ');b[0]=((char)(b[0][0]-32))+b[0].Substring(1);int i=0,n=b.Length;for(;++i<n;)if(!"a,an,the,at,by,for,in,of,on,to,up,and,as,but,or,nor".Split(',').Contains(b[i]))b[i]=((char)(b[i][0]-32))+b[i].Substring(1);b[n-1]=((char)(b[n-1][0]-32))+b[n-1].Substring(1);return string.Join(" ",b);};

1

Ruby, 123 117 111 102 ไบต์

->s{s.gsub(/ .|^./,&:upcase).gsub(/ (A[nts]?|The|By|In|To|Up|And|But|[NF]or|O[rnf])(?= )/,&:downcase)}

ขออภัยสำหรับการแก้ไขทั้งหมด - นี่ควรเป็นรายการสุดท้าย


1

Python ขนาด 177 ไบต์

จัดส่งในรูปแบบฟังก์ชั่นเพื่อการประหยัดไบต์ นี่ไม่ใช่คำตอบที่แข่งขันโดยเฉพาะอย่างยิ่ง แต่เป็นคำตอบที่ไม่ต้องการrepr()หรือมีregexเล่ห์เหลี่ยม นอกจากนี้ยังเป็นรุ่นที่ไม่เชื่อเรื่องพระเจ้า; ใช้งานได้กับ Python 2 หรือ 3

แม้ว่ามันอาจจะเป็นทางออกที่ดีโดยกฎ

def t(s):
 w="a an the the at by for in of on to up and as but or nor".split()
 l=[(s.title(),s)[s in w]for s in s.split()]
 for x in(0,-1):l[x]=l[x].title()
 return' '.join(l)

1

PHP, 109 142 ไบต์

<?=preg_replace_callback("# (A[snt]?|And|[FN]or|Up|By|But|The|To|In|O[rnf])(?= )#",function($m){return strtolower($m[0]);},ucwords($argv[1]));

การรวมกันของuser59178´sและmbomb007´sคำตอบ

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


มันใช้งานไม่ได้สำหรับa an and as at but by for in nor of on or the to up
JörgHülsermann

1

แร็กเก็ต 353 ไบต์

(define(cap i)(set! i(string-append i))(define c(string-ref i 0))(string-set! i 0(if(char-upper-case? c)c(integer->char(-(char->integer c)32))))i)
(let*((ex(list"a""an""the""at""by""for""in""of""on""to""up""and""as""but""or""and""nor"))(sl(string-split s)))
(string-join(for/list((i sl)(n(in-naturals)))(cond[(= n 0)(cap i)][(member i ex)i][(cap i)]))))

Ungolfed:

(define (f s)

  (define (cap i)                 ; sub-fn to capitalize first letter of a word
    (set! i (string-append i))
    (define c (string-ref i 0))
    (string-set! i 0
                 (if (char-upper-case? c)
                     c
                     (integer->char (-(char->integer c)32))))
    i)

  (let* ((ex (list "a""an""the""at""by""for""in""of""on""to""up""and""as""but""or""and""nor"))
         (sl (string-split s)))
    (string-join
     (for/list
         ((i sl)
          (n (in-naturals)))
       (cond
         [(= n 0) (cap i)]
         [(member i ex) i]
         [(cap i)]
         )))))

การทดสอบ:

(f "the rule of thumb for title capitalization")

เอาท์พุท:

"The Rule of Thumb for Title Capitalization"

1

Java 7 431 317 311 ไบต์

ขอบคุณ @KevinCruijssen สำหรับ114ไบต์
ขอบคุณ @RosLup สำหรับการบันทึก6ไบต์

String c(String s){String v="",x,l[]=s.split(" "),b[]={"a","an","the","at","but,"by","for","in","of","on","to","‌​up","as","or","and","nor"};int i=0,f=0,z=0;for(String c:l){for(f=0;f<b.length;z=c.equals(b[f++])|z>0?1:0);x=(char)(c.charAt(0)-32)+c.substring(1);v+=(z>0?i<1|i>l.length-2?x:c:x)+" ";i++;}return v;}

ungolfed

คำตอบแรกที่สูงกว่า 250 ไบต์

 static String c(String s) {
      String v = "", x, l[] = s.split(" "),
b[]={"a","an","the","at","by","for","in","of","on","to",
                                         "‌​up","and","as","or","nor","but"};
    int i , f , z = i = f = 0;
    for (String c : l) {

   for (f = 0; f < b.length; z = c.equals( b[f++] ) | z > 0 ? 1 : 0);
        x = (char)(c.charAt(0) - 32) + c.substring(1);

        v += (z > 0 ? i < 1 | i > l.length - 2 ? x : c : x) + " ";
        i++;
   }
    return v;
    }

1
มันมากเกินไปที่จะสรุปในความคิดเห็น แต่คุณสามารถตีมันได้: String f(String s){String v="",x,l[]=s.split(" "),b[]={"a","an","the","at","by","for","in","of","on","to","up","and","as","but","or","and","nor"};int i=0,f=0,z=0;for(String c:l){for(f=0;f<b.length;z=c.equals(b[f++])|z>0?1:0);x=(char)(c.charAt(0)-32)+c.substring(1);v+=z>0?i<1|i++==l.length-1?x:c:x)+" ";}return v;}( 314 ไบต์ ) ฉันขอแนะนำให้ดูสิ่งที่ฉันเปลี่ยนไปเป็นเคล็ดลับในครั้งต่อไป :) PS: ฉันโพสต์คำตอบด้วยวิธีอื่น ( 259 bytes )
Kevin Cruijssen

1
โดยเฉพาะอย่างยิ่งสิ่งc.substring(0,1).toUpperCase()+c.substring(1,c.length())+" "ที่คุณทำสองครั้งควรทำให้คุณคิดถึงการใช้ซ้ำอีกครั้ง และ initializations รวมเช่นคุณได้อย่างถูกต้องด้วยแต่ด้วยเหตุผลไม่ได้กับบางint Stringนอกจากนี้ยังมีความจำเป็นในการเสริมไม่มีbooleanเมื่อคุณสามารถจัดเก็บที่เป็นint0 หรือ 1 >0และจากนั้นตรวจสอบ และฉันจะพยายามหลีกเลี่ยงวงเล็บและbreakมากที่สุด มักจะมีเคล็ดลับในการกำจัดพวกเขาเช่นfor(f=0;f<b.length;z=c.equals(b[f++])|z>0?1:0);ฉันได้แสดงให้เห็น :)
Kevin Cruijssen

1
มากที่จะเรียนรู้และขอบคุณสำหรับการช่วยเหลืออยู่เสมอ (Long Nederland;)
Numberknot

1
โอ้ฉันได้ทำผิดพลาดการคัดลอกวาง .. มันควรจะเป็นอย่างนี้String c(String s){String v="",x,l[]=s.split(" "),b[]={"a","an","the","at","by","for","in","of","on","to","up","and","as","but","or","and","nor"};int i=0,f=0,z=0;for(String c:l){for(f=0;f<b.length;z=c.equals(b[f++])|z>0?1:0);x=(char)(c.charAt(0)-32)+c.substring(1);v+=(z>0?i<1|i++>l.length-2?x:c:x)+" ";}return v;}และไม่มีปัญหา :) ฉันยังได้เรียนรู้มากมายเมื่อฉันยังใหม่กับการตีกอล์ฟ ฉันเพิ่งสร้างรายการพร้อมกับเคล็ดลับ codegolf ทั่วไปที่ฉันเรียนรู้และดู / อัปเดตบางครั้ง แต่รหัสของฉันยังคงได้รับจากคนอื่นมากกอล์ฟ
Kevin Cruijssen

1
ในสตริง b [] มี 2 'และ' ตกลงไหม?
RosLuP

1

PHP, 117 118 112 ไบต์

<?=strtr(ucwords(preg_replace("# (?=(a[snt]?|and|[fn]or|up|by|but|the|to|in|o[rnf]) )#","!",$argv[1])),'!',' ');

ใช้ลักษณะการทำงานucwords()และ Escape คำที่เกี่ยวข้องที่ล้อมรอบด้วยช่องว่างจากนั้นลบอักขระการหลีกเลี่ยง

ฉันคัดลอก(a[snt]?|and|[fn]or|up|by|but|the|to|in|o[rnf])มาจากคำตอบของJörgHülsermann แต่เนื่องจากวิธีการแตกต่างไปจากเดิมอย่างสิ้นเชิงฉันโพสต์เป็นคำตอบแยกต่างหาก

แก้ไข: ข้อผิดพลาดที่สังเกตเห็นโดยติตัสแก้ไขได้ค่า 1 ไบต์ ยัง: 6 ไบต์บันทึกขอบคุณความคิดเห็นที่เป็นประโยชน์ของเขาเกี่ยวกับ strtr


บันทึก 6 ไบต์กับแทนstrtr str_replaceหรือเติมคำด้วย<>และวางthe str_replaceแล้วใช้เอาต์พุต HTML
ติตัส

ในบางกรณีคุณสามารถใช้แทนpreg_filter preg_replaceฉันไม่ได้ลองด้วยวิธีการแก้ปัญหาของคุณ
JörgHülsermann

regex จะไม่ทำงานสองคำจากรายการในแถว; nice try for a startทดสอบ การแทนที่ช่องว่างด้วยการยืนยันนั้นจะแก้ปัญหานั้น (+4 ไบต์)
ติตัส

น่าเสียดายpreg_filterที่titleกรณีทดสอบล้มเหลวโดยไม่ส่งคืนอะไร
user59178

1

เพียว bash - 253

(ไม่มีโปรแกรมภายนอกที่เรียกว่า) - ต้องการ bash v4

declare -A b;for x in A An The At By For In Of On To Up And As But Or Nor;do b[$x]=1;done
while read -a w;do
n=${#w[@]};o[0]=${w[0]^}
for((i=1;i<n-1;i++)){
g=${w[$i]^};((${b[$g]}))&&o+=(${g,,})||o+=($g);}
((n>1))&&o[$n]=${w[-1]^}
echo ${o[@]};o=()
done

มุมมองปกติที่มีความคิดเห็น

#create the "blacklist"
declare -A b
for w in A An The At By For In Of On To Up And As But Or Nor
do
    b[$x]=1
done

# logic:
# read each line (split by words) into array
# and each word is assigned capitalized to the new output array
# but the blacklisted ones

#read each line to array w (split on spaces)
while read -a w
do
    n=${#w[@]}         # get the number of words
    o[0]=${w[0]^}          # copy the capitalized word1
    for((i=1 ; i<n-1 ; i++)) { # loop over 2 up to last -1 words

        g=${w[$i]^}    # for the given word
        # check if it is in the blacklisted ones
        # if yes - convert to lowercase, if not leave as it is
        # and append to the output array
        (( ${b[$g]} )) && o+=(${g,,}) || o+=($g)
    }
    # capitalize the last word if here is more words
    (( n>1 )) && o[$n]=${w[-1]^}
    # make a line from the words
    echo ${o[@]}
    o=() #cleanup
done

เอาท์พุต

Title
And and And
The Rule of Thumb for Title Capitalization
Programming Puzzles and Code Golf
The Many Uses of the Letter A
A an and as at but by for in nor of on or the to Up
On Computable Numbers With an Application to the Entscheidungsproblem

1

Japt , 71 ไบต์

£`a  e  by f     up d  ¿t  n`¸aX >0©Y¦0©YĦZl ?X:Xg u +XÅ}S

ลองออนไลน์!

คำอธิบาย:

£`a  e  by f     up d  ¿t  n`¸aX >0©Y¦0©YĦZl ?X:Xg u +XÅ}S
£`...`qS aX >0&&Y!=0&&Y!=UqS l -1?X:Xg u +Xs1}S

£                                            }S   // Split at spaces and map each item X by this function:
 `...`                                            //  Backticks are used to decompress strings
      qS                                          //  Split the decompressed string at spaces.
         aX >J                                    //  If this contains X
              &&Y!=0                              //  and the index is non-zero (it's not the first word)
                    &&Y!=UqS l -1                 //  and the index is not the length of the input -1 (it's not the last word),
                                 ?X               //  return X.
                                   :Xg u +Xs1     //  Else, return X capitalized. (Literally X[0].toUpperCase() + X.slice(1))
                                             }S   // Rejoin with spaces

หนึ่งในคุณสมบัติ Japt ที่ฉันชอบคือการบีบอัดสตริงซึ่งใช้ไลบรารี shocoห้องสมุดโสโค

คุณสามารถบีบอัดสตริงโดยห่อในOc"{string}"Oc"a an the at by for in of on to up and as but or nor"

จากนั้นคลายการบีบอัดด้วย backticks หรือOd"{compressed string}"Od"a e by f up d ¿t n"


การ-Sตั้งค่าสถานะถูกเพิ่มหลังจากความท้าทายนี้ถูกโพสต์ดังนั้นโซลูชันปัจจุบันของคุณจึงไม่สามารถแข่งขันได้ อย่างไรก็ตามฉันคิดว่าคุณสามารถทำได้£...+XÅ}Sซึ่งจะเป็นการแข่งขันสำหรับจำนวนไบต์เดียวกัน ( ลองใช้ออนไลน์! )
ETHproductions

shoco เปรียบเทียบกับการบีบอัดพจนานุกรมของ Jelly ในความคิดเห็นของคุณอย่างไร?
Robert Fraser

@RobertFraser เมื่อเทียบกับวุ้นก็ไม่ดีมากที่การบีบอัดสตริงของคำภาษาอังกฤษ แต่มันเป็นสิ่งที่ดีมากที่สายการบีบอัดของตัวอักษรตัวพิมพ์เล็กพลที่มาในบางครั้งที่มีประโยชน์
ETHproductions

1

บริสุทธิ์ bash - 205 192 181 ไบต์

tc(){
while read -a x
do x=(${x[@]^})
for ((i=1;i<${#x[@]}-1;i++))
do
case "${x[i]}" in
A|A[nts]|The|By|[FN]or|In|O[fnr]|To|Up|And|But)x[i]=${x[i],};;
esac
done
echo ${x[@]}
done
}

เช่นเดียวกับคำตอบของ jm66 tcยอมรับอินพุตมาตรฐาน


0

ที่จริงแล้ว 79 ไบต์

' ,ÿsd@p@`;0"A0An0The0At0By0For0In0Of0On0To0Up0And0As0But0Or0Nor"síu'ù*ƒ`Moq' j

ลองออนไลน์!

คำอธิบาย:

' ,ÿsd@p@`;0"longstring"síu'ù*ƒ`Moq' j
' ,ÿs                                   title case input, split on spaces
     d@p@                               pop first and last words to stack
         `;0"longstring"síu'ù*ƒ`M       for every word except the first and last:
          ;0"longstring"s                 duplicate word, split the long string on 0s
                         íu               1-based index of word in list (0 if not found)
                           'ù*            "ù"*(index)
                              ƒ           execute the resulting string as a function (lowercases word if it's in the list)
                                 oq' j  put the first and last word back in the list, join with spaces

0

แบตช์ 323 ไบต์

@echo off
set s=
for %%w in (@%*@)do call:w %%w
echo%s%
exit/b
:w
for %%s in (a an the at by for in of on to up and as but or nor)do if %%s==%1 set s=%s% %1&exit/b
set w=%1
set w=%w:@=%
set f=%w:~0,1%
for %%c in (A B C D E F G H I J K L M N O P Q R S T U V W X Y Z)do call set f=%%f:%%c=%%c%%
set s=%s% %f%%w:~1%

ด้วยความคิดเห็น:

@echo off
rem Start with an empty output string
set s=
rem Wrap the parameters in @ signs to identify the first and last words 
for %%w in (@%*@) do call :w %%w
rem Ignore the leading space when printing the result
echo%s%
exit/b
:w
rem Check whether this is a word that we don't change
for %%s in (a an the at by for in of on to up and as but or nor) do if %%s==%1 set s=%s% %1&exit/b
set w=%1
rem Delete any @ signs from the first and last words
set w=%w:@=%
rem Get the first character
set f=%w:~0,1%
rem Case insensitively replace each upper case letter with itself
for %%c in (A B C D E F G H I J K L M N O P Q R S T U V W X Y Z) do call set f=%%f:%%c=%%c%%
rem Concatenate with the rest of the word
set s=%s% %f%%w:~1%
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.