Programming Puzzles & Code Golf Stack Exchange is a question and answer site for programming puzzle enthusiasts and code golfers. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

Given an input string S, return truthy if all the letters in S are Lexically Ordered: their ASCII values need to be in either ascending or descending order. Return falsy in other cases.

Input

  • Input will be in the same case (all upper- or all lowercase). Your submission should be able to handle both.
  • Input will consist of ASCII in the range [A-Za-z] only
  • Input length will be at least 1, up to whatever maximum your language supports.
  • Input is a string - not a list of characters, not an array of ASCII-codepoints.

Output

  • Output should be true or false, or 0/1, or any other distinct true / false style output your language can provide.
  • All true cases need to have the same output, as well as all the false cases. No "False is 0, true is 1, 2, or 3".

Additional rules

  • Standard loopholes are forbidden
  • Answer must be a full program or a function, not a snippet or a REPL-entry.
  • , shortest answer in bytes wins.

Test cases

Truthy

"ABCDEF"
"ZYX"
"no"
"tree"   --> the multiple 'e's don't break the order
"q"

Falsy

"ABCDC"
"yes"
"deed"

Invalid

"Hello" --> invalid input - mixed case-, does not have to be handled
""      --> invalid input - length 0-, does not have to be handled
"\n
  "     --> invalid input - newline is not in range [A-Za-z]-, does not have to be handled
share|improve this question
1  
Can you clarify about the output: does the truthy value need be the same regardless of what input is given? – Business Cat 12 hours ago
    
@BusinessCat I've added a clarification. – steenbergh 12 hours ago
    
What if your language's implementation of a string is a list of characters? Many of the answers posted here are using such languages... – theonlygusti 11 hours ago
    
@theonlygusti If your language of choice treats strings as lists of characters, that's fine. If your language has a string type, input may not be given as a list. – steenbergh 10 hours ago
1  
related: Find the Wavy Words! – Titus 9 hours ago

30 Answers 30

Python 2, 53 44 40 39 bytes

lambda a:`sorted(a)`[2::5]in(a,a[::-1])

Try it online!

share|improve this answer

JavaScript (ES6), 43 bytes

([...s],q=s+"")=>q==s.sort()|q==s.reverse()
share|improve this answer
    
Didn't know you could modify variables in the argument itself. Nice! – Luke 13 hours ago
    
@Luke This is just a tricky use of default parameters: if you were to call the function with a second argument, q would be set to that value instead. – ETHproductions 12 hours ago
    
I actually meant the spread operator which (in this case) converts it into an array right away. – Luke 12 hours ago
    
Oh, OK. Yeah, destructuring assignments are really handy too ;-) – ETHproductions 11 hours ago

Perl 6, 25 bytes

{[le] .comb or[ge] .comb}

