Die Faustregel für die Großschreibung von Titeln

30

Laut dieser Site ist eine allgemeine Regel, die vom US Government Printing Office Style Manual empfohlen wird

Großschreibung aller Wörter in Titeln von Veröffentlichungen und Dokumenten, mit Ausnahme von a, an, at, by, for, in, on, to, up und as, but, or, and nor.

Dies mag nicht zutreffen, da ich eine solche Empfehlung im Style-Handbuch nicht finden kann , aber verwenden wir diese Regel trotzdem.


Die Herausforderung

Bei einer Eingabezeichenfolge, die aus durch Leerzeichen getrennten Wörtern in Kleinbuchstaben besteht, wird die Groß- und Kleinschreibung der Zeichenfolge gemäß den folgenden Regeln ausgegeben

  • Das erste und letzte Wort wird in Großbuchstaben geschrieben.
  • Alle anderen Worten werden aktiviert, mit der Ausnahme ein , ein , die , an , von , für , in , der , auf , zu , auf , und , wie , aber , oder , und noch .

Die Eingabezeichenfolge enthält mindestens ein Wort und jedes Wort enthält mindestens einen Buchstaben und nur Zeichen von abis z.

Dies ist eine Code-Golf-Herausforderung. Versuchen Sie daher, so wenig Bytes wie möglich in der Sprache Ihrer Wahl zu verwenden. Sie können ein vollständiges Programm oder eine Funktion schreiben, um die Aufgabe zu erfüllen.

Testfälle

"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"
Laikoni
quelle
1
Sollten Anfangs- / Endwörter groß geschrieben werden, auch wenn sie in der Ausschlussliste enthalten sind? Ihre Beispiele sagen ja, aber die Spezifikation sagt nur Großbuchstaben, sofern sie nicht in der Liste enthalten sind, und nichts über das erste / letzte Wort. Beachten Sie, dass sich die beiden Möglichkeiten deutlich unterscheiden, wobei die eine ein einfacher Filter ist und die andere in (wörtlichen) Randfällen ein besonderes Verhalten erfordert.
CAD97
3
@ CAD97 Die Regeln für die Groß- und Kleinschreibung sind die beiden Aufzählungszeichen, nicht das Zitat. Und der erste Aufzählungspunkt lautet "Das erste und letzte Wort wird in Großbuchstaben geschrieben." und das zweite sagt "Alle anderen Wörter werden groß geschrieben, außer ...", was bedeutet, dass das erste und das letzte Wort immer groß geschrieben werden.
Laikoni
Das habe ich irgendwie verpasst. Trotzdem danke für die Klarstellung.
CAD97
Ich bin mir nicht sicher, ob es wirklich notwendig ist, anzugeben, dass jedes Wort mindestens einen Buchstaben enthält. :)
David Conrad

Antworten:

11

Python 2, 118 Bytes

Schau ma, kein 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("'"),

Die Eingabe muss in Anführungszeichen gesetzt werden. Die Ausgabe enthält ein Leerzeichen und keine Zeilenumbrüche (ich gehe davon aus, dass das in Ordnung ist). Überprüfen Sie alle Testfälle auf Ideone .

Erläuterung

Nehmen wir die Eingabe a or anals unser Beispiel.

Mit Python 2 der `x`Abkürzung für repr, wickeln wir die Eingabe in einfachen Anführungszeichen: 'a or an'. Dann teilen wir uns Leerzeichen auf und iterieren über die Wörter.

Innerhalb der Schleife nehmen wir das repr nochmal . Für das erste und letzte Wort ergibt dies "'a"und "an'". Mit anderen Worten, es gibt 'or'. Wir möchten vermeiden, Wörter in Großbuchstaben zu schreiben, wenn sie zu dem letztgenannten Muster passen und in der Liste der Kurzwörter enthalten sind. So können wir die Wortliste als Zeichenfolge darstellen "'a'an'...'up'"und wissen, dass dierepr eines kurzen Wortes eine Teilzeichenfolge ist.

`w` in "..."gibt einen booleschen Wert an, den wir als 0oder 1zum Indizieren in die Liste behandeln können [w.title(), w]. Kurz gesagt, wir schreiben das Wort als Titel, ob es am Anfang, am Ende oder nicht in der Liste der Kurzwörter steht. Ansonsten lassen wir es in Ruhe. Zum Glück title()klappt das mit Eingaben wie erwartet immer noch 'a.

Schließlich entfernen wir einzelne Anführungszeichen aus dem Wort und drucken sie mit einem Leerzeichen nach.

DLosc
quelle
8

05AB1E , 68 61 Bytes

7 Bytes gespart dank Adnan

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

