43
\$\begingroup\$

Write a function/program that accepts a string of lower/uppercase letters [A-Za-z] as input, that checks whether the occuring letters are unique and in alphabetical order (ignoring lower and uppercase) or not. The output must be truthy if they are unique and in alphabetical order and falsy if not.

Here some testcases

a                           true
abcdefGHIjklmnopqrSTUVWXyz  true     
aa                          false
puz                         true
puzz                        false
puzZ                        false
puZ                         true
PuZ                         true
pzu                         false
pzU                         false
abcdABCD                    false
dcba                        false

If you want, run your program on all words of a wordlist like this one and and post some interesting ones =).

Score

Lowest number of bytes wins.

\$\endgroup\$
10
  • 4
    \$\begingroup\$ Weak test cases. (See my comment on Richard A's PHP answer.) \$\endgroup\$
    – manatwork
    Commented Mar 11, 2015 at 17:20
  • \$\begingroup\$ Does the alphabet loop? Should za be a truthy value? \$\endgroup\$
    – bren
    Commented Sep 24, 2015 at 1:06
  • \$\begingroup\$ No, the alphabet begins with a and ends with z. \$\endgroup\$
    – flawr
    Commented Sep 24, 2015 at 12:17
  • \$\begingroup\$ You should have some test cases that aren't in alphabetical order \$\endgroup\$
    – Jo King
    Commented Mar 3, 2019 at 21:43
  • 1
    \$\begingroup\$ @JoKing I added some. \$\endgroup\$
    – flawr
    Commented Mar 5, 2019 at 9:02

64 Answers 64

2
\$\begingroup\$

Prolog (SWI), 36 bytes

\S:-maplist(to_lower,S,L),sort(L,L).

Try it online!

Ungolfed:

\S :-
  maplist(to_lower, S, L), % convert each character code in S to lowercase, putting that in a list called L
  sort(L, L). % Does L sorted and uniquified equal L?
\$\endgroup\$
1
\$\begingroup\$

Erlang, 51

f(S)->G=string:to_lower(S),ordsets:from_list(G)==G.

Uses an ordered set (analogous to java.util.TreeSet) to sort the characters and discard any duplicates. The new list is then compared with the input string.

Test Function:

test() ->
    [io:format("~p ~p~n", [S, f(S)]) || S <- ["a","abcdefGHIjklmnopqrSTUVWXyz","aa","puz","puzz","puzZ","puZ","PuZ"]].
\$\endgroup\$
1
\$\begingroup\$

PHP (52 bytes)

This is an answer based on @HSL's regex (sorry dude).

The idea is to grab the regex and generate it instead of having it hard-coded.

Here is the code:

echo preg_match("@^".join('?',range(a,z))."?$@",$s);

Since this answer isn't entirely of my authority, I have marked it as "Community Wiki".

To use this, simply add a line before with $s='String!';.

\$\endgroup\$
2
  • \$\begingroup\$ If the string to parse should be provided in variable $s, then that should be preg_match()'s 2nd parameter. Which is 2 characters shorter. \$\endgroup\$
    – manatwork
    Commented Mar 2, 2015 at 11:21
  • \$\begingroup\$ @manatwork Oh god! Sorry the stupidity! I was distracted and wrote it without thinking. I've fixed it now. \$\endgroup\$ Commented Mar 2, 2015 at 12:11
1
\$\begingroup\$

Java, 96

boolean a(char[]a){int i=-1,l=0;for(;++i<a.length;l+=i>0&&a[i]<=a[i-1]?1:0)a[i]|=32;return l<1;}

Pretty straightforward here. Just convert all to lower and compare each to the previous character.

\$\endgroup\$
1
\$\begingroup\$

PowerShell, 37

-join(($x="$input")[0..26]|sort)-eq$x

Can be shortened by another byte by using command-line arguments instead of stdin ($args instead of $input).

Tricks used:

  • PowerShell is case-insensitive by default, simplifying the check.
  • Getting a char[] from the input is a bit shorter if we know an upper bound for the length [0..x] instead of [char[]]
\$\endgroup\$
1
\$\begingroup\$

R, 62 Bytes

s=strsplit(tolower(word),"")[[1]]
all(s[order(unique(s))]==s)

This will throw a warning if there is a repeating character.

To avoid this, I inserted zeros to make both strings the same length. I assumed this is OK since we are only using letters and not numbers.

s <- strsplit(tolower(word), "")[[1]]
all(c(s[order(unique(s))],rep('0',length(s)-length(unique(s)) )) == s) 
\$\endgroup\$
1
\$\begingroup\$

Clojure, 69

(let[s(seq(.toLowerCase (read-line)))](= s(seq(apply sorted-set s))))

Run in the REPL, enter a string and press return. Prints true or false. E.g.

user=> (let[s(seq(.toLowerCase (read-line)))](= s(seq(apply sorted-set s))))
puZ
true
user=> (let[s(seq(.toLowerCase (read-line)))](= s(seq(apply sorted-set s))))
puzz
false
\$\endgroup\$
1
\$\begingroup\$

Rebol - 26 25

(s: input)= sort unique s

NB. Above works fine in Rebol 2. However in Rebol 3 sort isn't case insensitive (yet) so for now it would need to be written has (s: input)= sort lowercase unique s

\$\endgroup\$
1
\$\begingroup\$

Javascript, 147 145 bytes

function(a){b=[];a=a.toLowerCase().split('');while(a.length)b.push(a.pop().charCodeAt(0));while(c=b.pop()){if(c>=b[b.length-1])return 0}return 1}

An anonymous function that converts to lowercase, creates an array of char codes, then checks them from right to left.

\$\endgroup\$
1
\$\begingroup\$

C++14, 59 58 bytes

-1 byte for int instead of auto in range-based for-loop.

As unnamed lambda returning via reference parameter. 64 (>0) for true, 0 for false. Input s may be std::string or char[].

[](auto&s,int&r){int b=r=64;for(int c:s)r*=b<(c&=95),b=c;}

The &=95 is from this answer.

Ungolfed and usage:

#include<string>
#include<iostream>

auto f=
[](auto&s,int&r){
  int b=r=64;
  for(int c:s)
    r*=b<(c&=95),
    b=c;
}
;

int main(){
  std::string s;
  int r;
  s="ABC";
  f(s,r); std::cout << s << ", " << r << std::endl;
  s="AbC";
  f(s,r); std::cout << s << ", " << r << std::endl;
  s="ACB";
  f(s,r); std::cout << s << ", " << r << std::endl;
  s="AcB";
  f(s,r); std::cout << s << ", " << r << std::endl;
}
\$\endgroup\$
1
\$\begingroup\$

Japt, 6 bytes

v ä< e

Try it online!

Explanation:

v         #Convert to all lowercase
  ä  e    #For every pair of consecutive letters:
   <      # Check that the second letter is later in the alphabet than the first
\$\endgroup\$
1
\$\begingroup\$

Python 2, 62 bytes (thank to Shaggy)

def a(w):
    v=w.lower()
    print v==''.join(sorted(set(v)))

I know I can not beat anyone but here is my solution.

PoC: https://repl.it/repls/UnderstatedDecimalSales

\$\endgroup\$
1
  • \$\begingroup\$ Thank you so much for pointing the missing part for me, I just updated my answer! \$\endgroup\$
    – Chau Giang
    Commented Mar 3, 2019 at 18:13
1
\$\begingroup\$

MathGolf, 6 bytes

mδ_s▀=

Try it online!

Explanation

m        explicit map (per character)
 δ       capitalize string
         these two commands transforms the input string to uppercase
  _      duplicate the uppercase string
   s     sort(array)
    ▀    unique elements of string
     =   check if equal to the uppercased input
\$\endgroup\$
1
\$\begingroup\$

APL (Dyalog Extended), 6 bytesSBCS

Anonymous tacit prefix function.

(∧≡∪)⌊

Try it online!

()⌊ on the lowercase:

∧≡∪ does the ascending sort match the unique?

\$\endgroup\$
1
\$\begingroup\$

Bash+coreutils, 27 bytes

grep -Ei ^1`echo ?{a..z}?`$

Try it online!

There was an earlier answer with pure Bash, but this one is cool because it saves space by making a much "worse" regular expression. The command substitution expands to the regular expression

^1?a? ?b? ?c? ?d? ?e? ?f? ?g? ?h? ?i? ?j? ?k? ?l? ?m? ?n? ?o? ?p? ?q? ?r? ?s? ?t? ?u? ?v? ?w? ?x? ?y? ?z?$

which accepts many things that we don't care about (1's at the beginning and spaces almost anywhere) but that's okay because it selects correctly when limited to things in the input specification. This lets us avoid a printf %s and just accept the spaces that Bash gives when it expands ?{a..z}?

