Ogólna zasada wielkich liter

30

Zgodnie z tą witryną ogólną zasadą zalecaną przez Podręcznik stylu drukowania biurowego rządu USA jest

Wielkie słowa w tytułach publikacji i dokumentów, z wyjątkiem a, an, the, at, by, in, of, on, up, i, as, ale, lub, i nor.

Może to nie być prawda, ponieważ nie mogę znaleźć takiej rekomendacji w Podręczniku stylu , ale i tak skorzystajmy z tej reguły.


Wyzwanie

Biorąc pod uwagę ciąg wejściowy składający się ze słów pisanych małymi literami oddzielonych spacjami, wypisz wielkość liter ciągu zgodnie z następującymi regułami

  • Pierwsze i ostatnie słowo jest pisane wielką literą.
  • Wszystkie inne słowa są kapitalizowane, z wyjątkiem , , , na , przez , na , na , na , na , na , góry , i , jak , ale , albo i nie .

Łańcuch wejściowy będzie zawierał co najmniej jedno słowo, a każde słowo zawiera co najmniej jedną literę i tylko znaki od ado z.

Jest to wyzwanie polegające na kodzie golfowym, więc spróbuj użyć jak najmniej bajtów w wybranym języku. Możesz napisać pełny program lub funkcję, aby wykonać zadanie.

Przypadki testowe

"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
źródło
1
Czy słowa rozpoczynające / kończące powinny być pisane dużymi literami, nawet jeśli znajdują się na liście wykluczeń? Twoje przykłady mówią tak, ale specyfikacja mówi po prostu wielkie litery, chyba że są na liście, i nic o pierwszym / ostatnim słowie. Zauważ, że dwie możliwości są wyraźnie różne, jedna jest prostym filtrem, a druga wymaga specjalnego zachowania w (dosłownych) przypadkach krawędzi.
97 CAD
3
@ CAD97 Reguły dotyczące wielkich liter to dwa punkty, a nie cytat. A pierwszy punkt mówi: „Pierwsze i ostatnie słowo jest pisane wielką literą”. a drugi mówi „Wszystkie pozostałe słowa są pisane wielkimi literami, z wyjątkiem…”, co oznacza, że ​​pierwsze i ostatnie słowa są zawsze pisane wielkimi literami.
Laikoni
Jakoś mi tego brakowało. Mimo to dziękuję za wyjaśnienie.
97 CAD
Nie jestem pewien, czy naprawdę konieczne jest określenie, że każde słowo zawiera co najmniej jedną literę. :)
David Conrad

Odpowiedzi:

11

Python 2, 118 bajtów

Spójrz, nie ma wyrażeń regularnych!

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

Dane wejściowe muszą być ujęte w cudzysłów. Wyjście ma spację końcową i brak spacji nowej linii (zakładam, że jest w porządku). Sprawdź wszystkie przypadki testowe w Ideone .

Wyjaśnienie

Weźmy dane wejściowe a or anza nasz przykład.

Korzystanie Python 2 za `x`skrót dla repr, możemy owinąć wejście w apostrofach: 'a or an'. Następnie dzielimy się na białe znaki i powtarzamy słowa.

Wewnątrz pętli bierzemy repr ponownie . W przypadku pierwszego i ostatniego słowa daje to "'a"i "an'". Innymi słowy, daje 'or'. Chcemy unikać wielkich liter, jeśli pasują do tego ostatniego wzorca i znajdują się na liście krótkich słów. Możemy więc przedstawić listę słów jako ciąg znaków "'a'an'...'up'"i wiedzieć, że reprkażde krótkie słowo będzie podłańcuchem.

`w` in "..."daje wartość logiczną, którą możemy traktować jako 0lub 1do celów indeksowania na liście [w.title(), w]. Krótko mówiąc, w tytule wpisujemy słowo, jeśli znajduje się na początku, na końcu lub nie ma go na liście krótkich słów. W przeciwnym razie zostawiamy to w spokoju. Na szczęście title()nadal działa zgodnie z oczekiwaniami z danymi wejściowymi takimi jak 'a.

Na koniec usuwamy wszystkie pojedyncze cytaty ze słowa i drukujemy je z końcową spacją.

DLosc
źródło
8

05AB1E , 68 61 bajtów

