9
\$\begingroup\$

The ls utility lists specified directory content. It is infamous for stupidly lots of options which is known for anti-pattern design of implementing software.(citation needed)

Given an alphanumeric character, decide whether the character is an option for the ls utility defined in POSIX.1-2017.

From POSIX.1-2017 (removed XSI-OPTION tags to include those options):

ls [-ikqrs] [-glno] [-A|-a] [-C|-m|-x|-1] [-F|-p] [-H|-L] [-R|-d] [-S|-f|-t] [-c|-u] [file...]

Input

An alphanumeric character, which is one of

0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz

Output

A boolean value whether the input is one of following characters:

ikqrsglnoAaCmx1FpHLRdSftc

The lowercase ell and number one are in, but the uppercase eye is not. If the input is not one of the characters above your program or function must return a falsey value.

Note

Don't expect the following shellscript works according to specification:

ls -$1

Many ls implementations have some extensions; for example I tried it with toybox 0.8.0-android. It has some extensions such as -b and -Z, which are not defined by POSIX. If you find an implementation that implements what the standard says and nothing else, then this program is yours.

This task in the sandbox on Codegolf.Meta.StackExchange.com.

\$\endgroup\$
1
  • 9
    \$\begingroup\$ Sorted truthy inputs: 1ACFHLRSacdfgiklmnopqrstx \$\endgroup\$
    – Bubbler
    Commented Jul 8 at 4:24

13 Answers 13

9
\$\begingroup\$

sed, 26 24 bytes

-2 from @GammaFunction for swapping truthy/falsy

/[1ACFHLRSacdfgik-tx]/Q1

Try it online!

guess I can start it off with the obvious solution. I alphabetized the options so that I could abbreviate any ranges; but k-t was the only one. in sed, Q means 'immediately quit', and it takes an optional number as an error code; so if input was a good char then it'll quit with an error code of 1, otherwise it'll exit normally with your input in stdout.

if you need it to check if the entire string is a valid option, it'd look like

/^[1ACFHLRSacdfgik-tx]*$/Q1
\$\endgroup\$
2
  • 1
    \$\begingroup\$ Since you're outputting via exit code, extraneous stdout doesn't matter. Our standard decision problem rules say you can also swap truthy and falsy values. So /[1ACFHLRSacdfgik-tx]/q1 is 24 bytes and POSIX (which I think is appropriate for the challenge) \$\endgroup\$ Commented Jul 8 at 4:42
  • \$\begingroup\$ @GammaFunction oh, I didn't know that swapping truthy/falsy was allowed, nice. I still think Q is nicer than q though, it's not like it's any longer. exiting with an error code is non-POSIX in the first place so it doesn't help in that front \$\endgroup\$
    – guest4308
    Commented Jul 8 at 5:02
4
\$\begingroup\$

JavaScript (ES11), 34 bytes

Expects an ASCII code as a BigInt and returns 0 or 1.

This is an attempt at using a bitmask and see how it compares with the regular expression.

By reducing the code modulo 71, we create a harmless collision between 0,1,2,3 and w,x,y,z (both mapped to 48 … 51) where only 1 and x respectively are truthy.

n=>0x4a00023ff5b4001822n>>n%71n&1n

Try it online!


JavaScript (ES6), 33 bytes

Using the regular expression is 1 byte shorter.

c=>/[1ACFHLRSacdfgik-tx]/.test(c)

Try it online!

\$\endgroup\$
3
\$\begingroup\$

Charcoal, 22 bytes

⁼№1ACFHLRSbehjxθ№…β²⁰θ

Try it online! Link is to verbose version of code. Outputs an inverted Charcoal boolean, i.e. - if the input is not a valid POSIX ls option, nothing if it is. Explanation:

 №                      Count of
               θ        Input character in
  1ACFHLRSbehjx         Literal string `1ACFHLRSbehjx`
⁼                       Is equal to
                №       Count of
                     θ  Input character in
                  β     Lowercase alphabet
                 …      Truncated to length
                   ²⁰   Literal integer `20`
                        Implicitly print
\$\endgroup\$
2
\$\begingroup\$

R, 34 bytes

\(o)grep("[1ACFHLRSacdfgik-tx]",o)

Attempt This Online!

Basically a port of @guest4308's sed answer.

Uses 1 as truthy and integer(0) as falsy.

\$\endgroup\$
2
\$\begingroup\$

05AB1E, 22 bytes

.•Qfāþ•uA.•’»'WT•м1ýÃg

Try it online or verify all alphanumeric characters.

.•Qfāþ•u could alternatively be ‘ÕÉLF‘ê¨ for the same byte-count:
Try it online or verify all alphanumeric characters.

Explanation:

.•Qfāþ•     #  Push compressed string "acfhlrs"
       u    #  Uppercase it: "ACFHLRS"
            # OR:
‘ÕÉLF‘      #  Push uppercased dictionary string "SCRATCHLF"
      ê     #  Uniquify and sort it to "ACFHLRST"
       ¨    #  Remove the trailing character: "ACFHLRS"
