# Converting a string to lower-case (without built-in to-lower functions!)

The goal of this code-golf is to create a code that lets the user input an ASCII string (contains only printable ASCII characters), and your program outputs the lower-case variant of this string.

Important: you are NOT allowed to use a built-in function that converts the string (or just one character) to lowercase (such as ToLower() in .NET, strtolower() in PHP , ...)! You're allowed to use all other built-in functions, however.

Another important note: The input string doesn't contain only uppercase characters. The input string is a mix of uppercase characters, lowercase characters, numbers and other ASCII printable characters.

Good luck!

• unfortunately, I'll have to opt-out. I'm not a beginner. Oct 6, 2013 at 13:42
• @Jan: Well, with beginner I actually meant that the skill level of this would be 'beginner', not that only beginners would be allowed to enter. I removed the word 'beginner' and surely, you're allowed to enter. Oct 6, 2013 at 13:45
• Are regular expressions allowed? Only GolfScript could beat s/./\L\0/g. Oct 6, 2013 at 13:49
• @manatwork: surely \L is built in? Oct 6, 2013 at 13:50
• @manatwork: Yes, a regex is allowed. Oct 6, 2013 at 13:50

## 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.

# x86-16 machine code, 14 bytes

Assembled:

ac3c 417c 063c 5a7f 020c 20aa e2f2


Unassembled listing:

       _LOOP:
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


Input string in [SI], length in CX. Output string in [DI].

Output from PC DOS test program:

• where is the 14 byte count coming from? the snippet is longer than that, even without comments... is 14 bytes the compiled program? Apr 9, 2019 at 16:08
• @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 Apr 9, 2019 at 16:18

# J, 39 30 bytes

(<&91*64&<)(,:32+])}&.(a.i.])


-9 thanks to xash

Try it online!

Uses Item Amend } to choose which characters need to be lowercased and which passed through unaltered.

It applies this operation "under" conversion to ascii indexes &.(a.i.]) -- it first converts the string to the indexes of its characters, than applies the item amend transformation, then converts back.

The item amend transformation is defined by the gerund (<&91*64&<)(,:32+]). (,:32+]) defines the two possibilities: the input unaltered, or the the input shifted 32 places to the right, converting A to a, etc. (<&91*64&<) determines which integers go into which transformation category: If an integer is greater than 64 and less than 91 -- ie, the integers corresponding to ABCDEFGHIJKLMNOPQRSTUVWXYZ -- it gets shifted by 32.

• Monadic } works here neatly to choose between +32 and unaltered: Try it online!
– xash
Dec 31, 2020 at 18:41
• Very nice. I typically forget about item amend, but occasionally it's the perfect tool. Dec 31, 2020 at 18:57

# naz, 92 90 bytes

2x1v8a8m2x2v2d3m5s2x3v1x1f1r3x1v4e3x2v2g1o1f0x1x2f3x3v3l1o1f0x1x3f8a8a8a8a1o1f0x1x4f0a0x1f


Works for any null-terminated input string.

Try it online!

Explanation (with 0x instructions removed)

2x1v                   # Set variable 1 equal to 0
8a8m2x2v               # Set variable 2 equal to 64 ("@")
2d3m5s2x3v             # Set variable 3 equal to 91 ("[")
1x1f1r3x1v4e3x2v2g1o1f # Function 1
# Read a byte of input
# Goto function 4 if it equals variable 1
# Goto function 2 if it's greater than variable 2
# Otherwise, output it and call the function again
1x2f3x3v3l1o1f         # Function 2
# Goto function 3 if the register is less than variable 3
1x3f8a8a8a8a1o1f       # Function 3
# Add 32 to the register, output, and call function 1
1x4f0a                 # Function 4
# Add 0 to the register
1f                     # Call function 1


# Vyxal, 2 bytes

⇧N


Try it Online!

This is the same as the 05ab1e answer but shorter because overloads.

## Non-trivial version

kAkaĿ


Try it Online!

Funnily enough, I've used this before.

kAka    # Push "ABC...XYZ" and "abc...xyz"
Ŀ   # Transliterate input with the above strings


# Acc!!, 44 bytes

N
Count i while _ {
Write _+_/65*90/_*32
N
}