Zaoszczędzono 7 bajtów dzięki Adnan

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

Wypróbuj online!

Wyjaśnienie

“a€¤€€€›€‹€‡€†€‚€‰€„€¾€ƒ€œ€³€—š¯“to ciąg słownika przetłumaczony jako 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
źródło
2
Nigdy nie przestaje mnie zadziwiać tym, co udało ci się osiągnąć krótkim ciągiem całkowicie nierozpoznawalnych postaci. Wygląda na to, że wtedy działa :) +1
ElPedro
Bah! Jestem tak blisko i nie mogę znaleźć sposobu na ogolenie postaci.
mbomb007,
@ mbomb007: Lepiej pospiesz się, zanim pojawi się Jelly, MATL lub inny język, który może zastosować funkcje do indeksów i pobije to :) Wydaje mi się, że pamiętam również język ze skompresowanym wyrażeniem regularnym, ale nie pamiętam, jak się nazywał. Jest to wystarczająco długo, aby nadal można było grać w golfa.
Emigna
1
Za 62 bajty :)
Adnan
@Adnan: Zacząłem tak, ale tylko ze słowami 3-znakowymi (które skończyły się dłużej), ale nie zastanawiałem się również nad słowami 2-znakowymi ... azamiast €…oszczędzać dodatkowy bajt, jeśli wiodący z tym :) Dzięki!
Emigna
7

GNU sed 81 74 73 bajtów

Obejmuje +1 za -r

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

Pierwszy wiersz zawiera wielką literę pierwszej litery każdego słowa. Drugi przełącza wszystkie wymagane słowa z powrotem na małe litery.

Wypróbuj online!

Riley
źródło
6

Retina, 69 66 bajtów

Wielką literę każdego słowa używaj wielkiej litery, a następnie zmień wybrane słowa na małe, jeśli nie są to pierwsze lub ostatnie słowo. Na końcu ostatniej linii jest spacja.

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

Wypróbuj online

Działa to również z .pierwszą spacją.

Istnieje wiele wyrażeń regularnych o tej samej długości, ale nie mogę już znaleźć sposobu na ich przycięcie ...

mbomb007
źródło
(Podejście to ma również 69 bajtów w Pipie, ale nie mogę użyć +sztuczki, aby je skrócić.)
DLosc
@DLosc Dzięki. Nie wiem, dlaczego tego nie widziałem. Byłem blisko.
mbomb007,
3

JavaScript (ES6), 141 138 135 133 bajtów

Zaoszczędzono 3 bajty dzięki 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))

Przypadki testowe

Arnauld
źródło
3

Galaretka , 58 bajtów

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

TryItOnline! lub uruchom wszystkie testy

W jaki sposób?

Skompresowany ciąg znaków ze spacjami oddzielającymi słowa to 47bajty, których podział kosztuje 1bajt dla 48bajtów.

Dwa nieseparowane skompresowane ciągi słów długości 2i 3(z literą „a” na końcu jednego) byłyby odpowiednio 40bajtami plus, 2aby je podzielić i 1połączyć, 45tworząc bajty.

Jedna podstawowa liczba 250, jak opisano poniżej, to 32bajty, a następnie 3konwersja do bazy 26, 3indeksowanie do małego alfabetu i 3dzielenie go na nieużywany znak 'z', dla 41bajtów.

Wyszukiwanie słów, które nie powinny być pisane dużymi literami:
“Ð/ṃƇ¬þṄẊƙ€,⁽ṙƬ®OṪJ"ɦ3×kf3Ṙç%ġu’
powstało w następujący sposób:

Weź te słowa i połącz je za pomocą separatora:
s="a an the at by for in of on to up and as but or nor"

Następna etykieta 'a'jako 1, 'b'jak 2w przypadku separatora jako 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]

Konwertuj to na 26liczbę podstawową (ostatnia użyta litera jest 'y'plus cyfra dla separatora, kod Pythona to:
n=sum(v*26**i for i,v in enumerate(x[::-1]))

Przekształć to w 250numer podstawowy (używając listy cyfr):

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]

Wyszukaj znaki w tych indeksach na stronie kodowej galaretki:

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

(uwaga: ponieważ faktyczna implementacja jest bijectywna, gdyby bmiał jakieś 0cyfry, trzeba by je najpierw wykonać)

