title: File Permissions

text:
# Question
Title: File Permissions
*Adapted from the UIL - Computer Science Programming free response question "Carla" for 2018 District.*

## Introduction

In UNIX-like operating systems, each file, directory, or link is "owned" by a "user", who is a member of a "group", and has certain "permissions" represented by a ten-character string such as "drwxrwxrwx". The first character is 'd', '-', or 'l' (directory, file, or link), followed by three sets of "rwx" values, indicating "read, write, execute" permissions. The first set is the user's rights, the middle set the group's rights, and the third everyone else's rights to that object.

Permission denied for any of these rights is represented by a '-' in place of the 'r', 'w', or 'x'. For example, a sample directory permission string would be "drwxr--r--", indicating full directory rights for the user, but "read-only" rights for the group member and all others.

**Each "rwx" combination can also be represented by an octal value (0-7) with the most significant bit representing read permission, the next most significant bit representing write permission, and the least significant bit representing execute permission.**

## Challenge

Given a four-character code string made up of a character: 'D', 'F', or 'L', followed by a three-digit octal integer value, like 664, output the resulting 10 character string that represents the permission value indicated.

## Input

Your program or function may either read the input from standard in (four characters will be entered, optionally followed by a newline) or be passed the input as an argument.

Your program may accept uppercase or lowercase inputs but must be consistent (either all inputs are uppercase or all inputs are lowercase).

## Output

Your program must print the resulting ten-character string that represents the permission value indicated in the exact format specified above. Tailing white space is allowed.

## Test Cases

In: `F664` Out: `-rw-rw-r--`
In: `D775` Out: `drwxrwxr-x`
In: `L334` Out: `l-wx-wxr--`
In: `F530` Out: `-r-x-wx---`
In: `D127` Out: `d--x-w-rwx`

## Scoring and Rules

# Answer
> 7 votes
# Jelly, 19 bytes

```
“rwx“-”Œp⁺;Ṁ⁾f-yị@~

```

Try it online!

### How it works

```
“rwx“-”Œp⁺;Ṁ⁾f-yị@~  Main link. Argument: s (string)

“rwx“-”              Set the return value to ["rwx, "-"].
       Œp            Take the Cartesian product, yielding ["r-", "w-", "x-"].
         ⁺           Take the Cartesian product, yielding
                     ["rwx", "rw-", "r-x", "r--", "-wx", "-w-", "--x", "---"].
          ;Ṁ         Append the maximum of s (the letter).
            ⁾f-y     Translate 'f' to '-'.
                  ~  Map bitwise NOT over s.
                     This maps the letter to 0, because it cannot be cast to int,
                     and each digit d to ~d = -(d+1).
                ị@   Retrieve the results from the array to the left at the indices
                     calculated to the right.
                     Indexing is modular and 1-based, so the letter from s is at
                     index 0, "---" at index -1, ..., and "rwx" at index -8.

```

# Answer
> 17 votes
## bash, ~~59~~ 53 bytes

```
chmod ${1:1} a>a;stat -c%A a|sed s/./${1:0:1}/|tr f -

```

Right tool for the job?

Thanks to Dennis for saving 5 bytes and HTNW for saving one.

Try it online!

```
chmod ${1:1} a>a;  # call chmod with the input with its first character removed
                   # note that the redirection creates the file a *before* the
                   #   chmod is run, because of the way bash works
stat -c%A a|       # get the human readable access rights
sed s/./${1:0:1}/  # replace the first character with the first char of input
|tr f -            # transliterate, replacing f with -

```

# Answer
> 11 votes
# Python 2, 78 bytes

```
lambda a,*b:[a,'-'][a=='f']+''.join('-r'[x/4]+'-w-w'[x/2]+'-x'[x%2]for x in b)

```

Takes input as a character and three ints.
Try it online!

### Explanation

`[a,'-'][a=='f']` takes either the input character or `-`, if the character is `f`.
`'-r'[x/4]+'-w-w'[x/2]+'-x'[x%2]` is essentially an octal conversion to get the `rwx` string.

