将字符串转换为小写(没有内置的转换函数!)


25

该代码高尔夫球的目标是创建一个代码,该代码允许用户输入ASCII字符串(仅包含可打印的ASCII字符),并且程序将输出此字符串的小写字母。

重要提示:不允许使用将字符串(或仅一个字符)转换为小写的内置函数(例如ToLower().NET,strtolower()PHP等)!但是,您可以使用所有其他内置函数。

另外要注意:输入字符串不包含大写字符。输入字符串是大写字符,小写字符,数字和其他ASCII可打印字符的混合。

祝好运!


4
不幸的是,我必须选择退出。我不是初学者。
约翰·德沃夏克

@Jan:好吧,对于初学者,我的意思是说它的技能水平是“初学者”,而不是只允许初学者进入。我删除了“初学者”一词,可以肯定的是,您可以进入。
ProgramFOX 2013年

1
是否允许使用正则表达式?只有GolfScript可以击败s/./\L\0/g
manatwork

3
@manatwork:肯定\L是内置的吗?
marinus

@manatwork:是的,允许使用正则表达式。
ProgramFOX 2013年

Answers:


21

贝壳-10

使用转换@Gowtham的Perl解决方案/bin/tr

tr A-Z a-z

样品运行:

% tr A-Z a-z <<<'Hello WORLD! @'
hello world! @

出于好奇,是什么使它成为公认的答案?Gowtham首先有10个字符的解决方案…
Ry-

1
根据对meta的讨论,似乎原因是Gowtham的解决方案是11个字符(因为-p标志算作1)。我同意,虽然,他好像它更值得被接受..
萤火虫

啊,谢谢–这很有道理。我会记住的!
Ry-

53

Python 2.7-30(严重且毫无歉意的规则滥用)

raw_input().upper().swapcase()

匿名编辑指出,您可以在 27在Python 3中为26

input().upper().swapcase()

我在这里公然滥用规则,但是...

重要提示:不允许使用将字符串(或仅一个字符)转换为小写的内置函数(例如ToLower().NET,strtolower()PHP等)!但是,您可以使用所有其他内置函数。

将使字符串变暗并将其转换为大写。然后,在一个非常不相关的方法调用中,它反转字符串的大小写-以便所有小写字母变为大写字母...并将任何大写字母交换为小写字母


1
Python 3解决方案是26个字符。
Timtech

@Timtech我无法计数。

1
这不只是无关的。这是完全无关的。
卡特·帕佩2014年

1
当遇到包含字符ß的文本时,这将产生奇怪的结果。
2014年

33

Perl - 11个10个字符。

y/A-Z/a-z/

y///tr///

实际上:

% perl -pe 'y/A-Z/a-z/' <<< 'Hello @ WORLD !'
hello @ world !

3
+1,是唯一能击败所有次要(?)真实语言的真实语言。
Behrooz

实际上是11个字符。该-p选项被计数为1
manatwork

@manatwork或应计为2:-p:)
Gowtham

如果假设-eperl -e-> perl -pe),则为1;如果假设脚本(perl-> perl -p),则为3 。
nyuszika7h 2014年

10

Befunge-98-26 22 21 19

~:''-d2*/1-!' *+,#@

依赖于一个事实,即(c-39)/261只为大写ASCII字符(假定整数除法)字符代码。对于每个字符c,请打印出来c + (((c-39)/26)==1)*' '

会话示例:

% cfunge lower.b98
hello WORLD!
hello world!
This is a TEST!!11 az AZ @[`{
this is a test!!11 az az @[`{

9

Python 3、58

print("".join(chr(ord(x)+('@'<x<'[')*32)for x in input()))

您能解释一下这是如何工作的吗?我真的对提高Python感兴趣。我不知道该如何map(ord,input())工作。
asteri

1
@JeffGohlke:map将一个函数(在本例中为ord)应用于一个互操作对象并返回一个可迭代对象。就像是的较短形式(ord(x) for x in input())
Ry-

得到它了。感谢您的解释!
asteri

1
你的回答如下精神的问题,但我遵循的问题...

非常好。击败我未发布的62长度解决方案for c in input():print([c,(chr(ord(c)+32))]['@'<c<'['],end='')。我尝试了一些map(ord,input())技巧,但是没有将真实值乘以32并将其添加到字符代码技巧中。非常好。
史蒂芬·鲁姆巴尔斯基

8

Ruby,18个字符

没什么好有趣的。

gets.tr'A-Z','a-z'

(在IRB中运行)

只是为了好玩:一个令人困惑的版本:

$,=$* *' ';$;=$,.tr'A-Z','a-z';$><<$;

像这样运行:

c:\a\ruby>lowercase.rb Llamas are AMAZING!

输出量

llamas are amazing!

7

J-30

'@Z'(]+32*1=I.)&.(a.&i.)1!:1]1