How it works:

  • .comb splits the input into a sequence of characters.
  • le and ge are the "less or equal" and "greater or equal" string comparison operators.
  • [ ] around an infix operator, reduces ("folds") the argument list with that operator. (It's smart enough to return True if the input has only zero or one characters.)
  • or returns True if the expressions on either side of it is true.
share|improve this answer

MATL, 8 bytes

tPvGSXma

Try it Online!

Explanation

        % Implicitly grab the input as a string
tP      % Create a copy that is reversed
v       % Vertically concatenate these
GS      % Grab the input again and sort it
Xm      % Check if each row of the normal and reversed matrix is equal to the sorted one
a       % Check if either row matched
        % Implicitly display the result
share|improve this answer

Haskell, 34 bytes

f s=or[s==scanl1 q s|q<-[min,max]]

Try it online!

Haskell is an interesting language to golf sorting-based challenges because it does not have a built-in sort, barring a lengthy import Data.List. This encourages finding a way to do the task by hand without explicitly sorting.

The code uses scanl1, which folds an operation over the list from left to right, keeping track of the intermediate results. So, scanl1 max has the effect of listing the cumulative maxima of the list, i.e. the maxima of progressively longer prefixes. For example, scanl1 max [3,1,2,5,4] == [3,3,3,5,5].

Then, s==scanl1 max s if s is sorted in increasing order. The same expression with min checks if the list is decreasing. In the code, [s==scanl1 q s|q<-[min,max]] checks both these options and or sees if either is true.

Compare to other expressions:

f s=or[s==scanl1 q s|q<-[min,max]]

f s=s==scanl1 max s||s==scanl1 min s
f s=any(\q->scanl1 q s==s)[min,max]
f s=any((==s).(`scanl1`s))[min,max]
f s=elem s$(`scanl1`s)<$>[min,max]
share|improve this answer

Jelly, 4 5 bytes

Ṣm0ẇ@

Try it online!

Originally was Ṣm0w at four bytes.

Explanation

Ṣm0ẇ@  Input: string S
Ṣ      Sort S
 m0    Concatenate sort(S) with reverse(sort(S))
   ẇ@  Sublist exists? Check if S is contained in the previous result
share|improve this answer
    
I was sure there was a four byter, but couldn't think of it! – Jonathan Allan 11 hours ago
1  
...unfortunately the OP has clarified output is not truthy/falsy, but two distinct values. Four bytes still possible with though, I believe. Edit: ugh Ṣm0ẇ@. – Jonathan Allan 11 hours ago
    
@JonathanAllan Unfortunate since it did meet the original rule of using the true/false style of the language. Another form might be Ṣẇm0$. If the argument order wasn't different for w and ... – miles 11 hours ago

05AB1E, 5 bytes

Â)¤{å

Try it online!

Explanation

Â)     # pair the input with it's reverse in a list
  ¤{   # get a copy of the reverse and sort it
    å  # check if the sorted copy is in the list of [input,reverse_input]
share|improve this answer
    
{¹å for 4, deleted my answer. Didn't notice the use of bifurcate, mine was too similar. – carusocomputing 14 hours ago
    
@carusocomputing: that would unfortunately only check if the input is in the reverse of the sorted input. – Emigna 14 hours ago
    
Or equal to the sorted input. aba => ['aab', 'baa'] => is in? => 0| aab => same => 1 – carusocomputing 14 hours ago
    
@carusocomputing: The sorted input is ignored as it's below the reverse on the stack. You never pair them in a list. – Emigna 14 hours ago
    
Coulda sworn bifurcate wrapped output; nvm, ignore me. – carusocomputing 14 hours ago

Jelly, 5 bytes

,Ue@Ṣ

Try it online!

How?

,Ue@Ṣ - Main link: string
,     - pair string with
 U    - reverse(string)
    Ṣ - sorted(string)
  e@  - exists in with reversed arguments
share|improve this answer

PowerShell, 61 bytes

param($a)$a-in-join(($b=[char[]]$a)|sort),-join($b|sort -des)

Try it online!

Takes input $a, then checks whether it's -in a two-element array. The array is formed by taking $a, casting it as a char-array, storing that in $b for later, piping it to sort-object which sorts lexically. The other element is $b sorted in -descending order.

share|improve this answer

MATL, 7 bytes

dZSuz2<

Try it online! Or verify all test cases.

d     % Implicitly input string. Push array of consecutive differences of code points
ZS    % Sign. Transforms each entry into 1, 0 or -1
u     % Unique
z     % Number of nonzeros
2<    % Is it less than 2? Implicit display
share|improve this answer

MATLAB / Octave, 38 bytes

@(x)any(all([x;flip(x)]'==sort(x)',1))

Online demo

share|improve this answer

CJam, 12 bytes

r__$=\W%_$=|

Try it online!

Explanation

r             Take input
 _            Duplicate it
  _$          Duplicate and sort it
    =         Check if equal
     \        Swap top stack elements (bringing the original word to the top of the stack)
      W%      Reverse it
        _$    Duplicate and sort it
          =   Check if equal
           |  OR
share|improve this answer

Bash + coreutils, 59 bytes

f()(sed 's/\(.\)/\1\
/g'<<<$s|grep .|sort -c$1)
s=$1
f||f r

The input string is passed as an argument.

The output is returned in the exit code (0 for truthy, 1 for falsy, as usual), as allowed by PPCG I/O methods.

share|improve this answer

JavaScript (ES6) 74 62 50 47 43 bytes

([...a],b=a+'')=>b==a.sort()|b==a.reverse()

After some golfing and bugfixing, this answer ended up being pretty much the same as ETHProduction's, so please check his answer out and give it a +1.

share|improve this answer
    
Fixed the bug.. – Luke 14 hours ago
1  
You caught me, I posted the comment before editing... – Luke 14 hours ago
    
I found the cause of the bug, and I now fixed it properly by arranging everything cleverly... – Luke 13 hours ago
    
Bug is back... repl.it/FZrs/2 – steenbergh 13 hours ago
    
Well, this is pretty much @ETHProduction's answer now, so I added a notice. Please +1 his answer. – Luke 11 hours ago

Haskell, 54 50 bytes

t a=or[and(zipWith(<=)`f`tail$a)|f<-[(=<<),(<*>)]]

Usage example: t "defggh" -> True. Try it online!.

Maybe using sort like may other answers is shorter although it requires import Data.List. Here's a different approach:

For every function f from [(=<<),(<*>)], calculate and(zipWith(<=)`f`tail$a) and require any of the results to be True. The functions are

((=<<) (zipWith(<=)) tail) a
((<*>) (zipWith(<=)) tail) a

which both perform comparisons of neighbor elements of the input list a with <=, but one with the arguments flipped resulting in a >=. and checks if all comparisons are True.

share|improve this answer

Clojure, 47 bytes

#(let[c(map int %)a apply](or(a <= c)(a >= c)))
share|improve this answer
    
Couldn't figure out how to decide which operator to apply concisely. This is great. – Carcigenicate 7 hours ago

PHP, 66 bytes

$a=$s=$r=str_split($argv[1]);sort($s);rsort($r);echo$s==$a|$r==$a;

takes input from command line argument. Run with -r.

share|improve this answer

TI-Basic, 66 + 78 = 144 bytes

Input Str1
For(I,1,length(Str1
inString(Str2,sub(Str1,I,1->L1(I
End
L1->L2
Ans->L3
SortA(L2
SortD(L3
L1=L2 or L1=L3

And in Str2 you must have this (+78 bytes):

`ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
share|improve this answer

Retina, 36 bytes

Byte count assumes ISO 8859-1 encoding.

$
¶$_¶$_
O^#`\G.
Or`.\G
(.+)\D*\b\1$

Try it online!

share|improve this answer

Perl, 43 bytes

42 bytes of code + -p flag.

$"="*";@b=reverse@a=a..z;$_=/^@a*$|^@b*$/i

Try it online!

The code checks if the input matches the regex /^a*b*c*...z*$/ or in reverse order, /^z*y*w*...a*$/.
This is done by creating an array @a containing characters from a to z, and @b is the same in reverse order.
And we set $" (the separator for arrays when interpolated in string context) to *. So when writing /@a/, @a is converted to a*b*c*...z*.

share|improve this answer

Pyke, 5 bytes

SD_]{

Try it here!

S     -   sorted(input)
   ]  -  [^, v]
 D    -    ^
  _   -   reverse(^)
    { - input in ^
share|improve this answer

Haskell, 46 bytes

import Data.List
f s=sort s`elem`[s,reverse s]

Try it online! Usage: f "somestring", returns True or False.

Not as interesting as nimi's approach, but some bytes shorter.

Given a string s, we check whether s sorted is euqal to the original or reversed string.

share|improve this answer

Pyth, 5 bytes

}SQ,_

Explanation:

}SQ,_
}SQ      Check if the sorted input is a member ...
   ,_QQ  ... of [reversed input, input]
share|improve this answer

R, 61 bytes

As an unnamed function

function(s,d=diff(as.double(charToRaw(s))))all(d<1)|all(d>=0)

charToRaw takes s and splits into a raw vector. This is converted to integers and a diff applied. Return true if all diffs are >= 0 or <= 0.

Test

f=
+ function(s,d=diff(as.double(charToRaw(s))))all(d<1)|all(d>=0)
> f('test')
[1] FALSE
> f('abc')
[1] TRUE
> f('cba')
[1] TRUE
> f('deer')
[1] TRUE
> f('reed')
[1] TRUE
> f('deed')
[1] FALSE
share|improve this answer

Mathematica, 33 bytes

0<=##||##>=0&@@ToCharacterCode@#&

Based on this tip. Unfortunately, I have to use ToCharacterCode instead of Characters, because <= and >= don't compare strings.

share|improve this answer
    
If you take the input as a list of characters, (o=OrderedQ)@#||o@Reverse@#& and Or@@OrderedQ/@{#,Reverse@#}& are both 28 bytes. – Greg Martin 9 hours ago
    
@GregMartin "Input is a string - not a list of characters, not an array of ASCII-codepoints." – Martin Ender 9 hours ago
    
meh, can't read, sorry – Greg Martin 9 hours ago

Pushy, 7 bytes

ogoGo|#

Try it online!

Explanation:

      \ Implicit: Input on stack as charcodes
og    \ Check if the stack is sorted ascendingly (Push 0/1)
oG    \ Check if the stack is sorted descendingly (Push 0/1)
      \   - Note that this will work regardless of the first check, as input
      \     is guaranteed to be /[A-Za-z]+/
o|    \ Bitwise OR
#     \ Print the result
share|improve this answer
    
This does not return one distinct true-value. – steenbergh 13 hours ago
1  
@steenbergh No, but it satisfies our meta consensus on what counts as truthy or falsy - 1 and 2 are True in Pushy, whereas 0 is False. – FlipTack 12 hours ago
    
If Pushy has a bitwise OR operator, that should work instead. – ETHproductions 12 hours ago
    
@FlipTack I thought it was clear in the challenge, but I've now made it more specific: TRUE must output the same value on all testcases. Same goes for FALSE. – steenbergh 10 hours ago
    
@steenbergh The meta consensus is there for a reason and makes sense, but if you insist... – FlipTack 10 hours ago

Pyth, 5 bytes

}Q_BS

A program that takes input of a "quoted string" and prints True or False as appropriate.

Test suite

How it works

}Q_BS   Program. Input: Q
}Q_BSQ  Implicit variable fill
 Q      Is Q
}       in
    SQ  Q sorted
   B    or
  _     Q sorted reversed?
        Implicitly print
share|improve this answer

Scala, 52 bytes

def p(s:String)=List(s,s.reverse).contains(s.sorted)
share|improve this answer

Clojure, 69 bytes

#(let[o(apply str(sort %))r(apply str(reverse o))](or(= % o)(= % r)))

My original try ended up being a longer version of the other Clojure answer, so I went the "sorted" route. Checks if the original string is equal to a sorted version of itself, or a reversed sorted string. Amazingly, (apply str (reverse s) ended up being shorter than using the built-in reverse string method.

(defn lex? [s]
  ; (apply str ...) basically just turns a list into a string
  (let [sorted (apply str (sort s))
        reversed (apply str (reverse sorted))]
    (or (= s sorted) (= s reversed))))
share|improve this answer

Scala, 47 bytes

def f(x:String)=x==x.sorted|x==x.sorted.reverse
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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