# Answer
> 6 votes
# Perl 5 \+ `-p`, 37 bytes

```
s/\d/(<{-,r}{-,w}{-,x}>)[$&]/ge;y;f;-
```

Try it online!

## Explanation

`s///`ubstitutes each `\d`igit in the string (`$_`, implicit from the implicit `-n` provided by `-p`) with the result of the `glob` (`<...>`) of `{-,r}{-,w}{-,x}` (which is treated as a list) at index `$&` (the matched `\d`igit).

The `glob` computes this list:

```
(
"---", # 0
"--x", # 1
"-w-", # 2
"-wx", # 3
"r--", # 4
"r-x", # 5
"rw-", # 6
"rwx", # 7
)

```

# Answer
> 5 votes
# Retina, 51 bytes

```
f
-
0
---
1
--x
2
-w-
3
-wx
4
r--
5
r-x
6
rw-
7
rwx

```

Try it online!

No idea how to use Retina, so please let me know how to do this better. I just figured I'd try to learn at least one language that isn't Pyth.

### Explanation:

Replace `f` with `-` (leaving `d` and `l` unchanged), then replace each digit with the appropriate `rwx`.

# Answer
> 5 votes
# Retina 0.8.2, 43 bytes

```
\d
$&r$&w$&x
f|[0-3]r|[0145]w|[0246]x
-
\d

```

Try it online! Link includes test cases. Takes input in lower case. Explanation:

```
\d
$&r$&w$&x

```

Triplicate each digit, suffixing with `r`, `w` and `x`.

```
f|[0-3]r|[0145]w|[0246]x
-

```

Change all the incorrect letters to `-`s.

```
\d

```

Delete any remaining digits.

# Answer
> 4 votes
# JavaScript (ES6), 63 bytes

Expects the input string in lowercase.

```
s=>s.replace(/\d|f/g,c=>1/c?s[c&4]+s[c&2]+s[c&1]:'-',s='-xw-r')

```

Try it online!

### Commented

```
s => s.replace(   // replace in the input string s
  /\d|f/g, c =>   //   each character c which is either a digit or the letter 'f'
    1 / c ?       //   if c is a digit:
      s[c & 4] +  //     append '-' or 'r'
      s[c & 2] +  //     append '-' or 'w'
      s[c & 1]    //     append '-' or 'x'
    :             //   else:
      '-',        //     just replace 'f' with '-'
  s = '-xw-r'     //   s holds the permission characters
)                 // end of replace()

```

# Answer
> 4 votes
# Charcoal, 27 bytes

```
ＦＳ≡ιdιlιf¦-⭆rwx⎇§↨⁺⁸Ｉι²⊕λκ-

```

Try it online! Link is to verbose version of code. Explanation:

```
 Ｓ                          Input string
Ｆ                           Loop over characters
   ι                        Current character
  ≡                         Switch
    d                       Literal `d`
     ι                      Implicitly print current character
      l                     Literal `l`
       ι                    Implicitly print current character
        f                   Literal `f`
         ¦                  (Separator between string literals)
          -                 Implicitly print literal `-`
                            Implicit default case
            rwx             Literal `rwx`
           ⭆                Map over characters
                     ι      Input character
                    Ｉ       Cast to integer
                   ⁸        Literal 8
                  ⁺         Sum
                      ²     Literal 2
                 ↨          Base conversion
                        λ   Inner index
                       ⊕    Incremented
                §           Index into base conversion
                         κ  Inner character
                          - Literal `-`
               ⎇            Ternary
                            Implicitly print

```

# Answer
> 4 votes
# Haskell, ~~84~~ ~~83~~ 81 bytes

```
f 'f'='-'
f y=y
t#n=f t:((\x->["-r"!!div x 4,"-w-w"!!div x 2,"-x"!!mod x 2])=<<n)

```

Try it online!