J是从右到左读取的,因此可以将其分解:

  1. 提示用户输入: 1!:1]1
  2. 在代码点空间中执行算法: &.(a.&i.)
  3. 确定每个字母的字符范围;代码点“ @”和“ Z”之间的字符被认为是大写的:1=I.
  4. 对于每个大写代码点,添加32: ]+32* ...
  5. 请注意,步骤(2)创建了一个隐式步骤(5):我们从将字符投影到整数域开始,所以现在我们完成了,将这些整数映射回字符。

显然,此特定实现只考虑了ASCII。但是该方法至少可以扩展到Unicode中的基本多语言平面。


1
真好!不幸的是,您的解决方案似乎走错了路。;-)不过应该很容易解决。(编辑:'@Z'(]+32*1=I.)&.(a.&i.)1!:1]1应该这样做)
FireFly 2013年

很好,谢谢。我还给您留下了深刻的印象,您可以自己修复该代码:J并不是目前最易访问的语言:)
Dan Bron

啊,我和J自己一起玩过。.我设法提出了u:(a.i.x)+32*1='@Z'I.x=.1!:1]1,它与您的长度相匹配,但是没那么有趣了(因为它没有使用'under')。说到这,我不了解dyadic I.,所以感谢您使用它。:-)
FireFly 2013年

凉。但是您的Befunge解决方案仍然让J击败4个字符。显然,我不能忍受这一点:)我试图通过遵循仅依靠'@'而不是'@'和'Z'的方法来查看是否缩减J解决方案。
丹·布朗

(32(23)b.])&.(3&u:),应短5个字节。
FrownyFrog


5

Golfscript-17

程序:

{..64>\91<*32*+}%

说明:

  1. {}% 将内部代码映射到字符串中的每个字符。
  2. .. 复制堆栈顶部(字符)两次。
  3. 64> 如果字符代码大于64,则为1,否则为0。
  4. \交换堆栈上的两个项目(获取信函的第二份副本,并将结果存储64>在位置2中)。
  5. 91< 检查字符代码是否小于91。类似于步骤3。
  6. *将步骤3和5的结果相乘。如果两个步骤都为真,则仅等于1。
  7. 32* 将步骤6的结果与32相乘。如果步骤6为1,则结果为32,否则为0。
  8. + 将结果(32或0)添加到字符代码上。

输出示例:

echo HelLO @ WorLD | ruby golfscript.rb upper_to_lower.gs
hello @ world

4

Perl:24个字符

s/[A-Z]/chr 32+ord$&/ge

样品运行:

bash-4.1$ perl -pe 's/[A-Z]/chr 32+ord$&/ge' <<< 'Hello @ WORLD !'
hello @ world !

下摆,为什么chr ord?我很确定您在阅读我的回答时不会学到任何东西;-)
F. Hauri 2013年

神奇的把戏,@ F.Hauri!
manatwork 2013年

@ nyuszika7h,+ 1是-p命令行参数,而不是换行符。
manatwork 2014年

哦,对不起。
nyuszika7h 2014年

3

巨蟒(33)

如有疑问,请使用外壳。

import os;os.system('tr A-Z a-z')

遗憾的是,这仍然比Lego的解决方案更长。


+1确实不是您正在使用的Python内置程序。仅适用于linux,但仍然非常规则!!!

tr我想,@ LegoStormtroopr可以在任何地方工作,只要在被调用的shell路径上有一个命令(做正确的事)即可。
圣保罗Ebermann

3

德尔菲

const
  UpChars:set of AnsiChar = ['A'..'Z'];
var
  I: Integer;
begin
  SetLength(Result, Length(pString));
  for I := 1 to length(pstring) do
    Result[i] := AnsiChar((Integer(pString[i] in UpChars))*(Ord(pString[i])+32));
  WriteLn(Result);
end;

3
这不是高尔夫。您难道不觉得这件作品与其他作品有很大不同吗?

