Determine if a string has all unique characters: Difference between revisions
Determine if a string has all unique characters (view source)
Revision as of 16:39, 24 November 2023
, 6 months ago→{{header|Wren}}: Minor tidy
(Add Erlang version) |
m (→{{header|Wren}}: Minor tidy) |
||
(24 intermediate revisions by 17 users not shown) | |||
Line 39:
{{trans|Kotlin}}
<
[Char = Int] charMap
V dup = Char("\0")
Line 62:
print(‘#<40 #2 #10 #8 #. #.’.format(‘------------------------’, ‘------’, ‘----------’, ‘--------’, ‘---’, ‘---------’))
L(s) [‘’, ‘.’, ‘abcABC’, ‘XYZ ZYX’, ‘1234567890ABCDEFGHIJKLMN0PQRSTUVWXYZ’]
processString(s)</
{{out}}
Line 73:
XYZ ZYX 7 no 'Z' 5A 3 5
1234567890ABCDEFGHIJKLMN0PQRSTUVWXYZ 36 no '0' 30 10 25
</pre>
=={{header|Action!}}==
<syntaxhighlight lang="action!">PROC PrintBH(BYTE a)
BYTE ARRAY hex=['0 '1 '2 '3 '4 '5 '6 '7 '8 '9 'A 'B 'C 'D 'E 'F]
Put(hex(a RSH 4))
Put(hex(a&$0F))
RETURN
PROC Test(CHAR ARRAY s)
BYTE i,j,n,pos1,pos2
pos1=0 pos2=0
n=s(0)-1
IF n=255 THEN n=0 FI
FOR i=1 TO n
DO
FOR j=i+1 TO s(0)
DO
IF s(j)=s(i) THEN
pos1=i
pos2=j
EXIT
FI
OD
IF pos1#0 THEN
EXIT
FI
OD
PrintF("""%S"" (len=%B) -> ",s,s(0))
IF pos1=0 THEN
PrintE("all characters are unique.")
ELSE
PrintF("""%C"" (hex=$",s(pos1))
PrintBH(s(pos1))
PrintF(") is duplicated at pos. %B and %B.%E",pos1,pos2)
FI
PutE()
RETURN
PROC Main()
Test("")
Test(".")
Test("abcABC")
Test("XYZ ZYX")
Test("1234567890ABCDEFGHIJKLMN0PQRSTUVWXYZ")
RETURN</syntaxhighlight>
{{out}}
[https://gitlab.com/amarok8bit/action-rosetta-code/-/raw/master/images/Determine_if_a_string_has_all_unique_characters.png Screenshot from Atari 8-bit computer]
<pre>
"" (len=0) -> all characters are unique.
"." (len=1) -> all characters are unique.
"abcABC" (len=6) -> all characters are unique.
"XYZ ZYX" (len=7) -> "X" (hex=$58) is duplicated at pos. 1 and 7.
"1234567890ABCDEFGHIJKLMN0PQRSTUVWXYZ" (len=36) -> "0" (hex=$30) is duplicated at pos. 10 and 25.
</pre>
=={{header|Ada}}==
<
with Ada.Text_IO; use Ada.Text_IO;
procedure Test_All_Chars_Unique is
Line 103 ⟶ 164:
All_Chars_Unique ("1234567890ABCDEFGHIJKLMN0PQRSTUVWXYZ");
end Test_All_Chars_Unique;
</syntaxhighlight>
{{out}}
Line 118 ⟶ 179:
=={{header|ALGOL 68}}==
<
# mode to hold the positions of duplicate characters in a string #
MODE DUPLICATE = STRUCT( INT original, first duplicate );
Line 157 ⟶ 218:
FI
OD
END</
{{out}}
<pre>
Line 173 ⟶ 234:
{{Trans|Python}}
{{Trans|JavaScript}}
<
use framework "Foundation"
use scripting additions
Line 566 ⟶ 627:
return lst
end tell
end zipWith</
{{Out}}
<pre>Indices (1-based) of any duplicated characters:
Line 578 ⟶ 639:
=={{header|Arturo}}==
<
"", ".", "abcABC", "XYZ ZYX",
"1234567890ABCDEFGHIJKLMN0PQRSTUVWXYZ",
Line 610 ⟶ 671:
]
]
]</
{{out}}
Line 626 ⟶ 687:
=={{header|AutoHotkey}}==
<
arr := [], res := ""
for i, v in StrSplit(str)
Line 637 ⟶ 698:
res := StrSplit(res, "`n").1
return """" str """`tlength = " StrLen(str) "`n" (res ? "Duplicates Found:`n" res : "Unique Characters")
}</
Examples:<
for i, v in test
MsgBox % unique_characters(v)
return</
Outputs:<pre>"" length = 0
Unique Characters
Line 663 ⟶ 724:
=={{header|AWK}}==
<syntaxhighlight lang="awk">
# syntax: GAWK -f DETERMINE_IF_A_STRING_HAS_ALL_UNIQUE_CHARACTERS.AWK
BEGIN {
Line 700 ⟶ 761:
}
function max(x,y) { return((x > y) ? x : y) }
</syntaxhighlight>
{{out}}
<pre>
Line 713 ⟶ 774:
|----------------------------------------|--------|------------|----------|-----|-----------|
</pre>
=={{header|BASIC}}==
==={{header|BASIC256}}===
{{trans|FreeBASIC}}
<syntaxhighlight lang="vb">subroutine CaracteresUnicos (cad$)
lngt = length(cad$)
print 'Cadena = "'; cad$; '", longitud = '; lngt
for i = 1 to lngt
for j = i + 1 to lngt
if mid(cad$,i,1) = mid(cad$,j,1) then
print " Primer duplicado en las posiciones " & i & " y " & j & ", caracter = '" & mid(cad$,i,1) & "', valor hex = " & tohex(asc(mid(cad$,i,1)))
return
end if
next j
next i
print " Todos los caracteres son unicos." & chr(10)
end subroutine
call CaracteresUnicos("")
call CaracteresUnicos(".")
call CaracteresUnicos("abcABC")
call CaracteresUnicos("XYZ ZYX")
call CaracteresUnicos("1234567890ABCDEFGHIJKLMN0PQRSTUVWXYZ")</syntaxhighlight>
{{out}}
<pre>Similar as FreeBASIC entry.</pre>
==={{header|Chipmunk Basic}}===
{{works with|Chipmunk Basic|3.6.4}}
{{trans|FreeBASIC}}
<syntaxhighlight lang="qbasic">100 cls
110 sub caracteresunicos(cad$)
120 lngt = len(cad$)
130 print 'Cadena = "';cad$;'" longitud = ';lngt
140 for i = 1 to lngt
150 for j = i+1 to lngt
160 if mid$(cad$,i,1) = mid$(cad$,j,1) then
170 print " Primer duplicado en las posiciones ";i;" y ";j;", caracter = '";mid$(cad$,i,1);"', valor hex = ";hex$(asc(mid$(cad$,i,1)))
180 print
190 exit sub
200 endif
210 next j
220 next i
230 print " Todos los caracteres son unicos.";chr$(10)
240 end sub
250 caracteresunicos("")
260 caracteresunicos(".")
270 caracteresunicos("abcABC")
280 caracteresunicos("XYZ ZYX")
290 caracteresunicos("1234567890ABCDEFGHIJKLMN0PQRSTUVWXYZ")
300 end</syntaxhighlight>
{{out}}
<pre>Same as FreeBASIC entry.</pre>
==={{header|FreeBASIC}}===
<syntaxhighlight lang="freebasic">Sub CaracteresUnicos (cad As String)
Dim As Integer lngt = Len(cad)
Print "Cadena = """; cad; """, longitud = "; lngt
For i As Integer = 1 To lngt
For j As Integer = i + 1 To lngt
If Mid(cad,i,1) = Mid(cad,j,1) Then
Print " Primer duplicado en las posiciones " & i & _
" y " & j & ", caracter = '" & Mid(cad,i,1) & _
"', valor hex = " & Hex(Asc(Mid(cad,i,1)))
Print
Exit Sub
End If
Next j
Next i
Print " Todos los caracteres son unicos." & Chr(10)
End Sub
CaracteresUnicos ("")
CaracteresUnicos (".")
CaracteresUnicos ("abcABC")
CaracteresUnicos ("XYZ ZYX")
CaracteresUnicos ("1234567890ABCDEFGHIJKLMN0PQRSTUVWXYZ")
Sleep</syntaxhighlight>
{{out}}
<pre>
Cadena = "", longitud = 0
Todos los caracteres son unicos.
Cadena = ".", longitud = 1
Todos los caracteres son unicos.
Cadena = "abcABC", longitud = 6
Todos los caracteres son unicos.
Cadena = "XYZ ZYX", longitud = 7
Primer duplicado en las posiciones 1 y 7, caracter = 'X', valor hex = 58
Cadena = "1234567890ABCDEFGHIJKLMN0PQRSTUVWXYZ", longitud = 36
Primer duplicado en las posiciones 10 y 25, caracter = '0', valor hex = 30
</pre>
==={{header|FutureBasic}}===
<syntaxhighlight lang="futurebsic">void local fn StringHasUniqueCharacters( string as CFStringRef )
long i, j, length = len( string )
if length == 0 then printf @"The string \"\" is empty and thus has no characters to compare.\n" : exit fn
printf @"The string: \"%@\" has %ld characters.", string, length
for i = 0 to length - 1
for j = i + 1 to length - 1
if ( fn StringIsEqual( mid( string, i, 1 ), mid( string, j, 1 ) ) )
CFStringRef duplicate = mid( string, i, 1 )
printf @"The first duplicate character, \"%@\", is found at positions %ld and %ld.", duplicate, i, j
printf @"The hex value of \"%@\" is: 0X%x\n", duplicate, fn StringCharacterAtIndex( duplicate, 0 )
exit fn
end if
next
next
printf @"All characters in string are unique.\n"
end fn
fn StringHasUniqueCharacters( @"" )
fn StringHasUniqueCharacters( @"." )
fn StringHasUniqueCharacters( @"abcABC" )
fn StringHasUniqueCharacters( @"XYZ ZYX" )
fn StringHasUniqueCharacters( @"1234567890ABCDEFGHIJKLMN0PQRSTUVWXYZ" )
HandleEvents</syntaxhighlight>
{{output}}
<pre>
The string "" is empty and thus has no characters to compare.
The string: "." has 1 characters.
All characters in string are unique.
The string: "abcABC" has 6 characters.
All characters in string are unique.
The string: "XYZ ZYX" has 7 characters.
The first duplicate character, "X", is found at positions 0 and 6.
The hex value of "X" is: 0X58
The string: "1234567890ABCDEFGHIJKLMN0PQRSTUVWXYZ" has 36 characters.
The first duplicate character, "0", is found at positions 9 and 24.
The hex value of "0" is: 0X30
</pre>
==={{header|PureBasic}}===
{{trans|FreeBASIC}}
<syntaxhighlight lang="purebasic">Procedure CaracteresUnicos(cad.s)
lngt.i = Len(cad)
PrintN("Cadena = '" + cad + "' longitud = " + Str(lngt))
For i.i = 1 To lngt
For j.i = i + 1 To lngt
If Mid(cad, i, 1) = Mid(cad, j, 1)
PrintN(" Primer duplicado en las posiciones " + Str(i) + " y " + Str(j) + ", caracter = '" + Mid(cad, i, 1) + "', valor hex = " + Hex(Asc(Mid(cad, i, 1))))
ProcedureReturn
EndIf
Next
Next
PrintN(" Todos los caracteres son unicos.")
EndProcedure
OpenConsole()
CaracteresUnicos("")
CaracteresUnicos(".")
CaracteresUnicos("abcABC")
CaracteresUnicos("XYZ ZYX")
CaracteresUnicos("1234567890ABCDEFGHIJKLMN0PQRSTUVWXYZ")
PrintN(#CRLF$ + "--- Press ENTER to exit ---"): Input()
CloseConsole()</syntaxhighlight>
{{out}}
<pre>Similar as FreeBASIC entry.</pre>
==={{header|Visual Basic .NET}}===
{{trans|C#}}
<syntaxhighlight lang="vbnet">Module Module1
Sub Main()
Dim input() = {"", ".", "abcABC", "XYZ ZYX", "1234567890ABCDEFGHIJKLMN0PQRSTUVWXYZ"}
For Each s In input
Console.WriteLine($"'{s}' (Length {s.Length}) " + String.Join(", ", s.Select(Function(c, i) (c, i)).GroupBy(Function(t) t.c).Where(Function(g) g.Count() > 1).Select(Function(g) $"'{g.Key}' (0X{AscW(g.Key):X})[{String.Join(", ", g.Select(Function(t) t.i))}]").DefaultIfEmpty("All characters are unique.")))
Next
End Sub
End Module</syntaxhighlight>
{{out}}
<pre>'' (Length 0) All characters are unique.
'.' (Length 1) All characters are unique.
'abcABC' (Length 6) All characters are unique.
'XYZ ZYX' (Length 7) 'X' (0X58)[0, 6], 'Y' (0X59)[1, 5], 'Z' (0X5A)[2, 4]
'1234567890ABCDEFGHIJKLMN0PQRSTUVWXYZ' (Length 36) '0' (0X30)[9, 24]</pre>
==={{header|Yabasic}}===
{{trans|FreeBASIC}}
<syntaxhighlight lang="vb">sub caracteresunicos (cad$)
local lngt, i, j
lngt = len(cad$)
print "cadena = \"", cad$, "\", longitud = ", lngt
for i = 1 to lngt
for j = i + 1 to lngt
if mid$(cad$,i,1) = mid$(cad$,j,1) then
print " Primer duplicado en las posiciones ", i, " y ", j, ", caracter = \'", mid$(cad$,i,1), "\', valor hex = ", hex$(asc(mid$(cad$,i,1)))
print
return
end if
next j
next i
print " Todos los caracteres son unicos.\n"
end sub
caracteresunicos ("")
caracteresunicos (".")
caracteresunicos ("abcABC")
caracteresunicos ("XYZ ZYX")
caracteresunicos ("1234567890ABCDEFGHIJKLMN0PQRSTUVWXYZ")</syntaxhighlight>
{{out}}
<pre>Same as FreeBASIC entry.</pre>
=={{header|BQN}}==
O(n^2) method used for finding indices.
Hex function and loop similar to [[Determine if a string has all the same characters#BQN|Determine if a string has all the same characters]]
<syntaxhighlight lang="bqn">Check←=⌜˜
Hex←⊏⟜(∾"0A"+⟜↕¨10‿26)16{⌽𝕗|⌊∘÷⟜𝕗⍟(↕1+·⌊𝕗⋆⁼1⌈⊢)}
{
𝕊 str:
r←Check str
•Out {
∧´1=+´˘r ? "All characters are unique" ;
i←/⊏(1<+´˘r)/r
ch←(⊑i)⊑str
"'"∾ch∾"' (hex: "∾(Hex ch-@)∾", indices: "∾(•Fmt i)∾") duplicated in string '"∾str∾"'"
}
}¨⟨
""
"."
"abcABC"
"XYZ ZYX"
"1234567890ABCDEFGHIJKLMN0PQRSTUVWXYZ"
⟩</syntaxhighlight><syntaxhighlight lang="text">All characters are unique
All characters are unique
All characters are unique
'X' (hex: 58, indices: ⟨ 0 7 ⟩) duplicated in string 'XYZ ZYX'
'0' (hex: 30, indices: ⟨ 9 24 ⟩) duplicated in string '1234567890ABCDEFGHIJKLMN0PQRSTUVWXYZ'</syntaxhighlight>
=={{header|C}}==
In interactive mode, strings with spaces have to be enclosed in double quotes ("")
<syntaxhighlight lang="c">
#include<stdbool.h>
#include<string.h>
Line 845 ⟶ 1,150:
return 0;
}
</syntaxhighlight>
Output, test strings from the task [[Determine_if_a_string_has_all_the_same_characters]] are also included :
<pre>
Line 882 ⟶ 1,187:
</pre>
=={{header|C sharp|C#}}==
<
using System.Linq;
Line 902 ⟶ 1,207:
}
}
}</
{{out}}
<pre>
Line 913 ⟶ 1,218:
=={{header|C++}}==
<
#include <string>
Line 941 ⟶ 1,246:
string_has_repeated_character("1234567890ABCDEFGHIJKLMN0PQRSTUVWXYZ");
return 0;
}</
{{out}}
Line 965 ⟶ 1,270:
=={{header|Clojure}}==
<syntaxhighlight lang="clojure">
(defn uniq-char-string [s]
(let [len (count s)]
Line 980 ⟶ 1,285:
(inc idx)
(rest chars))))))))
</syntaxhighlight>
{{out}}
Line 996 ⟶ 1,301:
=={{header|Common Lisp}}==
<
(eval-when (:compile-toplevel :load-toplevel)
(ql:quickload '("iterate")))
Line 1,032 ⟶ 1,337:
(return result))))
(mapcar #'unique-string test-strings)</
{{out}}
Line 1,053 ⟶ 1,358:
=={{header|D}}==
{{trans|C++}}
<
void uniqueCharacters(string str) {
Line 1,077 ⟶ 1,382:
uniqueCharacters("XYZ ZYX");
uniqueCharacters("1234567890ABCDEFGHIJKLMN0PQRSTUVWXYZ");
}</
{{out}}
<pre>input: ``, length: 0
Line 1,098 ⟶ 1,403:
{{libheader| System.SysUtils}}
{{Trans|Cpp}}
<syntaxhighlight lang="delphi">
program Determine_if_a_string_has_all_unique_characters;
Line 1,135 ⟶ 1,440:
string_has_repeated_character('1234567890ABCDEFGHIJKLMN0PQRSTUVWXYZ');
readln;
end.</
{{out}}
Delphi strings are start index in one.
Line 1,155 ⟶ 1,460:
String contains a repeated character.
Character "0" (hex 0030) occurs at positions 11 and 26.</pre>
=={{header|EasyLang}}==
<syntaxhighlight>
func$ hex h .
for d in [ h div 16 h mod 16 ]
if d > 9
d += 7
.
h$ &= strchar (d + 48)
.
return h$
.
proc unichar s$ . .
len d[] 65536
s$[] = strchars s$
for i to len s$[]
h = strcode s$[i]
if d[h] <> 0
write " --> duplicates: '" & s$[i] & "' (" & hex h & "h)"
print "' positions: " & d[h] & ", " & i
return
.
d[h] = i
.
print "ok"
.
repeat
s$ = input
until s$ = "EOF"
print "'" & s$ & "'" & " length " & len s$
unichar s$
print ""
.
input_data
.
abcABC
XYZ ZYX
1234567890ABCDEFGHIJKLMN0PQRSTUVWXYZ
EOF
</syntaxhighlight>
=={{header|Erlang|Erlang}}==
<
-module(string_examples).
-export([all_unique/1, all_unique_examples/0]).
Line 1,189 ⟶ 1,535:
["", ".", "abcABC", "XYZ ZYX",
"1234567890ABCDEFGHIJKLMN0PQRSTUVWXYZ"]).
</syntaxhighlight>
{{out}}
<pre>
Line 1,209 ⟶ 1,555:
=={{header|F_Sharp|F#}}==
<
// Determine if a string has all unique characters. Nigel Galloway: June 9th., 2020
let fN (n:string)=n.ToCharArray()|>Array.mapi(fun n g->(n,g))|>Array.groupBy(fun (_,n)->n)|>Array.filter(fun(_,n)->n.Length>1)
Line 1,223 ⟶ 1,569:
allUnique "XYZ ZYX"
allUnique "1234567890ABCDEFGHIJKLMN0PQRSTUVWXYZ"
</syntaxhighlight>
{{out}}
<pre>
Line 1,234 ⟶ 1,580:
=={{header|Factor}}==
<
sequences sets ;
Line 1,252 ⟶ 1,598:
"XYZ ZYX"
"1234567890ABCDEFGHIJKLMN0PQRSTUVWXYZ"
[ uniqueness-report nl ] 5 napply</
{{out}}
<pre>
Line 1,270 ⟶ 1,616:
</pre>
=={{header|Fortran}}==
<syntaxhighlight lang="fortran">
program demo_verify
implicit none
call nodup('')
call nodup('.')
call nodup('abcABC')
call nodup('XYZ ZYX')
call nodup('1234567890ABCDEFGHIJKLMN0PQRSTUVWXYZ')
contains
subroutine nodup(str)
character(len=*),intent(in) :: str
character(len=*),parameter :: g='(*(g0))'
character(len=:),allocatable :: ch
integer
integer
where=0
ch=''
do i=1,len(str)-1
where=index(str(i+1:),ch)
endif
enddo
if(where.eq.0)then
write(*,g)'STR: "',str,'"',new_line('a'),'LEN: ',len(str),'. No duplicate characters found'
else
write(*,g)'STR: "',str,'"'
write(*,'(a,a,t1,a,a)')repeat(' ',where+5),'^',repeat(' ',i+5),'^'
write(*,g)'LEN: ',len(str), &
& '. Duplicate chars. First duplicate at positions ',i,' and ',where, &
& ' where a ','"'//str(where:where)//'"(hex:',hex(str(where:where)),') was found.'
endif
write(*,*)
end subroutine nodup
function hex(ch) result(hexstr)
character(len=1),intent(in) :: ch
character(len=:),allocatable :: hexstr
hexstr=repeat(' ',100)
write(hexstr,'(Z0)')ch
hexstr=trim(hexstr)
end function hex
end program demo_verify
</syntaxhighlight>
{{out}}
<pre>
STR: ""
LEN: 0. No duplicate characters found
STR: "."
LEN: 1. No duplicate characters found
LEN: 6. No duplicate characters found
^ ^
LEN: 7. Duplicate chars. First duplicate at positions 1 and 7 where a "X"(hex:58) was found.
STR: "1234567890ABCDEFGHIJKLMN0PQRSTUVWXYZ"
^ ^
LEN: 36. Duplicate chars. First duplicate at positions 10 and 25 where a "0"(hex:30) was found.
</pre>
=={{header|Go}}==
<
import "fmt"
Line 1,353 ⟶ 1,729:
analyze(s)
}
}</
{{out}}
Line 1,396 ⟶ 1,772:
=={{header|Groovy}}==
{{trans|Java}}
<
static void main(String[] args) {
printf("%-40s %2s %10s %8s %s %s%n", "String", "Length", "All Unique", "1st Diff", "Hex", "Positions")
Line 1,427 ⟶ 1,803:
printf("%-40s %-6d %-10s %-8s %-3s %-5s%n", input, input.length(), unique, diff, hex, position)
}
}</
{{out}}
<pre>String Length All Unique 1st Diff Hex Positions
Line 1,438 ⟶ 1,814:
=={{header|Haskell}}==
<
import Data.Char (ord, toUpper)
import Data.Function(on)
Line 1,507 ⟶ 1,883:
main =
putStrLn $
table ["", ".", "abcABC", "XYZ ZYX", "1234567890ABCDEFGHIJKLMN0PQRSTUVWXYZ"]</
{{out}}
<pre>
Line 1,522 ⟶ 1,898:
Alternatively, defining a duplicatedCharIndices function in terms of sortOn, groupBy, and filter:
<
import Data.Function (on)
import Numeric (showHex)
Line 1,570 ⟶ 1,946:
rjust n c = drop . length <*> (replicate n c <>)
w = maximum (length . xShow <$> xs)
</syntaxhighlight>
{{Out}}
<pre>First duplicated character, if any:
Line 1,581 ⟶ 1,957:
Or, as an alternative to grouping and sorting – folding a string down to a Map of indices:
<
import qualified Data.Map.Strict as M
import Data.List (intercalate, foldl') --'
Line 1,645 ⟶ 2,021:
where
rjust n c = drop . length <*> (replicate n c <>)
w = maximum (length . xShow <$> xs)</
{{Out}}
<pre>First duplicated character, if any:
Line 1,656 ⟶ 2,032:
=={{header|J}}==
Quotes surround the literals to make the computed one-at-a-time results present well in the combined table.
<syntaxhighlight lang="j">
rc_unique=: monad define
string=. '"' , y , '"'
Line 1,673 ⟶ 2,049:
end.
)
</syntaxhighlight>
Tests include those of the C example and a pair of MS-DOS line terminations.
<pre>
Line 1,719 ⟶ 2,095:
More uniqueness tests with performance comparison
<syntaxhighlight lang="j">
NB. unique_index answers "Do the left and right indexes match?"
unique_index=: (i. -: i:)~
Line 1,736 ⟶ 2,112:
the set formation method 15% longer and uses 7 times additional memory.
)
</syntaxhighlight>
=={{header|Java}}==
<
import java.util.HashMap;
import java.util.Map;
Line 1,781 ⟶ 2,157:
}
</syntaxhighlight>
{{Out}}
<pre>
Line 1,791 ⟶ 2,167:
XYZ ZYX 7 no 'Z' 5A 3 5
1234567890ABCDEFGHIJKLMN0PQRSTUVWXYZ 36 no '0' 30 10 25
</pre>
===Using Java 11===
<syntaxhighlight lang="java">
import java.util.HashSet;
import java.util.List;
import java.util.OptionalInt;
import java.util.Set;
public final class DetermineUniqueCharacters {
public static void main(String[] aArgs) {
List<String> words = List.of( "", ".", "abcABC", "XYZ ZYX", "1234567890ABCDEFGHIJKLMN0PQRSTUVWXYZ" );
for ( String word : words ) {
Set<Integer> seen = new HashSet<Integer>();
OptionalInt first = word.chars().filter( ch -> ! seen.add(ch) ).findFirst();
if ( first.isPresent() ) {
final char ch = (char) first.getAsInt();
final String hex = Integer.toHexString(ch).toUpperCase();
System.out.println("Word: \"" + word + "\" contains a repeated character.");
System.out.println("Character '" + ch + "' (hex " + hex + ") occurs at positions "
+ word.indexOf(ch) + " and " + word.indexOf(ch, word.indexOf(ch) + 1));
} else {
System.out.println("Word: \"" + word + "\" has all unique characters.");
}
System.out.println();
}
}
}
</syntaxhighlight>
{{ out }}
<pre>
Word: "" has all unique characters.
Word: "." has all unique characters.
Word: "abcABC" has all unique characters.
Word: "XYZ ZYX" contains a repeated character.
Character 'Z' (hex 5A) occurs at positions 2 and 4
Word: "1234567890ABCDEFGHIJKLMN0PQRSTUVWXYZ" contains a repeated character.
Character '0' (hex 30) occurs at positions 9 and 24
</pre>
=={{header|JavaScript}}==
<
'use strict';
Line 2,003 ⟶ 2,425:
// MAIN ---
return main();
})();</
{{Out}}
<pre>First duplicated character, if any:
Line 2,014 ⟶ 2,436:
Or, as an alternative to sorting and grouping – folding a string down to a dictionary of indices:
<
'use strict';
Line 2,172 ⟶ 2,594:
// MAIN ---
return main();
})();</
{{Out}}
<pre>First duplicated character, if any:
Line 2,186 ⟶ 2,608:
modification of `firstDuplicate` as defined here to implement the alternative
interpretation as the first character to be duplicated.
<
def firstDuplicate:
label $out
Line 2,195 ⟶ 2,617:
| .[.iu] += [ $ix] ;
if .[.iu]|length == 2 then [.iu, .[.iu]], break $out else empty end )
// null ;</
Some helper functions for accomplishing other aspects of the task:
<
def hex:
def stream:
recurse(if . >=
if type=="string" then explode[0] else . end
|
| map(if . < 10 then 48 + . else
def lpad($len): tostring | " " * ($len - width) + .;
Line 2,221 ⟶ 2,641:
"XYZ ZYX",
"1234567890ABCDEFGHIJKLMN0PQRSTUVWXYZ",
"😍😀🙌💃😍🙌" ;</
The main program:<
(data
| firstDuplicate as [$k, $v]
| "\(q|lpad(38)) : \(length|lpad(4)) : \($k // " ") : \($k |if . then hex else " " end) \($v // [])" )
</syntaxhighlight>
{{out}}
<syntaxhighlight lang="sh">
«string» : |s| : C : hex IO=0
«» : 0 : : []
Line 2,235 ⟶ 2,655:
«XYZ ZYX» : 7 : Z : 5A [2,4]
«1234567890ABCDEFGHIJKLMN0PQRSTUVWXYZ» : 36 : 0 : 30 [9,24]
«😍😀🙌💃😍🙌» : 6 : 😍:1f60d [0,4]</
The last line above was adjusted manually as jq has no built-in function for computing the horizontal "printing" width of unicode strings in general.
=={{header|Julia}}==
<
alldup(a) = filter(x -> length(x) > 1, [findall(x -> x == a[i], a) for i in 1:length(a)])
firstduplicate(s) = (a = arr(s); d = alldup(a); isempty(d) ? nothing : first(d))
Line 2,265 ⟶ 2,685:
"🐠🐟🐡🦈🐬🐳🐋🐡",
])
</
<pre>
String | Length | All Unique | First Duplicate (Hex) | Positions
Line 2,282 ⟶ 2,702:
=={{header|Kotlin}}==
{{trans|Java}}
<
fun main() {
Line 2,313 ⟶ 2,733:
val position = if (dup.toInt() == 0) "" else "$pos1 $pos2"
System.out.printf("%-40s %-6d %-10s %-8s %-3s %-5s%n", input, input.length, unique, diff, hex, position)
}</
{{out}}
<pre>String Length All Unique 1st Diff Hex Positions
Line 2,327 ⟶ 2,747:
would caused pattern to match, in the first example below, the substring "cocc" instead of "coc".
<
local function printf(fmt, ...) print(format(fmt,...)) end
Line 2,351 ⟶ 2,771:
show('XYZ ZYX')
show('1234567890ABCDEFGHIJKLMN0PQRSTUVWXYZ')
</syntaxhighlight>
{{out}}
Line 2,362 ⟶ 2,782:
=={{header|Maple}}==
<
local i, index;
printf("input: \"%s\", length: %a\n", s, StringTools:-Length(s));
Line 2,383 ⟶ 2,803:
CheckUnique("abcABC");
CheckUnique("XYZ ZYX");
CheckUnique("1234567890ABCDEFGHIJKLMN0PQRSTUVWXYZ");</
{{out}}
<pre>
Line 2,405 ⟶ 2,825:
=={{header|Mathematica}} / {{header|Wolfram Language}}==
<
UniqueCharacters[s_String] := Module[{c, len, good = True},
c = Characters[s];
Line 2,431 ⟶ 2,851:
UniqueCharacters["abcABC"]
UniqueCharacters["XYZ ZYX"]
UniqueCharacters["1234567890ABCDEFGHIJKLMN0PQRSTUVWXYZ"]</
{{out}}
<pre> with length 0
Line 2,452 ⟶ 2,872:
=={{header|Nanoquery}}==
<
s = str(s)
println "Examining [" + s + "] which has a length of " + str(len(s)) + ":"
Line 2,479 ⟶ 2,899:
for s in tests
analyze(s)
end</
{{out}}
<pre>Examining [] which has a length of 0:
Line 2,495 ⟶ 2,915:
=={{header|Nim}}==
<
proc checkUniqueChars(s: string) =
Line 2,523 ⟶ 2,943:
for s in Strings:
s.checkUniqueChars()</
{{out}}
Line 2,557 ⟶ 2,977:
The string contains duplicate characters.
Character 🐡 (1f421) is present at positions 3 and 8.</pre>
=={{header|OCaml}}==
Using a map to store characters we've met (as keys) and their first position (as indexes).
<syntaxhighlight lang="ocaml">module CMap = Map.Make(struct
type t = char
let compare = compare
end)
(** Add index as argument to string.fold_left *)
let string_fold_left_i f acc str =
snd (String.fold_left
(fun (index, acc) char -> (index+1, f acc index char))
(0, acc) str)
exception Found of int * int * char
let has_duplicates str =
try let _ = string_fold_left_i
(fun map index char ->
match CMap.find_opt char map with
| None -> CMap.add char index map
| Some i -> raise (Found (i,index,char)))
CMap.empty str
in Ok ()
with Found (i,j,c) -> Error (i,j,c)
let printer str =
Format.printf "%S (len %d) : " str (String.length str);
match has_duplicates str with
| Ok () -> Format.printf "No duplicates.\n"
| Error (i,j,c) -> Format.printf "Duplicate '%c' (%#x) at %d and %d\n" c (int_of_char c) i j
let () =
printer "";
printer ".";
printer "abcABC";
printer "XYZ ZYX";
printer "1234567890ABCDEFGHIJKLMN0PQRSTUVWXYZ"</syntaxhighlight>
{{out}}
<pre>"" (len 0) : No duplicates.
"." (len 1) : No duplicates.
"abcABC" (len 6) : No duplicates.
"XYZ ZYX" (len 7) : Duplicate 'Z' (0x5a) at 2 and 4
"1234567890ABCDEFGHIJKLMN0PQRSTUVWXYZ" (len 36) : Duplicate '0' (0x30) at 9 and 24</pre>
=={{header|Perl}}==
<
use warnings;
use feature 'say';
Line 2,591 ⟶ 3,056:
say "no duplicated characters."
}
}</
{{out}}
<pre>"" (length: 0) has no duplicated characters.
Line 2,620 ⟶ 3,085:
=={{header|Phix}}==
As with [[Determine_if_a_string_has_all_the_same_characters#Phix]], you can use utf8_to_utf32() when needed.
<!--<
<span style="color: #008080;">procedure</span> <span style="color: #000000;">all_uniq</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">string</span> <span style="color: #000000;">chars</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">""</span>
Line 2,659 ⟶ 3,124:
<span style="color: #008000;">" "</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"2"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"333"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"55"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"tttTTT"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"tTTTtt"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"4444 444k"</span><span style="color: #0000FF;">}</span>
<span style="color: #7060A8;">papply</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tests</span><span style="color: #0000FF;">,</span><span style="color: #000000;">all_uniq</span><span style="color: #0000FF;">)</span>
<!--</
{{out}}
<pre>
Line 2,705 ⟶ 3,170:
=={{header|PicoLisp}}==
<
(let P 0
(by
Line 2,733 ⟶ 3,198:
(uniq? "abcABC")
(uniq? "XYZ ZYX")
(uniq? "1234567890ABCDEFGHIJKLMN0PQRSTUVWXYZ")</
{{out}}
<pre>
Line 2,744 ⟶ 3,209:
=={{header|Prolog}}==
<
duplicates(S, Dups),
format('For value "~w":~n', S),
Line 2,780 ⟶ 3,245:
test :- report_duplicates('abcABC').
test :- report_duplicates('XYZ ZYX').
test :- report_duplicates('1234567890ABCDEFGHIJKLMN0PQRSTUVWXYZ').</
{{out}}
<pre>
Line 2,808 ⟶ 3,273:
Defined in terms of itertools.groupby:
<
from itertools import groupby
Line 2,953 ⟶ 3,418:
# MAIN ---
if __name__ == '__main__':
main()</
{{Out}}
<pre>First duplicated character, if any:
Line 2,965 ⟶ 3,430:
Or, as an alternative to sorting and grouping, folding a string down to a dictionary with '''reduce''':
<
from functools import reduce
Line 3,129 ⟶ 3,594:
# MAIN ---
if __name__ == '__main__':
main()</
{{Out}}
<pre>First duplicated character, if any:
Line 3,143 ⟶ 3,608:
Tested with Python 3.7.
<
pattern = '(.)' + '.*?' + r'\1'
Line 3,168 ⟶ 3,633:
show('XYZ ZYX')
show('1234567890ABCDEFGHIJKLMN0PQRSTUVWXYZ')
</syntaxhighlight>
{{out}}
Line 3,178 ⟶ 3,643:
"1234567890ABCDEFGHIJKLMN0PQRSTUVWXYZ" (36): '0' (0x30) duplicates at 9, 24
</pre>
=={{header|Quackery}}==
<syntaxhighlight lang="Quackery"> [ over find swap found ] is has ( $ c --> b )
[ dip [ 0 0 true ]
dup size 2 < iff
drop done
dup size 1 - times
[ behead 2dup has iff
[ swap find
dip not
2swap 2drop
i^ tuck + 1+ rot
0 conclude ] done
drop ]
drop ] is uniquechars ( $ --> n n b )
[ dup say 'String "'
echo$
say '" has length '
dup size echo
say ". "
dup uniquechars iff
[ say "There are no duplicated characters."
drop 2drop ]
else
[ rot over peek
dup say 'The character "'
emit
say '" (hex:'
16 base put
echo
base release
say ") is at positions "
swap echo
say " and "
echo
say "." ]
cr ] is task ( $ --> )
$ "" task
$ "." task
$ "abcABC" task
$ "XYZ ZYX" task
$ "1234567890ABCDEFGHIJKLMN0PQRSTUVWXYZ" task</syntaxhighlight>
{{out}}
<pre>String "" has length 0. There are no duplicated characters.
String "." has length 1. There are no duplicated characters.
String "abcABC" has length 6. There are no duplicated characters.
String "XYZ ZYX" has length 7. The character "X" (hex:58) is at positions 0 and 6.
String "1234567890ABCDEFGHIJKLMN0PQRSTUVWXYZ" has length 36. The character "0" (hex:30) is at positions 9 and 24.
</pre>
=={{header|R}}==
Most of this is adapted from [[Determine if a string has all the same characters#R]].
<
{
strLength <- nchar(string)
if(length(strLength) > 1)
{
#R has a distinction between the length of a string and that of a character vector. It is a common source
Line 3,191 ⟶ 3,712:
stop("This task is intended for character vectors with lengths of at most 1.")
}
else if(length(strLength) == 0)
{
cat("Examining a character vector of length 0.",
Line 3,197 ⟶ 3,718:
TRUE
}
else if(strLength == 0)
{
cat("Examining a character vector of length 1, containing an empty string.",
Line 3,203 ⟶ 3,724:
TRUE
}
else if(strLength == 1)
{
cat("Examining the string", paste0(sQuote(string), ","),
Line 3,215 ⟶ 3,736:
"which is of length", paste0(strLength, ":"), "\n")
#strsplit outputs a list. Its first element is the vector of characters that we desire.
characters <- strsplit(string, "")[[1]]
#Our use of match is using R's vector recycling rules. Element i is being checked
#against every other.
indexesOfDuplicates <- sapply(seq_len(strLength), function(i) match(TRUE, characters[i] == characters[-i], nomatch = -1)) + 1
firstDuplicateElementIndex <- indexesOfDuplicates[indexesOfDuplicates != 0][1]
if(is.na(firstDuplicateElementIndex))
{
Line 3,228 ⟶ 3,749:
{
cat("It has duplicates. ")
firstDuplicatedCharacter <- characters[firstDuplicateElementIndex]
cat(sQuote(firstDuplicatedCharacter), "is the first duplicated character. It has hex value",
sprintf("0x%X", as.integer(charToRaw(firstDuplicatedCharacter))),
Line 3,252 ⟶ 3,773:
print(isAllUnique("XYZ ZYX"))
cat("Test: A string of length 36 doesn't contain the letter 'oh':\n")
print(isAllUnique("1234567890ABCDEFGHIJKLMN0PQRSTUVWXYZ"))</
{{out}}
<pre>Test: A string of length 0 (an empty string):
Line 3,278 ⟶ 3,799:
This is a duplicate of the character at index 10.
[1] FALSE</pre>
=={{header|Racket}}==
<
(define (first-non-unique-element.index seq)
Line 3,299 ⟶ 3,821:
(list "" "." "abcABC" "XYZ ZYX"
"1234567890ABCDEFGHIJKLMN0PQRSTUVWXYZ")))
</syntaxhighlight>
{{out}}
Line 3,313 ⟶ 3,835:
Raku works with unicode natively and handles combining characters and multi-byte emoji correctly. In the last string, notice the the length is correctly shown as 11 characters and that the delta with a combining circumflex in position 6 is not the same as the deltas without in positions 5 & 9.
<syntaxhighlight lang="raku"
my $i = 0;
print "\n{$str.raku} (length: {$str.chars}), has ";
my %m = $str.comb.Bag;
if any(%m.values) > 1 {
say "duplicated characters:";
Line 3,332 ⟶ 3,853:
'1234567890ABCDEFGHIJKLMN0PQRSTUVWXYZ',
'01234567890ABCDEFGHIJKLMN0PQRSTUVWXYZ0X',
'🦋🙂👨👩👧👦🙄ΔΔ̂ 🦋Δ👍👨👩👧👦'</
{{out}}
<pre>"" (length: 0), has no duplicated characters.
Line 3,359 ⟶ 3,880:
=={{header|REXX}}==
<
@.= /*assign a default for the @. array. */
parse arg @.1 /*obtain optional argument from the CL.*/
Line 3,387 ⟶ 3,908:
if p\==0 then return k /*Find a dup? Return location.*/
end /*k*/
return 0 /*indicate all chars unique. */</
{{out|output|text= when using the internal defaults}}
<pre>
Line 3,415 ⟶ 3,936:
=={{header|Ring}}==
<
inputStr = ["",".","abcABC","XYZ ZYX","1234567890ABCDEFGHIJKLMN0PQRSTUVWXYZ"]
Line 3,432 ⟶ 3,953:
? " All characters are unique."
next
</syntaxhighlight>
{{out}}
<pre>
Line 3,446 ⟶ 3,967:
Input = '1234567890ABCDEFGHIJKLMN0PQRSTUVWXYZ', length = 36
First duplicate at positions 10 and 25, character = '0'
</pre>
=={{header|RPL}}==
{{works with|Halcyon Calc|4.2.7}}
{| class="wikitable"
! RPL code
! Comment
|-
|
≪ → string
≪ "All chars unique" ""
1 string SIZE '''FOR''' j
string j DUP SUB
'''IF''' DUP2 POS
'''THEN''' DUP " duplicated at " +
string ROT POS →STR + " and " + j →STR +
ROT DROP SWAP
string SIZE 'j' STO
'''ELSE''' + '''END NEXT'''
DROP
≫ ≫ ''''UNICH?'''' STO
|
'''UNICH?''' ''( "string" -- "report" )''
initialize stack
scan string
extract jth character
if already seen
generate report
.
.
exit loop
else add the char to already seen list
clean stack
.
|}
{{in}}
<pre>
≪ { "" "." "abcABC" "XYZ ZYX" "1234567890ABCDEFGHIJKLMN0PQRSTUVWXYZ" } → cases
≪ 1 cases SIZE FOR n cases n GET UNICH? NEXT
≫ ≫ ´TASK’ STO
</pre>
{{out}}
<pre>
5: "All chars unique"
4: "All chars unique"
3: "All chars unique"
2: "Z duplicated at 3 and 5"
1: "0 duplicated at 10 and 25"
</pre>
=={{header|Ruby}}==
<
".",
"abcABC",
Line 3,474 ⟶ 4,043:
puts res
end
</syntaxhighlight>
{{out}}
<pre>"" (size 0) has no duplicates.
Line 3,489 ⟶ 4,058:
=={{header|Rust}}==
<
s.chars().enumerate().find_map(|(i, c)| {
s.chars()
Line 3,524 ⟶ 4,093:
}
}
</syntaxhighlight>
{{out}}
<pre>"" (length 0) is unique
Line 3,545 ⟶ 4,114:
=={{header|Sidef}}==
<
gather {
for k,v in (str.chars.kv) {
Line 3,570 ⟶ 4,139:
}
say "has no duplicates." if !dups
}</
{{out}}
<pre>
Line 3,611 ⟶ 4,180:
=={{header|Tcl}}==
<
array set yesno {1 Yes 2 No}
Line 3,648 ⟶ 4,217:
}
}
</syntaxhighlight>
{{out}}
<pre>
Line 3,662 ⟶ 4,231:
</pre>
=={{header|
{{trans|
<syntaxhighlight lang="v (vlang)">fn analyze(s string) {
chars := s.runes()
le := chars.len
println("Analyzing $s which has a length of $le:")
if le > 1 {
for i := 0; i < le-1; i++ {
for j := i + 1; j < le; j++ {
if chars[j] == chars[i] {
println(" Not all characters in the string are unique.")
println(" '${chars[i]}'' (0x${chars[i]:x}) is duplicated at positions ${i+1} and ${j+1}.\n")
return
}
}
}
}
println(" All characters in the string are unique.\n")
}
fn main() {
strings := [
"",
".",
"abcABC",
"XYZ ZYX",
"1234567890ABCDEFGHIJKLMN0PQRSTUVWXYZ",
"01234567890ABCDEFGHIJKLMN0PQRSTUVWXYZ0X",
"hétérogénéité",
"🎆🎃🎇🎈",
"😍😀🙌💃😍🙌",
"🐠🐟🐡🦈🐬🐳🐋🐡",
]
for s in strings {
analyze(s)
}
}</syntaxhighlight>
{{out}}
<pre>
Analyzing which has a length of 0:
Analyzing . which has a length of 1:
All characters in the string are unique.
Analyzing abcABC which has a length of 6:
All characters in the string are unique.
Analyzing XYZ ZYX which has a length of 7:
Not all characters in the string are unique.
'X'' (0x58) is duplicated at positions 1 and 7.
Analyzing 1234567890ABCDEFGHIJKLMN0PQRSTUVWXYZ which has a length of 36:
Not all characters in the string are unique.
'0'' (0x30) is duplicated at positions 10 and 25.
Analyzing 01234567890ABCDEFGHIJKLMN0PQRSTUVWXYZ0X which has a length of 39:
Not all characters in the string are unique.
'0'' (0x30) is duplicated at positions 1 and 11.
Analyzing hétérogénéité which has a length of 13:
Not all characters in the string are unique.
'é'' (0xe9) is duplicated at positions 2 and 4.
Analyzing 🎆🎃🎇🎈 which has a length of 4:
All characters in the string are unique.
Analyzing 😍😀🙌💃😍🙌 which has a length of 6:
Not all characters in the string are unique.
'😍'' (0x1f60d) is duplicated at positions 1 and 5.
Analyzing 🐠🐟🐡🦈🐬🐳🐋🐡 which has a length of 8:
Not all characters in the string are unique.
'🐡'' (0x1f421) is duplicated at positions 3 and 8.
</pre>
=={{header|Wren}}==
{{trans|Go}}
{{libheader|Wren-fmt}}
<
var analyze = Fn.new { |s|
Line 3,718 ⟶ 4,345:
"🐠🐟🐡🦈🐬🐳🐋🐡"
]
for (s in strings) analyze.call(s)</
{{out}}
Line 3,760 ⟶ 4,387:
=={{header|XPL0}}==
<
proc StrUnique(S); \Show if string has unique chars
Line 3,794 ⟶ 4,421:
StrUnique("1234567890ABCDEFGHIJKLMN0PQRSTUVWXYZ");
StrUnique("thequickbrownfoxjumps");
]</
{{out}}
Line 3,812 ⟶ 4,439:
^ ^ Duplicate character: u, hex 75
</pre>
=={{header|zkl}}==
<
sz,unique,uz,counts := str.len(), str.unique(), unique.len(), str.counts();
println("Length %d: \"%s\"".fmt(sz,str));
Line 3,870 ⟶ 4,454:
else Void.Skip
}.fp(str)).concat(", "));
}</
<
"1234567890ABCDEFGHIJKLMN0PQRSTUVWXYZ",
"01234567890ABCDEFGHIJKLMN0PQRSTUVWXYZ0X");
foreach s in (testStrings){ stringUniqueness(s) }</
{{out}}
<pre>
|