区分大小写(非常)的字符串更有趣


28

受此挑战(或更具体地说,是通过误读)的启发,我提出了以下挑战:

给定输入字符串S,请颠倒所有大写字符和所有小写字符的顺序。保留所有非字母字符。例如:

你好,世界!

请注意,大写字母W(第一个大写字母)被替换为H(最后一个)。小写字母也一样:“ d”(第一个)被e(最后一个)交换,l(第二个)被l(pen-ultimate)替换……所有非字母字符都保留在原位。

输入值

  • 输入是仅包含32-126范围内的ASCII字符的字符串。
  • 保证输入的字符长度至少为1个字符,并且不会超出您的语言限制。

输出量

  • 相同的字符串,并按说明交换字符。

附加规则

  • 禁止出现标准漏洞
  • 答案必须是完整的程序或功能,而不是摘要或REPL条目。
  • ,最短答案(以字节为单位)获胜。

测试用例

A
A

Ok
Ok

OK
KO

Hello, World!
Wdlro, Holle!

0123456789
0123456789

The quick brown Fox jumps over the lazy doge
Feg odyza lehtr Tev ospmu jxon wor bkci uqeh

odd
ddo

racecar
racecar

EtOn Em OsN R AaToNsIsIhT!!1!
ThIs Is NoT A RaNsOmEnOtE!!1!