\$\endgroup\$
1
\$\begingroup\$

><>, 29 20 bytes

Saved 9 bytes thanks to Jo King

0\0=n;
!\i1+48*%:r)?

Try it online!

\$\endgroup\$
2
  • \$\begingroup\$ 20 bytes \$\endgroup\$
    – Jo King
    Commented Mar 5, 2019 at 1:54
  • \$\begingroup\$ @JoKing: I was sure it could still be golfed, but 9 bytes is more than I'd thought was possible. I really like the 0=. Need to remember that one for future golfs :) \$\endgroup\$
    – Emigna
    Commented Mar 5, 2019 at 6:56
1
\$\begingroup\$

APL(NARS), 32 char, 64 bytes

{(k≡∪k)∧k≡k[⍋k←26∣¯1+(⎕A,⎕a)⍳⍵]}

how to use and test (note that "'a'" is a char type and ",'a'" is one type array chars):

  h←{(k≡∪k)∧k≡k[⍋k←26∣¯1+(⎕A,⎕a)⍳⍵]}
  h ,'a'
1
  h 'abcdefGHIjklmnopqrSTUVWXyz'
1
  h 'aa'
0
  h 'puz'
1
  h 'puzz'
0
  h 'puzZ'
0

Possible there is something more short.

\$\endgroup\$
1
\$\begingroup\$

