Unique characters
- Task
Given a list of strings, find characters appearing only in one string and once only.
The result should be given in alphabetical order.
Use the following list for this task:
["133252abcdeeffd", "a6789798st", "yxcdfgxcyz"]
- 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 contains most consonants
- Find words which contains more than 3 vowels
- Find words which first and last three letters are equals
- Find words which odd letters are consonants and even letters are vowels or vice_versa
- 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
AppleScript
The filtering here is case sensitive, the sorting dependent on locale.
<lang applescript>use AppleScript version "2.4" -- OS X 10.10 (Yosemite) or later use framework "Foundation"
on uniqueCharacters(listOfStrings)
set countedSet to current application's class "NSCountedSet"'s new() repeat with thisString in listOfStrings tell countedSet to addObjectsFromArray:(thisString's characters) end repeat set mutableSet to current application's class "NSMutableSet"'s setWithSet:(countedSet) tell countedSet to minusSet:(mutableSet) tell mutableSet to minusSet:(countedSet) set sortDescriptor to current application's class "NSSortDescriptor"'s sortDescriptorWithKey:("self") ¬ ascending:(true) selector:("localizedStandardCompare:") return (mutableSet's sortedArrayUsingDescriptors:({sortDescriptor})) as list
end uniqueCharacters
return uniqueCharacters({"133252abcdeeffd", "a6789798st", "yxcdfgxcyz"})</lang>
- Output:
<lang applescript>{"1", "5", "6", "b", "g", "s", "t", "z"}</lang>
Factor
<lang factor>USING: io sequences sets.extras sorting ;
{ "133252abcdeeffd" "a6789798st" "yxcdfgxcyz" } concat non-repeating natural-sort print</lang>
- Output:
156bgstz
Julia
<lang julia>list = ["133252abcdeeffd", "a6789798st", "yxcdfgxcyz"]
function is_once_per_all_strings_in(a::Vector{String})
charlist = collect(prod(a)) counts = Dict(c => count(x -> c == x, charlist) for c in unique(charlist)) return sort([p[1] for p in counts if p[2] == 1])
end
println(is_once_per_all_strings_in(list))
</lang>
- Output:
['1', '5', '6', 'b', 'g', 's', 't', 'z']
One might think that the method above suffers from too many passes through the text with one pass per count, but with a small text length the dictionary lookup takes more time. Compare times for a single pass version:
<lang julia>function uniquein(a)
counts = Dict{Char, Int}() for c in prod(list) counts[c] = get!(counts, c, 0) + 1 end return sort([c for (c, n) in counts if n == 1])
end
println(uniquein(list))
using BenchmarkTools @btime is_once_per_all_strings_in(list) @btime uniquein(list)
</lang>
- Output:
['1', '5', '6', 'b', 'g', 's', 't', 'z']
1.740 μs (28 allocations: 3.08 KiB) 3.763 μs (50 allocations: 3.25 KiB)
This can be rectified (see Phix entry) if we don't save the counts as we go but just exclude entries with duplicates: <lang julia>function uniquein2(a)
s = sort(collect(prod(list))) l = length(s) return [p[2] for p in enumerate(s) if (p[1] == 1 || p[2] != s[p[1] - 1]) && (p[1] == l || p[2] != s[p[1] + 1])]
end
println(uniquein2(list))
@btime uniquein2(list)
</lang>
- Output:
['1', '5', '6', 'b', 'g', 's', 't', 'z']
1.010 μs (14 allocations: 1.05 KiB)
Phix
function once(integer ch, i, string s) integer l = length(s) return (i=1 or ch!=s[i-1]) and (i=l or ch!=s[i+1]) end function sequence set = {"133252abcdeeffd","a6789798st","yxcdfgxcyz"}, res = filter(sort(join(set,"")),once) printf(1,"found %d unique characters: %s\n",{length(res),res})
- Output:
found 8 unique characters: 156bgstz
Raku
One has to wonder where the digits 0 through 9 come in the alphabet... 🤔 For that matter, What alphabet should they be in order of? Most of these entries seem to presuppose ASCII order but that isn't specified anywhere. What to do with characters outside of ASCII (or Latin-1)? Unicode ordinal order? Or maybe DUCET Unicode collation order? It's all very vague.
<lang perl6>my @list = <133252abcdeeffd a6789798st yxcdfgxcyz>;
for @list, (@list, 'AАΑSäaoö٥🤔👨👩👧👧') {
say "$_\nSemi-bogus \"Unicode natural sort\" order: ", .map( *.comb ).Bag.grep( *.value == 1 )».key.sort( { .unival, .NFKD[0], .fc } ).join, "\n (DUCET) Unicode collation order: ", .map( *.comb ).Bag.grep( *.value == 1 )».key.collate.join, "\n";
}</lang>
- Output:
133252abcdeeffd a6789798st yxcdfgxcyz Semi-bogus "Unicode natural sort" order: 156bgstz (DUCET) Unicode collation order: 156bgstz 133252abcdeeffd a6789798st yxcdfgxcyz AАΑSäaoö٥🤔👨👩👧👧 Semi-bogus "Unicode natural sort" order: 15٥6ASäbgoöstzΑА👨👩👧👧🤔 (DUCET) Unicode collation order: 👨👩👧👧🤔ä15٥6AbögosStzΑА
REXX
This REXX program doesn't assume ASCII (or any other) order. This example was run on an ASCII machine.
If this REXX program is run on an ASCII machine, it will use the ASCII order of characters, in this case,
decimal digits, uppercase Latin letters, and then lowercase Latin letters, with other characters interspersed.
On an EBCDIC machine, the order would be lowercase Latin letters, uppercase Latin letters, and then the
decimal digits, with other characters interspersed.
On an EBCDIC machine, the lowercase letters and the uppercase letters aren't contiguous. <lang rexx>/*REXX pgm finds and shows characters that are unique to only one string and once only.*/ parse arg $ /*obtain optional arguments from the CL*/ if $= | $="," then $= '133252abcdeeffd' "a6789798st" 'yxcdfgxcyz' /*use defaults.*/ if $= then do; say "***error*** no lists were specified."; exit 13; end @= /*will be a list of all unique chars. */
do j=0 for 256; x= d2c(j) /*process all the possible characters. */ if x==' ' then iterate /*ignore blanks which are a delimiter. */ _= pos(x, $); if _==0 then iterate /*character not found, then skip it. */ _= pos(x, $, _+1); if _ >0 then iterate /*Character is a duplicate? Skip it. */ @= @ x end /*j*/ /*stick a fork in it, we're all done. */
@@= space(@, 0); L= length(@@) /*elided superfluous blanks; get length*/ if @@== then @= " (none)" /*if none were found, pretty up message*/ if L==0 then L= "no" /*do the same thing for the # of chars.*/ say 'unique characters are: ' @ /*display the unique characters found. */ say say 'Found ' L " unique characters." /*display the # of unique chars found. */</lang>
- output when using the default inputs:
unique characters are: 1 5 6 b g s t z Found 8 unique characters.
Ring
<lang ring> see "working..." + nl see "Unique characters are:" + nl row = 0 str = "" cList = [] uniqueChars = ["133252abcdeeffd", "a6789798st","yxcdfgxcyz"] for n = 1 to len(uniqueChars)
str = str + uniqueChars[n]
next for n = 1 to len(str)
ind = count(str,str[n]) if ind = 1 row = row + 1 add(cList,str[n]) ok
next cList = sort(cList) for n = 1 to len(cList)
see "" + cList[n] + " "
next see nl
see "Found " + row + " unique characters" + nl see "done..." + nl
func count(cString,dString)
sum = 0 while substr(cString,dString) > 0 sum++ cString = substr(cString,substr(cString,dString)+len(string(sum))) end return sum
</lang>
- Output:
working... Unique characters are: 1 5 6 b g s t z Found 8 unique characters done...
Wren
<lang ecmascript>import "/seq" for Lst import "/sort" for Sort
var strings = ["133252abcdeeffd", "a6789798st","yxcdfgxcyz"] var totalChars = strings.reduce { |acc, str| acc + str }.toList var uniqueChars = Lst.individuals(totalChars).where { |l| l[1] == 1 }.map { |l| l[0] }.toList Sort.insertion(uniqueChars) System.print("Found %(uniqueChars.count) unique character(s), namely:") System.print(uniqueChars.join(" "))</lang>
- Output:
Found 8 unique character(s), namely: 1 5 6 b g s t z
XPL0
<lang XPL0>int List, I, N, C; char Tbl(128), Str; string 0; [List:= ["133252abcdeeffd", "a6789798st","yxcdfgxcyz"]; for I:= 0 to 127 do Tbl(I):= 0; for N:= 0 to 2 do
[Str:= List(N); I:= 0; loop [C:= Str(I); if C = 0 then quit; I:= I+1; Tbl(C):= Tbl(C)+1; ]; ];
for I:= 0 to 127 do
if Tbl(I) = 1 then ChOut(0, I);
]</lang>
- Output:
156bgstz