Décoder le chmod


26

Défi

Étant donné un nombre d'autorisations octal à trois chiffres, affichez les autorisations qu'il accorde.

chmod

Sous UNIX OS, les autorisations de fichier sont modifiées à l'aide de chmod commande. Il y a peu de façons différentes d'utiliser chmod, mais celle sur laquelle nous nous concentrerons aujourd'hui utilise les autorisations octales.

Les trois chiffres du numéro d'autorisation représentent une personne différente:

  • Le premier chiffre représente les autorisations pour l' utilisateur
  • Le deuxième chiffre représente les autorisations pour le groupe
  • Le dernier chiffre représente les autorisations pour les autres

Ensuite, chaque chiffre représente une autorisation comme indiqué ci-dessous dans:

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

Contribution

L'entrée sera le nombre à trois chiffres sous forme de chaîne, par exemple:

133

ou

007

Cela sera transmis via STDIN ou via des arguments de fonction.

Sortie

Votre sortie doit être les différentes autorisations pour chacun des utilisateurs, le groupe et les autres. Vous devez afficher ces informations comme suit:

User:   ddd
Group:  ddd
Others: ddd

Où il y a trois espaces après User, deux espaces après Groupet un espace après Others. Vous remplacez dddpar les informations sur les autorisations.

Votre sortie peut être vers STDOUT ou sous forme de chaîne renvoyée.

Exemples

Entrée: 666

Sortie:

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

Entrée: 042

Sortie:

User:   None
Group:  Read only
Others: Write only

Entrée: 644

Sortie:

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

Gagnant

Le code le plus court en octets gagne.


Quelles sont les spécifications de l'entrée?
Jonathan Allan

@JonathanAllan Juste le nombre à trois chiffres
Beta Decay

Vous voulez dire comme un entier décimal uniquement, donc 042 serait reçu comme 42?
Jonathan Allan

2
@Jonathan Non, c'est une entrée de chaîne donc ce serait 042
Beta Decay

1
La sortie semble correcte avec un caractère de tabulation, alors pourquoi ne pas l'utiliser? Juste aux langues pénales qui ont besoin de plus d'octets pour remplir une chaîne?
Titus

Réponses:


3

05AB1E , 89 87 octets

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

Invoque l' encodage Cthulhu . Utilise l' encodage CP-1252 . Essayez-le en ligne!


14

Javascript (ES6), 165 161 octets

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

Modifier: +1 octet pour respecter la règle "sans tabulation"

Exemples

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


Vous pouvez gagner quelques octets en réorganisant le tableau (et peut-être en séparant les nombres des chaînes). +1 pour l'idée.
Titus

@Titus - Je dois admettre que je n'arrive pas à voir un réarrangement qui enregistre quelques octets. En outre, les nombres doivent être traités comme des chaînes afin que cela replace()fonctionne sans contrainte. Mais je manque peut-être votre point.
Arnauld

@Titus - Quelque chose comme ça 'User3Group68Others58None576Read48Write476Execute475and4576only'.split(/(\d+)/)pourrait fonctionner. Est-ce ce que tu avais en tête?
Arnauld

Je les comprenais mal; pensaient qu'il s'agissait de valeurs octales. :) Mais votre nouvelle idée n'est pas mauvaise non plus.
Titus

La sortie de défi nécessite des espaces au lieu des tabulations telles qu'elles sont actuellement écrites.
Mwr247

13

GNU sed, 187163 (157 + 1) octets

Exécutez avec -r (expression rationnelle ERE). Le fichier ne contient aucune nouvelle ligne de fin.

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

Belle approche mais vous pouvez économiser environ 20 octets en supprimant les chiffres lorsque vous ajoutez le andou only.
Neil

@Neil there :) a incorporé votre suggestion pour une sauvegarde très importante.
FireFly

1
La première ligne pourrait être juste: s/(.)(.)/User: \1\nGroup: \2\nOthers: /. Quelques octets supplémentaires pourraient être enregistrés en portant sur Perl, qui a \det \K.
ninjalj

@ninjalj bon point. Je m'en tiendrai à sed car je ne connais pas Perl, et je suis sûr qu'il y aurait d'autres astuces à tirer pour le rendre encore plus court, en dehors des remplacements s ///.
FireFly

6

C # 214 octets

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']}";}

6

Gelée , 100 91 85 octets

Presque certainement jouable au golf - 91 octets, quoi?! 8 mois et 6 octets de sagesse!
- 1. plus de compression de cordes;
- 2. supprimer le décrément post-ordinal de 48 car l'indexation est modulaire;
- 3. utiliser un meilleur chaînage tacite).

-9 octets avec l'aimable aide de @Lynn exécutant des compressions de chaînes pour moi

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

Testez-le sur TryItOnline