Outputs with a trailing newline. Try it online!

### Explanation

The joke's on you, OP: Acc!! doesn't even have built-in to-lower functions... >:^D

N reads a byte from stdin into the accumulator; then we loop while that value is nonzero (i.e. we haven't yet reached end-of-input). We want to add 32 to the character code iff the input is an uppercase letter--that is, if its character code is between 65 and 90. Lacking comparison operators, we use int division:

Code range | _/65 | 90/_ | (_/65)*(90/_)
-----------|------|------|--------------
32-64      | 0    | >0   | 0
65-90      | 1    | 1    | 1
90-126     | >0   | 0    | 0


Now observe that _/65 will always be either 0 or 1 for all values of _ in the range we're interested in. So we can drop the parentheses: _/65*90/_ is equivalent to (_/65*90)/_, which is 90/_ if _ is >= 65 and 0 otherwise. Thus, our conditional lowercase formula is simply _+_/65*90/_*32. We write the corresponding character, read a new one, and loop.

bash: 11 characters?

$i="This is A STRING"$ echo ${i,,} this is a string  • It's a built'in toLower function! Dec 4, 2013 at 7:55 • @F.Hauri I assume that you'd need to add this comment on most of the answers in the thread. Dec 4, 2013 at 7:58 • @F.Hauri Wrong. Thats not a built-in function. Thats a built-in case-modification operator. Sep 19, 2018 at 15:57 ## Game Maker Language, 228 Make script/function s with this code, 53 characters: a=argument0;b=string_replace_all(b,string_upper(a),a)  Then, use this 175 character code: b=get_string('','')s('a')s('b')s('c')s('d')s('e')s('f')s('g')s('h')s('i')s('j')s('k')s('l')s('m')s('n')s('o')s('p')s('q')s('r')s('s')s('t')s('u')s('v')s('w')s('x')s('y')s('z')  The input (stored in variable b), is now lowercase. # JavaScript 124 The closest I got was 124 characters... b=prompt();a=[];for(c=b.length;c--;)a[c]="@"<b[c]&"[">b[c]?String.fromCharCode(b[c].charCodeAt(0)+32):b[c];alert(a.join(""))  @Firefly, nice work with using the "map" command... I've yet to master it... Because I felt like it (I know that I'm a bit late) # Java - 162 class a{public static void main(String[]a){for(char c:(new java.util.Scanner(System.in)).nextLine().toCharArray())System.out.print((char)((c>64&&c<91)?c+32:c));}}  expanded: public class a{ public static void main(String[] a) { for (char c : (new java.util.Scanner(System.in)).nextLine().toCharArray()) { System.out.print((char) ((c > 64 && c < 91) ? c + 32 : c)); } } }  # Java - 119 class a{static{for(char c:(new java.util.Scanner(System.in)).nextLine().toCharArray())System.out.print((char)(c|32));}}  Works for every character except @ which becomes the back-tick (), and the following (foo:bar for foo becomes bar) : \:| ]:} ^:~ _:  Even though this isn't a true solution because it has 5 cases where it doesn't work, I thought it was very interesting. It takes the characters of the input and does a bitwise or with ' ' (c|32). I discovered that c^32 swaps the case when the input is only letters while solving a project euler problem. I wondered what would happen in I changed the XOR to an OR. ### Delphi XE3 (153 chars) uses System.SysUtils;var u:string;i:int8;begin readln(u);for i:=1to Length(u)do if CharInSet(u[i],['A'..'Z'])then u[i]:=Chr(Ord(u[i])+32);writeln(u);end.  Not a winner but fun to do :) ### with indent uses System.SysUtils; var u:string; i:int8; begin readln(u); for i:=1to Length(u)do if CharInSet(u[i],['A'..'Z'])then u[i]:=Chr(Ord(u[i])+32); writeln(u); end.  ## J 35 echo(+32*64&<*.95&>)&.(a.&i.)1!:1]3  Using the magical under &.. This looks up the ascii code, then adds 32 * the boolean inRange , where inRange is x>64 and x<91. The under operation automatically applies the inverse lookup afterwards, resulting in the wanted lowercase. In action:  echo(+32*64&<*.91&>)&.(a.&i.)1!:1]3 Hello World AZ! hello world az!  # Python - 9694 82 for c in input():print(chr(ord(c)-65+97),end="")if c.isupper()else print(c,end="")  Ungolfed version: for char in input(): print(chr(ord(char) - (ord("A") - ord("a"))), end="") if char.isupper() \ else print(char, end="")  • You can replace ord("A") with 65 and ord("a") with 97 to save 12 bytes. Aug 20, 2014 at 10:26 # Powershell - 81 characters ## Program: param($s);[char[]]$s|%{if($_-lt90-and$_-gt64){$n+=[char](+$_+32)}else{$n+=$_}};$n


## Example Usage:

.\lower.ps1 -s "TEST!"


## Output:

test!


## How it works:

It just adds 32 to the decimal value of the ASCII character, which is the lowercase version.
It only does this if it is within 64-90, which is all capital letters.

• I don't know where you got 63 from. That's 81 characters. mothereff.in/byte-counter Aug 20, 2014 at 10:16

## Python 3, 78 bytes

t=input()
for c in t:
x=ord(c)
if 64<x<91:t=t.replace(c,chr(x+32))
print(t)


{$[x in .Q.A;x:(.Q.A!.Q.a)[x];x]}each  # Explanation $[x in .Q.A          // If the character is in the capitals list
x:(.Q.A!.Q.a)[x]   // Create a key mapping between upper and lower case letters,
// and set x to it's pair
x]}                // else, just return the character
each               // apply to each character in string passed in