1
@ray Golfing旨在使您的代码尽可能短。德尔福不是打高尔夫球的好语言。我自己使用了delphi,尽管我不太可能赢得与delphi一起打高尔夫球的机会,但挑战自己仍然很有趣。
Teun Pronk

3

的JavaScript的-109 104(ES6:95)

感谢一些正确的版本。

a=prompt();for(b=[i=0];c=a.charCodeAt(i);)b[i++]=String.fromCharCode(c|(c>64&c<91)*32);alert(b.join(""))

如果浏览器支持ES6函数表达式,则可以使用以下功能:

alert(prompt().split("").map(c=>String.fromCharCode(c.charCodeAt()|(c>"@"&c<"[")*32)).join(""))

第一个代码不起作用(在FF和Chrome中测试),因为尝试在字符串的长度后获取字符时,您会得到undefined,然后c.charCodeAt()失败,因为未定义的没有charCodeAt。工作实例105个字符:a=prompt();for(b=[i=0];c=a.charCodeAt(i);)b[i++]=String.fromCharCode(c|(c>64&&c‌​<91)*32);alert(b.join(''))
一些

@some oops,我想知道我是怎么想到这个代码片段的。我很确定自己已经测试了该代码,也许我复制了一个不起作用的版本。无论如何,感谢您的纠正。
FireFly 2013年

用位and而不是逻辑的...好!
一些

一个甚至更ES6溶液(79): L=s=>[String.fromCharCode(c.charCodeAt()|(c>"@"&c<"[")*32)for(c of s)].join('')。用法:L('SoMeTeXt')
Florent 2014年

真好!不过,我不确定将其仅用作功能,因为所有其他解决方案都是“适当”的程序。尽管如此,for..of无论如何都很好用。
FireFly 2014年

3

Perl 18

s/[A-Z]/$&|" "/eg

就像是:

perl -pe 's/[A-Z]/$&|" "/eg'  <<<'are NOT allowed to: ToLower() in .NET, strtolower() in PHP'
are not allowed to: tolower() in .net, strtolower() in php

perl -pe 's/[A-Z]/$&|" "/eg' <<< "The input string Doesn't cOntaIn...( C0D3-@01F. ;-)"
the input string doesn't contain...( c0d3-@01f. ;-)

对于@FireFly

perl -pe 's/[A-Z]/$&|" "/eg' <<< "Doesn't this translate @ to \` and [\]^_ to {|}~DEL? "
doesn't ... @ to ` and [\]^_ to {|}~del? 

没有。

更通用:反正18个字符:

s/[A-Z]/$&|" "/eg

s/[A-Z]/$&^" "/eg

这不会改变任何状态:

perl -pe 's/[A-Z]/$&^" "/eg' <<< "Doesn't ... @ to \` and [\]^_ to {|}~DEL? "
doesn't ... @ to ` and [\]^_ to {|}~del? 

所有的工作很好,但改变的好处|(或)由^(XOR)是同样的语法可以用于toLowertoUpperswapCase

toUpper:

perl -pe 's/[a-z]/$&^" "/eg' <<< "Doesn't ... @ to \` and [\]^_ to {|}~DEL? "
DOESN'T ... @ TO ` AND [\]^_ TO {|}~DEL? 

和swapCase (18 + 1 = 19个字符)

perl -pe 's/[a-z]/$&^" "/egi' <<< "Doesn't ... @ to \` and [\]^_ to {|}~DEL? "
dOESN'T ... @ TO ` AND [\]^_ TO {|}~del? 

我忘了+1,因为-p对不起@manatwork
F. Hauri

这难道不是翻译@到BACKTICK和[\]^_{|}~DEL?就在这里棘手的部分..
萤火虫

1
@FireFly不,$&必须匹配[A-Z]
F. Hauri 2013年

哦,我的坏。那么,太酷了!
FireFly 2013年

3

JavaScript 80

"X".replace(/[A-Z]/g,function($){return String.fromCharCode($.charCodeAt()+32)})

(76如果您移除 "X")

with prompt and alert - 92

alert(prompt().replace(/[A-Z]/g,function($){return String.fromCharCode($.charCodeAt()+32)}))

fiddle

thanks to @FireFly @some @C5H8NNaO4 and @minitech


Er, you'd need to wrap the second argument to replace with function($){return ...}, no? By the way, the first param to the replacement function is the matched string, so you could drop the parens in the regex.
FireFly

