Decodificar o chmod

26

Desafio

Dado um número de permissões octais de três dígitos, produza as permissões que ele concede.

chmod

Nos sistemas operacionais UNIX, as permissões de arquivo são alteradas usando o chmodcomando Existem algumas maneiras diferentes de usar o chmod, mas o que focaremos hoje é o uso de permissões octais.

Os três dígitos no número de permissões representam uma pessoa diferente:

  • O primeiro dígito representa as permissões para o usuário
  • O segundo dígito representa as permissões para o grupo
  • O último dígito representa as permissões para outros

Em seguida, cada dígito representa uma permissão, como mostrado abaixo em:

Key: number | permission

7 | Read Write and Execute
6 | Read and Write
5 | Read and Execute
4 | Read only
3 | Write and Execute
2 | Write only
1 | Execute only
0 | None

Entrada

A entrada será o número de três dígitos como uma sequência, por exemplo:

133

ou

007

Isso será passado via STDIN ou através de argumentos de função.

Saída

Sua saída deve ter as permissões diferentes para cada usuário, grupo e outros. Você deve exibir essas informações da seguinte maneira:

User:   ddd
Group:  ddd
Others: ddd

Onde existem três espaços depois User, dois espaços depois Groupe um espaço depois Others. Você substitui dddpelas informações de permissões.

Sua saída pode ser para STDOUT ou como uma string retornada.

Exemplos

Entrada: 666

Saída:

User:   Read and Write
Group:  Read and Write
Others: Read and Write

Entrada: 042

Saída:

User:   None
Group:  Read only
Others: Write only

Entrada: 644

Saída:

User:   Read and Write
Group:  Read only
Others: Read only

Ganhando

O código mais curto em bytes vence.

Beta Decay
fonte
Quais são as especificações da entrada?
Jonathan Allan
@JonathanAllan Apenas o número de três dígitos
Decay Beta
Você quer dizer apenas um número inteiro decimal, então 042 seria recebido como 42?
Jonathan Allan
2
@ Jonathan Não, é uma entrada de string, então seria 042
Decay Beta 13/16
1
A saída parece correta com um caractere de tabulação; por que não usá-la? Apenas para idiomas penais que precisam de mais bytes para preencher uma string?
Titus

Respostas:

3

05AB1E , 89 87 bytes

”‚Ý:‚Ù:ˆ†:”ð¡v”Šª0ÍÃ20‡í20‡í1ÍÃ0‚Ø20‚Ø1ÍÃ0‚Ø1‡í0‚؇í1ÍÔ2ð'€É«:1ð'€ƒ«:0ð«¡¹Nèèð3N-×ìyì,

Convoca a codificação Cthulhu . Usa a codificação CP-1252 . Experimente online!

Adnan
fonte
14

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`
`

Editar: +1 byte para cumprir a regra "sem separadores"

Exemplos

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"));

Arnauld
fonte
Você pode obter alguns bytes reorganizando a matriz (e talvez separando os números das cadeias). +1 para a ideia.
Titus
@ Titus - tenho que admitir que não vejo um rearranjo que economiza alguns bytes. Além disso, os números devem ser tratados como seqüências de caracteres para que replace()funcionem neles sem coagir. Mas posso estar perdendo o seu ponto.
Arnauld
@ Titus - Algo como 'User3Group68Others58None576Read48Write476Execute475and4576only'.split(/(\d+)/)pode funcionar. É isso que você tinha em mente?
Arnauld
Eu os estava entendendo mal; pensavam que eram valores octais. :) Mas sua nova ideia também não é ruim.
Titus
A saída do desafio requer espaços em vez de guias, como está atualmente escrita.
precisa saber é o seguinte
13

GNU sed, 187 163 158 (157 + 1) bytes

Execute com -r (ERE regexp). O arquivo não contém nenhuma nova linha à direita.

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
FireFly
fonte
Boa abordagem, mas você pode salvar cerca de 20 bytes removendo os dígitos ao adicionar o andou only.
Neil
@ Neil there :) incorporou sua sugestão para uma economia muito significativa.
FireFly
1
A primeira linha poderia ser apenas: s/(.)(.)/User: \1\nGroup: \2\nOthers: /. Mais alguns bytes podem ser salvos portando para Perl, que possui \de \K.
Ninjalj 16/09/16
@ninjalj good point. Eu vou ficar com o sed, já que não conheço o Perl, e tenho certeza de que existem outros truques para puxá-lo para torná-lo ainda mais curto, fora das substituições s ///.
FireFly
6

C # 214 bytes

string h(string y){string e="Execute ",r="Read ",w="Write ",O="Only",a="and ";var z=new[]{"None",e+O,w+O,w+a+e,r+O,r+a+e,r+a+w,r+w+a+e};return$"User:   {z[y[0]-'0']}\nGroup:  {z[y[1]-'0']}\nOthers: {z[y[2]-'0']}";}
pinkfloydx33
fonte
6

