I'm working on modernizing Rosetta Code's infrastructure. Starting with communications. Please accept this time-limited open invite to RC's Slack.. --Michael Mol (talk) 20:59, 30 May 2020 (UTC)

Determine if a string has all the same characters

From Rosetta Code
Task
Determine if a string has all the same characters
You are encouraged to solve this task according to the task description, using any language you may know.
Task

Given a character string   (which may be empty, or have a length of zero characters):

  •   create a function/procedure/routine to:
  •   determine if all the characters in the string are the same
  •   indicate if or which character is different from the previous character
  •   display each string and its length   (as the strings are being examined)
  •   a zero─length (empty) string shall be considered as all the same character(s)
  •   process the strings from left─to─right
  •   if       all the same character,   display a message saying such
  •   if not all the same character,   then:
  •   display a message saying such
  •   display what character is different
  •   only the 1st different character need be displayed
  •   display where the different character is in the string
  •   the above messages can be part of a single message
  •   display the hexadecimal value of the different character


Use (at least) these seven test values   (strings):

  •   a string of length   0   (an empty string)
  •   a string of length   3   which contains three blanks
  •   a string of length   1   which contains:   2
  •   a string of length   3   which contains:   333
  •   a string of length   3   which contains:   .55
  •   a string of length   6   which contains:   tttTTT
  •   a string of length   9   with a blank in the middle:   4444   444k


Show all output here on this page.


Related tasks



Ada[edit]