How would i go about running it,like this?
C5H8NNaO4

@C5H8NNaO4 str(code here)
Math chiller

6
I think all (or at least most) answers in here read from stdin and print to stdout. From what I gather the convention is to use prompt and alert for I/O in JS.
FireFly

1
You need a /g flag for this to work properly.
Ry-

2

R

71 characters:

chartr(paste(LETTERS,collapse=""),paste(letters,collapse=""),scan(,""))

83 characters:

a=as.integer(charToRaw(scan(,"")))
b=a%in%(65:90)
a[b]=a[b]+32
rawToChar(as.raw(a))

That's 86 characters - newlines count as 2 characters. (string-functions.com/length.aspx)
Timtech

@Timtech: In R you can replace newlines in code by ; so no they count just for one character. It could be written: a=as.integer(charToRaw(scan(,"")));b=a%in%(65:90);a[b]=a[b]+32;rawToChar(as.raw(a))
plannapus

Yes, now I realized. I read up on meta... seems that only on Windows that newlines are 2 characters (I was using a program to measure the length of my code).
Timtech



2

PHP (42)

Run from the command line:

-R'echo@str_ireplace($a=range(a,z),$a,$argn);'

-R and the single quotes are not counted.


If you follow Gowtham's Peal solution, you would only count 42 characters.
eisberg

1
@eisberg: Updated the score, leaving a 43-character version in the history in case of any dispute.
PleaseStand

str_ireplace does case insensitive search, which is stretching the rules, if not breaking them.
ugoren

@ugoren I do not think so. As it is clearly stated that only build in function changing the case are not allowed and this is ignoring the case not changing it.
eisberg

2

PowerShell: 69 65 64

I've tried a half-dozen ways to get Replace to work the way I want it to without using the long [regex]::Replace syntax, but I haven't had any luck. If anyone else has an idea of what might work, please do suggest it.

Golfed code:

[regex]::Replace((read-host),"[A-Z]",{[char](32+[char]"$args")})

Changes from original:

  • Rearranged last argument so that [int] is no longer needed, per suggestion in comments.

Explanation:

(read-host) gets the user input.

[regex]::Replace(...) tells PowerShell to use RegEx matching to perform replacement operations on a string.

"[A-Z]" matches all uppercase letters.

{...} tells PowerShell to use a script to determine the replacement value.

[char]"$args" takes the current match and types it as an ASCII character.

32+ converts the character to an integer, representing the ASCII code, and increases the value by 32 - which would match ASCII code of the corresponding lowercase letter.

[char](...) takes the resulting value and converts it back to an ASCII character.

Demo of original:

enter image description here

(Current version tested - screenshot not yet posted.)


1
Haven't checked on how to get around that [regex]::Replace, but you can save 4 chars by changing [int] to +
goric

1
Actually, the whole last argument can be rearranged to {[char](32+[char]"$args")}, which removes the need to explicitly cast to int and shaves off one more character
goric

@goric Geez, why didn't I think of that already? Still learning, I guess.
Iszi

2

k2, 15 bytes

I am super late to this one, but I found this cool anyway.

{_ci 32+_ic x}'

Also:

Pyth, 10 bytes

Doesn't really count because Pyth was created after this was posted. Still cool.

jkmC+32Cdw

2

05AB1E, 3 bytes

u.š

Port of @user8777 Python 3 answer.

Try it online.

Explanation:

u    # Convert the (implicit) input to uppercase
   # Switch the case (upper to lower and vice-versa)
     # (and output the result implicitly)

But without any case-altering builtins:

05AB1E, 12 11 bytes

ÇIS.u32*+çJ

-1 byte thanks to @Emigna.

Try it online.

Explanation:

Ç            # Get the unicode values of each character of the (implicit) input-String
 IS          # Get the input-string, split to characters again
   .u        # Check for each if it's uppercase or not (1 if truthy; 0 if falsey)
     32*     # Multiply that result by 32 (32 if truhy; 0 if falsey)
        +    # Add it to all the unicode values at the same indices in the list
         ç   # Convert the now modified unicode values back to characters
          J  # And join all characters together to a string again
             # (which is output implicitly as result)

1
ÇIS.u32*+çJ saves a byte on your 12-byte version.
Emigna