Ruby, 29 bytes

->s{s=~/^#{[*?a..?z]*??}?$/i}

Try it online!

Returns 0 if in order, or false if not in order.

\$\endgroup\$
1
\$\begingroup\$

05AB1E, 4 bytes

lDêQ

Try it online or verify all test cases.

Explanation:

      #  i.e. input: "Test"
l     # Convert the (implicit) input-string to lowercase
      #  STACK: ["test"]
 D    # Duplicate it
      #  STACK: ["test", "test"]
  ê   # Uniquify and sort the characters in the duplicated string
      #  STACK: ["test", "est"]
   Q  # Check if both strings are equal
      #  STACK: [0]
      # (after which the top of the stack is output implicitly as result)
\$\endgroup\$
1
\$\begingroup\$

Jelly, 5 bytes

Œu<ƝẠ

Try it online!

How it works

Œu<ƝẠ - Main link. Takes a string S on the left
Œu    - Uppercase
   Ɲ  - Over overlapping pairs [a, b]:
  <   -   Is a < b?
    Ạ - True for all?
\$\endgroup\$
1
\$\begingroup\$

x86 machine code, 15 bytes

Hexdump:

33 c0 ac 24 5f 3a e0 73 05 8a e0 e2 f5 f9 c3

A function which receives a pointer to the string in esi and its length in ecx. Returns in CF.

Disassembly:

10011860 33 C0                xor         eax,eax  
10011862 AC                   lods        byte ptr [esi]  
10011863 24 5F                and         al,5Fh  
10011865 3A E0                cmp         ah,al  
10011867 73 05                jae         bad (1001186Eh)  
10011869 8A E0                mov         ah,al  
1001186B E2 F5                loop        my+2h (10011862h)  
1001186D F9                   stc  
1001186E C3                   ret  

I had arrange the comparison in such a way that for "bad" strings the carry flag gets set to 0.

Test program (works in Visual Studio):

#include <stdio.h>
#include <string.h>

__declspec(naked) char my()
{
    _asm
    {
        xor eax, eax;
    myloop:
        lodsb;
        and al, 0x5f;
        cmp ah, al;
        jae bad;

        mov ah, al;
        loop myloop;
        stc;
    bad:
        ret;
    }
}

__declspec(naked) bool __fastcall caller(const char*, size_t)
{
    _asm
    {
        push esi;
        mov esi, ecx;
        mov ecx, edx;
        call my;
        mov al, 0;
        adc al, 0;
        pop esi;
        ret;
    }
}

bool is_good(const char* s)
{
    printf("%s ", s);
    size_t l = strlen(s);
    return caller(s, l);
}

int main()
{
    printf("%d\n", is_good("abd"));
    printf("%d\n", is_good("a"));
    printf("%d\n", is_good("abcdefGHIjklmnopqrSTUVWXyz"));
    printf("%d\n", is_good("aa"));
    printf("%d\n", is_good("puz"));
    printf("%d\n", is_good("puzz"));
    printf("%d\n", is_good("puzZ"));
    printf("%d\n", is_good("puZ"));
    printf("%d\n", is_good("PuZ"));
    printf("%d\n", is_good("pzu"));
    printf("%d\n", is_good("pzU"));
    printf("%d\n", is_good("abcdABCD"));
    printf("%d\n", is_good("dcba"));
}

It contains a function caller which translates calling conventions.

\$\endgroup\$
1
\$\begingroup\$

Pyth, 8 bytes

qKrQ1S{K

Try it online!

qKrQ1S{K
qKrQ1S{KQ  // Implicit input
 KrQ1      // Assign uppercase input to K
q    S{K   // Deduplicate K and sort it
q          // Is original K == deduplicated and sorted
\$\endgroup\$
1
\$\begingroup\$

Retina, 33 bytes

Byte count assumes ISO 8859-1 encoding.

T`L`l
^
$_¶
O`\G.
D`\G.
^(.*)¶\1$

Try it online

Translate uppercase to lowercase, duplicate input, sort the first line, deduplicate first line, then check if the lines are equal.

\$\endgroup\$
0
1
\$\begingroup\$

Husk, 7 5 bytes

ΠẊ>ma

Try it online!

Inspired by caird's Jelly answer

   m    # map over all letters of input:
    a   #  make lowercase
 Ẋ      # then for each pair
  >     #  test if R > L
Π       # and get the product of all the results.
\$\endgroup\$
1
\$\begingroup\$

Excel ms365, 45 bytes

=CONCAT(SORT(UNIQUE(MID(A1,ROW(1:26),1))))=A1
\$\endgroup\$
5
  • \$\begingroup\$ The formula fails if you copy it to other cells. I think you have to change it to ...ROW($1:26)..., \$\endgroup\$
    – jdt
    Commented Oct 17, 2022 at 14:47
  • 2
    \$\begingroup\$ @jdt one can assume input in cell A1. Since this is code-golf I'd not drag the formula down, a simple copy would do. \$\endgroup\$
    – JvdV
    Commented Oct 17, 2022 at 14:49
  • \$\begingroup\$ @JvdV sir, how are you getting to know about the bytes and is it necessary to mention while posting an answer? \$\endgroup\$ Commented Oct 18, 2022 at 0:23
  • 1
    \$\begingroup\$ @MayukhBhattacharya code-golf is not about making the most efficient answer. It's about the shortest answer in butes Each character is a byte in Excel. I usually count them here \$\endgroup\$
    – JvdV
    Commented Oct 18, 2022 at 5:40
  • \$\begingroup\$ Oh sounds good sir, really helpful. \$\endgroup\$ Commented Oct 18, 2022 at 23:20
1
\$\begingroup\$

Vyxal, 3 bytes

⇩Þ⇧

Try it Online!

\$\endgroup\$
1
\$\begingroup\$

Julia 1.0, 34 bytes

!x=all(diff(([x...].-'A').%32).>0)

Try it online!

\$\endgroup\$
0
\$\begingroup\$

C# (Visual C# Interactive Compiler), 44 bytes

n=>n.Aggregate((a,b)=>a>1&a%32<b%32?b:'')>1

Can be 42 bytes if I return a SOH char for non-alphabetic and anything else for alphabetic.

Try it online!

\$\endgroup\$
0
\$\begingroup\$

JavaScript (Node.js), 93 bytes

w=>new Set(w).size==w.length&&[...w.toLowerCase()].sort().join``==[...w.toLowerCase()].join``

Try it online!

\$\endgroup\$
0
\$\begingroup\$

PHP, 42 bytes

for(;$c=_&$argn[$i++];$p=$c)$c<$p&&die(1);

exits with 1 (error) for falsy, exit code 0 for truthy.
Run as pipe with -nR or try it online.

If you absolutely need visible output, take these 51 bytes:

for(;$c=_&$argn[$i++];$p=$c)$c<$p&&die("0");echo 1;
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.