Comment?

,“£ɱ~» - 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

4

Octave, 185 octets

@(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})

Créez une fonction anonyme qui prend l'entrée sous forme de chaîne: '042'. Convertir à un tableau: (56-'042)' = [0 4 2]. Utilisez-le comme plusieurs indices de cellule pour indexer le tableau de cellules avec Read Write and Execute','Read and Write', .... Les utilisations fprintfà produire les trois chaînes, avec les catégories appropriées: User:, Group:et Others:.

J'ai essayé de trouver un moyen de stocker Execute, Write,Read comme des mots séparés et concaténer au besoin, mais se sont avérés plus que l'approche naïve.

Exemples:

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

Essayez-le en ligne.


2
Vous pouvez enregistrer quelques octets en utilisant strsplit('Read Write and Execute*Read and Write*Read and Execute*Read only*Write and Execute*Write only*Execute only*None','*')au lieu du littéral de tableau de cellules
Luis Mendo

4

PowerShell v2 +, 189168 octets

[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]]}

Boucle à travers l'entrée $args[0]sous forme de chartableau. Chaque itération, nous index dans un tableau avec $i++(par défaut 0) pour sélectionner User, GroupouOthers , concaténer que par deux points et une languette, et que concaténer avec un autre indice de tableau.

Voici la magie. Nous transcrivons implicitement le chardans un intet soustrayons 48(c'est-à-dire, transformons ASCII 48( "0") en 0), en choisissant la formulation appropriée comme un tableau de ints. Ce tableau est ensuite utilisé comme index dans le 'None','Read','Write','Execute','only','and'tableau. Depuis la valeur par défaut$ofs (Output Field Separator) est un espace, cela insère correctement les espaces entre les éléments du tableau lors de la chaîne (ce qui se produit lorsqu'il concatène à gauche).

Ces trois chaînes sont laissées sur le pipeline et sorties via implicite Write-Output se produit à la fin du programme.

Exemple

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

3

Paille , 193 octets

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

Essayez-le en ligne

Appuyez 3 fois sur une table de conversion sur la première pile, passez à la deuxième pile, convertissez chaque nombre à l'aide de la table de conversation et imprimez.


2

Haskell, 186 octets

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

Exemple:

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

Seul Prelude a été utilisé. Suis-je en train de faire ça?

Non golfé:

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

2

Python 2, 190 185 octets

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])]

Laisse un espace de fin si Execute ou Write sont à la fin de la ligne mais je n'ai pas vu que cela n'était pas autorisé.

EDIT Sauvegardé 5 octets en changeant la plage (3) à 0,1,2 et en vérifiant le nombre d'octets sur mon ordinateur portable Linux au lieu de mon ordinateur Windows (\ n = \ r \ n ou l'inverse. Je ne me souviens jamais lequel).


2

Python 2, 240 239 238 237 228 octets

J'ai pensé que j'allais enfin essayer ce golf froid. Espérons que les espaces vides soient autorisés. (corrigé, et dans le processus enregistré un octet)

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

Bienvenue chez PPCG, et belle première réponse!
ETHproductions

J'ai sans vergogne remplacé la plage (3) dans ma réponse Python 2 à 0,1,2 après avoir lu votre code. Bonne réponse. +1
ElPedro

2

PHP, 169 159 octets

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]," ";}

prend la chaîne comme argument de ligne de commande: php -r '<code>' <argument> ,
imprime un premier saut de ligne au lieu d'une fuite

Merci à Jörg d'avoir signalé mes bugs - et pour le \t .

PHP, 169 octets

avec la nouvelle restriction: (caractère de tabulation interdit)

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];}

C'est 1 octet plus court qu'avec str_pad, à cause du blanc supplémentaire qu'il nécessiterait.

panne

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
}

Pour créer le tableau pour $n, utilisez ceci:

$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,";}

1
foreach (['User', 'Group', 'Others'] as $ i => $ u) {echo "\\ n $ u: \\ t"; enregistre quelques octets et la sortie pour 3,4,6 est incorrecte
Jörg Hülsermann

1
C'est le bon ordre [5,33,34,66,35,67,131,531] bonne idée
Jörg Hülsermann

J'ai oublié "Utilisateur" à Utilisateur pour enregistrer par exemple les 6 prochains octets que vous voulez battre JavaScript
Jörg Hülsermann

@ JörgHülsermann: J'étais sur le point d'adopter le "\ t" de toute façon; Merci. +1 pour ça :) Bon oeil sur le 33!
Titus

1
pour 346, notre sortie est Utilisateur: Groupe de lecture et d'écriture: Exécuter uniquement Autres: Écriture et exécution il doit Utilisateur: Écriture et exécution de groupe: Lecture seule Autres: Lecture et écriture
Jörg Hülsermann