@Emigna Ah, smart. I had tried the .u32*+ approach like this: εÇy.u32*+ç]J, but unfortunately ç wraps the characters in a list, so an additional J or ` was required after the ç..
Kevin Cruijssen

1

Javascript, 105

prompt().split("").map(function(a){c=a.charCodeAt(0);return String.fromCharCode(c|(c-64?32:0))}).join("")

Actually ther was no output form specified, so run it in console Yea, JavaScript really is verbose with charcode <-> string


1
c.charCodeAt() -- it defaults to 0 if an index is omitted. Also, breaks on '@' I believe (it gets "lowercased" into backtick)
FireFly

@FireFly Nice, Thanks!, ok i'll gonna fix it =)
C5H8NNaO4

1

Ruby: 66

def l(s)s.bytes.map{|b|(65..90).include?(b)?b+32:b}.pack('c*');end

1

C# - 108

class P{static void Main(string[]a){foreach(var c in a[0])System.Console.Write(
(char)(c>64&&c<91?c+32:c));}}

About 70 for just the method body.

Add 5 chars to include a LF/CR in the output:

class P{static void Main(string[]a){foreach(var c in a[0]+"\n")System.Console.Write(
(char)(c>64&&c<91?c+32:c));}}

A LINQ version would be shorter:

class P{static void Main(string[]a){a[0].Any(c=>System.Console.Write(
(char)(c>64&&c<91?32+c:c))is P);}}

(103) .. except that it requires using System.Linq; (total: 121).


1

Haskell - 58

p x|(elem x['A'..'Z'])=[x..]!!32|1<2=x
main=interact$map p

1

Python 3 - 70

Updated for OP's changes.

I'm a Python newbie, so any critique is welcome.

print("".join(chr(ord(c)+32) if 64<ord(c)<91 else c for c in input()))

I'm sorry, I had to say that you're not allowed to use a to-lower function on one character. Question updated.
ProgramFOX

1
Please see my recent comment: your code does only work if the input string contains only uppercase characters, but please note that it also contain other ASCII characters such as lowercase characters and numbers.
ProgramFOX

Okay, will update when I get home
asteri

@ProgramFOX Updated.
asteri

Jeff, check out @minitechs answer. You both have very similar approaches so you should be able to see how, and why his answer is shorter.

1

Perl, 9 + 1 (for -p flag) = 10

$_="\L$_"

\L was specifically asked about and allowed, because even though it's a built-in, it's not a function.


1

Powershell, 53 49 bytes

-4 bytes thanks @AdmBorkBork

-join($args|% t*y|%{[char](32*($_-in65..90)+$_)})

Test script:

$f = {

-join($args|% t*y|%{[char](32*($_-in65..90)+$_)})

}

@(
    ,("Hello WORLD from PowerShell", "hello world from powershell")
) | % {
    $a,$e = $_
    $r = &$f $a
    "$($r-eq$e): $r"
}

Output:

True: hello world from powershell

cool! ¯\_(ツ)_/¯
mazzy

1

8086 machine code, 14 bytes

Assembled:

AC 3C 41 7C 06 3C 5A 7F 02 0C 20 AA E2 F2

Unassembled listing:

 ; Lowercase a string
 ; Input: string: SI, length: CX
 ; Output: string: DI
 TOLOW  MACRO   
        LOCAL _LOOP, _STORE
       _LOOP:
 AC         LODSB           ; load byte from [SI] into AL, advance SI 
 3C 41      CMP  AL, 'A'    ; is char less than 'A'? 
 7C 06      JL   _STORE     ; if so, do not convert 
 3C 5A      CMP  AL, 'Z'    ; is char greater than 'Z'? 
 7F 02      JG   _STORE     ; if so, do not convert 
 0C 20      OR   AL, 020H   ; lowercase the char 
       _STORE:
 AA         STOSB           ; store char to [DI], advance DI 
 E2 F2      LOOP _LOOP      ; continue loop through string 

Implemented as a MACRO (essentially a function). Input string in SI, length in CX. Output string in DI.

Output from PC DOS test program:

enter image description here

Download and test TOLOW.COM example program.


where is the 14 byte count coming from? the snippet is longer than that, even without comments... is 14 bytes the compiled program?
Jonah

1
@Jonah The byte opcode is in the lefthand column, AC 3C 41, etc. I'll add the assembled hex byte code to the top for clarity. codegolf.meta.stackexchange.com/a/12340/84624
640KB
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.