标题大写的经验法则


30

根据该站点,美国政府印刷办公室样式手册建议的一般规则是

将出版物和文档标题中的所有单词大写,但不包括“一个”,“该”,“在”,“在”,“在”,“在”,“在”,“在”,“在”,“在”,“在”,“或”,“或”和“或”上。

这可能不是正确的,因为我无法在“ 样式手册”中找到这样的建议,但是无论如何,让我们使用此规则。


挑战

给定一个输入字符串,该字符串由用空格分隔的小写单词组成,请根据以下规则输出字符串的大写字母

  • 第一个和最后一个单词大写。
  • 所有其他词大写,除了一个所述通过用于向上并且,和也不

输入字符串将包含至少一个单词,每个单词至少包含一个字母,并且仅包含从a到的字符z

这是一个代码挑战,因此,请尝试使用您选择的语言使用尽可能少的字节。您可以编写完整的程序或函数来完成任务。

测试用例

"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 '16

我以某种方式错过了。不过,感谢您的澄清。
CAD97

我不确定是否真的需要指定每个单词至少包含一个字母。:)
David Conrad

Answers:


11

Python 2,118字节

看,没有正则表达式!

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为例。

使用Python 2的`x`快捷方式repr,我们将输入括在单引号中'a or an'。然后我们在空白处分割并遍历单词。

在循环内部,我们repr 再次执行。对于第一个和最后一个词,给出"'a""an'"。换句话说,它给出'or'。如果它们适合后一种模式并且在短单词列表中,我们希望避免使用大写字母。因此,我们可以将单词列表表示为字符串,"'a'an'...'up'"并且知道repr任何短单词的都是子字符串。

`w` in "..."给出一个布尔值,我们可以将其视为01用于索引到list的目的[w.title(), w]。简而言之,如果单词在开头,结尾或不在简短单词列表中,则我们对其进行大小写转换。否则,我们将不理会它。幸运的是,使用title()仍然可以按预期工作'a

最后,我们从单词中去除所有单引号,并在其后加上空格。


8

05AB1E68 61字节

感谢Adnan,节省了7个字节

™ð¡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 '16

呸! 我是如此亲密,我找不到剃除角色的方法。
mbomb007 '16

@ mbomb007:最好在Jelly,MATL或其他可以将函数应用于索引的语言出现之前击败它:)我似乎还记得带有压缩正则表达式的语言,但不记得它叫什么。这足够长,以至于仍然可以打高尔夫球。
Emigna

1
对于62个字节:)
Adnan

@Adnan:我是这样开始的,但只用了3个字符的单词(最终用了更长的时间),但是我没有考虑采用2个字符的单词... 如果以...开头的话也a不会€…保存额外的字节:)谢谢!
Emigna

7

GNU sed 81 74 73字节

包括+1的-r

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

第一行将每个单词的首字母大写。第二个将所有必需的单词切换回小写。

在线尝试!


6

视网膜,69 66字节

将每个单词的首字母大写,如果所选单词不是第一个或最后一个单词,则将其更改为小写。最后一行的末尾有一个空格。

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

在线尝试

这也适用于.而不是第一个空格。

有很多具有相同长度的正则表达式,但是我找不到办法修剪它了。


(此方法在Pip中也是69字节,但我不能用+技巧来缩短它。)
DLosc

@DLosc谢谢。Idk为什么我没看到那个。我离得很近。
mbomb007 '16

3

的JavaScript(ES6),141个 138 135 133字节的

多亏了mbomb007,节省了3个字节

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字节。

两个未分隔的压缩字符串,分别为length 23(在末尾带有“ 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]

在jelly的代码页中的那些索引处查找字符:

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

(注意:由于实际的实现是双射的,因此如果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字节

@Titus保存的10个字节

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

2

TI-Basic,295 + 59 + 148 = 502字节

现在,您可以利用计算器了。非常适合学校:)

主程序,295字节

基本上,匹配单词以使所有单词A都不成为单词的技巧a是用空格括起来,例如replace " A "with " 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);}

取消测试的代码:

在这里尝试。

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()}
魔术章鱼缸

1
我不了解Groovy,但这真的使首尾两个字大写吗?
Emigna

@Emigna的最后一个大写字母以单词之一开头。
魔术章鱼缸

@Emigna并不是真的,我错过了这个要求(最后一个单词需要大写)。我需要调整我的anwser。
KrzysztofAtłasik'16 -10-26

两种用法.capitalize()占用大量字节。您可以使用一个简短的方法作为别名.capitalize()吗?
Cyoce '16

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

红宝石,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]));

user59178mbomb007的答案的合并。

将每个单词的第一个字母大写,然后将列表中所有单词的小写字母用空格包围。
不幸的是,回调必须在完整的集合上进行。花费29个字节。


它的工作原理不是a an and as at but by for in nor of on or the to up
约尔格Hü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)]))))

取消高尔夫:

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

不打高尔夫球

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个字节)发布了答案。
凯文·克鲁伊森

1
特别是像c.substring(0,1).toUpperCase()+c.substring(1,c.length())+" "您两次做过的事情,应该使您考虑以某种方式重新使用它。和合并的初始化一样,您可以正确地使用int,但是由于某种原因,不能使用String。另外,boolean当您可以将其存储为int0或1并进行检查时,也不需要额外的存储空间>0。而且我会尽量避免使用方括号break;通常有一个技巧可以摆脱它们,就像for(f=0;f<b.length;z=c.equals(b[f++])|z>0?1:0);我展示的那样。:)
Kevin Cruijssen '16

1
需要学习的东西太多,感谢一直以来的帮助(尼德兰万岁;)
Numberknot 16-10-27

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;},没问题。:)当我刚接触代码高尔夫时,我也学到了很多东西。我只是列出我所学的所有通用代码技巧的清单,有时会查找/更新它。但是我的代码仍然受到很多人的欢迎。
凯文·克鲁伊森

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()并转义由空格包围的相关单词,然后删除转义字符。

我复制了 (a[snt]?|and|[fn]or|up|by|but|the|to|in|o[rnf]) JörgHülsermann的答案,但是由于方法完全不同,我将其发布为单独的答案。

编辑:提多斯注意到的错误,修复它花费1个字节。还:由于他对strtr的有益评论,节省了6个字节


使用strtr代替保存6个字节str_replace。或在单词前面加上<>和放下the str_replace并使用HTML输出。
泰特斯

在某些情况下,您可以使用preg_filter代替preg_replace。我还没有和您的解决方案尝试
约尔格Hülsermann

正则表达式不能连续使用列表中的两个单词;测试nice try for a start。用断言替换空格之一可以解决该问题(+4个字节)。
泰特斯(Titus)

不幸的是preg_filtertitle测试用例上失败了,什么也不返回。
2016年

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"

然后用反引号或Od"{compressed string}"→ 解压缩Od"a e by f up d ¿t n"


-S在发布此挑战后添加了该标志,因此您当前的解决方案是不竞争的。但是,我认为您可以做到£...+XÅ}S,这将为相同的字节数竞争(在线尝试!
ETHproductions

您认为shoco与Jelly的字典压缩相比如何?
罗伯特·弗雷泽

@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%
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.