Reszta:

ḲŒ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
źródło
2

PHP, 158 bajtów

10 bajtów zapisanych przez @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);

Poprzednia wersja PHP, 174 bajtów

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
źródło
Echoing w pętli pozwala zaoszczędzić 10 bajtów:foreach(...)echo" "[!$k],(condition)?$v:ucfirst($v);
Tytus
2

TI-Basic, 295 + 59 + 148 = 502 bajtów

Teraz możesz wykorzystać swój kalkulator. Idealne do szkoły :)

Program główny, 295 bajtów

Zasadniczo, sztuczka polegająca na dopasowywaniu słów, tak aby wszystko Asię nie stało, apolega na umieszczeniu w nich spacji, takich jak zamień" A " z " a ". To również automatycznie powoduje, że pierwsze i ostatnie słowa pozostają wielkimi literami, ponieważ nie mają spacji po obu stronach, a zatem nie pasują do żadnego ze słów. (Genialne, prawda? I bardzo długie, ponieważ małe litery to dwa bajty każdy ...)

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

Podprogram ( prgmQ), 59 bajtów:

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

Podprogram (prgmR ), 148 bajtów:

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 ~reprezentuje token 0x81i @reprezentuje token 0x7F, dowiedz się więcej tutaj .

Timtech
źródło
2

Java 7, 271 259 258 bajtów

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

Kod niepoznany i testowy:

Wypróbuj tutaj.

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

Wydajność:

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

Groovy, 131 129

Dwa bajty zaoszczędzone dzięki 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
źródło
Fajnie, miałem 137 lat; wygrałeś. Usuń go i->i użyj, itaby zapisać 2 bajty. {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
Nie znam Groovy, ale czy to naprawdę wielkie i pierwsze słowo?
Emigna
@Emigna, końcowe wielkie litery zaczynają się od jednego ze słów.
Magic Octopus Urn
@Emigna nie bardzo, spóźniłem się z tym wymogiem (to ostatnie słowo wymaga dużej litery). Musiałbym dostosować moją odpowiedź.
Krzysztof Atłasik
Dwa zastosowania .capitalize()zajmują dużo bajtów. Czy istnieje krótki sposób na utworzenie aliasu .capitalize()?
Cyoce,
1

C #, 305 bajtów

Wciąż dużo miejsca na ulepszenia, ale proszę bardzo:

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

Ruby, 123 117 111 102 bajtów

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

Przepraszamy za wszystkie zmiany - powinna to być ostatnia.

Lee W.
źródło
1

Python, 177 bajtów

Dostarczone w formacie funkcji do celów zapisywania bajtów. To nie jest szczególnie konkurencyjna odpowiedź, ale taka, która nie wymaga repr()ani regexoszustwa. Jest także niezależny od wersji; działa z Python 2 lub 3.

Chociaż jest to być może rozwiązanie bardzo zgodne z zasadami.

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

PHP, 109 142 bajtów

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

Połączenie odpowiedzi user59178 i mbomb007 .

wielkie litery pierwsza litera każdego słowa, następnie małe litery wszystkich słów z listy otoczone spacjami.
Niestety, wywołanie zwrotne musi działać na całym zestawie; kosztuje to 29 bajtów.

Tytus
źródło
to nie działa dlaa an and as at but by for in nor of on or the to up
Jörg Hülsermann
1

Rakieta 353 bajtów

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

Nie golfowany:

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

Testowanie:

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

Wydajność:

"The Rule of Thumb for Title Capitalization"
rnso
źródło
1

Java 7, 431 317 311 bajtów

Dzięki @KevinCruijssen za 114 bajtów.
Dzięki @RosLup za zapisanie 6 bajtów.

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

bez golfa

pierwsza odpowiedź powyżej 250 bajtów

 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;
    }
