La règle d'or pour la capitalisation du titre

30

Selon ce site, une règle générale recommandée par le US Government Printing Office Style Manual est

Mettez en majuscule tous les mots dans les titres des publications et des documents, à l'exception de a, an, the, at, by, for, in, of, on, to, up, and, as, but, or, and nor.

Ce n'est peut-être pas vrai car je ne peux pas trouver une telle recommandation dans le manuel de style , mais utilisons quand même cette règle.


Le défi

Étant donné une chaîne d'entrée composée de mots en minuscules délimités par des espaces, affichez la capitalisation de la chaîne selon les règles suivantes

  • Le premier et le dernier mot sont en majuscule.
  • Tous les autres mots sont en majuscules, sauf a , an , the , at , by , for , in , of , on , to , up , and , as , but , or , and nor .

La chaîne d'entrée contiendra au moins un mot et chaque mot contient au moins une lettre et uniquement des caractères de aà z.

C'est un défi de golf de code, essayez donc d'utiliser le moins d'octets possible dans la langue de votre choix. Vous pouvez écrire un programme complet ou une fonction pour accomplir la tâche.

Cas de test

"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
la source
1
Les mots de début / fin doivent-ils être mis en majuscule même s'ils figurent dans la liste d'exclusion? Vos exemples disent oui, mais la spécification dit simplement mettre des mots en majuscule à moins qu'ils ne soient dans la liste, et rien sur le premier / dernier mot. Notez que les deux possibilités sont distinctement différentes, l'une étant un simple filtre et la seconde nécessitant un comportement spécial dans les cas de bord (littéraux).
CAD97
3
@ CAD97 Les règles de capitalisation sont les deux puces, pas la citation. Et le premier point dit "Le premier et le dernier mot sont en majuscules". et le second dit "Tous les autres mots sont en majuscule, sauf ..." ce qui signifie que le premier et le dernier mot sont toujours en majuscule.
Laikoni
J'ai manqué ça, en quelque sorte. Encore merci d'avoir clarifié.
CAD97
Je ne suis pas sûr qu'il soit vraiment nécessaire de préciser que chaque mot contient au moins une lettre. :)
David Conrad

Réponses:

11

Python 2, 118 octets

Regardez ma, pas de 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("'"),

L'entrée doit être entourée de guillemets. La sortie a un espace de fin et aucune nouvelle ligne de fin (je suppose que c'est correct). Vérifiez tous les cas de test sur Ideone .

Explication

Prenons l'entrée a or ancomme exemple.

L' utilisation de Python 2 `x`raccourci pour reprnous envelopper l'entrée dans des guillemets simples: 'a or an'. Ensuite, nous nous séparons sur les espaces blancs et parcourons les mots.

A l' intérieur de la boucle, nous prenons le repr nouveau . Pour les premier et dernier mots, cela donne "'a"et "an'". Autrement dit, ça donne 'or'. Nous voulons éviter de mettre des mots en majuscule s'ils correspondent à ce dernier modèle et sont dans la liste des mots courts. Nous pouvons donc représenter la liste de mots comme une chaîne "'a'an'...'up'"et savoir que le reprmot court sera une sous-chaîne.

`w` in "..."donne une valeur booléenne, que nous pouvons traiter comme 0ou 1à des fins d'indexation dans la liste [w.title(), w]. En bref, on met en majuscule le mot s'il se trouve au début, à la fin ou non dans la liste des mots courts. Sinon, nous le laissons tranquille. Heureusement, title()fonctionne toujours comme prévu avec une entrée comme 'a.

Enfin, nous supprimons les guillemets simples du mot et l'imprimons avec un espace de fin.

DLosc
la source
8

05AB1E , 68 61 octets

7 octets enregistrés grâce à Adnan

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

Essayez-le en ligne!

Explication

“a€¤€€€›€‹€‡€†€‚€‰€„€¾€ƒ€œ€³€—š¯“est une chaîne de dictionnaire traduite par 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
la source
2
Il ne cesse de m'étonner de ce que vous parvenez à réaliser avec une courte chaîne de caractères totalement méconnaissables. On dirait que ça marche alors :) +1
ElPedro
Bah! Je suis si proche et je ne trouve pas de moyen de raser un personnage.
mbomb007
@ mbomb007: Mieux vaut se dépêcher avant que Jelly, MATL ou un autre langage qui puisse appliquer des fonctions aux indices ne vienne battre :) Je semble me souvenir d'un langage avec regex compressé également, mais je ne me souviens pas de son nom. C'est suffisamment long pour qu'il soit également jouable au golf.
Emigna
1
Pour 62 octets :)
Adnan
@Adnan: J'ai commencé comme ça, mais seulement avec les mots de 3 caractères (qui ont fini plus longtemps), mais je n'ai pas envisagé de prendre les mots de 2 caractères aussi ... aau lieu d' €…enregistrer un octet supplémentaire également si le plomb de avec ça :) Merci!
Emigna
7

GNU sed 81 74 73 octets

Comprend +1 pour -r

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

La première ligne met en majuscule la première lettre de chaque mot. Le second bascule tous les mots requis en minuscules.

Essayez-le en ligne!