Probieren Sie es online!

Erläuterung

“a€¤€€€›€‹€‡€†€‚€‰€„€¾€ƒ€œ€³€—š¯“ist eine Wörterbuchzeichenfolge übersetzt als 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
Emigna
quelle
2
Es wird mich immer wieder in Erstaunen versetzen, was Sie mit einer kurzen Reihe völlig unerkennbarer Zeichen erreichen können. Sieht aus wie es dann funktioniert :) +1
ElPedro
Bah! Ich bin so nah dran und finde keinen Weg, einen Charakter abzuschaben.
mbomb007
@ mbomb007: Besser beeilen Sie sich, bevor Jelly, MATL oder eine andere Sprache, die Funktionen auf Indizes anwenden kann, dazu kommt und dies unterbietet :) Ich erinnere mich an eine Sprache mit komprimiertem Regex, kann mich aber nicht erinnern, wie sie genannt wurde. Dies ist lang genug, um auch noch Golf spielen zu können.
Emigna
1
Für 62 Bytes :)
Adnan
@Adnan: Ich habe so angefangen, aber nur mit den 3-Zeichen-Wörtern (die länger endeten), aber ich habe nicht darüber nachgedacht, auch die 2-Zeichen-Wörter zu verwenden ... aanstatt €…ein zusätzliches Byte zu speichern, wenn der Vorsprung von damit :) Danke!
Emigna
7

GNU sed 81 74 73 Bytes

Beinhaltet +1 für -r

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

In der ersten Zeile wird der erste Buchstabe jedes Wortes groß geschrieben. Die zweite Option schaltet alle erforderlichen Wörter auf Kleinbuchstaben zurück.

Probieren Sie es online!

Riley
quelle
6

Retina, 69 66 Bytes

Schreiben Sie den ersten Buchstaben jedes Wortes in Großbuchstaben und ändern Sie die ausgewählten Wörter in Kleinbuchstaben, wenn sie nicht das erste oder letzte Wort sind. Am Ende der letzten Zeile steht ein Leerzeichen.

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

Probieren Sie es online aus

Dies funktioniert auch mit einem .anstelle des ersten Leerzeichens.

Es gibt viele reguläre Ausdrücke mit der gleichen Länge, aber ich kann sie nicht mehr zuschneiden ...

mbomb007
quelle
(Dieser Ansatz ist auch 69 Bytes in Pip, aber ich kann den +Trick nicht verwenden , um es zu verkürzen.)
DLosc
@ DLosc Danke. Idk, warum ich das nicht gesehen habe. Ich war nahe.
mbomb007
3

JavaScript (ES6), 141 138 135 133 Bytes

3 Bytes gespart dank 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))

Testfälle

Arnauld
quelle
3

Jelly , 58 Bytes

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

TryItOnline! oder führen Sie alle Tests durch

Wie?

Eine komprimierte Zeichenfolge mit Leerzeichen, die die Wörter trennen 47, ist 1byteweise und kostet Byte für 48Byte.

Zwei nicht getrennte komprimierte Zeichenfolgen der Wörter der Länge 2und 3(mit einem 'a' am Ende von einem) wären 40Bytes plus 2, um jedes zu teilen und 1sie für 45Bytes zu verbinden.

Eine Basis-250-Zahl, wie unten beschrieben, besteht aus 32Bytes, um sie dann 3in Basis-26 umzuwandeln, 3in das Kleinbuchstaben-Alphabet zu indizieren und 3auf das nicht verwendete Zeichen 'z'für 41Bytes aufzuteilen .

Die Suche nach Wörtern, die nicht in Großbuchstaben geschrieben werden sollen,
“Ð/ṃƇ¬þṄẊƙ€,⁽ṙƬ®OṪJ"ɦ3×kf3Ṙç%ġu’
sah folgendermaßen aus:

Nimm diese Wörter und verbinde sie mit einem Trennzeichen:
s="a an the at by for in of on to up and as but or nor"

Nächstes Label 'a'als 1, 'b'wie 2beim Separator als 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]

Wandle dies in eine Basiszahl um 26(der letzte verwendete Buchstabe ist 'y'plus eine Ziffer für das Trennzeichen, der Python-Code dafür ist:
n=sum(v*26**i for i,v in enumerate(x[::-1]))

Wandle das in eine Basiszahl um 250(benutze eine Liste für die Ziffern):

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]

Suchen Sie die Zeichen in diesen Indizes in Jellys Codepage:

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

(Anmerkung: Da die tatsächliche Umsetzung bijektiv ist, wenn balle haben 0Ziffern müßte man zuerst herunterzuzutragen)

