Decode the chmod
Javascript (ES6), 165 161 bytes
n=>[0,1,2].map(i=>(s='User: 3Group: 68Others:58None576Read48Write476Execute475and4576only'.split(/(\d+)/))[i*2]+s[n[i]*2+1].replace(/./g,c=>' '+s[c*2])).join`
`
Edit: +1 byte to fulfill the "no tab" rule
Examples
let f =
n=>[0,1,2].map(i=>(s='User: 3Group: 68Others:58None576Read48Write476Execute475and4576only'.split(/(\d+)/))[i*2]+s[n[i]*2+1].replace(/./g,c=>' '+s[c*2])).join`
`
console.log(f("666"));
console.log(f("042"));
console.log(f("644"));
console.log(f("137"));
GNU sed, 187 163 158 (157+1) bytes
Run with -r (ERE regexp). File contains no trailing newline.
s/(.)(.)/User: \1\nGroup: \2\nOthers: /g
s/[4-7]/Read &/g
s/[2367]/Write &/g
s/[1357]/Execute &/g
s/(\w) (\w+) [1-7]/\1 and \2/g
s/[1-7]/only/g
s/0/None/g
Jelly, 100 91 85 bytes
Almost certainly golfable - 91 bytes, what?! 8 months and 6 wisdom bytes!
- 1. more string compression;
- 2. remove the post-ordinal decrement by 48 since indexing is modular;
- 3. use better tacit chaining).
-9 bytes with the kind help of @Lynn running string compressions for me
,“£ɱ~»
Ñ
ṖK,“ and”,Ṫ
LĿK
7RBUT€Uị“ØJƓ“¥Ị£“¤/¡»Ç€“¡*g»ṭ
“ṖŒhJ"ỵd¡»ḲðJ4_⁶ẋ⁸,"j€”:ż⁹Oị¢¤Y
Test it at TryItOnline
How?
,“£ɱ~» - Link 1: pair with the string "Only"
Ñ - Link 2: call next link
ṖK,“ and”,Ṫ - Link 3: insert " and" between the last two elements of x
Ṗ - x[:-1]
K - join with spaces
“ and” - the string " and"
Ṫ - x[-1]
, , - pair
LĿK - Link 4: call appropriate link and add missing spaces
L - length
Ŀ - call link at that index
K - join the result with spaces
7RBUT€Uị“ØJƓ“¥Ị£“¤/¡»Ç€“¡*g»ṭ - Link 5: construct all 8 cases
7R - range of 7: [1,2,3,4,5,6,7]
B - binary (vectorises): [[1],[1,0],[1,1],[1,0,0],[1,0,1],[1,1,0],[1,1,1]]
U - reverse (vectorises): [[1],[0,1],[1,1],[0,0,1],[1,0,1],[0,1,1],[1,1,1]]
T€ - indexes of truthy values for each: [[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3]]
U - reverse (vectorises): [[1],[2],[2,1],[3],[3, 1],[3,2],[3,2,1]]
“ØJƓ“¥Ị£“¤/¡» - list of strings: ["Execute","Write","Read"]
ị - item at index (vectorises): [["Execute"],["Write"],["Write","Execute"],["Read"],["Read","Execute",["Read","Write"],["Read","Write","Execute"]]
Ç€ - call the previous link for each
“¡*g» - the string "None"
ṭ - tack (Jelly is 1-based so the 8th item will be indexed as 0)
“ṖŒhJ"ỵd¡»ḲðJṚ⁶ẋ⁸,"j€”:ż⁹Oị¢¤Y - Main Link: parse input and make the result. e.g.: "042"
“ṖŒhJ"ỵd¡» - dictionary compression of "User Group Others"
Ḳ - split at spaces -> ["User","Group","Others"]
ð - dyadic chain separation, call that g (input as right)
J - range of length of g -> [1,2,3]
Ṛ - reverse -> [3,2,1]
⁶ - literal space
ẋ - repeat -> [" "," "," "]
⁸ - chain's left argument, g
" - zip with:
, - pair -> [["User"," "],["Group"," "],["Others"," "]]
”: - literal ':'
j€ - join for €ach -> ["User: ","Group: ","Others: "]
¤ - nilad followed by link(s) as a nilad:
⁹ - chain's right argument, the input string -> "042"
O - cast to ordinal (vectorises) -> [48, 52, 50]
¢ - call last link (5) as a nilad -> ["Execute Only","Write Only","Write and Execute","Read Only","Read and Execute","Read and Write","Read Write and Execute","None"]
ị - index into (1-based & modular) -> ["None","Read Only","Write Only"]
ż - zip together -> [["User: ","None"],["Group: ","Read Only"],["Others: ","Write Only"]]
Y - join with line feeds -> ["User: ","None",'\n',"Group: ","Read Only",'\n',"Others: ","Write Only"]
- implicit print:
>>>User: None
>>>Group: Read Only
>>>Others: Write Only