您可能要包括一个2个字符的测试用例,最初我的原始解决方案对此失败。(通过免费更改.+为固定.*
ETHproductions's

“懒惰的总督”使我想起了这一点:youtube.com/watch?
v=W

Answers:


5

MATL,14个字节

2:"t@Y2myy)Pw(

在MATL Online上尝试

说明

        % Impicitly grab input as a string
2:      % Push the array [1, 2] to the stack
"       % For each value in this array
  t     % Duplicate the top element of the stack (S)
  @     % Get the current loop index
  Y2    % Load the predefined literal 1Y2 ('ABC...Z') on the first loop
        % and the predefined literal 2Y2 ('abc...z') on the second loop (M)
  m     % Create a logical array the length of S that is TRUE when a character is in the
        % array M and FALSE otherwise (B)
  yy    % Make a copy of both S and B
  )     % Grab just the letters of S that were in M using B as an index
  P     % Reverse this array
  w     % Flip the top two stack elements
  (     % Assign them back into the string
        % Implicit end of for loop and implicit display

1
做得好!我只有2:"tttXk>f)5MP(Yo17个字节
路易斯·门多

11

视网膜,19字节

Retina没有直接的方法来反转字符串,但是我们可以通过利用排序阶段来做到这一点:

O^#`[a-z]
O^#`[A-Z]

排序(O与给定正则表达式匹配的所有字符串进行),将其读取为数字(#),然后颠倒顺序(^)(第一行为小写字母,第二行为大写字母)。

之所以起作用,是因为当我们尝试将没有数字字符的字符串读取为数字时,会将它们视为0,因此所有字符都具有相同的排序值。由于排序是稳定的,因此它们将以相同的顺序保留,并且反转它们将返回反转的原始字符串。

在线尝试!


10

佩尔,45个字节

44个字节的代码+ -p标志。

for$c(u,l){@T=/\p{L$c}/g;s/\p{L$c}/pop@T/ge}

在线尝试!

Unicode字符分类\p{Lu}\p{Ll}分别匹配大写和小写字母。
因此,/\p{L$c}/将返回所有大写(或小写)字母的列表(并将其存储在中@T)。
然后,正则表达式s/\p{$c}/pop@T/ge将通过的最后一个字母替换每个(上,然后小写)字母@T而从取出@T


7

JavaScript(ES6),74 73 71 70字节

f=
s=>(g=r=>s=s.replace(r,_=>a.pop(),a=s.match(r)))(/[A-Z]/g,g(/[a-z]/g))
<input oninput=o.textContent=f(this.value)><pre id=o>

编辑:由于@Arnauld,节省了1个字节。


4
知道有更好的方法……
ETHproductions '17

5

JavaScript(ES6),92个字节

s=>(F=(r,s)=>s.replace(r,([x],a,y)=>y+F(r,a)+x))(/[a-z](.*)([a-z])/,F(/[A-Z](.*)([A-Z])/,s))

必须一种方法可以利用正则表达式之间的相似性...

测试片段


这是否假设该函数已分配给名为的变量f?那不应该在字节数中吗?
steenbergh

@steenbergh该函数是匿名的,可以将其命名为任意名称
Kritixi Lithos

1
@steenbergh不,这是一个匿名函数,它将创建另一个函数,F然后递归调用两次。外部函数实际上在任何时候都不会自行调用。
ETHproductions'2

为什么.*在正则表达式中使用括号?
路加福音

@Luke捕获这些字符(the a中的字符([x],a,y)=>
ETHproductions

4

Perl 6的75 69个字节

{my @a=.comb;@(grep $_,@a).&{@$_=[R,] $_} for /<:Lu>/,/<:Ll>/;[~] @a}

怎么运行的

  1. my @a=.comb;
    将字符串拆分为字符,然后将它们存储在数组中。

  2. for /<:Lu>/,/<:Ll>/
    对于分别匹配大写和小写字母的两个正则表达式...

    • @(grep $_,@a)
      获取所有与正则表达式匹配的数组条目的一部分。

    • .&{@$_=[R,] $_}
      将切片的背面分配给自身。

  3. [~] @a
    连接修改后的数组以再次形成字符串,然后返回它。


通过从@Dada的解决方案中窃取使用Unicode类而不是字符范围的想法来获得-6个字节。


3

果冻,14字节

nŒlT,Ṛ$yJịŒsµ⁺

在线尝试!

怎么运行的

nŒlT,Ṛ$yJịŒsµ⁺  Main link. Argument: s (string)

 Œl             Convert to lowercase.
n               Test for inequality.
   T            Truth; yield all indices of 1's.
    ,Ṛ$         Pair with its reverse. Yields [A, B] (pair of lists).
        J       Indices; yield I := [1, ..., len(s)].
       y        Translate; replace the integers of I that occur in A with the
                corresponding integers in B.
          Œs    Swapcase; yield s with swapped case.
         ị      Use the translated index list to index into s with swapped case.
            µ   Combine all links to the left into a chain.
             ⁺   Duplicate the chain, executing it twice.

不要挑剔,
Gizmo

@Gizmo Jelly使用代码页。有关更多信息,请参见此元文章
Suever

@Suever哦,这很整洁,今天学到了一些东西^。^
Gizmo

3

Bash + Unix实用程序,122 121字节

f()(p=[^$1*
v="\)\([$1\)\("
for((n=99;n;n--)){
q="$q;s/^\($p$v.*$v$p\)$/\1\4\3\2\5/"
p=[^$1*[$1$p
}
sed $q)
f a-z]|f A-Z]

在线尝试!

不是很短;也许有人可以进一步打高尔夫球。

在stdin上输入,在stdout上输出。

少于200个字符的输入将正确运行。

(实际上,它可以正确处理任何少于200个小写字母和少于200个大写字母的字符串。)

如果将代码中的99增加到102(增加一个字节),它将处理最多205个字符的字符串。

但是,您不能将代码中的99增加到102以上,因为这将超过sed的最大参数长度。

这是一个没有任何特定输入大小限制的版本,但计数稍长一些,为137个字节。(此较长版本将写入名为t的辅助文件。)

f()(p=[^$1*
v="\)\([$1\)\("
for((n=`wc -c<t`;n;n--)){
sed -i "s/^\($p$v.*$v$p\)$/\1\4\3\2\5/" t
p=[^$1*[$1$p
})
cat>t
f a-z]
f A-Z]
cat t

测试运行:

for x in A Ok OK 'Hello, World!' 0123456789 'The quick brown Fox jumps over the lazy doge' odd racecar 'EtOn Em OsN R AaToNsIsIhT!!1!'
  do
    echo "$x"
    ./swapping3 <<<"$x"
    echo
  done

A
A

Ok
Ok

OK
KO

Hello, World!
Wdlro, Holle!

0123456789
0123456789

The quick brown Fox jumps over the lazy doge
Feg odyza lehtr Tev ospmu jxon wor bkci uqeh

odd
ddo

racecar
racecar

EtOn Em OsN R AaToNsIsIhT!!1!
ThIs Is NoT A RaNsOmEnOtE!!1!

有趣的是,它在TIO中失败了。☹可能取决于系统上sed安装的实现,但是对于GNU,sed您可以添加-roption并删除\所有括号的转义。
manatwork

2

Python 2,115个字节

s=input();u=str.isupper
exec"r='';i=0\nfor c in s:r+=c[u(c):]or filter(u,s)[~i];i+=u(c)\ns=r.swapcase();"*2
print s

在线尝试!


您可以用\ n代替\ n吗?
蒂姆(Tim)

很不幸的是,不行。参数的exec解析方式与通常的Python代码一样,因此for循环必须位于其自己的行上。
丹尼斯,

2

Java(OpenJDK 8),271字节

s->new String(new Error(){char[]o=s.toCharArray();char c;int b;{while(b++<2)for(int l=0,r=o.length;l<r;l++){for(--r;r>l&&f(r);r--);for(;l<r&&f(l);l++);if(l<r){o[l]=o[r];o[r]=c;}}}boolean f(int i){c=o[i];return b>1?!Character.isUpperCase(c):!Character.isLowerCase(c);}}.o)

在线尝试!


您可以通过将其设置为lambda来节省一些字节。s->new String...
NonlinearFruit

1
@NonlinearFruit谢谢!294-> 272,还修复了在未经初始化的情况下重复使用ra1时的错误。
DmitrySamoylenko '17

欢迎来到PPCG!有些事情你仍然可以打高尔夫球:char[]o=s.toCharArray();char c;int b;char o[]=s.toCharArray(),c,b;; 两者都&&&'; 和c=o[i];return b>1?!Character.isUpperCase(c):!Character.isLowerCase(c);c=o[i];Character x=c;return b>1?!x.isUpperCase(c):!x.isLowerCase(c);总共259个字节)。而且我可能错过了一些打高尔夫球的东西。另外,如果您还没有看到它,那么阅读Java高尔夫技巧可能会很有趣。
凯文·克鲁伊森

1

R,107字节

u=utf8ToInt(scan(,''));for(i in c(65,97)){l=which(u%in%i:(i+25));u[l]=u[rev(l)]};cat(intToUtf8(u,T),sep="")

改编自我对相关挑战的回应。这比仅交换对要容易得多。我想知道我能否打些高尔夫低于100分...

在线尝试!

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.