Der Rest:

ḲŒ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`)
Jonathan Allan
quelle
2

PHP, 158 Bytes

10 Bytes von @Titus gespeichert

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);

Vorherige Version PHP, 174 Bytes

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);
Jörg Hülsermann
quelle
Das Echo in der Schleife spart 10 Bytes:foreach(...)echo" "[!$k],(condition)?$v:ucfirst($v);
Titus
2

TI-Basic, 295 + 59 + 148 = 502 Bytes

Jetzt können Sie Ihren Taschenrechner nutzen. Ideal für die schule :)

Hauptprogramm, 295 Bytes

Grundsätzlich ist der Trick , um passende Worte , so dass alle Awerden nicht amit Leerzeichen umschließen, wie ersetzen " A "mit " a ". Dies bewirkt auch automatisch, dass das erste und das letzte Wort in Großbuchstaben geschrieben bleiben, da sie auf beiden Seiten kein Leerzeichen enthalten und daher mit keinem der Wörter übereinstimmen. (Genie, richtig? Und super lang, weil Kleinbuchstaben jeweils zwei Bytes sind ...)

"("+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

Unterprogramm ( prgmQ), 59 Bytes:

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

Unterprogramm ( prgmR), 148 Bytes:

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 steht ~für Token 0x81und @stellt Token dar 0x7F. Weitere Informationen finden Sie hier .

Timtech
quelle
2

Java 7, 271 259 258 Bytes

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 & Testcode:

Probieren Sie es hier aus.

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

Ausgabe:

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 
Kevin Cruijssen
quelle
1

Groovy, 131 129

Zwei Bytes gespart dank 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()}
Krzysztof Atłasik
quelle
Schön, ich war bei 137; du gewinnst. Entfernen Sie es i->und verwenden Sie it, um 2 Bytes zu speichern. {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
Ich kenne Groovy nicht, aber wird hier wirklich das erste und letzte Wort groß geschrieben?
Emigna
@Emigna Die letzte Großschreibung beginnt mit einem der Wörter.
Magic Octopus Urn
@Emigna nicht wirklich, ich habe diese Anforderung verpasst (das letzte Wort muss groß geschrieben werden). Ich müsste meine Antwort anpassen.
Krzysztof Atłasik
Die beiden Verwendungen von .capitalize()verbrauchen eine Menge Bytes. Gibt es einen kurzen Weg, zu dem Sie einen Alias ​​erstellen können .capitalize()?
Cyoce
1

C #, 305 Bytes

Es gibt noch viel Raum für Verbesserungen, aber los geht's:

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);};
TheLethalCoder
quelle
1

Rubin, 123 117 111 102 Bytes

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

Entschuldigung für alle Änderungen - dies sollte die letzte sein.

Lee W
quelle
1

Python, 177 Bytes

Wird im Funktionsformat zum Speichern von Bytes geliefert. Dies ist keine besonders wettbewerbsfähige Antwort, aber es ist eine, die repr()oder nicht erfordertregex trickreich ist. Es ist auch versionsunabhängig; es funktioniert mit Python 2 oder 3.

Obwohl es vielleicht eine sehr regelkonforme Lösung ist.

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)
James Murphy
quelle
1

PHP, 109 142 Bytes

<?=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]));

Eine Fusion von user59178´s und mbomb007´s Antwort.

setzt den ersten Buchstaben jedes Wortes in Großbuchstaben und alle Wörter der Liste in Kleinbuchstaben, die von Leerzeichen umgeben sind.
Leider muss der Rückruf auf dem kompletten Satz funktionieren; das kostet 29 bytes.

Titus
quelle
es funktioniert nicht füra an and as at but by for in nor of on or the to up
Jörg Hülsermann
1

Schläger 353 Bytes

(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)]
         )))))

Testen:

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

Ausgabe:

"The Rule of Thumb for Title Capitalization"
rnso
quelle
1

Java 7, 431 317 311 Bytes

Danke an @KevinCruijssen für 114 Bytes.
Vielen Dank an @RosLup für das Speichern von 6 Bytes.

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

erste Antwort über 250 Bytes

 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;
    }
Zahlenknoten
quelle
1
Es war zu viel, um es in einem Kommentar zusammenzufassen, aber Sie können es so zusammenfassen: 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 Bytes ) Ich schlage vor, einen Blick darauf zu werfen, was ich als Tipps für das nächste Mal geändert habe. :) PS: Ich habe eine Antwort mit einem anderen Ansatz gepostet ( 259 Bytes ).
Kevin Cruijssen
1
Vor allem Dinge wie die, c.substring(0,1).toUpperCase()+c.substring(1,c.length())+" "die Sie zweimal gemacht haben, sollten Sie darüber nachdenken, sie irgendwie wiederzuverwenden. Und kombinierte Initialisierungen wie Sie richtig mit dem int, aber aus irgendeinem Grund nicht mit dem String. Außerdem ist das Extra nicht erforderlich, booleanwenn Sie es als int0 oder 1 speichern und dann überprüfen können >0. Und ich würde versuchen, Klammern und breakso viel wie möglich zu vermeiden ; Normalerweise gibt es einen Trick, um sie loszuwerden, wie for(f=0;f<b.length;z=c.equals(b[f++])|z>0?1:0);ich es gezeigt habe. :)
Kevin Cruijssen
1
So viel zu lernen und danke, dass Sie immer hilfsbereit sind (es lebe Nederland;)
Numberknot
1
Oh, ich habe einen Copy-Paste-Fehler gemacht. Es sollte das sein 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;}und kein Problem. :) Ich habe auch viel gelernt, als ich noch nicht mit Code-Golfen vertraut war. Ich erstelle einfach eine Liste mit jedem allgemeinen Codegolf-Tipp, den ich lerne und schaue / aktualisiere es manchmal. Aber mein Code wird immer noch viel von anderen gespielt.
Kevin Cruijssen
1
In der Zeichenfolge b [] gibt es 2 'und' ist das in Ordnung?
RosLuP
1

PHP, 117 118 112 Bytes

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

Benutzt das Verhalten von ucwords() der relevanten Wörter, die von Leerzeichen umgeben sind, und escape-Zeichen und löscht die Escape-Zeichen.

Ich habe das kopiert (a[snt]?|and|[fn]or|up|by|but|the|to|in|o[rnf]) Antwort von Jörg Hülsermann , aber da der Ansatz völlig anders ist, veröffentliche ich sie als separate Antwort.

edit: Fehler, der von Titus bemerkt wurde und 1 Byte gekostet hat. auch: 6 Bytes gespart dank seines hilfreichen Kommentars zu strtr

user59178
quelle
Speichern Sie 6 Bytes mit strtranstelle von str_replace. Oder stellen Sie den Wörtern voran <>und löschen the str_replaceund verwenden Sie die HTML-Ausgabe.
Titus
In einigen Fällen können Sie preg_filteranstelle von verwenden preg_replace. Ich habe es mit deiner Lösung nicht versucht
Jörg Hülsermann
Der reguläre Ausdruck funktioniert nicht für zwei Wörter aus der Liste in einer Reihe. Test nice try for a start. Das Ersetzen eines der Leerzeichen durch eine Zusicherung löst das (+4 Bytes).
Titus
preg_filterWürde leider am titleTestfall scheitern und nichts zurückgeben.
user59178
1

Pure bash - 253

(keine externen Programme aufgerufen) - benötigt 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

normale Ansicht mit Kommentaren

#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

Ausgabe

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
jm666
quelle
1

Japt , 71 Bytes

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

Probieren Sie es online!

Erläuterung:

£`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

