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.
17 Answers 17
sed, (削除) 26 (削除ここまで) 24 bytes
-2 from @GammaFunction for swapping truthy/falsy
/[1ACFHLRSacdfgik-tx]/Q1
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
-
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]/q1is 24 bytes and POSIX (which I think is appropriate for the challenge) \$\endgroup\$GammaFunction– GammaFunction2024年07月08日 04:42:53 +00:00Commented Jul 8, 2024 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– guest43082024年07月08日 05:02:38 +00:00Commented Jul 8, 2024 at 5:02
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
JavaScript (ES6), 33 bytes
Using the regular expression is 1 byte shorter.
c=>/[1ACFHLRSacdfgik-tx]/.test(c)
Nibbles, (削除) 33 (削除ここまで) 28 nibbles (14 bytes)
? ! _ \``@_ * o$ ~100c114a011ffada
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)
R, 34 bytes
\(o)grep("[1ACFHLRSacdfgik-tx]",o)
Basically a port of @guest4308's sed answer.
Uses 1 as truthy and integer(0) as falsy.
Charcoal, 22 bytes
=No1ACFHLRSbehjxθNo...β20θ
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:
No Count of
θ Input character in
1ACFHLRSbehjx Literal string `1ACFHLRSbehjx`
= Is equal to
No Count of
θ Input character in
β Lowercase alphabet
... Truncated to length
20 Literal integer `20`
Implicitly print
x86-64 machine code, 24 bytes
Signature bool lsfunc(char c);. Expects c in ecx and returns truthy/falsy in edx. Clobbers rax.
00000000: 48b8 2304 508a 6040 5bff 48d3 c8c0 e905 H.#.P.`@[.H.....
00000010: 48c1 c006 e2fa 99c3 H.......
Disassembly
0: 48 b8 23 04 50 movabs rax,0xff5b40608a500423
8a 60 40 5b ff
a: 48 d3 c8 ror rax,cl
d: c0 e9 05 shr cl,0x5
10: 48 c1 c0 06 rol rax,0x6
14: e2 fa loop 0x10
16: 99 cdq
17: c3 ret
The function calculates 0xff5b40608a500423L >> (c - ((c>>5)*6)) in order to get the truthy/falsy value in bit 31 of rax (high bit of eax), which is then extended into edx and returned. \$c-6(\lfloor\frac{c}{32}\rfloor)\$ converts c into an integer in the range \$[0, 62]\$, which is used to pull the correct bit out of the 64-bit table.
Acc!!, 39 bytes
Outputs 0x01 (SOH) for truthy and 0x00 (NUL) for falsy.
Write 1365059694728979683362/2^(N%71)%2
Port of @Arnauld's JavaScript ES11 answer.
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".
Dis, 154 bytes
}*^_!!!_!_!!{{__!!{!!!!{!!!{_______________>>*_________________|*_^______!!!___!!{___________________________!!!{!{!!!!_{_!____{{!!{{!{{{{{{{{{{{___!!!!{!
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);
Dis, 163 bytes
}*__|*__^__________!!!___!{!___!!!!__!{!__{!{!*!!{!!!{!___________________________{{{{{{{{{___!!!{!!____________________________________!!!!{{!!!_{!!_____{!{{{!{{!
Assumes ASCII input. Reaches to { to output a byte if truthy, no output if falsey.
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);
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;
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'
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.
-
1\$\begingroup\$ Welcome to the CGCC! Nice first answer! See also: Tips for golfing in C \$\endgroup\$IY5dVSjABEeV– IY5dVSjABEeV2024年07月09日 22:28:38 +00:00Commented Jul 9, 2024 at 22:28
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}
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.
BusyBox 1.36.1 shellscript, 39 bytes
ls -1ドル&&case 1ドル in [QXhuv]) false;;esac
Exit status as output.
How it works
According to busybox ls --help:
Usage: ls [-1AaCxdLHRFplinshrSXvctu] [-w WIDTH] [FILE]...
which indicated to lack options gkmoq and have extensions Xuv; however it was not true; it implemented all of gkmoq and additional undocumented options Qh; this is why I had to reject more.
How I tested on my environment
I use Arch btw; with package mkinitcpio-busybox:
printf %s '/usr/lib/initcpio/busybox ls -1ドル&&case 1ドル in [QXhuv]) false;;esac' > Hi.sh
echo '1ACFHLRSacdfgiklmnopqrstx' > __golf
cat __golf | fold -w1 > __golf-sorted
perl -e 'print 0..9,A..Z,a..z,$/' | fold -w1 | while read C;do /usr/lib/initcpio/busybox sh ./Hi.sh $C >/dev/null 2>&1; case $? in 0) grep -q "$C" __golf-sorted || echo Fail: truthy: $C ;; *) grep -qv "$C" __golf-sorted || echo Fail: falsey: $C ;; esac ; done
Uiua SBCS , 29 bytes
∊:"ikqrsglnoAaCmx1FpHLRdSftc"
That's right, Uiua has a built-in function for checking membership.
-
1\$\begingroup\$ You say that like it's not a common function of most programming languages... :) \$\endgroup\$noodle person– noodle person2024年07月29日 03:05:09 +00:00Commented Jul 29, 2024 at 3:05
Explore related questions
See similar questions with these tags.
1ACFHLRSacdfgiklmnopqrstx\$\endgroup\$