Numberknot
źródło
1
To było zbyt wiele, by podsumować w komentarzu, ale możesz pograć w golfa: 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 bajtów ) Sugeruję przyjrzeć się temu, co zmieniłem jako wskazówki na następny raz. :) PS: Wysłałem odpowiedź z innym podejściem ( 259 bajtów ).
Kevin Cruijssen
1
Szczególnie rzeczy, c.substring(0,1).toUpperCase()+c.substring(1,c.length())+" "które zrobiłeś dwa razy, powinny sprawić, że pomyślisz o ponownym użyciu. I połączone inicjalizacje, jak zrobiłeś poprawnie z int, ale z jakiegoś powodu nie z String. Nie trzeba też dodawać, booleankiedy można zapisać jako int0 lub 1, a następnie sprawdzić >0. I starałbym się unikać nawiasów i breakjak najwięcej; zazwyczaj istnieje pewien sposób, aby się ich pozbyć, tak jak for(f=0;f<b.length;z=c.equals(b[f++])|z>0?1:0);pokazałem. :)
Kevin Cruijssen
1
Tyle do nauczenia i dzięki za bycie zawsze pomocnym (niech żyje Nederland;)
Numberknot
1
Och, popełniłem błąd kopiowania i wklejenia. Powinno być to 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;}i nie ma problemu. :) Dużo się też nauczyłem, kiedy byłem nowym golfistą. Po prostu tworzę listę z każdą ogólną wskazówką dla kodegolfa, której się uczę i czasem ją szukam / aktualizuję. Ale mój kod wciąż bardzo lubi golfiści.
Kevin Cruijssen
1
W ciągu b [] są 2 'i' czy to w porządku?
RosLuP,
1

PHP, 117 118 112 bajtów

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

Wykorzystuje zachowanie ucwords() odpowiednich znaków otoczonych spacjami i unika ich, a następnie usuwa znaki specjalne.

Skopiowałem (a[snt]?|and|[fn]or|up|by|but|the|to|in|o[rnf]) Jörga Hülsermanna, ale ponieważ podejście jest zupełnie inne, zamieszczam ją jako osobną odpowiedź.

edycja: błąd zauważony przez Tytusa, naprawienie kosztuje 1 bajt. także: 6 bajtów zapisanych dzięki jego pomocnemu komentarzowi na temat strtr

użytkownik59178
źródło
Zaoszczędź 6 bajtów strtrzamiast str_replace. Lub dodaj słowa za pomocą <>i upuść the str_replacei użyj danych wyjściowych HTML.
Tytus
W niektórych przypadkach możesz użyć preg_filterzamiast preg_replace. Nie próbowałem tego z twoim rozwiązaniem
Jörg Hülsermann
Wyrażenie regularne nie będzie działać dla dwóch słów z listy z rzędu; test nice try for a start. Zastąpienie jednego ze spacji twierdzeniem rozwiązuje ten problem (+4 bajty).
Tytus
Niestety preg_filterzawiedzie w titleprzypadku testowym, nic nie zwracając.
user59178,
1

Czysty bash - 253

(bez wywoływania zewnętrznych programów) - wymaga 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

normalny widok z komentarzami

#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

wydajność

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

Japt , 71 bajtów

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

Wypróbuj online!

Wyjaśnienie:

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

Jedną z moich ulubionych funkcji Japt jest kompresja ciągów znaków, która korzysta z biblioteki shoco .

Możesz skompresować ciąg, zawijając go w Oc"{string}"Oc"a an the at by for in of on to up and as but or nor"

Następnie dekompresuj go za pomocą strzałek wstecznych lub Od"{compressed string}"Od"a e by f up d ¿t n"

Oliver
źródło
-SFlaga została dodana po to wyzwanie zostało wysłane, więc obecne rozwiązanie jest zakaz konkurowania. Myślę jednak, że możesz to zrobić £...+XÅ}S, co konkurowałoby o tę samą liczbę bajtów ( wypróbuj online! )
ETHproductions
Jak oceniasz Shoco w porównaniu z kompresją słownikową Jelly?
Robert Fraser
@RobertFraser W porównaniu do Jelly, nie jest zbyt dobry w kompresji ciągów angielskich słów, ale jest bardzo dobry w kompresji ciągów dowolnych małych liter, co czasem się przydaje.
ETHprodukcje
1

Czysty bash - 205 192 181 bajtów

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
}

Podobnie jak odpowiedź jm66 tc akceptuje standardowe dane wejściowe.

agc
źródło
0

Właściwie 79 bajtów

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

Wypróbuj online!

Wyjaśnienie:

' ,ÿ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
źródło
0

Partia, 323 bajty

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

Z komentarzami:

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