# Example

q){$[x in .Q.A;x:(.Q.A!.Q.a)[x];x]}each "LoWersWFSfdgSA" "lowerswfsfdgsa"  • {x^.Q.a .Q.A?x} for 15 bytes. – mkst Apr 27, 2020 at 11:49 • Very nice. never use lookup, was surprised to see it index non-list members as just out-of-bounds (26). Apr 28, 2020 at 0:48 # JavaScript, 58 bytes s=>s.replace(/[A-Z]/g,x=>(x.charCodeAt()-55).toString(36))  # Forth (gforth), 55 bytes : f 0 do dup i + c@ dup 65 91 within 32 * - emit loop ;  Try it online! ### Explanation Iterates through the string, for each character: • Gets the ascii value of the character • If between 65 and 90 (inclusive) add 32, else leave as is • Print the char corresponding to that value ### Code Explanation : f \ start new word definition 0 do \ start counted loop from 0 to string-length - 1 dup i + \ duplicate the string address and add the loop index c@ \ get the ascii char value at that address dup 65 91 within \ check if value is between 65 and 90 (-1 = true, 0 = false) 32 * - \ multiply result by 32 and subtract from original number emit \ output value loop \ end loop ; \ end word definition  # ><>, 17 bytes i::" @["{)${(**+o


Try it online!

# JavaScript(ES6), 92/90 bytes

prompt().split('').map(x=>String.fromCharCode((y=x.charCodeAt(),y>64&y<91)?y+32:y)).join('')

l=a=>a.split('').map(x=>String.fromCharCode((y=x.charCodeAt(),y>64&y<91)?y+32:y)).join('')


Turn the input string into a char array, turn all uppercase letters into lowercase, and turn it back into a string.(Difference between uppercase letter and lowercase letter('a'-'A') is 32, 64 is '@', 91 is '['.)

If using alerts is required, that increases the characters by 7, which means it's 99 bytes.