Riley
la source
6

Rétine, 69 66 octets

Mettez en majuscule la première lettre de chaque mot, puis changez les mots sélectionnés en minuscules s'ils ne sont pas le premier ou le dernier mot. Il y a un espace à la fin de la dernière ligne.

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

Essayez-le en ligne

Cela fonctionne également avec un .au lieu du premier espace.

Il y a beaucoup de regex de même longueur, mais je ne trouve plus de moyen de les couper ...

mbomb007
la source
(Cette approche est également de 69 octets dans Pip, mais je ne peux pas utiliser l' +astuce pour la raccourcir.)
DLosc
@DLosc Merci. Je sais pourquoi je n'ai pas vu ça. J'étais fermé.
mbomb007
3

JavaScript (ES6), 141 138 135 133 octets

Sauvegardé 3 octets grâce à 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))

Cas de test

Arnauld
la source
3

Gelée , 58 octets

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

TryItOnline! ou exécutez tous les tests

Comment?

Une chaîne compressée avec des espaces séparant les mots serait des 47octets, la fractionnant coûte 1octet, pour les 48octets.

Deux chaînes compressées non séparées des mots de longueur 2et 3(avec un «a» à la fin d'un) respectivement seraient des 40octets plus 2pour les séparer et 1les joindre, pour les 45octets.

Un nombre de base 250 comme décrit ci-dessous est des 32octets, puis 3à convertir en base 26, 3à indexer dans l'alphabet en minuscules et 3à le diviser sur le caractère inutilisé ,, 'z'pour les 41octets.

Ainsi, la recherche des mots à ne pas mettre en majuscule: a
“Ð/ṃƇ¬þṄẊƙ€,⁽ṙƬ®OṪJ"ɦ3×kf3Ṙç%ġu’
été formée comme suit:

Prenez ces mots et joignez-les à un séparateur:
s="a an the at by for in of on to up and as but or nor"

Etiquette suivante 'a'as 1, 'b'as 2avec le séparateur as 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]

Convertissez-le en un 26nombre de base (la dernière lettre utilisée est 'y'plus un chiffre pour le séparateur, le code Python pour cela est:
n=sum(v*26**i for i,v in enumerate(x[::-1]))

Convertissez cela en un 250nombre de base (en utilisant une liste pour les chiffres):

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]

Recherchez les caractères de ces index dans la page de codes de jelly:

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

(Remarque: étant donné que l'implémentation réelle est bijective, s'il y bavait des 0chiffres, il faudrait d'abord les effectuer)

Le reste:

ḲŒ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
la source
2

PHP, 158 octets

10 octets enregistrés par @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);

Version précédente PHP, 174 octets

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
la source
L'écho dans la boucle économise 10 octets:foreach(...)echo" "[!$k],(condition)?$v:ucfirst($v);
Titus
2

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

Vous pouvez maintenant capitaliser sur votre calculatrice. Idéal pour l'école :)

Programme principal, 295 octets

Fondamentalement, l'astuce pour faire correspondre les mots afin que tout Ane devienne pas aest de joindre des espaces, tels que remplacer " A "par " a ". Cela permet également automatiquement que les premier et dernier mots restent en majuscule, car ils n'ont pas d'espace des deux côtés et ne correspondent donc à aucun des mots. (Génie, non? Et super long parce que les lettres minuscules font deux octets chacune ...)

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

Sous-programme ( prgmQ), 59 octets:

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

Sous-programme ( prgmR), 148 octets:

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 ~représente un jeton 0x81et @représente un jeton 0x7F, apprenez-en plus ici .

Timtech
la source
2

Java 7, 271 259 258 octets

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

Code non testé et testé:

Essayez-le ici.

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

Sortie:

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
la source
1

Groovy, 131 129

Deux octets économisés grâce à 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
la source
Sympa, j'étais à 137; Vous gagnez. Retirez-le i->et utilisez itpour économiser 2 octets. {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()}
Urne de poulpe magique du
1
Je ne connais pas Groovy mais cela capitalise-t-il vraiment le premier et le dernier mot?
Emigna
@Emigna les couvertures majuscules finales commençant par l'un des mots.
Urne de poulpe magique du
@Emigna pas vraiment, j'ai raté cette exigence (ce dernier mot doit être capitalisé). J'aurais besoin d'ajuster ma réponse.
Krzysztof Atłasik
Les deux utilisations de .capitalize()prennent beaucoup d'octets. Existe-t-il un moyen rapide de créer un alias .capitalize()?
Cyoce
1

C #, 305 octets

Il y a encore beaucoup de place à l'amélioration mais c'est parti:

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
la source
1

Ruby, 123 117 111 102 octets

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

Désolé pour toutes les modifications - ce devrait être le dernier.

Lee W
la source
1

Python, 177 octets

Livré au format de fonction à des fins d'économie d'octets. Ce n'est pas une réponse particulièrement compétitive, mais c'est une réponse qui ne nécessite repr()ni regexastuce. Il est également indépendant de la version; cela fonctionne avec Python 2 ou 3.

Bien qu'il s'agisse peut-être d'une solution très stricte.

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
la source
1