Ended up being pretty similar in concept to Mnemonic's Python 2 answer. f creates the file type, the rest is the gets permissions from the octal number. This one really made me wish & was a bitwise and operator included in prelude.

# Answer
> 4 votes
# Java 8, 100 bytes

```
s->s.replaceAll("(\\d)","$1r$1w$1x").replaceAll("f|[0-3]r|[0145]w|[0246]x","-").replaceAll("\\d","")

```

Try it online.

Port of *@Neil*'s Retina answer.

**Explanation:**

```
s->                                 // Method with String as both parameter and return-type
  s.replaceAll("(\\d)","$1r$1w$1x") //  Replace every digit `d` with 'drdwdx'
   .replaceAll("f                   //  Replace every "f",
                |[0-3]r             //  every "0r", "1r", "2r", "3r",
                |[0145]w            //  every "0w", "1w", "4w", "5w",
                |[0246]x",          //  and every "0x", "2x", "4x", "6x"
               "-")                 //  with a "-"
   .replaceAll("\\d","")            //  Remove any remaining digits

```

# Answer
> 3 votes
# Jelly, 21 bytes

```
Ḣ⁾f-yɓOBṫ€4a“rwx”o”-ṭ

```

A full program printing to STDOUT. (As a monadic link the return value is a list containing a character and a list of three lists of characters.)

**Try it online!** Or see the test-suite.

### How?

```
Ḣ⁾f-yɓOBṫ€4a“rwx”o”-ṭ | Main Link: list of characters
Ḣ                     | head & pop (get the 1st character and modify the list)
 ⁾f-                  | list of characters = ['f', '-']
    y                 | translate (replacing 'f' with '-'; leaving 'd' and 'l' unaffected)
     ɓ                | (call that X) new dyadic chain: f(modified input; X)
      O               | ordinals ('0'->48, '1'->59, ..., '7'->55 -- notably 32+16+value)
       B              | convert to binary (vectorises) (getting three lists of six 1s and 0s)
        ṫ€4           | tail €ach from index 4 (getting the three least significant bits)
           “rwx”      | list of characters ['r', 'w', 'x']
          a           | logical AND (vectorises) (1s become 'r', 'w', or 'x'; 0s unaffected)
                 ”-   | character '-'
                o     | logical OR (vectorises) (replacing any 0s with '-'s)
                   ṭ  | tack (prepend the character X)
                      | implicit print (smashes everything together)

```

# Answer
> 3 votes
# Perl 6 `-p`, 37 bytes

```
s:g[\d]=[X~]('-'X <r w x>)[$/];s/f/-/

```

Try it online!

Port of Dom Hastings' Perl 5 solution.

# Answer
> 3 votes
# Retina, 38 bytes

Inspired by a comment from ASCII-only.

```
\d
---$&*
---____
r--
--__
w-
-_
x
f
-

```

Try it online!

The idea is converting each digit to unary (the default unary digit in Retina is `_`) with three leading `-`, and then converting binary digits from the most to the least significant.

# Answer
> 2 votes
# Python 3, 71 bytes

```
lambda s:("-"+s)[s[0]!="f"]+stat.filemode(int(s[1:],8))[1:]
import stat

```

Try it online!

Python 3.3+ has a built-in for that, although due to the need for an import, and differences in expected input format, it is not very golf-friendly.

# Answer
> 2 votes
# 05AB1E, ~~34~~ 27 bytes

```
ćls8βbvyi…rwx3*Nèë'-}J'f'-:

```

Try it online!

Golfed down 7 bytes by @MagicOctopusUrn

---

```
ć                           # Remove head from string.
 ls                         # Lowercase swap.
   8βb                      # Octal convert to binary.
      vy                    # For each...
        i        ë  }
         …rwx3*Nè           # If true, push the correct index of rwx.
                  '-        # Else push '-'.
                     J      # Repeatedly join stack inside the loop.
                      'f'-: # Repeatedly replace 'f' with '-' inside the loop.

```

# Answer
> 2 votes
# Tcl, 139 bytes