Eine meiner Lieblingsfunktionen von Japt ist die String-Komprimierung, bei der die Shoco-Bibliothek verwendet wird .

Sie können eine Zeichenfolge komprimieren, indem Sie sie in Oc"{string}"→ einschließenOc"a an the at by for in of on to up and as but or nor"

Dann mit Backticks oder Od"{compressed string}"→ dekomprimierenOd"a e by f up d ¿t n"

Oliver
quelle
Die -SFlagge wurde hinzugefügt, nachdem diese Herausforderung veröffentlicht wurde, sodass Ihre aktuelle Lösung nicht konkurrierend ist. Ich denke jedoch, dass Sie das können £...+XÅ}S, was im Wettbewerb um die gleiche
Byteanzahl stehen
Inwiefern ist Shoco Ihrer Meinung nach mit der Wörterbuchkomprimierung von Jelly vergleichbar?
Robert Fraser
@RobertFraser Im Vergleich zu Jelly ist es nicht sehr gut, Zeichenfolgen aus englischen Wörtern zu komprimieren, aber es ist sehr gut, Zeichenfolgen aus willkürlichen Kleinbuchstaben zu komprimieren, was manchmal nützlich ist.
ETHproductions
1

Pure bash - 205 192 181 Bytes

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
}

Wie die Antwort von jm66 tc akzeptiert die Standardeingabe.

agc
quelle
0

Eigentlich 79 Bytes

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

Probieren Sie es online!

Erläuterung:

' ,ÿ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
Mego
quelle
0

Batch, 323 Bytes

@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%

Mit Kommentaren:

@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%
Neil
quelle