Reverse a string: Difference between revisions
→Nu: add |
|||
(234 intermediate revisions by more than 100 users not shown) | |||
Line 17: | Line 17: | ||
=={{header|0815}}== |
=={{header|0815}}== |
||
This program reverses each line of its input. |
This program reverses each line of its input. |
||
< |
<syntaxhighlight lang="0815">}:r: Start reader loop. |
||
!~>& Push a character to the "stack". |
!~>& Push a character to the "stack". |
||
<:a:=- Stop reading on newline. |
<:a:=- Stop reading on newline. |
||
Line 26: | Line 26: | ||
${~ Print the current character until it's 0. |
${~ Print the current character until it's 0. |
||
^:p: |
^:p: |
||
#:r: Read again.</ |
#:r: Read again.</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
< |
<syntaxhighlight lang="bash">echo -e "foo\nbar" | 0815 rev.0 |
||
oof |
oof |
||
rab</ |
rab</syntaxhighlight> |
||
=={{header|11l}}== |
|||
<syntaxhighlight lang="11l">reversed(string)</syntaxhighlight> |
|||
=={{header|360 Assembly}}== |
=={{header|360 Assembly}}== |
||
For maximum compatibility, this program uses only the basic instruction set (S/360) |
For maximum compatibility, this program uses only the basic instruction set (S/360) |
||
and an ASSIST macro (XPRNT) to keep the code as short as possible. |
and an ASSIST macro (XPRNT) to keep the code as short as possible. |
||
< |
<syntaxhighlight lang="360asm">* Reverse a string 21/05/2016 |
||
REVERSE CSECT |
REVERSE CSECT |
||
USING REVERSE,R13 base register |
USING REVERSE,R13 base register |
||
Line 65: | Line 68: | ||
C DC CL12'edoC attesoR' |
C DC CL12'edoC attesoR' |
||
TMP DS CL12 |
TMP DS CL12 |
||
REGEQU |
|||
END REVERSE</ |
END REVERSE</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Rosetta Code |
Rosetta Code |
||
</pre> |
</pre> |
||
This second example uses MVCIN introduced in S/370 architecture. |
|||
<syntaxhighlight lang="360asm">* Reverse a string 25/04/2020 |
|||
REVERSEI CSECT |
|||
USING REVERSEI,R13 base register |
|||
B 72(R15) skip savearea |
|||
DC 17F'0' savearea |
|||
STM R14,R12,12(R13) prolog |
|||
ST R13,4(R15) " |
|||
ST R15,8(R13) " |
|||
LR R13,R15 " |
|||
MVCIN BB,AA+L'AA-1 |
|||
XPRNT BB,L'BB print bb |
|||
L R13,4(0,R13) epilog |
|||
LM R14,R12,12(R13) " |
|||
XR R15,R15 " |
|||
BR R14 exit |
|||
AA DC CL12'edoC attesoR' a |
|||
BB DS CL(L'AA) b |
|||
REGEQU |
|||
END REVERSEI</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
Rosetta Code |
|||
</pre> |
|||
=={{header|8080 Assembly}}== |
|||
This is a routine that reverses a string with a terminator in place. |
|||
Back when the 8080 was commonly used, there wasn't really a set standard about how to store strings. |
|||
Zero-terminated strings were already in use by the C language (and therefore, programs written in it). |
|||
CP/M, on the other hand, used <code>$</code> as a string terminator. (Later versions would even allow |
|||
the programmer to set it himself with a system call!) Therefore, to allow for some flexibility, |
|||
this routine also allows you to set it yourself, using the A register. |
|||
There were other ways of representing strings, like setting the high bit of the last character to mark |
|||
the end (saves a byte per string, but halves the character set size), or prepending the length |
|||
(making it unnecessary to scan through the string to find the end, but capping string size at |
|||
255 bytes), or even storing tuples of lengths and pointers (easy for a garbage collector to manage). |
|||
These are not supported, as they would be completely different routines, though the <code>arrayrev</code> |
|||
entry point will reverse a byte array if you already have its start and end. |
|||
Unicode is not supported either. While it wouldn't be impossible to do, I think writing a full UTF-8 |
|||
implementation is beyond the scope of the task. |
|||
<syntaxhighlight lang="8080asm"> org 100h |
|||
jmp test |
|||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
|||
;; Reverse a string under HL in place |
|||
;; strrev0: reverse a zero-terminated string |
|||
;; strrev: reverse a string terminated by the value in A |
|||
;; arrayrev: reverse bytes starting at DE and ending at HL |
|||
;; Destroys a, b, d, e, h, l registers. |
|||
strrev0: xra a ; Zero A |
|||
strrev: mov d,h ; Copy string begin to DE |
|||
mov e,l |
|||
dcx h |
|||
strrev_end: inx h ; Find string end in HL |
|||
cmp m |
|||
jnz strrev_end |
|||
dcx h ; Point HL to last character |
|||
arrayrev: mov a,h ; If HL<DE, we're done |
|||
cmp d |
|||
rc |
|||
mov a,l |
|||
cmp e |
|||
rc |
|||
ldax d ; Get low character in string |
|||
mov b,m ; Get high character in string |
|||
mov m,a ; Swap them |
|||
mov a,b |
|||
stax d |
|||
inx d ; Move the low pointer up, |
|||
dcx h ; and the high pointer down |
|||
jmp arrayrev |
|||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
|||
;; Test code (CP/M): ask the user for a string, and reverse it |
|||
prompt: db " :gnirts a retne esaelP$" |
|||
bufdef: db 127, 0 |
|||
buf: ds 128 ; one extra byte that will remain 0 |
|||
newline: lxi d,newline_str |
|||
mvi c,9 |
|||
jmp 5 |
|||
newline_str: db 13, 10, "$" |
|||
test: ;; Reverse and output the prompt |
|||
mvi a,'$' ; CP/M string is $-terminated |
|||
lxi h,prompt ; Reverse the string |
|||
call strrev |
|||
lxi d,prompt ; Output the string |
|||
mvi c,9 |
|||
call 5 |
|||
;; Get input and reverse it |
|||
lxi d,bufdef |
|||
mvi c,10 |
|||
call 5 |
|||
call newline |
|||
lxi h,buf |
|||
call strrev0 ; 0-terminated due to buffer definition |
|||
;; Output reversed input |
|||
lxi h,buf |
|||
loop: mov e,m |
|||
xra a |
|||
ora e |
|||
rz ; Stop when done |
|||
mvi c,2 |
|||
push h |
|||
call 5 |
|||
pop h |
|||
inx h |
|||
jmp loop</syntaxhighlight> |
|||
=={{header|8th}}== |
=={{header|8th}}== |
||
In 8th strings are UTF-8 and the language retains characters per-se: |
In 8th strings are UTF-8 and the language retains characters per-se: |
||
< |
<syntaxhighlight lang="forth"> |
||
"abc" s:rev |
"abc" s:rev |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
<tt>"cba"</tt> |
<tt>"cba"</tt> |
||
=={{header|ACL2}}== |
=={{header|ACL2}}== |
||
< |
<syntaxhighlight lang="lisp">(reverse "hello")</syntaxhighlight> |
||
ACL2 does not support unicode. |
ACL2 does not support unicode. |
||
=={{header|Action!}}== |
|||
<syntaxhighlight lang="action!">PROC Reverse(CHAR ARRAY src,dst) |
|||
BYTE i,j |
|||
i=1 j=src(0) dst(0)=j |
|||
WHILE j>0 |
|||
DO |
|||
dst(j)=src(i) |
|||
i==+1 j==-1 |
|||
OD |
|||
RETURN |
|||
PROC Test(CHAR ARRAY src) |
|||
CHAR ARRAY dst(40) |
|||
Reverse(src,dst) |
|||
PrintF("'%S' -> '%S'%E",src,dst) |
|||
RETURN |
|||
PROC Main() |
|||
Test("Hello World!") |
|||
Test("123456789") |
|||
Test("!noitcA iratA") |
|||
RETURN</syntaxhighlight> |
|||
{{out}} |
|||
[https://gitlab.com/amarok8bit/action-rosetta-code/-/raw/master/images/Reverse_a_string.png Screenshot from Atari 8-bit computer] |
|||
<pre> |
|||
'Hello World!' -> '!dlroW olleH' |
|||
'123456789' -> '987654321' |
|||
'!noitcA iratA' -> 'Atari Action!' |
|||
</pre> |
|||
=={{header|ActionScript}}== |
=={{header|ActionScript}}== |
||
< |
<syntaxhighlight lang="actionscript">function reverseString(string:String):String |
||
{ |
{ |
||
var reversed:String = new String(); |
var reversed:String = new String(); |
||
Line 97: | Line 253: | ||
{ |
{ |
||
return string.split('').reverse().join(''); |
return string.split('').reverse().join(''); |
||
}</ |
}</syntaxhighlight> |
||
=={{header|Ada}}== |
=={{header|Ada}}== |
||
< |
<syntaxhighlight lang="ada">with Ada.Text_IO; use Ada.Text_IO; |
||
procedure Reverse_String is |
procedure Reverse_String is |
||
Line 113: | Line 269: | ||
begin |
begin |
||
Put_Line (Reverse_It (Get_Line)); |
Put_Line (Reverse_It (Get_Line)); |
||
end Reverse_String;</ |
end Reverse_String;</syntaxhighlight> |
||
=={{header|Agda}}== |
=={{header|Agda}}== |
||
Using the Agda standard library, version |
Using the Agda standard library, version 1.7 . |
||
<syntaxhighlight lang="agda"> |
|||
<lang agda2>module reverse_string where |
|||
module ReverseString where |
|||
open import Data.String |
open import Data.String using (String ; fromList ; toList) |
||
open import Data.List |
open import Data.List using (reverse) |
||
reverse-string : String → String |
|||
reverse-string s = fromList (reverse (toList s)) |
|||
</syntaxhighlight> |
|||
=={{header|Aime}}== |
=={{header|Aime}}== |
||
<syntaxhighlight lang="aime">o_(b_reverse("Hello, World!"), "\n");</syntaxhighlight> |
|||
<lang aime>text |
|||
reverse(text s) |
|||
{ |
|||
data b; |
|||
integer i; |
|||
i = length(s); |
|||
while (i) { |
|||
i -= 1; |
|||
b_insert(b, -1, s[i]); |
|||
} |
|||
return b_string(b); |
|||
} |
|||
integer |
|||
main(void) |
|||
{ |
|||
o_text(reverse("Hello, World!")); |
|||
o_byte('\n'); |
|||
return 0; |
|||
}</lang> |
|||
=={{header|ALGOL 68}}== |
=={{header|ALGOL 68}}== |
||
Line 155: | Line 290: | ||
{{works with|ALGOL 68G|Any - tested with release mk15-0.8b.fc9.i386}} |
{{works with|ALGOL 68G|Any - tested with release mk15-0.8b.fc9.i386}} |
||
{{works with|ELLA ALGOL 68|Any (with appropriate job cards) - tested with release 1.8.8d.fc9.i386}} |
{{works with|ELLA ALGOL 68|Any (with appropriate job cards) - tested with release 1.8.8d.fc9.i386}} |
||
< |
<syntaxhighlight lang="algol68">PROC reverse = (REF STRING s)VOID: |
||
FOR i TO UPB s OVER 2 DO |
FOR i TO UPB s OVER 2 DO |
||
CHAR c = s[i]; |
CHAR c = s[i]; |
||
Line 167: | Line 302: | ||
reverse(text); |
reverse(text); |
||
print((text, new line)) |
print((text, new line)) |
||
)</ |
)</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 173: | Line 308: | ||
</pre> |
</pre> |
||
=={{header|Amazing Hopper}}== |
|||
<syntaxhighlight lang="amazing hopper"> |
|||
#include <hopper.h> |
|||
main: |
|||
s="mañana será otro día" |
|||
reverse(s),strtoutf8, println |
|||
{0}return |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
aíd orto áres anañam |
|||
</pre> |
|||
=={{header|Apex}}== |
=={{header|Apex}}== |
||
< |
<syntaxhighlight lang="java"> |
||
String str = 'Hello World!'; |
String str = 'Hello World!'; |
||
str = str.reverse(); |
str = str.reverse(); |
||
system.debug(str); |
system.debug(str); |
||
</syntaxhighlight> |
|||
</lang> |
|||
== |
=={{header|APL}}== |
||
< |
<syntaxhighlight lang="apl"> ⌽'asdf' |
||
fdsa</ |
fdsa</syntaxhighlight> |
||
=={{header|AppleScript}}== |
=={{header|AppleScript}}== |
||
{{works with |AppleScript| 2.0 or newer.}} |
{{works with |AppleScript| 2.0 or newer.}} |
||
< |
<syntaxhighlight lang="applescript">reverseString("Hello World!") |
||
on reverseString(str) |
on reverseString(str) |
||
reverse of characters of str as string |
|||
end reverseString</ |
end reverseString</syntaxhighlight> |
||
'''NB.''' Since coercing lists to string involves the interpolation of the current value of AppleScript's text item delimiters between the list items, it's considered best practice to set the delimiters ''explicitly'' to their default value of <code>{""}</code> (or just <code>""</code>) before doing an operation like this, in case they've been set to something else elsewhere in the script: |
|||
=={{header|Applesoft BASIC}}== |
|||
<lang ApplesoftBasic>10 A$ = "THE FIVE BOXING WIZARDS JUMP QUICKLY" |
|||
20 GOSUB 100REVERSE |
|||
30 PRINT R$ |
|||
40 END |
|||
<syntaxhighlight lang="applescript">reverseString("Hello World!") |
|||
100 REMREVERSE A$ |
|||
110 R$ = "" |
|||
120 FOR I = 1 TO LEN(A$) |
|||
130 R$ = MID$(A$, I, 1) + R$ |
|||
140 NEXT I |
|||
150 RETURN</lang> |
|||
on reverseString(str) |
|||
=={{header|ATS}}== |
|||
set astid to AppleScript's text item delimiters |
|||
<lang ATS> |
|||
set AppleScript's text item delimiters to "" |
|||
// |
|||
set reversedString to reverse of characters of str as text |
|||
// How to compile: |
|||
set AppleScript's text item delimiters to astid |
|||
// patscc -DATS_MEMALLOC_LIBC -o string_reverse string_reverse.dats |
|||
return reversedString |
|||
// |
|||
end reverseString</syntaxhighlight> |
|||
---- |
|||
Or, if we want a polymorphic '''reverse()''' for both strings and lists, we can define it either in terms of a generic fold/reduce, or using the built-in method for lists: |
|||
<syntaxhighlight lang="applescript">-- Using either a generic foldr(f, a, xs) |
|||
#include |
|||
"share/atspre_staload.hats" |
|||
-- reverse1 :: [a] -> [a] |
|||
fun |
|||
on reverse1(xs) |
|||
string_reverse |
|||
script rev |
|||
( |
|||
on |λ|(a, x) |
|||
x: string |
|||
a & x |
|||
) : Strptr1 = let |
|||
end |λ| |
|||
// |
|||
end script |
|||
val [n:int] x = g1ofg0(x) |
|||
val y = string1_copy(x) |
|||
if class of xs is text then |
|||
val n = string1_length(x) |
|||
foldr(rev, {}, xs) as text |
|||
val (pf, fpf | p) = |
|||
else |
|||
$UNSAFE.ptr_vtake{array(char,n)}(ptrcast(y)) |
|||
foldr(rev, {}, xs) |
|||
end if |
|||
prval () = fpf(pf) |
|||
end reverse1 |
|||
// |
|||
in |
|||
$UNSAFE.castvwtp0{Strptr1}(y) |
|||
end (* end of [string_reverse] *) |
|||
-- or the built-in reverse method for lists |
|||
(* ****** ****** *) |
|||
-- reverse2 :: [a] -> [a] |
|||
implement |
|||
on reverse2(xs) |
|||
main0 () = let |
|||
if class of xs is text then |
|||
// |
|||
(reverse of characters of xs) as text |
|||
val rev = string_reverse("asdf") |
|||
else |
|||
val ((*void*)) = println! ("reverse(\"asdf\") = \"", rev, "\"") |
|||
reverse of xs |
|||
val ((*freed*)) = strptr_free (rev) |
|||
end if |
|||
// |
|||
end reverse2 |
|||
in |
|||
// nothing |
|||
end // end of [main0] |
|||
-- TESTING reverse1 and reverse2 with same string and list --------------------------------------------------------------------------- |
|||
</lang> |
|||
on run |
|||
script test |
|||
on |λ|(f) |
|||
map(f, ["Hello there !", {1, 2, 3, 4, 5}]) |
|||
end |λ| |
|||
end script |
|||
map(test, [reverse1, reverse2]) |
|||
end run |
|||
-- GENERIC FUNCTIONS --------------------------------------------------------------------------- |
|||
-- foldr :: (a -> b -> a) -> a -> [b] -> a |
|||
on foldr(f, startValue, xs) |
|||
tell mReturn(f) |
|||
set v to startValue |
|||
set lng to length of xs |
|||
repeat with i from lng to 1 by -1 |
|||
set v to |λ|(v, item i of xs, i, xs) |
|||
end repeat |
|||
return v |
|||
end tell |
|||
end foldr |
|||
-- map :: (a -> b) -> [a] -> [b] |
|||
on map(f, xs) |
|||
tell mReturn(f) |
|||
set lng to length of xs |
|||
set lst to {} |
|||
repeat with i from 1 to lng |
|||
set end of lst to |λ|(item i of xs, i, xs) |
|||
end repeat |
|||
return lst |
|||
end tell |
|||
end map |
|||
-- Lift 2nd class handler function into 1st class script wrapper |
|||
-- mReturn :: Handler -> Script |
|||
on mReturn(f) |
|||
if class of f is script then |
|||
f |
|||
else |
|||
script |
|||
property |λ| : f |
|||
end script |
|||
end if |
|||
end mReturn</syntaxhighlight> |
|||
{{Out}} |
|||
<syntaxhighlight lang="applescript">{{"! ereht olleH", {5, 4, 3, 2, 1}}, |
|||
{"! ereht olleH", {5, 4, 3, 2, 1}}}</syntaxhighlight> |
|||
=={{header|Arturo}}== |
|||
<syntaxhighlight lang="rebol">str: "Hello World" |
|||
print reverse str</syntaxhighlight> |
|||
{{out}} |
|||
<pre>dlroW olleH</pre> |
|||
=={{header|AutoHotkey}}== |
=={{header|AutoHotkey}}== |
||
; <nowiki>"Normal" version:</nowiki> |
; <nowiki>"Normal" version:</nowiki> |
||
< |
<syntaxhighlight lang="autohotkey">MsgBox % reverse("asdf") |
||
reverse(string) |
reverse(string) |
||
Line 256: | Line 455: | ||
reversed := A_LoopField . reversed |
reversed := A_LoopField . reversed |
||
Return reversed |
Return reversed |
||
}</ |
}</syntaxhighlight> |
||
; <nowiki>A ''much'' slower version:</nowiki> |
; <nowiki>A ''much'' slower version:</nowiki> |
||
< |
<syntaxhighlight lang="ahk">Reverse(String){ ; credit to Rseding91 |
||
If (A_IsUnicode){ |
If (A_IsUnicode){ |
||
SLen := StrLen(String) * 2 |
SLen := StrLen(String) * 2 |
||
Line 276: | Line 475: | ||
Return RString |
Return RString |
||
}</ |
}</syntaxhighlight> |
||
=={{header|AutoIt}}== |
=={{header|AutoIt}}== |
||
< |
<syntaxhighlight lang="autoit">#AutoIt Version: 3.2.10.0 |
||
$mystring="asdf" |
$mystring="asdf" |
||
$reverse_string = "" |
$reverse_string = "" |
||
Line 290: | Line 489: | ||
Next |
Next |
||
MsgBox(0, "Reversed string is:", $reverse_string)</ |
MsgBox(0, "Reversed string is:", $reverse_string)</syntaxhighlight> |
||
=={{header|Avail}}== |
|||
<syntaxhighlight lang="avail">"asfd" reversed</syntaxhighlight> |
|||
=={{header|AWK}}== |
=={{header|AWK}}== |
||
< |
<syntaxhighlight lang="awk">function reverse(s) |
||
{ |
{ |
||
p = "" |
p = "" |
||
Line 302: | Line 504: | ||
BEGIN { |
BEGIN { |
||
print reverse("edoCattesoR") |
print reverse("edoCattesoR") |
||
}</ |
}</syntaxhighlight> |
||
;Recursive |
;Recursive |
||
< |
<syntaxhighlight lang="awk">function reverse(s ,l) |
||
{ |
{ |
||
l = length(s) |
l = length(s) |
||
Line 313: | Line 515: | ||
BEGIN { |
BEGIN { |
||
print reverse("edoCattesoR") |
print reverse("edoCattesoR") |
||
}</ |
}</syntaxhighlight> |
||
;using split, then joining in front: |
;using split, then joining in front: |
||
< |
<syntaxhighlight lang="awk"># Usage: awk -f reverse.awk -v s=Rosetta |
||
function rev(s, i,a,r) { |
function rev(s, i,len,a,r) { |
||
split(s, a, "") |
len = split(s, a, "") |
||
#for (i in a) r = a[i] r # may not work - order is not guaranteed ! |
|||
for (i=1; i<=len; i++) r = a[i] r |
|||
return r |
return r |
||
} |
} |
||
Line 327: | Line 530: | ||
print s, "<-->", rev(s) |
print s, "<-->", rev(s) |
||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
Rosetta <--> attesoR |
Rosetta <--> attesoR |
||
Line 333: | Line 536: | ||
=={{header|Babel}}== |
=={{header|Babel}}== |
||
This example will handle UTF-8 encoded Unicode but doesn't handle combining characters. |
This example will handle UTF-8 encoded Unicode but doesn't handle combining characters. |
||
< |
<syntaxhighlight lang="babel">strrev: { str2ar ar2ls reverse ls2lf ar2str }</syntaxhighlight> |
||
*str2ar - this operator converts a UTF-8 encoded string to an array of Unicode codepoints |
*str2ar - this operator converts a UTF-8 encoded string to an array of Unicode codepoints |
||
*ar2ls - this operator converts the array to a linked-list |
*ar2ls - this operator converts the array to a linked-list |
||
Line 339: | Line 542: | ||
*ls2lf - this operator undoes the effect of ar2ls |
*ls2lf - this operator undoes the effect of ar2ls |
||
*ar2str - this operator undoes the effect of str2ar |
*ar2str - this operator undoes the effect of str2ar |
||
=={{header|BaCon}}== |
|||
<syntaxhighlight lang="freebasic">OPTION UTF8 TRUE |
|||
s$ = "asdf" |
|||
PRINT REVERSE$(s$)</syntaxhighlight> |
|||
Unicode preservation works in BaCon 3.6 and higher. |
|||
=={{header|BASIC}}== |
=={{header|BASIC}}== |
||
==={{header|Applesoft BASIC}}=== |
|||
<syntaxhighlight lang="applesoftbasic">10 A$ = "THE FIVE BOXING WIZARDS JUMP QUICKLY" |
|||
20 GOSUB 100REVERSE |
|||
30 PRINT R$ |
|||
40 END |
|||
100 REMREVERSE A$ |
|||
110 R$ = "" |
|||
120 FOR I = 1 TO LEN(A$) |
|||
130 R$ = MID$(A$, I, 1) + R$ |
|||
140 NEXT I |
|||
150 RETURN</syntaxhighlight> |
|||
==={{header|BASIC256}}=== |
|||
<syntaxhighlight lang="vb">s = "asdf" |
|||
print "'"; s; "' reversed is '"; reverse(s); "'" |
|||
end |
|||
function reverse(a) |
|||
b = "" |
|||
for i = 1 to length(a) |
|||
b = mid(a, i, 1) + b |
|||
next i |
|||
return b |
|||
end function</syntaxhighlight> |
|||
{{out}} |
|||
<pre>'asdf' reversed is 'fdsa'</pre> |
|||
==={{header|Commodore BASIC}}=== |
|||
{{works with|Commodore BASIC|3.5,7.0}} |
|||
Commodore BASIC 3.5 turned MID$ into an lvalue function, and assigning a string of the same length to MID$ replaces the characters instead of allocating a new string, so the reversal can be done in-place: |
|||
<syntaxhighlight lang="basic"> |
|||
100 INPUT "STRING";S$ |
|||
110 FOR I=1 TO INT(LEN(S$)/2) |
|||
120 : J=LEN(S$)+1-I |
|||
130 : T$=MID$(S$,I,1) |
|||
140 : MID$(S$,I,1) = MID$(S$,J,1) |
|||
150 : MID$(S$,J,1) = T$ |
|||
160 NEXT I |
|||
170 PRINT S$</syntaxhighlight> |
|||
{{Out}} |
|||
<pre>STRING? THIS IS A TEST |
|||
TSET A SI SIHT |
|||
READY.</pre> |
|||
==={{header|IS-BASIC}}=== |
|||
<syntaxhighlight lang="is-basic">100 INPUT PROMPT "String: ":TX$ |
|||
120 LET REV$="" |
|||
130 FOR I=LEN(TX$) TO 1 STEP-1 |
|||
140 LET REV$=REV$&TX$(I) |
|||
150 NEXT |
|||
160 PRINT REV$</syntaxhighlight> |
|||
==={{header|QuickBASIC}}=== |
|||
{{works with|QBasic|1.1}} |
|||
{{works with|QuickBasic|4.5}} |
{{works with|QuickBasic|4.5}} |
||
< |
<syntaxhighlight lang="qbasic">function reverse$(a$) |
||
b$ = "" |
b$ = "" |
||
for i = 1 to len(a$) |
for i = 1 to len(a$) |
||
Line 348: | Line 616: | ||
next i |
next i |
||
reverse$ = b$ |
reverse$ = b$ |
||
end function</ |
end function</syntaxhighlight> |
||
==={{header|Sinclair ZX81 BASIC}}=== |
|||
<syntaxhighlight lang="basic">10 INPUT S$ |
|||
20 LET T$="" |
|||
30 FOR I=LEN S$ TO 1 STEP -1 |
|||
40 LET T$=T$+S$(I) |
|||
50 NEXT I |
|||
60 PRINT T$</syntaxhighlight> |
|||
==={{header|True BASIC}}=== |
|||
<syntaxhighlight lang="qbasic">FUNCTION reverse$(a$) |
|||
LET b$ = "" |
|||
FOR i = 1 TO LEN(a$) |
|||
LET b$ = (a$)[i:i+1-1] & b$ |
|||
NEXT i |
|||
LET reverse$ = b$ |
|||
END FUNCTION |
|||
LET s$ = "asdf" |
|||
PRINT "'"; s$; "' reversed is '"; reverse$(s$); "'" |
|||
END</syntaxhighlight> |
|||
{{out}} |
|||
<pre>'asdf' reversed is 'fdsa'</pre> |
|||
==={{header|XBasic}}=== |
|||
{{works with|Windows XBasic}} |
|||
<syntaxhighlight lang="qbasic">PROGRAM "progname" |
|||
VERSION "0.0000" |
|||
DECLARE FUNCTION Entry () |
|||
DECLARE FUNCTION reverse$ (a$) |
|||
FUNCTION Entry () |
|||
s$ = "asdf" |
|||
PRINT "'"; s$; "' reversed is '"; reverse$(s$); "'" |
|||
END FUNCTION |
|||
FUNCTION reverse$ (a$) |
|||
b$ = "" |
|||
FOR i = 1 TO LEN(a$) |
|||
b$ = MID$(a$, i, 1) + b$ |
|||
NEXT i |
|||
RETURN b$ |
|||
END FUNCTION |
|||
END PROGRAM</syntaxhighlight> |
|||
{{out}} |
|||
<pre>'asdf' reversed is 'fdsa'</pre> |
|||
==={{header|Yabasic}}=== |
|||
<syntaxhighlight lang="vb">s$ = "asdf" |
|||
print "'", s$, "' reversed is '", reverse$(s$), "'" |
|||
end |
|||
sub reverse$(a$) |
|||
b$ = "" |
|||
for i = 1 to len(a$) |
|||
b$ = mid$(a$, i, 1) + b$ |
|||
next i |
|||
return b$ |
|||
end sub</syntaxhighlight> |
|||
{{out}} |
|||
<pre>'asdf' reversed is 'fdsa'</pre> |
|||
=={{header|Batch File}}== |
=={{header|Batch File}}== |
||
< |
<syntaxhighlight lang="dos">@echo off |
||
setlocal enabledelayedexpansion |
setlocal enabledelayedexpansion |
||
call :reverse %1 res |
call :reverse %1 res |
||
Line 367: | Line 697: | ||
set str=%str:~1% |
set str=%str:~1% |
||
set %2=%chr%!%2! |
set %2=%chr%!%2! |
||
goto loop</ |
goto loop</syntaxhighlight> |
||
=={{header|BBC BASIC}}== |
=={{header|BBC BASIC}}== |
||
< |
<syntaxhighlight lang="bbcbasic"> PRINT FNreverse("The five boxing wizards jump quickly") |
||
END |
END |
||
Line 378: | Line 708: | ||
B$ += MID$(A$,C%,1) |
B$ += MID$(A$,C%,1) |
||
NEXT |
NEXT |
||
= B$</ |
= B$</syntaxhighlight> |
||
=={{header|Beef}}== |
|||
Beef does not have a built-in Reverse method for strings, however one can 'extend' the builtin String class to provide a Reverse function. |
|||
<syntaxhighlight lang="csharp">using System; |
|||
namespace System |
|||
{ |
|||
extension String |
|||
{ |
|||
public void Reverse() |
|||
{ |
|||
int i = 0; |
|||
int j = mLength - 1; |
|||
while (i < j) |
|||
{ |
|||
Swap!(Ptr[i++], Ptr[j--]); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
namespace StringReverse |
|||
{ |
|||
class Program |
|||
{ |
|||
static void Main() |
|||
{ |
|||
String s = scope .("abcdef"); |
|||
s.Reverse(); |
|||
Console.WriteLine(s); |
|||
} |
|||
} |
|||
} |
|||
</syntaxhighlight> |
|||
=={{header|Befunge}}== |
=={{header|Befunge}}== |
||
Reads a line from stdin and write the reverse to stdout. Can be made to repeat indefinitely by removing the final <tt>@</tt> command. |
Reads a line from stdin and write the reverse to stdout. Can be made to repeat indefinitely by removing the final <tt>@</tt> command. |
||
< |
<syntaxhighlight lang="befunge">55+~>:48>*#8\#4`#:!#<#~_$>:#,_@</syntaxhighlight> |
||
=={{header|Binary Lambda Calculus}}== |
|||
This 9 byte program, featured on https://www.ioccc.org/2012/tromp/hint.html, reverses its input in byte-oriented BLC: |
|||
<pre>16 46 80 17 3e f0 b7 b0 40</pre> |
|||
=={{header|BQN}}== |
|||
BQN has a reverse builtin, given as <code>⌽</code>. |
|||
<syntaxhighlight lang="bqn"> ⌽"racecar" |
|||
"racecar"</syntaxhighlight> |
|||
=={{header|Bracmat}}== |
=={{header|Bracmat}}== |
||
< |
<syntaxhighlight lang="bracmat"> ( reverse |
||
= L x |
= L x |
||
. :?L |
. :?L |
||
Line 400: | Line 776: | ||
| str$!L |
| str$!L |
||
) |
) |
||
& out$reverse$Ελληνικά</ |
& out$reverse$Ελληνικά</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>άκινηλλΕ</pre> |
<pre>άκινηλλΕ</pre> |
||
=={{header|Brainf***}}== |
=={{header|Brainf***}}== |
||
< |
<syntaxhighlight lang="bf">[-]>,[>,]<[.<]</syntaxhighlight> |
||
Another solution: |
|||
The former wont stop taking input bytes unless a special compiler was made to stop at ENTER. |
|||
<syntaxhighlight lang="bf">,----- ----- [+++++ +++++ > , ----- -----] If a newline is hit counter will be zero and input loop ends |
|||
The following checks for 10 ascii (line feed) and stops taking input at that point |
|||
<lang bf>,----- ----- [+++++ +++++ > , ----- -----] If a newline is hit counter will be zero and input loop ends |
|||
<[.<] run all chars backwards and print them |
<[.<] run all chars backwards and print them |
||
just because it looks good we print CRLF |
just because it looks good we print CRLF |
||
+++++ +++++ +++ . --- .</ |
+++++ +++++ +++ . --- .</syntaxhighlight> |
||
=={{header|Brat}}== |
=={{header|Brat}}== |
||
< |
<syntaxhighlight lang="brat">p "olleh".reverse #Prints "hello"</syntaxhighlight> |
||
=={{header|Burlesque}}== |
=={{header|Burlesque}}== |
||
< |
<syntaxhighlight lang="burlesque"> |
||
"Hello, world!"<- |
"Hello, world!"<- |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|C}}== |
=={{header|C}}== |
||
< |
<syntaxhighlight lang="c">#include <stdio.h> |
||
#include <stdlib.h> |
#include <stdlib.h> |
||
#include <locale.h> |
#include <locale.h> |
||
Line 490: | Line 865: | ||
printf("%s => %s\n", su, mb_reverse(su)); |
printf("%s => %s\n", su, mb_reverse(su)); |
||
return 0; |
return 0; |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>abcdef => fedcba |
<pre>abcdef => fedcba |
||
Line 496: | Line 871: | ||
{{libheader|GLib}} |
{{libheader|GLib}} |
||
< |
<syntaxhighlight lang="c">#include <glib.h> |
||
gchar *srev (const gchar *s) { |
gchar *srev (const gchar *s) { |
||
if (g_utf8_validate(s,-1,NULL)) { |
if (g_utf8_validate(s,-1,NULL)) { |
||
Line 508: | Line 883: | ||
printf ("%s\n",srev(u)); |
printf ("%s\n",srev(u)); |
||
return 0; |
return 0; |
||
}</ |
}</syntaxhighlight> |
||
=={{header|C sharp}}== |
|||
C# does not have a built-in Reverse method for strings, and cannot reverse them in place because they are immutable. One way to implement this is to convert the string to an array of characters, reverse that, and return a new string from the reversed array: |
|||
<syntaxhighlight lang="csharp">static string ReverseString(string input) |
|||
{ |
|||
char[] inputChars = input.ToCharArray(); |
|||
Array.Reverse(inputChars); |
|||
return new string(inputChars); |
|||
}</syntaxhighlight> |
|||
As of .Net 3.5 the LINQ-to-objects allows the Reverse() extension method to be called on a string, since String implements the IEnumerable<char> interface. Because of this, the return type of Reverse is IEnumerable<char>. Fortunately, LINQ also provides the ToArray extension method, which can be used in conjunction with the constructor of string that accepts a char array: |
|||
<syntaxhighlight lang="csharp">using System.Linq; |
|||
// ... |
|||
return new string(input.Reverse().ToArray()); |
|||
// ...</syntaxhighlight> |
|||
'''Version supporting combining characters:''' |
|||
System.Globalization.StringInfo provides a means of separating a string into individual graphemes. |
|||
<syntaxhighlight lang="csharp">public string ReverseElements(string s) |
|||
{ |
|||
// In .NET, a text element is series of code units that is displayed as one character, and so reversing the text |
|||
// elements of the string correctly handles combining character sequences and surrogate pairs. |
|||
var elements = System.Globalization.StringInfo.GetTextElementEnumerator(s); |
|||
return string.Concat(AsEnumerable(elements).OfType<string>().Reverse()); |
|||
} |
|||
// Wraps an IEnumerator, allowing it to be used as an IEnumerable. |
|||
public IEnumerable AsEnumerable(IEnumerator enumerator) |
|||
{ |
|||
while (enumerator.MoveNext()) |
|||
yield return enumerator.Current; |
|||
}</syntaxhighlight> |
|||
=={{header|C++}}== |
=={{header|C++}}== |
||
< |
<syntaxhighlight lang="cpp">#include <string> |
||
#include < |
#include <iostream> |
||
#include <algorithm> |
#include <algorithm> |
||
int main() |
int main() { |
||
{ |
|||
std::string s; |
std::string s; |
||
std::getline(std::cin, s); |
std::getline(std::cin, s); |
||
std::reverse(s.begin(), s.end()); // modifies s |
std::reverse(s.begin(), s.end()); // modifies s |
||
std::cout << s << |
std::cout << s << '\n'; |
||
}</syntaxhighlight> |
|||
return 0; |
|||
}</lang> |
|||
=={{header|C sharp|C#}}== |
|||
C# does not have a built-in Reverse method for strings, which are immutable. One way to implement this is to convert the string to an array of characters, reverse that, and return a new string from the reversed array: |
|||
<lang csharp>private static string ReverseString(string input) |
|||
{ |
|||
char[] inputChars = input.ToCharArray(); |
|||
Array.Reverse(inputChars); |
|||
return new string(inputChars); |
|||
}</lang> |
|||
As of .Net 3.5 you can call LINQ's Reverse extension method on a string, since String implements the IEnumerable<char> interface. Because of this, the return type of Reverse is IEnumerable<char>. Fortunately, LINQ also provides the ToArray extension method, which can be used in conjunction with one of the constructors belonging to the String class which accepts an array of chars: |
|||
<lang csharp>return new string(input.Reverse().ToArray());</lang> |
|||
=={{header|Caché ObjectScript}}== |
=={{header|Caché ObjectScript}}== |
||
<pre>USER>Write $Reverse("Hello, World") |
<pre>USER>Write $Reverse("Hello, World") |
||
dlroW ,olleH</pre> |
dlroW ,olleH</pre> |
||
=={{header|Ceylon}}== |
|||
<syntaxhighlight lang="ceylon"> |
|||
shared void run() { |
|||
while(true) { |
|||
process.write("> "); |
|||
String? text = process.readLine(); |
|||
if (is String text) { |
|||
print(text.reversed); |
|||
} |
|||
else { |
|||
break; |
|||
} |
|||
} |
|||
} |
|||
</syntaxhighlight> |
|||
=={{header|Clipper}}== |
=={{header|Clipper}}== |
||
Works with versions since 5, because ''LOCAL'' variables and the ''+='' operator was not implemented before. |
Works with versions since 5, because ''LOCAL'' variables and the ''+='' operator was not implemented before. |
||
< |
<syntaxhighlight lang="clipper">FUNCTION Reverse(sIn) |
||
LOCAL sOut := "", i |
LOCAL sOut := "", i |
||
FOR i := Len(sIn) TO 1 STEP -1 |
FOR i := Len(sIn) TO 1 STEP -1 |
||
sOut += Substr(sIn, i, 1) |
sOut += Substr(sIn, i, 1) |
||
NEXT |
NEXT |
||
RETURN sOut</ |
RETURN sOut</syntaxhighlight> |
||
=={{header|Clojure}}== |
=={{header|Clojure}}== |
||
=== Basic reverse === |
|||
=== A Simple implementation with the magic of "conj" function === |
|||
<syntaxhighlight lang="lisp"> |
|||
(defn reverse-string [s] |
|||
"Returns a string with all characters in reverse" |
|||
(apply str (reduce conj '() s))) |
|||
</syntaxhighlight> |
|||
=== Other alternatives (resorting to the "reverse" function in the standard library)=== |
|||
For normal strings, the reverse function can be used to do the bulk of the work. However, it returns a character sequence, which has to be converted back to a string. |
For normal strings, the reverse function can be used to do the bulk of the work. However, it returns a character sequence, which has to be converted back to a string. |
||
< |
a) <syntaxhighlight lang="lisp">(defn str-reverse [s] (apply str (reverse s)))</syntaxhighlight> |
||
=== Reverse words in a string === |
|||
< |
b) <syntaxhighlight lang="lisp">(apply str (interpose " " (reverse (.split "the quick brown fox" " "))))</syntaxhighlight> |
||
=== Supporting combining characters === |
=== Supporting combining characters === |
||
Handling combining characters present a trickier task. We need to protect the relative ordering of the combining character and the character to its left. Thus, before reversing, the characters need to be grouped. |
Handling combining characters present a trickier task. We need to protect the relative ordering of the combining character and the character to its left. Thus, before reversing, the characters need to be grouped. |
||
< |
<syntaxhighlight lang="lisp">(defn combining? [c] |
||
(let [type (Character/getType c)] |
(let [type (Character/getType c)] |
||
;; currently hardcoded to the types taken from the sample string |
;; currently hardcoded to the types taken from the sample string |
||
Line 577: | Line 1,003: | ||
"Unicode-safe string reverse" |
"Unicode-safe string reverse" |
||
[s] |
[s] |
||
(apply str (apply concat (reverse (group s)))))</ |
(apply str (apply concat (reverse (group s)))))</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 588: | Line 1,014: | ||
user=> |
user=> |
||
</pre> |
</pre> |
||
=={{header|CLU}}== |
|||
<syntaxhighlight lang="clu">reverse = proc (s: string) returns (string) |
|||
rslt: array[char] := array[char]$predict(1,string$size(s)) |
|||
for c: char in string$chars(s) do |
|||
array[char]$addl(rslt,c) |
|||
end |
|||
return(string$ac2s(rslt)) |
|||
end reverse |
|||
start_up = proc () |
|||
po: stream := stream$primary_output() |
|||
stream$putl(po, reverse("!dlrow ,olleH")) |
|||
end start_up</syntaxhighlight> |
|||
{{out}} |
|||
<pre>Hello, world!</pre> |
|||
=={{header|COBOL}}== |
=={{header|COBOL}}== |
||
<lang |
<syntaxhighlight lang="cobol">FUNCTION REVERSE('QWERTY')</syntaxhighlight> |
||
=={{header|CoffeeScript}}== |
=={{header|CoffeeScript}}== |
||
< |
<syntaxhighlight lang="javascript">"qwerty".split("").reverse().join ""</syntaxhighlight> |
||
=={{header|ColdFusion}}== |
=={{header|ColdFusion}}== |
||
You can reverse anything that can be written to the document in hashmarks (i.e. strings, numbers, now( ), etc.). |
You can reverse anything that can be written to the document in hashmarks (i.e. strings, numbers, now( ), etc.). |
||
< |
<syntaxhighlight lang="cfm"><cfset myString = "asdf" /> |
||
<cfset myString = reverse( myString ) /></ |
<cfset myString = reverse( myString ) /></syntaxhighlight> |
||
=={{header|Common Lisp}}== |
=={{header|Common Lisp}}== |
||
<lang |
<syntaxhighlight lang="lisp">(reverse my-string)</syntaxhighlight> |
||
=={{header|Component Pascal}}== |
=={{header|Component Pascal}}== |
||
BlackBox Component Builder |
BlackBox Component Builder |
||
< |
<syntaxhighlight lang="oberon2"> |
||
MODULE BbtReverseString; |
MODULE BbtReverseString; |
||
IMPORT StdLog; |
IMPORT StdLog; |
||
Line 632: | Line 1,074: | ||
END Do; |
END Do; |
||
END BbtReverseString. |
END BbtReverseString. |
||
</syntaxhighlight> |
|||
</lang> |
|||
Execute: ^Q BbtReverseString.Do<br/> |
Execute: ^Q BbtReverseString.Do<br/> |
||
{{Out}} |
{{Out}} |
||
<pre> |
<pre> |
||
'asdf' reversed:> fdsa |
'asdf' reversed:> fdsa |
||
</pre> |
|||
=={{header|Cowgol}}== |
|||
<syntaxhighlight lang="cowgol">include "cowgol.coh"; |
|||
include "strings.coh"; |
|||
# Reverse a string in place |
|||
sub StrRev(s: [uint8]): (r: [uint8]) is |
|||
r := s; |
|||
var e := s; |
|||
while [e] != 0 loop |
|||
e := @next e; |
|||
end loop; |
|||
e := @prev e; |
|||
while e > s loop |
|||
var c := [s]; |
|||
[s] := [e]; |
|||
[e] := c; |
|||
s := @next s; |
|||
e := @prev e; |
|||
end loop; |
|||
end sub; |
|||
# Test |
|||
var buf: uint8[32]; |
|||
var str: [uint8] := "\nesreveR"; |
|||
CopyString(str, &buf[0]); |
|||
print(StrRev(&buf[0]));</syntaxhighlight> |
|||
{{out}} |
|||
<pre>Reverse</pre> |
|||
=={{header|Crystal}}== |
|||
<syntaxhighlight lang="ruby"># version 0.21.1 |
|||
strings = ["asdf", "as⃝df̅"] |
|||
strings.each do |s| |
|||
puts "#{s} -> #{s.reverse}" |
|||
end</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
asdf -> fdsa |
|||
as⃝df̅ -> f̅ds⃝a |
|||
</pre> |
</pre> |
||
=={{header|D}}== |
=={{header|D}}== |
||
< |
<syntaxhighlight lang="d">void main() { |
||
import std.range, std.conv; |
import std.range, std.conv; |
||
Line 655: | Line 1,142: | ||
dstring s4 = "hello"d; |
dstring s4 = "hello"d; |
||
assert(s4.dup.reverse == "olleh"d); // simple but inefficient (copies first, then reverses) |
assert(s4.dup.reverse == "olleh"d); // simple but inefficient (copies first, then reverses) |
||
}</ |
}</syntaxhighlight> |
||
=={{header|Dart}}== |
=={{header|Dart}}== |
||
Since Dart strings are sequences of [http://en.wikipedia.org/wiki/UTF-16 UTF-16] code units, it would not be sufficient to simply reverse the characters in strings, as this would not work with UTF-16 [http://en.wikipedia.org/wiki/UTF-16#Code_points_U.2B10000_to_U.2B10FFFF surrogate pairs] (pairs of UTF-16 code units that represent single characters [http://en.wikipedia.org/wiki/Plane_(Unicode)#Supplementary_Multilingual_Plane outside the Unicode BMP]). However, Dart provides a method to convert strings to sequences of unicode code points (called "runes" in Dart), and these sequences can easily be reversed and used to create new strings, so a string reversal function can be written with a single line of Dart code: |
Since Dart strings are sequences of [http://en.wikipedia.org/wiki/UTF-16 UTF-16] code units, it would not be sufficient to simply reverse the characters in strings, as this would not work with UTF-16 [http://en.wikipedia.org/wiki/UTF-16#Code_points_U.2B10000_to_U.2B10FFFF surrogate pairs] (pairs of UTF-16 code units that represent single characters [http://en.wikipedia.org/wiki/Plane_(Unicode)#Supplementary_Multilingual_Plane outside the Unicode BMP]). However, Dart provides a method to convert strings to sequences of unicode code points (called "runes" in Dart), and these sequences can easily be reversed and used to create new strings, so a string reversal function can be written with a single line of Dart code: |
||
< |
<syntaxhighlight lang="dart">String reverse(String s) => new String.fromCharCodes(s.runes.toList().reversed);</syntaxhighlight> |
||
A more complete example with unit tests would look like this: |
A more complete example with unit tests would look like this: |
||
< |
<syntaxhighlight lang="dart">import 'package:unittest/unittest.dart'; |
||
String reverse(String s) => new String.fromCharCodes(s.runes.toList().reversed); |
String reverse(String s) => new String.fromCharCodes(s.runes.toList().reversed); |
||
Line 680: | Line 1,167: | ||
}); |
}); |
||
}); |
}); |
||
}</ |
}</syntaxhighlight> |
||
=={{header|DBL}}== |
|||
<syntaxhighlight lang="dbl">K= |
|||
STR_OUT= |
|||
FOR J=%TRIM(STR_IN) STEP -1 UNTIL 1 |
|||
DO BEGIN |
|||
INCR K |
|||
STR_OUT(K:1)=STR_IN(J:1) |
|||
END |
|||
</syntaxhighlight> |
|||
=={{header|Dc}}== |
|||
Reversing "Hello world!" which is "22405534230753963835153736737" in Dc's numerical string representaion.<br> |
|||
Due to using "~" this example needs GNU Dc or OpenBSD Dc. |
|||
<syntaxhighlight lang="dc">22405534230753963835153736737 [ 256 ~ d SS 0<F LS SR 1+ ] d sF x 1 - [ 1 - d 0<F 256 * LR + ] d sF x P</syntaxhighlight> |
|||
<pre> |
|||
!dlrow olleH |
|||
</pre> |
|||
=={{header|Delphi}}== |
=={{header|Delphi}}== |
||
< |
<syntaxhighlight lang="delphi">function ReverseString(const InString: string): string; |
||
var |
var |
||
i: integer; |
i: integer; |
||
Line 689: | Line 1,196: | ||
for i := Length(InString) downto 1 do |
for i := Length(InString) downto 1 do |
||
Result := Result + InString[i]; |
Result := Result + InString[i]; |
||
end;</ |
end;</syntaxhighlight> |
||
You could also use this RTL function Introduced in Delphi 6: |
You could also use this RTL function Introduced in Delphi 6: |
||
<lang |
<syntaxhighlight lang="delphi">StrUtils.ReverseString</syntaxhighlight> |
||
=={{header|Déjà Vu}}== |
|||
Another alternative. |
|||
<lang dejavu>!print concat chars "Hello"</lang> |
|||
<syntaxhighlight lang="delphi"> |
|||
function Reverse(const s: string): string; |
|||
var |
|||
i, aLength, ahalfLength: Integer; |
|||
c: Char; |
|||
begin |
|||
Result := s; |
|||
aLength := Length(s); |
|||
ahalfLength := aLength div 2; |
|||
if aLength > 1 then |
|||
for i := 1 to ahalfLength do |
|||
begin |
|||
c := result[i]; |
|||
result[i] := result[aLength - i + 1]; |
|||
result[aLength - i + 1] := c; |
|||
end; |
|||
end;</syntaxhighlight> |
|||
All versions has the same perfomance, then StrUtils is recomended. |
|||
=={{header|Draco}}== |
|||
<syntaxhighlight lang="draco">/* Reverse string in place */ |
|||
proc nonrec reverse(*char s) void: |
|||
*char e; |
|||
char t; |
|||
e := s; |
|||
while e* /= '\e' do |
|||
e := e + 1 |
|||
od; |
|||
while |
|||
e := e - 1; |
|||
s < e |
|||
do |
|||
t := e*; |
|||
e* := s*; |
|||
s* := t; |
|||
s := s + 1 |
|||
od |
|||
corp |
|||
proc nonrec main() void: |
|||
*char testString = "!dlrow ,olleH"; |
|||
reverse(testString); |
|||
writeln(testString) |
|||
corp</syntaxhighlight> |
|||
{{out}} |
{{out}} |
||
<pre> |
<pre>Hello, world!</pre> |
||
=={{header|dt}}== |
|||
<syntaxhighlight lang="dt">"asdf" rev</syntaxhighlight> |
|||
=={{header|DWScript}}== |
=={{header|DWScript}}== |
||
See [[Reverse a string#Delphi|Delphi]]. |
See [[Reverse a string#Delphi|Delphi]]. |
||
=={{header|Dyalect}}== |
|||
<syntaxhighlight lang="dyalect">let str = "asdf" |
|||
func String.Reverse() { |
|||
var cs = [] |
|||
let len = this.Length() |
|||
for n in 1..len { |
|||
cs.Add(this[len - n]) |
|||
} |
|||
String(values: cs) |
|||
} |
|||
str.Reverse()</syntaxhighlight> |
|||
=={{header|Déjà Vu}}== |
|||
<syntaxhighlight lang="dejavu">!print concat chars "Hello"</syntaxhighlight> |
|||
{{out}} |
|||
<pre>olleH</pre> |
|||
=={{header|E}}== |
=={{header|E}}== |
||
[[Category:E examples needing attention]] <!-- Replacing accum, grapheme clusters --> |
[[Category:E examples needing attention]] <!-- Replacing accum, grapheme clusters --> |
||
< |
<syntaxhighlight lang="e">pragma.enable("accumulator") |
||
def reverse(string) { |
def reverse(string) { |
||
return accum "" for i in (0..!(string.size())).descending() { _ + string[i] } |
return accum "" for i in (0..!(string.size())).descending() { _ + string[i] } |
||
}</ |
}</syntaxhighlight> |
||
=={{header|EasyLang}}== |
|||
<syntaxhighlight lang="easylang"> |
|||
func$ reverse s$ . |
|||
a$[] = strchars s$ |
|||
for i = 1 to len a$[] div 2 |
|||
swap a$[i] a$[len a$[] - i + 1] |
|||
. |
|||
return strjoin a$[] |
|||
. |
|||
print reverse "hello" |
|||
</syntaxhighlight> |
|||
=={{header|EchoLisp}}== |
=={{header|EchoLisp}}== |
||
< |
<syntaxhighlight lang="lisp"> |
||
(define (string-reverse string) |
(define (string-reverse string) |
||
(list->string (reverse (string->list string)))) |
(list->string (reverse (string->list string)))) |
||
Line 716: | Line 1,304: | ||
(string-reverse "un roc lamina l animal cornu") |
(string-reverse "un roc lamina l animal cornu") |
||
→ unroc lamina l animal cor nu |
→ unroc lamina l animal cor nu |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header| |
=={{header|EGL}}== |
||
<lang |
<syntaxhighlight lang="egl">function reverse( str string ) returns( string ) |
||
result string; |
|||
{{out}} |
|||
for ( i int from StrLib.characterLen( str ) to 1 decrement by 1 ) |
|||
<pre> |
|||
result ::= str[i:i]; |
|||
"dlroW olleH" |
|||
end |
|||
</pre> |
|||
return( result ); |
|||
end</syntaxhighlight> |
|||
=={{header|Eiffel}}== |
=={{header|Eiffel}}== |
||
< |
<syntaxhighlight lang="eiffel">class |
||
APPLICATION |
APPLICATION |
||
create |
create |
||
Line 740: | Line 1,330: | ||
my_string: STRING |
my_string: STRING |
||
-- Used for reversal |
-- Used for reversal |
||
end</ |
end</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 746: | Line 1,336: | ||
</pre> |
</pre> |
||
=={{header|EGL}}== |
|||
<lang EGL>function reverse( str string ) returns( string ) |
|||
result string; |
|||
for ( i int from StrLib.characterLen( str ) to 1 decrement by 1 ) |
|||
result ::= str[i:i]; |
|||
end |
|||
return( result ); |
|||
end</lang> |
|||
=={{header|Ela}}== |
=={{header|Ela}}== |
||
< |
<syntaxhighlight lang="ela">reverse_string str = rev len str |
||
where len = length str |
where len = length str |
||
rev 0 str = "" |
rev 0 str = "" |
||
Line 761: | Line 1,343: | ||
where nn = n - 1 |
where nn = n - 1 |
||
reverse_string "Hello"</ |
reverse_string "Hello"</syntaxhighlight> |
||
{{out}}<pre>"olleH"</pre> |
{{out}}<pre>"olleH"</pre> |
||
Line 767: | Line 1,349: | ||
Another approach is to covert a string to a list, reverse a list and then convert it back to a string: |
Another approach is to covert a string to a list, reverse a list and then convert it back to a string: |
||
< |
<syntaxhighlight lang="ela">open string |
||
fromList <| reverse <| toList "Hello" ::: String</ |
fromList <| reverse <| toList "Hello" ::: String</syntaxhighlight> |
||
=={{header|Elena}}== |
=={{header|Elena}}== |
||
ELENA 4.x: |
|||
<lang elena>#import system. |
|||
<syntaxhighlight lang="elena">import system'routines; |
|||
import extensions; |
|||
import extensions'text; |
|||
#class(extension) extension |
|||
extension extension |
|||
{ |
{ |
||
reversedLiteral() |
|||
= self |
= self.toArray().sequenceReverse().summarize(new StringWriter()); |
||
} |
} |
||
public program() |
|||
{ |
|||
console |
console.printLine("Hello World".reversedLiteral()) |
||
}</syntaxhighlight> |
|||
].</lang> |
|||
{{out}} |
|||
<pre> |
|||
dlroW olleH |
|||
</pre> |
|||
=={{header|Elixir}}== |
=={{header|Elixir}}== |
||
Elixir handles Unicode graphemes correctly by default. |
Elixir handles Unicode graphemes correctly by default. |
||
< |
<syntaxhighlight lang="elixir"> |
||
IO.puts (String.reverse "asdf") |
IO.puts (String.reverse "asdf") |
||
IO.puts (String.reverse "as⃝df̅") |
IO.puts (String.reverse "as⃝df̅") |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{Out}} |
{{Out}} |
||
<pre> |
<pre> |
||
Line 797: | Line 1,384: | ||
f̅ds⃝a |
f̅ds⃝a |
||
</pre> |
</pre> |
||
=={{header|Elm}}== |
=={{header|Elm}}== |
||
<syntaxhighlight lang="elm">module Main exposing (main) |
|||
<lang elm>-- The import on the next line provides the reverse string |
|||
-- functionality satisfying the rosettacode.org task description. |
|||
import String exposing (reverse) |
|||
import Html exposing (Html, text, div, p) |
|||
-- The rest is fairly boilerplate code demonstrating |
|||
import Html.Attributes exposing (style) |
|||
-- interactively that the reverse function works. |
|||
import Html exposing (Html, Attribute, text, div, input) |
|||
import Html.Attributes exposing (placeholder, value, style) |
|||
import Html.Events exposing (on, targetValue) |
|||
import Html.App exposing (beginnerProgram) |
|||
main = beginnerProgram { model = "", view = view, update = update } |
|||
change myText = |
|||
update newStr oldStr = newStr |
|||
text ("reverse " ++ myText |
|||
++ " = " ++ String.reverse myText) |
|||
view : String -> Html String |
|||
view forward = |
|||
div [] |
|||
([ input |
|||
[ placeholder "Enter a string to be reversed." |
|||
, value forward |
|||
, on "input" targetValue |
|||
, myStyle |
|||
] |
|||
[] |
|||
] ++ |
|||
[ let backward = reverse forward |
|||
in div [ myStyle] [text backward] |
|||
]) |
|||
main = |
|||
myStyle : Attribute msg |
|||
div [style "margin" "5%", style "font-size" "1.5em"] |
|||
myStyle = |
|||
[change "as⃝da" |
|||
style |
|||
[ |
, p [] [change "a⃝su-as⃝u"] |
||
, |
, p [] [change "Hello!"] |
||
] |
|||
, ("padding", "5px 0 0 5px") |
|||
</syntaxhighlight> |
|||
, ("font-size", "1em") |
|||
, ("text-align", "left") |
|||
]</lang> |
|||
Link to live demo: |
Link to live demo: https://ellie-app.com/qdg6RP3DGCBa1 |
||
{{out}} |
|||
<pre> |
|||
reverse as⃝da = ad⃝sa |
|||
reverse a⃝su-as⃝u = u⃝sa-us⃝a |
|||
reverse Hello! = !olleH |
|||
</pre> |
|||
=={{header|Emacs Lisp}}== |
|||
<syntaxhighlight lang="lisp">(reverse "Hello World")</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
"dlroW olleH" |
|||
</pre> |
|||
=={{header|Erlang}}== |
=={{header|Erlang}}== |
||
< |
<syntaxhighlight lang="erlang">1> lists:reverse("reverse!"). |
||
"!esrever"</ |
"!esrever"</syntaxhighlight> |
||
Erlang also supports binary strings, which uses its binary format. There is no standard function to reverse a binary sequence, but the following one does the job well enough. It works by changing the endianness (from little to big or the opposite) of the whole sequence, effectively reversing the string. |
Erlang also supports binary strings, which uses its binary format. There is no standard function to reverse a binary sequence, but the following one does the job well enough. It works by changing the endianness (from little to big or the opposite) of the whole sequence, effectively reversing the string. |
||
< |
<syntaxhighlight lang="erlang">reverse(Bin) -> |
||
Size = size(Bin)*8, |
Size = size(Bin)*8, |
||
<<T:Size/integer-little>> = Bin, |
<<T:Size/integer-little>> = Bin, |
||
<<T:Size/integer-big>>.</ |
<<T:Size/integer-big>>.</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 855: | Line 1,435: | ||
=={{header|ERRE}}== |
=={{header|ERRE}}== |
||
<syntaxhighlight lang="erre"> |
|||
<lang ERRE> |
|||
PROGRAM REVERSE_STRING |
PROGRAM REVERSE_STRING |
||
Line 871: | Line 1,451: | ||
PRINT(R$) |
PRINT(R$) |
||
END PROGRAM |
END PROGRAM |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Euler Math Toolbox}}== |
=={{header|Euler Math Toolbox}}== |
||
<syntaxhighlight lang="euler math toolbox"> |
|||
<lang Euler Math Toolbox> |
|||
>function strrev (s) := chartostr(fliplr(strtochar(s))) |
>function strrev (s) := chartostr(fliplr(strtochar(s))) |
||
>strrev("This is a test!") |
>strrev("This is a test!") |
||
!tset a si sihT |
!tset a si sihT |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Euphoria}}== |
=={{header|Euphoria}}== |
||
< |
<syntaxhighlight lang="euphoria"> |
||
include std/sequence.e |
include std/sequence.e |
||
printf(1, "%s\n", {reverse("abcdef") }) |
printf(1, "%s\n", {reverse("abcdef") }) |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Explore}}== |
|||
The [[Scratch]] [[Reverse a string#Scratch|solution]], which requires making variables named "i" and "inv" first, works, unmodified:<br>https://i.ibb.co/3c9k641/Reverse-a-string-in-Explore-using-the-Scratch-solution.png |
|||
This example uses a special block located in the Strings category:<br>https://i.ibb.co/4pM9G8b/Reverse-a-string-in-Explore-using-a-special-block.png |
|||
=={{header|Ezhil}}== |
=={{header|Ezhil}}== |
||
<syntaxhighlight lang="ezhil"> |
|||
<lang Ezhil> |
|||
## இந்த நிரல் தரப்படும் சரம் ஒன்றைத் தலைகீழாகத் திருப்பி அச்சிடும் |
## இந்த நிரல் தரப்படும் சரம் ஒன்றைத் தலைகீழாகத் திருப்பி அச்சிடும் |
||
Line 936: | Line 1,521: | ||
பதிப்பி "வேறொரு வகையில் திருப்பியுள்ளோம்: " மீண்டும்திருப்புக(அ) |
பதிப்பி "வேறொரு வகையில் திருப்பியுள்ளோம்: " மீண்டும்திருப்புக(அ) |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|F_Sharp|F#}}== |
|||
===The function=== |
|||
<syntaxhighlight lang="fsharp"> |
|||
// Reverse a string. Nigel Galloway: August 14th., 2019 |
|||
let strRev α=let N=System.Globalization.StringInfo.GetTextElementEnumerator(α) |
|||
List.unfold(fun n->if n then Some(N.GetTextElement(),N.MoveNext()) else None)(N.MoveNext())|>List.rev|>String.concat "" |
|||
</syntaxhighlight> |
|||
===The Task=== |
|||
I was a little concerned when entering this task because in the edit window the overline appears above the d, but when previewed it is correctly above the f, using Firefox anyway. Using XTERM the output is correct with the s inside a circle but appears as sO in Firefox. |
|||
<syntaxhighlight lang="fsharp"> |
|||
printfn "%s" (strRev "as⃝df̅") |
|||
printfn "%s" (strRev "Nigel") |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
f̅ds⃝a |
|||
legiN |
|||
</pre> |
|||
=={{header|Factor}}== |
|||
A string is a sequence and there is a default reverse implementation for those. |
|||
<syntaxhighlight lang="factor">"hello" reverse</syntaxhighlight> |
|||
<code>string-reverse</code> preserves graphemes: |
|||
<syntaxhighlight lang="factor">"as⃝df̅" string-reverse "f̅ds⃝a" = .</syntaxhighlight> |
|||
=={{header|FALSE}}== |
|||
This solution does not take into account combination characters: |
|||
<syntaxhighlight lang="false">1_ |
|||
[^$1_=~][]#% |
|||
[$1_=~][,]#</syntaxhighlight> |
|||
This solution does take into account combination characters (except for half-marks): |
|||
<syntaxhighlight lang="false">1_ |
|||
[^$1_=~][ |
|||
$$767>\879\>& |
|||
1ø$7615>\7620\>&| |
|||
1ø$8399>\8428\>&| |
|||
[\]? |
|||
]#% |
|||
[$1_=~][,]#</syntaxhighlight> |
|||
=={{header|Fancy}}== |
|||
<syntaxhighlight lang="fancy">"hello world!" reverse</syntaxhighlight> |
|||
=={{header|FBSL}}== |
=={{header|FBSL}}== |
||
A slow way |
A slow way |
||
< |
<syntaxhighlight lang="qbasic">Function StrRev1(ByVal $p1) |
||
dim $b = "" |
dim $b = "" |
||
REPEAT len(p1) |
REPEAT len(p1) |
||
Line 948: | Line 1,576: | ||
return b |
return b |
||
End Function |
End Function |
||
</syntaxhighlight> |
|||
</lang> |
|||
A much faster (twice at least) way |
A much faster (twice at least) way |
||
< |
<syntaxhighlight lang="qbasic">Function StrRev2(ByVal $p1) |
||
dim $b = "", %i |
dim $b = "", %i |
||
for i = len(p1) DOWNTO 1 |
for i = len(p1) DOWNTO 1 |
||
Line 957: | Line 1,585: | ||
next |
next |
||
return b |
return b |
||
End Function</ |
End Function</syntaxhighlight> |
||
An even faster way using PEEK, POKE, double-calls and quantity-in-hand |
An even faster way using PEEK, POKE, double-calls and quantity-in-hand |
||
< |
<syntaxhighlight lang="qbasic">Function StrRev3( $s ) |
||
FOR DIM x = 1 TO LEN(s) \ 2 |
FOR DIM x = 1 TO LEN(s) \ 2 |
||
PEEK(@s + LEN - x, $1) |
PEEK(@s + LEN - x, $1) |
||
Line 967: | Line 1,595: | ||
RETURN s |
RETURN s |
||
end function |
end function |
||
</syntaxhighlight> |
|||
</lang> |
|||
An even faster way using the DynC (Dynamic C) mode |
An even faster way using the DynC (Dynamic C) mode |
||
< |
<syntaxhighlight lang="c">DynC StringRev($theString) As String |
||
void rev(char *str) |
void rev(char *str) |
||
{ |
{ |
||
Line 989: | Line 1,617: | ||
return theString; |
return theString; |
||
} |
} |
||
End DynC</ |
End DynC</syntaxhighlight> |
||
Using DynASM, the Dynamic Assembler mode. |
Using DynASM, the Dynamic Assembler mode. |
||
< |
<syntaxhighlight lang="asm">DYNASM RevStr(BYVAL s AS STRING) AS STRING |
||
// get length of string |
// get length of string |
||
// divide by two |
// divide by two |
||
Line 1,041: | Line 1,669: | ||
RET |
RET |
||
END DYNASM |
END DYNASM |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header| |
=={{header|Fe}}== |
||
In this language, strings are very limited and are not designed to store large text data, so there are no built-in operations to work with strings. But with the C API you can make functions that convert a string to a list and vice versa. |
|||
<lang fsharp>let ReverseString (s:string) = new string(Array.rev (s.ToCharArray()))</lang> |
|||
<syntaxhighlight lang="c"> |
|||
#define MAXSTRINGLEN ( 1024 ) |
|||
/* chop string to list of single character strings */ |
|||
=={{header|Factor}}== |
|||
static fe_Object* chop(fe_Context *ctx, fe_Object *args) { |
|||
A string is a sequence and there is a default reverse implementation for those. |
|||
char buf[MAXSTRINGLEN]; |
|||
<lang factor>"hello" reverse</lang> |
|||
int len = fe_tostring(ctx, fe_nextarg(ctx, &args), buf, sizeof(buf)); |
|||
<code>string-reverse</code> preserves graphemes: |
|||
int gc = fe_savegc(ctx); |
|||
<lang factor>"as⃝df̅" string-reverse "f̅ds⃝a" = .</lang> |
|||
args = fe_bool(ctx, 0); |
|||
while (len > 0) { |
|||
buf[len--] = '\0'; |
|||
args = fe_cons(ctx, fe_string(ctx, buf + len), args); |
|||
fe_restoregc(ctx, gc); |
|||
fe_pushgc(ctx, args); |
|||
} |
|||
return args; |
|||
} |
|||
/* pack list of strings to single string */ |
|||
=={{header|FALSE}}== |
|||
static fe_Object* pack(fe_Context *ctx, fe_Object *args) { |
|||
This solution does not take into account combination characters: |
|||
char buf[MAXSTRINGLEN], *ptr = buf; |
|||
<lang false>1_ |
|||
for (args = fe_nextarg(ctx, &args); !fe_isnil(ctx, args);) { |
|||
[^$1_=~][]#% |
|||
ptr += fe_tostring(ctx, fe_nextarg(ctx, &args), ptr, buf + sizeof(buf) - ptr); |
|||
[$1_=~][,]#</lang> |
|||
} |
|||
This solution does take into account combination characters (except for half-marks): |
|||
return fe_string(ctx, buf); |
|||
<lang false>1_ |
|||
} |
|||
[^$1_=~][ |
|||
</syntaxhighlight> |
|||
$$767>\879\>& |
|||
So, we can manipulate strings like lists: |
|||
1ø$7615>\7620\>&| |
|||
<syntaxhighlight lang="clojure"> |
|||
1ø$8399>\8428\>&| |
|||
; reverse list |
|||
[\]? |
|||
(= reverse (fn (lst) |
|||
]#% |
|||
(let res nil) |
|||
[$1_=~][,]#</lang> |
|||
(while lst |
|||
(= res (cons (car lst) res)) |
|||
(= lst (cdr lst))) |
|||
res)) |
|||
; chop string to list, reverse list and pack it back to string |
|||
=={{header|Fancy}}== |
|||
(print (pack (reverse (chop "Hello world!")))) |
|||
<lang fancy>"hello world!" reverse</lang> |
|||
</syntaxhighlight> |
|||
Output: |
|||
<syntaxhighlight lang="clojure"> |
|||
!dlrow olleH |
|||
</syntaxhighlight> |
|||
=={{header|Fennel}}== |
|||
Uses the same methods (and suffers from the same limitations) as [[#Lua|the Lua example]]. |
|||
<syntaxhighlight lang="fennel"> |
|||
(let [example :asdf] |
|||
(string.reverse example) ; fdsa |
|||
(example:reverse) ; fdsa |
|||
nil) |
|||
</syntaxhighlight> |
|||
=={{header|Forth}}== |
=={{header|Forth}}== |
||
=== Method 1 === |
=== Method 1 === |
||
< |
<syntaxhighlight lang="forth">: exchange ( a1 a2 -- ) |
||
2dup c@ swap c@ rot c! swap c! ; |
2dup c@ swap c@ rot c! swap c! ; |
||
: reverse ( c-addr u -- ) |
: reverse ( c-addr u -- ) |
||
Line 1,081: | Line 1,738: | ||
repeat 2drop ; |
repeat 2drop ; |
||
s" testing" 2dup reverse type \ gnitset</ |
s" testing" 2dup reverse type \ gnitset</syntaxhighlight> |
||
=== Method 2 Using the stack === |
=== Method 2 Using the stack === |
||
< |
<syntaxhighlight lang="forth">\ reverse a string using the data stack for temporary storage |
||
\ Method: Read the input string character by character onto the parameter stack |
|||
\ Then write the character back into the same string from the stack |
|||
: mystring ( -- caddr len) S" ABCDEFGHIJKLMNOPQRSTUVWXYZ987654321" ; |
|||
create mystring ," ABCDEFGHIJKLMNOPQRSTUVWXYZ987654321" \ this is a counted string |
|||
: pushstr ( |
: pushstr ( caddr len -- c..c[n]) bounds do I c@ loop ; |
||
: popstr ( c.. c[n] caddr len -- ) bounds do I c! loop ; |
|||
: reverse ( caddr len -- ) 2dup 2>r pushstr 2r> popstr ;</syntaxhighlight> |
|||
: popstr ( char[1].. char[n] str -- ) \ read chars off stack into str |
|||
count bounds do I c! loop ; |
|||
: reverse ( str -- ) \ create the reverse function with the factored words |
|||
dup >r \ put a copy of the string addr on return stack |
|||
pushstr \ push the characters onto the parameter stack |
|||
r> popstr ; \ get back our copy of the string addr and pop the characters into it |
|||
\ test in the Forth console |
|||
</lang> |
|||
Forth Console Output |
Forth Console Output |
||
<pre> |
<pre> |
||
mystring |
mystring type ABCDEFGHIJKLMNOPQRSTUVWXYZ987654321 ok |
||
mystring |
mystring 2dup reverse type 123456789ZYXWVUTSRQPONMLKJIHGFEDCBA ok |
||
</pre> |
</pre> |
||
Line 1,117: | Line 1,762: | ||
The xchars wordset offers several ways to skin this cat; this is just one way to do it, not necessarily the best one. Because the xchars wordset currently does not support recognizing combining characters, this code does not get extra credit. |
The xchars wordset offers several ways to skin this cat; this is just one way to do it, not necessarily the best one. Because the xchars wordset currently does not support recognizing combining characters, this code does not get extra credit. |
||
< |
<syntaxhighlight lang="forth">: xreverse {: c-addr u -- c-addr2 u :} |
||
u allocate throw u + c-addr swap over u + >r begin ( from to r:end) |
u allocate throw u + c-addr swap over u + >r begin ( from to r:end) |
||
over r@ u< while |
over r@ u< while |
||
Line 1,125: | Line 1,770: | ||
\ example use |
\ example use |
||
s" ώщыē" xreverse type \ outputs "ēыщώ"</ |
s" ώщыē" xreverse type \ outputs "ēыщώ"</syntaxhighlight> |
||
=={{header|Fortran}}== |
=={{header|Fortran}}== |
||
{{works with|Fortran|90 and later}} |
{{works with|Fortran|90 and later}} |
||
< |
<syntaxhighlight lang="fortran">PROGRAM Example |
||
CHARACTER(80) :: str = "This is a string" |
CHARACTER(80) :: str = "This is a string" |
||
Line 1,144: | Line 1,789: | ||
WRITE(*,*) str |
WRITE(*,*) str |
||
END PROGRAM Example</ |
END PROGRAM Example</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
This is a string |
This is a string |
||
gnirts a si sihT |
gnirts a si sihT |
||
Another implementation that uses a recursive not-in-place algorithm: |
Another implementation that uses a recursive not-in-place algorithm: |
||
< |
<syntaxhighlight lang="fortran">program reverse_string |
||
implicit none |
implicit none |
||
Line 1,173: | Line 1,818: | ||
end function reverse |
end function reverse |
||
end program reverse_string</ |
end program reverse_string</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>no devil lived on |
<pre>no devil lived on |
||
no devil lived on</pre> |
no devil lived on</pre> |
||
Another shorter implementation (adapted version from stackoverflow question 10605574 how-to-reverse-a-chain-of-character-fortran-90): |
|||
<syntaxhighlight lang="fortran"> program reverse_string |
|||
implicit none |
|||
character (80) :: cadena |
|||
integer :: k, n |
|||
! |
|||
cadena = "abcdefgh" |
|||
n = len_trim (cadena) |
|||
! |
|||
write (*,*) cadena |
|||
forall (k=1:n) cadena (k:k) = cadena (n-k+1:n-k+1) |
|||
write (*,*) cadena |
|||
! |
|||
end program reverse_string</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
abcdefgh |
|||
hgfedcba </pre> |
|||
=={{header|FreeBASIC}}== |
|||
<syntaxhighlight lang="freebasic">' FB 1.05.0 Win64 |
|||
Function ReverseString(s As Const String) As String |
|||
If s = "" Then Return s |
|||
Dim length As Integer = Len(s) |
|||
Dim r As String = Space(length) |
|||
For i As Integer = 0 To length - 1 |
|||
r[i] = s[length - 1 - i] |
|||
Next |
|||
Return r |
|||
End Function |
|||
Dim s As String = "asdf" |
|||
Print "'"; s; "' reversed is '"; ReverseString(s); "'"</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
'asdf' reversed is 'fdsa' |
|||
</pre> |
|||
=={{header|Frink}}== |
=={{header|Frink}}== |
||
The built-in <CODE>reverse</CODE> function reverses a string or the elements of a list. |
The built-in <CODE>reverse</CODE> function reverses a string or the elements of a list. |
||
<lang frink>println[reverse["abcdef"]]</lang> |
|||
Frink's built-in <CODE>reverse[''string'']</CODE> is quite smart and uses a grapheme-based algorithm to handle Unicode correctly. That is, it preserves "user-perceived characters" that may consist of characters, combining accents, high-plane Unicode characters (that is, above U+FFFF,) surrogate pairs, ''etc.'' correctly. |
|||
Many languages will not work correctly with upper-plane Unicode characters because they are represented as Unicode "surrogate pairs" which are represented as two characters in a UTF-16 stream. |
|||
For example, the string "g\u0308o" represents a g with combining diaeresis, followed by the letter o. Or, in other words, "g̈o". Note that while there are three Unicode codepoints, only two "graphemes" are displayed. Using Frink's smart "reverse" function preserves these combined graphemes. A naive reverse would move the diaeresis over the o instead of the g. |
|||
<syntaxhighlight lang="frink">println[reverse["abcdef"]]</syntaxhighlight> |
|||
=={{header|Futhark}}== |
|||
Futhark has no real strings beyond a little bit of syntactic sugar, so this is the same as reversing an array. |
|||
<syntaxhighlight lang="futhark"> |
|||
fun main(s: []i32) = s[::-1] |
|||
</syntaxhighlight> |
|||
=={{header|FutureBasic}}== |
|||
<syntaxhighlight lang="futurebasic">void local fn DoIt |
|||
CFStringRef s1 = @"asdf", s2 = @"" |
|||
long index |
|||
for index = len(s1) - 1 to 0 step -1 |
|||
s2 = fn StringByAppendingString( s2, mid(s1,index,1) ) |
|||
next |
|||
print s1,s2 |
|||
end fn |
|||
window 1 |
|||
fn DoIt |
|||
HandleEvents</syntaxhighlight> |
|||
Output:<pre> |
|||
asdf fdsa</pre> |
|||
=={{header|Gambas}}== |
|||
'''[https://gambas-playground.proko.eu/?gist=e32989a1ffdc4428075ca6d4cb15dfa6 Click this link to run this code]''' |
|||
<syntaxhighlight lang="gambas">Public Sub Main() |
|||
Dim sString As String = "asdf" |
|||
Dim sOutput As String |
|||
Dim siCount As Short |
|||
For siCount = Len(sString) DownTo 1 |
|||
sOutput &= Mid(sString, siCount, 1) |
|||
Next |
|||
Print sOutput |
|||
End</syntaxhighlight> |
|||
Output: |
|||
<pre> |
|||
fdsa |
|||
</pre> |
|||
=={{header|GAP}}== |
=={{header|GAP}}== |
||
< |
<syntaxhighlight lang="gap">Reversed("abcdef"); |
||
# "fedcba"</ |
# "fedcba"</syntaxhighlight> |
||
=={{header|Gema}}== |
=={{header|Gema}}== |
||
Reverse each line in the input stream. Using built in function: |
Reverse each line in the input stream. Using built in function: |
||
< |
<syntaxhighlight lang="gema">\L<U>=@reverse{$1}</syntaxhighlight> |
||
Not using built in function (recursively apply substring to same rule): |
Not using built in function (recursively apply substring to same rule): |
||
< |
<syntaxhighlight lang="gema">\L<U1><U>=@{$2}$1</syntaxhighlight> |
||
=={{header|Genie}}== |
|||
Pretty sure the output capture fails the extra credit, but that may be more local setup and font installs rather than the glib functions used. |
|||
<syntaxhighlight lang="genie">[indent=4] |
|||
/* |
|||
Reverse a string, in Genie |
|||
valac reverse.gs |
|||
*/ |
|||
init |
|||
utf8:string = "asdf" |
|||
combining:string = "asdf̅" |
|||
print utf8 |
|||
print utf8.reverse() |
|||
print combining |
|||
print combining.reverse()</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
prompt$ valac reverse.gs |
|||
prompt$ ./reverse |
|||
asdf |
|||
fdsa |
|||
as?df? |
|||
?fd?sa</pre> |
|||
=={{header|GFA Basic}}== |
=={{header|GFA Basic}}== |
||
<lang> |
<syntaxhighlight lang="text"> |
||
PRINT @reverse$("asdf") |
PRINT @reverse$("asdf") |
||
' |
' |
||
Line 1,205: | Line 1,970: | ||
RETURN result$ |
RETURN result$ |
||
ENDFUNC |
ENDFUNC |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Go}}== |
=={{header|Go}}== |
||
Functions below assume UTF-8 encoding. (The task mentions Unicode but does not specify an encoding.) Strings in Go are not restricted to be UTF-8, but Go has good support for it and works with UTF-8 most natually. As shown below, certain string conversions work in UTF-8 and the range clause over a string works in UTF-8. Go also has a Unicode package in the standard library that makes easy work of recognizing combining characters for this task. |
Functions below assume UTF-8 encoding. (The task mentions Unicode but does not specify an encoding.) Strings in Go are not restricted to be UTF-8, but Go has good support for it and works with UTF-8 most natually. As shown below, certain string conversions work in UTF-8 and the range clause over a string works in UTF-8. Go also has a Unicode package in the standard library that makes easy work of recognizing combining characters for this task. |
||
< |
<syntaxhighlight lang="go">package main |
||
import ( |
import ( |
||
Line 1,284: | Line 2,049: | ||
r = reversePreservingCombiningCharacters(s) |
r = reversePreservingCombiningCharacters(s) |
||
fmt.Println("combining characters:", []rune(r), r) |
fmt.Println("combining characters:", []rune(r), r) |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 1,302: | Line 2,067: | ||
=={{header|Groovy}}== |
=={{header|Groovy}}== |
||
=====Solution:===== |
=====Solution:===== |
||
< |
<syntaxhighlight lang="groovy">println "Able was I, 'ere I saw Elba.".reverse()</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>.ablE was I ere' ,I saw elbA</pre> |
<pre>.ablE was I ere' ,I saw elbA</pre> |
||
=====Extra Credit:===== |
=====Extra Credit:===== |
||
< |
<syntaxhighlight lang="groovy">def string = "as⃝df̅" |
||
List combiningBlocks = [ |
List combiningBlocks = [ |
||
Line 1,321: | Line 2,086: | ||
} |
} |
||
} |
} |
||
println chars.reverse().join()</ |
println chars.reverse().join()</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>f̅ds⃝a</pre> |
<pre>f̅ds⃝a</pre> |
||
=={{header|Harbour}}== |
=={{header|Harbour}}== |
||
< |
<syntaxhighlight lang="visualfoxpro">FUNCTION Reverse( sIn ) |
||
LOCAL cOut := "", i |
LOCAL cOut := "", i |
||
Line 1,334: | Line 2,099: | ||
NEXT |
NEXT |
||
RETURN cOut</ |
RETURN cOut</syntaxhighlight> |
||
=={{header|Haskell}}== |
=={{header|Haskell}}== |
||
< |
<syntaxhighlight lang="haskell">reverse = foldl (flip (:)) []</syntaxhighlight> |
||
This function as defined in the Haskell Prelude. |
This function as defined in the Haskell Prelude. |
||
Though variants using a helper function with an additional accumulator argument are more efficient, and are now used by default in GHC.List unless the USE_REPORT_PRELUDE key is set. |
|||
Perhaps, for example: |
|||
<syntaxhighlight lang="haskell">accumulatingReverse :: [a] -> [a] |
|||
accumulatingReverse lst = |
|||
let rev xs a = foldl (flip (:)) a xs |
|||
in rev lst []</syntaxhighlight> |
|||
===Supporting combining characters=== |
===Supporting combining characters=== |
||
< |
<syntaxhighlight lang="haskell">import Data.Char (isMark) |
||
import Data.List (groupBy) |
import Data.List (groupBy) |
||
myReverse = concat . reverse . groupBy (const isMark)</ |
myReverse = concat . reverse . groupBy (const isMark)</syntaxhighlight> |
||
<code>groupBy (const isMark)</code> is an unusual way of splitting a string into its combined characters |
<code>groupBy (const isMark)</code> is an unusual way of splitting a string into its combined characters |
||
=={{header|HicEst}}== |
=={{header|HicEst}}== |
||
< |
<syntaxhighlight lang="hicest">CHARACTER string = "Hello World", tmp |
||
L = LEN( string ) |
L = LEN( string ) |
||
Line 1,355: | Line 2,129: | ||
ENDDO |
ENDDO |
||
WRITE(Messagebox, Name) string </ |
WRITE(Messagebox, Name) string </syntaxhighlight> |
||
=={{header|Icon}} and {{header|Unicon}}== |
=={{header|Icon}} and {{header|Unicon}}== |
||
< |
<syntaxhighlight lang="icon">procedure main(arglist) |
||
s := \arglist[1] | "asdf" |
s := \arglist[1] | "asdf" |
||
write(s," <-> ", reverse(s)) # reverse is built-in |
write(s," <-> ", reverse(s)) # reverse is built-in |
||
end</ |
end</syntaxhighlight> |
||
=={{header|Io}}== |
=={{header|Io}}== |
||
< |
<syntaxhighlight lang="io">"asdf" reverse</syntaxhighlight> |
||
=={{Header|Insitux}}== |
|||
<syntaxhighlight lang="insitux"> |
|||
(reverse "hello") |
|||
</syntaxhighlight> |
|||
=={{header|J}}== |
=={{header|J}}== |
||
Reverse (<tt>|.</tt>) reverses a list of items (of any shape or type). |
Reverse (<tt>|.</tt>) reverses a list of items (of any shape or type). |
||
< |
<syntaxhighlight lang="j"> |.'asdf' |
||
fdsa</ |
fdsa</syntaxhighlight> |
||
Extra credit: |
Extra credit: |
||
First, a function to determine whether a Unicode character is a combining character: |
First, a function to determine whether a Unicode character is a combining character: |
||
< |
<syntaxhighlight lang="j"> ranges=.16b02ff 16b036f, 16b1dbf 16b1dff, 16b20cf 16b20ff, 16bfe1f 16bfe2f |
||
iscombining=. 2 | ranges&I.</ |
iscombining=. 2 | ranges&I.</syntaxhighlight> |
||
Then we need to box groups of letters and combining characters, reverse, and unbox. The boxing function can be carried out easily with dyad cut, which uses the indices of the ones on the right as the starting points for groups of characters. For clarity, its inverse will be defined as raze, which simply runs together the items inside boxes of its argument. |
Then we need to box groups of letters and combining characters, reverse, and unbox. The boxing function can be carried out easily with dyad cut, which uses the indices of the ones on the right as the starting points for groups of characters. For clarity, its inverse will be defined as raze, which simply runs together the items inside boxes of its argument. |
||
< |
<syntaxhighlight lang="j"> split=. (<;.1~ -.@iscombining) :. ;</syntaxhighlight> |
||
After this, the solution is just to reverse under the split transformation. This also takes place under J code to convert from Unicode to integers. |
After this, the solution is just to reverse under the split transformation. This also takes place under J code to convert from Unicode to integers. |
||
< |
<syntaxhighlight lang="j"> |.&.split&.(3 u: 7&u:) 'as⃝df̅' |
||
f̅ds⃝a</ |
f̅ds⃝a</syntaxhighlight> |
||
=={{header|Java}}== |
=={{header|Java}}== |
||
<lang java>public static String reverseString(String s) { |
|||
=== Reverse Unicode Codepoints === |
|||
return new StringBuffer(s).reverse().toString(); |
|||
}</lang> |
|||
Reversing codepoints works in most cases when reversing single characters wherever they are encoded on multi-bytes or not. But this doesn't work for composed characters. |
|||
{{works with|Java|1.5+}} |
|||
<lang java5>public static String reverseString(String s) { |
|||
<syntaxhighlight lang="java"> |
|||
return new StringBuilder(s).reverse().toString(); |
|||
String reversed = new StringBuilder("as⃝df̅").reverse().toString(); // fd⃝sa |
|||
}</lang> |
|||
String reversed = new StringBuffer("as⃝df̅").reverse().toString(); // fd⃝sa |
|||
</syntaxhighlight> |
|||
Alternately, you could use a for-loop with the same issue. |
|||
<syntaxhighlight lang="java"> |
|||
String string = "as⃝df̅"; |
|||
StringBuilder reversed = new StringBuilder(); |
|||
for (int index = string.length() - 1; index >= 0; index--) |
|||
reversed.append(string.charAt(index)); |
|||
reversed; // fd⃝sa |
|||
</syntaxhighlight> |
|||
=== Reverse Unicode Graphemes === |
|||
A third-party solution is to use [https://mvnrepository.com/artifact/com.ibm.icu/icu4j ICU4J]. |
|||
A native solution, since JDK 15, is to use <code>Pattern.compile( "\\X" )</code> from <code>java.util.regex</code> to parse grapemes. |
|||
Another native solution, since JDK 20, is to use <code>java.text.BreakIterator</code> class that now parse graphemes correctly<ref>https://bugs.openjdk.org/browse/JDK-8291660</ref>. |
|||
<syntaxhighlight lang="java"> |
|||
import java.text.BreakIterator; |
|||
public class Reverse { |
|||
/* works with Java 20+ only |
|||
* cf. https://bugs.openjdk.org/browse/JDK-8291660 |
|||
*/ |
|||
public static StringBuilder graphemeReverse(String text) { |
|||
BreakIterator boundary = BreakIterator.getCharacterInstance(); |
|||
boundary.setText(text); |
|||
StringBuilder reversed = new StringBuilder(); |
|||
int end = boundary.last(); |
|||
int start = boundary.previous(); |
|||
while (start != BreakIterator.DONE) { |
|||
reversed.append(text.substring(start, end)); |
|||
end = start; |
|||
start = boundary.previous(); |
|||
} |
|||
return reversed; |
|||
} |
|||
public static void main(String[] args) throws Exception { |
|||
String a = "as⃝df̅"; |
|||
System.out.println(graphemeReverse(a)); // f̅ds⃝a |
|||
} |
|||
} |
|||
</syntaxhighlight> |
|||
=={{header|JavaScript}}== |
=={{header|JavaScript}}== |
||
<lang javascript>//using chained methods |
|||
=== Unicode === |
|||
==== Split code points ==== |
|||
<code><nowiki>split('')</nowiki></code> (with empty string argument) works only for ASCII. For Unicode strings, one of the two following methods can be used. |
|||
<syntaxhighlight lang="javascript"> |
|||
example = 'Tux 🐧 penguin'; |
|||
// array expansion operator |
|||
[...example].reverse().join('') // 'niugnep 🐧 xuT' |
|||
// split regexp separator with Unicode mode |
|||
example.split(/(?:)/u).reverse().join('') // 'niugnep 🐧 xuT' |
|||
// do not use |
|||
example.split('').reverse().join(''); // 'niugnep \udc27\ud83d xuT' |
|||
</syntaxhighlight> |
|||
==== Split graphemes ===== |
|||
More generally, one would want to combine characters such as joining emojis or diacritics to be handled properly so enumerating over graphemes is a must. |
|||
<syntaxhighlight lang="javascript"> |
|||
a = "\u{1F466}\u{1F3FB}\u{1f44b}"; // '👦🏻👋' |
|||
// wrong behavior - ASCII sequences |
|||
a.split('').reverse().join(''); // '\udc4b🁦\ud83d' |
|||
// wrong behavior - Unicode code points |
|||
[...a].reverse().join(''); // '👋🏻👦' |
|||
a.split(/(?:)/u).reverse().join(''); // '👋🏻👦' |
|||
// correct behavior - Unicode graphemes |
|||
[...new Intl.Segmenter().segment(a)].map(x => x.segment).reverse().join('') // 👋👦🏻 |
|||
</syntaxhighlight> |
|||
=== ASCII === |
|||
==== ES5 ==== |
|||
<syntaxhighlight lang="javascript">//using chained methods |
|||
function reverseStr(s) { |
function reverseStr(s) { |
||
return s.split('').reverse().join(''); |
return s.split('').reverse().join(''); |
||
Line 1,407: | Line 2,275: | ||
while (i--) o += s[i]; |
while (i--) o += s[i]; |
||
return o; |
return o; |
||
}</ |
}</syntaxhighlight> |
||
==== ES6 ==== |
|||
<syntaxhighlight lang="javascript">(() => { |
|||
// .reduceRight() can be useful when reversals |
|||
// are composed with some other process |
|||
let reverse1 = s => Array.from(s) |
|||
.reduceRight((a, x) => a + (x !== ' ' ? x : ' <- '), ''), |
|||
// but ( join . reverse . split ) is faster for |
|||
// simple string reversals in isolation |
|||
reverse2 = s => s.split('').reverse().join(''); |
|||
return [reverse1, reverse2] |
|||
.map(f => f("Some string to be reversed")); |
|||
})();</syntaxhighlight> |
|||
{{Out}} |
|||
<syntaxhighlight lang="javascript">["desrever <- eb <- ot <- gnirts <- emoS", "desrever eb ot gnirts emoS"]</syntaxhighlight> |
|||
=={{header|Joy}}== |
|||
<syntaxhighlight lang="joy">DEFINE reverse == "" [swons] fold. |
|||
"asdf" reverse putchars.</syntaxhighlight> |
|||
{{out}} |
|||
<pre>fdsa</pre> |
|||
=={{header|jq}}== |
=={{header|jq}}== |
||
jq's explode/implode filters are based on codepoints, and therefore "reverse_string" as defined here will reverse the sequence of codepoints. |
jq's explode/implode filters are based on codepoints, and therefore "reverse_string" as defined here will reverse the sequence of codepoints. |
||
The topic of Unicode combining characters is a large one that is not touched on here. |
The topic of Unicode combining characters is a large one that is not touched on here. |
||
< |
<syntaxhighlight lang="jq">def reverse_string: explode | reverse | implode;</syntaxhighlight> |
||
'''Examples''': |
'''Examples''': |
||
"nöel" | reverse_string # => "leön" |
"nöel" | reverse_string # => "leön" |
||
"as⃝df̅" | reverse_string # => "̅fd⃝sa" |
"as⃝df̅" | reverse_string # => "̅fd⃝sa" |
||
=={{header|Jsish}}== |
|||
ECMAScript has no builtin string reversal, so split the characters into an array, reverse the array and join it back together. |
|||
Jsi only supports UTF-8 literals so far (in release 2.8), character by character manipulation routines of multibyte UTF-8 data will not be correct. No extra credit, ''yet''. |
|||
<syntaxhighlight lang="javascript">var str = "Never odd or even"; |
|||
puts(str); |
|||
puts(str.split('').reverse().join(''));</syntaxhighlight> |
|||
{{out}} |
|||
<pre>Never odd or even |
|||
neve ro ddo reveN</pre> |
|||
=={{header|Julia}}== |
=={{header|Julia}}== |
||
< |
<syntaxhighlight lang="julia">julia> reverse("hey") |
||
"yeh"</ |
"yeh"</syntaxhighlight> |
||
The <code>reverse</code> function reverses codepoints ([https://github.com/JuliaLang/julia/issues/6165 because this is the right behavior] for the main application of string reversal: reversed string processing by external C libraries). However, [https://github.com/JuliaLang/julia/pull/9261 starting in Julia 0.4], you can also reverse the graphemes if you want (i.e. to reverse "visual order" including combining characters etc.) by: |
The <code>reverse</code> function reverses codepoints ([https://github.com/JuliaLang/julia/issues/6165 because this is the right behavior] for the main application of string reversal: reversed string processing by external C libraries). However, [https://github.com/JuliaLang/julia/pull/9261 starting in Julia 0.4], you can also reverse the graphemes if you want (i.e. to reverse "visual order" including combining characters etc.) by: |
||
< |
<syntaxhighlight lang="julia">julia> join(reverse(collect(graphemes("as⃝df̅")))) |
||
"f̅ds⃝a"</ |
"f̅ds⃝a"</syntaxhighlight> |
||
=={{header|K}}== |
|||
Monadic reverse (| ) verb reverses a string or list of any shape |
|||
<syntaxhighlight lang="k"> |
|||
|"asdf" |
|||
"fdsa" |
|||
| 23 4 5 1 |
|||
1 5 4 23 |
|||
</syntaxhighlight> |
|||
=={{header|Kotlin}}== |
=={{header|Kotlin}}== |
||
< |
<syntaxhighlight lang="kotlin">fun main(args: Array<String>) { |
||
println("asdf".reversed()) |
println("asdf".reversed()) |
||
}</ |
}</syntaxhighlight> |
||
=={{header|L++}}== |
=={{header|L++}}== |
||
< |
<syntaxhighlight lang="lisp">(include "string" "algorithm") |
||
(main |
(main |
||
(decl std::string s) |
(decl std::string s) |
||
(std::getline std::cin s) |
(std::getline std::cin s) |
||
(std::reverse (s.begin) (s.end)) |
(std::reverse (s.begin) (s.end)) |
||
(prn s))</ |
(prn s))</syntaxhighlight> |
||
=={{header|LabVIEW}}== |
=={{header|LabVIEW}}== |
||
{{VI solution|LabVIEW_Reverse_a_string.png}} |
{{VI solution|LabVIEW_Reverse_a_string.png}} |
||
=={{header|Lambdatalk}}== |
|||
<syntaxhighlight lang="scheme"> |
|||
{S.reverse hello brave new world} |
|||
-> world new brave hello |
|||
</syntaxhighlight> |
|||
=={{header|Lang}}== |
|||
<syntaxhighlight lang="lang"> |
|||
# Inv operator |
|||
fn.println(parser.op(-asdf)) |
|||
# Ouput: fdsa |
|||
# Inv operator function |
|||
fn.println(fn.inv(asdf)) |
|||
# Ouput: fdsa |
|||
</syntaxhighlight> |
|||
=={{header|Lang5}}== |
=={{header|Lang5}}== |
||
< |
<syntaxhighlight lang="lang5">: flip "" split reverse "" join ; |
||
"qwer asdf" flip .</ |
"qwer asdf" flip .</syntaxhighlight> |
||
=={{header|langur}}== |
|||
The reverse() function will reverse a string according to graphemes. |
|||
<syntaxhighlight lang="langur">writeln reverse("don't you know")</syntaxhighlight> |
|||
{{out}} |
|||
<pre>wonk uoy t'nod</pre> |
|||
=={{header|Lasso}}== |
=={{header|Lasso}}== |
||
< |
<syntaxhighlight lang="lasso">local(input) = 'asdf' |
||
#input->reverse</ |
#input->reverse</syntaxhighlight> |
||
===Using Query Expression & Array=== |
===Using Query Expression & Array=== |
||
More verbose than the string->reverse method, but this example illustrates different techniques to achieve the same result: |
More verbose than the string->reverse method, but this example illustrates different techniques to achieve the same result: |
||
using string->values to iterate over a string in order, inserting at position 1, and joining the resulting array as a string. |
using string->values to iterate over a string in order, inserting at position 1, and joining the resulting array as a string. |
||
< |
<syntaxhighlight lang="lasso">local(input = 'asdf', output = array) |
||
with i in #input->values |
with i in #input->values |
||
do #output->insertFirst(#i) |
do #output->insertFirst(#i) |
||
#output->join</ |
#output->join</syntaxhighlight> |
||
=={{header|LC3 Assembly}}== |
=={{header|LC3 Assembly}}== |
||
A string is stored as a zero-terminated array of character codes. To reverse it, we first scan forwards until we find the end; we then move backwards again, copying each code into a block of memory we have reserved for the purpose; and finally, when we have got back to the beginning, we append a terminal zero to the new string we have created. We can then call <tt>PUTS</tt> to print it. |
A string is stored as a zero-terminated array of character codes. To reverse it, we first scan forwards until we find the end; we then move backwards again, copying each code into a block of memory we have reserved for the purpose; and finally, when we have got back to the beginning, we append a terminal zero to the new string we have created. We can then call <tt>PUTS</tt> to print it. |
||
< |
<syntaxhighlight lang="lc3asm"> .ORIG 0x3000 |
||
LEA R1,STRING |
LEA R1,STRING |
||
Line 1,493: | Line 2,437: | ||
GNIRTS .BLKW 128 |
GNIRTS .BLKW 128 |
||
.END</ |
.END</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>d'gnahc woh !n'llaf woh O tub -- eh tseeb uoht fI</pre> |
<pre>d'gnahc woh !n'llaf woh O tub -- eh tseeb uoht fI</pre> |
||
Line 1,500: | Line 2,444: | ||
Ordinary string: |
Ordinary string: |
||
< |
<syntaxhighlight lang="lisp"> |
||
> (lists:reverse "asdf") |
> (lists:reverse "asdf") |
||
"fdsa" |
"fdsa" |
||
</syntaxhighlight> |
|||
</lang> |
|||
Create a UTF-8 encoded string: |
Create a UTF-8 encoded string: |
||
< |
<syntaxhighlight lang="lisp"> |
||
> (set encoded (binary ("åäö ð" utf8))) |
> (set encoded (binary ("åäö ð" utf8))) |
||
#B(195 165 195 164 195 182 32 195 176) |
#B(195 165 195 164 195 182 32 195 176) |
||
</syntaxhighlight> |
|||
</lang> |
|||
Display it, to be sure: |
Display it, to be sure: |
||
< |
<syntaxhighlight lang="lisp"> |
||
> (io:format "~tp~n" (list encoded)) |
> (io:format "~tp~n" (list encoded)) |
||
<<"åäö ð"/utf8>> |
<<"åäö ð"/utf8>> |
||
</syntaxhighlight> |
|||
</lang> |
|||
Reverse it: |
Reverse it: |
||
< |
<syntaxhighlight lang="lisp"> |
||
> (lists:reverse (unicode:characters_to_list encoded)) |
> (lists:reverse (unicode:characters_to_list encoded)) |
||
"ð öäå" |
"ð öäå" |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Liberty BASIC}}== |
=={{header|Liberty BASIC}}== |
||
{{works with|Just BASIC}} |
|||
<lang lb>input$ ="abcdefgABCDEFG012345" |
|||
{{works with|Run BASIC}} |
|||
<syntaxhighlight lang="lb">input$ ="abcdefgABCDEFG012345" |
|||
print input$ |
print input$ |
||
print ReversedStr$( input$) |
print ReversedStr$( input$) |
||
Line 1,535: | Line 2,480: | ||
ReversedStr$ =ReversedStr$ +mid$( in$, i, 1) |
ReversedStr$ =ReversedStr$ +mid$( in$, i, 1) |
||
next i |
next i |
||
end function</ |
end function</syntaxhighlight> |
||
=={{header|Lingo}}== |
|||
Lingo strings are always UTF-8 encoded and string operations are based on Unicode code points, so the "extra credit" is built-in: |
|||
<syntaxhighlight lang="lingo">on reverse (str) |
|||
res = "" |
|||
repeat with i = str.length down to 1 |
|||
put str.char[i] after res |
|||
end repeat |
|||
return res |
|||
end</syntaxhighlight> |
|||
To reverse a string byte-wise, the ByteArray data type has to be used: |
|||
<syntaxhighlight lang="lingo">on reverseBytes (str) |
|||
ba = byteArray(str) |
|||
res = byteArray() |
|||
repeat with i = ba.length down to 1 |
|||
res[res.length+1] = ba[i] |
|||
end repeat |
|||
return res |
|||
end</syntaxhighlight> |
|||
=={{header|LiveCode}}== |
=={{header|LiveCode}}== |
||
< |
<syntaxhighlight lang="livecode">function reverseString S |
||
repeat with i = length(S) down to 1 |
repeat with i = length(S) down to 1 |
||
put char i of S after R |
put char i of S after R |
||
end repeat |
end repeat |
||
return R |
return R |
||
end reverseString</ |
end reverseString</syntaxhighlight> |
||
=={{header|LLVM}}== |
|||
<syntaxhighlight lang="llvm">; This is not strictly LLVM, as it uses the C library function "printf". |
|||
; LLVM does not provide a way to print values, so the alternative would be |
|||
; to just load the string into memory, and that would be boring. |
|||
; Additional comments have been inserted, as well as changes made from the output produced by clang such as putting more meaningful labels for the jumps |
|||
$"main.printf" = comdat any |
|||
@main.str = private unnamed_addr constant [12 x i8] c"Hello world\00", align 1 |
|||
@"main.printf" = linkonce_odr unnamed_addr constant [4 x i8] c"%s\0A\00", comdat, align 1 |
|||
define void @reverse(i64, i8*) { |
|||
%3 = alloca i8*, align 8 ; allocate str (local) |
|||
%4 = alloca i64, align 8 ; allocate len (local) |
|||
%5 = alloca i64, align 8 ; allocate i |
|||
%6 = alloca i64, align 8 ; allocate j |
|||
%7 = alloca i8, align 1 ; allocate t |
|||
store i8* %1, i8** %3, align 8 ; set str (local) to the parameter str |
|||
store i64 %0, i64* %4, align 8 ; set len (local) to the paremeter len |
|||
store i64 0, i64* %5, align 8 ; i = 0 |
|||
%8 = load i64, i64* %4, align 8 ; load len |
|||
%9 = sub i64 %8, 1 ; decrement len |
|||
store i64 %9, i64* %6, align 8 ; j = |
|||
br label %loop |
|||
loop: |
|||
%10 = load i64, i64* %5, align 8 ; load i |
|||
%11 = load i64, i64* %6, align 8 ; load j |
|||
%12 = icmp ult i64 %10, %11 ; i < j |
|||
br i1 %12, label %loop_body, label %exit |
|||
loop_body: |
|||
%13 = load i8*, i8** %3, align 8 ; load str |
|||
%14 = load i64, i64* %5, align 8 ; load i |
|||
%15 = getelementptr inbounds i8, i8* %13, i64 %14 ; address of str[i] |
|||
%16 = load i8, i8* %15, align 1 ; load str[i] |
|||
store i8 %16, i8* %7, align 1 ; t = str[i] |
|||
%17 = load i64, i64* %6, align 8 ; load j |
|||
%18 = getelementptr inbounds i8, i8* %13, i64 %17 ; address of str[j] |
|||
%19 = load i8, i8* %18, align 1 ; load str[j] |
|||
%20 = getelementptr inbounds i8, i8* %13, i64 %14 ; address of str[i] |
|||
store i8 %19, i8* %20, align 1 ; str[i] = str[j] |
|||
%21 = load i8, i8* %7, align 1 ; load t |
|||
%22 = getelementptr inbounds i8, i8* %13, i64 %17 ; address of str[j] |
|||
store i8 %21, i8* %22, align 1 ; str[j] = t |
|||
;-- loop increment |
|||
%23 = load i64, i64* %5, align 8 ; load i |
|||
%24 = add i64 %23, 1 ; increment i |
|||
store i64 %24, i64* %5, align 8 ; store i |
|||
%25 = load i64, i64* %6, align 8 ; load j |
|||
%26 = add i64 %25, -1 ; decrement j |
|||
store i64 %26, i64* %6, align 8 ; store j |
|||
br label %loop |
|||
exit: |
|||
ret void |
|||
} |
|||
define i32 @main() { |
|||
;-- char str[] |
|||
%1 = alloca [12 x i8], align 1 |
|||
;-- memcpy(str, "Hello world") |
|||
%2 = bitcast [12 x i8]* %1 to i8* |
|||
call void @llvm.memcpy.p0i8.p0i8.i64(i8* %2, i8* getelementptr inbounds ([12 x i8], [12 x i8]* @main.str, i32 0, i32 0), i64 12, i32 1, i1 false) |
|||
;-- printf("%s\n", str) |
|||
%3 = getelementptr inbounds [12 x i8], [12 x i8]* %1, i32 0, i32 0 |
|||
%4 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @"main.printf", i32 0, i32 0), i8* %3) |
|||
;-- %7 = strlen(str) |
|||
%5 = getelementptr inbounds [12 x i8], [12 x i8]* %1, i32 0, i32 0 |
|||
%6 = call i64 @strlen(i8* %5) |
|||
;-- reverse(%6, str) |
|||
call void @reverse(i64 %6, i8* %5) |
|||
;-- printf("%s\n", str) |
|||
%7 = getelementptr inbounds [12 x i8], [12 x i8]* %1, i32 0, i32 0 |
|||
%8 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @"main.printf", i32 0, i32 0), i8* %7) |
|||
;-- end of main |
|||
ret i32 0 |
|||
} |
|||
;--- The declaration for the external C printf function. |
|||
declare i32 @printf(i8*, ...) |
|||
; Function Attrs: argmemonly nounwind |
|||
declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture writeonly, i8* nocapture readonly, i64, i32, i1) |
|||
declare i64 @strlen(i8*)</syntaxhighlight> |
|||
{{out}} |
|||
<pre>Hello world |
|||
dlrow olleH</pre> |
|||
=={{header|Logo}}== |
=={{header|Logo}}== |
||
REVERSE works on both words and lists. |
REVERSE works on both words and lists. |
||
< |
<syntaxhighlight lang="logo">print reverse "cat ; tac</syntaxhighlight> |
||
=={{header|Lua}}== |
=={{header|Lua}}== |
||
Built-in string.reverse(s) or s:reverse(). |
Built-in string.reverse(s) or s:reverse(). |
||
<lang lua>theString = theString:reverse()</lang> |
|||
=== ASCII === |
|||
<syntaxhighlight lang="lua"> |
|||
example = 'asdf' |
|||
string.reverse(example) -- fdsa |
|||
example:reverse() -- fdsa |
|||
</syntaxhighlight> |
|||
=== Unicode === |
|||
Lua doesn't support Unicode strings. |
|||
=={{header|M2000 Interpreter}}== |
|||
===Using Custom Function=== |
|||
Version 2, using insert to string (with no copies of strings) |
|||
<syntaxhighlight lang="m2000 interpreter"> |
|||
Module ReverseString { |
|||
a$="as⃝df̅" |
|||
Print Len(a$), len.disp(a$) |
|||
Let i=1, j=Len(a$) |
|||
z$=String$(" ",j) |
|||
j++ |
|||
do { |
|||
k$=mid$(a$, i, 1) |
|||
if i<len(a$) then { |
|||
while len.disp(k$+mid$(a$, i+1,1)) =len.disp(k$) { |
|||
k$+=mid$(a$, i+1,1) |
|||
i++ |
|||
if i>len(a$) then exit |
|||
j-- |
|||
} |
|||
j-- |
|||
insert j, len(k$) Z$=K$ |
|||
} else j-- :Insert j,1 z$=k$ |
|||
if i>=len(a$) then exit |
|||
i++ |
|||
} Always |
|||
Print len(z$), len.disp(z$) |
|||
Print z$="f̅ds⃝a" |
|||
Print z$ |
|||
} |
|||
ReverseString |
|||
</syntaxhighlight> |
|||
===using StrRev$()=== |
|||
this function (new to 9.5 version) use StrReverse from Vb6 |
|||
<syntaxhighlight lang="m2000 interpreter"> |
|||
a$="as⃝df̅" |
|||
b$=strrev$(a$) |
|||
clipboard b$ |
|||
Print b$="̅fd⃝sa" |
|||
</syntaxhighlight> |
|||
=={{header|M4}}== |
=={{header|M4}}== |
||
< |
<syntaxhighlight lang="m4">define(`invert',`ifelse(len(`$1'),0,,`invert(substr(`$1',1))'`'substr(`$1',0,1))')</syntaxhighlight> |
||
=={{header|Maclisp}}== |
=={{header|Maclisp}}== |
||
< |
<syntaxhighlight lang="lisp">(readlist (reverse (explode "my-string")))</syntaxhighlight> |
||
Output: |
Output: |
||
<pre>"gnirts-ym"</pre> |
<pre>"gnirts-ym"</pre> |
||
=={{header|MACRO-11}}== |
|||
<syntaxhighlight lang="macro11"> .TITLE REVERS |
|||
.MCALL .GTLIN,.PRINT,.EXIT |
|||
REVERS::.GTLIN #1$ ; READ STRING |
|||
MOV #1$,R0 |
|||
JSR PC,REV ; REVERSE IT |
|||
.PRINT #1$ ; PRINT RESULT |
|||
.EXIT |
|||
1$: .BLKB 200 |
|||
; REVERSE STRING AT R0 |
|||
REV: MOV R0,R1 |
|||
1$: TSTB (R1)+ ; FIND END OF STRING |
|||
BNE 1$ |
|||
DEC R1 ; MOVE BACK TO LAST CHAR |
|||
2$: MOVB -(R1),R2 ; SWAP CHARS |
|||
MOVB (R0),(R1) |
|||
MOVB R2,(R0)+ |
|||
CMP R0,R1 ; STOP WHEN POINTERS MEET |
|||
BLT 2$ |
|||
RTS PC |
|||
.END REVERS</syntaxhighlight> |
|||
{{out}} |
|||
<pre>.revers |
|||
A man, a plan, a canal: Panama |
|||
amanaP :lanac a ,nalp a ,nam A</pre> |
|||
=={{header|Maple}}== |
=={{header|Maple}}== |
||
< |
<syntaxhighlight lang="maple">> StringTools:-Reverse( "foo" ); |
||
"oof"</ |
"oof"</syntaxhighlight> |
||
=={{header|Mathematica}}== |
=={{header|Mathematica}}/{{header|Wolfram Language}}== |
||
< |
<syntaxhighlight lang="mathematica">StringReverse["asdf"]</syntaxhighlight> |
||
=={{header|MATLAB}}== |
=={{header|MATLAB}}== |
||
Line 1,572: | Line 2,708: | ||
Sample Usage: |
Sample Usage: |
||
< |
<syntaxhighlight lang="matlab">>> fliplr(['She told me that she spoke English and I said great. '... |
||
'Grabbed her hand out the club and I said let''s skate.']) |
'Grabbed her hand out the club and I said let''s skate.']) |
||
ans = |
ans = |
||
.etaks s'tel dias I dna bulc eht tuo dnah reh debbarG .taerg dias I dna hsilgnE ekops ehs taht em dlot ehS</ |
.etaks s'tel dias I dna bulc eht tuo dnah reh debbarG .taerg dias I dna hsilgnE ekops ehs taht em dlot ehS</syntaxhighlight> |
||
=={{header|Maxima}}== |
=={{header|Maxima}}== |
||
< |
<syntaxhighlight lang="maxima">sreverse("abcdef"); /* "fedcba" */ |
||
sreverse("rats live on no evil star"); /* not a bug :o) */</ |
sreverse("rats live on no evil star"); /* not a bug :o) */</syntaxhighlight> |
||
=={{header|MAXScript}}== |
=={{header|MAXScript}}== |
||
< |
<syntaxhighlight lang="maxscript">fn reverseString s = |
||
( |
( |
||
local reversed = "" |
local reversed = "" |
||
for i in s.count to 1 by -1 do reversed += s[i] |
for i in s.count to 1 by -1 do reversed += s[i] |
||
reversed |
reversed |
||
)</ |
)</syntaxhighlight> |
||
=={{header|min}}== |
|||
{{works with|min|0.19.3}} |
|||
<syntaxhighlight lang="min">("" split reverse "" join) :reverse-str</syntaxhighlight> |
|||
=={{header|MiniScript}}== |
|||
<syntaxhighlight lang="miniscript">str = "This is a string" |
|||
print "Forward: " + str |
|||
newStr = "" |
|||
for i in range(str.len-1, 0) |
|||
newStr = newStr + str[i] |
|||
end for |
|||
print "Reversed: " + newStr</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
Forward: This is a string |
|||
Reversed: gnirts a si sihT |
|||
</pre> |
|||
=={{header|MIPS Assembly}}== |
|||
<syntaxhighlight lang="mips"> |
|||
# First, it gets the length of the original string |
|||
# Then, it allocates memory from the copy |
|||
# Then it copies the pointer to the original string, and adds the strlen |
|||
# subtract 1, then that new pointer is at the last char. |
|||
# while(strlen) |
|||
# copy char |
|||
# decrement strlen |
|||
# decrement source pointer |
|||
# increment target pointer |
|||
.text |
|||
strcpy: |
|||
addi $sp, $sp, -4 |
|||
sw $s0, 0($sp) |
|||
add $s0, $zero, $zero |
|||
L1: |
|||
add $t1, $s0, $a1 |
|||
lb $t2, 0($t1) |
|||
add $t3, $s0, $a0 |
|||
sb $t2, 0($t3) |
|||
beq $t2, $zero, L2 |
|||
addi $s0, $s0, 1 |
|||
j L1 |
|||
L2: |
|||
lw $s0, 0($sp) |
|||
addi $sp, $sp, 4 |
|||
jr $ra |
|||
.data |
|||
ex_msg_og: .asciiz "Original string:\n" |
|||
ex_msg_cpy: .asciiz "\nCopied string:\n" |
|||
string: .asciiz "Nice string you got there!\n" |
|||
</syntaxhighlight> |
|||
=={{header|Mirah}}== |
=={{header|Mirah}}== |
||
< |
<syntaxhighlight lang="mirah">def reverse(s:string) |
||
StringBuilder.new(s).reverse |
StringBuilder.new(s).reverse |
||
end |
end |
||
puts reverse('reversed')</ |
puts reverse('reversed')</syntaxhighlight> |
||
=={{header|Miranda}}== |
|||
<syntaxhighlight lang="miranda">main :: [sys_message] |
|||
main = [Stdout (reverse "esreveR"), |
|||
Stdout "\n"]</syntaxhighlight> |
|||
{{out}} |
|||
<pre>Reverse</pre> |
|||
=={{header|Modula-2}}== |
|||
<syntaxhighlight lang="modula2">MODULE ReverseStr; |
|||
FROM FormatString IMPORT FormatString; |
|||
FROM Terminal IMPORT Write,WriteString,WriteLn,ReadChar; |
|||
PROCEDURE WriteInt(n : INTEGER); |
|||
VAR buf : ARRAY[0..15] OF CHAR; |
|||
BEGIN |
|||
FormatString("%i", buf, n); |
|||
WriteString(buf) |
|||
END WriteInt; |
|||
PROCEDURE ReverseStr(in : ARRAY OF CHAR; VAR out : ARRAY OF CHAR); |
|||
VAR ip,op : INTEGER; |
|||
BEGIN |
|||
ip := 0; |
|||
op := 0; |
|||
WHILE in[ip] # 0C DO |
|||
INC(ip) |
|||
END; |
|||
DEC(ip); |
|||
WHILE ip>=0 DO |
|||
out[op] := in[ip]; |
|||
INC(op); |
|||
DEC(ip) |
|||
END |
|||
END ReverseStr; |
|||
TYPE A = ARRAY[0..63] OF CHAR; |
|||
VAR is,os : A; |
|||
BEGIN |
|||
is := "Hello World"; |
|||
ReverseStr(is, os); |
|||
WriteString(is); |
|||
WriteLn; |
|||
WriteString(os); |
|||
WriteLn; |
|||
ReadChar |
|||
END ReverseStr.</syntaxhighlight> |
|||
=={{header|Modula-3}}== |
=={{header|Modula-3}}== |
||
< |
<syntaxhighlight lang="modula3">MODULE Reverse EXPORTS Main; |
||
IMPORT IO, Text; |
IMPORT IO, Text; |
||
Line 1,615: | Line 2,858: | ||
BEGIN |
BEGIN |
||
IO.Put(String("Foobarbaz") & "\n"); |
IO.Put(String("Foobarbaz") & "\n"); |
||
END Reverse.</ |
END Reverse.</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 1,622: | Line 2,865: | ||
=={{header|MUMPS}}== |
=={{header|MUMPS}}== |
||
< |
<syntaxhighlight lang="mumps">REVERSE |
||
;Take in a string and reverse it using the built in function $REVERSE |
;Take in a string and reverse it using the built in function $REVERSE |
||
NEW S |
NEW S |
||
READ:30 "Enter a string: ",S |
READ:30 "Enter a string: ",S |
||
WRITE !,$REVERSE(S) |
WRITE !,$REVERSE(S) |
||
QUIT</ |
QUIT</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 1,633: | Line 2,876: | ||
Enter a string: Hello, World! |
Enter a string: Hello, World! |
||
!dlroW ,olleH |
!dlroW ,olleH |
||
</pre> |
|||
=={{header|Nanoquery}}== |
|||
<syntaxhighlight lang="nanoquery">def reverse(string) |
|||
l = "" |
|||
for char in list(str(string)).reverse() |
|||
l += char |
|||
end |
|||
return l |
|||
end</syntaxhighlight> |
|||
=={{header|Neko}}== |
|||
No extra credit for UTF in this example. |
|||
<syntaxhighlight lang="actionscript">/* Reverse a string, in Neko */ |
|||
var reverse = function(s) { |
|||
var len = $ssize(s) |
|||
if len < 2 return s |
|||
var reverse = $smake(len) |
|||
var pos = 0 |
|||
while len > 0 $sset(reverse, pos ++= 1, $sget(s, len -= 1)) |
|||
return reverse |
|||
} |
|||
var str = "never odd or even" |
|||
$print(str, "\n") |
|||
$print(reverse(str), "\n\n") |
|||
str = "abcdefghijklmnopqrstuvwxyz" |
|||
$print(str, "\n") |
|||
$print(reverse(str), "\n\n") |
|||
$print("single test\n") |
|||
str = "a" |
|||
$print(str, "\n") |
|||
$print(reverse(str), "\n\n") |
|||
$print("empty test\n") |
|||
str = "" |
|||
$print(str, "\n") |
|||
$print(reverse(str), "\n")</syntaxhighlight> |
|||
{{out}} |
|||
<pre>prompt$ nekoc reverse.neko |
|||
prompt$ neko reverse.n |
|||
never odd or even |
|||
neve ro ddo reven |
|||
abcdefghijklmnopqrstuvwxyz |
|||
zyxwvutsrqponmlkjihgfedcba |
|||
single test |
|||
a |
|||
a |
|||
empty test |
|||
</pre> |
</pre> |
||
Line 1,638: | Line 2,941: | ||
===Supporting Combining Characters=== |
===Supporting Combining Characters=== |
||
Compile with:<pre>ncc -reference:System.Windows.Forms reverse.n</pre> |
Compile with:<pre>ncc -reference:System.Windows.Forms reverse.n</pre> |
||
< |
<syntaxhighlight lang="nemerle">using System; |
||
using System.Globalization; |
using System.Globalization; |
||
using System.Windows.Forms; |
using System.Windows.Forms; |
||
Line 1,660: | Line 2,963: | ||
MessageBox.Show($"$test --> $(UReverse(test))"); //for whatever reason my console didn't display Unicode properly, but a MessageBox worked |
MessageBox.Show($"$test --> $(UReverse(test))"); //for whatever reason my console didn't display Unicode properly, but a MessageBox worked |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
===Basic Reverse=== |
===Basic Reverse=== |
||
Doesn't require the '''System.Globalization''' namespace, probably a little less overhead. |
Doesn't require the '''System.Globalization''' namespace, probably a little less overhead. |
||
< |
<syntaxhighlight lang="nemerle">Reverse(text : string) : string |
||
{ |
{ |
||
mutable output = []; |
mutable output = []; |
||
Line 1,669: | Line 2,972: | ||
output ::= c.ToString(); |
output ::= c.ToString(); |
||
Concat("", output) |
Concat("", output) |
||
}</ |
}</syntaxhighlight> |
||
=={{header|NetRexx}}== |
=={{header|NetRexx}}== |
||
< |
<syntaxhighlight lang="netrexx">/* NetRexx */ |
||
options replace format comments java crossref savelog symbols nobinary |
options replace format comments java crossref savelog symbols nobinary |
||
Line 1,682: | Line 2,985: | ||
say sihTesrever |
say sihTesrever |
||
return</ |
return</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 1,688: | Line 2,991: | ||
fdsa |
fdsa |
||
</pre> |
</pre> |
||
=={{header|NewLISP}}== |
|||
<syntaxhighlight lang="newlisp">(reverse "!dlroW olleH")</syntaxhighlight> |
|||
=={{header|Nial}}== |
=={{header|Nial}}== |
||
< |
<syntaxhighlight lang="nial">reverse 'asdf' |
||
=fdsa</ |
=fdsa</syntaxhighlight> |
||
=={{header|Nim}}== |
=={{header|Nim}}== |
||
<lang nim>import unicode |
|||
=== Unicode codepoints === |
|||
proc reverse(s: var string) = |
|||
for i in 0 .. s.high div 2: |
|||
swap(s[i], s[s.high - i]) |
|||
Since Nim 0.11.0, the <code>unicode</code> module provides a [https://nim-lang.github.io/Nim/unicode.html#reversed%2Cstring <code>reversed</code>] proc... |
|||
proc reversed(s: string): string = |
|||
Hence: |
|||
result = newString(s.len) |
|||
for i,c in s: |
|||
result[s.high - i] = c |
|||
<syntaxhighlight lang="nim"> |
|||
proc uniReversed(s: string): string = |
|||
import unicode |
|||
result = newStringOfCap(s.len) |
|||
var tmp: seq[Rune] = @[] |
|||
for r in runes(s): |
|||
tmp.add(r) |
|||
for i in countdown(tmp.high, 0): |
|||
result.add(toUtf8(tmp[i])) |
|||
doAssert "foobar".reversed == "raboof" |
|||
proc isComb(r: Rune): bool = |
|||
doAssert "先秦兩漢".reversed == "漢兩秦先" |
|||
(r >=% Rune(0x300) and r <=% Rune(0x36f)) or |
|||
</syntaxhighlight> |
|||
(r >=% Rune(0x1dc0) and r <=% Rune(0x1dff)) or |
|||
(r >=% Rune(0x20d0) and r <=% Rune(0x20ff)) or |
|||
(r >=% Rune(0xfe20) and r <=% Rune(0xfe2f)) |
|||
This proc is enumerating codepoints so it will work with Unicode multi-bytes characters. A special handling was added so it's supports composing as well but since it's not enumerating graphemes it won't work with joining. |
|||
proc uniReversedPreserving(s: string): string = |
|||
result = newStringOfCap(s.len) |
|||
var tmp: seq[Rune] = @[] |
|||
for r in runes(s): |
|||
if isComb(r): tmp.insert(r, tmp.high) |
|||
else: tmp.add(r) |
|||
for i in countdown(tmp.high, 0): |
|||
result.add(toUtf8(tmp[i])) |
|||
=== Unicode graphemes === |
|||
for str in ["Reverse This!", "as⃝df̅"]: |
|||
echo "Original string: ", str |
|||
There is no native method to handle grapheme currently. |
|||
echo "Reversed: ", reversed(str) |
|||
echo "UniReversed: ", uniReversed(str) |
|||
=={{header|NS-HUBASIC}}== |
|||
echo "UniReversedPreserving: ", uniReversedPreserving(str)</lang> |
|||
<syntaxhighlight lang="ns-hubasic">10 STRING$="THIS TEXT IS REVERSED." |
|||
20 REVERSED$="" |
|||
30 FOR I=1 TO LEN(STRING$) |
|||
40 REVERSED$=MID$(STRING$,I,1)+REVERSED$ |
|||
50 NEXT |
|||
60 PRINT REVERSED$</syntaxhighlight> |
|||
=={{header|Nu}}== |
|||
<syntaxhighlight lang="nu">'äsdf' | str reverse</syntaxhighlight> |
|||
{{out}} |
{{out}} |
||
<pre>fdsä</pre> |
|||
<pre>Original string: Reverse This! |
|||
Reversed: !sihT esreveR |
|||
UniReversed: !sihT esreveR |
|||
UniReversedPreserving: !sihT esreveR |
|||
Original string: as⃝df̅ |
|||
Reversed: Ìfdâsa |
|||
UniReversed: ‾fd⃝sa |
|||
UniReversedPreserving: f̅ds⃝a</pre> |
|||
=={{header| |
=={{header|Oberon-2}}== |
||
Tested with [https://miasap.se/obnc OBNC]. |
|||
<lang NewLISP>(reverse "!dlroW olleH")</lang> |
|||
<syntaxhighlight lang="oberon">MODULE reverse; |
|||
IMPORT Out, Strings; |
|||
VAR s: ARRAY 12 + 1 OF CHAR; |
|||
PROCEDURE Swap(VAR c, d: CHAR); |
|||
VAR oldC: CHAR; |
|||
BEGIN |
|||
oldC := c; c := d; d := oldC |
|||
END Swap; |
|||
PROCEDURE Reverse(VAR s: ARRAY OF CHAR); |
|||
VAR len, i: INTEGER; |
|||
BEGIN |
|||
len := Strings.Length(s); |
|||
FOR i := 0 TO len DIV 2 DO |
|||
Swap(s[i], s[len - 1 - i]) |
|||
END |
|||
END Reverse; |
|||
BEGIN |
|||
s := "hello, world"; |
|||
Reverse(s); |
|||
Out.String(s); |
|||
Out.Ln |
|||
END reverse.</syntaxhighlight> |
|||
=={{header|Objeck}}== |
=={{header|Objeck}}== |
||
< |
<syntaxhighlight lang="objeck"> |
||
result := "asdf"->Reverse(); |
result := "asdf"->Reverse(); |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Objective-C}}== |
=={{header|Objective-C}}== |
||
This extends the <code>NSString</code> object adding a <code>reverseString</code> class method. |
This extends the <code>NSString</code> object adding a <code>reverseString</code> class method. |
||
< |
<syntaxhighlight lang="objc">#import <Foundation/Foundation.h> |
||
@interface NSString (Extended) |
@interface NSString (Extended) |
||
Line 1,772: | Line 3,089: | ||
return rtr; |
return rtr; |
||
} |
} |
||
@end</ |
@end</syntaxhighlight> |
||
Usage example: |
Usage example: |
||
< |
<syntaxhighlight lang="objc">int main() |
||
{ |
{ |
||
@autoreleasepool { |
@autoreleasepool { |
||
Line 1,784: | Line 3,101: | ||
} |
} |
||
return 0; |
return 0; |
||
}</ |
}</syntaxhighlight> |
||
===Supporting combining characters=== |
===Supporting combining characters=== |
||
Extra credit |
Extra credit |
||
< |
<syntaxhighlight lang="objc">#import <Foundation/Foundation.h> |
||
@interface NSString (Extended) |
@interface NSString (Extended) |
||
Line 1,806: | Line 3,123: | ||
return ostr; |
return ostr; |
||
} |
} |
||
@end</ |
@end</syntaxhighlight> |
||
Usage example: |
Usage example: |
||
< |
<syntaxhighlight lang="objc">int main() |
||
{ |
{ |
||
@autoreleasepool { |
@autoreleasepool { |
||
Line 1,818: | Line 3,135: | ||
} |
} |
||
return 0; |
return 0; |
||
}</ |
}</syntaxhighlight> |
||
=={{header|OCaml}}== |
=={{header|OCaml}}== |
||
Since OCaml 4.02 we can use the handy [http://caml.inria.fr/pub/docs/manual-ocaml/libref/String.html#VALinit String.init] function. |
|||
Here a version that returns a new allocated string (preserving the original one): |
Here a version that returns a new allocated string (preserving the original one): |
||
<lang ocaml>let rev_string str = |
|||
{{works with|OCaml|4.02+}} |
|||
let len = String.length str in |
|||
<syntaxhighlight lang="ocaml">let string_rev s = |
|||
let res = String.create len in |
|||
let |
let len = String.length s in |
||
String.init len (fun i -> s.[len - 1 - i]) |
|||
for i = 0 to last do |
|||
let j = last - i in |
|||
let () = |
|||
res.[i] <- str.[j]; |
|||
print_endline (string_rev "Hello world!")</syntaxhighlight> |
|||
done; |
|||
(res)</lang> |
|||
for in place modification we can't use strings anymore because strings became immutable in ocaml 4.02, so the type bytes has to be used instead: |
|||
and here with in place modification: |
|||
<lang ocaml>let rev_string str = |
|||
<syntaxhighlight lang="ocaml">let rev_bytes bs = |
|||
let last = String.length str - 1 in |
|||
let last = Bytes.length bs - 1 in |
|||
for i = 0 to last / 2 do |
for i = 0 to last / 2 do |
||
let j = last - i in |
let j = last - i in |
||
let c = |
let c = Bytes.get bs i in |
||
Bytes.set bs i (Bytes.get bs j); |
|||
Bytes.set bs j c; |
|||
done |
done |
||
here is a 100% functionnal string reversing function: |
|||
let () = |
|||
<lang ocaml>let rec revs strin list index = |
|||
let s = Bytes.of_string "Hello World" in |
|||
rev_bytes s; |
|||
print_bytes s; |
|||
print_newline (); |
|||
;;</syntaxhighlight> |
|||
Here is a 100% functionnal string reversing function: |
|||
<syntaxhighlight lang="ocaml">let rec revs_aux strin list index = |
|||
if List.length list = String.length strin |
if List.length list = String.length strin |
||
then String.concat "" list |
then String.concat "" list |
||
else |
else revs_aux strin ((String.sub strin index 1)::list) (index+1) |
||
let revs s = revs_aux s [] 0 |
|||
let () = |
|||
print_endline (revs "Hello World!")</syntaxhighlight> |
|||
revs "Hello World!" [] 0 |
|||
will return "!dlroW olleH" |
will return "!dlroW olleH" |
||
=={{header|Octave}}== |
=={{header|Octave}}== |
||
< |
<syntaxhighlight lang="octave">s = "a string"; |
||
rev = s(length(s):-1:1)</ |
rev = s(length(s):-1:1)</syntaxhighlight> |
||
=={{header|Oforth}}== |
=={{header|Oforth}}== |
||
<lang |
<syntaxhighlight lang="oforth">reverse</syntaxhighlight> |
||
=={{header|Ol}}== |
|||
<syntaxhighlight lang="scheme"> |
|||
(define (rev s) |
|||
(runes->string (reverse (string->runes s)))) |
|||
; testing: |
|||
(print (rev "Hello, λ!")) |
|||
; ==> !λ ,olleH |
|||
</syntaxhighlight> |
|||
=={{header|OmniMark}}== |
|||
This handles the characters U+0073,U+20DD (Latin Small Letter S + Combining Enclosing Circle; UTF-8: 73 + e2 83 9D) and U+0066,U+0305 (Latin Small Letter F + Combining Overline; UTF-8: 66 + cc 85). It would need extension to handle ''non-combining'' UTF-8 characters, but that's not been done. |
|||
<syntaxhighlight lang="omnimark"> |
|||
macro utf8-not-ascii is |
|||
(["%16r{C0}" to "%16r{DF}"] ["%16r{80}" to "%16r{BF}"] | |
|||
["%16r{E0}" to "%16r{EF}"] ["%16r{80}" to "%16r{BF}"] {2} | |
|||
["%16r{F0}" to "%16r{F7}"] ["%16r{80}" to "%16r{BF}"] {3}) macro-end |
|||
global stream reverse initial {''} |
|||
process |
|||
submit 'as⃝df̅' |
|||
find (any-text utf8-not-ascii) => char |
|||
set reverse to char || reverse |
|||
find any-text => char |
|||
set reverse to char || reverse |
|||
process-end |
|||
output reverse || '%n' |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
f̅ds⃝a |
|||
</pre> |
|||
=={{header|OOC}}== |
|||
<syntaxhighlight lang="ooc"> |
|||
main: func { |
|||
"asdf" reverse() println() // prints "fdsa" |
|||
} |
|||
</syntaxhighlight> |
|||
=={{header|OpenEdge/Progress}}== |
=={{header|OpenEdge/Progress}}== |
||
<lang |
<syntaxhighlight lang="openedge/progress">FUNCTION reverseString RETURNS CHARACTER ( |
||
INPUT i_c AS CHARACTER |
INPUT i_c AS CHARACTER |
||
): |
): |
||
Line 1,871: | Line 3,249: | ||
END FUNCTION. |
END FUNCTION. |
||
MESSAGE reverseString( "asdf" ) VIEW-AS ALERT-BOX.</ |
MESSAGE reverseString( "asdf" ) VIEW-AS ALERT-BOX.</syntaxhighlight> |
||
=={{header|OOC}}== |
|||
<lang ooc> |
|||
main: func { |
|||
"asdf" reverse() println() // prints "fdsa" |
|||
} |
|||
</lang> |
|||
=={{header|OxygenBasic}}== |
=={{header|OxygenBasic}}== |
||
< |
<syntaxhighlight lang="oxygenbasic"> |
||
'8 BIT CHARACTERS |
'8 BIT CHARACTERS |
||
Line 1,915: | Line 3,286: | ||
' |
' |
||
print s |
print s |
||
</syntaxhighlight> |
|||
</lang> |
|||
==OxygenBasic x86 Assembler== |
==OxygenBasic x86 Assembler== |
||
32 bit code, 8-bit characters: |
32 bit code, 8-bit characters: |
||
< |
<syntaxhighlight lang="oxygenbasic"> |
||
string s="qwertyuiop" |
string s="qwertyuiop" |
||
Line 1,940: | Line 3,311: | ||
print s |
print s |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Oz}}== |
=={{header|Oz}}== |
||
Strings are lists. A function "Reverse" defined on lists is part of the implementation. |
Strings are lists. A function "Reverse" defined on lists is part of the implementation. |
||
< |
<syntaxhighlight lang="oz">{System.showInfo {Reverse "!dlroW olleH"}}</syntaxhighlight> |
||
An efficient (tail-recursive) implementation could look like this: |
An efficient (tail-recursive) implementation could look like this: |
||
< |
<syntaxhighlight lang="oz">local |
||
fun {DoReverse Xs Ys} |
fun {DoReverse Xs Ys} |
||
case Xs of nil then Ys |
case Xs of nil then Ys |
||
Line 1,954: | Line 3,325: | ||
in |
in |
||
fun {Reverse Xs} {DoReverse Xs nil} end |
fun {Reverse Xs} {DoReverse Xs nil} end |
||
end</ |
end</syntaxhighlight> |
||
Oz uses a single-byte encoding by default. If you decide to use a multi-byte encoding, Reverse will not work correctly. |
Oz uses a single-byte encoding by default. If you decide to use a multi-byte encoding, Reverse will not work correctly. |
||
Line 1,960: | Line 3,331: | ||
===Version #1.=== |
===Version #1.=== |
||
< |
<syntaxhighlight lang="parigp">reverse(s)=concat(Vecrev(s))</syntaxhighlight> |
||
===Version #2.=== |
===Version #2.=== |
||
{{Works with|PARI/GP|2.7.4 and above}} |
{{Works with|PARI/GP|2.7.4 and above}} |
||
< |
<syntaxhighlight lang="parigp"> |
||
\\ Return reversed string str. |
\\ Return reversed string str. |
||
\\ 3/3/2016 aev |
\\ 3/3/2016 aev |
||
Line 1,978: | Line 3,349: | ||
for(i=1,n, sr=sreverse(s)); |
for(i=1,n, sr=sreverse(s)); |
||
} |
} |
||
</ |
</syntaxhighlight> |
||
{{Output}} |
{{Output}} |
||
Line 1,988: | Line 3,359: | ||
</pre> |
</pre> |
||
< |
<syntaxhighlight lang="parigp"> |
||
\\ Version #1 upgraded to complete function. Practically the same. |
\\ Version #1 upgraded to complete function. Practically the same. |
||
reverse(str)={return(concat(Vecrev(str)))} |
reverse(str)={return(concat(Vecrev(str)))} |
||
Line 2,000: | Line 3,371: | ||
for(i=1,n, sr=reverse(s)); |
for(i=1,n, sr=reverse(s)); |
||
} |
} |
||
</ |
</syntaxhighlight> |
||
{{Output}} |
{{Output}} |
||
Line 2,016: | Line 3,387: | ||
Standard Pascal doesn't have a separate string type, but uses arrays of char for strings. Note that Standard Pascal doesn't allow a return type of char array, therefore the destination array is passed through a var parameter (which is more efficient anyway). |
Standard Pascal doesn't have a separate string type, but uses arrays of char for strings. Note that Standard Pascal doesn't allow a return type of char array, therefore the destination array is passed through a var parameter (which is more efficient anyway). |
||
< |
<syntaxhighlight lang="pascal">{ the result array must be at least as large as the original array } |
||
procedure reverse(s: array[min .. max: integer] of char, var result: array[min1 .. max1: integer] of char); |
procedure reverse(s: array[min .. max: integer] of char, var result: array[min1 .. max1: integer] of char); |
||
var |
var |
||
Line 2,024: | Line 3,395: | ||
for i := 0 to len-1 do |
for i := 0 to len-1 do |
||
result[min1 + len-1 - i] := s[min + i] |
result[min1 + len-1 - i] := s[min + i] |
||
end;</ |
end;</syntaxhighlight> |
||
< |
<syntaxhighlight lang="pascal">{Copy and paste it in your program} |
||
function revstr(my_s:string):string; |
function revstr(my_s:string):string; |
||
var out_s:string; |
var out_s:string; |
||
Line 2,034: | Line 3,405: | ||
out_s:=out_s+my_s[ls-i+1]; |
out_s:=out_s+my_s[ls-i+1]; |
||
revstr:=out_s; |
revstr:=out_s; |
||
end;</ |
end;</syntaxhighlight> |
||
=== Extended Pascal, Turbo Pascal, Delphi and compatible compilers === |
=== Extended Pascal, Turbo Pascal, Delphi and compatible compilers === |
||
< |
<syntaxhighlight lang="pascal">function reverse(s:string):string; |
||
var i:integer; |
var i:integer; |
||
var tmp:char; |
var tmp:char; |
||
Line 2,047: | Line 3,418: | ||
reverse:=s; |
reverse:=s; |
||
end; |
end; |
||
end;</ |
end;</syntaxhighlight> |
||
alternative as procedure which changes the original |
alternative as procedure which changes the original |
||
< |
<syntaxhighlight lang="pascal">procedure revString(var s:string); |
||
var |
var |
||
i,j:integer; |
i,j:integer; |
||
Line 2,064: | Line 3,435: | ||
dec(j) |
dec(j) |
||
end; |
end; |
||
end;</ |
end;</syntaxhighlight> |
||
=={{header|PascalABC.NET}}== |
|||
<syntaxhighlight lang="delphi"> |
|||
## |
|||
var s:='asdf';//ReadLnString; |
|||
ReverseString(s).Print; |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
fdsa |
|||
</pre> |
|||
=={{header|Peloton}}== |
=={{header|Peloton}}== |
||
Padded out, variable length Chinese dialect |
Padded out, variable length Chinese dialect |
||
< |
<syntaxhighlight lang="sgml"><# 显示 指定 变量 反转顺序 字串>集装箱|猫坐在垫子</#></syntaxhighlight> |
||
This assigns the reverse of 'the cat sat on the mat' to the variable 'container' and displays the result which is <pre>子垫在坐猫</pre> which Google Translate renders as <pre>Sub-pad sitting cat</pre>. |
This assigns the reverse of 'the cat sat on the mat' to the variable 'container' and displays the result which is <pre>子垫在坐猫</pre> which Google Translate renders as <pre>Sub-pad sitting cat</pre>. |
||
The same again but with everything in Korean. |
The same again but with everything in Korean. |
||
< |
<syntaxhighlight lang="sgml"><# 보이십 할당하 변물건 열거꾸 문자그>컨테이너|고양이가 매트 위에 앉아</#></syntaxhighlight> |
||
Reversing the Korean makes an untranslatable-by-Google mess of the sentence, viz <pre>아앉 에위 트매 가이양고</pre>. |
Reversing the Korean makes an untranslatable-by-Google mess of the sentence, viz <pre>아앉 에위 트매 가이양고</pre>. |
||
The short-opcode version in English dialect is |
The short-opcode version in English dialect is |
||
< |
<syntaxhighlight lang="sgml"><@ SAYLETVARREVLIT>集装箱|猫坐在垫子</@></syntaxhighlight> |
||
Peloton works in Unicode. |
Peloton works in Unicode. |
||
=={{header|Perl}}== |
=={{header|Perl}}== |
||
This reverses characters (code points): |
|||
<lang perl>$string = "visor"; |
|||
$flip = reverse $string; # becomes "rosiv"</lang> |
|||
[https://perldoc.perl.org/functions/reverse reverse()] works in the context of a List or a scalar, not a string. |
|||
This reverses graphemes: |
|||
<lang perl>$string = "Jose\x{301}"; # "José" in NFD |
|||
$flip = join("", reverse $string =~ /\X/g); # becomes "ésoJ"</lang> |
|||
<syntaxhighlight lang="perl">use utf8; |
|||
=={{header|Perl 6}}== |
|||
binmode STDOUT, ":utf8"; |
|||
{{Works with|rakudo|2015-11-22}} |
|||
Perl 6 handles graphemes correctly by default. |
|||
# to reverse characters (code points): |
|||
<lang perl6>say "hello world".flip; |
|||
print scalar reverse('visor'), "\n"; |
|||
say "as⃝df̅".flip</lang> |
|||
# to reverse graphemes: |
|||
print join("", reverse "José" =~ /\X/g), "\n"; |
|||
$string = 'ℵΑΩ 駱駝道 🤔 🇸🇧 🇺🇸 🇬🇧 👨👩👧👦🆗🗺'; |
|||
print join("", reverse $string =~ /\X/g), "\n";</syntaxhighlight> |
|||
{{out}} |
{{out}} |
||
<pre> |
<pre>rosiv |
||
ésoJ |
|||
dlrow olleh |
|||
🗺🆗👨👩👧👦 🇬🇧 🇺🇸 🇸🇧 🤔 道駝駱 ΩΑℵ</pre> |
|||
f̅ds⃝a |
|||
</pre> |
|||
=={{header|Pharo}}== |
|||
<syntaxhighlight lang="pharo">'123' reversed</syntaxhighlight> |
|||
=={{header|Phix}}== |
=={{header|Phix}}== |
||
<!--<syntaxhighlight lang="phix">(phixonline)--> |
|||
<lang Phix>?reverse("asdf")</lang> |
|||
<span style="color: #0000FF;">?</span><span style="color: #7060A8;">reverse</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"asdf"</span><span style="color: #0000FF;">)</span> |
|||
However that would go horribly wrong on utf8 strings, even without combining characters, so... this seems ok on "as\u203Ddf\u0305", as long as it is displayed in a message box rather than a Windows Console (even with chcp 65001 and Lucida Console, the characters do not combine). |
|||
<!--</syntaxhighlight>--> |
|||
<lang Phix>function unicode_reverse(string utf8) |
|||
However that would go horribly wrong on utf8 strings, even without combining characters, so... this seems ok on "as\u203Ddf\u0305", as long as it is displayed in a message box rather than a Windows Console (even with chcp 65001 and Lucida Console, the characters do not combine). It actually works better under pwa/p2js than on desktop/Phix, you can find a copy of this code in demo/HelloUTF8.exw which outputs the result in a message box and therefore looks much better on the latter.<br> |
|||
sequence utf32 = utf8_to_utf32(utf8) |
|||
Note that [[XXXX_redacted#Phix]] adds some ZERO-WIDTH-JOINER handling to the inner code. |
|||
integer ch |
|||
<!--<syntaxhighlight lang="phix">(phixonline)--> |
|||
-- the assumption is made that <char><comb1><comb2> |
|||
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span> |
|||
-- and <char><comb2><comb1> etc would work the same. |
|||
<span style="color: #008080;">function</span> <span style="color: #000000;">unicode_reverse</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">utf8</span><span style="color: #0000FF;">)</span> |
|||
for i=1 to length(utf32) do |
|||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">utf32</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">utf8_to_utf32</span><span style="color: #0000FF;">(</span><span style="color: #000000;">utf8</span><span style="color: #0000FF;">)</span> |
|||
ch = utf32[i] |
|||
<span style="color: #000080;font-style:italic;">-- The assumption is made that <char><comb1><comb2> |
|||
if (ch>=0x300 and ch<=0x36f) |
|||
-- and <char><comb2><comb1> etc would work the same. |
|||
or (ch>=0x1dc0 and ch<=0x1dff) |
|||
-- The following loop converts <char><comb1><comb2> |
|||
or (ch>=0x20d0 and ch<=0x20ff) |
|||
-- to <comb1><comb2><char>, as a pre-reverse() step.</span> |
|||
or (ch>=0xfe20 and ch<=0xfe2f) then |
|||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">utf32</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span> |
|||
utf32[i] = utf32[i-1] |
|||
<span style="color: #004080;">integer</span> <span style="color: #000000;">ch</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">utf32</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> |
|||
utf32[i-1] = ch |
|||
<span style="color: #008080;">if</span> <span style="color: #0000FF;">(</span><span style="color: #000000;">ch</span><span style="color: #0000FF;">>=</span><span style="color: #000000;">0x300</span> <span style="color: #008080;">and</span> <span style="color: #000000;">ch</span><span style="color: #0000FF;"><=</span><span style="color: #000000;">0x36f</span><span style="color: #0000FF;">)</span> |
|||
end if |
|||
<span style="color: #008080;">or</span> <span style="color: #0000FF;">(</span><span style="color: #000000;">ch</span><span style="color: #0000FF;">>=</span><span style="color: #000000;">0x1dc0</span> <span style="color: #008080;">and</span> <span style="color: #000000;">ch</span><span style="color: #0000FF;"><=</span><span style="color: #000000;">0x1dff</span><span style="color: #0000FF;">)</span> |
|||
end for |
|||
<span style="color: #008080;">or</span> <span style="color: #0000FF;">(</span><span style="color: #000000;">ch</span><span style="color: #0000FF;">>=</span><span style="color: #000000;">0x20d0</span> <span style="color: #008080;">and</span> <span style="color: #000000;">ch</span><span style="color: #0000FF;"><=</span><span style="color: #000000;">0x20ff</span><span style="color: #0000FF;">)</span> |
|||
utf32 = reverse(utf32) |
|||
<span style="color: #008080;">or</span> <span style="color: #0000FF;">(</span><span style="color: #000000;">ch</span><span style="color: #0000FF;">>=</span><span style="color: #000000;">0xfe20</span> <span style="color: #008080;">and</span> <span style="color: #000000;">ch</span><span style="color: #0000FF;"><=</span><span style="color: #000000;">0xfe2f</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span> |
|||
utf8 = utf32_to_utf8(utf32) |
|||
<span style="color: #000000;">utf32</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">utf32</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span> |
|||
return utf8 |
|||
<span style="color: #000000;">utf32</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">ch</span> |
|||
end function</lang> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
|||
<span style="color: #000000;">utf32</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">reverse</span><span style="color: #0000FF;">(</span><span style="color: #000000;">utf32</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #000000;">utf8</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">utf32_to_utf8</span><span style="color: #0000FF;">(</span><span style="color: #000000;">utf32</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #008080;">return</span> <span style="color: #000000;">utf8</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span> |
|||
<span style="color: #004080;">string</span> <span style="color: #000000;">r4</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"as\u203Ddf\u0305"</span><span style="color: #0000FF;">,</span> |
|||
<span style="color: #000000;">rt</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">r4</span><span style="color: #0000FF;">&</span><span style="color: #008000;">" reversed is "</span><span style="color: #0000FF;">&</span><span style="color: #000000;">unicode_reverse</span><span style="color: #0000FF;">(</span><span style="color: #000000;">r4</span><span style="color: #0000FF;">)&</span><span style="color: #008000;">"\n"</span> |
|||
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">rt</span><span style="color: #0000FF;">)</span> |
|||
<!--</syntaxhighlight>--> |
|||
=={{header|PHP}}== |
=={{header|PHP}}== |
||
<lang php>strrev($string);</lang> |
|||
=== Unicode === |
|||
==== Code points ==== |
|||
If you want Unicode support, you have to use some multibyte function. Sadly, PHP doesn't contain <code>mb_strrev()</code>. One of functions which support Unicode and is useful in this case is <code>preg_split()</code>. |
If you want Unicode support, you have to use some multibyte function. Sadly, PHP doesn't contain <code>mb_strrev()</code>. One of functions which support Unicode and is useful in this case is <code>preg_split()</code>. |
||
<syntaxhighlight lang="php"> |
|||
<lang php>// Will split every Unicode character to array, reverse array and will convert it to string. |
|||
// Will split every Unicode character to array, reverse array and will convert it to string. |
|||
join('', array_reverse(preg_split('""u', $string, -1, PREG_SPLIT_NO_EMPTY)));</lang> |
|||
join('', array_reverse(preg_split('""u', $string, -1, PREG_SPLIT_NO_EMPTY))); |
|||
</syntaxhighlight> |
|||
With PHP 7.4+ and 8+, it's also possible to use <code>mb_str_split()</code>, which may ends easier. |
|||
<syntaxhighlight lang="php"> |
|||
implode('', array_reverse(mb_str_split($string))); |
|||
</syntaxhighlight> |
|||
==== Graphemes ==== |
|||
When using combining characters such as diacritics or ZWJ (joining), reversing code points will mess with the result, reversing the graphemes instead is mandatory. This is generally the best and safest approach. As there is no <code>grapheme_reverse()</code> function or grapheme iterator, one has to implement it with <code>grapheme_strlen</code> and <code>grapheme_substr</code>. In PHP, there is no Unicode escape sequence so to specify characters by code point a tricks must be used: for example, using the escape sequence of HTML entities and then convert it to a Unicode encoding such as UTF-8. |
|||
<syntaxhighlight lang="php"> |
|||
$a = mb_convert_encoding('👦🏻👋', 'UTF-8', 'HTML-ENTITIES'); // 👦🏻👋 |
|||
function str_to_array($string) |
|||
{ |
|||
$length = grapheme_strlen($string); |
|||
$ret = []; |
|||
for ($i = 0; $i < $length; $i += 1) { |
|||
$ret[] = grapheme_substr($string, $i, 1); |
|||
} |
|||
return $ret; |
|||
} |
|||
function utf8_strrev($string) |
|||
{ |
|||
return implode(array_reverse(str_to_array($string))); |
|||
} |
|||
print_r(utf8_strrev($a)); // 👋👦🏻 |
|||
</syntaxhighlight> |
|||
=== ASCII === |
|||
<syntaxhighlight lang="php">strrev($string);</syntaxhighlight> |
|||
=={{header|PicoLisp}}== |
=={{header|PicoLisp}}== |
||
< |
<syntaxhighlight lang="picolisp">(pack (flip (chop "äöüÄÖÜß")))</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>-> "ßÜÖÄüöä"</pre> |
<pre>-> "ßÜÖÄüöä"</pre> |
||
=={{header|Pike}}== |
|||
For simple ASCII: |
|||
<syntaxhighlight lang="pike">reverse("foo");</syntaxhighlight> |
|||
{{out}} |
|||
<pre>"oof"</pre> |
|||
When dealing with Unicode (or any other supported encoding) care must |
|||
be taken primarily in the output step to serialize the Unicode string |
|||
into something the sink can handle. IO functions will throw an error |
|||
if sent raw wide strings. |
|||
<syntaxhighlight lang="pike">#charset utf8 |
|||
void main() |
|||
{ |
|||
string s = "ßÜÖÄüöää ἀρχῇ"; |
|||
write("%s\n", string_to_utf8( reverse(s) )); |
|||
}</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
ῇχρἀ ääöüÄÖÜß |
|||
</pre> |
|||
=={{header|PL/I}}== |
=={{header|PL/I}}== |
||
< |
<syntaxhighlight lang="pl/i">s = reverse(s);</syntaxhighlight> |
||
=={{header|Plain English}}== |
|||
<syntaxhighlight lang="plainenglish">To run: |
|||
Start up. |
|||
Put "asdf" into a string. |
|||
Reverse the string. |
|||
Shut down.</syntaxhighlight> |
|||
=={{header|plainTeX}}== |
|||
Works well if the string has no space (spaces are gobbled). |
|||
<syntaxhighlight lang="tex">\def\gobtoA#1\revA{}\def\gobtoB#1\revB{} |
|||
\def\reverse#1{\reversei{}#1\revA\revB\revB\revB\revB\revB\revB\revB\revB\revA} |
|||
\def\reversei#1#2#3#4#5#6#7#8#9{\gobtoB#9\revend\revB\reversei{#9#8#7#6#5#4#3#2#1}} |
|||
\def\revend\revB\reversei#1#2\revA{\gobtoA#1} |
|||
\reverse{Rosetta} |
|||
\bye</syntaxhighlight> |
|||
Output: |
|||
<pre>attesoR</pre> |
|||
=={{header|Pop11}}== |
=={{header|Pop11}}== |
||
< |
<syntaxhighlight lang="pop11">define reverse_string(s); |
||
lvars i, l = length(s); |
lvars i, l = length(s); |
||
for i from l by -1 to 1 do |
for i from l by -1 to 1 do |
||
Line 2,143: | Line 3,628: | ||
endfor; |
endfor; |
||
consstring(l); |
consstring(l); |
||
enddefine;</ |
enddefine;</syntaxhighlight> |
||
=={{header|PostScript}}== |
=={{header|PostScript}}== |
||
The following implementation works on arrays of numerics as well as characters ( string ). |
The following implementation works on arrays of numerics as well as characters ( string ). |
||
< |
<syntaxhighlight lang="postscript">/reverse{ |
||
/str exch def |
/str exch def |
||
/temp str 0 get def |
/temp str 0 get def |
||
Line 2,158: | Line 3,643: | ||
}repeat |
}repeat |
||
str pstack |
str pstack |
||
}def</ |
}def</syntaxhighlight> |
||
{{Out}} |
{{Out}} |
||
< |
<syntaxhighlight lang="postscript">[1 2 3] reverse % input |
||
[3 2 1] |
[3 2 1] |
||
(Hello World) reverse % input |
(Hello World) reverse % input |
||
(dlroW olleH)</ |
(dlroW olleH)</syntaxhighlight> |
||
=={{header|PowerBASIC}}== |
|||
<syntaxhighlight lang="powerbasic">#DIM ALL |
|||
#COMPILER PBCC 6 |
|||
FUNCTION PBMAIN () AS LONG |
|||
CON.PRINT STRREVERSE$("PowerBASIC") |
|||
END FUNCTION</syntaxhighlight> |
|||
=={{header|PowerShell}}== |
=={{header|PowerShell}}== |
||
=== For ASCII === |
|||
Test string |
Test string |
||
< |
<syntaxhighlight lang="powershell">$s = "asdf"</syntaxhighlight> |
||
===Array indexing=== |
====Array indexing==== |
||
Creating a character array from the end to the string's start and join it together into a string again. |
Creating a character array from the end to the string's start and join it together into a string again. |
||
{{works with|PowerShell|1}} |
{{works with|PowerShell|1}} |
||
< |
<syntaxhighlight lang="powershell">[string]::Join('', $s[$s.Length..0])</syntaxhighlight> |
||
{{works with|PowerShell|2}} |
{{works with|PowerShell|2}} |
||
< |
<syntaxhighlight lang="powershell">-join ($s[$s.Length..0])</syntaxhighlight> |
||
{{works with|PowerShell|2}} |
{{works with|PowerShell|2}} |
||
<lang |
<syntaxhighlight lang="powershell">[array]::Reverse($s)</syntaxhighlight> |
||
===Regular expressions=== |
====Regular expressions==== |
||
Creating a regular expression substitution which captures every character of the string in a capture group and uses a reverse-ordered string of references to those to construct the reversed string. |
Creating a regular expression substitution which captures every character of the string in a capture group and uses a reverse-ordered string of references to those to construct the reversed string. |
||
{{works with|PowerShell|1}} |
{{works with|PowerShell|1}} |
||
< |
<syntaxhighlight lang="powershell">$s -replace |
||
('(.)' * $s.Length), |
('(.)' * $s.Length), |
||
[string]::Join('', ($s.Length..1 | ForEach-Object { "`$$_" }))</ |
[string]::Join('', ($s.Length..1 | ForEach-Object { "`$$_" }))</syntaxhighlight> |
||
{{works with|PowerShell|2}} |
{{works with|PowerShell|2}} |
||
< |
<syntaxhighlight lang="powershell">$s -replace |
||
('(.)' * $s.Length), |
('(.)' * $s.Length), |
||
-join ($s.Length..1 | ForEach-Object { "`$$_" } )</ |
-join ($s.Length..1 | ForEach-Object { "`$$_" } )</syntaxhighlight> |
||
{{works with|PowerShell|3}} |
{{works with|PowerShell|3}} |
||
<syntaxhighlight lang="powershell"> |
|||
<lang PowerShell> |
|||
[Regex]::Matches( |
[Regex]::Matches($s,'.','RightToLeft').Value -join '' |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{Out}} |
|||
=== For Unicode === |
|||
<pre> |
|||
cba |
|||
==== For codepoints ==== |
|||
</pre> |
|||
Since PowerShell 7, there is a <code>EnumerateRunes()</code> method to enumerate Unicode codepoints. Enumerating codepoints works for multi-bytes characters but not for composing or joining. |
|||
<syntaxhighlight lang="powershell"> |
|||
$a = 'abc 🐧 def' |
|||
$enum = $a.EnumerateRunes() | % { "$_" } |
|||
-join $enum[$enum.length..0] # fed 🐧 cba |
|||
</syntaxhighlight> |
|||
==== For graphemes ==== |
|||
For composing or joining, enumerating graphemes is required. |
|||
<syntaxhighlight lang="powershell"> |
|||
$a = "aeiou`u{0308}yz" |
|||
$enum = [System.Globalization.StringInfo]::GetTextElementEnumerator($a) |
|||
$arr = @() |
|||
while($enum.MoveNext()) { $arr += $enum.GetTextElement() } |
|||
[array]::reverse($arr) |
|||
$arr -join '' # zyüoiea |
|||
</syntaxhighlight> |
|||
=={{header|Prolog}}== |
=={{header|Prolog}}== |
||
{{works with|SWI Prolog}} |
{{works with|SWI Prolog}} |
||
< |
<syntaxhighlight lang="prolog">reverse("abcd", L), string_to_list(S,L).</syntaxhighlight> |
||
{{Out}} |
{{Out}} |
||
<pre> |
<pre> |
||
Line 2,206: | Line 3,723: | ||
The main workings are hidden inside the reverse/2 predicate, |
The main workings are hidden inside the reverse/2 predicate, |
||
so lets write one to see how it works: |
so lets write one to see how it works: |
||
< |
<syntaxhighlight lang="prolog">accRev([H|T], A, R) :- accRev(T, [H|A], R). |
||
accRev([], A, A). |
accRev([], A, A). |
||
rev(L,R) :- accRev(L,[],R).</ |
rev(L,R) :- accRev(L,[],R).</syntaxhighlight> |
||
=={{header|PureBasic}}== |
=={{header|PureBasic}}== |
||
< |
<syntaxhighlight lang="purebasic">Debug ReverseString("!dekrow tI")</syntaxhighlight> |
||
=={{header|Python}}== |
=={{header|Python}}== |
||
===Optimized for user input=== |
===Optimized for user input=== |
||
<lang |
<syntaxhighlight lang="python">input()[::-1]</syntaxhighlight> |
||
===Already known string=== |
===Already known string=== |
||
<lang |
<syntaxhighlight lang="python">string[::-1]</syntaxhighlight> |
||
or |
|||
<syntaxhighlight lang="python">''.join(reversed(string))</syntaxhighlight> |
|||
===Unicode reversal=== |
===Python: Unicode reversal=== |
||
(See [http://paddy3118.blogspot.com/2009/07/case-of-disappearing-over-bar.html this article] for more information) |
(See [http://paddy3118.blogspot.com/2009/07/case-of-disappearing-over-bar.html this article] for more information from which this is improved) |
||
<lang python>''' |
|||
Reverse a Unicode string with proper handling of combining characters |
|||
''' |
|||
'''Note:''' How this looks may be subject to how the tool you are using to view this page can render Unicode. |
|||
import unicodedata |
|||
<syntaxhighlight lang="python">import unicodedata |
|||
def ureverse(ustring): |
def ureverse(ustring): |
||
'Reverse a string including unicode combining characters' |
|||
''' |
|||
Reverse a string including unicode combining characters |
|||
Example: |
|||
>>> ucode = ''.join( chr(int(n, 16)) |
|||
for n in ['61', '73', '20dd', '64', '66', '305'] ) |
|||
>>> ucoderev = ureverse(ucode) |
|||
>>> ['%x' % ord(char) for char in ucoderev] |
|||
['66', '305', '64', '73', '20dd', '61'] |
|||
>>> |
|||
''' |
|||
groupedchars = [] |
groupedchars = [] |
||
uchar = list(ustring) |
uchar = list(ustring) |
||
while uchar: |
while uchar: |
||
if |
if unicodedata.combining(uchar[0]) != 0: |
||
groupedchars[-1] += uchar.pop(0) |
groupedchars[-1] += uchar.pop(0) |
||
else: |
else: |
||
Line 2,249: | Line 3,757: | ||
# Grouped reversal |
# Grouped reversal |
||
groupedchars = groupedchars[::-1] |
groupedchars = groupedchars[::-1] |
||
return ''.join(groupedchars) |
return ''.join(groupedchars) |
||
def say_string(s): |
|||
return ' '.join([s, '=', ' | '.join(unicodedata.name(ch, '') for ch in s)]) |
|||
def say_rev(s): |
|||
print(f"Input: {say_string(s)}") |
|||
print(f"Character reversed: {say_string(s[::-1])}") |
|||
print(f"Unicode reversed: {say_string(ureverse(s))}") |
|||
print(f"Unicode reverse²: {say_string(ureverse(ureverse(s)))}") |
|||
if __name__ == '__main__': |
if __name__ == '__main__': |
||
ucode = ''.join( |
ucode = ''.join(chr(int(n[2:], 16)) for n in |
||
'U+0041 U+030A U+0073 U+0074 U+0072 U+006F U+0308 U+006D'.split()) |
|||
say_rev(ucode)</syntaxhighlight> |
|||
print (ucode) |
|||
{{out}} |
|||
print (ucoderev)</lang> |
|||
<pre>Input: Åström = LATIN CAPITAL LETTER A | COMBINING RING ABOVE | LATIN SMALL LETTER S | LATIN SMALL LETTER T | LATIN SMALL LETTER R | LATIN SMALL LETTER O | COMBINING DIAERESIS | LATIN SMALL LETTER M |
|||
Character reversed: m̈orts̊A = LATIN SMALL LETTER M | COMBINING DIAERESIS | LATIN SMALL LETTER O | LATIN SMALL LETTER R | LATIN SMALL LETTER T | LATIN SMALL LETTER S | COMBINING RING ABOVE | LATIN CAPITAL LETTER A |
|||
Unicode reversed: mörtsÅ = LATIN SMALL LETTER M | LATIN SMALL LETTER O | COMBINING DIAERESIS | LATIN SMALL LETTER R | LATIN SMALL LETTER T | LATIN SMALL LETTER S | LATIN CAPITAL LETTER A | COMBINING RING ABOVE |
|||
Unicode reverse²: Åström = LATIN CAPITAL LETTER A | COMBINING RING ABOVE | LATIN SMALL LETTER S | LATIN SMALL LETTER T | LATIN SMALL LETTER R | LATIN SMALL LETTER O | COMBINING DIAERESIS | LATIN SMALL LETTER M |
|||
</pre> |
|||
If this code is then used: |
|||
<syntaxhighlight lang="python">ucode = ''.join(chr(int(n[2:], 16)) for n in |
|||
'U+006B U+0301 U+0075 U+032D U+006F U+0304 U+0301 U+006E'.split()) |
|||
say_rev(ucode)</syntaxhighlight> |
|||
It produces this output |
|||
{{out}} |
|||
<pre>Input: ḱṷṓn = LATIN SMALL LETTER K | COMBINING ACUTE ACCENT | LATIN SMALL LETTER U | COMBINING CIRCUMFLEX ACCENT BELOW | LATIN SMALL LETTER O | COMBINING MACRON | COMBINING ACUTE ACCENT | LATIN SMALL LETTER N |
|||
Character reversed: ń̄o̭úk = LATIN SMALL LETTER N | COMBINING ACUTE ACCENT | COMBINING MACRON | LATIN SMALL LETTER O | COMBINING CIRCUMFLEX ACCENT BELOW | LATIN SMALL LETTER U | COMBINING ACUTE ACCENT | LATIN SMALL LETTER K |
|||
Unicode reversed: nṓṷḱ = LATIN SMALL LETTER N | LATIN SMALL LETTER O | COMBINING MACRON | COMBINING ACUTE ACCENT | LATIN SMALL LETTER U | COMBINING CIRCUMFLEX ACCENT BELOW | LATIN SMALL LETTER K | COMBINING ACUTE ACCENT |
|||
Unicode reverse²: ḱṷṓn = LATIN SMALL LETTER K | COMBINING ACUTE ACCENT | LATIN SMALL LETTER U | COMBINING CIRCUMFLEX ACCENT BELOW | LATIN SMALL LETTER O | COMBINING MACRON | COMBINING ACUTE ACCENT | LATIN SMALL LETTER N</pre> |
|||
'''This uses the unicode string mentioned in the task:''' |
|||
<syntaxhighlight lang="python">ucode = ''.join(chr(int(n, 16)) |
|||
for n in ['61', '73', '20dd', '64', '66', '305']) |
|||
say_rev(ucode)</syntaxhighlight> |
|||
It produces this output |
|||
{{out}} |
|||
<pre>Input: as⃝df̅ = LATIN SMALL LETTER A | LATIN SMALL LETTER S | COMBINING ENCLOSING CIRCLE | LATIN SMALL LETTER D | LATIN SMALL LETTER F | COMBINING OVERLINE |
|||
Character reversed: ̅fd⃝sa = COMBINING OVERLINE | LATIN SMALL LETTER F | LATIN SMALL LETTER D | COMBINING ENCLOSING CIRCLE | LATIN SMALL LETTER S | LATIN SMALL LETTER A |
|||
Unicode reversed: f̅d⃝sa = LATIN SMALL LETTER F | COMBINING OVERLINE | LATIN SMALL LETTER D | COMBINING ENCLOSING CIRCLE | LATIN SMALL LETTER S | LATIN SMALL LETTER A |
|||
Unicode reverse²: as⃝df̅ = LATIN SMALL LETTER A | LATIN SMALL LETTER S | COMBINING ENCLOSING CIRCLE | LATIN SMALL LETTER D | LATIN SMALL LETTER F | COMBINING OVERLINE</pre> |
|||
=={{header|Quackery}}== |
|||
reverse is predefined (and applies to nests in general, including strings) as: |
|||
<syntaxhighlight lang="quackery"> [ dup nest? if |
|||
[ [] swap witheach |
|||
[ nested |
|||
swap join ] ] ] is reverse ( x --> x )</syntaxhighlight> |
|||
=={{header|Qi}}== |
=={{header|Qi}}== |
||
It's simplest just to use the common lisp REVERSE function. |
It's simplest just to use the common lisp REVERSE function. |
||
< |
<syntaxhighlight lang="qi">(REVERSE "ABCD")</syntaxhighlight> |
||
=={{header|R}}== |
=={{header|R}}== |
||
{{works with|R|2.8.1}} |
{{works with|R|2.8.1}} |
||
The following code works with UTF-8 encoded strings too. |
The following code works with UTF-8 encoded strings too. |
||
< |
<syntaxhighlight lang="r">revstring <- function(stringtorev) { |
||
return( |
return( |
||
paste( |
paste( |
||
Line 2,272: | Line 3,825: | ||
,collapse="") |
,collapse="") |
||
) |
) |
||
}</ |
}</syntaxhighlight> |
||
Alternatively (using rev() function): |
Alternatively (using rev() function): |
||
< |
<syntaxhighlight lang="r"> revstring <- function(s) paste(rev(strsplit(s,"")[[1]]),collapse="")</syntaxhighlight> |
||
< |
<syntaxhighlight lang="r">revstring("asdf") |
||
revstring("m\u00f8\u00f8se") |
revstring("m\u00f8\u00f8se") |
||
Encoding("m\u00f8\u00f8se") # just to check if on your system it's something |
Encoding("m\u00f8\u00f8se") # just to check if on your system it's something |
||
# different!</ |
# different!</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 2,289: | Line 3,842: | ||
</pre> |
</pre> |
||
R can encode strings in Latin1 and UTF-8 (the default may depend on the locale); the <tt>Encoding(string)</tt> can be used to know if the string is encoded in Latin1 or UTF-8; the encoding can be forced (<tt>Encoding(x) <- "latin1"</tt>), or we can use <tt>iconv</tt> to properly translate between encodings whenever possible. |
R can encode strings in Latin1 and UTF-8 (the default may depend on the locale); the <tt>Encoding(string)</tt> can be used to know if the string is encoded in Latin1 or UTF-8; the encoding can be forced (<tt>Encoding(x) <- "latin1"</tt>), or we can use <tt>iconv</tt> to properly translate between encodings whenever possible. |
||
=={{header|Rascal}}== |
|||
<lang rascal>import String; |
|||
reverse("string")</lang> |
|||
=={{header|Racket}}== |
=={{header|Racket}}== |
||
Line 2,298: | Line 3,847: | ||
As in Scheme: |
As in Scheme: |
||
< |
<syntaxhighlight lang="racket">#lang racket |
||
(define (string-reverse s) |
(define (string-reverse s) |
||
(list->string (reverse (string->list s)))) |
(list->string (reverse (string->list s)))) |
||
(string-reverse "aoeu")</ |
(string-reverse "aoeu")</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 2,310: | Line 3,859: | ||
"ueoa" |
"ueoa" |
||
> </pre> |
> </pre> |
||
=={{header|Raku}}== |
|||
(formerly Perl 6) |
|||
{{Works with|rakudo|2018.08}} |
|||
Raku handles graphemes, multi-byte characters and emoji correctly by default. |
|||
<syntaxhighlight lang="raku" line>say "hello world".flip; |
|||
say "as⃝df̅".flip; |
|||
say 'ℵΑΩ 駱駝道 🤔 🇸🇧 🇺🇸 🇬🇧 👨👩👧👦🆗🗺'.flip;</syntaxhighlight> |
|||
{{out}} |
|||
<pre>dlrow olleh |
|||
f̅ds⃝a |
|||
🗺🆗👨👩👧👦 🇬🇧 🇺🇸 🇸🇧 🤔 道駝駱 ΩΑℵ</pre> |
|||
=={{header|RapidQ}}== |
=={{header|RapidQ}}== |
||
<syntaxhighlight lang="vb"> |
|||
<lang vb> |
|||
print reverse$("This is a test") |
print reverse$("This is a test") |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Rascal}}== |
|||
<syntaxhighlight lang="rascal">import String; |
|||
reverse("string")</syntaxhighlight> |
|||
=={{header|Raven}}== |
=={{header|Raven}}== |
||
< |
<syntaxhighlight lang="raven">"asdf" reverse</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>fdsa</pre> |
<pre>fdsa</pre> |
||
=={{header|REBOL}}== |
=={{header|REBOL}}== |
||
< |
<syntaxhighlight lang="rebol">print reverse "asdf"</syntaxhighlight> |
||
Note the string is reversed in place. If you were using it anywhere else, you would find it reversed: |
Note the string is reversed in place. If you were using it anywhere else, you would find it reversed: |
||
< |
<syntaxhighlight lang="rebol">x: "asdf" |
||
print reverse x |
print reverse x |
||
print x ; Now reversed.</ |
print x ; Now reversed.</syntaxhighlight> |
||
REBOL/View 2.7.6.3.1 14-Mar-2008 does not handle Unicode strings. This is planned for REBOL 3. |
REBOL/View 2.7.6.3.1 14-Mar-2008 does not handle Unicode strings. This is planned for REBOL 3. |
||
=={{header|Red}}== |
|||
<syntaxhighlight lang="red">>> reverse "asdf" |
|||
== "fdsa"</syntaxhighlight> |
|||
=={{header|Refal}}== |
|||
<syntaxhighlight lang="refal">$ENTRY Go { |
|||
= <Prout <Reverse 'asdf'>>; |
|||
}; |
|||
Reverse { |
|||
(e.X) = e.X; |
|||
(e.X) s.C e.Y = <Reverse (s.C e.X) e.Y>; |
|||
e.X = <Reverse () e.X>; |
|||
};</syntaxhighlight> |
|||
{{out}} |
|||
<pre>fdsa</pre> |
|||
=={{header|ReScript}}== |
|||
<syntaxhighlight lang="rescript">let rev_string = (s) => { |
|||
let len = Js.String2.length(s) |
|||
let arr = [] |
|||
for i in 0 to (len-1) { |
|||
let c = Js.String2.get(s, len - 1 - i) |
|||
let _ = Js.Array2.push(arr, c) |
|||
} |
|||
Js.String2.concatMany("", arr) |
|||
} |
|||
Js.log(rev_string("abcdefg"))</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
$ bsc revstr.res > revstr.bs.js |
|||
$ node revstr.bs.js |
|||
gfedcba |
|||
</pre> |
|||
=={{header|Retro}}== |
=={{header|Retro}}== |
||
<syntaxhighlight lang="retro">'asdf s:reverse s:put</syntaxhighlight> |
|||
<lang Retro>with strings' |
|||
"asdf" reverse puts</lang> |
|||
=={{header|REXX}}== |
=={{header|REXX}}== |
||
All methods shown below also work with '''NULL''' values. |
All methods shown below also work with '''NULL''' values (strings with a zero length). |
||
===using REVERSE BIF=== |
===using REVERSE BIF=== |
||
< |
<syntaxhighlight lang="rexx">/*REXX program to reverse a string (and show before and after strings).*/ |
||
string1 = 'A man, a plan, a canal, Panama!' |
string1 = 'A man, a plan, a canal, Panama!' |
||
Line 2,342: | Line 3,943: | ||
say ' original string: ' string1 |
say ' original string: ' string1 |
||
say ' reversed string: ' string2 |
say ' reversed string: ' string2 |
||
/*stick a fork in it, we're done.*/</ |
/*stick a fork in it, we're done.*/</syntaxhighlight> |
||
'''output''' |
'''output''' |
||
<pre> |
<pre> |
||
Line 2,350: | Line 3,951: | ||
===using SUBSTR BIF, left to right=== |
===using SUBSTR BIF, left to right=== |
||
< |
<syntaxhighlight lang="rexx">/*REXX program to reverse a string (and show before and after strings).*/ |
||
string1 = 'A man, a plan, a canal, Panama!' |
string1 = 'A man, a plan, a canal, Panama!' |
||
Line 2,359: | Line 3,960: | ||
say ' original string: ' string1 |
say ' original string: ' string1 |
||
say ' reversed string: ' string2 |
say ' reversed string: ' string2 |
||
/*stick a fork in it, we're done.*/</ |
/*stick a fork in it, we're done.*/</syntaxhighlight> |
||
'''output''' is identical to the 1<sup>st</sup> REXX version. |
'''output''' is identical to the 1<sup>st</sup> REXX version. |
||
<br><br>(Regarding the previous example) Another method of coding an abutment (an implied concatenation) is: |
<br><br>(Regarding the previous example) Another method of coding an abutment (an implied concatenation) is: |
||
< |
<syntaxhighlight lang="rexx"> string2 = substr(string1,j,1) || string2 |
||
/*───── or ─────*/ |
/*───── or ─────*/ |
||
string2=substr(string1,j,1)string2</ |
string2= substr(string1,j,1)string2</syntaxhighlight> |
||
===using SUBSTR BIF, right to left=== |
===using SUBSTR BIF, right to left=== |
||
< |
<syntaxhighlight lang="rexx">/*REXX program to reverse a string (and show before and after strings).*/ |
||
string1 = 'A man, a plan, a canal, Panama!' |
string1 = 'A man, a plan, a canal, Panama!' |
||
Line 2,376: | Line 3,977: | ||
say ' original string: ' string1 |
say ' original string: ' string1 |
||
say ' reversed string: ' string2 |
say ' reversed string: ' string2 |
||
/*stick a fork in it, we're done.*/</ |
/*stick a fork in it, we're done.*/</syntaxhighlight> |
||
'''output''' is identical to the 1<sup>st</sup> version. |
'''output''' is identical to the 1<sup>st</sup> version. |
||
<br><br> |
<br><br> |
||
=={{header|Ring}}== |
|||
<syntaxhighlight lang="ring"> |
|||
cStr = "asdf" cStr2 = "" |
|||
for x = len(cStr) to 1 step -1 cStr2 += cStr[x] next |
|||
See cStr2 # fdsa |
|||
</syntaxhighlight> |
|||
=={{header|RLaB}}== |
=={{header|RLaB}}== |
||
< |
<syntaxhighlight lang="rlab">>> x = "rosettacode" |
||
rosettacode |
rosettacode |
||
Line 2,392: | Line 4,000: | ||
>> rx |
>> rx |
||
edocattesor</ |
edocattesor</syntaxhighlight> |
||
=={{header| |
=={{header|Robotic}}== |
||
<syntaxhighlight lang="robotic"> |
|||
<lang ring> |
|||
. "local1 = Main string" |
|||
cStr = "asdf" cStr2 = "" |
|||
. "local2 = Temporary string storage" |
|||
for x = len(cStr) to 1 step -1 cStr2 += cStr[x] next |
|||
. "local3 = String length" |
|||
See cStr2 # fdsa |
|||
set "$local1" to "" |
|||
</lang> |
|||
set "$local2 " to "" |
|||
set "local3" to 0 |
|||
input string "String to reverse:" |
|||
set "$local1" to "&INPUT&" |
|||
set "$local2" to "$local1" |
|||
set "local3" to "$local2.length" |
|||
loop start |
|||
set "$local1.(('local3' - 1) - 'loopcount')" to "$local2.('loopcount')" |
|||
loop for "('local3' - 1)" |
|||
* "Reversed string: &$local1& (Length: &$local1.length&)" |
|||
end |
|||
</syntaxhighlight> |
|||
=={{header|RPL}}== |
|||
{{works with|Halcyon Calc|4.2.7}} |
|||
≪ "" |
|||
OVER SIZE 1 '''FOR''' j |
|||
OVER j DUP SUB + |
|||
-1 '''STEP''' SWAP DROP |
|||
≫ '<span style="color:blue">RVSTR</span>' STO |
|||
"ABC" <span style="color:blue">RVSTR</span> |
|||
{{out}} |
|||
<pre>1: "CBA"</pre> |
|||
=={{header|Ruby}}== |
=={{header|Ruby}}== |
||
< |
<syntaxhighlight lang="ruby">str = "asdf" |
||
reversed = str.reverse |
reversed = str.reverse |
||
"résumé niño".reverse #=> "oñin émusér"</syntaxhighlight> |
|||
or |
|||
for extra credit |
|||
<lang ruby>#encoding: utf-8 |
|||
<syntaxhighlight lang="ruby"> |
|||
"résumé niño".reverse #=> "oñin émusér"</lang> |
|||
graphemes = 'as⃝df̅'.scan(/\X/) |
|||
reversed = graphemes.reverse |
|||
graphemes.join #=> "f̅ds⃝a" |
|||
</syntaxhighlight> |
|||
=={{header|Run BASIC}}== |
=={{header|Run BASIC}}== |
||
{{works with|Just BASIC}} |
|||
<lang runbasic>string$ = "123456789abcdefghijk" |
|||
{{works with|Liberty BASIC}} |
|||
{{works with|QBasic}} |
|||
{{works with|Yabasic}} |
|||
<syntaxhighlight lang="runbasic">string$ = "123456789abcdefghijk" |
|||
for i = len(string$) to 1 step -1 |
for i = len(string$) to 1 step -1 |
||
print mid$(string$,i,1); |
print mid$(string$,i,1); |
||
next i</ |
next i</syntaxhighlight> |
||
=={{header|Rust}}== |
=={{header|Rust}}== |
||
<lang rust>extern crate unicode_segmentation; |
|||
use unicode_segmentation::UnicodeSegmentation; |
|||
Reversing ASCII byte-slice (in-place): |
|||
fn main() { |
|||
let s = "一二三四五六七八九十"; |
|||
let s2 = "as⃝df̅"; |
|||
let reversed: String = s.chars().rev().collect(); |
|||
let reversed2: String = UnicodeSegmentation::graphemes(s2, true) |
|||
.rev().collect(); |
|||
println!("{}", reversed); |
|||
println!("{}", reversed2); |
|||
}</lang> |
|||
<syntaxhighlight lang="rust">let mut buffer = b"abcdef".to_vec(); |
|||
{{out}} |
|||
buffer.reverse(); |
|||
十九八七六五四三二一 |
|||
assert_eq!(buffer, b"fedcba");</syntaxhighlight> |
|||
Reversing Unicode scalar values: |
|||
f̅ds⃝a |
|||
<syntaxhighlight lang="rust">let output: String = "一二三四五六七八九十".chars().rev().collect(); |
|||
assert_eq!(output, "十九八七六五四三二一");</syntaxhighlight> |
|||
Reversing a <code>Chars</code> iterator doesn't solve the complete problem, because it iterates unicode scalar values, which doesn't account for combining marks: |
|||
<syntaxhighlight lang="rust">let output: String = "as⃝df̅".chars().rev().collect(); |
|||
assert_ne!(output, "f̅ds⃝a"); // should be this |
|||
assert_eq!(output, "̅fd⃝sa");</syntaxhighlight> |
|||
Reversing graphemes clusters, which is provided by the [https://unicode-rs.github.io/unicode-segmentation/unicode_segmentation/struct.Graphemes.html unicode-segmentation] crate, solves the problem: |
|||
<syntaxhighlight lang="rust">use unicode_segmentation::UnicodeSegmentation; |
|||
let output: String = "as⃝df̅".graphemes(true).rev().collect(); |
|||
assert_eq!(output, "f̅ds⃝a");</syntaxhighlight> |
|||
=={{header|S-lang}}== |
=={{header|S-lang}}== |
||
Here is an 8-bit version: |
Here is an 8-bit version: |
||
< |
<syntaxhighlight lang="s-lang">variable sa = "Hello, World", aa = Char_Type[strlen(sa)+1]; |
||
init_char_array(aa, sa); |
init_char_array(aa, sa); |
||
array_reverse(aa); |
array_reverse(aa); |
||
Line 2,444: | Line 4,092: | ||
% onto the array: |
% onto the array: |
||
print( strjoin(array_map(String_Type, &char, aa), "") );</ |
print( strjoin(array_map(String_Type, &char, aa), "") );</syntaxhighlight> |
||
Output: "dlroW ,olleH" |
Output: "dlroW ,olleH" |
||
Line 2,451: | Line 4,099: | ||
Side note: If needed, strbytelen() would give total length of string. |
Side note: If needed, strbytelen() would give total length of string. |
||
< |
<syntaxhighlight lang="s-lang">define init_unicode_array(a, buf) |
||
{ |
{ |
||
variable len = strbytelen(buf), ch, p0 = 0, p1 = 0; |
variable len = strbytelen(buf), ch, p0 = 0, p1 = 0; |
||
Line 2,467: | Line 4,115: | ||
array_reverse(au); |
array_reverse(au); |
||
% print(au); |
% print(au); |
||
print(strjoin(array_map(String_Type, &char, au), "") );</ |
print(strjoin(array_map(String_Type, &char, au), "") );</syntaxhighlight> |
||
Output: "ηψόκ νὴτ ὸπἀ ωζίρωνγ ὲΣ" |
Output: "ηψόκ νὴτ ὸπἀ ωζίρωνγ ὲΣ" |
||
Line 2,475: | Line 4,123: | ||
=={{header|SAS}}== |
=={{header|SAS}}== |
||
< |
<syntaxhighlight lang="sas">data _null_; |
||
length a b $11; |
length a b $11; |
||
a="I am Legend"; |
a="I am Legend"; |
||
Line 2,481: | Line 4,129: | ||
put a; |
put a; |
||
put b; |
put b; |
||
run;</ |
run;</syntaxhighlight> |
||
=={{header|Sather}}== |
=={{header|Sather}}== |
||
< |
<syntaxhighlight lang="sather">class MAIN is |
||
main is |
main is |
||
s ::= "asdf"; |
s ::= "asdf"; |
||
Line 2,490: | Line 4,138: | ||
-- current implementation does not handle multibyte encodings correctly |
-- current implementation does not handle multibyte encodings correctly |
||
end; |
end; |
||
end;</ |
end;</syntaxhighlight> |
||
=={{header|Scala}}== |
=={{header|Scala}}== |
||
Easy way: |
Easy way: |
||
< |
<syntaxhighlight lang="scala">"asdf".reverse</syntaxhighlight> |
||
Slightly less easy way: |
Slightly less easy way: |
||
< |
<syntaxhighlight lang="scala">"asdf".foldRight("")((a,b) => b+a)</syntaxhighlight> |
||
Unicode-aware, method 1: |
Unicode-aware, method 1: |
||
< |
<syntaxhighlight lang="scala">def reverse(s: String) = { |
||
import java.text.{Normalizer,BreakIterator} |
import java.text.{Normalizer,BreakIterator} |
||
val norm = Normalizer.normalize(s, Normalizer.Form.NFKC) // waffle -> waffle (optional) |
val norm = Normalizer.normalize(s, Normalizer.Form.NFKC) // waffle -> waffle (optional) |
||
Line 2,511: | Line 4,159: | ||
} |
} |
||
break(it, it.first).mkString |
break(it, it.first).mkString |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>scala> reverse("as⃝df̅") |
<pre>scala> reverse("as⃝df̅") |
||
Line 2,517: | Line 4,165: | ||
Unicode-aware, method 2: I can't guarantee it get all the cases, but it does work with combining characters as well as supplementary characters. I did not bother to preserve the order of newline characters, and I didn't even consider directionality beyond just ruling it out. |
Unicode-aware, method 2: I can't guarantee it get all the cases, but it does work with combining characters as well as supplementary characters. I did not bother to preserve the order of newline characters, and I didn't even consider directionality beyond just ruling it out. |
||
< |
<syntaxhighlight lang="scala">def reverseString(s: String) = { |
||
import java.lang.Character._ |
import java.lang.Character._ |
||
Line 2,546: | Line 4,194: | ||
} |
} |
||
recurse(splitString(s), Nil) |
recurse(splitString(s), Nil) |
||
}</ |
}</syntaxhighlight> |
||
REPL on Windows doesn't handle Unicode, so I'll show the bytes instead: |
REPL on Windows doesn't handle Unicode, so I'll show the bytes instead: |
||
<pre> |
<pre> |
||
Line 2,557: | Line 4,205: | ||
=={{header|Scheme}}== |
=={{header|Scheme}}== |
||
< |
<syntaxhighlight lang="scheme">(define (string-reverse s) |
||
(list->string (reverse (string->list s))))</ |
(list->string (reverse (string->list s))))</syntaxhighlight> |
||
> (string-reverse "asdf") |
> (string-reverse "asdf") |
||
Line 2,567: | Line 4,215: | ||
=={{header|Sed}}== |
=={{header|Sed}}== |
||
< |
<syntaxhighlight lang="sed">#!/bin/sed -f |
||
/../! b |
/../! b |
||
Line 2,584: | Line 4,232: | ||
# Remove the newline markers |
# Remove the newline markers |
||
s/\n//g</ |
s/\n//g</syntaxhighlight> |
||
=={{header|Seed7}}== |
=={{header|Seed7}}== |
||
Seed7 strings are encoded with UTF-32 therefore no special Unicode solution is necessary |
Seed7 strings are encoded with UTF-32 therefore no special Unicode solution is necessary. The following demonstrates one way of reversing a string with a user-defined function. |
||
<lang |
<syntaxhighlight lang="ada" line="1">$ include "seed7_05.s7i"; |
||
const func string: |
const func string: reverso(in string: stri) is func |
||
result |
result |
||
var string: result is ""; |
var string: result is ""; |
||
Line 2,603: | Line 4,251: | ||
const proc: main is func |
const proc: main is func |
||
begin |
begin |
||
writeln( |
writeln(reverso("Was it a cat I saw")); |
||
end func;</syntaxhighlight>The following demonstrates the use of the built-in 'reverse' function:<syntaxhighlight lang="ada" line="1"> |
|||
end func;</lang> |
|||
$ include "seed7_05.s7i"; |
|||
{{out}} |
|||
const proc: main is func |
|||
begin |
|||
writeln(reverse("Was it a cat I saw?")); |
|||
end func; |
|||
</syntaxhighlight>{{out}} |
|||
<pre> |
<pre> |
||
was I tac a ti saW |
was I tac a ti saW |
||
</pre> |
|||
=={{header|Self}}== |
|||
In-place reversal: |
|||
<syntaxhighlight lang="self">'asdf' copyMutable reverse</syntaxhighlight> |
|||
=={{header|SenseTalk}}== |
|||
<syntaxhighlight lang="sensetalk">put "asdf" reversed -- reverse on the fly |
|||
set imp to "rumpelstiltskin" |
|||
reverse imp -- reverse in place |
|||
put imp |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
fdsa |
|||
nikstlitslepmur |
|||
</pre> |
</pre> |
||
Line 2,614: | Line 4,285: | ||
There is a library function to reverse any Sequence. This works for strings since strings are Sequences of characters. |
There is a library function to reverse any Sequence. This works for strings since strings are Sequences of characters. |
||
< |
<syntaxhighlight lang="sequencel">import <Utilities/Sequence.sl>; |
||
main(args(2)) := Sequence::reverse(args[1]);</ |
main(args(2)) := Sequence::reverse(args[1]);</syntaxhighlight> |
||
'''The Library Function:''' |
'''The Library Function:''' |
||
The following is the library implementation of the reverse function. |
The following is the library implementation of the reverse function. |
||
< |
<syntaxhighlight lang="sequencel">reverse<T> : T(1) -> T(1); |
||
reverse(list(1))[i] := |
reverse(list(1))[i] := |
||
let |
let |
||
range := - ((1 ... size(list)) - (size(list) + 1)); |
range := - ((1 ... size(list)) - (size(list) + 1)); |
||
in |
in |
||
list[i] foreach i within range;</ |
list[i] foreach i within range;</syntaxhighlight> |
||
=={{header|Sidef}}== |
=={{header|Sidef}}== |
||
< |
<syntaxhighlight lang="ruby">"asdf".reverse; # fdsa |
||
"résumé niño".reverse; # oñin émusér</ |
"résumé niño".reverse; # oñin émusér</syntaxhighlight> |
||
=={{header| |
=={{header|Simula}}== |
||
<syntaxhighlight lang="simula"> |
|||
In-place reversal: |
|||
BEGIN |
|||
<lang self>'asdf' copyMutable reverse</lang> |
|||
TEXT PROCEDURE REV(S); TEXT S; |
|||
BEGIN |
|||
TEXT T; |
|||
INTEGER L,R; |
|||
T :- COPY(S); |
|||
L := 1; R := T.LENGTH; |
|||
WHILE L < R DO |
|||
BEGIN |
|||
CHARACTER CL,CR; |
|||
T.SETPOS(L); CL := T.GETCHAR; |
|||
T.SETPOS(R); CR := T.GETCHAR; |
|||
T.SETPOS(L); T.PUTCHAR(CR); |
|||
T.SETPOS(R); T.PUTCHAR(CL); |
|||
L := L+1; |
|||
R := R-1; |
|||
END; |
|||
REV :- T; |
|||
END REV; |
|||
TEXT INP; |
|||
INP :- "asdf"; |
|||
OUTTEXT(INP); OUTIMAGE; |
|||
OUTTEXT(REV(INP)); OUTIMAGE; |
|||
END |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
asdf |
|||
fdsa |
|||
</pre> |
|||
=={{header|Slate}}== |
=={{header|Slate}}== |
||
In-place reversal: |
In-place reversal: |
||
<lang |
<syntaxhighlight lang="slate">'asdf' reverse</syntaxhighlight> |
||
Non-destructive reversal: |
Non-destructive reversal: |
||
<lang |
<syntaxhighlight lang="slate">'asdf' reversed</syntaxhighlight> |
||
=={{header|Smalltalk}}== |
=={{header|Smalltalk}}== |
||
<lang |
<syntaxhighlight lang="smalltalk">'asdf' reverse</syntaxhighlight> |
||
{{works with|Smalltalk/X}} |
{{works with|Smalltalk/X}} |
||
the above does inplace, destructive reverse. It is usually better to use |
the above does inplace, destructive reverse. It is usually better to use |
||
<lang |
<syntaxhighlight lang="smalltalk">'asdf' reversed</syntaxhighlight> |
||
which returns a new string. |
which returns a new string. |
||
=={{header|SNOBOL4}}== |
=={{header|SNOBOL4}}== |
||
ASCII-only |
ASCII-only |
||
< |
<syntaxhighlight lang="snobol"> output = reverse(reverse("reverse")) |
||
end</ |
end</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>reverse</pre> |
<pre>reverse</pre> |
||
=={{header|Standard ML}}== |
=={{header|Standard ML}}== |
||
< |
<syntaxhighlight lang="sml">val str_reverse = implode o rev o explode; |
||
val string = "asdf"; |
val string = "asdf"; |
||
val reversed = str_reverse string;</ |
val reversed = str_reverse string;</syntaxhighlight> |
||
=={{header|Stata}}== |
|||
Use '''[https://www.stata.com/help.cgi?f_strreverse strreverse]''' if there are only ASCII characters, and '''[https://www.stata.com/help.cgi?f_ustrreverse ustrreverse]''' if there are Unicode characters in the string. |
|||
<syntaxhighlight lang="stata">. scalar s="ARS LONGA VITA BREVIS" |
|||
. di strreverse(s) |
|||
SIVERB ATIV AGNOL SRA |
|||
. scalar s="Ἐν ἀρχῇ ἐποίησεν ὁ θεὸς τὸν οὐρανὸν καὶ τὴν γῆν" |
|||
. di ustrreverse(s) |
|||
νῆγ νὴτ ὶακ νὸναρὐο νὸτ ςὸεθ ὁ νεσηίοπἐ ῇχρἀ νἘ</syntaxhighlight> |
|||
=={{header|Stringle}}== |
|||
This inputs a string from the user and outputs its reverse. The <code>\</code> ''reverse'' operator reverses any string. |
|||
<syntaxhighlight lang="stringle">$ \$</syntaxhighlight> |
|||
=={{header|Swift}}== |
=={{header|Swift}}== |
||
Swift's strings are iterated by <code>Character</code>s, which represent "Unicode grapheme clusters", so reversing it reverses it with combining characters too: |
Swift's strings are iterated by <code>Character</code>s, which represent "Unicode grapheme clusters", so reversing it reverses it with combining characters too: |
||
{{works with|Swift|2.x+}} |
{{works with|Swift|2.x+}} |
||
< |
<syntaxhighlight lang="swift">func reverseString(s: String) -> String { |
||
return String(s.characters.reverse()) |
return String(s.characters.reverse()) |
||
} |
} |
||
print(reverseString("asdf")) |
print(reverseString("asdf")) |
||
print(reverseString("as⃝df̅"))</ |
print(reverseString("as⃝df̅"))</syntaxhighlight> |
||
{{works with|Swift|1.x}} |
{{works with|Swift|1.x}} |
||
< |
<syntaxhighlight lang="swift">func reverseString(s: String) -> String { |
||
return String(reverse(s)) |
return String(reverse(s)) |
||
} |
} |
||
println(reverseString("asdf")) |
println(reverseString("asdf")) |
||
println(reverseString("as⃝df̅"))</ |
println(reverseString("as⃝df̅"))</syntaxhighlight> |
||
{{out}} |
|||
<pre> |
|||
fdsa |
|||
f̅ds⃝a |
|||
</pre> |
|||
=={{header|Symsyn}}== |
|||
<syntaxhighlight lang="symsyn"> |
|||
| reverse string |
|||
c : 'abcdefghijklmnopqrstuvwxyz' |
|||
d : ' ' |
|||
c [] |
|||
i |
|||
#c j |
|||
- j |
|||
if i < j |
|||
c.i d 1 |
|||
c.j c.i 1 |
|||
d c.j |
|||
- j |
|||
+ i |
|||
goif |
|||
endif |
|||
c [] |
|||
</syntaxhighlight> |
|||
OR |
|||
<syntaxhighlight lang="symsyn"> |
|||
c : 'abcdefghijklmnopqrstuvwxyz' |
|||
c [] |
|||
$s |
|||
#c j |
|||
if j > 0 |
|||
- j |
|||
+ c.j $s 1 |
|||
goif |
|||
endif |
|||
$s [] |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
abcdefghijklmnopqrstuvwxyz |
|||
zyxwvutsrqponmlkjihgfedcba |
|||
</pre> |
|||
=={{header|Tailspin}}== |
|||
<syntaxhighlight lang="tailspin"> |
|||
templates reverse |
|||
'$:[ $... ] -> $(last..first:-1)...;' ! |
|||
end reverse |
|||
'asdf' -> reverse -> !OUT::write |
|||
' |
|||
' -> !OUT::write |
|||
'as⃝df̅' -> reverse -> !OUT::write |
|||
</syntaxhighlight> |
|||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 2,682: | Line 4,465: | ||
=={{header|Tcl}}== |
=={{header|Tcl}}== |
||
< |
<syntaxhighlight lang="tcl">package require Tcl 8.5 |
||
string reverse asdf</ |
string reverse asdf</syntaxhighlight> |
||
=={{header|TI-83 BASIC}}== |
=={{header|TI-83 BASIC}}== |
||
Note: length( and sub( can be found in the catalog. |
Note: length( and sub( can be found in the catalog. |
||
< |
<syntaxhighlight lang="ti83b">:Str1 |
||
:For(I,1,length(Ans)-1 |
:For(I,1,length(Ans)-1 |
||
:sub(Ans,2I,1)+Ans |
:sub(Ans,2I,1)+Ans |
||
:End |
:End |
||
:sub(Ans,1,I→Str1</ |
:sub(Ans,1,I→Str1</syntaxhighlight> |
||
=={{header|TMG}}== |
|||
Unix TMG: |
|||
<syntaxhighlight lang="unixtmg">prog: parse(str); |
|||
str: smark any(!<<>>) scopy str/done = { 1 2 }; |
|||
done: ;</syntaxhighlight> |
|||
=={{header|Tosh}}== |
|||
<syntaxhighlight lang="tosh">when flag clicked |
|||
ask "Say something..." and wait |
|||
set i to (length of answer) |
|||
set inv to "" |
|||
repeat until i = 0 |
|||
set inv to (join (inv) (letter (i) of answer)) |
|||
change i by -1 |
|||
end |
|||
say inv</syntaxhighlight> |
|||
=={{header|Transd}}== |
|||
<syntaxhighlight lang="scheme">#lang transd |
|||
MainModule : { |
|||
_start: (lambda (with s "as⃝df̅" |
|||
(textout (reverse s)) |
|||
// reversing user input |
|||
(textout "\nPlease, enter a string: ") |
|||
(textout "Input: " (reverse (read s))) |
|||
)) |
|||
}</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
̅fd⃝sa |
|||
Please, enter a string: Hello! |
|||
Input: !olleH |
|||
</pre> |
|||
=={{header|Turing}}== |
=={{header|Turing}}== |
||
Iterative solution, for character shovelers: |
|||
<lang Turing> |
|||
% Reverse a string |
|||
<syntaxhighlight lang="turing">function reverse (s : string) : string |
|||
var input : string (100) |
|||
var rs := "" |
|||
for i : 0 .. length (s) - 1 |
|||
rs := rs + s (length (s) - i) |
|||
end for |
|||
result rs |
|||
end reverse |
|||
put |
put reverse ("iterative example") |
||
put reverse (reverse ("iterative example"))</syntaxhighlight> |
|||
get input |
|||
{{out}} |
|||
var count : int := length(input) |
|||
<pre> |
|||
loop |
|||
elpmaxe evitareti |
|||
if count >= 1 then |
|||
iterative example |
|||
put input(count) .. |
|||
</pre> |
|||
Recursive solution, more natural in Turing: |
|||
<syntaxhighlight lang="turing">function reverse (s : string) : string |
|||
if s = "" then |
|||
result s |
|||
else |
else |
||
result reverse (s (2 .. *)) + s (1) |
|||
exit |
|||
end if |
end if |
||
end reverse |
|||
count := count - 1 |
|||
end loop |
|||
put reverse ("recursive example") |
|||
</lang> |
|||
put reverse (reverse ("recursive example"))</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
elpmaxe evisrucer |
|||
recursive example |
|||
</pre> |
|||
=={{header|TUSCRIPT}}== |
=={{header|TUSCRIPT}}== |
||
< |
<syntaxhighlight lang="tuscript">$$ MODE TUSCRIPT |
||
SET input="was it really a big fat cat i saw" |
SET input="was it really a big fat cat i saw" |
||
SET reversetext=TURN (input) |
SET reversetext=TURN (input) |
||
PRINT "before: ",input |
PRINT "before: ",input |
||
PRINT "after: ",reversetext</ |
PRINT "after: ",reversetext</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 2,726: | Line 4,564: | ||
=={{header|UNIX Shell}}== |
=={{header|UNIX Shell}}== |
||
< |
<syntaxhighlight lang="bash"> |
||
#!/bin/bash |
#!/bin/bash |
||
str=abcde |
str=abcde |
||
Line 2,733: | Line 4,571: | ||
echo $rev |
echo $rev |
||
</syntaxhighlight> |
|||
</lang> |
|||
'''or''' |
'''or''' |
||
< |
<syntaxhighlight lang="bash"> |
||
str='i43go1342iu 23iu4o 23iu14i324y 2i13' |
str='i43go1342iu 23iu4o 23iu14i324y 2i13' |
||
rev <<< "$str" |
rev <<< "$str" |
||
#rev is not built-in function, though is in /usr/bin/rev |
#rev is not built-in function, though is in /usr/bin/rev |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Unlambda}}== |
=={{header|Unlambda}}== |
||
Reverse the whole input: |
Reverse the whole input: |
||
< |
<syntaxhighlight lang="unlambda">``@c`d``s`|k`@c</syntaxhighlight> |
||
=={{header|Ursala}}== |
=={{header|Ursala}}== |
||
< |
<syntaxhighlight lang="ursala">#import std |
||
#cast %s |
#cast %s |
||
Line 2,754: | Line 4,592: | ||
example = ~&x 'asdf' |
example = ~&x 'asdf' |
||
verbose_example = reverse 'asdf'</ |
verbose_example = reverse 'asdf'</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 2,760: | Line 4,598: | ||
</pre> |
</pre> |
||
=={{ |
=={{header|Vala}}== |
||
<syntaxhighlight lang="vala">int main (string[] args) { |
|||
if (args.length < 2) { |
|||
stdout.printf ("Please, input a string.\n"); |
|||
return 0; |
|||
} |
|||
var str = new StringBuilder (); |
|||
for (var i = 1; i < args.length; i++) { |
|||
str.append (args[i] + " "); |
|||
} |
|||
stdout.printf ("%s\n", str.str.strip ().reverse ()); |
|||
return 0; |
|||
}</syntaxhighlight> |
|||
=={{header|VBA}}== |
|||
===Non-recursive version=== |
===Non-recursive version=== |
||
< |
<syntaxhighlight lang="vba">Public Function Reverse(aString as String) as String |
||
' returns the reversed string |
' returns the reversed string |
||
dim L as integer 'length of string |
dim L as integer 'length of string |
||
Line 2,773: | Line 4,625: | ||
next |
next |
||
Reverse = newString |
Reverse = newString |
||
End Function</ |
End Function</syntaxhighlight> |
||
===Recursive version=== |
===Recursive version=== |
||
< |
<syntaxhighlight lang="vba">Public Function RReverse(aString As String) As String |
||
'returns the reversed string |
'returns the reversed string |
||
'do it recursively: cut the string in two, reverse these fragments and put them back together in reverse order |
'do it recursively: cut the string in two, reverse these fragments and put them back together in reverse order |
||
Line 2,788: | Line 4,640: | ||
RReverse = RReverse(Right$(aString, L - M)) & RReverse(Left$(aString, M)) |
RReverse = RReverse(Right$(aString, L - M)) & RReverse(Left$(aString, M)) |
||
End If |
End If |
||
End Function</ |
End Function</syntaxhighlight> |
||
===Example dialogue=== |
===Example dialogue=== |
||
<pre> |
<pre> |
||
Line 2,803: | Line 4,655: | ||
=={{header|VBScript}}== |
=={{header|VBScript}}== |
||
{{works with|Windows Script Host|*}} |
{{works with|Windows Script Host|*}} |
||
<syntaxhighlight lang="vbscript"> |
|||
<lang VBScript> |
|||
WScript.Echo StrReverse("asdf") |
WScript.Echo StrReverse("asdf") |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Vedit macro language}}== |
=={{header|Vedit macro language}}== |
||
This routine reads the text from current line, reverses it and stores the reversed string in text register 10: |
This routine reads the text from current line, reverses it and stores the reversed string in text register 10: |
||
< |
<syntaxhighlight lang="vedit">Reg_Empty(10) |
||
for (BOL; !At_EOL; Char) { |
for (BOL; !At_EOL; Char) { |
||
Reg_Copy_Block(10, CP, CP+1, INSERT) |
Reg_Copy_Block(10, CP, CP+1, INSERT) |
||
}</ |
}</syntaxhighlight> |
||
This routine reverses the current line in-place: |
This routine reverses the current line in-place: |
||
< |
<syntaxhighlight lang="vedit">BOL |
||
while (!At_EOL) { |
while (!At_EOL) { |
||
Block_Copy(EOL_pos-1, EOL_pos, DELETE) |
Block_Copy(EOL_pos-1, EOL_pos, DELETE) |
||
}</ |
}</syntaxhighlight> |
||
=={{header|Vim Script}}== |
|||
Take a buffer with the following content: |
|||
# Lines 1 and 2, the strings to reverse |
|||
# Line 3, comment |
|||
# Lines 4 to 6, the Vim Script function |
|||
# Lines 7 and 8, calling the Vim Script function twice, in the first instance using line 1's content for the argument and in the second instance line 2's content. |
|||
# Line 9, comment |
|||
<pre> |
|||
asdf |
|||
as⃝df̅ |
|||
"""""""""""""""""""""""" |
|||
function Reverse(chars) |
|||
call append(line('$'),join(reverse(split(a:chars, '\zs')), "")) |
|||
endfunction |
|||
call Reverse(getline(1)) |
|||
call Reverse(getline(2)) |
|||
"""""""""""""""""""""""" |
|||
</pre> |
|||
On entering ''':''' (Command-line mode), then typing '''4,8so''' (and {Enter}), the function and two call commands will be sourced and executed. Output is appended to the end of the buffer at lines 10 and 11. |
|||
{{out}} |
|||
<pre> |
|||
fdsa |
|||
f̅ds⃝a |
|||
</pre> |
|||
This illustrates reversing the simple ASCII text string as well as the one with Unicode combining characters ― the latter keeping s+combining enclosing circle (U+0073,U+20DD) together and f+macron (U+0066,U+0305) together. |
|||
=={{header|Visual Basic}}== |
|||
{{works with|Visual Basic|6}} |
|||
<syntaxhighlight lang="vb">Debug.Print VBA.StrReverse("Visual Basic")</syntaxhighlight> |
|||
=={{header|Visual Basic .NET}}== |
=={{header|Visual Basic .NET}}== |
||
'''Compiler:''' >= Visual Basic 2012 |
|||
<lang vbnet> Function Reverse(ByVal s As String) As String |
|||
Dim t() as Char = s.toCharArray |
|||
Includes both a simple version and a version that uses .NET's built-in ability to enumerate strings by grapheme to support combining characters. |
|||
Array.reverse(t) |
|||
Return new String(t) |
|||
Since the windows console may not support Unicode, the program can optionally redirect its output to a file. |
|||
End Function</lang> |
|||
<syntaxhighlight lang="vbnet">#Const REDIRECTOUT = True |
|||
Module Program |
|||
Const OUTPATH = "out.txt" |
|||
ReadOnly TestCases As String() = {"asdf", "as⃝df̅", "Les Misérables"} |
|||
' SIMPLE VERSION |
|||
Function Reverse(s As String) As String |
|||
Dim t = s.ToCharArray() |
|||
Array.Reverse(t) |
|||
Return New String(t) |
|||
End Function |
|||
' EXTRA CREDIT VERSION |
|||
Function ReverseElements(s As String) As String |
|||
' In .NET, a text element is series of code units that is displayed as one character, and so reversing the text |
|||
' elements of the string correctly handles combining character sequences and surrogate pairs. |
|||
Dim elements = Globalization.StringInfo.GetTextElementEnumerator(s) |
|||
Return String.Concat(AsEnumerable(elements).OfType(Of String).Reverse()) |
|||
End Function |
|||
' Wraps an IEnumerator, allowing it to be used as an IEnumerable. |
|||
Iterator Function AsEnumerable(enumerator As IEnumerator) As IEnumerable |
|||
Do While enumerator.MoveNext() |
|||
Yield enumerator.Current |
|||
Loop |
|||
End Function |
|||
Sub Main() |
|||
Const INDENT = " " |
|||
#If REDIRECTOUT Then |
|||
Const OUTPATH = "out.txt" |
|||
Using s = IO.File.Open(OUTPATH, IO.FileMode.Create), |
|||
sw As New IO.StreamWriter(s) |
|||
Console.SetOut(sw) |
|||
#Else |
|||
Try |
|||
Console.OutputEncoding = Text.Encoding.ASCII |
|||
Console.OutputEncoding = Text.Encoding.UTF8 |
|||
Console.OutputEncoding = Text.Encoding.Unicode |
|||
Catch ex As Exception |
|||
Console.WriteLine("Failed to set console encoding to Unicode." & vbLf) |
|||
End Try |
|||
#End If |
|||
For Each c In TestCases |
|||
Console.WriteLine(c) |
|||
Console.WriteLine(INDENT & "SIMPLE: " & Reverse(c)) |
|||
Console.WriteLine(INDENT & "ELEMENTS: " & ReverseElements(c)) |
|||
Console.WriteLine() |
|||
Next |
|||
#If REDIRECTOUT Then |
|||
End Using |
|||
#End If |
|||
End Sub |
|||
End Module</syntaxhighlight> |
|||
{{out|note=copied from Notepad}} |
|||
Output is presented using non-fixed-width typeface to properly display combining characters. |
|||
<pre style="font-family:TimesNewRoman,Times New Roman,Times,serif">asdf |
|||
SIMPLE: fdsa |
|||
ELEMENTS: fdsa |
|||
as⃝df̅ |
|||
SIMPLE: ̅fd⃝sa |
|||
ELEMENTS: f̅ds⃝a |
|||
Les Misérables |
|||
SIMPLE: selbaŕesiM seL |
|||
ELEMENTS: selbarésiM seL</pre> |
|||
=={{header|Wart}}== |
=={{header|Wart}}== |
||
< |
<syntaxhighlight lang="wart">(rev "asdf")</syntaxhighlight> |
||
Wart doesn't support |
Wart doesn't support Unicode yet. |
||
=={{header|V (Vlang)}}== |
|||
<syntaxhighlight lang="v (vlang)">const list = |
|||
(' |
|||
Hello world! |
|||
你好世界! |
|||
Salamu, Dunia! |
|||
こんにちは世界! |
|||
¡Hola Mundo! |
|||
Chào thế giới! |
|||
Hallo Welt! |
|||
') |
|||
fn main() { |
|||
for line in list.split('\n') {if line !='' {println(reverse_string(line))}} |
|||
} |
|||
fn reverse_string(word string) string { |
|||
return word.runes().reverse().string() |
|||
}</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
!dlrow olleH |
|||
!界世好你 |
|||
!ainuD ,umalaS |
|||
!界世はちにんこ |
|||
!odnuM aloH¡ |
|||
!iớig ếht oàhC |
|||
!tleW ollaH |
|||
</pre> |
|||
=={{header|Wren}}== |
|||
{{libheader|Wren-str}} |
|||
{{libheader|Wren-upc}} |
|||
<syntaxhighlight lang="wren">import "./str" for Str |
|||
import "./upc" for Graphemes |
|||
for (word in ["asdf", "josé", "møøse", "was it a car or a cat I saw", "😀🚂🦊"]) { |
|||
System.print(Str.reverse(word)) |
|||
} |
|||
for (word in ["as⃝df̅", "ℵΑΩ 駱駝道 🤔 🇸🇧 🇺🇸 🇬🇧 👨👩👧👦🆗🗺"]) { |
|||
System.print(Graphemes.new(word).toList[-1..0].join()) |
|||
}</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
fdsa |
|||
ésoj |
|||
esøøm |
|||
was I tac a ro rac a ti saw |
|||
🦊🚂😀 |
|||
f̅ds⃝a |
|||
🗺🆗👨👩👧👦 🇬🇧 🇺🇸 🇸🇧 🤔 道駝駱 ΩΑℵ |
|||
</pre> |
|||
=={{header|Wortel}}== |
=={{header|Wortel}}== |
||
< |
<syntaxhighlight lang="wortel">; the @rev operator reverses strings and arrays |
||
@rev "abc" ; returns "cba" |
@rev "abc" ; returns "cba" |
||
; or the same thing using a pointer expression |
; or the same thing using a pointer expression |
||
!~r "abc"</ |
!~r "abc"</syntaxhighlight> |
||
=={{header|XBS}}== |
|||
Using the standard library |
|||
<syntaxhighlight lang="xbs">log(string.reverse("Hello"))</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
olleH |
|||
</pre> |
|||
Using [[JavaScript]] methods |
|||
<syntaxhighlight lang="xbs">log("Hello"->split("")->reverse()->join(""));</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
olleH |
|||
</pre> |
|||
Using a custom method |
|||
<syntaxhighlight lang="xbs">func ReverseString(String){ |
|||
set Final = ""; |
|||
for(i=?String-1;0;-1){ |
|||
Final+=String[i]; |
|||
} |
|||
send Final; |
|||
} |
|||
log(ReverseString("Hello"));</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
elloH |
|||
</pre> |
|||
=={{header|XPL0}}== |
=={{header|XPL0}}== |
||
< |
<syntaxhighlight lang="xpl0">include c:\cxpl\codes; \intrinsic 'code' declarations |
||
string 0; \use zero-terminated strings, instead of MSb terminated |
string 0; \use zero-terminated strings, instead of MSb terminated |
||
Line 2,860: | Line 4,901: | ||
Text(0, RevStr("abc")); CrLf(0); |
Text(0, RevStr("abc")); CrLf(0); |
||
Text(0, RevStr("Able was I ere I saw Elba.")); CrLf(0); |
Text(0, RevStr("Able was I ere I saw Elba.")); CrLf(0); |
||
]</ |
]</syntaxhighlight> |
||
Output: |
Output: |
||
Line 2,872: | Line 4,913: | ||
=={{header|Yorick}}== |
=={{header|Yorick}}== |
||
This only handles ASCII characters. It works by converting a string to an array of char; dropping the last character (which is the null byte); reversing the order of the characters; then converting back to a string. |
This only handles ASCII characters. It works by converting a string to an array of char; dropping the last character (which is the null byte); reversing the order of the characters; then converting back to a string. |
||
< |
<syntaxhighlight lang="yorick">strchar(strchar("asdf")(:-1)(::-1))</syntaxhighlight> |
||
=={{header|Z80 Assembly}}== |
|||
This method uses the stack as a temporary store to reverse the order of characters in a string, and self-modifying code to restore the loop counter. |
|||
<syntaxhighlight lang="z80">PrintChar equ $BB5A ;Amstrad CPC bios call |
|||
Terminator equ 0 ;null terminator for strings |
|||
org $8000 |
|||
ld hl, StringA |
|||
call ReverseString |
|||
ld hl, StringA |
|||
call PrintString |
|||
ret ;return to basic |
|||
StringA: |
|||
byte "12345678",0 |
|||
;;;; SUBROUTINES |
|||
GetStringLength: |
|||
;HL = STRING. RETURNS LENGTH IN B. LENGTH IS ONE-INDEXED AND DOES NOT INCLUDE TERMINATOR. |
|||
ld b,0 ;clear B |
|||
loop_getStringLength: |
|||
ld a,(hl) ;read the next char |
|||
cp Terminator ;is it the terminator? |
|||
ret z ;if so, exit |
|||
inc hl ;point HL to next character |
|||
inc b ;increase tally |
|||
jr loop_getStringLength ;repeat |
|||
ReverseString: |
|||
;reverse the order of letters in a text string. |
|||
;e.g. "ABCD" -> "DCBA" |
|||
;the terminator stays put. |
|||
;INPUT: HL = SOURCE ADDRESS OF STRING |
|||
push de |
|||
push hl |
|||
push hl |
|||
call GetStringLength |
|||
pop hl |
|||
pop de ;LD DE,HL |
|||
LD a,b ;LOAD B INTO A |
|||
LD (SMC_ReverseString+1),a ;STORE IT LATER IN THE CODE SO WE CAN RETRIEVE IT. |
|||
; TO RECAP, BOTH HL AND DE POINT TO THE BEGINNING OF THE STRING WE WANT TO REVERSE. B EQUALS THE LENGTH OF THE STRING. |
|||
; B HAS BEEN BACKED UP WITHOUT USING THE STACK BY STORING IT AS THE OPERAND OF A LATER INSTRUCTION THAT LOADS B WITH A NUMERIC VALUE. |
|||
; PUSH BC WOULD NOT HAVE WORKED SINCE THE PROGRAM NEEDS TO PUSH EACH LETTER OF THE STRING DURING THE LOOP. |
|||
LOOP_REVERSESTRING_PUSH: |
|||
;start at the beginning of the string and push each letter in it, except the terminator. |
|||
ld a,(de) |
|||
push af |
|||
inc de |
|||
djnz LOOP_REVERSESTRING_PUSH |
|||
SMC_ReverseString: |
|||
ld b,$42 ;LETS US PRESERVE B WITHOUT PUSHING IT. THE $42 IS OVERWRITTEN WITH THE STRING'S LENGTH. |
|||
LOOP_REVERSESTRING_POP: |
|||
;Starting at the beginning of the string, pop A off the stack and store it into the string. This puts the letters back in the reverse |
|||
; order. |
|||
pop af |
|||
ld (hl),a |
|||
inc hl |
|||
djnz LOOP_REVERSESTRING_POP |
|||
pop de |
|||
ret</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
87654321 |
|||
</pre> |
|||
=={{header|zkl}}== |
=={{header|zkl}}== |
||
Line 2,892: | Line 5,007: | ||
{{omit from|Openscad}} |
{{omit from|Openscad}} |
||
[[Wikipedia::https://en.wikipedia.org/wiki/Comparison_of_programming_languages_%28string_functions%29#reverse]] |
[[Wikipedia::https://en.wikipedia.org/wiki/Comparison_of_programming_languages_%28string_functions%29#reverse]] |
||
=={{header|Zoea}}== |
|||
<syntaxhighlight lang="zoea"> |
|||
program: reverse_string |
|||
input: xyzzy |
|||
output: yzzyx |
|||
</syntaxhighlight> |
|||
=={{header|Zoea Visual}}== |
|||
[http://zoea.co.uk/examples/zv-rc/Reverse_string.png Reverse string] |
|||
=={{header|Zig}}== |
|||
We can use `.*` to dereference a literal string pointer to an array, and use `std.mem.reverse` to reverse the slice of that array in-place: |
|||
<syntaxhighlight lang="zig"> |
|||
var s = "socat".*; |
|||
std.mem.reverse(u8, &s); |
|||
</syntaxhighlight> |
|||
or: |
|||
<syntaxhighlight lang="zig"> |
|||
var s = "socat".*; |
|||
std.mem.reverse(u8, s[0..]); |
|||
</syntaxhighlight> |
|||
String `s` now becomes `"tacos"`. |
|||
Tested on version 0.9.0. Reference: [https://ziglang.org/documentation/0.9.0/#String-Literals-and-Unicode-Code-Point-Literals]. |
Latest revision as of 12:26, 10 August 2024
![Task](http://static.miraheze.org/rosettacodewiki/thumb/b/ba/Rcode-button-task-crushed.png/64px-Rcode-button-task-crushed.png)
You are encouraged to solve this task according to the task description, using any language you may know.
- Task
Take a string and reverse it.
For example, "asdf" becomes "fdsa".
- Extra credit
Preserve Unicode combining characters.
For example, "as⃝df̅" becomes "f̅ds⃝a", not "̅fd⃝sa".
- Metrics
- Counting
- Word frequency
- Letter frequency
- Jewels and stones
- I before E except after C
- Bioinformatics/base count
- Count occurrences of a substring
- Count how many vowels and consonants occur in a string
- Remove/replace
- XXXX redacted
- Conjugate a Latin verb
- Remove vowels from a string
- String interpolation (included)
- Strip block comments
- Strip comments from a string
- Strip a set of characters from a string
- Strip whitespace from a string -- top and tail
- Strip control codes and extended characters from a string
- Anagrams/Derangements/shuffling
- Word wheel
- ABC problem
- Sattolo cycle
- Knuth shuffle
- Ordered words
- Superpermutation minimisation
- Textonyms (using a phone text pad)
- Anagrams
- Anagrams/Deranged anagrams
- Permutations/Derangements
- Find/Search/Determine
- ABC words
- Odd words
- Word ladder
- Semordnilap
- Word search
- Wordiff (game)
- String matching
- Tea cup rim text
- Alternade words
- Changeable words
- State name puzzle
- String comparison
- Unique characters
- Unique characters in each string
- Extract file extension
- Levenshtein distance
- Palindrome detection
- Common list elements
- Longest common suffix
- Longest common prefix
- Compare a list of strings
- Longest common substring
- Find common directory path
- Words from neighbour ones
- Change e letters to i in words
- Non-continuous subsequences
- Longest common subsequence
- Longest palindromic substrings
- Longest increasing subsequence
- Words containing "the" substring
- Sum of the digits of n is substring of n
- Determine if a string is numeric
- Determine if a string is collapsible
- Determine if a string is squeezable
- Determine if a string has all unique characters
- Determine if a string has all the same characters
- Longest substrings without repeating characters
- Find words which contains all the vowels
- Find words which contain the most consonants
- Find words which contains more than 3 vowels
- Find words whose first and last three letters are equal
- Find words with alternating vowels and consonants
- Formatting
- Substring
- Rep-string
- Word wrap
- String case
- Align columns
- Literals/String
- Repeat a string
- Brace expansion
- Brace expansion using ranges
- Reverse a string
- Phrase reversals
- Comma quibbling
- Special characters
- String concatenation
- Substring/Top and tail
- Commatizing numbers
- Reverse words in a string
- Suffixation of decimal numbers
- Long literals, with continuations
- Numerical and alphabetical suffixes
- Abbreviations, easy
- Abbreviations, simple
- Abbreviations, automatic
- Song lyrics/poems/Mad Libs/phrases
- Mad Libs
- Magic 8-ball
- 99 bottles of beer
- The Name Game (a song)
- The Old lady swallowed a fly
- The Twelve Days of Christmas
- Tokenize
- Text between
- Tokenize a string
- Word break problem
- Tokenize a string with escaping
- Split a character string based on change of character
- Sequences
0815
This program reverses each line of its input.
}:r: Start reader loop.
!~>& Push a character to the "stack".
<:a:=- Stop reading on newline.
^:r:
@> Rotate the newline to the end and enqueue a sentinel 0.
{~ Dequeue and rotate the first character into place.
}:p:
${~ Print the current character until it's 0.
^:p:
#:r: Read again.
- Output:
echo -e "foo\nbar" | 0815 rev.0
oof
rab
11l
reversed(string)
360 Assembly
For maximum compatibility, this program uses only the basic instruction set (S/360) and an ASSIST macro (XPRNT) to keep the code as short as possible.
* Reverse a string 21/05/2016
REVERSE CSECT
USING REVERSE,R13 base register
B 72(R15) skip savearea
DC 17F'0' savearea
STM R14,R12,12(R13) prolog
ST R13,4(R15) "
ST R15,8(R13) "
LR R13,R15 "
MVC TMP(L'C),C tmp=c
LA R8,C @c[1]
LA R9,TMP+L'C-1 @tmp[n-1]
LA R6,1 i=1
LA R7,L'C n=length(c)
LOOPI CR R6,R7 do i=1 to n
BH ELOOPI leave i
MVC 0(1,R8),0(R9) substr(c,i,1)=substr(tmp,n-i+1,1)
LA R8,1(R8) @c=@c+1
BCTR R9,0 @tmp=@tmp-1
LA R6,1(R6) i=i+1
B LOOPI next i
ELOOPI XPRNT C,L'C print c
L R13,4(0,R13) epilog
LM R14,R12,12(R13) "
XR R15,R15 "
BR R14 exit
C DC CL12'edoC attesoR'
TMP DS CL12
REGEQU
END REVERSE
- Output:
Rosetta Code
This second example uses MVCIN introduced in S/370 architecture.
* Reverse a string 25/04/2020
REVERSEI CSECT
USING REVERSEI,R13 base register
B 72(R15) skip savearea
DC 17F'0' savearea
STM R14,R12,12(R13) prolog
ST R13,4(R15) "
ST R15,8(R13) "
LR R13,R15 "
MVCIN BB,AA+L'AA-1
XPRNT BB,L'BB print bb
L R13,4(0,R13) epilog
LM R14,R12,12(R13) "
XR R15,R15 "
BR R14 exit
AA DC CL12'edoC attesoR' a
BB DS CL(L'AA) b
REGEQU
END REVERSEI
- Output:
Rosetta Code
8080 Assembly
This is a routine that reverses a string with a terminator in place.
Back when the 8080 was commonly used, there wasn't really a set standard about how to store strings.
Zero-terminated strings were already in use by the C language (and therefore, programs written in it).
CP/M, on the other hand, used $
as a string terminator. (Later versions would even allow
the programmer to set it himself with a system call!) Therefore, to allow for some flexibility,
this routine also allows you to set it yourself, using the A register.
There were other ways of representing strings, like setting the high bit of the last character to mark
the end (saves a byte per string, but halves the character set size), or prepending the length
(making it unnecessary to scan through the string to find the end, but capping string size at
255 bytes), or even storing tuples of lengths and pointers (easy for a garbage collector to manage).
These are not supported, as they would be completely different routines, though the arrayrev
entry point will reverse a byte array if you already have its start and end.
Unicode is not supported either. While it wouldn't be impossible to do, I think writing a full UTF-8 implementation is beyond the scope of the task.
org 100h
jmp test
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Reverse a string under HL in place
;; strrev0: reverse a zero-terminated string
;; strrev: reverse a string terminated by the value in A
;; arrayrev: reverse bytes starting at DE and ending at HL
;; Destroys a, b, d, e, h, l registers.
strrev0: xra a ; Zero A
strrev: mov d,h ; Copy string begin to DE
mov e,l
dcx h
strrev_end: inx h ; Find string end in HL
cmp m
jnz strrev_end
dcx h ; Point HL to last character
arrayrev: mov a,h ; If HL<DE, we're done
cmp d
rc
mov a,l
cmp e
rc
ldax d ; Get low character in string
mov b,m ; Get high character in string
mov m,a ; Swap them
mov a,b
stax d
inx d ; Move the low pointer up,
dcx h ; and the high pointer down
jmp arrayrev
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Test code (CP/M): ask the user for a string, and reverse it
prompt: db " :gnirts a retne esaelP$"
bufdef: db 127, 0
buf: ds 128 ; one extra byte that will remain 0
newline: lxi d,newline_str
mvi c,9
jmp 5
newline_str: db 13, 10, "$"
test: ;; Reverse and output the prompt
mvi a,'$' ; CP/M string is $-terminated
lxi h,prompt ; Reverse the string
call strrev
lxi d,prompt ; Output the string
mvi c,9
call 5
;; Get input and reverse it
lxi d,bufdef
mvi c,10
call 5
call newline
lxi h,buf
call strrev0 ; 0-terminated due to buffer definition
;; Output reversed input
lxi h,buf
loop: mov e,m
xra a
ora e
rz ; Stop when done
mvi c,2
push h
call 5
pop h
inx h
jmp loop
8th
In 8th strings are UTF-8 and the language retains characters per-se:
"abc" s:rev
- Output:
"cba"
ACL2
(reverse "hello")
ACL2 does not support unicode.
Action!
PROC Reverse(CHAR ARRAY src,dst)
BYTE i,j
i=1 j=src(0) dst(0)=j
WHILE j>0
DO
dst(j)=src(i)
i==+1 j==-1
OD
RETURN
PROC Test(CHAR ARRAY src)
CHAR ARRAY dst(40)
Reverse(src,dst)
PrintF("'%S' -> '%S'%E",src,dst)
RETURN
PROC Main()
Test("Hello World!")
Test("123456789")
Test("!noitcA iratA")
RETURN
- Output:
Screenshot from Atari 8-bit computer
'Hello World!' -> '!dlroW olleH' '123456789' -> '987654321' '!noitcA iratA' -> 'Atari Action!'
ActionScript
function reverseString(string:String):String
{
var reversed:String = new String();
for(var i:int = string.length -1; i >= 0; i--)
reversed += string.charAt(i);
return reversed;
}
function reverseStringCQAlternative(string:String):String
{
return string.split('').reverse().join('');
}
Ada
with Ada.Text_IO; use Ada.Text_IO;
procedure Reverse_String is
function Reverse_It (Item : String) return String is
Result : String (Item'Range);
begin
for I in Item'range loop
Result (Result'Last - I + Item'First) := Item (I);
end loop;
return Result;
end Reverse_It;
begin
Put_Line (Reverse_It (Get_Line));
end Reverse_String;
Agda
Using the Agda standard library, version 1.7 .
module ReverseString where
open import Data.String using (String ; fromList ; toList)
open import Data.List using (reverse)
reverse-string : String → String
reverse-string s = fromList (reverse (toList s))
Aime
o_(b_reverse("Hello, World!"), "\n");
ALGOL 68
PROC reverse = (REF STRING s)VOID:
FOR i TO UPB s OVER 2 DO
CHAR c = s[i];
s[i] := s[UPB s - i + 1];
s[UPB s - i + 1] := c
OD;
main:
(
STRING text := "Was it a cat I saw";
reverse(text);
print((text, new line))
)
- Output:
was I tac a ti saW
Amazing Hopper
#include <hopper.h>
main:
s="mañana será otro día"
reverse(s),strtoutf8, println
{0}return
- Output:
aíd orto áres anañam
Apex
String str = 'Hello World!';
str = str.reverse();
system.debug(str);
APL
⌽'asdf'
fdsa
AppleScript
reverseString("Hello World!")
on reverseString(str)
reverse of characters of str as string
end reverseString
NB. Since coercing lists to string involves the interpolation of the current value of AppleScript's text item delimiters between the list items, it's considered best practice to set the delimiters explicitly to their default value of {""}
(or just ""
) before doing an operation like this, in case they've been set to something else elsewhere in the script:
reverseString("Hello World!")
on reverseString(str)
set astid to AppleScript's text item delimiters
set AppleScript's text item delimiters to ""
set reversedString to reverse of characters of str as text
set AppleScript's text item delimiters to astid
return reversedString
end reverseString
Or, if we want a polymorphic reverse() for both strings and lists, we can define it either in terms of a generic fold/reduce, or using the built-in method for lists:
-- Using either a generic foldr(f, a, xs)
-- reverse1 :: [a] -> [a]
on reverse1(xs)
script rev
on |λ|(a, x)
a & x
end |λ|
end script
if class of xs is text then
foldr(rev, {}, xs) as text
else
foldr(rev, {}, xs)
end if
end reverse1
-- or the built-in reverse method for lists
-- reverse2 :: [a] -> [a]
on reverse2(xs)
if class of xs is text then
(reverse of characters of xs) as text
else
reverse of xs
end if
end reverse2
-- TESTING reverse1 and reverse2 with same string and list ---------------------------------------------------------------------------
on run
script test
on |λ|(f)
map(f, ["Hello there !", {1, 2, 3, 4, 5}])
end |λ|
end script
map(test, [reverse1, reverse2])
end run
-- GENERIC FUNCTIONS ---------------------------------------------------------------------------
-- foldr :: (a -> b -> a) -> a -> [b] -> a
on foldr(f, startValue, xs)
tell mReturn(f)
set v to startValue
set lng to length of xs
repeat with i from lng to 1 by -1
set v to |λ|(v, item i of xs, i, xs)
end repeat
return v
end tell
end foldr
-- map :: (a -> b) -> [a] -> [b]
on map(f, xs)
tell mReturn(f)
set lng to length of xs
set lst to {}
repeat with i from 1 to lng
set end of lst to |λ|(item i of xs, i, xs)
end repeat
return lst
end tell
end map
-- Lift 2nd class handler function into 1st class script wrapper
-- mReturn :: Handler -> Script
on mReturn(f)
if class of f is script then
f
else
script
property |λ| : f
end script
end if
end mReturn
- Output:
{{"! ereht olleH", {5, 4, 3, 2, 1}},
{"! ereht olleH", {5, 4, 3, 2, 1}}}
Arturo
str: "Hello World"
print reverse str
- Output:
dlroW olleH
AutoHotkey
- "Normal" version:
MsgBox % reverse("asdf")
reverse(string)
{
Loop, Parse, string
reversed := A_LoopField . reversed
Return reversed
}
- A ''much'' slower version:
Reverse(String){ ; credit to Rseding91
If (A_IsUnicode){
SLen := StrLen(String) * 2
VarSetCapacity(RString,SLen)
Loop,Parse,String
NumPut(Asc(A_LoopField),RString,SLen-(A_Index * 2),"UShort")
} Else {
SLen := StrLen(String)
VarSetCapacity(RString,SLen)
Loop,Parse,String
NumPut(Asc(A_LoopField),RString,SLen-A_Index,"UChar")
}
VarSetCapacity(RString,-1)
Return RString
}
AutoIt
#AutoIt Version: 3.2.10.0
$mystring="asdf"
$reverse_string = ""
$string_length = StringLen($mystring)
For $i = 1 to $string_length
$last_n_chrs = StringRight($mystring, $i)
$nth_chr = StringTrimRight($last_n_chrs, $i-1)
$reverse_string= $reverse_string & $nth_chr
Next
MsgBox(0, "Reversed string is:", $reverse_string)
Avail
"asfd" reversed
AWK
function reverse(s)
{
p = ""
for(i=length(s); i > 0; i--) { p = p substr(s, i, 1) }
return p
}
BEGIN {
print reverse("edoCattesoR")
}
- Recursive
function reverse(s ,l)
{
l = length(s)
return l < 2 ? s:( substr(s,l,1) reverse(substr(s,1,l-1)) )
}
BEGIN {
print reverse("edoCattesoR")
}
- using split, then joining in front
# Usage: awk -f reverse.awk -v s=Rosetta
function rev(s, i,len,a,r) {
len = split(s, a, "")
#for (i in a) r = a[i] r # may not work - order is not guaranteed !
for (i=1; i<=len; i++) r = a[i] r
return r
}
BEGIN {
if(!s) s = "Hello, world!"
print s, "<-->", rev(s)
}
- Output:
Rosetta <--> attesoR
Babel
This example will handle UTF-8 encoded Unicode but doesn't handle combining characters.
strrev: { str2ar ar2ls reverse ls2lf ar2str }
- str2ar - this operator converts a UTF-8 encoded string to an array of Unicode codepoints
- ar2ls - this operator converts the array to a linked-list
- reverse - this operator reverses a linked-list
- ls2lf - this operator undoes the effect of ar2ls
- ar2str - this operator undoes the effect of str2ar
BaCon
OPTION UTF8 TRUE
s$ = "asdf"
PRINT REVERSE$(s$)
Unicode preservation works in BaCon 3.6 and higher.
BASIC
Applesoft BASIC
10 A$ = "THE FIVE BOXING WIZARDS JUMP QUICKLY"
20 GOSUB 100REVERSE
30 PRINT R$
40 END
100 REMREVERSE A$
110 R$ = ""
120 FOR I = 1 TO LEN(A$)
130 R$ = MID$(A$, I, 1) + R$
140 NEXT I
150 RETURN
BASIC256
s = "asdf"
print "'"; s; "' reversed is '"; reverse(s); "'"
end
function reverse(a)
b = ""
for i = 1 to length(a)
b = mid(a, i, 1) + b
next i
return b
end function
- Output:
'asdf' reversed is 'fdsa'
Commodore BASIC
Commodore BASIC 3.5 turned MID$ into an lvalue function, and assigning a string of the same length to MID$ replaces the characters instead of allocating a new string, so the reversal can be done in-place:
100 INPUT "STRING";S$
110 FOR I=1 TO INT(LEN(S$)/2)
120 : J=LEN(S$)+1-I
130 : T$=MID$(S$,I,1)
140 : MID$(S$,I,1) = MID$(S$,J,1)
150 : MID$(S$,J,1) = T$
160 NEXT I
170 PRINT S$
- Output:
STRING? THIS IS A TEST TSET A SI SIHT READY.
IS-BASIC
100 INPUT PROMPT "String: ":TX$
120 LET REV$=""
130 FOR I=LEN(TX$) TO 1 STEP-1
140 LET REV$=REV$&TX$(I)
150 NEXT
160 PRINT REV$
QuickBASIC
function reverse$(a$)
b$ = ""
for i = 1 to len(a$)
b$ = mid$(a$, i, 1) + b$
next i
reverse$ = b$
end function
Sinclair ZX81 BASIC
10 INPUT S$
20 LET T$=""
30 FOR I=LEN S$ TO 1 STEP -1
40 LET T$=T$+S$(I)
50 NEXT I
60 PRINT T$
True BASIC
FUNCTION reverse$(a$)
LET b$ = ""
FOR i = 1 TO LEN(a$)
LET b$ = (a$)[i:i+1-1] & b$
NEXT i
LET reverse$ = b$
END FUNCTION
LET s$ = "asdf"
PRINT "'"; s$; "' reversed is '"; reverse$(s$); "'"
END
- Output:
'asdf' reversed is 'fdsa'
XBasic
PROGRAM "progname"
VERSION "0.0000"
DECLARE FUNCTION Entry ()
DECLARE FUNCTION reverse$ (a$)
FUNCTION Entry ()
s$ = "asdf"
PRINT "'"; s$; "' reversed is '"; reverse$(s$); "'"
END FUNCTION
FUNCTION reverse$ (a$)
b$ = ""
FOR i = 1 TO LEN(a$)
b$ = MID$(a$, i, 1) + b$
NEXT i
RETURN b$
END FUNCTION
END PROGRAM
- Output:
'asdf' reversed is 'fdsa'
Yabasic
s$ = "asdf"
print "'", s$, "' reversed is '", reverse$(s$), "'"
end
sub reverse$(a$)
b$ = ""
for i = 1 to len(a$)
b$ = mid$(a$, i, 1) + b$
next i
return b$
end sub
- Output:
'asdf' reversed is 'fdsa'
Batch File
@echo off
setlocal enabledelayedexpansion
call :reverse %1 res
echo %res%
goto :eof
:reverse
set str=%~1
set cnt=0
:loop
if "%str%" equ "" (
goto :eof
)
set chr=!str:~0,1!
set str=%str:~1%
set %2=%chr%!%2!
goto loop
BBC BASIC
PRINT FNreverse("The five boxing wizards jump quickly")
END
DEF FNreverse(A$)
LOCAL B$, C%
FOR C% = LEN(A$) TO 1 STEP -1
B$ += MID$(A$,C%,1)
NEXT
= B$
Beef
Beef does not have a built-in Reverse method for strings, however one can 'extend' the builtin String class to provide a Reverse function.
using System;
namespace System
{
extension String
{
public void Reverse()
{
int i = 0;
int j = mLength - 1;
while (i < j)
{
Swap!(Ptr[i++], Ptr[j--]);
}
}
}
}
namespace StringReverse
{
class Program
{
static void Main()
{
String s = scope .("abcdef");
s.Reverse();
Console.WriteLine(s);
}
}
}
Befunge
Reads a line from stdin and write the reverse to stdout. Can be made to repeat indefinitely by removing the final @ command.
55+~>:48>*#8\#4`#:!#<#~_$>:#,_@
Binary Lambda Calculus
This 9 byte program, featured on https://www.ioccc.org/2012/tromp/hint.html, reverses its input in byte-oriented BLC:
16 46 80 17 3e f0 b7 b0 40
BQN
BQN has a reverse builtin, given as ⌽
.
⌽"racecar"
"racecar"
Bracmat
( reverse
= L x
. :?L
& @( !arg
: ?
( %?x
& utf$!x
& !x !L:?L
& ~`
)
?
)
| str$!L
)
& out$reverse$Ελληνικά
- Output:
άκινηλλΕ
Brainf***
[-]>,[>,]<[.<]
Another solution:
,----- ----- [+++++ +++++ > , ----- -----] If a newline is hit counter will be zero and input loop ends
<[.<] run all chars backwards and print them
just because it looks good we print CRLF
+++++ +++++ +++ . --- .
Brat
p "olleh".reverse #Prints "hello"
Burlesque
"Hello, world!"<-
C
#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
#include <wchar.h>
const char *sa = "abcdef";
const char *su = "as⃝df̅"; /* Should be in your native locale encoding. Mine is UTF-8 */
int is_comb(wchar_t c)
{
if (c >= 0x300 && c <= 0x36f) return 1;
if (c >= 0x1dc0 && c <= 0x1dff) return 1;
if (c >= 0x20d0 && c <= 0x20ff) return 1;
if (c >= 0xfe20 && c <= 0xfe2f) return 1;
return 0;
}
wchar_t* mb_to_wchar(const char *s)
{
wchar_t *u;
size_t len = mbstowcs(0, s, 0) + 1;
if (!len) return 0;
u = malloc(sizeof(wchar_t) * len);
mbstowcs(u, s, len);
return u;
}
wchar_t* ws_reverse(const wchar_t* u)
{
size_t len, i, j;
wchar_t *out;
for (len = 0; u[len]; len++);
out = malloc(sizeof(wchar_t) * (len + 1));
out[len] = 0;
j = 0;
while (len) {
for (i = len - 1; i && is_comb(u[i]); i--);
wcsncpy(out + j, u + i, len - i);
j += len - i;
len = i;
}
return out;
}
char *mb_reverse(const char *in)
{
size_t len;
char *out;
wchar_t *u = mb_to_wchar(in);
wchar_t *r = ws_reverse(u);
len = wcstombs(0, r, 0) + 1;
out = malloc(len);
wcstombs(out, r, len);
free(u);
free(r);
return out;
}
int main(void)
{
setlocale(LC_CTYPE, "");
printf("%s => %s\n", sa, mb_reverse(sa));
printf("%s => %s\n", su, mb_reverse(su));
return 0;
}
- Output:
abcdef => fedcba as⃝df̅ => f̅ds⃝a
#include <glib.h>
gchar *srev (const gchar *s) {
if (g_utf8_validate(s,-1,NULL)) {
return g_utf8_strreverse (s,-1);
} }
// main
int main (void) {
const gchar *t="asdf";
const gchar *u="as⃝df̅";
printf ("%s\n",srev(t));
printf ("%s\n",srev(u));
return 0;
}
C#
C# does not have a built-in Reverse method for strings, and cannot reverse them in place because they are immutable. One way to implement this is to convert the string to an array of characters, reverse that, and return a new string from the reversed array:
static string ReverseString(string input)
{
char[] inputChars = input.ToCharArray();
Array.Reverse(inputChars);
return new string(inputChars);
}
As of .Net 3.5 the LINQ-to-objects allows the Reverse() extension method to be called on a string, since String implements the IEnumerable<char> interface. Because of this, the return type of Reverse is IEnumerable<char>. Fortunately, LINQ also provides the ToArray extension method, which can be used in conjunction with the constructor of string that accepts a char array:
using System.Linq;
// ...
return new string(input.Reverse().ToArray());
// ...
Version supporting combining characters:
System.Globalization.StringInfo provides a means of separating a string into individual graphemes.
public string ReverseElements(string s)
{
// In .NET, a text element is series of code units that is displayed as one character, and so reversing the text
// elements of the string correctly handles combining character sequences and surrogate pairs.
var elements = System.Globalization.StringInfo.GetTextElementEnumerator(s);
return string.Concat(AsEnumerable(elements).OfType<string>().Reverse());
}
// Wraps an IEnumerator, allowing it to be used as an IEnumerable.
public IEnumerable AsEnumerable(IEnumerator enumerator)
{
while (enumerator.MoveNext())
yield return enumerator.Current;
}
C++
#include <string>
#include <iostream>
#include <algorithm>
int main() {
std::string s;
std::getline(std::cin, s);
std::reverse(s.begin(), s.end()); // modifies s
std::cout << s << '\n';
}
Caché ObjectScript
USER>Write $Reverse("Hello, World") dlroW ,olleH
Ceylon
shared void run() {
while(true) {
process.write("> ");
String? text = process.readLine();
if (is String text) {
print(text.reversed);
}
else {
break;
}
}
}
Clipper
Works with versions since 5, because LOCAL variables and the += operator was not implemented before.
FUNCTION Reverse(sIn)
LOCAL sOut := "", i
FOR i := Len(sIn) TO 1 STEP -1
sOut += Substr(sIn, i, 1)
NEXT
RETURN sOut
Clojure
A Simple implementation with the magic of "conj" function
(defn reverse-string [s]
"Returns a string with all characters in reverse"
(apply str (reduce conj '() s)))
Other alternatives (resorting to the "reverse" function in the standard library)
For normal strings, the reverse function can be used to do the bulk of the work. However, it returns a character sequence, which has to be converted back to a string.
a)
(defn str-reverse [s] (apply str (reverse s)))
b)
(apply str (interpose " " (reverse (.split "the quick brown fox" " "))))
Supporting combining characters
Handling combining characters present a trickier task. We need to protect the relative ordering of the combining character and the character to its left. Thus, before reversing, the characters need to be grouped.
(defn combining? [c]
(let [type (Character/getType c)]
;; currently hardcoded to the types taken from the sample string
(or (= type 6) (= type 7))))
(defn group
"Group normal characters with their combining characters"
[chars]
(cond (empty? chars) chars
(empty? (next chars)) (list chars)
:else
(let [dres (group (next chars))]
(cond (combining? (second chars)) (cons (cons (first chars)
(first dres))
(rest dres))
:else (cons (list (first chars)) dres)))))
(defn str-reverse
"Unicode-safe string reverse"
[s]
(apply str (apply concat (reverse (group s)))))
- Output:
user=> s "as⃝df̅" user=> (str-reverse s) "f̅ds⃝a"[ user=> (str-reverse (str-reverse s)) "as⃝df̅" user=>
CLU
reverse = proc (s: string) returns (string)
rslt: array[char] := array[char]$predict(1,string$size(s))
for c: char in string$chars(s) do
array[char]$addl(rslt,c)
end
return(string$ac2s(rslt))
end reverse
start_up = proc ()
po: stream := stream$primary_output()
stream$putl(po, reverse("!dlrow ,olleH"))
end start_up
- Output:
Hello, world!
COBOL
FUNCTION REVERSE('QWERTY')
CoffeeScript
"qwerty".split("").reverse().join ""
ColdFusion
You can reverse anything that can be written to the document in hashmarks (i.e. strings, numbers, now( ), etc.).
<cfset myString = "asdf" />
<cfset myString = reverse( myString ) />
Common Lisp
(reverse my-string)
Component Pascal
BlackBox Component Builder
MODULE BbtReverseString;
IMPORT StdLog;
PROCEDURE ReverseStr(str: ARRAY OF CHAR): POINTER TO ARRAY OF CHAR;
VAR
top,middle,i: INTEGER;
c: CHAR;
rStr: POINTER TO ARRAY OF CHAR;
BEGIN
NEW(rStr,LEN(str$) + 1);
top := LEN(str$) - 1; middle := (top - 1) DIV 2;
FOR i := 0 TO middle DO
rStr[i] := str[top - i];
rStr[top - i] := str[i];
END;
IF ODD(LEN(str$)) THEN rStr[middle + 1] := str[middle + 1] END;
RETURN rStr;
END ReverseStr;
PROCEDURE Do*;
VAR
x: CHAR;
BEGIN
StdLog.String("'asdf' reversed:> ");StdLog.String(ReverseStr("asdf"));StdLog.Ln
END Do;
END BbtReverseString.
Execute: ^Q BbtReverseString.Do
- Output:
'asdf' reversed:> fdsa
Cowgol
include "cowgol.coh";
include "strings.coh";
# Reverse a string in place
sub StrRev(s: [uint8]): (r: [uint8]) is
r := s;
var e := s;
while [e] != 0 loop
e := @next e;
end loop;
e := @prev e;
while e > s loop
var c := [s];
[s] := [e];
[e] := c;
s := @next s;
e := @prev e;
end loop;
end sub;
# Test
var buf: uint8[32];
var str: [uint8] := "\nesreveR";
CopyString(str, &buf[0]);
print(StrRev(&buf[0]));
- Output:
Reverse
Crystal
# version 0.21.1
strings = ["asdf", "as⃝df̅"]
strings.each do |s|
puts "#{s} -> #{s.reverse}"
end
- Output:
asdf -> fdsa as⃝df̅ -> f̅ds⃝a
D
void main() {
import std.range, std.conv;
string s1 = "hello"; // UTF-8
assert(s1.retro.text == "olleh");
wstring s2 = "hello"w; // UTF-16
assert(s2.retro.wtext == "olleh"w);
dstring s3 = "hello"d; // UTF-32
assert(s3.retro.dtext == "olleh"d);
// without using std.range:
dstring s4 = "hello"d;
assert(s4.dup.reverse == "olleh"d); // simple but inefficient (copies first, then reverses)
}
Dart
Since Dart strings are sequences of UTF-16 code units, it would not be sufficient to simply reverse the characters in strings, as this would not work with UTF-16 surrogate pairs (pairs of UTF-16 code units that represent single characters outside the Unicode BMP). However, Dart provides a method to convert strings to sequences of unicode code points (called "runes" in Dart), and these sequences can easily be reversed and used to create new strings, so a string reversal function can be written with a single line of Dart code:
String reverse(String s) => new String.fromCharCodes(s.runes.toList().reversed);
A more complete example with unit tests would look like this:
import 'package:unittest/unittest.dart';
String reverse(String s) => new String.fromCharCodes(s.runes.toList().reversed);
main() {
group("Reverse a string -", () {
test("Strings with ASCII characters are reversed correctly.", () {
expect(reverse("hello, world"), equals("dlrow ,olleh"));
});
test("Strings with non-ASCII BMP characters are reversed correctly.", () {
expect(reverse("\u4F60\u4EEC\u597D"), equals("\u597D\u4EEC\u4F60"));
});
test("Strings with non-BMP characters are reversed correctly.", () {
expect(reverse("hello, \u{1F310}"), equals("\u{1F310} ,olleh"));
});
});
}
DBL
K=
STR_OUT=
FOR J=%TRIM(STR_IN) STEP -1 UNTIL 1
DO BEGIN
INCR K
STR_OUT(K:1)=STR_IN(J:1)
END
Dc
Reversing "Hello world!" which is "22405534230753963835153736737" in Dc's numerical string representaion.
Due to using "~" this example needs GNU Dc or OpenBSD Dc.
22405534230753963835153736737 [ 256 ~ d SS 0<F LS SR 1+ ] d sF x 1 - [ 1 - d 0<F 256 * LR + ] d sF x P
!dlrow olleH
Delphi
function ReverseString(const InString: string): string;
var
i: integer;
begin
for i := Length(InString) downto 1 do
Result := Result + InString[i];
end;
You could also use this RTL function Introduced in Delphi 6:
StrUtils.ReverseString
Another alternative.
function Reverse(const s: string): string;
var
i, aLength, ahalfLength: Integer;
c: Char;
begin
Result := s;
aLength := Length(s);
ahalfLength := aLength div 2;
if aLength > 1 then
for i := 1 to ahalfLength do
begin
c := result[i];
result[i] := result[aLength - i + 1];
result[aLength - i + 1] := c;
end;
end;
All versions has the same perfomance, then StrUtils is recomended.
Draco
/* Reverse string in place */
proc nonrec reverse(*char s) void:
*char e;
char t;
e := s;
while e* /= '\e' do
e := e + 1
od;
while
e := e - 1;
s < e
do
t := e*;
e* := s*;
s* := t;
s := s + 1
od
corp
proc nonrec main() void:
*char testString = "!dlrow ,olleH";
reverse(testString);
writeln(testString)
corp
- Output:
Hello, world!
dt
"asdf" rev
DWScript
See Delphi.
Dyalect
let str = "asdf"
func String.Reverse() {
var cs = []
let len = this.Length()
for n in 1..len {
cs.Add(this[len - n])
}
String(values: cs)
}
str.Reverse()
Déjà Vu
!print concat chars "Hello"
- Output:
olleH
E
pragma.enable("accumulator")
def reverse(string) {
return accum "" for i in (0..!(string.size())).descending() { _ + string[i] }
}
EasyLang
func$ reverse s$ .
a$[] = strchars s$
for i = 1 to len a$[] div 2
swap a$[i] a$[len a$[] - i + 1]
.
return strjoin a$[]
.
print reverse "hello"
EchoLisp
(define (string-reverse string)
(list->string (reverse (string->list string))))
(string-reverse "ghij")
→ jihg
(string-reverse "un roc lamina l animal cornu")
→ unroc lamina l animal cor nu
EGL
function reverse( str string ) returns( string )
result string;
for ( i int from StrLib.characterLen( str ) to 1 decrement by 1 )
result ::= str[i:i];
end
return( result );
end
Eiffel
class
APPLICATION
create
make
feature
make
-- Demonstrate string reversal.
do
my_string := "Hello World!"
my_string.mirror
print (my_string)
end
my_string: STRING
-- Used for reversal
end
- Output:
!dlroW olleH
Ela
reverse_string str = rev len str
where len = length str
rev 0 str = ""
rev n str = toString (str : nn) +> rev nn str
where nn = n - 1
reverse_string "Hello"
- Output:
"olleH"
Another approach is to covert a string to a list, reverse a list and then convert it back to a string:
open string
fromList <| reverse <| toList "Hello" ::: String
Elena
ELENA 4.x:
import system'routines;
import extensions;
import extensions'text;
extension extension
{
reversedLiteral()
= self.toArray().sequenceReverse().summarize(new StringWriter());
}
public program()
{
console.printLine("Hello World".reversedLiteral())
}
- Output:
dlroW olleH
Elixir
Elixir handles Unicode graphemes correctly by default.
IO.puts (String.reverse "asdf")
IO.puts (String.reverse "as⃝df̅")
- Output:
fdsa f̅ds⃝a
Elm
module Main exposing (main)
import Html exposing (Html, text, div, p)
import Html.Attributes exposing (style)
change myText =
text ("reverse " ++ myText
++ " = " ++ String.reverse myText)
main =
div [style "margin" "5%", style "font-size" "1.5em"]
[change "as⃝da"
, p [] [change "a⃝su-as⃝u"]
, p [] [change "Hello!"]
]
Link to live demo: https://ellie-app.com/qdg6RP3DGCBa1
- Output:
reverse as⃝da = ad⃝sa reverse a⃝su-as⃝u = u⃝sa-us⃝a reverse Hello! = !olleH
Emacs Lisp
(reverse "Hello World")
- Output:
"dlroW olleH"
Erlang
1> lists:reverse("reverse!").
"!esrever"
Erlang also supports binary strings, which uses its binary format. There is no standard function to reverse a binary sequence, but the following one does the job well enough. It works by changing the endianness (from little to big or the opposite) of the whole sequence, effectively reversing the string.
reverse(Bin) ->
Size = size(Bin)*8,
<<T:Size/integer-little>> = Bin,
<<T:Size/integer-big>>.
- Output:
1> test:reverse(<<"hello">>). <<"olleh">>
ERRE
PROGRAM REVERSE_STRING
PROCEDURE REVERSE(A$->R$)
LOCAL I%
R$=""
FOR I=1 TO LEN(A$) DO
R$=MID$(A$,I,1)+R$
END FOR
END PROCEDURE
BEGIN
A$="THE FIVE BOXING WIZARDS JUMP QUICKLY"
REVERSE(A$->R$)
PRINT(R$)
END PROGRAM
Euler Math Toolbox
>function strrev (s) := chartostr(fliplr(strtochar(s)))
>strrev("This is a test!")
!tset a si sihT
Euphoria
include std/sequence.e
printf(1, "%s\n", {reverse("abcdef") })
Explore
The Scratch solution, which requires making variables named "i" and "inv" first, works, unmodified:
https://i.ibb.co/3c9k641/Reverse-a-string-in-Explore-using-the-Scratch-solution.png
This example uses a special block located in the Strings category:
https://i.ibb.co/4pM9G8b/Reverse-a-string-in-Explore-using-a-special-block.png
Ezhil
## இந்த நிரல் தரப்படும் சரம் ஒன்றைத் தலைகீழாகத் திருப்பி அச்சிடும்
## உதாரணமாக "abc" என்ற சரம் தரப்பட்டால் அதனைத் திருப்பி "cba" என அச்சிடும்
## "எழில்" மொழியின்மூலம் இரண்டு வகைகளில் இதனைச் செய்யலாம். இரண்டு உதாரணங்களும் இங்கே தரப்பட்டுள்ளன
நிரல்பாகம் திருப்புக (சரம்1)
## முதல் வகை
சரம்2 = ""
@( சரம்1 இல் இ) ஒவ்வொன்றாக
சரம்2 = இ + சரம்2
முடி
பின்கொடு சரம்2
முடி
நிரல்பாகம் மீண்டும்திருப்புக (சரம்1)
## இரண்டாம் வகை
சரநீளம் = len(சரம்1)
சரம்2 = ""
@(எண் = 0, எண் < சரநீளம், எண் = எண் + 1) ஆக
சரம்2 = எடு(சரம்1, எண்) + சரம்2
முடி
பின்கொடு சரம்2
முடி
அ = உள்ளீடு("ஓர் எழுத்துச் சரத்தைத் தாருங்கள் ")
பதிப்பி "நீங்கள் தந்த எழுத்துச் சரம்" அ
பதிப்பி "அதனை முதல் வகையில் திருப்பியுள்ளோம்: " திருப்புக(அ)
பதிப்பி "வேறொரு வகையில் திருப்பியுள்ளோம்: " மீண்டும்திருப்புக(அ)
F#
The function
// Reverse a string. Nigel Galloway: August 14th., 2019
let strRev α=let N=System.Globalization.StringInfo.GetTextElementEnumerator(α)
List.unfold(fun n->if n then Some(N.GetTextElement(),N.MoveNext()) else None)(N.MoveNext())|>List.rev|>String.concat ""
The Task
I was a little concerned when entering this task because in the edit window the overline appears above the d, but when previewed it is correctly above the f, using Firefox anyway. Using XTERM the output is correct with the s inside a circle but appears as sO in Firefox.
printfn "%s" (strRev "as⃝df̅")
printfn "%s" (strRev "Nigel")
- Output:
f̅ds⃝a legiN
Factor
A string is a sequence and there is a default reverse implementation for those.
"hello" reverse
string-reverse
preserves graphemes:
"as⃝df̅" string-reverse "f̅ds⃝a" = .
FALSE
This solution does not take into account combination characters:
1_
[^$1_=~][]#%
[$1_=~][,]#
This solution does take into account combination characters (except for half-marks):
1_
[^$1_=~][
$$767>\879\>&
1ø$7615>\7620\>&|
1ø$8399>\8428\>&|
[\]?
]#%
[$1_=~][,]#
Fancy
"hello world!" reverse
FBSL
A slow way
Function StrRev1(ByVal $p1)
dim $b = ""
REPEAT len(p1)
b = b & RIGHT(p1,1)
p1 = LEFT(p1,LEN(p1)-1)
END REPEAT
return b
End Function
A much faster (twice at least) way
Function StrRev2(ByVal $p1)
dim $b = "", %i
for i = len(p1) DOWNTO 1
b = b & MID(p1,i,1)
next
return b
End Function
An even faster way using PEEK, POKE, double-calls and quantity-in-hand
Function StrRev3( $s )
FOR DIM x = 1 TO LEN(s) \ 2
PEEK(@s + LEN - x, $1)
POKE(@s + LEN - x, s{x})(@s + x - 1, PEEK)
NEXT
RETURN s
end function
An even faster way using the DynC (Dynamic C) mode
DynC StringRev($theString) As String
void rev(char *str)
{
int len = strlen(str);
char *HEAD = str;
char *TAIL = str + len - 1;
char temp;
int i;
for ( i = 0; i <= len / 2; i++, HEAD++, TAIL--) {
temp = *HEAD;
*HEAD = *TAIL;
*TAIL = temp;
}
}
char *main(char* theString)
{
rev(theString);
return theString;
}
End DynC
Using DynASM, the Dynamic Assembler mode.
DYNASM RevStr(BYVAL s AS STRING) AS STRING
// get length of string
// divide by two
// setup pointers to head and tail
// iterate from 1 to (length \ 2)
// swap head with tail
// increment head pointer
// decrement tail pointer
ENTER 0, 0 // = PUSH EBP: MOV EBP, ESP
PUSH EBX // by Windows convention EBX, EDI, ESI must be saved before modification
MOV EAX, s // get string pointer
MOV ECX, EAX // duplicate it
.WHILE BYTE PTR [ECX] <> 0
INC ECX // propagate to tail
.WEND
MOV EDX, ECX // duplicate tail pointer
DEC EDX // set it to last byte before trailing zero
SUB ECX, EAX // get length in ECX in 1 CPU cycle
SHR ECX, 1 // get length \ 2 in 1 CPU cycle; that's the beauty of power-of-two division
.WHILE ECX > 0
MOV BL, [EDX] // no need to XOR; just overwrite BL and BH contents
MOV BH, [EAX] // DynAsm deduces data size from destination register sizes
MOV [EDX], BH // ditto, source register sizes
MOV [EAX], BL
INC EAX // propagate pointers
DEC EDX
DEC ECX // decrement counter
.WEND
// point to start of string again
MOV EAX, s // MOV = 1 CPU cycle, PUSH + POP = 2 CPU cycles
POP EBX // by Windows convention ESI, EDI, EBX must be restored if modified
LEAVE // = POP EBP
RET
END DYNASM
Fe
In this language, strings are very limited and are not designed to store large text data, so there are no built-in operations to work with strings. But with the C API you can make functions that convert a string to a list and vice versa.
#define MAXSTRINGLEN ( 1024 )
/* chop string to list of single character strings */
static fe_Object* chop(fe_Context *ctx, fe_Object *args) {
char buf[MAXSTRINGLEN];
int len = fe_tostring(ctx, fe_nextarg(ctx, &args), buf, sizeof(buf));
int gc = fe_savegc(ctx);
args = fe_bool(ctx, 0);
while (len > 0) {
buf[len--] = '\0';
args = fe_cons(ctx, fe_string(ctx, buf + len), args);
fe_restoregc(ctx, gc);
fe_pushgc(ctx, args);
}
return args;
}
/* pack list of strings to single string */
static fe_Object* pack(fe_Context *ctx, fe_Object *args) {
char buf[MAXSTRINGLEN], *ptr = buf;
for (args = fe_nextarg(ctx, &args); !fe_isnil(ctx, args);) {
ptr += fe_tostring(ctx, fe_nextarg(ctx, &args), ptr, buf + sizeof(buf) - ptr);
}
return fe_string(ctx, buf);
}
So, we can manipulate strings like lists:
; reverse list
(= reverse (fn (lst)
(let res nil)
(while lst
(= res (cons (car lst) res))
(= lst (cdr lst)))
res))
; chop string to list, reverse list and pack it back to string
(print (pack (reverse (chop "Hello world!"))))
Output:
!dlrow olleH
Fennel
Uses the same methods (and suffers from the same limitations) as the Lua example.
(let [example :asdf]
(string.reverse example) ; fdsa
(example:reverse) ; fdsa
nil)
Forth
Method 1
: exchange ( a1 a2 -- )
2dup c@ swap c@ rot c! swap c! ;
: reverse ( c-addr u -- )
1- bounds begin 2dup > while
2dup exchange
-1 /string
repeat 2drop ;
s" testing" 2dup reverse type \ gnitset
Method 2 Using the stack
\ reverse a string using the data stack for temporary storage
: mystring ( -- caddr len) S" ABCDEFGHIJKLMNOPQRSTUVWXYZ987654321" ;
: pushstr ( caddr len -- c..c[n]) bounds do I c@ loop ;
: popstr ( c.. c[n] caddr len -- ) bounds do I c! loop ;
: reverse ( caddr len -- ) 2dup 2>r pushstr 2r> popstr ;
Forth Console Output
mystring type ABCDEFGHIJKLMNOPQRSTUVWXYZ987654321 ok mystring 2dup reverse type 123456789ZYXWVUTSRQPONMLKJIHGFEDCBA ok
Using the Forth-2012 Xchars wordset to handle multi-byte characters
Characters accessed with C@ C! are usually bytes and can therefore only represent characters in 8-bit encodings (e.g., Latin-1). Forth-2012 added the Xchars wordset for dealing with multi-byte encodings such as UTF-8; actually these words are not needed much, because the magic of UTF-8 means that most byte-oriented code works as intended, but the present task is one of the few examples where that is not good enough.
The xchars wordset offers several ways to skin this cat; this is just one way to do it, not necessarily the best one. Because the xchars wordset currently does not support recognizing combining characters, this code does not get extra credit.
: xreverse {: c-addr u -- c-addr2 u :}
u allocate throw u + c-addr swap over u + >r begin ( from to r:end)
over r@ u< while
over r@ over - x-size dup >r - 2dup r@ cmove
swap r> + swap repeat
r> drop nip u ;
\ example use
s" ώщыē" xreverse type \ outputs "ēыщώ"
Fortran
PROGRAM Example
CHARACTER(80) :: str = "This is a string"
CHARACTER :: temp
INTEGER :: i, length
WRITE (*,*) str
length = LEN_TRIM(str) ! Ignores trailing blanks. Use LEN(str) to reverse those as well
DO i = 1, length/2
temp = str(i:i)
str(i:i) = str(length+1-i:length+1-i)
str(length+1-i:length+1-i) = temp
END DO
WRITE(*,*) str
END PROGRAM Example
- Output:
This is a string gnirts a si sihT
Another implementation that uses a recursive not-in-place algorithm:
program reverse_string
implicit none
character (*), parameter :: string = 'no devil lived on'
write (*, '(a)') string
write (*, '(a)') reverse (string)
contains
recursive function reverse (string) result (res)
implicit none
character (*), intent (in) :: string
character (len (string)) :: res
if (len (string) == 0) then
res = ''
else
res = string (len (string) :) // reverse (string (: len (string) - 1))
end if
end function reverse
end program reverse_string
- Output:
no devil lived on no devil lived on
Another shorter implementation (adapted version from stackoverflow question 10605574 how-to-reverse-a-chain-of-character-fortran-90):
program reverse_string
implicit none
character (80) :: cadena
integer :: k, n
!
cadena = "abcdefgh"
n = len_trim (cadena)
!
write (*,*) cadena
forall (k=1:n) cadena (k:k) = cadena (n-k+1:n-k+1)
write (*,*) cadena
!
end program reverse_string
- Output:
abcdefgh hgfedcba
FreeBASIC
' FB 1.05.0 Win64
Function ReverseString(s As Const String) As String
If s = "" Then Return s
Dim length As Integer = Len(s)
Dim r As String = Space(length)
For i As Integer = 0 To length - 1
r[i] = s[length - 1 - i]
Next
Return r
End Function
Dim s As String = "asdf"
Print "'"; s; "' reversed is '"; ReverseString(s); "'"
- Output:
'asdf' reversed is 'fdsa'
Frink
The built-in reverse
function reverses a string or the elements of a list.
Frink's built-in reverse[string]
is quite smart and uses a grapheme-based algorithm to handle Unicode correctly. That is, it preserves "user-perceived characters" that may consist of characters, combining accents, high-plane Unicode characters (that is, above U+FFFF,) surrogate pairs, etc. correctly.
Many languages will not work correctly with upper-plane Unicode characters because they are represented as Unicode "surrogate pairs" which are represented as two characters in a UTF-16 stream.
For example, the string "g\u0308o" represents a g with combining diaeresis, followed by the letter o. Or, in other words, "g̈o". Note that while there are three Unicode codepoints, only two "graphemes" are displayed. Using Frink's smart "reverse" function preserves these combined graphemes. A naive reverse would move the diaeresis over the o instead of the g.
println[reverse["abcdef"]]
Futhark
Futhark has no real strings beyond a little bit of syntactic sugar, so this is the same as reversing an array.
fun main(s: []i32) = s[::-1]
FutureBasic
void local fn DoIt
CFStringRef s1 = @"asdf", s2 = @""
long index
for index = len(s1) - 1 to 0 step -1
s2 = fn StringByAppendingString( s2, mid(s1,index,1) )
next
print s1,s2
end fn
window 1
fn DoIt
HandleEvents
Output:
asdf fdsa
Gambas
Click this link to run this code
Public Sub Main()
Dim sString As String = "asdf"
Dim sOutput As String
Dim siCount As Short
For siCount = Len(sString) DownTo 1
sOutput &= Mid(sString, siCount, 1)
Next
Print sOutput
End
Output:
fdsa
GAP
Reversed("abcdef");
# "fedcba"
Gema
Reverse each line in the input stream. Using built in function:
\L<U>=@reverse{$1}
Not using built in function (recursively apply substring to same rule):
\L<U1><U>=@{$2}$1
Genie
Pretty sure the output capture fails the extra credit, but that may be more local setup and font installs rather than the glib functions used.
[indent=4]
/*
Reverse a string, in Genie
valac reverse.gs
*/
init
utf8:string = "asdf"
combining:string = "asdf̅"
print utf8
print utf8.reverse()
print combining
print combining.reverse()
- Output:
prompt$ valac reverse.gs prompt$ ./reverse asdf fdsa as?df? ?fd?sa
GFA Basic
PRINT @reverse$("asdf")
'
FUNCTION reverse$(string$)
LOCAL result$,i%
result$=""
FOR i%=1 TO LEN(string$)
result$=MID$(string$,i%,1)+result$
NEXT i%
RETURN result$
ENDFUNC
Go
Functions below assume UTF-8 encoding. (The task mentions Unicode but does not specify an encoding.) Strings in Go are not restricted to be UTF-8, but Go has good support for it and works with UTF-8 most natually. As shown below, certain string conversions work in UTF-8 and the range clause over a string works in UTF-8. Go also has a Unicode package in the standard library that makes easy work of recognizing combining characters for this task.
package main
import (
"fmt"
"unicode"
"unicode/utf8"
)
// no encoding
func reverseBytes(s string) string {
r := make([]byte, len(s))
for i := 0; i < len(s); i++ {
r[i] = s[len(s)-1-i]
}
return string(r)
}
// reverseCodePoints interprets its argument as UTF-8 and ignores bytes
// that do not form valid UTF-8. return value is UTF-8.
func reverseCodePoints(s string) string {
r := make([]rune, len(s))
start := len(s)
for _, c := range s {
// quietly skip invalid UTF-8
if c != utf8.RuneError {
start--
r[start] = c
}
}
return string(r[start:])
}
// reversePreservingCombiningCharacters interprets its argument as UTF-8
// and ignores bytes that do not form valid UTF-8. return value is UTF-8.
func reversePreservingCombiningCharacters(s string) string {
if s == "" {
return ""
}
p := []rune(s)
r := make([]rune, len(p))
start := len(r)
for i := 0; i < len(p); {
// quietly skip invalid UTF-8
if p[i] == utf8.RuneError {
i++
continue
}
j := i + 1
for j < len(p) && (unicode.Is(unicode.Mn, p[j]) ||
unicode.Is(unicode.Me, p[j]) || unicode.Is(unicode.Mc, p[j])) {
j++
}
for k := j - 1; k >= i; k-- {
start--
r[start] = p[k]
}
i = j
}
return (string(r[start:]))
}
func main() {
test("asdf")
test("as⃝df̅")
}
func test(s string) {
fmt.Println("\noriginal: ", []byte(s), s)
r := reverseBytes(s)
fmt.Println("reversed bytes:", []byte(r), r)
fmt.Println("original code points:", []rune(s), s)
r = reverseCodePoints(s)
fmt.Println("reversed code points:", []rune(r), r)
r = reversePreservingCombiningCharacters(s)
fmt.Println("combining characters:", []rune(r), r)
}
- Output:
original: [97 115 100 102] asdf reversed bytes: [102 100 115 97] fdsa original code points: [97 115 100 102] asdf reversed code points: [102 100 115 97] fdsa combining characters: [102 100 115 97] fdsa original: [97 115 226 131 157 100 102 204 133] as⃝df̅ reversed bytes: [133 204 102 100 157 131 226 115 97] ��fd���sa original code points: [97 115 8413 100 102 773] as⃝df̅ reversed code points: [773 102 100 8413 115 97] ̅fd⃝sa combining characters: [102 773 100 115 8413 97] f̅ds⃝a
Groovy
Solution:
println "Able was I, 'ere I saw Elba.".reverse()
- Output:
.ablE was I ere' ,I saw elbA
Extra Credit:
def string = "as⃝df̅"
List combiningBlocks = [
Character.UnicodeBlock.COMBINING_DIACRITICAL_MARKS,
Character.UnicodeBlock.COMBINING_DIACRITICAL_MARKS_SUPPLEMENT,
Character.UnicodeBlock.COMBINING_HALF_MARKS,
Character.UnicodeBlock.COMBINING_MARKS_FOR_SYMBOLS
]
List chars = string as List
chars[1..-1].eachWithIndex { ch, i ->
if (Character.UnicodeBlock.of((char)ch) in combiningBlocks) {
chars[i..(i+1)] = chars[(i+1)..i]
}
}
println chars.reverse().join()
- Output:
f̅ds⃝a
Harbour
FUNCTION Reverse( sIn )
LOCAL cOut := "", i
FOR i := Len( sIn ) TO 1 STEP -1
cOut += Substr( sIn, i, 1 )
NEXT
RETURN cOut
Haskell
reverse = foldl (flip (:)) []
This function as defined in the Haskell Prelude.
Though variants using a helper function with an additional accumulator argument are more efficient, and are now used by default in GHC.List unless the USE_REPORT_PRELUDE key is set.
Perhaps, for example:
accumulatingReverse :: [a] -> [a]
accumulatingReverse lst =
let rev xs a = foldl (flip (:)) a xs
in rev lst []
Supporting combining characters
import Data.Char (isMark)
import Data.List (groupBy)
myReverse = concat . reverse . groupBy (const isMark)
groupBy (const isMark)
is an unusual way of splitting a string into its combined characters
HicEst
CHARACTER string = "Hello World", tmp
L = LEN( string )
DO i = 1, L/2
tmp = string(i)
string(i) = string(L-i+1)
string(L-i+1) = tmp
ENDDO
WRITE(Messagebox, Name) string
Icon and Unicon
Io
"asdf" reverse
Insitux
(reverse "hello")
J
Reverse (|.) reverses a list of items (of any shape or type).
|.'asdf'
fdsa
Extra credit: First, a function to determine whether a Unicode character is a combining character:
ranges=.16b02ff 16b036f, 16b1dbf 16b1dff, 16b20cf 16b20ff, 16bfe1f 16bfe2f
iscombining=. 2 | ranges&I.
Then we need to box groups of letters and combining characters, reverse, and unbox. The boxing function can be carried out easily with dyad cut, which uses the indices of the ones on the right as the starting points for groups of characters. For clarity, its inverse will be defined as raze, which simply runs together the items inside boxes of its argument.
split=. (<;.1~ -.@iscombining) :. ;
After this, the solution is just to reverse under the split transformation. This also takes place under J code to convert from Unicode to integers.
|.&.split&.(3 u: 7&u:) 'as⃝df̅'
f̅ds⃝a
Java
Reverse Unicode Codepoints
Reversing codepoints works in most cases when reversing single characters wherever they are encoded on multi-bytes or not. But this doesn't work for composed characters.
String reversed = new StringBuilder("as⃝df̅").reverse().toString(); // fd⃝sa
String reversed = new StringBuffer("as⃝df̅").reverse().toString(); // fd⃝sa
Alternately, you could use a for-loop with the same issue.
String string = "as⃝df̅";
StringBuilder reversed = new StringBuilder();
for (int index = string.length() - 1; index >= 0; index--)
reversed.append(string.charAt(index));
reversed; // fd⃝sa
Reverse Unicode Graphemes
A third-party solution is to use ICU4J.
A native solution, since JDK 15, is to use Pattern.compile( "\\X" )
from java.util.regex
to parse grapemes.
Another native solution, since JDK 20, is to use java.text.BreakIterator
class that now parse graphemes correctly[1].
import java.text.BreakIterator;
public class Reverse {
/* works with Java 20+ only
* cf. https://bugs.openjdk.org/browse/JDK-8291660
*/
public static StringBuilder graphemeReverse(String text) {
BreakIterator boundary = BreakIterator.getCharacterInstance();
boundary.setText(text);
StringBuilder reversed = new StringBuilder();
int end = boundary.last();
int start = boundary.previous();
while (start != BreakIterator.DONE) {
reversed.append(text.substring(start, end));
end = start;
start = boundary.previous();
}
return reversed;
}
public static void main(String[] args) throws Exception {
String a = "as⃝df̅";
System.out.println(graphemeReverse(a)); // f̅ds⃝a
}
}
JavaScript
Unicode
Split code points
split('')
(with empty string argument) works only for ASCII. For Unicode strings, one of the two following methods can be used.
example = 'Tux 🐧 penguin';
// array expansion operator
[...example].reverse().join('') // 'niugnep 🐧 xuT'
// split regexp separator with Unicode mode
example.split(/(?:)/u).reverse().join('') // 'niugnep 🐧 xuT'
// do not use
example.split('').reverse().join(''); // 'niugnep \udc27\ud83d xuT'
Split graphemes =
More generally, one would want to combine characters such as joining emojis or diacritics to be handled properly so enumerating over graphemes is a must.
a = "\u{1F466}\u{1F3FB}\u{1f44b}"; // '👦🏻👋'
// wrong behavior - ASCII sequences
a.split('').reverse().join(''); // '\udc4b🁦\ud83d'
// wrong behavior - Unicode code points
[...a].reverse().join(''); // '👋🏻👦'
a.split(/(?:)/u).reverse().join(''); // '👋🏻👦'
// correct behavior - Unicode graphemes
[...new Intl.Segmenter().segment(a)].map(x => x.segment).reverse().join('') // 👋👦🏻
ASCII
ES5
//using chained methods
function reverseStr(s) {
return s.split('').reverse().join('');
}
//fast method using for loop
function reverseStr(s) {
for (var i = s.length - 1, o = ''; i >= 0; o += s[i--]) { }
return o;
}
//fast method using while loop (faster with long strings in some browsers when compared with for loop)
function reverseStr(s) {
var i = s.length, o = '';
while (i--) o += s[i];
return o;
}
ES6
(() => {
// .reduceRight() can be useful when reversals
// are composed with some other process
let reverse1 = s => Array.from(s)
.reduceRight((a, x) => a + (x !== ' ' ? x : ' <- '), ''),
// but ( join . reverse . split ) is faster for
// simple string reversals in isolation
reverse2 = s => s.split('').reverse().join('');
return [reverse1, reverse2]
.map(f => f("Some string to be reversed"));
})();
- Output:
["desrever <- eb <- ot <- gnirts <- emoS", "desrever eb ot gnirts emoS"]
Joy
DEFINE reverse == "" [swons] fold.
"asdf" reverse putchars.
- Output:
fdsa
jq
jq's explode/implode filters are based on codepoints, and therefore "reverse_string" as defined here will reverse the sequence of codepoints. The topic of Unicode combining characters is a large one that is not touched on here.
def reverse_string: explode | reverse | implode;
Examples:
"nöel" | reverse_string # => "leön"
"as⃝df̅" | reverse_string # => "̅fd⃝sa"
Jsish
ECMAScript has no builtin string reversal, so split the characters into an array, reverse the array and join it back together.
Jsi only supports UTF-8 literals so far (in release 2.8), character by character manipulation routines of multibyte UTF-8 data will not be correct. No extra credit, yet.
var str = "Never odd or even";
puts(str);
puts(str.split('').reverse().join(''));
- Output:
Never odd or even neve ro ddo reveN
Julia
julia> reverse("hey")
"yeh"
The reverse
function reverses codepoints (because this is the right behavior for the main application of string reversal: reversed string processing by external C libraries). However, starting in Julia 0.4, you can also reverse the graphemes if you want (i.e. to reverse "visual order" including combining characters etc.) by:
julia> join(reverse(collect(graphemes("as⃝df̅"))))
"f̅ds⃝a"
K
Monadic reverse (| ) verb reverses a string or list of any shape
|"asdf"
"fdsa"
| 23 4 5 1
1 5 4 23
Kotlin
fun main(args: Array<String>) {
println("asdf".reversed())
}
L++
(include "string" "algorithm")
(main
(decl std::string s)
(std::getline std::cin s)
(std::reverse (s.begin) (s.end))
(prn s))
LabVIEW
This image is a VI Snippet, an executable image of LabVIEW code. The LabVIEW version is shown on the top-right hand corner. You can download it, then drag-and-drop it onto the LabVIEW block diagram from a file browser, and it will appear as runnable, editable code.
Lambdatalk
{S.reverse hello brave new world}
-> world new brave hello
Lang
# Inv operator
fn.println(parser.op(-asdf))
# Ouput: fdsa
# Inv operator function
fn.println(fn.inv(asdf))
# Ouput: fdsa
Lang5
: flip "" split reverse "" join ;
"qwer asdf" flip .
langur
The reverse() function will reverse a string according to graphemes.
writeln reverse("don't you know")
- Output:
wonk uoy t'nod
Lasso
local(input) = 'asdf'
#input->reverse
Using Query Expression & Array
More verbose than the string->reverse method, but this example illustrates different techniques to achieve the same result: using string->values to iterate over a string in order, inserting at position 1, and joining the resulting array as a string.
local(input = 'asdf', output = array)
with i in #input->values
do #output->insertFirst(#i)
#output->join
LC3 Assembly
A string is stored as a zero-terminated array of character codes. To reverse it, we first scan forwards until we find the end; we then move backwards again, copying each code into a block of memory we have reserved for the purpose; and finally, when we have got back to the beginning, we append a terminal zero to the new string we have created. We can then call PUTS to print it.
.ORIG 0x3000
LEA R1,STRING
LEA R2,GNIRTS
LD R3,MINUS1
NOT R5,R1
ADD R5,R5,1
SCAN LDR R4,R1,0
BRZ COPY
ADD R1,R1,1
BRNZP SCAN
COPY ADD R1,R1,R3
ADD R4,R1,R5
BRN COPIED
LDR R4,R1,0
STR R4,R2,0
ADD R2,R2,1
BRNZP COPY
COPIED AND R4,R4,0
STR R4,R2,0
LEA R0,GNIRTS
PUTS
HALT
MINUS1 .FILL 0xFFFF
STRING .STRINGZ "If thou beest he -- but O how fall'n! how chang'd"
GNIRTS .BLKW 128
.END
- Output:
d'gnahc woh !n'llaf woh O tub -- eh tseeb uoht fI
LFE
Ordinary string:
> (lists:reverse "asdf")
"fdsa"
Create a UTF-8 encoded string:
> (set encoded (binary ("åäö ð" utf8)))
#B(195 165 195 164 195 182 32 195 176)
Display it, to be sure:
> (io:format "~tp~n" (list encoded))
<<"åäö ð"/utf8>>
Reverse it:
> (lists:reverse (unicode:characters_to_list encoded))
"ð öäå"
Liberty BASIC
input$ ="abcdefgABCDEFG012345"
print input$
print ReversedStr$( input$)
end
function ReversedStr$(in$)
for i =len(in$) to 1 step -1
ReversedStr$ =ReversedStr$ +mid$( in$, i, 1)
next i
end function
Lingo
Lingo strings are always UTF-8 encoded and string operations are based on Unicode code points, so the "extra credit" is built-in:
on reverse (str)
res = ""
repeat with i = str.length down to 1
put str.char[i] after res
end repeat
return res
end
To reverse a string byte-wise, the ByteArray data type has to be used:
on reverseBytes (str)
ba = byteArray(str)
res = byteArray()
repeat with i = ba.length down to 1
res[res.length+1] = ba[i]
end repeat
return res
end
LiveCode
function reverseString S
repeat with i = length(S) down to 1
put char i of S after R
end repeat
return R
end reverseString
LLVM
; This is not strictly LLVM, as it uses the C library function "printf".
; LLVM does not provide a way to print values, so the alternative would be
; to just load the string into memory, and that would be boring.
; Additional comments have been inserted, as well as changes made from the output produced by clang such as putting more meaningful labels for the jumps
$"main.printf" = comdat any
@main.str = private unnamed_addr constant [12 x i8] c"Hello world\00", align 1
@"main.printf" = linkonce_odr unnamed_addr constant [4 x i8] c"%s\0A\00", comdat, align 1
define void @reverse(i64, i8*) {
%3 = alloca i8*, align 8 ; allocate str (local)
%4 = alloca i64, align 8 ; allocate len (local)
%5 = alloca i64, align 8 ; allocate i
%6 = alloca i64, align 8 ; allocate j
%7 = alloca i8, align 1 ; allocate t
store i8* %1, i8** %3, align 8 ; set str (local) to the parameter str
store i64 %0, i64* %4, align 8 ; set len (local) to the paremeter len
store i64 0, i64* %5, align 8 ; i = 0
%8 = load i64, i64* %4, align 8 ; load len
%9 = sub i64 %8, 1 ; decrement len
store i64 %9, i64* %6, align 8 ; j =
br label %loop
loop:
%10 = load i64, i64* %5, align 8 ; load i
%11 = load i64, i64* %6, align 8 ; load j
%12 = icmp ult i64 %10, %11 ; i < j
br i1 %12, label %loop_body, label %exit
loop_body:
%13 = load i8*, i8** %3, align 8 ; load str
%14 = load i64, i64* %5, align 8 ; load i
%15 = getelementptr inbounds i8, i8* %13, i64 %14 ; address of str[i]
%16 = load i8, i8* %15, align 1 ; load str[i]
store i8 %16, i8* %7, align 1 ; t = str[i]
%17 = load i64, i64* %6, align 8 ; load j
%18 = getelementptr inbounds i8, i8* %13, i64 %17 ; address of str[j]
%19 = load i8, i8* %18, align 1 ; load str[j]
%20 = getelementptr inbounds i8, i8* %13, i64 %14 ; address of str[i]
store i8 %19, i8* %20, align 1 ; str[i] = str[j]
%21 = load i8, i8* %7, align 1 ; load t
%22 = getelementptr inbounds i8, i8* %13, i64 %17 ; address of str[j]
store i8 %21, i8* %22, align 1 ; str[j] = t
;-- loop increment
%23 = load i64, i64* %5, align 8 ; load i
%24 = add i64 %23, 1 ; increment i
store i64 %24, i64* %5, align 8 ; store i
%25 = load i64, i64* %6, align 8 ; load j
%26 = add i64 %25, -1 ; decrement j
store i64 %26, i64* %6, align 8 ; store j
br label %loop
exit:
ret void
}
define i32 @main() {
;-- char str[]
%1 = alloca [12 x i8], align 1
;-- memcpy(str, "Hello world")
%2 = bitcast [12 x i8]* %1 to i8*
call void @llvm.memcpy.p0i8.p0i8.i64(i8* %2, i8* getelementptr inbounds ([12 x i8], [12 x i8]* @main.str, i32 0, i32 0), i64 12, i32 1, i1 false)
;-- printf("%s\n", str)
%3 = getelementptr inbounds [12 x i8], [12 x i8]* %1, i32 0, i32 0
%4 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @"main.printf", i32 0, i32 0), i8* %3)
;-- %7 = strlen(str)
%5 = getelementptr inbounds [12 x i8], [12 x i8]* %1, i32 0, i32 0
%6 = call i64 @strlen(i8* %5)
;-- reverse(%6, str)
call void @reverse(i64 %6, i8* %5)
;-- printf("%s\n", str)
%7 = getelementptr inbounds [12 x i8], [12 x i8]* %1, i32 0, i32 0
%8 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @"main.printf", i32 0, i32 0), i8* %7)
;-- end of main
ret i32 0
}
;--- The declaration for the external C printf function.
declare i32 @printf(i8*, ...)
; Function Attrs: argmemonly nounwind
declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture writeonly, i8* nocapture readonly, i64, i32, i1)
declare i64 @strlen(i8*)
- Output:
Hello world dlrow olleH
Logo
REVERSE works on both words and lists.
print reverse "cat ; tac
Lua
Built-in string.reverse(s) or s:reverse().
ASCII
example = 'asdf'
string.reverse(example) -- fdsa
example:reverse() -- fdsa
Unicode
Lua doesn't support Unicode strings.
M2000 Interpreter
Using Custom Function
Version 2, using insert to string (with no copies of strings)
Module ReverseString {
a$="as⃝df̅"
Print Len(a$), len.disp(a$)
Let i=1, j=Len(a$)
z$=String$(" ",j)
j++
do {
k$=mid$(a$, i, 1)
if i<len(a$) then {
while len.disp(k$+mid$(a$, i+1,1)) =len.disp(k$) {
k$+=mid$(a$, i+1,1)
i++
if i>len(a$) then exit
j--
}
j--
insert j, len(k$) Z$=K$
} else j-- :Insert j,1 z$=k$
if i>=len(a$) then exit
i++
} Always
Print len(z$), len.disp(z$)
Print z$="f̅ds⃝a"
Print z$
}
ReverseString
using StrRev$()
this function (new to 9.5 version) use StrReverse from Vb6
a$="as⃝df̅"
b$=strrev$(a$)
clipboard b$
Print b$="̅fd⃝sa"
M4
define(`invert',`ifelse(len(`$1'),0,,`invert(substr(`$1',1))'`'substr(`$1',0,1))')
Maclisp
(readlist (reverse (explode "my-string")))
Output:
"gnirts-ym"
MACRO-11
.TITLE REVERS
.MCALL .GTLIN,.PRINT,.EXIT
REVERS::.GTLIN #1$ ; READ STRING
MOV #1$,R0
JSR PC,REV ; REVERSE IT
.PRINT #1$ ; PRINT RESULT
.EXIT
1$: .BLKB 200
; REVERSE STRING AT R0
REV: MOV R0,R1
1$: TSTB (R1)+ ; FIND END OF STRING
BNE 1$
DEC R1 ; MOVE BACK TO LAST CHAR
2$: MOVB -(R1),R2 ; SWAP CHARS
MOVB (R0),(R1)
MOVB R2,(R0)+
CMP R0,R1 ; STOP WHEN POINTERS MEET
BLT 2$
RTS PC
.END REVERS
- Output:
.revers A man, a plan, a canal: Panama amanaP :lanac a ,nalp a ,nam A
Maple
> StringTools:-Reverse( "foo" );
"oof"
Mathematica /Wolfram Language
StringReverse["asdf"]
MATLAB
A built-in function, "fliplr(string)" handles reversing a string of ASCII characters. Unicode is a whole other beast, if you need this functionality test to see if "fliplr()" properly handles the unicode characters you use. If it doesn't then you will need to code a function that is specific to your application.
Sample Usage:
>> fliplr(['She told me that she spoke English and I said great. '...
'Grabbed her hand out the club and I said let''s skate.'])
ans =
.etaks s'tel dias I dna bulc eht tuo dnah reh debbarG .taerg dias I dna hsilgnE ekops ehs taht em dlot ehS
Maxima
sreverse("abcdef"); /* "fedcba" */
sreverse("rats live on no evil star"); /* not a bug :o) */
MAXScript
fn reverseString s =
(
local reversed = ""
for i in s.count to 1 by -1 do reversed += s[i]
reversed
)
min
("" split reverse "" join) :reverse-str
MiniScript
str = "This is a string"
print "Forward: " + str
newStr = ""
for i in range(str.len-1, 0)
newStr = newStr + str[i]
end for
print "Reversed: " + newStr
- Output:
Forward: This is a string Reversed: gnirts a si sihT
MIPS Assembly
# First, it gets the length of the original string
# Then, it allocates memory from the copy
# Then it copies the pointer to the original string, and adds the strlen
# subtract 1, then that new pointer is at the last char.
# while(strlen)
# copy char
# decrement strlen
# decrement source pointer
# increment target pointer
.text
strcpy:
addi $sp, $sp, -4
sw $s0, 0($sp)
add $s0, $zero, $zero
L1:
add $t1, $s0, $a1
lb $t2, 0($t1)
add $t3, $s0, $a0
sb $t2, 0($t3)
beq $t2, $zero, L2
addi $s0, $s0, 1
j L1
L2:
lw $s0, 0($sp)
addi $sp, $sp, 4
jr $ra
.data
ex_msg_og: .asciiz "Original string:\n"
ex_msg_cpy: .asciiz "\nCopied string:\n"
string: .asciiz "Nice string you got there!\n"
Mirah
def reverse(s:string)
StringBuilder.new(s).reverse
end
puts reverse('reversed')
Miranda
main :: [sys_message]
main = [Stdout (reverse "esreveR"),
Stdout "\n"]
- Output:
Reverse
Modula-2
MODULE ReverseStr;
FROM FormatString IMPORT FormatString;
FROM Terminal IMPORT Write,WriteString,WriteLn,ReadChar;
PROCEDURE WriteInt(n : INTEGER);
VAR buf : ARRAY[0..15] OF CHAR;
BEGIN
FormatString("%i", buf, n);
WriteString(buf)
END WriteInt;
PROCEDURE ReverseStr(in : ARRAY OF CHAR; VAR out : ARRAY OF CHAR);
VAR ip,op : INTEGER;
BEGIN
ip := 0;
op := 0;
WHILE in[ip] # 0C DO
INC(ip)
END;
DEC(ip);
WHILE ip>=0 DO
out[op] := in[ip];
INC(op);
DEC(ip)
END
END ReverseStr;
TYPE A = ARRAY[0..63] OF CHAR;
VAR is,os : A;
BEGIN
is := "Hello World";
ReverseStr(is, os);
WriteString(is);
WriteLn;
WriteString(os);
WriteLn;
ReadChar
END ReverseStr.
Modula-3
MODULE Reverse EXPORTS Main;
IMPORT IO, Text;
PROCEDURE String(item: TEXT): TEXT =
VAR result: TEXT := "";
BEGIN
FOR i := Text.Length(item) - 1 TO 0 BY - 1 DO
result := Text.Cat(result, Text.FromChar(Text.GetChar(item, i)));
END;
RETURN result;
END String;
BEGIN
IO.Put(String("Foobarbaz") & "\n");
END Reverse.
- Output:
zabrabooF
MUMPS
REVERSE
;Take in a string and reverse it using the built in function $REVERSE
NEW S
READ:30 "Enter a string: ",S
WRITE !,$REVERSE(S)
QUIT
- Output:
USER>D REVERSE^ROSETTA Enter a string: Hello, World! !dlroW ,olleH
Nanoquery
def reverse(string)
l = ""
for char in list(str(string)).reverse()
l += char
end
return l
end
Neko
No extra credit for UTF in this example.
/* Reverse a string, in Neko */
var reverse = function(s) {
var len = $ssize(s)
if len < 2 return s
var reverse = $smake(len)
var pos = 0
while len > 0 $sset(reverse, pos ++= 1, $sget(s, len -= 1))
return reverse
}
var str = "never odd or even"
$print(str, "\n")
$print(reverse(str), "\n\n")
str = "abcdefghijklmnopqrstuvwxyz"
$print(str, "\n")
$print(reverse(str), "\n\n")
$print("single test\n")
str = "a"
$print(str, "\n")
$print(reverse(str), "\n\n")
$print("empty test\n")
str = ""
$print(str, "\n")
$print(reverse(str), "\n")
- Output:
prompt$ nekoc reverse.neko prompt$ neko reverse.n never odd or even neve ro ddo reven abcdefghijklmnopqrstuvwxyz zyxwvutsrqponmlkjihgfedcba single test a a empty test
Nemerle
Supporting Combining Characters
Compile with:
ncc -reference:System.Windows.Forms reverse.n
using System;
using System.Globalization;
using System.Windows.Forms;
using System.Console;
using Nemerle.Utility.NString;
module StrReverse
{
UReverse(text : string) : string
{
mutable output = [];
def elements = StringInfo.GetTextElementEnumerator(text);
while (elements.MoveNext())
output ::= elements.GetTextElement().ToString();
Concat("", output.Reverse());
}
Main() : void
{
def test = "as⃝df̅";
MessageBox.Show($"$test --> $(UReverse(test))"); //for whatever reason my console didn't display Unicode properly, but a MessageBox worked
}
}
Basic Reverse
Doesn't require the System.Globalization namespace, probably a little less overhead.
Reverse(text : string) : string
{
mutable output = [];
foreach (c in text.ToCharArray())
output ::= c.ToString();
Concat("", output)
}
NetRexx
/* NetRexx */
options replace format comments java crossref savelog symbols nobinary
reverseThis = 'asdf'
sihTesrever = reverseThis.reverse
say reverseThis
say sihTesrever
return
- Output:
asdf fdsa
NewLISP
(reverse "!dlroW olleH")
Nial
reverse 'asdf'
=fdsa
Nim
Unicode codepoints
Since Nim 0.11.0, the unicode
module provides a reversed
proc...
Hence:
import unicode
doAssert "foobar".reversed == "raboof"
doAssert "先秦兩漢".reversed == "漢兩秦先"
This proc is enumerating codepoints so it will work with Unicode multi-bytes characters. A special handling was added so it's supports composing as well but since it's not enumerating graphemes it won't work with joining.
Unicode graphemes
There is no native method to handle grapheme currently.
NS-HUBASIC
10 STRING$="THIS TEXT IS REVERSED."
20 REVERSED$=""
30 FOR I=1 TO LEN(STRING$)
40 REVERSED$=MID$(STRING$,I,1)+REVERSED$
50 NEXT
60 PRINT REVERSED$
Nu
'äsdf' | str reverse
- Output:
fdsä
Oberon-2
Tested with OBNC.
MODULE reverse;
IMPORT Out, Strings;
VAR s: ARRAY 12 + 1 OF CHAR;
PROCEDURE Swap(VAR c, d: CHAR);
VAR oldC: CHAR;
BEGIN
oldC := c; c := d; d := oldC
END Swap;
PROCEDURE Reverse(VAR s: ARRAY OF CHAR);
VAR len, i: INTEGER;
BEGIN
len := Strings.Length(s);
FOR i := 0 TO len DIV 2 DO
Swap(s[i], s[len - 1 - i])
END
END Reverse;
BEGIN
s := "hello, world";
Reverse(s);
Out.String(s);
Out.Ln
END reverse.
Objeck
result := "asdf"->Reverse();
Objective-C
This extends the NSString
object adding a reverseString
class method.
#import <Foundation/Foundation.h>
@interface NSString (Extended)
-(NSString *)reverseString;
@end
@implementation NSString (Extended)
-(NSString *) reverseString
{
NSUInteger len = [self length];
NSMutableString *rtr=[NSMutableString stringWithCapacity:len];
// unichar buf[1];
while (len > (NSUInteger)0) {
unichar uch = [self characterAtIndex:--len];
[rtr appendString:[NSString stringWithCharacters:&uch length:1]];
}
return rtr;
}
@end
Usage example:
int main()
{
@autoreleasepool {
NSString *test = [@"!A string to be reverted!" reverseString];
NSLog(@"%@", test);
}
return 0;
}
Supporting combining characters
Extra credit
#import <Foundation/Foundation.h>
@interface NSString (Extended)
-(NSString *)reverseString;
@end
@implementation NSString (Extended)
-(NSString *)reverseString
{
NSInteger l = [self length] - 1;
NSMutableString *ostr = [NSMutableString stringWithCapacity:[self length]];
while (l >= 0)
{
NSRange range = [self rangeOfComposedCharacterSequenceAtIndex:l];
[ostr appendString:[self substringWithRange:range]];
l -= range.length;
}
return ostr;
}
@end
Usage example:
int main()
{
@autoreleasepool {
NSString *test = [@"as⃝df̅" reverseString];
NSLog(@"%@", test);
}
return 0;
}
OCaml
Since OCaml 4.02 we can use the handy String.init function.
Here a version that returns a new allocated string (preserving the original one):
let string_rev s =
let len = String.length s in
String.init len (fun i -> s.[len - 1 - i])
let () =
print_endline (string_rev "Hello world!")
for in place modification we can't use strings anymore because strings became immutable in ocaml 4.02, so the type bytes has to be used instead:
let rev_bytes bs =
let last = Bytes.length bs - 1 in
for i = 0 to last / 2 do
let j = last - i in
let c = Bytes.get bs i in
Bytes.set bs i (Bytes.get bs j);
Bytes.set bs j c;
done
let () =
let s = Bytes.of_string "Hello World" in
rev_bytes s;
print_bytes s;
print_newline ();
;;
Here is a 100% functionnal string reversing function:
let rec revs_aux strin list index =
if List.length list = String.length strin
then String.concat "" list
else revs_aux strin ((String.sub strin index 1)::list) (index+1)
let revs s = revs_aux s [] 0
let () =
print_endline (revs "Hello World!")
will return "!dlroW olleH"
Octave
s = "a string";
rev = s(length(s):-1:1)
Oforth
reverse
Ol
(define (rev s)
(runes->string (reverse (string->runes s))))
; testing:
(print (rev "Hello, λ!"))
; ==> !λ ,olleH
OmniMark
This handles the characters U+0073,U+20DD (Latin Small Letter S + Combining Enclosing Circle; UTF-8: 73 + e2 83 9D) and U+0066,U+0305 (Latin Small Letter F + Combining Overline; UTF-8: 66 + cc 85). It would need extension to handle non-combining UTF-8 characters, but that's not been done.
macro utf8-not-ascii is
(["%16r{C0}" to "%16r{DF}"] ["%16r{80}" to "%16r{BF}"] |
["%16r{E0}" to "%16r{EF}"] ["%16r{80}" to "%16r{BF}"] {2} |
["%16r{F0}" to "%16r{F7}"] ["%16r{80}" to "%16r{BF}"] {3}) macro-end
global stream reverse initial {''}
process
submit 'as⃝df̅'
find (any-text utf8-not-ascii) => char
set reverse to char || reverse
find any-text => char
set reverse to char || reverse
process-end
output reverse || '%n'
- Output:
f̅ds⃝a
OOC
main: func {
"asdf" reverse() println() // prints "fdsa"
}
OpenEdge/Progress
FUNCTION reverseString RETURNS CHARACTER (
INPUT i_c AS CHARACTER
):
DEFINE VARIABLE cresult AS CHARACTER NO-UNDO.
DEFINE VARIABLE ii AS INTEGER NO-UNDO.
DO ii = LENGTH( i_c ) TO 1 BY -1:
cresult = cresult + SUBSTRING( i_c, ii, 1 ).
END.
RETURN cresult.
END FUNCTION.
MESSAGE reverseString( "asdf" ) VIEW-AS ALERT-BOX.
OxygenBasic
'8 BIT CHARACTERS
string s="qwertyuiop"
sys a,b,i,j,le=len s
'
for i=1 to le
j=le-i+1
if j<=i then exit for
a=asc s,i
b=asc s,j
mid s,j,chr a
mid s,i,chr b
next
'
print s
'16 BIT CHARACTERS
wstring s="qwertyuiop"
sys a,b,i,j,le=len s
'
for i=1 to le
j=le-i+1
if j<=i then exit for
a=unic s,i
b=unic s,j
mid s,j,wchr a
mid s,i,wchr b
next
'
print s
OxygenBasic x86 Assembler
32 bit code, 8-bit characters:
string s="qwertyuiop"
sys p=strptr s, le=len s
mov esi,p
mov edi,esi
add edi,le
dec edi
(
cmp esi,edi
jge exit
mov al,[esi]
mov ah,[edi]
mov [esi],ah
mov [edi],al
inc esi
dec edi
repeat
)
print s
Oz
Strings are lists. A function "Reverse" defined on lists is part of the implementation.
{System.showInfo {Reverse "!dlroW olleH"}}
An efficient (tail-recursive) implementation could look like this:
local
fun {DoReverse Xs Ys}
case Xs of nil then Ys
[] X|Xr then {DoReverse Xr X|Ys}
end
end
in
fun {Reverse Xs} {DoReverse Xs nil} end
end
Oz uses a single-byte encoding by default. If you decide to use a multi-byte encoding, Reverse will not work correctly.
PARI/GP
Version #1.
reverse(s)=concat(Vecrev(s))
Version #2.
\\ Return reversed string str.
\\ 3/3/2016 aev
sreverse(str)={return(Strchr(Vecrev(Vecsmall(str))))}
{
\\ TEST1
print(" *** Testing sreverse from Version #2:");
print(sreverse("ABCDEF"));
my(s,sr,n=10000000);
s="ABCDEFGHIJKL";
for(i=1,n, sr=sreverse(s));
}
- Output:
*** Testing sreverse from Version #2: FEDCBA (17:28) gp > ## *** last result computed in 8,642 ms.
\\ Version #1 upgraded to complete function. Practically the same.
reverse(str)={return(concat(Vecrev(str)))}
{
\\ TEST2
print(" *** Testing reverse from Version #1:");
print(reverse("ABCDEF"));
my(s,sr,n=10000000);
s="ABCDEFGHIJKL";
for(i=1,n, sr=reverse(s));
}
- Output:
*** Testing reverse from Version #1: FEDCBA (17:31) gp > ## *** last result computed in 11,814 ms.
Pascal
The following examples handle correctly only single-byte encodings.
Standard Pascal
The following only works on implementations which implement Level 1 of standard Pascal (many popular compilers don't).
Standard Pascal doesn't have a separate string type, but uses arrays of char for strings. Note that Standard Pascal doesn't allow a return type of char array, therefore the destination array is passed through a var parameter (which is more efficient anyway).
{ the result array must be at least as large as the original array }
procedure reverse(s: array[min .. max: integer] of char, var result: array[min1 .. max1: integer] of char);
var
i, len: integer;
begin
len := max-min+1;
for i := 0 to len-1 do
result[min1 + len-1 - i] := s[min + i]
end;
{Copy and paste it in your program}
function revstr(my_s:string):string;
var out_s:string;
ls,i:integer;
begin
ls:=length(my_s);
for i:=1 to ls do
out_s:=out_s+my_s[ls-i+1];
revstr:=out_s;
end;
Extended Pascal, Turbo Pascal, Delphi and compatible compilers
function reverse(s:string):string;
var i:integer;
var tmp:char;
begin
for i:=1 to length(s) div 2 do
begin
tmp:=s[i];
s[i]:=s[length(s)+1-i];
s[length(s)+1-i]:=tmp;
reverse:=s;
end;
end;
alternative as procedure which changes the original
procedure revString(var s:string);
var
i,j:integer;
tmp:char;
begin
i := 1;
j := length(s);
while i<j do
begin
tmp:=s[i];
s[i]:=s[j];
s[j]:=tmp;
inc(i);
dec(j)
end;
end;
PascalABC.NET
##
var s:='asdf';//ReadLnString;
ReverseString(s).Print;
- Output:
fdsa
Peloton
Padded out, variable length Chinese dialect
<# 显示 指定 变量 反转顺序 字串>集装箱|猫坐在垫子</#>
This assigns the reverse of 'the cat sat on the mat' to the variable 'container' and displays the result which is
子垫在坐猫
which Google Translate renders as
Sub-pad sitting cat
.
The same again but with everything in Korean.
<# 보이십 할당하 변물건 열거꾸 문자그>컨테이너|고양이가 매트 위에 앉아</#>
Reversing the Korean makes an untranslatable-by-Google mess of the sentence, viz
아앉 에위 트매 가이양고
.
The short-opcode version in English dialect is
<@ SAYLETVARREVLIT>集装箱|猫坐在垫子</@>
Peloton works in Unicode.
Perl
reverse() works in the context of a List or a scalar, not a string.
use utf8;
binmode STDOUT, ":utf8";
# to reverse characters (code points):
print scalar reverse('visor'), "\n";
# to reverse graphemes:
print join("", reverse "José" =~ /\X/g), "\n";
$string = 'ℵΑΩ 駱駝道 🤔 🇸🇧 🇺🇸 🇬🇧 👨👩👧👦🆗🗺';
print join("", reverse $string =~ /\X/g), "\n";
- Output:
rosiv ésoJ 🗺🆗👨👩👧👦 🇬🇧 🇺🇸 🇸🇧 🤔 道駝駱 ΩΑℵ
Pharo
'123' reversed
Phix
?reverse("asdf")
However that would go horribly wrong on utf8 strings, even without combining characters, so... this seems ok on "as\u203Ddf\u0305", as long as it is displayed in a message box rather than a Windows Console (even with chcp 65001 and Lucida Console, the characters do not combine). It actually works better under pwa/p2js than on desktop/Phix, you can find a copy of this code in demo/HelloUTF8.exw which outputs the result in a message box and therefore looks much better on the latter.
Note that XXXX_redacted#Phix adds some ZERO-WIDTH-JOINER handling to the inner code.
with javascript_semantics function unicode_reverse(string utf8) sequence utf32 = utf8_to_utf32(utf8) -- The assumption is made that <char><comb1><comb2> -- and <char><comb2><comb1> etc would work the same. -- The following loop converts <char><comb1><comb2> -- to <comb1><comb2><char>, as a pre-reverse() step. for i=1 to length(utf32) do integer ch = utf32[i] if (ch>=0x300 and ch<=0x36f) or (ch>=0x1dc0 and ch<=0x1dff) or (ch>=0x20d0 and ch<=0x20ff) or (ch>=0xfe20 and ch<=0xfe2f) then utf32[i] = utf32[i-1] utf32[i-1] = ch end if end for utf32 = reverse(utf32) utf8 = utf32_to_utf8(utf32) return utf8 end function string r4 = "as\u203Ddf\u0305", rt = r4&" reversed is "&unicode_reverse(r4)&"\n" puts(1,rt)
PHP
Unicode
Code points
If you want Unicode support, you have to use some multibyte function. Sadly, PHP doesn't contain mb_strrev()
. One of functions which support Unicode and is useful in this case is preg_split()
.
// Will split every Unicode character to array, reverse array and will convert it to string.
join('', array_reverse(preg_split('""u', $string, -1, PREG_SPLIT_NO_EMPTY)));
With PHP 7.4+ and 8+, it's also possible to use mb_str_split()
, which may ends easier.
implode('', array_reverse(mb_str_split($string)));
Graphemes
When using combining characters such as diacritics or ZWJ (joining), reversing code points will mess with the result, reversing the graphemes instead is mandatory. This is generally the best and safest approach. As there is no grapheme_reverse()
function or grapheme iterator, one has to implement it with grapheme_strlen
and grapheme_substr
. In PHP, there is no Unicode escape sequence so to specify characters by code point a tricks must be used: for example, using the escape sequence of HTML entities and then convert it to a Unicode encoding such as UTF-8.
$a = mb_convert_encoding('👦🏻👋', 'UTF-8', 'HTML-ENTITIES'); // 👦🏻👋
function str_to_array($string)
{
$length = grapheme_strlen($string);
$ret = [];
for ($i = 0; $i < $length; $i += 1) {
$ret[] = grapheme_substr($string, $i, 1);
}
return $ret;
}
function utf8_strrev($string)
{
return implode(array_reverse(str_to_array($string)));
}
print_r(utf8_strrev($a)); // 👋👦🏻
ASCII
strrev($string);
PicoLisp
(pack (flip (chop "äöüÄÖÜß")))
- Output:
-> "ßÜÖÄüöä"
Pike
For simple ASCII:
reverse("foo");
- Output:
"oof"
When dealing with Unicode (or any other supported encoding) care must be taken primarily in the output step to serialize the Unicode string into something the sink can handle. IO functions will throw an error if sent raw wide strings.
#charset utf8
void main()
{
string s = "ßÜÖÄüöää ἀρχῇ";
write("%s\n", string_to_utf8( reverse(s) ));
}
- Output:
ῇχρἀ ääöüÄÖÜß
PL/I
s = reverse(s);
Plain English
To run:
Start up.
Put "asdf" into a string.
Reverse the string.
Shut down.
Plain TeX
Works well if the string has no space (spaces are gobbled).
\def\gobtoA#1\revA{}\def\gobtoB#1\revB{}
\def\reverse#1{\reversei{}#1\revA\revB\revB\revB\revB\revB\revB\revB\revB\revA}
\def\reversei#1#2#3#4#5#6#7#8#9{\gobtoB#9\revend\revB\reversei{#9#8#7#6#5#4#3#2#1}}
\def\revend\revB\reversei#1#2\revA{\gobtoA#1}
\reverse{Rosetta}
\bye
Output:
attesoR
Pop11
define reverse_string(s);
lvars i, l = length(s);
for i from l by -1 to 1 do
s(i);
endfor;
consstring(l);
enddefine;
PostScript
The following implementation works on arrays of numerics as well as characters ( string ).
/reverse{
/str exch def
/temp str 0 get def
/i 0 def
str length 2 idiv{
/temp str i get def
str i str str length i sub 1 sub get put
str str length i sub 1 sub temp put
/i i 1 add def
}repeat
str pstack
}def
- Output:
[1 2 3] reverse % input
[3 2 1]
(Hello World) reverse % input
(dlroW olleH)
PowerBASIC
#DIM ALL
#COMPILER PBCC 6
FUNCTION PBMAIN () AS LONG
CON.PRINT STRREVERSE$("PowerBASIC")
END FUNCTION
PowerShell
For ASCII
Test string
$s = "asdf"
Array indexing
Creating a character array from the end to the string's start and join it together into a string again.
[string]::Join('', $s[$s.Length..0])
-join ($s[$s.Length..0])
[array]::Reverse($s)
Regular expressions
Creating a regular expression substitution which captures every character of the string in a capture group and uses a reverse-ordered string of references to those to construct the reversed string.
$s -replace
('(.)' * $s.Length),
[string]::Join('', ($s.Length..1 | ForEach-Object { "`$$_" }))
$s -replace
('(.)' * $s.Length),
-join ($s.Length..1 | ForEach-Object { "`$$_" } )
[Regex]::Matches($s,'.','RightToLeft').Value -join ''
For Unicode
For codepoints
Since PowerShell 7, there is a EnumerateRunes()
method to enumerate Unicode codepoints. Enumerating codepoints works for multi-bytes characters but not for composing or joining.
$a = 'abc 🐧 def'
$enum = $a.EnumerateRunes() | % { "$_" }
-join $enum[$enum.length..0] # fed 🐧 cba
For graphemes
For composing or joining, enumerating graphemes is required.
$a = "aeiou`u{0308}yz"
$enum = [System.Globalization.StringInfo]::GetTextElementEnumerator($a)
$arr = @()
while($enum.MoveNext()) { $arr += $enum.GetTextElement() }
[array]::reverse($arr)
$arr -join '' # zyüoiea
Prolog
reverse("abcd", L), string_to_list(S,L).
- Output:
L = [100,99,98,97], S = "dcba".
The main workings are hidden inside the reverse/2 predicate, so lets write one to see how it works:
accRev([H|T], A, R) :- accRev(T, [H|A], R).
accRev([], A, A).
rev(L,R) :- accRev(L,[],R).
PureBasic
Debug ReverseString("!dekrow tI")
Python
Optimized for user input
input()[::-1]
Already known string
string[::-1]
or
''.join(reversed(string))
Python: Unicode reversal
(See this article for more information from which this is improved)
Note: How this looks may be subject to how the tool you are using to view this page can render Unicode.
import unicodedata
def ureverse(ustring):
'Reverse a string including unicode combining characters'
groupedchars = []
uchar = list(ustring)
while uchar:
if unicodedata.combining(uchar[0]) != 0:
groupedchars[-1] += uchar.pop(0)
else:
groupedchars.append(uchar.pop(0))
# Grouped reversal
groupedchars = groupedchars[::-1]
return ''.join(groupedchars)
def say_string(s):
return ' '.join([s, '=', ' | '.join(unicodedata.name(ch, '') for ch in s)])
def say_rev(s):
print(f"Input: {say_string(s)}")
print(f"Character reversed: {say_string(s[::-1])}")
print(f"Unicode reversed: {say_string(ureverse(s))}")
print(f"Unicode reverse²: {say_string(ureverse(ureverse(s)))}")
if __name__ == '__main__':
ucode = ''.join(chr(int(n[2:], 16)) for n in
'U+0041 U+030A U+0073 U+0074 U+0072 U+006F U+0308 U+006D'.split())
say_rev(ucode)
- Output:
Input: Åström = LATIN CAPITAL LETTER A | COMBINING RING ABOVE | LATIN SMALL LETTER S | LATIN SMALL LETTER T | LATIN SMALL LETTER R | LATIN SMALL LETTER O | COMBINING DIAERESIS | LATIN SMALL LETTER M Character reversed: m̈orts̊A = LATIN SMALL LETTER M | COMBINING DIAERESIS | LATIN SMALL LETTER O | LATIN SMALL LETTER R | LATIN SMALL LETTER T | LATIN SMALL LETTER S | COMBINING RING ABOVE | LATIN CAPITAL LETTER A Unicode reversed: mörtsÅ = LATIN SMALL LETTER M | LATIN SMALL LETTER O | COMBINING DIAERESIS | LATIN SMALL LETTER R | LATIN SMALL LETTER T | LATIN SMALL LETTER S | LATIN CAPITAL LETTER A | COMBINING RING ABOVE Unicode reverse²: Åström = LATIN CAPITAL LETTER A | COMBINING RING ABOVE | LATIN SMALL LETTER S | LATIN SMALL LETTER T | LATIN SMALL LETTER R | LATIN SMALL LETTER O | COMBINING DIAERESIS | LATIN SMALL LETTER M
If this code is then used:
ucode = ''.join(chr(int(n[2:], 16)) for n in
'U+006B U+0301 U+0075 U+032D U+006F U+0304 U+0301 U+006E'.split())
say_rev(ucode)
It produces this output
- Output:
Input: ḱṷṓn = LATIN SMALL LETTER K | COMBINING ACUTE ACCENT | LATIN SMALL LETTER U | COMBINING CIRCUMFLEX ACCENT BELOW | LATIN SMALL LETTER O | COMBINING MACRON | COMBINING ACUTE ACCENT | LATIN SMALL LETTER N Character reversed: ń̄o̭úk = LATIN SMALL LETTER N | COMBINING ACUTE ACCENT | COMBINING MACRON | LATIN SMALL LETTER O | COMBINING CIRCUMFLEX ACCENT BELOW | LATIN SMALL LETTER U | COMBINING ACUTE ACCENT | LATIN SMALL LETTER K Unicode reversed: nṓṷḱ = LATIN SMALL LETTER N | LATIN SMALL LETTER O | COMBINING MACRON | COMBINING ACUTE ACCENT | LATIN SMALL LETTER U | COMBINING CIRCUMFLEX ACCENT BELOW | LATIN SMALL LETTER K | COMBINING ACUTE ACCENT Unicode reverse²: ḱṷṓn = LATIN SMALL LETTER K | COMBINING ACUTE ACCENT | LATIN SMALL LETTER U | COMBINING CIRCUMFLEX ACCENT BELOW | LATIN SMALL LETTER O | COMBINING MACRON | COMBINING ACUTE ACCENT | LATIN SMALL LETTER N
This uses the unicode string mentioned in the task:
ucode = ''.join(chr(int(n, 16))
for n in ['61', '73', '20dd', '64', '66', '305'])
say_rev(ucode)
It produces this output
- Output:
Input: as⃝df̅ = LATIN SMALL LETTER A | LATIN SMALL LETTER S | COMBINING ENCLOSING CIRCLE | LATIN SMALL LETTER D | LATIN SMALL LETTER F | COMBINING OVERLINE Character reversed: ̅fd⃝sa = COMBINING OVERLINE | LATIN SMALL LETTER F | LATIN SMALL LETTER D | COMBINING ENCLOSING CIRCLE | LATIN SMALL LETTER S | LATIN SMALL LETTER A Unicode reversed: f̅d⃝sa = LATIN SMALL LETTER F | COMBINING OVERLINE | LATIN SMALL LETTER D | COMBINING ENCLOSING CIRCLE | LATIN SMALL LETTER S | LATIN SMALL LETTER A Unicode reverse²: as⃝df̅ = LATIN SMALL LETTER A | LATIN SMALL LETTER S | COMBINING ENCLOSING CIRCLE | LATIN SMALL LETTER D | LATIN SMALL LETTER F | COMBINING OVERLINE
Quackery
reverse is predefined (and applies to nests in general, including strings) as:
[ dup nest? if
[ [] swap witheach
[ nested
swap join ] ] ] is reverse ( x --> x )
Qi
It's simplest just to use the common lisp REVERSE function.
(REVERSE "ABCD")
R
The following code works with UTF-8 encoded strings too.
revstring <- function(stringtorev) {
return(
paste(
strsplit(stringtorev,"")[[1]][nchar(stringtorev):1]
,collapse="")
)
}
Alternatively (using rev() function):
revstring <- function(s) paste(rev(strsplit(s,"")[[1]]),collapse="")
revstring("asdf")
revstring("m\u00f8\u00f8se")
Encoding("m\u00f8\u00f8se") # just to check if on your system it's something
# different!
- Output:
[1] "fdsa" [1] "esøøm" [1] "UTF-8"
R can encode strings in Latin1 and UTF-8 (the default may depend on the locale); the Encoding(string) can be used to know if the string is encoded in Latin1 or UTF-8; the encoding can be forced (Encoding(x) <- "latin1"), or we can use iconv to properly translate between encodings whenever possible.
Racket
As in Scheme:
#lang racket
(define (string-reverse s)
(list->string (reverse (string->list s))))
(string-reverse "aoeu")
- Output:
Welcome to DrRacket, version 5.3.3.5--2013-02-20(5eddac74/d) [3m]. Language: racket; memory limit: 512 MB. "ueoa" >
Raku
(formerly Perl 6)
Raku handles graphemes, multi-byte characters and emoji correctly by default.
say "hello world".flip;
say "as⃝df̅".flip;
say 'ℵΑΩ 駱駝道 🤔 🇸🇧 🇺🇸 🇬🇧 👨👩👧👦🆗🗺'.flip;
- Output:
dlrow olleh f̅ds⃝a 🗺🆗👨👩👧👦 🇬🇧 🇺🇸 🇸🇧 🤔 道駝駱 ΩΑℵ
RapidQ
print reverse$("This is a test")
Rascal
import String;
reverse("string")
Raven
"asdf" reverse
- Output:
fdsa
REBOL
print reverse "asdf"
Note the string is reversed in place. If you were using it anywhere else, you would find it reversed:
x: "asdf"
print reverse x
print x ; Now reversed.
REBOL/View 2.7.6.3.1 14-Mar-2008 does not handle Unicode strings. This is planned for REBOL 3.
Red
>> reverse "asdf"
== "fdsa"
Refal
$ENTRY Go {
= <Prout <Reverse 'asdf'>>;
};
Reverse {
(e.X) = e.X;
(e.X) s.C e.Y = <Reverse (s.C e.X) e.Y>;
e.X = <Reverse () e.X>;
};
- Output:
fdsa
ReScript
let rev_string = (s) => {
let len = Js.String2.length(s)
let arr = []
for i in 0 to (len-1) {
let c = Js.String2.get(s, len - 1 - i)
let _ = Js.Array2.push(arr, c)
}
Js.String2.concatMany("", arr)
}
Js.log(rev_string("abcdefg"))
- Output:
$ bsc revstr.res > revstr.bs.js $ node revstr.bs.js gfedcba
Retro
'asdf s:reverse s:put
REXX
All methods shown below also work with NULL values (strings with a zero length).
using REVERSE BIF
/*REXX program to reverse a string (and show before and after strings).*/
string1 = 'A man, a plan, a canal, Panama!'
string2 = reverse(string1)
say ' original string: ' string1
say ' reversed string: ' string2
/*stick a fork in it, we're done.*/
output
original string: A man, a plan, a canal, Panama! reversed string: !amanaP ,lanac a ,nalp a ,nam A
using SUBSTR BIF, left to right
/*REXX program to reverse a string (and show before and after strings).*/
string1 = 'A man, a plan, a canal, Panama!'
string2 =
do j=1 for length(string1)
string2 = substr(string1,j,1)string2
end /*j*/
say ' original string: ' string1
say ' reversed string: ' string2
/*stick a fork in it, we're done.*/
output is identical to the 1st REXX version.
(Regarding the previous example) Another method of coding an abutment (an implied concatenation) is:
string2 = substr(string1,j,1) || string2
/*───── or ─────*/
string2= substr(string1,j,1)string2
using SUBSTR BIF, right to left
/*REXX program to reverse a string (and show before and after strings).*/
string1 = 'A man, a plan, a canal, Panama!'
string2 =
do j=length(string1) to 1 by -1
string2 = string2 || substr(string1,j,1)
end /*j*/
say ' original string: ' string1
say ' reversed string: ' string2
/*stick a fork in it, we're done.*/
output is identical to the 1st version.
Ring
cStr = "asdf" cStr2 = ""
for x = len(cStr) to 1 step -1 cStr2 += cStr[x] next
See cStr2 # fdsa
RLaB
>> x = "rosettacode"
rosettacode
// script
rx = "";
for (i in strlen(x):1:-1)
{
rx = rx + substr(x, i);
}
>> rx
edocattesor
Robotic
. "local1 = Main string"
. "local2 = Temporary string storage"
. "local3 = String length"
set "$local1" to ""
set "$local2 " to ""
set "local3" to 0
input string "String to reverse:"
set "$local1" to "&INPUT&"
set "$local2" to "$local1"
set "local3" to "$local2.length"
loop start
set "$local1.(('local3' - 1) - 'loopcount')" to "$local2.('loopcount')"
loop for "('local3' - 1)"
* "Reversed string: &$local1& (Length: &$local1.length&)"
end
RPL
≪ "" OVER SIZE 1 FOR j OVER j DUP SUB + -1 STEP SWAP DROP ≫ 'RVSTR' STO "ABC" RVSTR
- Output:
1: "CBA"
Ruby
str = "asdf"
reversed = str.reverse
"résumé niño".reverse #=> "oñin émusér"
for extra credit
graphemes = 'as⃝df̅'.scan(/\X/)
reversed = graphemes.reverse
graphemes.join #=> "f̅ds⃝a"
Run BASIC
string$ = "123456789abcdefghijk"
for i = len(string$) to 1 step -1
print mid$(string$,i,1);
next i
Rust
Reversing ASCII byte-slice (in-place):
let mut buffer = b"abcdef".to_vec();
buffer.reverse();
assert_eq!(buffer, b"fedcba");
Reversing Unicode scalar values:
let output: String = "一二三四五六七八九十".chars().rev().collect();
assert_eq!(output, "十九八七六五四三二一");
Reversing a Chars
iterator doesn't solve the complete problem, because it iterates unicode scalar values, which doesn't account for combining marks:
let output: String = "as⃝df̅".chars().rev().collect();
assert_ne!(output, "f̅ds⃝a"); // should be this
assert_eq!(output, "̅fd⃝sa");
Reversing graphemes clusters, which is provided by the unicode-segmentation crate, solves the problem:
use unicode_segmentation::UnicodeSegmentation;
let output: String = "as⃝df̅".graphemes(true).rev().collect();
assert_eq!(output, "f̅ds⃝a");
S-lang
Here is an 8-bit version:
variable sa = "Hello, World", aa = Char_Type[strlen(sa)+1];
init_char_array(aa, sa);
array_reverse(aa);
% print(aa);
% Unfortunately, strjoin() only joins strings, so we map char()
% [sadly named: actually converts char into single-length string]
% onto the array:
print( strjoin(array_map(String_Type, &char, aa), "") );
Output: "dlroW ,olleH"
For a Unicode version, we'll create a variant of init_char_array(). Side note: If needed, strbytelen() would give total length of string.
define init_unicode_array(a, buf)
{
variable len = strbytelen(buf), ch, p0 = 0, p1 = 0;
while (p1 < len) {
(p1, ch) = strskipchar(buf, p1, 1);
if (ch < 0) print("oops.");
a[p0] = ch;
p0++;
}
}
variable su = "Σὲ γνωρίζω ἀπὸ τὴν κόψη";
variable au = Int_Type[strlen(su)+1];
init_unicode_array(au, su);
array_reverse(au);
% print(au);
print(strjoin(array_map(String_Type, &char, au), "") );
Output: "ηψόκ νὴτ ὸπἀ ωζίρωνγ ὲΣ"
Note: The init...array() functions include the terminating '\0' chars, but we don't have to filter them out as char(0) produces a zero-length string.
SAS
data _null_;
length a b $11;
a="I am Legend";
b=reverse(a);
put a;
put b;
run;
Sather
class MAIN is
main is
s ::= "asdf";
reversed ::= s.reverse;
-- current implementation does not handle multibyte encodings correctly
end;
end;
Scala
Easy way:
"asdf".reverse
Slightly less easy way:
"asdf".foldRight("")((a,b) => b+a)
Unicode-aware, method 1:
def reverse(s: String) = {
import java.text.{Normalizer,BreakIterator}
val norm = Normalizer.normalize(s, Normalizer.Form.NFKC) // waffle -> waffle (optional)
val it = BreakIterator.getCharacterInstance
it setText norm
def break(it: BreakIterator, prev: Int, result: List[String] = Nil): List[String] = it.next match {
case BreakIterator.DONE => result
case cur => break(it, cur, norm.substring(prev, cur) :: result)
}
break(it, it.first).mkString
}
- Output:
scala> reverse("as⃝df̅") res0: String = f̅ds⃝a
Unicode-aware, method 2: I can't guarantee it get all the cases, but it does work with combining characters as well as supplementary characters. I did not bother to preserve the order of newline characters, and I didn't even consider directionality beyond just ruling it out.
def reverseString(s: String) = {
import java.lang.Character._
val combiningTypes = List(NON_SPACING_MARK, ENCLOSING_MARK, COMBINING_SPACING_MARK)
def isCombiningCharacter(c: Char) = combiningTypes contains c.getType
def isCombiningSurrogate(high: Char, low: Char) = combiningTypes contains getType(toCodePoint(high, low))
def isCombining(l: List[Char]) = l match {
case List(a, b) => isCombiningSurrogate(a, b)
case List(a) => isCombiningCharacter(a)
case Nil => true
case _ => throw new IllegalArgumentException("isCombining expects a list of up to two characters")
}
def cleanSurrogate(l: List[Char]) = l match {
case List(a, b) if a.isHighSurrogate && b.isLowSurrogate => l
case List(a, b) if a.isLowSurrogate => Nil
case List(a, b) => List(a)
case _ => throw new IllegalArgumentException("cleanSurrogate expects lists of two characters, exactly")
}
def splitString(string: String) = (string+" ").iterator sliding 2 map (_.toList) map cleanSurrogate toList
def recurse(fwd: List[List[Char]], rev: List[Char]): String = fwd match {
case Nil => rev.mkString
case c :: rest =>
val (combining, remaining) = rest span isCombining
recurse(remaining, c ::: combining.foldLeft(List[Char]())(_ ::: _) ::: rev)
}
recurse(splitString(s), Nil)
}
REPL on Windows doesn't handle Unicode, so I'll show the bytes instead:
scala> res71 map ("\\u%04x" format _.toInt) res80: scala.collection.immutable.IndexedSeq[String] = IndexedSeq(\u0061, \u0073, \u20dd, \u0064, \u0066, \u0305) scala> reverseString(res71) map ("\\u%04x" format _.toInt) res81: scala.collection.immutable.IndexedSeq[String] = IndexedSeq(\u0066, \u0305, \u0064, \u0073, \u20dd, \u0061)
Scheme
(define (string-reverse s)
(list->string (reverse (string->list s))))
> (string-reverse "asdf") "fdsa"
Scratch
Sed
#!/bin/sed -f
/../! b
# Reverse a line. Begin embedding the line between two newlines
s/^.*$/\
&\
/
# Move first character at the end. The regexp matches until
# there are zero or one characters between the markers
tx
:x
s/\(\n.\)\(.*\)\(.\n\)/\3\2\1/
tx
# Remove the newline markers
s/\n//g
Seed7
Seed7 strings are encoded with UTF-32 therefore no special Unicode solution is necessary. The following demonstrates one way of reversing a string with a user-defined function.
$ include "seed7_05.s7i";
const func string: reverso(in string: stri) is func
result
var string: result is "";
local
var integer: index is 0;
begin
for index range length(stri) downto 1 do
result &:= stri[index];
end for;
end func;
const proc: main is func
begin
writeln(reverso("Was it a cat I saw"));
end func;
The following demonstrates the use of the built-in 'reverse' function:
$ include "seed7_05.s7i";
const proc: main is func
begin
writeln(reverse("Was it a cat I saw?"));
end func;
- Output:
was I tac a ti saW
Self
In-place reversal:
'asdf' copyMutable reverse
SenseTalk
put "asdf" reversed -- reverse on the fly
set imp to "rumpelstiltskin"
reverse imp -- reverse in place
put imp
- Output:
fdsa nikstlitslepmur
SequenceL
Using Library Function:
There is a library function to reverse any Sequence. This works for strings since strings are Sequences of characters.
import <Utilities/Sequence.sl>;
main(args(2)) := Sequence::reverse(args[1]);
The Library Function:
The following is the library implementation of the reverse function.
reverse<T> : T(1) -> T(1);
reverse(list(1))[i] :=
let
range := - ((1 ... size(list)) - (size(list) + 1));
in
list[i] foreach i within range;
Sidef
"asdf".reverse; # fdsa
"résumé niño".reverse; # oñin émusér
Simula
BEGIN
TEXT PROCEDURE REV(S); TEXT S;
BEGIN
TEXT T;
INTEGER L,R;
T :- COPY(S);
L := 1; R := T.LENGTH;
WHILE L < R DO
BEGIN
CHARACTER CL,CR;
T.SETPOS(L); CL := T.GETCHAR;
T.SETPOS(R); CR := T.GETCHAR;
T.SETPOS(L); T.PUTCHAR(CR);
T.SETPOS(R); T.PUTCHAR(CL);
L := L+1;
R := R-1;
END;
REV :- T;
END REV;
TEXT INP;
INP :- "asdf";
OUTTEXT(INP); OUTIMAGE;
OUTTEXT(REV(INP)); OUTIMAGE;
END
- Output:
asdf fdsa
Slate
In-place reversal:
'asdf' reverse
Non-destructive reversal:
'asdf' reversed
Smalltalk
'asdf' reverse
the above does inplace, destructive reverse. It is usually better to use
'asdf' reversed
which returns a new string.
SNOBOL4
ASCII-only
output = reverse(reverse("reverse"))
end
- Output:
reverse
Standard ML
val str_reverse = implode o rev o explode;
val string = "asdf";
val reversed = str_reverse string;
Stata
Use strreverse if there are only ASCII characters, and ustrreverse if there are Unicode characters in the string.
. scalar s="ARS LONGA VITA BREVIS"
. di strreverse(s)
SIVERB ATIV AGNOL SRA
. scalar s="Ἐν ἀρχῇ ἐποίησεν ὁ θεὸς τὸν οὐρανὸν καὶ τὴν γῆν"
. di ustrreverse(s)
νῆγ νὴτ ὶακ νὸναρὐο νὸτ ςὸεθ ὁ νεσηίοπἐ ῇχρἀ νἘ
Stringle
This inputs a string from the user and outputs its reverse. The \
reverse operator reverses any string.
$ \$
Swift
Swift's strings are iterated by Character
s, which represent "Unicode grapheme clusters", so reversing it reverses it with combining characters too:
func reverseString(s: String) -> String {
return String(s.characters.reverse())
}
print(reverseString("asdf"))
print(reverseString("as⃝df̅"))
func reverseString(s: String) -> String {
return String(reverse(s))
}
println(reverseString("asdf"))
println(reverseString("as⃝df̅"))
- Output:
fdsa f̅ds⃝a
Symsyn
| reverse string
c : 'abcdefghijklmnopqrstuvwxyz'
d : ' '
c []
i
#c j
- j
if i < j
c.i d 1
c.j c.i 1
d c.j
- j
+ i
goif
endif
c []
OR
c : 'abcdefghijklmnopqrstuvwxyz'
c []
$s
#c j
if j > 0
- j
+ c.j $s 1
goif
endif
$s []
- Output:
abcdefghijklmnopqrstuvwxyz zyxwvutsrqponmlkjihgfedcba
Tailspin
templates reverse
'$:[ $... ] -> $(last..first:-1)...;' !
end reverse
'asdf' -> reverse -> !OUT::write
'
' -> !OUT::write
'as⃝df̅' -> reverse -> !OUT::write
- Output:
fdsa f̅ds⃝a
Tcl
package require Tcl 8.5
string reverse asdf
TI-83 BASIC
Note: length( and sub( can be found in the catalog.
:Str1
:For(I,1,length(Ans)-1
:sub(Ans,2I,1)+Ans
:End
:sub(Ans,1,I→Str1
TMG
Unix TMG:
prog: parse(str);
str: smark any(!<<>>) scopy str/done = { 1 2 };
done: ;
Tosh
when flag clicked
ask "Say something..." and wait
set i to (length of answer)
set inv to ""
repeat until i = 0
set inv to (join (inv) (letter (i) of answer))
change i by -1
end
say inv
Transd
#lang transd
MainModule : {
_start: (lambda (with s "as⃝df̅"
(textout (reverse s))
// reversing user input
(textout "\nPlease, enter a string: ")
(textout "Input: " (reverse (read s)))
))
}
- Output:
̅fd⃝sa Please, enter a string: Hello! Input: !olleH
Turing
Iterative solution, for character shovelers:
function reverse (s : string) : string
var rs := ""
for i : 0 .. length (s) - 1
rs := rs + s (length (s) - i)
end for
result rs
end reverse
put reverse ("iterative example")
put reverse (reverse ("iterative example"))
- Output:
elpmaxe evitareti iterative example
Recursive solution, more natural in Turing:
function reverse (s : string) : string
if s = "" then
result s
else
result reverse (s (2 .. *)) + s (1)
end if
end reverse
put reverse ("recursive example")
put reverse (reverse ("recursive example"))
- Output:
elpmaxe evisrucer recursive example
TUSCRIPT
$$ MODE TUSCRIPT
SET input="was it really a big fat cat i saw"
SET reversetext=TURN (input)
PRINT "before: ",input
PRINT "after: ",reversetext
- Output:
before: was it really a big fat cat i saw after: was i tac taf gib a yllaer ti saw
UNIX Shell
#!/bin/bash
str=abcde
for((i=${#str}-1;i>=0;i--)); do rev="$rev${str:$i:1}"; done
echo $rev
or
str='i43go1342iu 23iu4o 23iu14i324y 2i13'
rev <<< "$str"
#rev is not built-in function, though is in /usr/bin/rev
Unlambda
Reverse the whole input:
``@c`d``s`|k`@c
Ursala
#import std
#cast %s
example = ~&x 'asdf'
verbose_example = reverse 'asdf'
- Output:
'fdsa'
Vala
int main (string[] args) {
if (args.length < 2) {
stdout.printf ("Please, input a string.\n");
return 0;
}
var str = new StringBuilder ();
for (var i = 1; i < args.length; i++) {
str.append (args[i] + " ");
}
stdout.printf ("%s\n", str.str.strip ().reverse ());
return 0;
}
VBA
Non-recursive version
Public Function Reverse(aString as String) as String
' returns the reversed string
dim L as integer 'length of string
dim newString as string
newString = ""
L = len(aString)
for i = L to 1 step -1
newString = newString & mid$(aString, i, 1)
next
Reverse = newString
End Function
Recursive version
Public Function RReverse(aString As String) As String
'returns the reversed string
'do it recursively: cut the string in two, reverse these fragments and put them back together in reverse order
Dim L As Integer 'length of string
Dim M As Integer 'cut point
L = Len(aString)
If L <= 1 Then 'no need to reverse
RReverse = aString
Else
M = Int(L / 2)
RReverse = RReverse(Right$(aString, L - M)) & RReverse(Left$(aString, M))
End If
End Function
Example dialogue
print Reverse("Public Function Reverse(aString As String) As String") gnirtS sA )gnirtS sA gnirtSa(esreveR noitcnuF cilbuP print RReverse("Sunday Monday Tuesday Wednesday Thursday Friday Saturday Love") evoL yadrutaS yadirF yadsruhT yadsendeW yadseuT yadnoM yadnuS print RReverse(Reverse("I know what you did last summer")) I know what you did last summer
VBScript
WScript.Echo StrReverse("asdf")
Vedit macro language
This routine reads the text from current line, reverses it and stores the reversed string in text register 10:
Reg_Empty(10)
for (BOL; !At_EOL; Char) {
Reg_Copy_Block(10, CP, CP+1, INSERT)
}
This routine reverses the current line in-place:
BOL
while (!At_EOL) {
Block_Copy(EOL_pos-1, EOL_pos, DELETE)
}
Vim Script
Take a buffer with the following content:
- Lines 1 and 2, the strings to reverse
- Line 3, comment
- Lines 4 to 6, the Vim Script function
- Lines 7 and 8, calling the Vim Script function twice, in the first instance using line 1's content for the argument and in the second instance line 2's content.
- Line 9, comment
asdf as⃝df̅ """""""""""""""""""""""" function Reverse(chars) call append(line('$'),join(reverse(split(a:chars, '\zs')), "")) endfunction call Reverse(getline(1)) call Reverse(getline(2)) """"""""""""""""""""""""
On entering : (Command-line mode), then typing 4,8so (and {Enter}), the function and two call commands will be sourced and executed. Output is appended to the end of the buffer at lines 10 and 11.
- Output:
fdsa f̅ds⃝a
This illustrates reversing the simple ASCII text string as well as the one with Unicode combining characters ― the latter keeping s+combining enclosing circle (U+0073,U+20DD) together and f+macron (U+0066,U+0305) together.
Visual Basic
Debug.Print VBA.StrReverse("Visual Basic")
Visual Basic .NET
Compiler: >= Visual Basic 2012
Includes both a simple version and a version that uses .NET's built-in ability to enumerate strings by grapheme to support combining characters.
Since the windows console may not support Unicode, the program can optionally redirect its output to a file.
#Const REDIRECTOUT = True
Module Program
Const OUTPATH = "out.txt"
ReadOnly TestCases As String() = {"asdf", "as⃝df̅", "Les Misérables"}
' SIMPLE VERSION
Function Reverse(s As String) As String
Dim t = s.ToCharArray()
Array.Reverse(t)
Return New String(t)
End Function
' EXTRA CREDIT VERSION
Function ReverseElements(s As String) As String
' In .NET, a text element is series of code units that is displayed as one character, and so reversing the text
' elements of the string correctly handles combining character sequences and surrogate pairs.
Dim elements = Globalization.StringInfo.GetTextElementEnumerator(s)
Return String.Concat(AsEnumerable(elements).OfType(Of String).Reverse())
End Function
' Wraps an IEnumerator, allowing it to be used as an IEnumerable.
Iterator Function AsEnumerable(enumerator As IEnumerator) As IEnumerable
Do While enumerator.MoveNext()
Yield enumerator.Current
Loop
End Function
Sub Main()
Const INDENT = " "
#If REDIRECTOUT Then
Const OUTPATH = "out.txt"
Using s = IO.File.Open(OUTPATH, IO.FileMode.Create),
sw As New IO.StreamWriter(s)
Console.SetOut(sw)
#Else
Try
Console.OutputEncoding = Text.Encoding.ASCII
Console.OutputEncoding = Text.Encoding.UTF8
Console.OutputEncoding = Text.Encoding.Unicode
Catch ex As Exception
Console.WriteLine("Failed to set console encoding to Unicode." & vbLf)
End Try
#End If
For Each c In TestCases
Console.WriteLine(c)
Console.WriteLine(INDENT & "SIMPLE: " & Reverse(c))
Console.WriteLine(INDENT & "ELEMENTS: " & ReverseElements(c))
Console.WriteLine()
Next
#If REDIRECTOUT Then
End Using
#End If
End Sub
End Module
- Output (copied from Notepad):
Output is presented using non-fixed-width typeface to properly display combining characters.
asdf SIMPLE: fdsa ELEMENTS: fdsa as⃝df̅ SIMPLE: ̅fd⃝sa ELEMENTS: f̅ds⃝a Les Misérables SIMPLE: selbaŕesiM seL ELEMENTS: selbarésiM seL
Wart
(rev "asdf")
Wart doesn't support Unicode yet.
V (Vlang)
const list =
('
Hello world!
你好世界!
Salamu, Dunia!
こんにちは世界!
¡Hola Mundo!
Chào thế giới!
Hallo Welt!
')
fn main() {
for line in list.split('\n') {if line !='' {println(reverse_string(line))}}
}
fn reverse_string(word string) string {
return word.runes().reverse().string()
}
- Output:
!dlrow olleH !界世好你 !ainuD ,umalaS !界世はちにんこ !odnuM aloH¡ !iớig ếht oàhC !tleW ollaH
Wren
import "./str" for Str
import "./upc" for Graphemes
for (word in ["asdf", "josé", "møøse", "was it a car or a cat I saw", "😀🚂🦊"]) {
System.print(Str.reverse(word))
}
for (word in ["as⃝df̅", "ℵΑΩ 駱駝道 🤔 🇸🇧 🇺🇸 🇬🇧 👨👩👧👦🆗🗺"]) {
System.print(Graphemes.new(word).toList[-1..0].join())
}
- Output:
fdsa ésoj esøøm was I tac a ro rac a ti saw 🦊🚂😀 f̅ds⃝a 🗺🆗👨👩👧👦 🇬🇧 🇺🇸 🇸🇧 🤔 道駝駱 ΩΑℵ
Wortel
; the @rev operator reverses strings and arrays
@rev "abc" ; returns "cba"
; or the same thing using a pointer expression
!~r "abc"
XBS
Using the standard library
log(string.reverse("Hello"))
- Output:
olleH
Using JavaScript methods
log("Hello"->split("")->reverse()->join(""));
- Output:
olleH
Using a custom method
func ReverseString(String){
set Final = "";
for(i=?String-1;0;-1){
Final+=String[i];
}
send Final;
}
log(ReverseString("Hello"));
- Output:
elloH
XPL0
include c:\cxpl\codes; \intrinsic 'code' declarations
string 0; \use zero-terminated strings, instead of MSb terminated
func StrLen(Str); \Return the number of characters in an ASCIIZ string
char Str;
int I;
for I:= 0 to -1>>1-1 do
if Str(I) = 0 then return I;
func RevStr(S); \Reverse the order of the bytes in a string
char S;
int L, I, T;
[L:= StrLen(S);
for I:= 0 to L/2-1 do
[T:= S(I); S(I):= S(L-I-1); S(L-I-1):= T];
return S;
];
[Text(0, RevStr("a")); CrLf(0);
Text(0, RevStr("ab")); CrLf(0);
Text(0, RevStr("abc")); CrLf(0);
Text(0, RevStr("Able was I ere I saw Elba.")); CrLf(0);
]
Output:
a ba cba .ablE was I ere I saw elbA
Yorick
This only handles ASCII characters. It works by converting a string to an array of char; dropping the last character (which is the null byte); reversing the order of the characters; then converting back to a string.
strchar(strchar("asdf")(:-1)(::-1))
Z80 Assembly
This method uses the stack as a temporary store to reverse the order of characters in a string, and self-modifying code to restore the loop counter.
PrintChar equ $BB5A ;Amstrad CPC bios call
Terminator equ 0 ;null terminator for strings
org $8000
ld hl, StringA
call ReverseString
ld hl, StringA
call PrintString
ret ;return to basic
StringA:
byte "12345678",0
;;;; SUBROUTINES
GetStringLength:
;HL = STRING. RETURNS LENGTH IN B. LENGTH IS ONE-INDEXED AND DOES NOT INCLUDE TERMINATOR.
ld b,0 ;clear B
loop_getStringLength:
ld a,(hl) ;read the next char
cp Terminator ;is it the terminator?
ret z ;if so, exit
inc hl ;point HL to next character
inc b ;increase tally
jr loop_getStringLength ;repeat
ReverseString:
;reverse the order of letters in a text string.
;e.g. "ABCD" -> "DCBA"
;the terminator stays put.
;INPUT: HL = SOURCE ADDRESS OF STRING
push de
push hl
push hl
call GetStringLength
pop hl
pop de ;LD DE,HL
LD a,b ;LOAD B INTO A
LD (SMC_ReverseString+1),a ;STORE IT LATER IN THE CODE SO WE CAN RETRIEVE IT.
; TO RECAP, BOTH HL AND DE POINT TO THE BEGINNING OF THE STRING WE WANT TO REVERSE. B EQUALS THE LENGTH OF THE STRING.
; B HAS BEEN BACKED UP WITHOUT USING THE STACK BY STORING IT AS THE OPERAND OF A LATER INSTRUCTION THAT LOADS B WITH A NUMERIC VALUE.
; PUSH BC WOULD NOT HAVE WORKED SINCE THE PROGRAM NEEDS TO PUSH EACH LETTER OF THE STRING DURING THE LOOP.
LOOP_REVERSESTRING_PUSH:
;start at the beginning of the string and push each letter in it, except the terminator.
ld a,(de)
push af
inc de
djnz LOOP_REVERSESTRING_PUSH
SMC_ReverseString:
ld b,$42 ;LETS US PRESERVE B WITHOUT PUSHING IT. THE $42 IS OVERWRITTEN WITH THE STRING'S LENGTH.
LOOP_REVERSESTRING_POP:
;Starting at the beginning of the string, pop A off the stack and store it into the string. This puts the letters back in the reverse
; order.
pop af
ld (hl),a
inc hl
djnz LOOP_REVERSESTRING_POP
pop de
ret
- Output:
87654321
zkl
These only handle ASCII characters, no extra credit.
"this is a test".reverse()
Old school ways to do it:
Build by prepending characters, creates n strings:
"this is a test".reduce(fcn(p,c){c+p})
Convert to list, reverse, convert back to string:
"this is a test".split("").reverse().concat()
Write to a byte buffer and convert to string:
"this is a test".pump(Void,Data().insert.fp(0)).text
The ".fp(0)" creates a closure so each character is fed to data.insert(0,c). pump is a method that sends each character to a function to a sink (in this case /dev/null). The output is the result of the last call, which is data.insert which is self/data. https://en.wikipedia.org/wiki/Comparison_of_programming_languages_%28string_functions%29#reverseProperty "Wikipedia" (as page type) with input value "https://en.wikipedia.org/wiki/Comparison_of_programming_languages_%28string_functions%29#reverse" contains invalid characters or is incomplete and therefore can cause unexpected results during a query or annotation process.
Zoea
program: reverse_string
input: xyzzy
output: yzzyx
Zoea Visual
Zig
We can use `.*` to dereference a literal string pointer to an array, and use `std.mem.reverse` to reverse the slice of that array in-place:
var s = "socat".*;
std.mem.reverse(u8, &s);
or:
var s = "socat".*;
std.mem.reverse(u8, s[0..]);
String `s` now becomes `"tacos"`. Tested on version 0.9.0. Reference: [1].
- Programming Tasks
- String manipulation
- 0815
- 11l
- 360 Assembly
- 8080 Assembly
- 8th
- ACL2
- Action!
- ActionScript
- Ada
- Agda
- Aime
- ALGOL 68
- Amazing Hopper
- Apex
- APL
- AppleScript
- Arturo
- AutoHotkey
- AutoIt
- Avail
- AWK
- Babel
- BaCon
- BASIC
- Applesoft BASIC
- BASIC256
- Commodore BASIC
- IS-BASIC
- QuickBASIC
- Sinclair ZX81 BASIC
- True BASIC
- XBasic
- Yabasic
- Batch File
- BBC BASIC
- Beef
- Befunge
- Binary Lambda Calculus
- BQN
- Bracmat
- Brainf***
- Brat
- Burlesque
- C
- GLib
- C sharp
- C++
- Caché ObjectScript
- Ceylon
- Clipper
- Clojure
- CLU
- COBOL
- CoffeeScript
- ColdFusion
- Common Lisp
- Component Pascal
- Cowgol
- Crystal
- D
- Dart
- DBL
- Dc
- Delphi
- Draco
- Dt
- DWScript
- Dyalect
- Déjà Vu
- E
- E examples needing attention
- EasyLang
- EchoLisp
- EGL
- Eiffel
- Ela
- Elena
- Elixir
- Elm
- Emacs Lisp
- Erlang
- ERRE
- Euler Math Toolbox
- Euphoria
- Explore
- Ezhil
- F Sharp
- Factor
- FALSE
- Fancy
- FBSL
- Fe
- Fennel
- Forth
- Fortran
- FreeBASIC
- Frink
- Futhark
- FutureBasic
- Gambas
- GAP
- Gema
- Genie
- GFA Basic
- Go
- Groovy
- Harbour
- Haskell
- HicEst
- Icon
- Unicon
- Io
- Insitux
- J
- Java
- JavaScript
- Joy
- Jq
- Jsish
- Julia
- K
- Kotlin
- L++
- LabVIEW
- Lambdatalk
- Lang
- Lang5
- Langur
- Lasso
- LC3 Assembly
- LFE
- Liberty BASIC
- Lingo
- LiveCode
- LLVM
- Logo
- Lua
- M2000 Interpreter
- M4
- Maclisp
- MACRO-11
- Maple
- Mathematica
- Wolfram Language
- MATLAB
- Maxima
- MAXScript
- Min
- MiniScript
- MIPS Assembly
- Mirah
- Miranda
- Modula-2
- Modula-3
- MUMPS
- Nanoquery
- Neko
- Nemerle
- NetRexx
- NewLISP
- Nial
- Nim
- NS-HUBASIC
- Nu
- Oberon-2
- Objeck
- Objective-C
- OCaml
- Octave
- Oforth
- Ol
- OmniMark
- OOC
- OpenEdge/Progress
- OxygenBasic
- Oz
- PARI/GP
- Pascal
- PascalABC.NET
- Peloton
- Perl
- Pharo
- Phix
- PHP
- PicoLisp
- Pike
- PL/I
- Plain English
- PlainTeX
- Pop11
- PostScript
- PowerBASIC
- PowerShell
- Prolog
- PureBasic
- Python
- Quackery
- Qi
- R
- Racket
- Raku
- RapidQ
- Rascal
- Raven
- REBOL
- Red
- Refal
- ReScript
- Retro
- REXX
- Ring
- RLaB
- Robotic
- RPL
- Ruby
- Run BASIC
- Rust
- S-lang
- SAS
- Sather
- Scala
- Scheme
- Scratch
- Sed
- Seed7
- Self
- SenseTalk
- SequenceL
- Sidef
- Simula
- Slate
- Smalltalk
- SNOBOL4
- Standard ML
- Stata
- Stringle
- Swift
- Symsyn
- Tailspin
- Tcl
- TI-83 BASIC
- TMG
- Tosh
- Transd
- Turing
- TUSCRIPT
- UNIX Shell
- Unlambda
- Ursala
- Vala
- VBA
- VBScript
- Vedit macro language
- Vim Script
- Visual Basic
- Visual Basic .NET
- Wart
- V (Vlang)
- Wren
- Wren-str
- Wren-upc
- Wortel
- XBS
- XPL0
- Yorick
- Z80 Assembly
- Zkl
- Bc/Omit
- Dc/Omit
- Openscad/Omit
- Zoea
- Zoea Visual
- Zig
- Pages with too many expensive parser function calls