```
proc P s {join [lmap c [split $s ""] {expr {[regexp \\d $c]?"[expr $c&4?"r":"-"][expr $c&2?"w":"-"][expr $c&1?"x":"-"]":$c==f?"-":$c}}] ""}

```

Try it online!

---

~~Tcl, 144 bytes
```
proc P s {join [lmap c [split $s ""] {expr {[regexp \\d $c]?[list [expr $c&4?"r":"-"][expr $c&2?"w":"-"][expr $c&1?"x":"-"]]:$c==f?"-":$c}}] ""}

```
Try it online!
~~

##

~~Tcl, 149 bytes
```
proc P s {join [lmap c [split $s ""] {if [regexp \\d $c] {list [expr $c&4?"r":"-"][expr $c&2?"w":"-"][expr $c&1?"x":"-"]} {expr {$c==f?"-":$c}}}] ""}

```
Try it online!
~~

##

~~Tcl, 150 bytes
```
proc P s {join [lmap c [split $s ""] {if [regexp \\d $c] {set v [expr $c&4?"r":"-"][expr $c&2?"w":"-"][expr $c&1?"x":"-"]} {expr {$c==f?"-":$c}}}] ""}

```
Try it online!
~~

##

~~Tcl, 180 bytes
```
proc P s {join [lmap c [split $s ""] {if [regexp \\d $c] {[set R regsub] (..)1 [$R (.)1(.) [$R 1(..) [$R -all 0 [format %03b $c] -] r\\1] \\1w\\2] \\1x} {expr {$c==f?"-":$c}}}] ""}

```
Try it online!
~~

**Still very ungolfed!**

# Answer
> 2 votes
# Java (JDK 10), 118 bytes

```
s->{var r=s[0]=='f'?"-":""+s[0];var z="-xw r".split("");for(int i=0;++i<4;)r+=z[s[i]&4]+z[s[i]&2]+z[s[i]&1];return r;}

```

Try it online!

## Credits

# Answer
> 2 votes
# Excel, 224 bytes

```
=IF(LEFT(A1,1)="f","-",LEFT(A1,1))&CHOOSE(MID(A1,2,1)+1,"---","--x","-w-","-wx","r--","r-x","rw-","rwx")&CHOOSE(MID(A1,3,1)+1,"---","--x","-w-","-wx","r--","r-x","rw-","rwx")&CHOOSE(MID(A1,4,1)+1,"---","--x","-w-","-wx","r--","r-x","rw-","rwx")

```

Done in 4 stages:

```
IF(LEFT(A1,1)="f","-",LEFT(A1,1))    Replace "f" with "-".

```

And 3 times:

```
CHOOSE(MID(A1,2,1)+1,"---","--x","-w-","-wx","r--","r-x","rw-","rwx")

```

Trying to be smarter, adds `25 bytes` per set of rights, 75 in total:

```
IF(INT(MID(A1,2,1))>3,"r","-")&IF(MOD(MID(A1,2,1),4)>1,"w","-")&IF(ISODD(MID(A1,2,1)),"x","-")

```

# Answer
> 1 votes
# Python 2, 238 bytes

```
lambda m,r=str.replace,s=str.split,j="".join,b=bin,i=int,z=str.zfill,g=lambda h,y:y if int(h)else "-":r(m[0],"f","-")+j(j([g(z(s(b(i(x)),"b")[1],3)[0],"r"),g(z(s(b(i(x)),"b")[1],3)[1],"w"),g(z(s(b(i(x)),"b")[1],3)[2],"x")])for x in m[1:])

```

Try it online!

I had assumed this would be a drop in the bucket, but I was wrong indeed. Probably should have realized that a lambda wasn't the best idea at some point.

# Answer
> 1 votes
# APL+WIN, 55 bytes

Prompts for input string with leading character lower case:

```
('dl-'['dlf'⍳↑t]),⎕av[46+(,⍉(3⍴2)⊤⍎¨⍕1↓t←⎕)×9⍴69 74 75]

```

Explanation:

```
9⍴69 74 75 create a vector of ascii character codes for rwx -46, index origin 1

1↓t←⎕ prompt for input and drop first character

,⍉(3⍴2)⊤⍎¨⍕ create a 9 element vector by concatenating the binary representation for each digit

46+(,⍉(3⍴2)⊤⍎¨⍕1↓t←⎕)×9⍴69 74 75 multiply the two vectors and add 46

⎕av[.....] convert back from ascii code to characters, 46 being '-'

('dl-'['dlf'⍳↑t]), append first character from input swapping '-' for 'f'

```

# Answer
> 1 votes
# ,  57  52 bytes

5 bytes saved thanks to FrownyFrog!

```
-&.('-DLld'i.{.),[:,('-',:'rwx'){"0 1&.|:~1#:@}."."0

```

Try it online!

Yet another long solution... I don't know how to make `}` work in tacit verbs and that's why I used the much longer `{"0 1&.|:` for selection.

## Explanation:

`@}.` Drop the first symbol and

`,.&.":` convert the rest to a list of desimal digits

`]:#:` convert each digit to a list of binary digits (and cap the fork)

`('-',:'rwx')` creates a 2-row table and use 0 to select from its first row / 1 - from its second one

```
   '-',:'rwx'
---
rwx

```

`{"0 1&.|:~` uses the binary digits to select from the table above

`[:,` flattens the result

`('d-l'{~'DFL'i.{.)` formats the first symbol

`,` appends the fisrt symbol to the list of permissions

# Answer
> 1 votes
# Python 3, 77 bytes

```
lambda a,*b,k='-xw-r':f'{a}-'[a=='f']+''.join(k[x&4]+k[x&2]+k[x&1]for x in b)

```

Try it online!

# Answer
> 1 votes
# C (gcc), 109 104 bytes

At least C can convert octal input.... :-)

**Edit:** I realized that the size modifier wasn't strictly required, and that `putchar()` is shorter than `printf()` in this case!

```
f(a,b){char*s="-xwr";scanf("%c%o",&a,&b);putchar(a-70?a:*s);for(a=9;~--a;putchar(s[(1&b>>a)*(a%3+1)]));}

```

Try it online!

Original:

```
f(a,b){char*s="-xwr";scanf("%c%3o",&a,&b);putchar(a-70?a:*s);for(a=9;~--a;printf("%c",s[(1&b>>a)*(a%3+1)]));}

```

Try it online!

# Answer
> 1 votes
# PHP, 68 bytes

```
<?=strtr(strtr($argn,[f=>_,___,__x,_w_,_wx,r__,r_x,rw_,rwx]),_,"-");

```

translates `f` in lowercase input to underscore and every octal number to its `rwx` equivalent, using underscores instead of dashes (to save the need for quotes), then replaces the `_` with `-`.

Run as pipe with `-nF` or try it online.

# Answer
> 1 votes
# Ruby, ~~80~~ 76 bytes

```
->a,*b{a.tr(?f,?-)+b.map{("%03b"%_1).gsub(/./){$&>?0?"rwx"[$`.size]:?-}}*""}

```

Attempt This Online!

# Ruby, 64 bytes

A port of user48543's Python 2 solution.

```
->a,*b{a.tr(?f,?-)+b.map{"-r"[_1/4]+"-w-w"[_1/2]+"-x"[_1%2]}*""}

```

Attempt This Online!

---
Tags: code-golf
---


title: Tips for golfing in Wren

text:
# Question
Title: Tips for golfing in Wren
Wren is a small, fast, class-based concurrent scripting language. Does anyone have any tips for this language?

Please make sure to post 1 tip per answer, and don't post answers like "remove whitespace".

# Answer
# `String.fromByte`

Instead of the standard `String.fromCodePoint(x)`, a method that saves a whole 5 bytes is:

```
String.fromByte

```
> 2 votes

# Answer
In most cases `true` can be written `1` and `false` can be written `!1`
> 0 votes

---
Tags: code-golf, tips
---