PHP, 109 142 octets

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

Une fusion de réponse user59178 et de mbomb007 .

met en majuscule la première lettre de chaque mot, puis met en minuscule tous les mots de la liste entourés d'espaces.
Malheureusement, le rappel doit opérer sur l'ensemble complet; cela coûte 29 octets.

Titus
la source
ça ne marche pasa an and as at but by for in nor of on or the to up
Jörg Hülsermann
1

Raquette 353 octets

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

Non golfé:

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

Essai:

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

Sortie:

"The Rule of Thumb for Title Capitalization"
rnso
la source
1

Java 7, 431 317 311 octets

Merci à @KevinCruijssen pour 114 octets.
Merci à @RosLup pour avoir économisé 6 octets.

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

non golfé

première réponse supérieure à 250 octets

 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
la source
1
C'était trop pour résumer dans un commentaire, mais vous pouvez le jouer à ceci: 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 octets ) Je suggère de jeter un œil à ce que j'ai changé comme conseils pour la prochaine fois. :) PS: j'ai posté une réponse avec une approche différente ( 259 octets ).
Kevin Cruijssen
1
En particulier, des choses comme celles c.substring(0,1).toUpperCase()+c.substring(1,c.length())+" "que vous avez faites deux fois devraient vous faire penser à la réutiliser d'une manière ou d'une autre. Et des initialisations combinées comme vous l'avez fait correctement avec le int, mais pour une raison quelconque, pas avec le String. De plus, pas besoin de supplément booleanlorsque vous pouvez stocker à int0 ou 1, puis le vérifier >0. Et j'essaierais d'éviter les crochets et breakautant que possible; généralement, il y a une astuce pour s'en débarrasser, comme for(f=0;f<b.length;z=c.equals(b[f++])|z>0?1:0);je l'ai montré. :)
Kevin Cruijssen
1
Tant à apprendre et merci d'être toujours utile (longue vie aux Pays-Bas;)
Numberknot
1
Oh, j'ai fait une erreur de copier-coller .. Ça devrait être ça 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;}Et pas de problème. :) J'ai aussi beaucoup appris lorsque j'étais nouveau au golf à code. Je fais juste une liste avec toutes les astuces générales de golf que j'apprends et je les regarde / mets à jour parfois. Mais mon code est encore beaucoup joué par d'autres.
Kevin Cruijssen
1
Dans la chaîne b [], il y a 2 'et' ça va?
RosLuP
1

PHP, 117 118 112 octets

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

Utilise le comportement des ucwords()mots pertinents entourés d'espaces et les échappe, puis supprime les caractères d'échappement.

J'ai copié la (a[snt]?|and|[fn]or|up|by|but|the|to|in|o[rnf])réponse de Jörg Hülsermann mais comme l'approche est complètement différente, je la poste en tant que réponse distincte.

edit: bug remarqué par Titus, le fixant coûte 1 octet. aussi: 6 octets économisés grâce à son commentaire utile sur strtr

user59178
la source
Économisez 6 octets avec strtrau lieu de str_replace. Ou ajoutez les mots avec <>et déposez the str_replaceet utilisez la sortie HTML.
Titus
Dans certains cas, vous pouvez utiliser à la preg_filterplace de preg_replace. Je ne l'ai pas essayé avec votre solution
Jörg Hülsermann
L'expression régulière ne fonctionnera pas pour deux mots de la liste d'affilée; test nice try for a start. Remplacer l'un des espaces par une assertion résout cela (+4 octets).
Titus
Malheureusement preg_filteréchouerait sur le titlecas de test, ne retournant rien.
user59178
1

Pur bash - 253

(aucun programme externe appelé) - nécessite 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

vue normale avec commentaires

#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

sortie

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
la source
1

Japt , 71 octets

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

Essayez-le en ligne!

Explication:

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

L'une de mes fonctionnalités Japt préférées est sa compression de chaîne, qui utilise le bibliothèque shoco .

Vous pouvez compresser une chaîne en l'enveloppant dans Oc"{string}"Oc"a an the at by for in of on to up and as but or nor"

Ensuite, décompressez-le avec des backticks ou Od"{compressed string}"Od"a e by f up d ¿t n"

Oliver
la source
Le -Sdrapeau a été ajouté après la publication de ce défi, votre solution actuelle n'est donc pas en concurrence. Cependant, je pense que vous pouvez le faire £...+XÅ}S, ce qui serait en concurrence pour le même nombre d'octets ( Essayez-le en ligne! )
ETHproductions
Comment shoco se compare-t-il à la compression du dictionnaire de Jelly à votre avis?
Robert Fraser
@RobertFraser Comparé à Jelly, il n'est pas très bon pour compresser des chaînes de mots anglais, mais il est très bon pour compresser des chaînes de lettres minuscules arbitraires, ce qui est parfois utile.
ETHproductions
1

Pure bash - 205 192 181 181 octets

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
}

Comme la réponse de jm66 tc accepte l'entrée standard.

agc
la source
0

En fait , 79 octets

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

Essayez-le en ligne!

Explication:

' ,ÿ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
la source
0

Lot, 323 octets

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

Avec commentaires:

@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
la source