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

52 Answers 52

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\$

PHP (89 76 72 63 bytes)

I'm pretty horrible at golfing, but I thought I'd give it a shot.

<?=(join(array_unique(str_split($a=strtolower($argv[1]))))==$a)+0;

I had to cast the output to an integer, since booleans aren't printed in php.

I was able to remove the echo by using <?=, I also removed the $b.

[edit]

Removed the space after <?= and followed manatwork's suggestion to cut 4 bytes.

Also, replacing the implode with join and omitting the glue parameter saved another 9 bytes. Thanks manatwork.

\$\endgroup\$
  • \$\begingroup\$ You can also force a boolean into integer by adding 0 to it. +0 is shorter than (int). \$\endgroup\$ – manatwork Mar 11 '15 at 17:09
  • \$\begingroup\$ Though this passes successfully the test cases provided in the question, it definitely not checks for alphabetical order. For example it outputs 1 for “xa”. \$\endgroup\$ – manatwork Mar 11 '15 at 17:16
  • \$\begingroup\$ There is an alias for implode(), with shorter name: join(). And the first parameter is optional, defaulting to empty string. \$\endgroup\$ – manatwork Mar 11 '15 at 17:25
  • \$\begingroup\$ @manatwork There is too, completely missed it. Thank you. \$\endgroup\$ – MisterBla Mar 11 '15 at 17:28
  • \$\begingroup\$ @manatwork I see it doesn't do alphabetical order... which I find weird, array_unique should sort the array. \$\endgroup\$ – MisterBla Mar 11 '15 at 17:31
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\$

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\$
  • \$\begingroup\$ Thank you so much for pointing the missing part for me, I just updated my answer! \$\endgroup\$ – chau giang Mar 3 at 18:13
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\$

><>, 29 20 bytes

Saved 9 bytes thanks to Jo King

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

Try it online!

\$\endgroup\$
  • \$\begingroup\$ 20 bytes \$\endgroup\$ – Jo King Mar 5 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 Mar 5 at 6:56
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\$
0
\$\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\$
  • \$\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 Mar 2 '15 at 11:21
  • \$\begingroup\$ @manatwork Oh god! Sorry the stupidity! I was distracted and wrote it without thinking. I've fixed it now. \$\endgroup\$ – Ismael Miguel Mar 2 '15 at 12:11
0
\$\begingroup\$

Retina, 33 bytes (non-competing)

Uses features newer than the challenge. 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
\$\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\$
0
\$\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\$
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\$
0
\$\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\$
0
\$\begingroup\$

Perl 6, 30 14 bytes

{[<] .uc.ords}

Try it online!

Gets the ordinal values of the uppercased string and checks if they are in strictly increasing order.

\$\endgroup\$
0
\$\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\$
0
\$\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\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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