2

bash - 221 213 octets

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]}";}

On ne sait pas encore si cela peut être condensé, du moins pas sans changer fondamentalement l'approche ici (fractionner l'entrée et l'utiliser comme index du tableau ${b}qui contient les chaînes correspondantes).


1
Il est plus court avec \ onlyune ligne élargie. grep -o .<<<$1est plus court que echo $1|grep -o ., mais il while read -n1 cest préférable de lire l'entrée de stdin avec . Les index de tableau ont un contexte arithmétique dans bash, donc ça ${l[z++]}marche. lserait plus court comme une chaîne, qui serait accessible en tant que ${l:z++*8:8}(décalage et longueur ont un contexte arithmétique). Un autre octet peut être affiché en lisant l'intégralité du mode dans c, en développant "User:", ... en ligne et en utilisant judicieusement les extensions de paramètres.
ninjalj

1
Pour un résultat 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}]}"(remplacez \ n par des retours à la ligne littéraux).
ninjalj

1

Java 7, 300 284 octets

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

Approche directe pour l'instant. J'essaierai de trouver une approche plus générique pour réutiliser les mots.

Cas non testés et testés:

Essayez-le ici.

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

Sortie:

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

1

Groovy, 217 207 205 octets

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])}}

non golfé:

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])
  }
}

1

Mathematica, 211 octets

{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}&

Une implémentation simple (probablement facilement battable): ne calcule rien, juste code dur chaque sortie possible. L'entrée est un entier; sort chaque ligne avec un espace de fin et une nouvelle ligne de fin globale.

IntegerDigits[#,10,3]donne les trois chiffres de l'entrée (même s'il y a des zéros en tête). Chaque chiffre indique un argument de la "fonction"

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

avec 0 indiquant le nom de la fonction elle-même. ""<>concatène toutes les chaînes d'une liste (de listes). "\n"&~Array~3produit les trois nouvelles lignes.


Je viens de remarquer que ma réponse Python 2 est presque identique à la vôtre, même en utilisant les mêmes noms de variables. Honnêtement, je n'avais pas vu le vôtre avant de poster!
ElPedro

1
pas de soucis! Je pense que la correspondance des noms de variables est à peu près à prévoir dans cette situation :)
Greg Martin

Je suppose que tu as raison. Les noms des variables étaient un peu prévisibles ☺
ElPedro

btw, +1 cos nous pensons de la même façon :-)
ElPedro

1
btw, je ne connais pas Mathematica mais je pense que vous pourriez perdre un octet en supprimant l'espace de "seulement". Il sera toujours à la fin d'une ligne et n'a donc pas besoin d'espace de fin.
ElPedro

1

Java 7, 278

Golfé:

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;}

Non golfé:

  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;
  }

Sortie:

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

1

Python 3.5, 3,6 - 235 232 228 216 216 octets

(devrait fonctionner sur tous les Python 3.x)

Donc, l'entrée est sur STDIN ici (enregistre une importation ☺).

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

Utiliser des tuples, en omettant les espaces lorsque cela est possible et la priorité de l'opérateur où vous mettriez normalement des parenthèses pour clarifier vos intentions.

Exemple d'utilisation:

$ 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

Non-golfé:

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

1

Lot, 280 octets

@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

Le codage en dur des chaînes était 47 octets plus court que d'essayer de les assembler. Aurait été de 267 octets si les tabulations étaient légales.


1

C # 307 241 210 octets

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])));}

Formaté

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])));
}

1

C #, 322 337 348 octets

Ce n'est certainement pas la version la plus courte, mais j'ai essayé de résoudre ce problème en utilisant des opérateurs au niveau du bit car les chmodvaleurs sont en fait des indicateurs de bit. De plus, C # n'est probablement pas le meilleur langage de golf: 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')));}

non golfé: (avec commentaires)

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
}

C'est mon premier code de golf, alors dites-moi si j'ai mal fait :)

EDIT 1:

Enregistré quelques octets en remplaçant s[i]-'0'par s[i]&7(à la toute fin) et en enregistrant le nombre de listes dans la variable:

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:

Modifié en expression 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)));}

1

Javascript, 213 209 208 188 186 octets

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]]}

Économisé 20 octets grâce à Dada!


3
Je peux me tromper, mais votre tableau ne devrait-il pas être dans l'ordre inverse? Si j'appelle b ("000"), il renvoie "Lire, écrire et exécuter" alors que l'on peut s'attendre à "Aucun" ...
Dada

Et je suis presque sûr que cela pourrait être plus joué. Par exemple, une version 191 octets: 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 octets

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

1
Bienvenue chez PPCG! Belle première réponse BTW :)
Beta Decay

1

Cristal, 200 194 octets

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