A           # Push the lowercase alphabet: "abcdefghijklmnopqrstuvwxyz"
 .•’»'WT•  '# Push compressed string "behjuvwyz"
         м  # Remove those characters: "acdfgiklmnopqrstx"
1ý          # Join the two values on the stack with "1"-delimiter:
            #  "ACFHLRS1acdfgiklmnopqrstx"
  Ã         # Only keep those characters from the (implicit) input-character
   g        # Pop and push its length
            # (after which it's output implicitly as result)

See this 05AB1E tip of mine (sections How to use the dictionary? and How to compress strings not part of the dictionary?) to understand why .•Qfāþ• is "acfhlrs"; ‘ÕÉLF‘ is "SCRATCHLF"; and .•’»'WT• is "behjuvwyz".

\$\endgroup\$
2
\$\begingroup\$

Dis, 154 bytes

}*^_!!!_!_!!{{__!!{!!!!{!!!{_______________>>*_________________|*_^______!!!___!!{___________________________!!!{!{!!!!_{_!____{{!!{{!{{{{{{{{{{{___!!!!{!

On my dis.web

How it works

This time I subtracted 62 from the input.

Getchar to store to register A:

}

Goto 62 (as address 43 points):

*^

Obtw memory 43-45 as data:

>>*

Address 63-66 as code:

|     (Store op(A,62) to address 44)
 *_^  (goto what address 44 says)

Address 4-153 is lookup table:

!!!_!_!!{{__!!{!!!!{!!!{_______________>>*_________________|*_^______!!!___!!{___________________________!!!{!{!!!!_{_!____{{!!{{!{{{{{{{{{{{___!!!!{!

How generated

JavaScript (Node.js), 1113 bytes

disMath = {
    get subtract(){
        BASE=3;
        function _op_by_digit(x, y) {
            return ( x - y + BASE ) % BASE;
        }

      return function _subtract(x, y) {
        if ( x < 1 && y < 1 ) return 0;
        return _op_by_digit(x%BASE, y%BASE) + BASE*_subtract(Math.floor(x/BASE), Math.floor(y/BASE));
      }
    }
};
input = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
truthy = "1ACFHLRSacdfgiklmnopqrstx";

// [33,42,62,94,95,123,124,125].forEach(j=>{
[62].forEach(j=>{

  hello =
    [input, truthy].map(str=>
       [...str]
      .map(char=>char.codePointAt(0))
 
     .map(x=>disMath.subtract(x,j)+1).sort((x,y)=>x>y||(x==y)-1))
  // console.log(j,hello[0])

})

init = "}*^";
program = init;
for ( i = init.length; i <= 153; i++ ) {
    if ( 43 <= i && i <= 44 ) program += ">";
    else if ( i === 45 ) program += "*";
    else if ( i === 63 ) { program += "|*_^"; i = 67-1}
    else if ( hello[1].includes(i) ) program += "{";
    else if ( hello[0].includes(i) ) program += "!";
    else program += "_";
}
console.log(program);
console.log(program.length, i);

Try it online!


Dis, 163 bytes

}*__|*__^__________!!!___!{!___!!!!__!{!__{!{!*!!{!!!{!___________________________{{{{{{{{{___!!!{!!____________________________________!!!!{{!!!_{!!_____{!{{{!{{!

Assumes ASCII input. Reaches to { to output a byte if truthy, no output if falsey.

Try on dis.web!

Screencast to verify every test case (YouTube)

How it works

Get a character:

 }

Subtract 33 (!) from the character's code at memory 45:

*__|

Goto what memory 45 says:

*__^

It should go to one of 19 thru 162:

!!!___!{!___!!!!__!{!__{!{!*!!{!!!{!___________________________{{{{{{{{{___!!!{!!____________________________________!!!!{{!!!_{!!_____{!{{{!{{!

Obtw Memory 43-49, which is accessed by memory 1-8:

!{!*!!{

How I generated code above

JavaScript (Node.js), 871 bytes

disMath = {
    get subtract(){
        BASE=3;
        function _op_by_digit(x, y) {
            return ( x - y + BASE ) % BASE;
        }

      return function _subtract(x, y) {
        if ( x < 1 && y < 1 ) return 0;
        return _op_by_digit(x%BASE, y%BASE) + BASE*_subtract(Math.floor(x/BASE), Math.floor(y/BASE));
      }
    }
};
input = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
truthy = "1ACFHLRSacdfgiklmnopqrstx";
hello = [input, truthy].map(str=>[...str].map(char=>char.codePointAt(0)).map(x=>disMath.subtract(x,33)+1).sort((x,y)=>x>y||(x==y)-1))
init = "}*__|*__^";
program = init;
for ( i = 9; i <= 162; i++ ) {
    if ( i == 46 ) program += "*";
    else if ( hello[1].includes(i) ) program += "{";
    else if ( hello[0].includes(i) ) program += "!";
    else program += "_";
}
console.log(program);
console.log(program.length);

Try it online!

More explains

I first tried what operation to do could reduce code space.

For each possible inputs and truthy cases (let them x), I tried x subtracted by command character on Dis (which is one of 33, 42, 62, 94, 95, 123, 124, 125).

At first I tried if the program who begins with }*|*^ works;

\$\endgroup\$
2
\$\begingroup\$

Ruby, 30 bytes

->c{c=~/[1ACFHLRSacdfgik-tx]/}

Try it online!

Using the same regex as other answers.

\$\endgroup\$
2
\$\begingroup\$

APL+WIN, 29 bytes

Prompts for input. Can be single character or a vector of characters. Returns 1 if character is valid, 0 if not.

⎕∊'ikqrsglnoAaCmx1FpHLRdSftc'

Try it online! Thanks to Dyalog Classic

\$\endgroup\$
2
\$\begingroup\$

C89, 67 bytes

char*strchr();f(c){return!!strchr("ikqrsglnoAaCmx1FpHLRdSftcu",c);}

This is just a wrapper around the C standard library function strchr(). It leans on default int typing to golf away a few bytes of type declaration. Needing to declare strchr() because that function's return type is not int, it saves a few bytes by doing so itself instead of including the header where that function is declared, and by using a K&R-style declaration that does not provide a prototype. That declaration could be moved inside the function to make the function be the only top-level unit, but that would not change the code size.

C89 (assuming ASCII), 49 bytes

f(c){return c<65?c==49:0x8ffd6d000608a5>>c%65&1;}

This is a variation on @Arnauld's ES11 bitmask solution, adapted to account for C not necessarily providing an integer type wider than 64 bits. The bitmask is made to fit in 64 bits by using it only for test characters with values greater than 64, special-casing the one option having a lesser value.

HOWEVER, this approach assumes that the execution character set is congruent with US-ASCII, which is very common, but not required or universal.

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

Nibbles, 33 28 nibbles (14 bytes)

? ! _ \``@_ * o$ ~100c114a011ffada

Attempt This Online!

Returns a positive integer (truthy) if the input is a valid ls option, zero otherwise.

~100c114a011ffada   # hex value
      \``@@         # converted to bits and reversed:
                    # 0 1 0 1 1 0 1 1 0 1 0 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 1 0 1 0 0 0 1 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 1
  !                 # zip these with
    _               # " abcdefghijklmnopqrstuvwxyz.,!?_\n+ ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-+:;\"'~`@#$%^&*()[]{}<>\\/=|"
            *       # by multiplication (so converting to codepoints)
                    # (so retaining codepoints of "acdfgiklmnopqrstACFHLRS1", with intervening zeros)
?                   # and get the index of 
              o$    # codepoint of the input
                    # (or return zero if absent)
\$\endgroup\$
1
\$\begingroup\$

Funge-98, 41 bytes

"NRTS"4(I0"1ACFHLRSacdfgiklmnopqrstx"F!.@

Try it online!

Uses 0 as truthy and 1 as falsy.

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

Jelly, 15 bytes

“7Ȥ2R¶Ṁṡỵ’BoØBċ

A monadic link that accepts a single character from 0-9A-Za-z and yields 1 if it is an option or 0 if not.

Try it online! Or see the test-suite.

How?

“..’BoØBċ - Link: character, C
“..’      - base 250 compressed number
    B     - convert to binary
      ØB  - 'base digits' -> "012...9AB..Zab..z"
     o    - logical OR (vectorises)
        ċ - count occurrences of {C}
\$\endgroup\$
1
\$\begingroup\$

Pascal, 84 B

This complete program requires a processor supporting features of Extended Pascal as defined by ISO standard 10206, in particular the index function, and that the implementation‐defined set of char values contains both the upper‑ and lowercase alphabetic letters.

The function index(source, pattern) returns the 1‑based index of the first occurrence of pattern in source, or 0 in case pattern does not appear in source. The > 0 turns this integer value into a Boolean so an implementation‐defined rendition of the strings True or False are printed on output.

program p(input,output);begin
write(index('ikqrsglnoAaCmx1FpHLRdSftc',input↑)>0)end.

150 B If only Standard Pascal (ISO standard 7185) is supported, you need to write out the set membership test. Input↑ refers to the buffer variable of the text file input. This is one char value. Performing an ∈‑comparison (in Pascal written as in) against a set of char yields a Boolean value.

program p(input,output);begin
write(input↑in['i','k','q','r','s','g','l','n','o','A','a','C','m','x','1','F','p','H','L','R','d','S','f','t','c'])end.

Pascal does not make any assertions to the specific ordinal values of the required data type char except that alphabetic letters must be ascending and the Western‐Arabic digits must be consecutive and ascending in accordance to their numeric value. That means the Extended Pascal set‑builder expression ['k'‥'t'] is not guaranteed to comprise and comprise only ['k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't']; this range may inadvertently contain other characters, too.

\$\endgroup\$

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