[^$1_=~][$$64>\91>~&[32+]?,]#  Try it online! # Julia, 28 bytes x->map(c->c+32('@'<c<'['),x)  Try it online! # ///, 113 bytes /~/\/\///Q/q~W/w~E/e~R/r~T/t~Y/y~U/u~I/i~O/o~P/p~A/a~S/s~D/d~F/f~G/g~H/h~J/j~K/k~L/l~Z/z~X/x~C/c~V/v~B/b~N/n~M/m/  Try it online! Simply replaces all the uppercase characters with lowercase. Because there's no other way to take input in ///, it is hardcoded: /~/\/\///Q/q~W/w~E/e~R/r~T/t~Y/y~U/u~I/i~O/o~P/p~A/a~S/s~D/d~F/f~G/g~H/h~J/j~K/k~L/l~Z/z~X/x~C/c~V/v~B/b~N/n~M/m/INPUT  # batch 112 bytes lower.bat @Set "s=%~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 @Set "s=!s:%%c=%%c!" @Echo(!s!  Notes: • requires cmd.exe's codepage to be 430 or 850, to change codepage, use: CHCP 430 or CHCP 850 • Must be started in the directory containing lower.bat using: Echo(Lower "String to convert"|CMD /V:On # C (gcc), 61 59 bytes -2 thanks to @ceilingcat main(i){while(i=getchar()-10)putchar(i+(i>54&i<81?42:10));}  Try it online! Ungolfed: int main(i){ while((i=getchar()) != '\n') { if(i>64&i<91){ // uppercase ASCII range is 65-92 putchar(i+32); // lowercase ASCII range is 97-122 } else { putchar(i); } } }  • @ceilingcat I totally forgot to remove those braces when golfing it down – Yelp May 9, 2021 at 19:55 # mmo (MMIX executable), 112 bytes (28 tetras) (jxd) 00000000: 98090100 98010001 00000100 e0002000 Ƭµ¢¡Ƭ¢¡¢¡¡¢¡ṭ¡ ¡ 00000010: e3ff0140 00000300 58ff0002 00000000 ẉ”¢@¡¡¤¡X”¡£¡¡¡¡ 00000020: 83010000 31ff0140 7502ff20 31ff015b ³¢¡¡1”¢@u£” 1”¢[ 00000030: 7002ff02 c0010102 a3010000 e3ff0140 p£”£Ċ¢¢£ɲ¢¡¡ẉ”¢@ 00000040: 00000601 f1fffff3 00000000 20000000 ¡¡©¢ȯ””ṙ¡¡¡¡ ¡¡¡ 00000050: 98020008 00000001 980a00ff 00000000 Ƭ£¡®¡¡¡¢Ƭ½¡”¡¡¡¡ 00000060: 00000100 980b0000 00000000 980c0001 ¡¡¢¡Ƭ¿¡¡¡¡¡¡Ƭ€¡¢  Disassembly and explanation: 98090100 lop_pre 1,0 (mmo v1, 0 tetras) 98010001 lop_loc 0,1 (start loading at next tetra) 00000100 256 (which is 256) E0002000 SETH$0,#2000           (set $0 to address of data segment) E3FF0140 0H SETL$255,2F            (set $255 to address of handle) 00000300 TRAP 0,Fread,StdIn (read in one character) 58FF0002 PBNN$0,1F              (skip next instr if not EOF)
00000000    TRAP 0,Halt,0           (quit)
83010000 1H LDBU $1,$0,0            (read that byte in)
31FF0140    CMP  $255,$1,'@'        (compare with '@')
7502FF20    ZSP  $2,$255,#20        (if greater, then set $2 to 0x20) 31FF015B CMP$255,$1,'[' (compare with '[') 7002FF02 ZSN$2,$255,$2         (unless less, clear $2) C0010102 OR$1,$1,$2           (or in $2) A3010000 STBU$1,$0,0 (store it back) E3FF0140 SETL$255,2F            (set \$255 to address of handle)
00000601    TRAP 0,Fwrite,StdOut    (write that byte out)
F1FFFFF3    JMP  0B                 (loop back)
20000000 2H OCTA Data_Segment,1     (the handle)
98020008 lop_skip 8                 (slightly cheaper than two zero tetras)
00000001                            (end of handle)
980A00FF lop_post 255               (postamble, rG = 255)
00000000
00000100                            (start execution at location 256)
980B0000 lop_stab                   (begin symbol table)
00000000                            (no symbols)
980C0001 lop_end 1                  (symtab is one tetra long)


# Japt v2.0a0, 7 bytes

r\A_c^H


Try it

# Japt, 5 bytes

Not sure it's in keeping with the spirit of the challenge, though, as it uses toUpperCase.

u c^H


Try it

# MATLAB/Octave, 29 bytes

@(x)char(x+32*(x>64).*(x<91))


Try it online!
Output to standard output variable Ans` and written to command window.