Geléia , 100 91 85 bytes

Quase certamente jogável - 91 bytes, o que ?! 8 meses e 6 bytes de sabedoria!
- 1. mais compressão de strings;
- 2. remova o decremento pós-ordinal em 48, pois a indexação é modular;
- 3. use melhor encadeamento tácito).

-9 bytes com a ajuda do @Lynn executando compressões de string para mim

,“£ɱ~»
Ñ
ṖK,“ and”,Ṫ
LĿK
7RBUT€Uị“ØJƓ“¥Ị£“¤/¡»Ç€“¡*g»ṭ
“ṖŒhJ"ỵd¡»ḲðJ4_⁶ẋ⁸,"j€”:ż⁹Oị¢¤Y

Teste em TryItOnline

Quão?

,“£ɱ~» - 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
Jonathan Allan
fonte
4

Oitava, 185 bytes

@(n)fprintf('User:   %s\nGroup:  %s\nOthers: %s',{'Read Write and Execute','Read and Write','Read and Execute','Read only','Write and Execute','Write only','Execute only','None'}{56-n})

Crie uma função anônima que aceite a entrada como uma sequência: '042'. Convertê-lo para um array: (56-'042)' = [0 4 2]. Use isso como vários índices de célula para indexar a matriz de células Read Write and Execute','Read and Write', .... Usos fprintfpara a saída dos três cordas, com as categorias apropriadas: User:, Group:e Others:.

Eu tentei encontrar uma maneira de loja Execute, Write, Readcomo palavras e concatenar separados, conforme necessário, mas esta acabou por mais tempo do que a abordagem ingênua.

Exemplos:

1> f('000')
User:   None
Group:  None
Others: None
2> f('042')
User:   None
Group:  Read only
Others: Write only

Experimente online.

Stewie Griffin
fonte
2
Você pode economizar alguns bytes usando strsplit('Read Write and Execute*Read and Write*Read and Execute*Read only*Write and Execute*Write only*Execute only*None','*')em vez do literal matriz de célula
Luis Mendo
4

PowerShell v2 +, 189 168 bytes

[char[]]$args[0]|%{('User','Group','Others')[$i++]+":`t"+('None','Read','Write','Execute','only','and')[(0,(3,4),(2,4),(2,5,3),(1,4),(1,5,3),(1,5,2),(1,2,5,3))[$_-48]]}

Faz $args[0]um charloop através da entrada como uma matriz. A cada iteração, indexamos em uma matriz com $i++(o padrão é 0) para selecionar User, Groupou Others, concatenar isso com dois pontos e uma guia, e concatenar isso com outro índice de matriz.

Aqui está a mágica. Nós convertemos implicitamente o charpara an inte subtraímos 48(ie, transformando ASCII 48( "0") em 0), escolhendo a expressão apropriada como uma matriz de ints. Essa matriz é subseqüentemente usada como índice na 'None','Read','Write','Execute','only','and'matriz. Como o padrão $ofs(Separador de campo de saída) é um espaço, ele insere corretamente espaços entre os elementos da matriz quando for stringizado (o que acontece quando concatenado à esquerda).

Essas três seqüências são deixadas no pipeline e a saída via implícita Write-Outputacontece na conclusão do programa.

Exemplo

PS C:\Tools\Scripts\golfing> .\decode-the-chmod.ps1 '123'
User:   Execute only
Group:  Write only
Others: Write and Execute
AdmBorkBork
fonte
3

Palha , 193 bytes

((01234567)((None)(Execute only)(Write only)(Write and Execute)(Read only)(Read and Execute)(Read and Write)(Read Write and Execute)))::~<:{-¢(User:   ),+>
>}:{-¢(Group:  ),+>
>}-¢(Others: ),+>

Experimente online

Empurre 3 vezes uma tabela de conversão na primeira pilha, alterne para a segunda pilha, converta cada número usando a tabela de conversação e imprima.

TuxCrafting
fonte
2

Haskell, 186 bytes

s=zip(words"7654 6 7632 753 7531 0 421")(words"Read and Write and Execute None only")
m c=mapM_(\(x,y)->putStrLn(x++unwords[b|(a,b)<-s,elem y a]))$zip["User:   ","Group:  ","Others: "]c

Exemplo:

Prelude> :r
[1 of 1] Compiling Main             ( decCh.hs, interpreted )
Ok, modules loaded: Main.
*Main> m "654"
User:   Read and Write
Group:  Read and Execute
Others: Read only

Apenas Prelude usado. Estou fazendo isso certo?

Ungolfed:

s = zip (words "7654 6 7632 753 7531 0 421")
        (words "Read and Write and Execute None only")

ps y = unwords [b|(a,b)<-s,elem y a] -- build permissions string
pp (x,y) = putStrLn $ x ++ ps y -- print user + permission

m c =   let up = zip ["User:   ","Group:  ","Others: "] c -- pair user and permission
        in mapM_ pp up --print each
michi7x7
fonte
2

Python 2, 190 185 bytes

def f(i):
 r,w,a,x,o,g="Read ","Write ","and ","Execute ","only",["User:  ","Group: ","Others:"];p=["None",x+o,w+o,w+a+x,r+o,r+a+x,r+a+w,r+w+a+x]
 for z in 0,1,2:print g[z],p[int(i[z])]

Deixa um espaço à direita se Execute or Write estiver no final da linha, mas não vi que isso não fosse permitido.

EDIT Salvei 5 bytes alterando o intervalo (3) para 0,1,2 e verificando a contagem de bytes no meu laptop Linux em vez do meu no Windows (\ n = \ r \ n ou o contrário. Nunca me lembro qual).

ElPedro
fonte
2

Python 2, 240 239 238 237 228 bytes

Eu pensei em finalmente dar uma chance a essa coisa de golfe frio. Esperamos que o espaço em branco à direita seja permitido. (fixo e, no processo, salvou um byte)

i=0
def a(b):
 for d in 4,2,1:
    if b&d:yield('Execute','Write','Read')[d/2]
for k in raw_input():
 b,q=list(a(int(k))),' and';e=len(b)
 if e:b[~e/2]+=(' only',q,q)[e-1]
 print'UGOsrteohrue:pr :s  :'[i::3],' '.join(b)or None;i+=1
Jack Greenhill
fonte
Bem-vindo ao PPCG e boa primeira resposta!
ETHproductions
Substitui descaradamente o intervalo (3) na minha resposta do Python 2 para 0,1,2 depois de ler seu código. Boa resposta. +1
ElPedro 14/09/16
2

PHP, 169 159 bytes

foreach([User,Group,Others]as$i=>$u){echo"
$u: ";for($n=[5,33,34,66,35,67,131,531][$i]];$n;$n>>=3)echo["and",Execute,Write,Read,only,None][$n&7]," ";}

leva string como argumento de linha de comando: php -r '<code>' <argument>,
imprime uma nova linha líder em vez de uma fuga

Obrigado a Jörg por apontar meus erros - e pela \t.

PHP, 169 bytes

com a nova restrição: (caractere de tabulação proibido)

foreach(['User:  ','Group: ','Others:']as$i=>$u){echo"
$u";for($n=[5,33,34,66,35,67,131,531][$argv[1][$i]];$n;$n>>=3)echo' ',['and',Read,Write,Execute,only,None][$n&7];}

Este é 1 byte mais curto do que com str_pad, devido ao espaço em branco adicional necessário.

demolir

foreach([User,Group,Others]as$i=>$u)
{
    echo"\n$u:\t";                      // print newline, who, blanks
    for($n=[5,33,34,66,35,67,131,531]   // octal values for words indexes
        [$argv[1][$i]]                  // (last word=highest digit)
        ;$n;$n>>=3)                     // while value has bits left
        echo['and',Execute,Write,Read,only,None][$n&7]," "; // print that word
}

Para criar a matriz para $n, use isto:

$b=[[5],[1,4],[2,4],[2,0,1],[3,4],[3,0,1],[3,0,2],[3,2,0,1]];
foreach($b as$i=>$a){for($v=$j=0;$a;$j+=3)$v+=array_shift($a)<<$j;echo"$v,";}
Titus
fonte
1
foreach (['Usuário', 'Grupo', 'Outros'] como $ i => $ u) {echo "\\ n $ u: \\ t"; salva alguns bytes ea saída para 3,4,6 está errado
Jörg Hülsermann
1
Esta é a boa idéia [5,33,34,66,35,67,131,531] boa ideia
Jörg Hülsermann 13/16
Eu esqueci 'Usuário' para Usuário, por exemplo, salva os próximos 6 bytes que você deseja vencer no JavaScript
Jörg Hülsermann 13/16
@ JörgHülsermann: Eu estava prestes a adotar o "\ t" de qualquer maneira; obrigado. +1 para isso :) Bom olho no 33!
Titus
1
para 346 nossa produção é usuário: ler e escrever Grupo: Execute somente os outros: escrever e executar deveria Usuário: escrever e executar Grupo: Somente leitura Outros: ler e escrever
Jörg Hülsermann
2

bash - 221 213 bytes

GNU bash, version 4.3.46

l=("User:   " "Group:  " "Others: ")
o=\ only;a=" and ";x=Execute;w=Write;r=Read
b=(None "$x$o" "$w$o" "$w$a$x" "$r$o" "$r$a$x" "$r$a$w" "$r $w$a$x")
for c in `echo $1|grep -o .`;{ echo "${l[$((z++))]}${b[$c]}";}

Não está claro se isso pode ser condensado ainda mais, pelo menos não sem alterar fundamentalmente a abordagem aqui (dividindo a entrada e usando-a como um índice para a matriz ${b}que contém as seqüências correspondentes).

quadros
fonte
1
É mais curto com \ onlyo inline expandido. grep -o .<<<$1é mais curto que echo $1|grep -o ., mas ler a entrada de stdin com while read -n1 cé melhor. Os índices de matriz têm um contexto aritmético no bash, portanto ${l[z++]}funciona. lseria mais curto como uma string, que seria acessada como ${l:z++*8:8}(deslocamento e comprimento têm contexto aritmético). Outro byte pode ser exibido lendo todo o modo c, expandindo "Usuário:", ... inline e fazendo uso criterioso das expansões de parâmetros.
Ninjalj 20/09/16
1
Para um resultado final de: a=" and ";x=Execute;w=Write;r=Read;b=(None $x\ only $w\ only "$w$a$x" $r\ only "$r$a$x" "$r$a$w" "$r $w$a$x");read c;echo "User: ${b[${c%??}]}\nGroup: ${b[${c:1:1}]}\nOthers: ${b[${c:2}]}"(substitua \ n por novas linhas literais).
Ninjalj 20/09/16
1

Java 7, 300 284 bytes

String c(String s){char[]a=s.toCharArray();return"User:   "+f(a[0])+"Group:  "+f(a[1])+"Others: "+f(a[2]);}String f(int i){return new String[]{"None","Execute only","Write only","Write and Execute","Read only","Read and Execute","Read and Write","Read Write and Execute"}[i%48]+"\n";}

Abordagem direta por enquanto. Tentará criar uma abordagem mais genérica para reutilizar as palavras.

Casos não testados e de teste:

Experimente aqui.

class M{
  static String c(String s){
    char[] a = s.toCharArray();
    return "User:   " + f(a[0]) + "Group:  " + f(a[1]) + "Others: " + f(a[2]);
  }

  static String f(int i){
    return new String[]{ "None", "Execute only", "Write only", "Write and Execute", "Read only", "Read and Execute", "Read and Write", "Read Write and Execute" }
      [i % 48] + "\n";
  }

  public static void main(String[] a){
    System.out.println(c("666"));
    System.out.println(c("042"));
    System.out.println(c("644"));
  }
}

Saída:

User:   Read and Write
Group:  Read and Write
Others: Read and Write

User:   None
Group:  Read only
Others: Write only

User:   Read and Write
Group:  Read only
Others: Read only
Kevin Cruijssen
fonte
1

Groovy, 217 207 205 bytes

def c(m){def i=0,e='Execute',w='Write',r='Read',o=' only',a=' and ';m.each{println(['User:   ','Group:  ','Others: '][i++]+['None',"$e$o","$w$o","$w$a$e","$r$o","$r$a$e","$r$a$w","$r $w$a$e"][it as int])}}

ungolfed:

def c(m) {
  def i=0,e='Execute',w='Write',r='Read',o=' only',a=' and ';
  m.each{
    println(['User:   ','Group:  ','Others: '][i++]+['None',"$e$o","$w$o","$w$a$e","$r$o","$r$a$e","$r$a$w","$r $w$a$e"][it as int])
  }
}
norganos
fonte
1

Mathematica, 211 bytes

{r,w,e,o,a}={"Read ","Write ","Execute ","only ","and "};""<>Transpose@{{"User:   ","Group:  ","Others: "},"None"[{e,o},{w,o},{w,a,e},{r,o},{r,a,e},{r,a,w},{r,w,a,e}][[#]]&/@IntegerDigits[#,10,3],"\n"&~Array~3}&

Uma implementação direta (provavelmente facilmente superável): não calcula nada, apenas codifica cada saída possível. Entrada é um número inteiro; gera cada linha com um espaço à direita e uma nova linha à direita no geral.

IntegerDigits[#,10,3]fornece os três dígitos da entrada (mesmo se houver zeros à esquerda). Cada dígito indica um argumento da "função"

"None"[{e,o},{w,o},{w,a,e},{r,o},{r,a,e},{r,a,w},{r,w,a,e}]

com 0 indicando o próprio nome da função. ""<>concatena todas as seqüências de caracteres em uma lista (de listas). "\n"&~Array~3produz as três novas linhas.

Greg Martin
fonte
Acabei de notar que minha resposta do Python 2 é quase idêntica à sua, mesmo usando os mesmos nomes de variáveis. Sinceramente, não tinha visto o seu antes de postar!
ElPedro 14/09/16
1
não se preocupe! Eu acho que correspondam à variável nomes é muito bonito de se esperar nesta situação :)
Greg Martin
Acho que você está certo. Os nomes de variáveis foram um pouco previsível ☺
ElPedro
btw, +1 cos pensamos da mesma maneira :-)
ElPedro
1
Aliás, eu não conheço o Mathematica, mas acho que você pode perder um byte removendo o espaço de "somente". Sempre estará no final de uma linha, portanto não precisa de um espaço à direita.
ElPedro 14/09
1

Java 7, 278

Golfe:

String f(String i){String o="";for(int n=0;n<i.length();)o+=(n<1?"User:   ":n<2?"Group:  ":"Others: ")+new String[]{"None","Execute only","Write only","Write and Execute","Read only","Read and Execute","Read and Write","Read Write and Execute"}[i.charAt(n++)-48]+"\n";return o;}

Ungolfed:

  String f(String i) {
    String o = "";
    for (int n = 0; n < i.length();)
      o += (n < 1 ? "User:   " : n < 2 ? "Group:  " : "Others: ")
        + new String[] { "None", "Execute only", "Write only", "Write and Execute", "Read only", "Read and Execute",
            "Read and Write", "Read Write and Execute" }[i.charAt(n++) - 48]
        + "\n";
    return o;
  }

Saída:

User:   Read and Write
Group:  Read and Write
Others: Read and Write

User:   None
Group:  Read only
Others: Write only

User:   Read and Write
Group:  Read only
Others: Read only

fonte
1

Python 3.5, 3.6 - 235 232 228 216 bytes

(deve funcionar em todos os Python 3.x)

Portanto, a entrada está em STDIN aqui (salva uma importação ☺).

a=input()
r=range
for i in r(3):
 p=int(a[i]);x=[["Read","Write","Execute"][j]for j in r(3)if 4>>j&p]
 if x[1:]:x[-1:-1]="and",
 if len(x)==1:x+="only",
 print(["User:  ","Group: ","Others:"][i]," ".join(x)or"None")

Utilizando tuplas, omitindo espaços sempre que possível e precedência do operador em que você normalmente colocaria parênteses para deixar suas intenções claras.

Uso da amostra:

$ echo -n '666' | python3 golf2.py
User:   Read and Write
Group:  Read and Write
Others: Read and Write
$ echo -n '644' | python3 golf2.py
User:   Read and Write
Group:  Read only
Others: Read only
$ echo '042' | python3 golf2.py
User:   None
Group:  Read only
Others: Write only
$ echo '123' | python3 golf2.py
User:   Execute only
Group:  Write only
Others: Write and Execute
$ echo -n '777' | python3 golf2.py
User:   Read Write and Execute
Group:  Read Write and Execute
Others: Read Write and Execute

Sem golfe:

input_perms = list(map(int, input()))

entities = ["User", "Group", "Others"]
perm_names = ["Read", "Write", "Execute"]

for i in range(3):
    bits = input_perms[i]
    perms = [
        perm_names[j]
        for j in range(3)
        if (1 << (2-j)) & bits
    ]

    if len(perms) > 1:
        perms.insert(-1, "and")
    if len(perms) == 1:
        perms.append("only")

    print("{:7} {}".format(
        entities[i]+":",
        " ".join(perms) or "None"
    ))
Jonas Schäfer
fonte
1

Lote, 280 bytes

@echo off
set/pc=
call:l "User:   " %c:~0,1%
call:l "Group:  " %c:~1,1%
call:l "Others: " %c:~2,1%
exit/b
:l
for %%s in (None.0 Execute.1 Write.2 "Write and Execute.3" Read.4 "Read and Execute.5" "Read and Write.6" "Read Write and Execute.7") do if %%~xs==.%2 echo %~1%%~ns

A codificação das seqüências foi 47 bytes mais curta do que tentar reuni-las. Teria 267 bytes se as guias fossem legais.

Neil
fonte
1

C # 307 241 210 bytes

string X(string s){var z="User: ,Group: ,Others:,5,34,14,123,04,023,021,0123,Read,Write,and,Execute,only,None".Split(',');return string.Join("\n",s.Zip(z,(a,b)=>b+z[a-45].Aggregate("",(x,y)=>x+" "+z[y-37])));}

Formatado

string X(string s)
{
    var z = "User:  ,Group: ,Others:,5,34,14,123,04,023,021,0123,Read,Write,and,Execute,only,None".Split(',');
    return string.Join("\n", s.Zip(z, (a, b) => b + z[a - 45].Aggregate("", (x, y) => x + " " + z[y - 37])));
}
Grax32
fonte
1

C #, 322 337 348 bytes

Com certeza essa não é a versão mais curta, mas tentei resolver esse problema usando operadores bit a bit, já que os chmodvalores são realmente sinalizadores de bit. Também C # provavelmente não é a melhor linguagem de golfe: D

string P(string s){Func<int,string>X=p=>{var a=new List<string>();if((p&4)>0)a.Add("Read");if((p&2)>0)a.Add("Write");if((p&1)>0)a.Add("Execute");return a.Count>1?string.Join(" ",a.Take(a.Count-1))+" and "+a.Last():a.Count>0?a.First()+" only":"none";};return string.Join("\n",(new[]{"User:   ","Group:  ","Others: "}).Select((c,i)=>c+X(s[i]-'0')));}

ungolfed: (com comentários)

string P(string s)
{
    // Function that determines the permissions represented by a single digit (e.g. 4 => "Read only")
    Func<int, string> X = p => 
    {
        var a = new List<string>();         // temporary storage for set permissions
        if ((p & 4) > 0) a.Add("Read");     // Read bit set
        if ((p & 2) > 0) a.Add("Write");    // Write bit set
        if ((p & 1) > 0) a.Add("Execute");  // Execute bit set

        // actually just Output formatting ... Takes a lot of bytes *grr*
        return a.Count > 1 
            ? string.Join(" ", a.Take(a.Count - 1)) + " and " + a.Last() 
            : a.Count > 0 
                ? a.First() + " only" 
                : "none";
    };

    // Actual result:
    return string.Join("\n", (new[] { "User:   ", "Group:  ", "Others: " })
        .Select((c, i) => c + X(s[i] - '0'))); // Map "User, .." to its permissions by using above function
}

Esta é a minha primeira vez no código de golfe, então por favor me diga, se eu fiz alguma coisa errada :)

EDIT 1:

Salvou alguns bytes substituindo s[i]-'0'por s[i]&7(no final) e salvando a contagem da lista na variável:

string P(string s){Func<int,string>X=p=>{var a=new List<string>();if((p&4)>0)a.Add("Read");if((p&2)>0)a.Add("Write");if((p&1)>0)a.Add("Execute");var c=a.Count;return c>1?string.Join(" ",a.Take(c-1))+" and "+a.Last():c>0?a[0]+" only":"none";};return string.Join("\n",(new[]{"User:   ","Group:  ","Others: "}).Select((c,i)=>c+X(s[i]&7)));}

EDIT 2:

Alterado para expressão lambda:

s=>{Func<int,string>X=p=>{var a=new List<string>();if((p&4)>0)a.Add("Read");if((p&2)>0)a.Add("Write");if((p&1)>0)a.Add("Execute");var c=a.Count;return c>1?string.Join(" ",a.Take(c-1))+" and "+a.Last():c>0?a[0]+" only":"none";};return string.Join("\n",(new[]{"User:   ","Group:  ","Others: "}).Select((c,i)=>c+X(s[i]&7)));}
Stefan
fonte
1

Javascript, 213 209 208 188 186 bytes

function(d){a=" and ";r="Read";w="Write";e="Execute";v=";";o=" only";c=["None",e+o,w+o,w+a+e,r+o,r+a+e,r+a+w,r+" "+w+a+e];return"User: "+c[d[0]]+"\nGroup: "+c[d[1]]+"\nOthers: "+c[d[2]]}

Economizou 20 bytes graças ao Dada!

Paul Schmitz
fonte
3
Posso estar enganado, mas sua matriz não deveria estar na ordem oposta? Se eu chamar b ("000"), ele retornará "Read Write and Execute", enquanto se pode esperar "None" ...
Dada
E eu tenho certeza que isso poderia ser mais jogado. Por exemplo, uma versão 191 byte: function b(p){a=" and ";r="Read";w="Write";e="Execute";v=";";o=" only";c=["None",e+o,w+o,w+a+e,r+o,r+a+e,r+a+w,r+" "+w+a+e];return"User: "+c[p[0]]+"\nGroup: "+c[p[1]]+"\nOthers: "+c[p[2]]}.
Dada
1

Visual Basic, 606 bytes

imports System.Collections
module h
sub main()
Dim i As String=console.readline()
Dim s=new Stack(new String(){"Others: ","Group:  ","User:   "})
for each j as Char in i
dim t=new Stack()
if((asc(j) MOD 2)=1)then t.push("Execute")
if(asc(j)=50 or asc(j)=51 or asc(j)=54 or asc(j)=55)then t.push("Write")
if(asc(J)>51)then t.push("Read")
if t.count=3 then
w(s.pop+t.pop+" "+t.pop+" and "+t.pop)
else
if t.count=2 then
w(s.pop+t.pop+" and "+t.pop)
else
if t.count=0 then
w(s.pop+"None")
else
w(s.pop+t.pop+" only")
end if
end if
end if
next
end sub
sub w(s As String)
console.writeline(s)
end sub
end module
polyglotrealIknow
fonte
1
Bem-vindo ao PPCG! Boa primeira resposta BTW :)
Beta Decay
1

Cristal, 200 194 bytes

def m(y)y=y.chars.map &.to_i
a=" and "
o=" only"
r="Read"
w="Write"
x="Execute"
c=["None",x+o,w+o,w+a+x,r+o,r+a+x,r+a+w,r+" "+w+a+x]
"User:   "+c[y[0]]+"
Group:  "+c[y[1]]+"
Others: "+c[y[2]]end

retorna a sequência resultante para uma determinada sequência octal como uma sequência. por exemplo: m("670")resultados para: User: Read and Write\nGroup: Read Write and Execute\nOthers: None.

Experimente online .

Domii
fonte
0

C #, 371 bytes

public String[] a = {"none","Execute only","Write only","Write and Execute","Read only","Read and Execute","Read and Write","Read Write and Execute"};
public String pA(int i){return a[i];}
public int d(int n,int i){
  n=n/Math.pow(10,i);
  return n%=10;
}
public void main(int i){
  Console.Write("User:\t{0}\nGroup:\t{1},Others:\t{2}",pA(d(i,0)),pA(d(i,1)),pA(d(i,2));
}
Alireza Tabatabaeian
fonte
4
Isso é código-golfe, então você deve colocar seu código no golfe. Além disso, adicione um cabeçalho com o nome do idioma e o número de bytes.
TuxCrafting 13/09/16
Adicionei sua contagem de bytes, que é sua pontuação. Você precisa obter a sua pontuação mais baixa possível para ganhar
Beta Decay
Por exemplo, você se livra de todo o espaço em branco desnecessário em cada função
Decay Beta
1
@BetaDecay Obrigado, sou novo nesta comunidade e acho melhor usar o php, o que poderia levar a mais códigos compactados.
Alireza Tabatabaeian
1
@Alireza Essa é uma boa ideia. Embora neste site, nós gostamos de ver respostas curtas em Java e C # :)
Beta Decay
0

Python 3.5 - 370 294 243 bytes

Golfe:

import sys
a=lambda o: [print(('User:  ','Group: ','Others:')[n],('None','Execute only','Write only','Write and Execute','Read only','Read and Execute','Read and Write','Read Write and Execute')[int(o[n])]) for n in range(0,3)]
a(sys.argv[1])

Verificação de tamanho:

$ du -b OctalToHuman.py 
243     OctalToHuman.py

Sem golfe:

#!/usr/bin/env python3
from sys import argv as ARGS

types = ('User:  ', 'Group: ', 'Others:')
perms = ('None','Execute only','Write only','Write and Execute','Read only','Read and Execute','Read and Write','Read Write and Execute')

def convert(octal_string):
    for n in range(0,3):
        print(types[n], perms[int(octal_string[n])])

if __name__ == '__main__':
    convert(ARGS[1])

Saída de amostra:

$ python ./OctalToHuman.py 666
User:   Read and Write
Group:  Read and Write
Others: Read and Write

$ python ./OctalToHuman.py 042
User:   None
Group:  Read only
Others: Write only

$ python ./OctalToHuman.py 644
User:   Read and Write
Group:  Read only
Others: Read only
Raio
fonte
Este não é um candidato sério para os critérios vencedores. Exigimos que todas as respostas façam uma tentativa séria de otimizar sua pontuação para os critérios vencedores (por exemplo, em desafios de código de golfe como este, os envios devem fazer uma tentativa séria de minimizar a contagem de bytes do programa).
Mego
Você pode salvar alguns bytes removendo import syse apenas tornando o programa uma função anônima ( lambda o:...).
NoOneIsHere
0

F #, 204 203 bytes

meu primeiro golfe, por favor, perdoe os erros;)
A versão golfada (com base em 1: 1 na resposta de pinkfloydx33 ):

fun(y:string)->let e,r,w,o,a="Execute ","Read ","Write ","only","and ";let z=["None";e+o;w+o;w+a+e;r+o;r+a+e;r+a+w;r+w+a+e;];let(!-)a=z.[int y.[a]-48];sprintf"User:   %s\nGroup:  %s\nOthers: %s"!-0!-1!-2

A versão não destruída:

fun (y : string) ->
    let e, r, w, o, a = "Execute ", "Read ", "Write ", "only", "and "
    let z = [
                "None";
                e + o;
                w + o;
                w + a + e;
                r + o;
                r + a + e;
                r + a + w;
                r + w + a + e;
            ]
    let (!-) a = z.[int(y.[a]) - 48]
    sprintf "User:   %s\nGroup:  %s\nOthers: %s" !-0 !-1 !-2

Exemplo de uso:

let k =  ...... // function definition goes here

printf"%s"<|k"755"
printf"%s"<|k"042"
// etc ...


Isso é apenas para verificar se eu poderia 'melhorar' a resposta de pinkfloydx33 - não aceito nenhum crédito pelo algoritmo

desconhecido6656
fonte
0

PHP, 199 bytes

foreach([User,Group,Others]as$i=>$u){$a=[];foreach([Read,Write,Execute]as$k=>$s)if($argv[1][$i]&4>>$k)$a[]=$s;$a[]=($x=array_pop($a))?$a?"and $x":"$x only":None;echo str_pad("\n$u:",9).join(" ",$a);}

PHP, 189 bytes com \ t

foreach([User,Group,Others]as$i=>$u){$a=[];foreach([Read,Write,Execute]as$k=>$s)if($argv[1][$i]&4>>$k)$a[]=$s;$a[]=($x=array_pop($a))?$a?"and $x":"$x only":None;echo"\n$u:\t".join(" ",$a);}
Jörg Hülsermann
fonte
Ei, você deve usar espaços em vez de tabulações
Beta Decay
Nesse caso, parece str_repeat ("", 3- $ i) ou str_pad ("", 3- $ i, ""), mas não importa com a minha ideia, não tenho chance de ganhar. outro espaço cs.tut.fi/~jkorpela/chars/spaces.html
Jörg Hülsermann
1
13 + 34 bytes para salvar. Na versão longa: use em echo str_pad("$u:",8)vez de echo"$u:".str_repeat(" ",3-$i)(-9); isso torna $i=>obsoleto (-4). Nas duas versões: use em $a[$z-1]="and $a[$z-1]";vez de {$a[]=$a[$z-1];$a[$z-1]="and";}(-7) e em else$a[]=$a?Only:None;vez de elseif($z<1)$a[]=None;else$a[]=Only;(-14). Transforme-se if(1<$z=count($a))$a[$z-1]="and $a[$z-1]";else$a[]=$a?Only:None;em if($x=array_pop($a))$a[]=$a?"and $x":"$x Only";else$a[]=None;(-3) e depois em $a[]=($x=array_pop($a))?$a?"and $x":"$x Only":None;(-10)
Titus
@Titus echo str_pad ("$ u:", 8), $ a [$ z-1] = "e $ a [$ z-1]" ;, else $ a [] = $ a? Somente: nenhum; Concluído $ i => obsoleto Eu não posso fazer, então $ m = $ argv [1] [$ i] é necessário. De resto, tentaria primeiro de outra maneira. Obrigado para a entrada
Jörg Hülsermann
1
Mais ideias: if(4&$m=$argv[1][$i])em vez de $m=$argv[1][$i];if(4&$m)(-3) OU substitua $m=;if();if();if();com um loop: foreach([Read,Write,Execute]as$k=>$s)if($argv[1][$i]&4>>$k)$a[]=$s;(-7)
Titus
0

Python 3, 191 bytes

def d(n):a,b,c,d,e=' and ',' only',"Execute","Write","Read";l=["None",c+b,d+b,d+a+c,e+b,e+a+c,e+a+d,e+" "+d+a+c];y,u,i=map(int,n);return"User:   %s\nGroup:  %s\nOthers: %s\n"%(l[y],l[u],l[i])

destroçado

def d(n):
    a,b,c,d,e=' and ',' only',"Execute","Write","Read"
    l=["None",c+b,d+b,d+a+c,e+b,e+a+c,e+a+d,e+" "+d+a+c]
    y,u,i=map(int,n)
    return"User:   %s\nGroup:  %s\nOthers: %s\n"%(l[y],l[u],l[i])
Aleksandr Smirnov
fonte
1
Bem-vindo ao PPCG! bom primeiro post!
Rɪᴋᴇʀ
Hmm, estou muito curioso para saber como o moderador obteve 151 bytes quando só tenho 191: D É um erro? Verifique edições
Aleksandr Smirnov
Fui eu, desculpe. Eu digitei na edição. Corrigido agora.
Rɪᴋᴇʀ
0

Javascript (ES6), 159 bytes

a=>`User:  ${(b=[' None',(c=' Execute')+(d=' only'),(e=' Write')+d,f=e+(g=' and')+c,(h=' Read')+d,h+g+c,h+g+e,h+f])[a[0]]}\nGroup: ${b[a[1]]}\nOthers:`+b[a[2]]

Exemplo:

(a=>`User:  ${(b=[' None',(c=' Execute')+(d=' only'),(e=' Write')+d,f=e+(g=' and')+c,(h=' Read')+d,h+g+c,h+g+e,h+f])[a[0]]}\nGroup: ${b[a[1]]}\nOthers:`+b[a[2]])("042")
Ian
fonte