with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
with Ada.Text_IO; use Ada.Text_IO;
procedure Test_All_Chars_Are_Same is
procedure All_Chars_Are_Same (S : in String) is
First_Diff : Natural := 0;
begin
Put_Line ("Input = """ & S & """, length =" & S'Length'Image);
for I in S'First + 1 .. S'Last loop
if S(I) /= S(S'First) then
First_Diff := I;
exit;
end if;
end loop;
if First_Diff = 0 then
Put_Line (" All characters are the same.");
else
Put (" First difference at position" & First_Diff'Image &
", character = '" & S(First_Diff) &
"', hex = ");
Put (Character'Pos (S(First_Diff)), Width => 0, Base => 16);
New_Line;
end if;
end All_Chars_Are_Same;
begin
All_Chars_Are_Same ("");
All_Chars_Are_Same (" ");
All_Chars_Are_Same ("2");
All_Chars_Are_Same ("333");
All_Chars_Are_Same (".55");
All_Chars_Are_Same ("tttTTT");
All_Chars_Are_Same ("4444 444k");
end Test_All_Chars_Are_Same;
Output:
Input = "", length = 0
 All characters are the same.
Input = "   ", length = 3
 All characters are the same.
Input = "2", length = 1
 All characters are the same.
Input = "333", length = 3
 All characters are the same.
Input = ".55", length = 3
 First difference at position 2, character = '5', hex = 16#35#
Input = "tttTTT", length = 6
 First difference at position 4, character = 'T', hex = 16#54#
Input = "4444 444k", length = 9
 First difference at position 5, character = ' ', hex = 16#20#

ALGOL 68[edit]

BEGIN
# return the position of the first different character in s #
# or UPB s + 1 if all the characters are the same #
OP FIRSTDIFF = ( STRING s )INT:
IF UPB s <= LWB s
THEN
# 0 or 1 character #
UPB s + 1
ELSE
# two or more characters #
INT result := LWB s + 1;
CHAR c1 = s[ LWB s ];
FOR s pos FROM LWB s + 1 TO UPB s WHILE s[ s pos ] = c1 DO result +:= 1 OD;
result
FI # FIRSTDIFF # ;
# convert a character to a hex string #
PROC hex = ( CHAR c )STRING:
BEGIN
STRING result := "";
INT n := ABS c;
IF n = 0
THEN
result := "0"
ELSE
WHILE n > 0 DO
INT d = n MOD 16;
n OVERAB 16;
IF d < 10
THEN REPR ( d + ABS "0" )
ELSE REPR ( ( d - 10 ) + ABS "0" )
FI +=: result
OD
FI;
result
END # hex # ;
# show whether s contains all the same character of the first diff #
PROC show first diff = ( STRING s )VOID:
IF print( ( """", s, """ (length ", whole( ( UPB s + 1 ) - LWB s, 0 ), "): " ) );
INT diff pos = FIRSTDIFF s;
diff pos > UPB s
THEN
# all characters the same #
print( ( "all characters are the same", newline ) )
ELSE
# not all characters are the same #
print( ( "first different character """
, s[ diff pos ]
, """(0x", hex( s[ diff pos ] )
, ") at position: "
, whole( diff pos, 0 )
, newline
)
)
FI # show first diff # ;
# task test cases #
show first diff( "" );
show first diff( " " );
show first diff( "2" );
show first diff( "333" );
show first diff( ".55" );
show first diff( "tttTTT" );
show first diff( "4444 444k" )
END
Output:
"" (length 0): all characters are the same
"   " (length 3): all characters are the same
"2" (length 1): all characters are the same
"333" (length 3): all characters are the same
".55" (length 3): first different character "5"(0x35) at position: 2
"tttTTT" (length 6): first different character "T"(0x54) at position: 4
"4444 444k" (length 9): first different character " "(0x20) at position: 5

AutoHotkey[edit]

testCases := ["", "   ", "2", "333", ".55", "tttTTT", "4444 4444k"]
for key, str in testCases {
MsgBox % "Examining `'" str "`' which has a length of " StrLen(str) ":`n"
if (StrLen(str) == 0) or (StrLen(str) == 1) {
MsgBox % " All characters in the string are the same.`n"
continue
}
firstChar := SubStr(str, 1, 1)
Loop, Parse, str
{
if (firstChar != A_LoopField) {
hex := Format("0x{:x}", Ord(A_LoopField))
MsgBox % " Not all characters in the string are the same.`n Character `'" A_LoopField "`' (" hex ") is different at position " A_Index ".`n", *
break
}
if (A_Index = StrLen(str))
MsgBox % " All characters in the string are the same.`n", *
}
}
 
Output:
Examining '' which has a length of 0:
    All characters in the string are the same.
Examining '   ' which has a length of 3:
    All characters in the string are the same.
Examining '2' which has a length of 1:
    All characters in the string are the same.
Examining '333' which has a length of 3:
    All characters in the string are the same.
Examining '.55' which has a length of 3:
    Not all characters in the string are the same.
    Character '5' (0x35) is different at position 2.
Examining 'tttTTT' which has a length of 6:
    All characters in the string are the same.
Examining '4444 4444k' which has a length of 10:
    Not all characters in the string are the same.
    Character ' ' (0x20) is different at position 5.

AWK[edit]

 
# syntax: GAWK -f DETERMINE_IF_A_STRING_HAS_ALL_THE_SAME_CHARACTERS.AWK
BEGIN {
for (i=0; i<=255; i++) { ord_arr[sprintf("%c",i)] = i } # build array[character]=ordinal_value
n = split(", ,2,333,.55,tttTTT,4444 444k",arr,",")
for (i in arr) {
width = max(width,length(arr[i]))
}
width += 2
fmt = "| %-*s | %-6s | %-8s | %-8s | %-3s | %-8s |\n"
head1 = head2 = sprintf(fmt,width,"string","length","all same","1st diff","hex","position")
gsub(/[^|\n]/,"-",head1)
printf(head1 head2 head1) # column headings
for (i=1; i<=n; i++) {
main(arr[i])
}
printf(head1) # column footing
exit(0)
}
function main(str, c,first_diff,hex,i,leng,msg,position) {
msg = "yes"
leng = length(str)
for (i=1; i<leng; i++) {
c = substr(str,i+1,1)
if (substr(str,i,1) != c) {
msg = "no"
first_diff = "'" c "'"
hex = sprintf("%2X",ord_arr[c])
position = i + 1
break
}
}
printf(fmt,width,"'" str "'",leng,msg,first_diff,hex,position)
}
function max(x,y) { return((x > y) ? x : y) }
 
Output:
|-------------|--------|----------|----------|-----|----------|
| string      | length | all same | 1st diff | hex | position |
|-------------|--------|----------|----------|-----|----------|
| ''          | 0      | yes      |          |     |          |
| '   '       | 3      | yes      |          |     |          |
| '2'         | 1      | yes      |          |     |          |
| '333'       | 3      | yes      |          |     |          |
| '.55'       | 3      | no       | '5'      | 35  | 2        |
| 'tttTTT'    | 6      | no       | 'T'      | 54  | 4        |
| '4444 444k' | 9      | no       | ' '      | 20  | 5        |
|-------------|--------|----------|----------|-----|----------|

C[edit]

In interactive mode, strings with spaces have to be enclosed in double quotes ("")

 
#include<string.h>
#include<stdio.h>
 
int main(int argc,char** argv)
{
int i,len;
char reference;
 
if(argc>2){
printf("Usage : %s <Test String>\n",argv[0]);
return 0;
}
 
if(argc==1||strlen(argv[1])==1){
printf("Input string : \"%s\"\nLength : %d\nAll characters are identical.\n",argc==1?"":argv[1],argc==1?0:(int)strlen(argv[1]));
return 0;
}
 
reference = argv[1][0];
len = strlen(argv[1]);
 
for(i=1;i<len;i++){
if(argv[1][i]!=reference){
printf("Input string : \"%s\"\nLength : %d\nFirst different character : \"%c\"(0x%x) at position : %d\n",argv[1],len,argv[1][i],argv[1][i],i+1);
return 0;
}
}
 
printf("Input string : \"%s\"\nLength : %d\nAll characters are identical.\n",argv[1],len);
 
return 0;
 
}
 

Output :

[email protected]:~/doodles$ ./a.out
Input string : ""
Length : 0
All characters are identical.
[email protected]:~/doodles$ ./a.out "   "
Input string : "   "
Length : 3
All characters are identical.
[email protected]:~/doodles$ ./a.out 2
Input string : "2"
Length : 1
All characters are identical.
[email protected]:~/doodles$ ./a.out 333
Input string : "333"
Length : 3
All characters are identical.
[email protected]:~/doodles$ ./a.out .55
Input string : ".55"
Length : 3
First different character : "5"(0x35) at position : 2
[email protected]:~/doodles$ ./a.out tttTTT
Input string : "tttTTT"
Length : 6
First different character : "T"(0x54) at position : 4
[email protected]:~/doodles$ ./a.out "4444 444k"
Input string : "4444 444k"
Length : 9
First different character : " "(0x20) at position : 5

C#[edit]

Translation of: D
using System;
 
namespace AllSame {
class Program {
static void Analyze(string s) {
Console.WriteLine("Examining [{0}] which has a length of {1}:", s, s.Length);
if (s.Length > 1) {
var b = s[0];
for (int i = 1; i < s.Length; i++) {
var c = s[i];
if (c != b) {
Console.WriteLine(" Not all characters in the string are the same.");
Console.WriteLine(" '{0}' (0x{1:X02}) is different at position {2}", c, (int)c, i);
return;
}
}
 
}
Console.WriteLine(" All characters in the string are the same.");
}
 
static void Main() {
var strs = new string[] { "", " ", "2", "333", ".55", "tttTTT", "4444 444k" };
foreach (var str in strs) {
Analyze(str);
}
}
}
}
Output:
Examining [] which has a length of 0:
    All characters in the string are the same.
Examining [   ] which has a length of 3:
    All characters in the string are the same.
Examining [2] which has a length of 1:
    All characters in the string are the same.
Examining [333] which has a length of 3:
    All characters in the string are the same.
Examining [.55] which has a length of 3:
    Not all characters in the string are the same.
    '5' (0x35) is different at position 1
Examining [tttTTT] which has a length of 6:
    Not all characters in the string are the same.
    'T' (0x54) is different at position 3
Examining [4444 444k] which has a length of 9:
    Not all characters in the string are the same.
    ' ' (0x20) is different at position 4

C++[edit]

#include <iostream>
#include <string>
 
void all_characters_are_the_same(const std::string& str) {
size_t len = str.length();
std::cout << "input: \"" << str << "\", length: " << len << '\n';
if (len > 0) {
char ch = str[0];
for (size_t i = 1; i < len; ++i) {
if (str[i] != ch) {
std::cout << "Not all characters are the same.\n";
std::cout << "Character '" << str[i]
<< "' (hex " << std::hex << static_cast<unsigned int>(str[i])
<< ") at position " << std::dec << i + 1
<< " is not the same as '" << ch << "'.\n\n";
return;
}
}
}
std::cout << "All characters are the same.\n\n";
}
 
int main() {
all_characters_are_the_same("");
all_characters_are_the_same(" ");
all_characters_are_the_same("2");
all_characters_are_the_same("333");
all_characters_are_the_same(".55");
all_characters_are_the_same("tttTTT");
all_characters_are_the_same("4444 444k");
return 0;
}
Output:
input: "", length: 0
All characters are the same.

input: "   ", length: 3
All characters are the same.

input: "2", length: 1
All characters are the same.

input: "333", length: 3
All characters are the same.

input: ".55", length: 3
Not all characters are the same.
Character '5' (hex 35) at position 2 is not the same as '.'.

input: "tttTTT", length: 6
Not all characters are the same.
Character 'T' (hex 54) at position 4 is not the same as 't'.

input: "4444 444k", length: 9
Not all characters are the same.
Character ' ' (hex 20) at position 5 is not the same as '4'.

Clojure[edit]

 
(defn check-all-chars-same [s]
(println (format "String (%s) of len: %d" s (count s)))
(let [num-same (-> (take-while #(= (first s) %) s)
count)]
(if (= num-same (count s))
(println "...all characters the same")
(println (format "...character %d differs - it is 0x%x"
num-same
(byte (nth s num-same)))))))
 
(map check-all-chars-same
[""
" "
"2"
"333"
".55"
"tttTTT"
"4444 444k"])
 
Output:
(String () of len: 0
...all characters the same
String (   ) of len: 3
...all characters the same
String (2) of len: 1
...all characters the same
String (333) of len: 3
...all characters the same
String (.55) of len: 3
...character 1 differs - it is 0x35
String (tttTTT) of len: 6
...character 3 differs - it is 0x54
String (4444 444k) of len: 9
...character 4 differs - it is 0x20

Common Lisp[edit]

Usage : (strequ string(s)) or (strequ) for auto-test

(defun strequ (&rest str)
(if (not str) (setf str (list "" " " "2" "333" ".55" "tttTTT" "4444 444k")))
(dolist (s str)
(do ((i 0 (1+ i)))
((cond
((= i (length s))
(format t "\"~a\" [~d] : All characters are identical.~%" s (length s)) t)
((char/= (char s i) (char s 0))
(format t "\"~a\" [~d] : '~c' (0x~0x) at index ~d is different.~%" s (length s) (char s i) (char-int (char s i)) i) t))))))
Output:
"" [0] : All characters are identical.
"   " [3] : All characters are identical.
"2" [1] : All characters are identical.
"333" [3] : All characters are identical.
".55" [3] : '5' (0x35) at index 1 is different.
"tttTTT" [6] : 'T' (0x54) at index 3 is different.
"4444 444k" [9] : ' ' (0x20) at index 4 is different.

D[edit]

Translation of: Kotlin
import std.stdio;
 
void analyze(string s) {
writefln("Examining [%s] which has a length of %d:", s, s.length);
if (s.length > 1) {
auto b = s[0];
foreach (i, c; s[1..$]) {
if (c != b) {
writeln(" Not all characters in the string are the same.");
writefln(" '%c' (0x%x) is different at position %d", c, c, i);
return;
}
}
}
writeln(" All characters in the string are the same.");
}
 
void main() {
auto strs = ["", " ", "2", "333", ".55", "tttTTT", "4444 444k"];
foreach (str; strs) {
analyze(str);
}
}
Output:
Examining [] which has a length of 0:
    All characters in the string are the same.
Examining [   ] which has a length of 3:
    All characters in the string are the same.
Examining [2] which has a length of 1:
    All characters in the string are the same.
Examining [333] which has a length of 3:
    All characters in the string are the same.
Examining [.55] which has a length of 3:
    Not all characters in the string are the same.
    '5' (0x35) is different at position 0
Examining [tttTTT] which has a length of 6:
    Not all characters in the string are the same.
    'T' (0x54) is different at position 2
Examining [4444 444k] which has a length of 9:
    Not all characters in the string are the same.
    ' ' (0x20) is different at position 3

Delphi[edit]

Translation of: D
 
program Determine_if_a_string_has_all_the_same_characters;
 
{$APPTYPE CONSOLE}
 
uses
System.SysUtils;
 
procedure Analyze(s: string);
var
b, c: char;
i: Integer;
begin
writeln(format('Examining [%s] which has a length of %d:', [s, s.Length]));
if s.Length > 1 then
begin
b := s[1];
for i := 2 to s.Length - 1 do
begin
c := s[i];
if c <> b then
begin
writeln(' Not all characters in the string are the same.');
writeln(format(' "%s" 0x%x is different at position %d', [c, Ord(c), i]));
Exit;
end;
end;
end;
writeln(' All characters in the string are the same.');
end;
 
var
TestCases: array of string = ['', ' ', '2', '333', '.55', 'tttTTT', '4444 444k'];
w: string;
 
begin
for w in TestCases do
Analyze(w);
Readln;
end.
Output:
Examining [] which has a length of 0:
    All characters in the string are the same.
Examining [   ] which has a length of 3:
    All characters in the string are the same.
Examining [2] which has a length of 1:
    All characters in the string are the same.
Examining [333] which has a length of 3:
    All characters in the string are the same.
Examining [.55] which has a length of 3:
    Not all characters in the string are the same.
    "5" 0x35 is different at position 2
Examining [tttTTT] which has a length of 6:
    Not all characters in the string are the same.
    "T" 0x54 is different at position 4
Examining [4444 444k] which has a length of 9:
    Not all characters in the string are the same.
    " " 0x20 is different at position 5

F#[edit]

 
// Determine if a string has all the same characters. Nigel Galloway: June 9th., 2020
let fN n=if String.length n=0 then None else n.ToCharArray()|>Array.tryFindIndex(fun g->g<>n.[0])
 
let allSame n=match fN n with
Some g->printfn "First different character in <<<%s>>> (length %d) is hex %x at position %d" n n.Length (int n.[g]) g
|_->printfn "All Characters are the same in <<<%s>>> (length %d)" n n.Length
 
 
allSame ""
allSame " "
allSame "2"
allSame "333"
allSame ".55"
allSame "tttTTT"
allSame "4444 444k"
 
Output:
All Characters are the same in <<<>>> (length 0)
All Characters are the same in <<<   >>> (length 3)
All Characters are the same in <<<2>>> (length 1)
All Characters are the same in <<<333>>> (length 3)
First different character in <<<.55>>> (length 3) is hex 35 at position 1
First different character in <<<tttTTT>>> (length 6) is hex 54 at position 3
First different character in <<<4444 444k>>> (length 9) is hex 20 at position 4

Factor[edit]

USING: formatting io kernel math.parser sequences ;
 
: find-diff ( str -- i elt ) dup ?first [ = not ] curry find ;
: len. ( str -- ) dup length "%u — length %d — " printf ;
: same. ( -- ) "contains all the same character." print ;
: diff. ( -- ) "contains a different character at " write ;
 
: not-same. ( i elt -- )
dup >hex diff. "index %d: '%c' (0x%s)\n" printf ;
 
: sameness-report. ( str -- )
dup len. find-diff dup [ not-same. ] [ 2drop same. ] if ;
 
{
""
" "
"2"
"333"
".55"
"tttTTT"
"4444 444k"
} [ sameness-report. ] each
Output:
"" — length 0 — contains all the same character.
"   " — length 3 — contains all the same character.
"2" — length 1 — contains all the same character.
"333" — length 3 — contains all the same character.
".55" — length 3 — contains a different character at index 1: '5' (0x35)
"tttTTT" — length 6 — contains a different character at index 3: 'T' (0x54)
"4444 444k" — length 9 — contains a different character at index 4: ' ' (0x20)

Go[edit]

package main
 
import "fmt"
 
func analyze(s string) {
chars := []rune(s)
le := len(chars)
fmt.Printf("Analyzing %q which has a length of %d:\n", s, le)
if le > 1 {
for i := 1; i < le; i++ {
if chars[i] != chars[i-1] {
fmt.Println(" Not all characters in the string are the same.")
fmt.Printf("  %q (%#[1]x) is different at position %d.\n\n", chars[i], i+1)
return
}
}
}
fmt.Println(" All characters in the string are the same.\n")
}
 
func main() {
strings := []string{
"",
" ",
"2",
"333",
".55",
"tttTTT",
"4444 444k",
"pépé",
"🐶🐶🐺🐶",
"🎄🎄🎄🎄",
}
for _, s := range strings {
analyze(s)
}
}
Output:
Analyzing "" which has a length of 0:
  All characters in the string are the same.

Analyzing "   " which has a length of 3:
  All characters in the string are the same.

Analyzing "2" which has a length of 1:
  All characters in the string are the same.

Analyzing "333" which has a length of 3:
  All characters in the string are the same.

Analyzing ".55" which has a length of 3:
  Not all characters in the string are the same.
  '5' (0x35) is different at position 2.

Analyzing "tttTTT" which has a length of 6:
  Not all characters in the string are the same.
  'T' (0x54) is different at position 4.

Analyzing "4444 444k" which has a length of 9:
  Not all characters in the string are the same.
  ' ' (0x20) is different at position 5.

Analyzing "pépé" which has a length of 4:
  Not all characters in the string are the same.
  'é' (0xe9) is different at position 2.

Analyzing "🐶🐶🐺🐶" which has a length of 4:
  Not all characters in the string are the same.
  '🐺' (0x1f43a) is different at position 3.

Analyzing "🎄🎄🎄🎄" which has a length of 4:
  All characters in the string are the same.

Groovy[edit]

Translation of: Java
class Main {
static void main(String[] args) {
String[] tests = ["", " ", "2", "333", ".55", "tttTTT", "4444 444k"]
for (String s : tests) {
analyze(s)
}
}
 
static void analyze(String s) {
println("Examining [$s] which has a length of ${s.length()}")
if (s.length() > 1) {
char firstChar = s.charAt(0)
int lastIndex = s.lastIndexOf(firstChar as String)
if (lastIndex != 0) {
println("\tNot all characters in the string are the same.")
println("\t'$firstChar' (0x${Integer.toHexString(firstChar as Integer)}) is different at position $lastIndex")
return
}
}
println("\tAll characters in the string are the same.")
}
}
Output:
Examining [] which has a length of 0
	All characters in the string are the same.
Examining [   ] which has a length of 3
	Not all characters in the string are the same.
	' ' (0x20) is different at position 2
Examining [2] which has a length of 1
	All characters in the string are the same.
Examining [333] which has a length of 3
	Not all characters in the string are the same.
	'3' (0x33) is different at position 2
Examining [.55] which has a length of 3
	All characters in the string are the same.
Examining [tttTTT] which has a length of 6
	Not all characters in the string are the same.
	't' (0x74) is different at position 2
Examining [4444 444k] which has a length of 9
	Not all characters in the string are the same.
	'4' (0x34) is different at position 7

Haskell[edit]

import Numeric (showHex)
import Data.List (span)
import Data.Char (ord)
 
inconsistentChar :: Eq a => [a] -> Maybe (Int, a)
inconsistentChar [] = Nothing
inconsistentChar xs@(x:_) =
let (pre, post) = span (x ==) xs
in if null post
then Nothing
else Just (length pre, head post)
 
 
---------------------------TEST----------------------------
samples :: [String]
samples = [" ", "2", "333", ".55", "tttTTT", "4444 444"]
 
main :: IO ()
main = do
let w = succ . maximum $ length <$> samples
justifyRight n c = (drop . length) <*> (replicate n c ++)
f = (++ "' -> ") . justifyRight w ' ' . ('\'' :)
(putStrLn . unlines) $
(\s ->
maybe
(f s ++ "consistent")
(\(n, c) ->
f s ++
"inconsistent '" ++
c : "' (0x" ++ showHex (ord c) ")" ++ " at char " ++ show (succ n))
(inconsistentChar s)) <$>
samples

and inconsistentChar could alternatively be defined in terms of findIndex:

import Data.List (findIndex)
 
inconsistentChar :: Eq a => [a] -> Maybe (Int, a)
inconsistentChar [] = Nothing
inconsistentChar xs@(x:_) = findIndex (x /=) xs >>= Just . ((,) <*> (xs !!))
Output:
     '   ' -> consistent
       '2' -> consistent
     '333' -> consistent
     '.55' -> inconsistent '5' (0x35) at char 2
  'tttTTT' -> inconsistent 'T' (0x54) at char 4
'4444 444' -> inconsistent ' ' (0x20) at char 5

J[edit]

 
Doc=: 2 : 'u :: (n"_)'
 
task=: monad define
common=. (; #) y NB. the string and its length
if. same y do.
common , <'same'
else.
i =. differ y
c =. i { y
common , <((, (' (' , ') ' ,~ hex))c),'differs at index ',":i
end.
)
 
hex=: ((Num_j_,26}.Alpha_j_) {~ 16 16 #: a.&i.)&> Doc 'convert ASCII literals to hex representation'
assert '61' -: hex 'a'
 
 
   STRINGS=: <;._2';   ;2;333;.55;tttTTT;4444 444k;'

   same=: (2 > #@:~.)Doc'is 1 if the set of characters has less than 2 elements'
   assert 1 1 1 1 0 0 0 -: same&>STRINGS


   differ=: ([: >: [: {. [: I. 2 ~:/\ ])Doc'given different characters, return the zero index origin position of the character that differs'
   assert 1 -: differ'abbb'

   task&>STRINGS
+---------+-+-------------------------+
|         |0|same                     |
+---------+-+-------------------------+
|         |3|same                     |
+---------+-+-------------------------+
|2        |1|same                     |
+---------+-+-------------------------+
|333      |3|same                     |
+---------+-+-------------------------+
|.55      |3|5 (35) differs at index 1|
+---------+-+-------------------------+
|tttTTT   |6|T (54) differs at index 3|
+---------+-+-------------------------+
|4444 444k|9|  (20) differs at index 4|
+---------+-+-------------------------+

Java[edit]

public class Main{
public static void main(String[] args){
String[] tests = {"", " ", "2", "333", ".55", "tttTTT", "4444 444k"};
for(String s:tests)
analyze(s);
}
 
public static void analyze(String s){
System.out.printf("Examining [%s] which has a length of %d:\n", s, s.length());
if(s.length() > 1){
char firstChar = s.charAt(0);
int lastIndex = s.lastIndexOf(firstChar);
if(lastIndex != 0){
System.out.println("\tNot all characters in the string are the same.");
System.out.printf("\t'%c' (0x%x) is different at position %d\n", firstChar, (int) firstChar, lastIndex);
return;
}
}
System.out.println("\tAll characters in the string are the same.");
}
}
Output:
Examining [] which has a length of 0:
	All characters in the string are the same.
Examining [   ] which has a length of 3:
	Not all characters in the string are the same.
	' ' (0x20) is different at position 2
Examining [2] which has a length of 1:
	All characters in the string are the same.
Examining [333] which has a length of 3:
	Not all characters in the string are the same.
	'3' (0x33) is different at position 2
Examining [.55] which has a length of 3:
	All characters in the string are the same.
Examining [tttTTT] which has a length of 6:
	Not all characters in the string are the same.
	't' (0x74) is different at position 2
Examining [4444 444k] which has a length of 9:
	Not all characters in the string are the same.
	'4' (0x34) is different at position 7

Julia[edit]

firstdifferent(s) = isempty(s) ? nothing : findfirst(x -> x != s[1], s)
 
function testfunction(strings)
println("String | Length | All Same | First Different(Hex) | Position\n" *
"-----------------------------------------------------------------------------")
for s in strings
n = firstdifferent(s)
println(rpad(s, 27), rpad(length(s), 9), n == nothing ? "yes" :
rpad("no $(s[n]) ($(string(Int(s[n]), base=16)))", 36) * string(n))
end
end
 
testfunction([
"",
" ",
"2",
"333",
".55",
"tttTTT",
"4444 444k",
"pépé",
"🐶🐶🐺🐶",
"🎄🎄🎄🎄",
])
 
Output:
String                  | Length | All Same | First Different(Hex) | Position
-----------------------------------------------------------------------------
                           0        yes
                           3        yes
2                          1        yes
333                        3        yes
.55                        3        no               5   (35)           2
tttTTT                     6        no               T   (54)           4
4444 444k                  9        no                   (20)           5
pépé                       4        no               é   (e9)           2
🐶🐶🐺🐶                 4        no               🐺  (1f43a)        9
🎄🎄🎄🎄                   4        yes

Kotlin[edit]

Translation of: Go
fun analyze(s: String) {
println("Examining [$s] which has a length of ${s.length}:")
if (s.length > 1) {
val b = s[0]
for ((i, c) in s.withIndex()) {
if (c != b) {
println(" Not all characters in the string are the same.")
println(" '$c' (0x${Integer.toHexString(c.toInt())}) is different at position $i")
return
}
}
}
println(" All characters in the string are the same.")
}
 
fun main() {
val strs = listOf("", " ", "2", "333", ".55", "tttTTT", "4444 444k")
for (str in strs) {
analyze(str)
}
}
Output:
Examining [] which has a length of 0:
    All characters in the string are the same.
Examining [   ] which has a length of 3:
    All characters in the string are the same.
Examining [2] which has a length of 1:
    All characters in the string are the same.
Examining [333] which has a length of 3:
    All characters in the string are the same.
Examining [.55] which has a length of 3:
    Not all characters in the string are the same.
    '5' (0x35) is different at position 1
Examining [tttTTT] which has a length of 6:
    Not all characters in the string are the same.
    'T' (0x54) is different at position 3
Examining [4444 444k] which has a length of 9:
    Not all characters in the string are the same.
    ' ' (0x20) is different at position 4

Lambdatalk[edit]

 
{def firstDifferingChar
{def firstDifferingChar.r
{lambda {:w :i :n}
{if {or {> :i :n} {= {+ :i 1} {W.length :w}}}
then all characters are the same
else {if {not {W.equal? {W.get :i :w} {W.get {+ :i 1} :w}}}
then at position {+ :i 1} {W.get :i :w} becomes {W.get {+ :i 1} :w}
else {firstDifferingChar.r :w {+ :i 1} :n}}}}}
{lambda {:w}
{if {= {W.length :w} 1}
then :w is a single character
else {firstDifferingChar.r :w 0 {W.length :w}}}}}
-> firstDifferingChar
 
{firstDifferingChar 2}
-> 2 is a single character
{firstDifferingChar 333}
-> all characters are the same
{firstDifferingChar .55}
-> at position 1 . becomes 5
{firstDifferingChar tttTTT}
-> at position 3 t becomes T
 

Lua[edit]

function analyze(s)
print(string.format("Examining [%s] which has a length of %d:", s, string.len(s)))
if string.len(s) > 1 then
local last = string.byte(string.sub(s,1,1))
for i=1,string.len(s) do
local c = string.byte(string.sub(s,i,i))
if last ~= c then
print(" Not all characters in the string are the same.")
print(string.format(" '%s' (0x%x) is different at position %d", string.sub(s,i,i), c, i - 1))
return
end
end
end
print(" All characters in the string are the same.")
end
 
function main()
analyze("")
analyze(" ")
analyze("2")
analyze("333")
analyze(".55")
analyze("tttTTT")
analyze("4444 444k")
end
 
main()
Output:
Examining [] which has a length of 0:
    All characters in the string are the same.
Examining [   ] which has a length of 3:
    All characters in the string are the same.
Examining [2] which has a length of 1:
    All characters in the string are the same.
Examining [333] which has a length of 3:
    All characters in the string are the same.
Examining [.55] which has a length of 3:
    Not all characters in the string are the same.
    '5' (0x35) is different at position 1
Examining [tttTTT] which has a length of 6:
    Not all characters in the string are the same.
    'T' (0x54) is different at position 3
Examining [4444 444k] which has a length of 9:
    Not all characters in the string are the same.
    ' ' (0x20) is different at position 4

Nanoquery[edit]

Translation of: Java
def analyze(s)
s = str(s)
println "Examining [" + s + "] which has a length of " + str(len(s)) + ":"
 
if len(s) < 2
println "\tAll characters in the string are the same."
return
end
 
for i in range(0, len(s) - 2)
if s[i] != s[i + 1]
println "\tNot all characters in the string are the same."
println "\t'" + s[i + 1] + "' " + format("(0x%x)", ord(s[i + 1])) +\
" is different at position " + str(i + 2)
return
end
end
 
println "\tAll characters in the string are the same."
end
 
tests = {"", " ", "2", "333", ".55", "tttTTT", "444 444k"}
for s in tests
analyze(s)
end
Output:
Examining [] which has a length of 0:
        All characters in the string are the same.
Examining [   ] which has a length of 3:
        All characters in the string are the same.
Examining [2] which has a length of 1:
        All characters in the string are the same.
Examining [333] which has a length of 3:
        All characters in the string are the same.
Examining [.55] which has a length of 3:
        Not all characters in the string are the same.
        '5' (0x35) is different at position 2
Examining [tttTTT] which has a length of 6:
        Not all characters in the string are the same.
        'T' (0x54) is different at position 4
Examining [444 444k] which has a length of 8:
        Not all characters in the string are the same.
        ' ' (0x20) is different at position 4

Pascal[edit]

program SameNessOfChar;
{$IFDEF FPC}
{$MODE DELPHI}{$OPTIMIZATION ON,ALL}{$CODEALIGN proc=16}{$ALIGN 16}
{$ELSE}
{$APPTYPE CONSOLE}
{$ENDIF}
uses
sysutils;//Format
const
TestData : array[0..6] of String =
('',' ','2','333','.55','tttTTT','4444 444k');
function PosOfDifferentChar(const s: String):NativeInt;
var
i: Nativeint;
ch:char;
Begin
result := length(s);
IF result < 2 then
EXIT;
ch := s[1];
i := 2;
while (i< result) AND (S[i] =ch) do
inc(i);
result := i;
end;
 
procedure OutIsAllSame(const s: String);
var
l,len: NativeInt;
Begin
l := PosOfDifferentChar(s);
len := Length(s);
write('"',s,'" of length ',len);
IF l = len then
writeln(' contains all the same character')
else
writeln(Format(' is different at position %d "%s" (0x%X)',[l,s[l],Ord(s[l])]));
end;
 
var
i : NativeInt;
begin
For i := Low(TestData) to HIgh(TestData) do
OutIsAllSame(TestData[i]);
end.
Output:
"" of length 0 contains all the same character
"   " of length 3 contains all the same character
"2" of length 1 contains all the same character
"333" of length 3 contains all the same character
".55" of length 3 is different at position 2 "5" (0x35)
"tttTTT" of length 6 is different at position 4 "T" (0x54)
"4444 444k" of length 9 is different at position 5 " " (0x20)

Perl[edit]

use strict;
use warnings;
use feature 'say';
use utf8;
binmode(STDOUT, ':utf8');
use List::AllUtils qw(uniq);
use Unicode::UCD 'charinfo';
use Unicode::Normalize qw(NFC);
 
for my $str (
'',
' ',
'2',
'333',
'.55',
'tttTTT',
'4444 444k',
'Δ👍👨',
'🇬🇧🇬🇧🇬🇧🇬🇧',
"\N{LATIN CAPITAL LETTER A}\N{COMBINING DIAERESIS}\N{COMBINING MACRON}" .
"\N{LATIN CAPITAL LETTER A WITH DIAERESIS}\N{COMBINING MACRON}" .
"\N{LATIN CAPITAL LETTER A WITH DIAERESIS AND MACRON}"
) {
my @S;
push @S, NFC $1 while $str =~ /(\X)/g;
printf qq{\n"$str" (length: %d) has }, scalar @S;
my @U = uniq @S;
if (1 != @U and @U > 0) {
say 'different characters:';
for my $l (@U) {
printf "'%s' %s (0x%x) in positions: %s\n",
$l, charinfo(ord $l)->{'name'}, ord($l), join ', ', map { 1+$_ } grep { $l eq $S[$_] } 0..$#S;
}
} else {
say 'the same character in all positions.'
}
}
Output:
"" (length: 0) has the same character in all positions.

"   " (length: 3) has the same character in all positions.

"2" (length: 1) has the same character in all positions.

"333" (length: 3) has the same character in all positions.

".55" (length: 3) has different characters:
'.' FULL STOP (0x2e) in positions: 1
'5' DIGIT FIVE (0x35) in positions: 2, 3

"tttTTT" (length: 6) has different characters:
't' LATIN SMALL LETTER T (0x74) in positions: 1, 2, 3
'T' LATIN CAPITAL LETTER T (0x54) in positions: 4, 5, 6

"4444 444k" (length: 9) has different characters:
'4' DIGIT FOUR (0x34) in positions: 1, 2, 3, 4, 6, 7, 8
' ' SPACE (0x20) in positions: 5
'k' LATIN SMALL LETTER K (0x6b) in positions: 9

"Δ👍👨" (length: 3) has different characters:
'Δ' GREEK CAPITAL LETTER DELTA (0x394) in positions: 1
'👍' THUMBS UP SIGN (0x1f44d) in positions: 2
'👨' MAN (0x1f468) in positions: 3

"🇬🇧🇬🇧🇬🇧🇬🇧" (length: 4) has the same character in all positions.

"ǞǞǞ" (length: 3) has the same character in all positions.

Phix[edit]

procedure samechar(sequence s)
string msg = "all characters are the same"
integer l = length(s)
if l>=2 then
integer ch = s[1]
for i=2 to l do
integer si = s[i]
if si!=ch then
msg = sprintf(`first different character "%c"(#%02x) at position %d`,{si,si,i})
exit
end if
end for
end if
printf(1,"\"%s\" (length %d): %s\n",{s,l,msg})
end procedure
 
constant tests = {""," ","2","333",".55","tttTTT","4444 444k",
utf8_to_utf32("🐶🐶🐺🐶"),utf8_to_utf32("🎄🎄🎄🎄")}
for i=1 to length(tests) do samechar(tests[i]) end for
Output:
"" (length 0): all characters are the same
"   " (length 3): all characters are the same
"2" (length 1): all characters are the same
"333" (length 3): all characters are the same
".55" (length 3): first different character "5"(#35) at position 2
"tttTTT" (length 6): first different character "T"(#54) at position 4
"4444 444k" (length 9): first different character " "(#20) at position 5
"🐶🐶🐺🐶" (length 4): first different character "🐺"(#1F43A) at position 3
"🎄🎄🎄🎄" (length 4): all characters are the same

PicoLisp[edit]

(de equal? (Str)
(let (Lst (chop Str) C (car Lst) P 2 F)
(prin Str ": ")
(for A (cdr Lst)
(NIL (= A C) (on F) (prin "First different character " A))
(inc 'P) )
(if F (prinl " at position: " P) (prinl "all characters are the same")) ) )
(equal?)
(equal? " ")
(equal? "333")
(equal? ".55")
(equal? "tttTTT")
Output:
: all characters are the same
   : all characters are the same
333: all characters are the same
.55: First different character 5 at position: 2
tttTTT: First different character T at position: 4

Python[edit]

Functional[edit]

What we are testing here is the cardinality of the set of characters from which a string is drawn, so the first thought might well be to use set.

On the other hand, itertools.groupby has the advantage of yielding richer information (the list of groups is ordered), for less work.

Works with: Python version 3.7
'''Determine if a string has all the same characters'''
 
from itertools import groupby
 
 
# firstDifferingCharLR :: String -> Either String Dict
def firstDifferingCharLR(s):
'''Either a message reporting that no character changes were
seen, or a dictionary with details of the first character
(if any) that differs from that at the head of the string.
'''

def details(xs):
c = xs[1][0]
return {
'char': repr(c),
'hex': hex(ord(c)),
'index': s.index(c),
'total': len(s)
}
xs = list(groupby(s))
return Right(details(xs)) if 1 < len(xs) else (
Left('Total length ' + str(len(s)) + ' - No character changes.')
)
 
 
# TEST ----------------------------------------------------
# main :: IO ()
def main():
'''Test of 7 strings'''
 
print(fTable('First, if any, points of difference:\n')(repr)(
either(identity)(
lambda dct: dct['char'] + ' (' + dct['hex'] +
') at character ' + str(1 + dct['index']) +
' of ' + str(dct['total']) + '.'
)
)(firstDifferingCharLR)([
'',
' ',
'2',
'333',
'.55',
'tttTTT',
'4444 444'
]))
 
 
# GENERIC -------------------------------------------------
 
# either :: (a -> c) -> (b -> c) -> Either a b -> c
def either(fl):
'''The application of fl to e if e is a Left value,
or the application of fr to e if e is a Right value.
'''

return lambda fr: lambda e: fl(e['Left']) if (
None is e['Right']
) else fr(e['Right'])
 
 
# identity :: a -> a
def identity(x):
'''The identity function.'''
return x
 
 
# fTable :: String -> (a -> String) ->
# (b -> String) -> (a -> b) -> [a] -> String
def fTable(s):
'''Heading -> x display function -> fx display function ->
f -> xs -> tabular string.
'''

def go(xShow, fxShow, f, xs):
ys = [xShow(x) for x in xs]
w = max(map(len, ys))
return s + '\n' + '\n'.join(map(
lambda x, y: y.rjust(w, ' ') + ' -> ' + fxShow(f(x)),
xs, ys
))
return lambda xShow: lambda fxShow: lambda f: lambda xs: go(
xShow, fxShow, f, xs
)
 
 
# Left :: a -> Either a b
def Left(x):
'''Constructor for an empty Either (option type) value
with an associated string.
'''

return {'type': 'Either', 'Right': None, 'Left': x}
 
 
# Right :: b -> Either a b
def Right(x):
'''Constructor for a populated Either (option type) value'''
return {'type': 'Either', 'Left': None, 'Right': x}
 
 
# MAIN ---
if __name__ == '__main__':
main()
Output:
First, if any, points of difference:

        '' -> Total length 0 - No character changes.
     '   ' -> Total length 3 - No character changes.
       '2' -> Total length 1 - No character changes.
     '333' -> Total length 3 - No character changes.
     '.55' -> '5' (0x35) at character 2 of 3.
  'tttTTT' -> 'T' (0x54) at character 4 of 6.
'4444 444' -> ' ' (0x20) at character 5 of 8.


and for very long strings, itertools.takewhile (here used in the definition of a more general span function), should be slightly more efficient:

'''Determine if a string has all the same characters'''
 
from itertools import takewhile
 
 
# inconsistentChar :: String -> Maybe (Int, Char)
def inconsistentChar(s):
'''Just the first inconsistent character and its position,
or Nothing if all the characters of s are the same,
'''

if s:
h = s[0]
pre, post = span(lambda c: h == c)(s)
return Just((len(pre), post[0])) if post else Nothing()
else:
return Nothing()
 
 
# --------------------------TEST---------------------------
# main :: IO ()
def main():
'''Consistency tests of seven strings'''
 
samples = ['', ' ', '2', '333', '.55', 'tttTTT', '4444 444']
w = 1 + max(map(len, samples))
 
def pfx(s):
return ("'" + s).rjust(w) + "' -> "
 
def charPosn(ic):
i, c = ic
return "inconsistent '" + c + "' (" + hex(ord(c)) + ")" + (
" at char " + str(1 + i)
)
 
print(main.__doc__ + ':\n')
print(
'\n'.join([
pfx(s) + maybe('consistent')(charPosn)(
inconsistentChar(s)
)
for s in samples
])
)
 
 
# -------------------------GENERIC-------------------------
 
# Just :: a -> Maybe a
def Just(x):
'''Constructor for an inhabited Maybe (option type) value.
Wrapper containing the result of a computation.
'''

return {'type': 'Maybe', 'Nothing': False, 'Just': x}
 
 
# Nothing :: Maybe a
def Nothing():
'''Constructor for an empty Maybe (option type) value.
Empty wrapper returned where a computation is not possible.
'''

return {'type': 'Maybe', 'Nothing': True}
 
 
# maybe :: b -> (a -> b) -> Maybe a -> b
def maybe(v):
'''Either the default value v, if m is Nothing,
or the application of f to x,
where m is Just(x).
'''

return lambda f: lambda m: v if None is m or m.get('Nothing') else (
f(m.get('Just'))
)
 
 
# span :: (a -> Bool) -> [a] -> ([a], [a])
def span(p):
'''The longest (possibly empty) prefix of xs
that contains only elements satisfying p,
tupled with the remainder of xs.
span p xs is equivalent to (takeWhile p xs, dropWhile p xs).
'''

def go(xs):
prefix = list(takewhile(p, xs))
return (prefix, xs[len(prefix):])
return lambda xs: go(xs)
 
 
# MAIN ---
if __name__ == '__main__':
main()

Putting itertools aside, we could equivalently define inconsistentChar as:

# inconsistentChar :: String -> Maybe (Int, Char)
def inconsistentChar(s):
'''Just the first inconsistent character and its index,
or Nothing if all the characters of s are the same.
'''

return next(
(Just(ix) for ix in enumerate(s) if s[0] != ix[1]),
Nothing()
)
Output:
Consistency tests of seven strings:

        '' -> consistent
     '   ' -> consistent
       '2' -> consistent
     '333' -> consistent
     '.55' -> inconsistent '5' (0x35) at char 2
  'tttTTT' -> inconsistent 'T' (0x54) at char 4
'4444 444' -> inconsistent ' ' (0x20) at char 5

Racket[edit]

#lang racket
 
(define (first-non-matching-index l =)
(and (not (null? l)) (index-where l (curry (negate =) (car l)))))
 
(define (report-string-sameness s)
(printf "~s (length: ~a): ~a~%"
s
(string-length s)
(cond [(first-non-matching-index (string->list s) char=?)
=> (λ (i)
(let ((c (string-ref s i)))
(format "first different character ~s(~a) at position: ~a" c (char->integer c) (add1 i))))]
[else "all characters are the same"])))
 
(module+ test
(for-each report-string-sameness '("" " " "2" "333" ".55" "tttTTT" "4444 444k")))
Output:
"" (length: 0): all characters are the same
"   " (length: 3): all characters are the same
"2" (length: 1): all characters are the same
"333" (length: 3): all characters are the same
".55" (length: 3): first different character #\5(53) at position: 2
"tttTTT" (length: 6): first different character #\T(84) at position: 4
"4444 444k" (length: 9): first different character #\space(32) at position: 5

Raku[edit]

(formerly Perl 6)

Works with: Rakudo version 2020.08.1

The last string demonstrates how Raku can recognize that glyphs made up of different combinations of combining characters can compare the same. It is built up from explicit codepoints to show that each of the glyphs is made up of different combinations.

  -> $str {
my $i = 0;
print "\n{$str.raku} (length: {$str.chars}), has ";
my %m;
%m{$_}.push: ++$i for $str.comb;
 
if %m > 1 {
say "different characters:";
say "'{.key}' ({.key.uninames}; hex ordinal: {(.key.ords).fmt: "0x%X"})" ~
" in positions: {.value.join: ', '}" for %m.sort( *.value[0] );
} else {
say "the same character in all positions."
}
} for
'',
' ',
'2',
'333',
'.55',
'tttTTT',
'4444 444k',
'🇬🇧🇬🇧🇬🇧🇬🇧',
"\c[LATIN CAPITAL LETTER A]\c[COMBINING DIAERESIS]\c[COMBINING MACRON]" ~
"\c[LATIN CAPITAL LETTER A WITH DIAERESIS]\c[COMBINING MACRON]" ~
"\c[LATIN CAPITAL LETTER A WITH DIAERESIS AND MACRON]",
'AАΑꓮ𐌀𐊠Ꭺ'
Output:
"" (length: 0), has the same character in all positions.

"   " (length: 3), has the same character in all positions.

"2" (length: 1), has the same character in all positions.

"333" (length: 3), has the same character in all positions.

".55" (length: 3), has different characters:
'.' (FULL STOP; hex ordinal: 0x2E) in positions: 1
'5' (DIGIT FIVE; hex ordinal: 0x35) in positions: 2, 3

"tttTTT" (length: 6), has different characters:
't' (LATIN SMALL LETTER T; hex ordinal: 0x74) in positions: 1, 2, 3
'T' (LATIN CAPITAL LETTER T; hex ordinal: 0x54) in positions: 4, 5, 6

"4444 444k" (length: 9), has different characters:
'4' (DIGIT FOUR; hex ordinal: 0x34) in positions: 1, 2, 3, 4, 6, 7, 8
' ' (SPACE; hex ordinal: 0x20) in positions: 5
'k' (LATIN SMALL LETTER K; hex ordinal: 0x6B) in positions: 9

"🇬🇧🇬🇧🇬🇧🇬🇧" (length: 4), has the same character in all positions.

"ǞǞǞ" (length: 3), has the same character in all positions.

"AАΑꓮ𐌀𐊠Ꭺ" (length: 7), has different characters:
'A' (LATIN CAPITAL LETTER A; hex ordinal: 0x41) in positions: 1
'А' (CYRILLIC CAPITAL LETTER A; hex ordinal: 0x410) in positions: 2
'Α' (GREEK CAPITAL LETTER ALPHA; hex ordinal: 0x391) in positions: 3
'ꓮ' (LISU LETTER A; hex ordinal: 0xA4EE) in positions: 4
'𐌀' (OLD ITALIC LETTER A; hex ordinal: 0x10300) in positions: 5
'𐊠' (CARIAN LETTER A; hex ordinal: 0x102A0) in positions: 6
'Ꭺ' (CHEROKEE LETTER GO; hex ordinal: 0x13AA) in positions: 7

REXX[edit]

/*REXX program verifies that  all characters  in a string are all the same (character). */
@chr= ' [character' /* define a literal used for SAY.*/
@all= 'all the same character for string (length' /* " " " " " " */
@.= /*define a default for the @. array. */
parse arg x /*obtain optional argument from the CL.*/
if x\='' then @.1= x /*if user specified an arg, use that. */
else do; @.1= /*use this null string if no arg given.*/
@.2= ' ' /* " " " " " " " */
@.3= 2 /* " " " " " " " */
@.4= 333 /* " " " " " " " */
@.5= .55 /* " " " " " " " */
@.6= 'tttTTT' /* " " " " " " " */
@.7= 4444 444k /* " " " " " " " */
end /* [↑] seventh value contains a blank.*/
 
do j=1; L= length(@.j) /*obtain the length of an array element*/
if j>1 & L==0 then leave /*if arg is null and J>1, then leave. */
r= allSame(@.j) /*R: ≡0, or the location of bad char.*/
if r\==0 then ?= substr(@.j,r,1) /*if not monolithic, obtain the char.*/
if r==0 then say ' ' @all L"):" @.j
else say 'not' @all L"):" @.j @chr ? "('"c2x(?)"'x) at position" r"]."
end /*j*/
exit /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
allSame: procedure; parse arg y /*get a value from the argument list. */
if y=='' then return 0 /*if Y is null, then return 0 (zero)*/
return verify(y, left(y,1) ) /*All chars the same? Return 0 (zero)*/
/* else return location*/
output   when using the internal default inputs:
    all the same character for string (length 0):
    all the same character for string (length 3):
    all the same character for string (length 1): 2
    all the same character for string (length 3): 333
not all the same character for string (length 3): .55      [character 5 ('35'x)  at position 2].
not all the same character for string (length 6): tttTTT      [character T ('54'x)  at position 4].
not all the same character for string (length 9): 4444 444K      [character   ('20'x)  at position 5].

Ring[edit]

 
nputStr = [""," ","2","333",".55","tttTTT","4444 444k"]
 
for word in inputStr
for x = 1 to len(word)
for y = x + 1 to len(word)
if word[x] != word[y]
char = word[y]
 ? "Input = " + "'" + word + "'" + ", length = " + len(word)
 ? " First difference at position " + y + ", character = " + "'" + char + "'"
loop 3
ok
next
next
 
 ? "Input = " + "'" + word + "'" + ", length = " + len(word)
 ? " All characters are the same."
next
 
Output:
Input = '', length = 0
  All characters are the same.
Input = '   ', length = 3
  All characters are the same.
Input = '2', length = 1
  All characters are the same.
Input = '333', length = 3
  All characters are the same.
Input = '.55', length = 3
 First difference at position 2, character = '5'
Input = 'tttTTT', length = 6
 First difference at position 4, character = 'T'
Input = '4444 444k', length = 9
 First difference at position 5, character = ' '

Ruby[edit]

strings = ["", "   ", "2", "333", ".55", "tttTTT", "4444   444k", "pépé", "🐶🐶🐺🐶", "🎄🎄🎄🎄"]
 
strings.each do |str|
pos = str.empty? ? nil : str =~ /[^#{str[0]}]/
print "#{str.inspect} (size #{str.size}): "
puts pos ? "first different char #{str[pos].inspect} (#{'%#x' % str[pos].ord}) at position #{pos}." : "all the same."
end
 
Output:
""  (size 0): all the same.
"   "  (size 3): all the same.
"2"  (size 1): all the same.
"333"  (size 3): all the same.
".55"  (size 3): first different char "5" (0x35) at position 1.
"tttTTT"  (size 6): first different char "T" (0x54) at position 3.
"4444   444k"  (size 11): first different char " " (0x20) at position 4.
"pépé"  (size 4): first different char "é" (0xe9) at position 1.
"🐶🐶🐺🐶"  (size 4): first different char "🐺" (0x1f43a) at position 2.
"🎄🎄🎄🎄"  (size 4): all the same.

Rust[edit]

fn test_string(input: &str) {
println!("Checking string {:?} of length {}:", input, input.chars().count());
 
let mut chars = input.chars();
 
match chars.next() {
Some(first) => {
if let Some((character, pos)) = chars.zip(2..).filter(|(c, _)| *c != first).next() {
println!("\tNot all characters are the same.");
println!("\t{:?} (0x{:X}) at position {} differs.", character, character as u32, pos);
 
return;
}
},
None => {}
}
 
println!("\tAll characters in the string are the same");
}
 
fn main() {
let tests = ["", " ", "2", "333", ".55", "tttTTT", "4444 444k", "pépé", "🐶🐶🐺🐶", "🎄🎄🎄🎄"];
 
for string in &tests {
test_string(string);
}
}
Output:
Checking string "" of length 0:
        All characters in the string are the same
Checking string "   " of length 3:
        All characters in the string are the same
Checking string "2" of length 1:
        All characters in the string are the same
Checking string "333" of length 3:
        All characters in the string are the same
Checking string ".55" of length 3:
        Not all characters are the same.
        '5' (0x35) at position 2 differs.
Checking string "tttTTT" of length 6:
        Not all characters are the same.
        'T' (0x54) at position 4 differs.
Checking string "4444 444k" of length 9:
        Not all characters are the same.
        ' ' (0x20) at position 5 differs.
Checking string "pépé" of length 4:
        Not all characters are the same.
        'é' (0xE9) at position 2 differs.
Checking string "🐶🐶🐺🐶" of length 4:
        Not all characters are the same.
        '🐺' (0x1F43A) at position 3 differs.
Checking string "🎄🎄🎄🎄" of length 4:
        All characters in the string are the same

Scala[edit]

import scala.collection.immutable.ListMap
 
object StringAllSameCharacters {
 
/**Transform an input String into an HashMap of its characters and its first occurrence index*/
def countChar( s : String) : Map[Char, Int] = {
val mapChar = s.toSeq.groupBy(identity).map{ case (a,b) => a->s.indexOf(a) }
val orderedMapChar = ListMap(mapChar.toSeq.sortWith(_._2 < _._2):_*)
orderedMapChar
}
 
/**Check if all the characters of a String are the same given an input Hashmap of it */
def areAllCharEquals ( mapChar : Map[Char, Int] ) : Boolean = {
return mapChar.size <= 1
}
 
/**Retrieve the first "breaking" different character of a String*/
def findFirstDifferentChar ( mapChar : Map[Char, Int] ) : Char = {
if(areAllCharEquals(mapChar) == false) mapChar.keys.toList(1)
else 0.toChar
}
 
/**Convert char to hexadecimal values as "0xHEXVALUE" */
def charToHexString ( c : Char) : String = "0x" + c.toHexString
 
/**Display results as asked in the ask*/
def reportResults( s : String) : String = {
val mapChar = countChar(s)
if (areAllCharEquals(mapChar)) s + " -- length " + s.size + " -- contains all the same character."
else {
val diffChar = findFirstDifferentChar(mapChar)
s + " -- length " + s.size +
" -- contains a different character at index " +
(s.indexOf(diffChar).toInt+1).toString + " : " + charToHexString(diffChar)
}
}
 
def main(args: Array[String]): Unit = {
println(reportResults(""))
println(reportResults(" "))
println(reportResults("2"))
println(reportResults("333"))
println(reportResults(".55"))
println(reportResults("tttTTT"))
println(reportResults("4444 444k"))
}
 
 
}
 
 
Output:
 -- length 0 -- contains all the same character.
    -- length 3 -- contains all the same character.
2 -- length 1 -- contains all the same character.
333 -- length 3 -- contains all the same character.
.55 -- length 3 -- contains a different character at index 2 : 0x35
tttTTT -- length 6 -- contains a different character at index 4 : 0x54
4444 444k -- length 9 -- contains a different character at index 5 : 0x20

Sidef[edit]

func analyze_string(str) {
var chars = str.chars
chars.range.to_a.each_cons(2, {|a,b|
chars[a] == chars[b] || return b
})
return str.len
}
 
var strings = ["", " ", "2", "333", ".55", "tttTTT", "4444 444k", "pépé", "🐶🐶🐺🐶", "🎄🎄🎄🎄"]
 
strings.each {|str|
print "'#{str}' (size #{str.len}): "
var idx = analyze_string(str)
 
if (idx == str.len) {
say "all the same."
}
else {
say "first different char '#{str[idx]}' (#{'%#x' % str[idx].ord}) at position #{idx}."
}
}
Output:
'' (size 0): all the same.
'   ' (size 3): all the same.
'2' (size 1): all the same.
'333' (size 3): all the same.
'.55' (size 3): first different char '5' (0x35) at position 1.
'tttTTT' (size 6): first different char 'T' (0x54) at position 3.
'4444   444k' (size 11): first different char ' ' (0x20) at position 4.
'pépé' (size 4): first different char 'é' (0xe9) at position 1.
'🐶🐶🐺🐶' (size 4): first different char '🐺' (0x1f43a) at position 2.
'🎄🎄🎄🎄' (size 4): all the same.

Standard ML[edit]

 
datatype result=allSame | difference of string*char*int ;
val chkstring = fn input =>
let
val rec chk = fn ([],n) => allSame
| ([x],n) => allSame
| (x::y::t,n)=> if x=y then chk (y::t,n+1)
else difference (Int.fmt StringCvt.HEX(Char.ord(y)),y,n)
in
( input, String.size input , chk ( String.explode input,2 ) )
end;
 

result (string, string length, same or (hex,char,position))

 
- map chkstring [ ""," ","1","333",".55","tttTTT","4444 444k" ];
val it =
[("", 0, allSame), (" ", 3, allSame), ("1", 1, allSame),
("333", 3, allSame), (".55", 3, difference ("35", #"5", 2)),
("tttTTT", 6, difference ("54", #"T", 4)),
("4444 444k", 9, difference ("20", #" ", 5))]:
 

Tcl[edit]

package require Tcl 8.6 ; # For binary encode
 
array set yesno {1 Yes 0 No}
 
set test {
{}
{ }
{2}
{333}
{.55}
{tttTTT}
{4444 444k}
{jjjjjjj}
}
 
# Loop through test strings
foreach str $test {
set chars [dict create] ; # init dictionary
set same 1
set prev {}
# Loop through characters in string
for {set i 0} {$i < [string length $str]} {incr i} {
set c [string index $str $i] ; # get char at index
if {$prev == {}} {
set prev $c ; # initialize prev if it doesn't exist
}
if {$c != $prev} {
set same 0
break ; # Found a different char, break out of the loop
}
}
 
# Handle Output
puts [format "Tested: %12s (len: %2d). All Same? %3s. " \
"'$str'" [string length $str] $yesno($same)]
if {! $same} {
puts [format " --> Different character '%s' (hex: 0x%s) appears at index: %s." \
$c [binary encode hex $c] $i]
}
}
Output:
Tested:           '' (len:  0). All Same? Yes.
Tested:        '   ' (len:  3). All Same? Yes.
Tested:          '2' (len:  1). All Same? Yes.
Tested:        '333' (len:  3). All Same? Yes.
Tested:        '.55' (len:  3). All Same?  No.
 --> Different character '5' (hex: 0x35) appears at index: 1.
Tested:     'tttTTT' (len:  6). All Same?  No.
 --> Different character 'T' (hex: 0x54) appears at index: 3.
Tested:  '4444 444k' (len:  9). All Same?  No.
 --> Different character ' ' (hex: 0x20) appears at index: 4.
Tested:    'jjjjjjj' (len:  7). All Same? Yes.

Visual Basic .NET[edit]

Translation of: C#
Module Module1
 
Sub Analyze(s As String)
Console.WriteLine("Examining [{0}] which has a length of {1}:", s, s.Length)
If s.Length > 1 Then
Dim b = s(0)
For i = 1 To s.Length
Dim c = s(i - 1)
If c <> b Then
Console.WriteLine(" Not all characters in the string are the same.")
Console.WriteLine(" '{0}' (0x{1:X02}) is different at position {2}", c, AscW(c), i - 1)
Return
End If
Next
End If
Console.WriteLine(" All characters in the string are the same.")
End Sub
 
Sub Main()
Dim strs() = {"", " ", "2", "333", ".55", "tttTTT", "4444 444k"}
For Each s In strs
Analyze(s)
Next
End Sub
 
End Module
Output:
Examining [] which has a length of 0:
    All characters in the string are the same.
Examining [   ] which has a length of 3:
    All characters in the string are the same.
Examining [2] which has a length of 1:
    All characters in the string are the same.
Examining [333] which has a length of 3:
    All characters in the string are the same.
Examining [.55] which has a length of 3:
    Not all characters in the string are the same.
    '5' (0x35) is different at position 1
Examining [tttTTT] which has a length of 6:
    Not all characters in the string are the same.
    'T' (0x54) is different at position 3
Examining [4444 444k] which has a length of 9:
    Not all characters in the string are the same.
    ' ' (0x20) is different at position 4

Wren[edit]

Translation of: Go
Library: Wren-fmt
import "/fmt" for Conv, Fmt
 
var analyze = Fn.new { |s|
var chars = s.codePoints.toList
var le = chars.count
System.print("Analyzing %(Fmt.q(s)) which has a length of %(le):")
if (le > 1) {
for (i in 1...le) {
if (chars[i] != chars[i-1]) {
System.print(" Not all characters in the string are the same.")
var c = String.fromCodePoint(chars[i])
var hex = Conv.hex(chars[i])
System.print(" '%(c)' (0x%(hex)) is different at position %(i+1).\n")
return
}
}
}
System.print(" All characters in the string are the same.\n")
}
 
var strings = [
"",
" ",
"2",
"333",
".55",
"tttTTT",
"4444 444k",
"pépé",
"🐶🐶🐺🐶",
"🎄🎄🎄🎄"
]
for (s in strings) analyze.call(s)
Output:
Analyzing "" which has a length of 0:
  All characters in the string are the same.

Analyzing "   " which has a length of 3:
  All characters in the string are the same.

Analyzing "2" which has a length of 1:
  All characters in the string are the same.

Analyzing "333" which has a length of 3:
  All characters in the string are the same.

Analyzing ".55" which has a length of 3:
  Not all characters in the string are the same.
  '5' (0x35) is different at position 2.

Analyzing "tttTTT" which has a length of 6:
  Not all characters in the string are the same.
  'T' (0x54) is different at position 4.

Analyzing "4444 444k" which has a length of 9:
  Not all characters in the string are the same.
  ' ' (0x20) is different at position 5.

Analyzing "pépé" which has a length of 4:
  Not all characters in the string are the same.
  'é' (0xe9) is different at position 2.

Analyzing "🐶🐶🐺🐶" which has a length of 4:
  Not all characters in the string are the same.
  '🐺' (0x1f43a) is different at position 3.

Analyzing "🎄🎄🎄🎄" which has a length of 4:
  All characters in the string are the same.

XPL0[edit]

include xpllib;                 \contains StrLen function
 
proc StrSame(S); \Show if string has same characters
char S;
int L, I, J, K;
[L:= StrLen(S);
IntOut(0, L); Text(0, ": ^""); Text(0, S); ChOut(0, ^"); CrLf(0);
for I:= 0 to L-1 do
for J:= I+1 to L-1 do
[if S(I) # S(J) then
[ChOut(0, \tab\ 9);
for K:= 0 to J do ChOut(0, ^ );
Text(0, "^^ Not same character: ");
ChOut(0, S(J));
Text(0, ", hex ");
SetHexDigits(2);
HexOut(0, S(J));
CrLf(0);
return;
];
];
Text(0, " All same character"); CrLf(0);
];
 
[Text(0, "Length"); CrLf(0);
StrSame("");
StrSame(" ");
StrSame("2");
StrSame("333");
StrSame(".55");
StrSame("tttTTT");
StrSame("4444 444k");
]
Output:
Length
0:      ""
        All same character
3:      "   "
        All same character
1:      "2"
        All same character
3:      "333"
        All same character
3:      ".55"
          ^ Not same character: 5, hex 35
6:      "tttTTT"
            ^ Not same character: T, hex 54
9:      "4444 444k"
             ^ Not same character:  , hex 20

zkl[edit]

fcn stringSameness(str){  // Does not handle Unicode
sz,unique,uz := str.len(), str.unique(), unique.len();
println("Length %d: \"%s\"".fmt(sz,str));
if(sz==uz or uz==1) println("\tSame character in all positions");
else
println("\tDifferent: ",
unique[1,*].pump(List,
'wrap(c){ "'%s' (0x%x)[%d]".fmt(c,c.toAsc(), str.find(c)+1) })
.concat(", "));
}
testStrings:=T("", "   ", "2", "333", ".55", "tttTTT", "4444 444k");
foreach s in (testStrings){ stringSameness(s) }
Output:
Length 0: ""
	Same character in all positions
Length 3: "   "
	Same character in all positions
Length 1: "2"
	Same character in all positions
Length 3: "333"
	Same character in all positions
Length 3: ".55"
	Different: '5' (0x35)[2]
Length 6: "tttTTT"
	Different: 'T' (0x54)[4]
Length 9: "4444 444k"
	Different: ' ' (0x20)[5], 'k' (0x6b)[9]