renvoie la chaîne résultante pour une séquence octale donnée sous forme de chaîne. par exemple:m("670") résultats à: User: Read and Write\nGroup: Read Write and Execute\nOthers: None.

Essayez-le en ligne .


0

C #, 371 octets

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

4
Il s'agit de code-golf, vous devez donc jouer à votre code. Ajoutez également un en-tête avec le nom de la langue et le nombre d'octets.
TuxCrafting

J'ai ajouté votre nombre d'octets, qui est votre score. Vous devez obtenir votre score le plus bas possible pour gagner
Beta Decay

Par exemple, vous vous débarrassez de tous les espaces inutiles dans chaque fonction
Beta Decay

1
@BetaDecay Merci, je suis nouveau dans cette communauté et je pense que je ferais mieux d'utiliser php à la place, ce qui pourrait conduire à des codes plus compacts.
Alireza Tabatabaeian

1
@Alireza C'est une bonne idée. Bien que sur ce site, nous aimons voir des réponses courtes en Java et C # :)
Beta Decay

0

Python 3,5 - 370 294 243 octets

Golfé:

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])

Vérification de la taille:

$ du -b OctalToHuman.py 
243     OctalToHuman.py

Non-golfé:

#!/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])

Exemple de sortie:

$ 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

Ce n'est pas un concurrent sérieux pour les critères gagnants. Nous avons besoin de toutes les réponses pour tenter sérieusement d'optimiser leur score pour les critères gagnants (par exemple, dans les défis de golf de code comme celui-ci, les soumissions doivent faire un effort sérieux pour minimiser le nombre d'octets du programme).
Mego

Vous pouvez économiser quelques octets en supprimant import syset en faisant simplement du programme une fonction anonyme ( lambda o:...).
NoOneIsHere

0

F #, 204 203 octets

mon premier golf, alors pardonnez toutes les erreurs;)
La version golfée (basée 1: 1 sur la réponse 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

La version non golfée:

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

Exemple d'utilisation:

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

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


C'est uniquement pour vérifier si je pouvais "améliorer" la réponse de pinkfloydx33 - je ne prends aucun crédit pour l'algorithme


0

PHP, 199 octets

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 octets avec \ 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);}

Hé, vous devriez utiliser des espaces au lieu des tabulations
Beta Decay

Dans ce cas, \ t ressemble à str_repeat ("", 3- $ i) ou str_pad ("", 3- $ i, "") mais peu importe mon idée, je n'ai aucune chance de gagner. Si je devais prendre un autre espace cs.tut.fi/~jkorpela/chars/spaces.html
Jörg Hülsermann

1
13 + 34 octets à sauvegarder. Dans la version longue: utilisez echo str_pad("$u:",8)au lieu de echo"$u:".str_repeat(" ",3-$i)(-9); cela rend $i=>obsolète (-4). Dans les deux versions: utilisez $a[$z-1]="and $a[$z-1]";au lieu de {$a[]=$a[$z-1];$a[$z-1]="and";}(-7) et else$a[]=$a?Only:None;au lieu de elseif($z<1)$a[]=None;else$a[]=Only;(-14). Transformez if(1<$z=count($a))$a[$z-1]="and $a[$z-1]";else$a[]=$a?Only:None;en if($x=array_pop($a))$a[]=$a?"and $x":"$x Only";else$a[]=None;(-3) puis en $a[]=($x=array_pop($a))?$a?"and $x":"$x Only":None;(-10)
Titus

@Titus echo str_pad ("$ u:", 8), $ a [$ z-1] = "et $ a [$ z-1]" ;, sinon $ a [] = $ a? Seulement: Aucun; Fait $ i => obsolète je ne peux pas faire alors $ m = $ argv [1] [$ i] est nécessaire. Pour le reste, j'essaierais d'abord d'une autre manière. Merci pour la contribution
Jörg Hülsermann

1
Plus d'idées: if(4&$m=$argv[1][$i])au lieu de $m=$argv[1][$i];if(4&$m)(-3) OU remplacez $m=;if();if();if();par une boucle: foreach([Read,Write,Execute]as$k=>$s)if($argv[1][$i]&4>>$k)$a[]=$s;(-7)
Titus

0

Python 3, 191 octets

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])

non golfé

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])

1
Bienvenue chez PPCG! joli premier post!
Rɪᴋᴇʀ

Hmm, je suis très curieux de savoir comment le modérateur a obtenu 151 octets alors que je ne reçois que 191: D Est-ce une erreur? Vérifications des chèques
Aleksandr Smirnov

C'était moi, désolé. J'ai fait une faute de frappe dans l'édition. Fixé maintenant.
Rɪᴋᴇʀ

0

Javascript (ES6), 159 octets

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

Exemple:

(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")
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.