Écrire un programme qui inverse le nom de son fichier source


27

Dans un seul fichier, écrivez un programme qui ne nécessite aucune entrée et ne produit aucune sortie. Lorsqu'il est exécuté, il doit inverser le nom du fichier dans lequel il se trouve, quel que soit son nom , sans altérer le code ni produire d'autres effets secondaires durables.

Tout moyen d'y parvenir est très bien. Il importe seulement qu'une fois le programme exécuté, le seul changement durable soit que son nom de fichier ait été inversé. par exemple, aucun nouveau fichier ne doit se trouver dans le répertoire.

Réexécuter le programme devrait inverser le nom. En effet, le programme devrait pouvoir être exécuté arbitrairement plusieurs fois.

Aux fins de ce défi:

  • Vous pouvez supposer que les noms de fichiers sont toujours des chaînes de lettres minuscules (az) de 1 à 127 caractères. (Si votre langue nécessite que les fichiers aient des extensions pour s'exécuter, inversez simplement la partie avant l'extension, par exemple mycode.batedocym.bat.)
  • Vous pouvez supposer que le fichier de code se trouve dans un répertoire lui-même afin qu'il n'ait pas de conflits de dénomination (sauf avec lui-même).
  • Vous ne pouvez pas supposer que le nom de fichier n'est pas un palindrome, c'est-à-dire le même lorsqu'il est inversé. Les noms de fichiers qui sont des palindromes devraient fonctionner aussi bien que ceux qui ne le sont pas.
  • Vous pouvez lire le contenu ou les métadonnées de votre fichier. Il n'y a aucune restriction de ici.
  • Vous pouvez supposer que votre programme sera exécuté sur un système d'exploitation courant particulier, moderne (par exemple Windows / Linux), car tous les shells n'ont pas le même jeu de commandes.

Par exemple, disons que vous avez un programme Python dans un fichier appelé mycodedans son propre répertoire. Fonctionnement

python mycode

dans le terminal devrait entraîner une inversion du nom de fichier edocym. Le fichier edocymdoit être seul dans son répertoire - aucun fichier nommé mycodene doit plus exister. Fonctionnement

python edocym

inversera le nom mycode, auquel cas le processus peut être répété indéfiniment.

Si le même fichier Python a été renommé racecar(sans changer le code), puis exécutez

python racecar

rien ne devrait visiblement changer puisque "racecar" est un palindrome. Il en va de même si le nom de fichier était, disons, aou xx.

Le code le plus court en octets gagne. Tiebreaker est la réponse la plus votée.


Le répertoire de travail actuel est-il important?
Brad Gilbert b2gills

@ BradGilbertb2gills Vous devriez être en mesure de copier le dossier avec le programme ailleurs et de le faire fonctionner (en supposant que vous ayez les autorisations et ainsi de suite). Vous pouvez supposer que le répertoire de travail du shell sera le dossier dans lequel se trouve le fichier.
Calvin's Hobbies

6
Et si nous utilisons un langage compilé? Comment l'exécutable affecte-t-il vos règles?
EMBLEM

Demande de clarification «n'accepte aucune entrée et ne produit aucune sortie». Techniquement, le nom du fichier est une entrée qui ne doit pas être récupérée du système de fichiers et le nom modifié doit être envoyé au système de fichiers. Ce sont des entrées et des sorties. Il peut être utile de spécifier qu'aucune autre sortie n'est autorisée.
atk

En outre, considérez-vous que l'utilisation de processus enfants constitue une violation des règles d'entrée / sortie? Autrement dit, appeler un processus distinct pour effectuer une partie de la tâche, comme inverser le nom, nécessiterait d'envoyer à l'autre processus le nom (sortie de votre code et entrée dans l'application) et recevoir la valeur du processus (sortie du processus et entrée dans l'application).
atk

Réponses:


41

Bash + utilitaires Linux communs, 13 octets

Ma méthode est similaire à celle de @ DigitalTrauma mais un peu plus courte en raison de la pipe avec ls:

mv * `ls|rev`

Oh très bien.
Digital Trauma

20
Bienvenue sur Programmation Puzzles & Code Golf! Ceci est une très bonne première réponse. :)
Alex A.

1
Fonctionne uniquement s'il n'y a pas d'autre fichier dans le répertoire.
WGroleau

1
@WGroleau && terdon: vos deux commentaires sont corrects mais la question gère déjà ces 2 hypothèses.
Julie Pelletier

@JuliePelletier ah, oui, vous avez tout à fait raison. J'ai raté que les noms de fichiers ne peuvent être composés que de lettres minuscules.
terdon

14

C #, 153 octets

void f(){var x=System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name;File.Move(x,new string(x.Reverse().ToArray()).Substring(4)+".exe");}

OO est cool et jusqu'à ce qu'une variable soit définie:

System.Reflection.Assembly.GetExecutingAssembly (). ManifestModule.Name

c'est juste dire


12

Bash + utilitaires Linux courants, 15

  • 1 octet enregistré grâce à @Dennis

Suppose que le script se trouve dans un répertoire lui-même.

mv * `rev<<<$0`

6
Vous pouvez supposer que le fichier de code se trouve dans un répertoire lui - même , il $0peut donc être remplacé par *.
Dennis

Désolé mais il y a un petit bug dans votre mise à jour et cela ne fonctionne pas tel quel. La solution la plus simple consiste à revenir plus près de ce que vous aviez auparavant avec $0au lieu du dernier *.
Julie Pelletier

@JuliePelletier Cela semblait fonctionner avant quand je l'ai essayé, mais oui, vous avez raison - * l'expansion de globbing ne se produit pas à la droite de a <<<.
Digital Trauma

7

Julia, 51 octets

d,f=splitdir(@__FILE__)
cd(d)do
mv(f,reverse(f))end

Ce programme devrait être indépendant du système d'exploitation, bien qu'il n'ait été testé que sur OS X.

Non golfé:

# Get the directory and file name of the current source file
d, f = splitdir(@__FILE__)

# Change the working directory temporarily to d
cd(d) do
    # Overwrite the file with the reverse of its name
    mv(f, reverse(f))
end

8
Félicitations! 20k !!!
Luis Mendo

La plupart des réponses semblent supposer que le fichier se trouve dans le répertoire courant, donc je ne pense pas que vous en ayez besoin cd. Dans ce cas, ce f=readdir()[]serait encore plus court.
Dennis

6

MATLAB, 50 46 octets

e='.m';x=mfilename;movefile([x e],[flip(x) e])

Merci à @Suever d'avoir supprimé 4 octets et pour les tests!

Testé sur OS X El Capitan et Debian Jessie, tous deux avec la version Matlab R2014a.

Sous Windows, un indicateur 'f'est nécessaire ( e='.m';x=mfilename;movefile([x e],[flip(x) e]),'f') pour modifier le nom du fichier lors de son utilisation.

Comment ça marche

e='.m';                       % Store file extension '.m' in variable `e`
x=mfilename;                  % Get name of file being run, without the extension
movefile([x e],[flip(x) e])   % Move (rename) file. `flip` is used for reversing the
                              % name without extension. [...] is (string) concatenation

Quel système d'exploitation utilisez-vous 'f'?
Suever

@Suever Windows. N'est-il pas nécessaire sur Mac?
Luis Mendo

Pas nécessaire sur Mac de Linux semble-t-il.
Suever

@Suever Merci! 4 octets de moins :-)
Luis Mendo

@Suever Pouvez-vous indiquer le système d'exploitation exact sur lequel cela fonctionne?
Luis Mendo

4

Rubis, 24 octets

File.rename$0,$0.reverse

Assez explicite. ( $0est le nom du fichier en cours d'exécution.)

Exécutez avec ruby whateverun répertoire de travail du répertoire qui contient le fichier.


4

Lot, 109 octets

@echo off
set f=%0
set r=
:l
set r=%f:~0,1%%r%
set f=%f:~1%
if not .%f%==. goto l
ren %0.bat %r%.bat

Remarque 1: les fichiers batch doivent se terminer par .bat; il est supposé que le fichier de commandes est exécuté par son nom sans extension et que le .batne doit pas être inversé. Par exemple, reversetenterait de renommer reverse.batà esrever.bat.
Remarque 2: CMD.EXEerreurs après avoir renommé le fichier de commandes. ( COMMAND.COMne le ferait pas, sauf qu'il est incapable de manipuler les chaînes en premier lieu.)

Edit: sauvé 2 octets en utilisant la garantie que le nom du fichier est alphabétique (basé sur le commentaire de @ CᴏɴᴏʀO'Bʀɪᴇɴ).


3
1. POURQUOI NE CRIEZ-VOUS PAS? 2. Je pense que vous pouvez enregistrer un octet en faisantif ]%f% NEQ ] goto l
Conor O'Brien

@ CᴏɴᴏʀO'Bʀɪᴇɴ Ah oui, le nom du fichier est alphabétique, donc je peux en fait économiser 2 octets, mais merci pour l'astuce.
Neil

1
VOUS DEVEZ CRIER EN LOT À MOINS QUE VOUS UTILISEZ OOBL AKA SMALLTALK-80
cat

4

C, 102 octets

main(c,v)char**v;{char*b=strdup(*v),*n=strrchr(*v,47),*t=strchr(b,0);for(;*++n;*--t=*n);rename(*v,b);}

Panne:

                            // No #include lines required (for GCC at least)
main(c,v)char**v;{          // K&R style function to save 2 bytes
    char*b=strdup(*v),      // Duplicate args[0] (script path)
        *n=strrchr(*v,47),  // Find last "/" in input
        *t=strchr(b,0);     // Go to end of output string
    for(;*++n;*--t=*n);     // Reverse input into output character-by-character
    rename(*v,b);           // Rename the file
}                           // Implicit return 0

Enfin un défi où C n'est pas (tout à fait désespérément) non compétitif!


Si l' on prend « Vous pouvez supposer le répertoire de travail de la coquille sera le dossier que le fichier est » pour signifier que le programme sera toujours invoquée ./myexecutable, nous pouvons simplifier *n=strrchr(*v,47)pour *n=*v+1sauver 10 caractères, mais ce n'est pas tout à fait valable ( elle pourrait être invoquée ././myexecutablepar exemple).


De plus, si vous souhaitez conserver une extension de fichier (par exemple ".out") intacte, vous pouvez modifier *t=strchr(b,0) à *t=strrchr(b,46), coûtant 2 octets. Pas obligatoire cependant.


Sympa - je n'avais jamais cherché à voir ce renamequi se passait si src == dest; il semble que vous satisfaisiez gratuitement la contrainte palindrome.
Toby Speight

Notez que cela nécessite un système de fichiers où le point de code 47 est le séparateur. Je pense que cela inclut POSIX (ou cela permet-il EBCDIC /dans un cas d'angle?)
Toby Speight

@TobySpeight ouais j'ai vérifié gnu.org/software/libc/manual/html_node/Renaming-Files.html pour des éclaircissements, mais le plus proche que j'ai trouvé était "Un cas spécial pour renommer est quand oldname et newname sont deux noms pour le même fichier . La manière cohérente de gérer ce cas est de supprimer l'ancien nom. Cependant, dans ce cas, POSIX exige que le changement de nom ne fasse rien et signale le succès — ce qui est incohérent. Nous ne savons pas ce que fera votre système d'exploitation. ", Donc je suppose qu'il y a une chance extérieure, il supprimera simplement le fichier sur les systèmes non compatibles POSIX. Alors oui, le vrai code devrait vérifier!
Dave

Je viens de vérifier linux.die.net/man/3/rename et cela confirme que Linux le gère conformément à POSIX: "Si l'ancien argument et le nouvel argument se résolvent dans le même fichier existant, rename () retournera avec succès et n'effectuera aucune autre action."
Dave

J'allais avec la page de manuel Debian: "Si oldpathet newpathsont des liens durs existants se référant au même fichier, alors rename()ne fait rien et retourne un état de réussite" - si les chaînes sont identiques, elles se réfèrent au même fichier.
Toby Speight

3

Vitsy + * sh, 15 octets

iG:`?r.iG' mr',

Explication

iG:`?r.iG' mr',
i               Push -1 to the stack. (this assumes that no arguments are passed)
 G              Get the use name of the class specified by the top item of the
                stack. (-1 refers to the origin class, so this class)
  :             Duplicate stack and jump to it.
   `            Read a file with the current stack as its name, replacing the stack
                with the file's contents.
    ?           Shift one stack to the right.
     r          Reverse the current stack.
      .         Write a file with the name specified by the top stack and the
                contents as the second-to-top stack.
       iG       Get the name of the current class again.
         ' mr'  Push 'rm ' to the stack.
              , Execute the current stack as a command.

Notez que cette soumission doit utiliser la version non sûre de Vitsy (ne peut pas être effectuée sur Try It Online!)


3

Perl 5, 18 octets

Un peu comme celui de Ruby (run perl nameofscript):

rename$0,reverse$0

La prise en compte d'un chemin possible est plus laide (47 octets)

($a,$b)=$0=~/(.*\/)?(.*)/;rename$0,$a.reverse$b

1
Bonjour et bienvenue chez PPCG! Excellent premier post!
NoOneIsHere

2

V , 29 26 octets

:se ri
izyw:!mv z "
dd

Puisqu'il contient des non imprimables, voici un vidage hexadécimal:

00000000: 3a73 6520 7269 0a69 127a 1b79 773a 216d  :se ri.i.z.yw:!m
00000010: 7620 127a 2012 220a 6464                 v .z .".dd

Remarque: cela ne fonctionnera pas sur v.tryitonline.net car TIO n'autorise pas l'accès aux fichiers.

Explication:

:se ri            "Turn on 'reverse mode' (all text is inserted backwards)
i<C-r>z<esc>      "Enter the path to the file in reverse
yw                "Yank a word. This first word is the name we will save the new file as

"Run an "mv" in the terminal with the contents of register 'z' (the path to the file)
"And the contents of register '"' (the word we yanked)
:!mv <C-r>z <C-r>"

dd                "Delete a line so that we don't have any text printed.

2

Python 3, 105 octets

import os;a=__file__.split('\\')[::-1][0].split('.');os.rename('.'.join(a),'.'.join([a[0][::-1],a[1]]))

-Alex.A a supprimé 1 octet.

-Digital Trauma m'a montré os.rename () qui a enlevé 62 octets.

-muddyfish a supprimé 7 octets.


Je pense que vous pouvez économiser un octet en supprimant l'espace après la virgule dans leimport
Alex A.

import os,sys;f=sys.argv[0];os.rename(f,f[::-1])devrait faire l'affaire pour 48 octets
Digital Trauma

faire f [:: - 1] inverse non seulement le nom du fichier, mais le chemin complet. Cependant, merci de m'avoir présenté la fonction os.rename ().
Magenta

@Magenta Pour moi, sys.argv[0]retourne simplement le nom de fichier uniquement sans le chemin lorsque le script est exécuté directement. Helka a indiqué que tout allait bien
Digital Trauma

@DigitalTrauma lorsque j'ai exécuté le programme seul, sys.arg [0] a renvoyé le chemin complet. Je vais ajouter une deuxième solution où sys.argv [0] est juste le nom de fichier.
Magenta

2

PHP, 84, 70, 54 octets

rename($f=__FILE__,strrev(basename($f,$e='.php')).$e);


EDIT: supprimé 14 octets grâce aux insertusernameherecommentaires
EDIT: supprimé 16 octets grâce aux Martijncommentaires


2
Vous pouvez obtenir jusqu'à 70 octets : rename($f=__FILE__,__DIR__."/".strrev(pathinfo($f)[filename]).".php");.
insertusernamehere

Excellent !!! mais votre code c'est mieux, wow vous avez 31 octets
tttony

Tu ne peux pas le rendre relatif? WOuld enregistrer 7 octets:rename($f=__FILE__,"./".strrev(pathinfo($f)[filename]).".php");
Martijn

ou encore plus petit:rename(__FILE__,strrev(basename(__FILE__,'.php')).'.php');
Martijn

Cool! Ajout de vars, j'ai maintenant 54 octets
tttony

2

PowerShell, 39 octets

mi *(-join((ls).name)[-5..-999]+'.ps1')

Bonjour et bienvenue chez PPCG! Bon premier post!
Rɪᴋᴇʀ

2

Python 2 , 41 octets

import os;s=__file__;os.rename(s,s[::-1])

Démo sur Bash.

Python ne se soucie vraiment pas de l'extension du fichier, nous pouvons donc simplement retourner le nom complet du fichier.



1

Perl 6 ,  70   27 octets

S'il devait fonctionner dans un répertoire de travail différent, vous auriez besoin de quelque chose comme ceci:

$_=$*PROGRAM;.rename: .basename.flip.IO.absolute: .absolute.IO.dirname

Puisque le répertoire de travail sera le même répertoire que le programme, il peut être simplifié simplement:

$_=$*PROGRAM;.rename: .flip

Explication:

$_ = $*PROGRAM;  # IO::Path object

$_.rename:
    $_.basename
      .flip      # reverse characters
      .IO        # turn into an IO object (IO::Path)
      .absolute: # turn it into an absolute path Str in the following dir
        $_.absolute.IO.dirname

1

JavaScript (Node), 108 104 68 octets

36 octets économisés, grâce à Downgoat!

Version Windows:

require("fs").rename(F=__filename,F.split(/.*\\|/).reverse().join``)

Autre version:

require("fs").rename(F=__filename,F.split(/.*\/|/).reverse().join``)

@Upgoat Je n'en ai pas besoin, je ne pense pas. Je fais correspondre jsà la fin du chemin de fichier, précédé d'un caractère. Ce sera toujours un ..
Conor O'Brien

1

JavaScript ES6 (Node.js) 70 octets

Pas de Regex Yay!

require("fs").rename(a=__filename,[...a].reverse().join``.split`/`[0])

Toute aide est appréciée


1

PowerShell v4 +, 68 octets

$a,$b=($c=(ls).Name)-split'\.';mv $c "$(-join($a[$a.length..0])).$b"

Fonctionne uniquement parce que le script est garanti d'être dans un répertoire à lui tout seul. Effectue un ls(alias pour Get-ChildItem) et prend le ou .Nameles objets résultants. Nous stockons cela dans $cet ensuite -splitsur période littérale pour obtenir le nom de fichier et l'extension, et stockons ceux-ci dans $aet $b, respectivement.

Vient ensuite la commande mv(alias pour Move-Item), où nous passons $cà $a(inversé) .$b.

Exemple

PS C:\Tools\Scripts\golfing\reverse> ls

    Directory: C:\Tools\Scripts\golfing\reverse

Mode                LastWriteTime     Length Name
----                -------------     ------ ----
-a---         6/13/2016   7:58 AM         88 reverse.ps1

PS C:\Tools\Scripts\golfing\reverse> .\reverse.ps1

PS C:\Tools\Scripts\golfing\reverse> ls

    Directory: C:\Tools\Scripts\golfing\reverse

Mode                LastWriteTime     Length Name
----                -------------     ------ ----
-a---         6/13/2016   7:58 AM         88 esrever.ps1

1

Python (2,7 ou 3,4+), 61 49 octets

Je crois que cela est proche de la solution Python optimale:

import os;a=__file__;os.rename(a,a[-4::-1]+".py")

Inspiré par s4b3r6la réponse de, mais utilise le découpage de liste au lieu de l'inverse et enregistre __file__dans une variable pour enregistrer les octets lors de son utilisation double.

Remarque: Cela suppose que le nom de fichier est toujours *.py. Une solution légèrement plus générique qui peut gérer n'importe quelle extension de fichier à deux caractères serait d'utiliser a[-3:]pour remplacer ".py", au prix d'un octet supplémentaire.

Mise à jour: enregistré 12 octets en utilisant l'astuce de découpage de liste a[-4::-1]pour supprimer l'extension de fichier, au lieu de fractionner puis d'inverser avec a.split(".")[0][::-1].


1

Powershell, 112 octets

Je ne vais pas battre les cmds unix, juste ajouter mes deux pence pour le plaisir :-)

gci * | % { $n=($_.basename[-1..-(($_.basename).length)] -join “”)+$_.Extension; mv -Path $_.Fullname -Dest $n }

Bienvenue chez PPCG! Nous exigeons que les réponses affichent leur score, je l'ai donc édité pour vous. Vous pouvez également formater votre code en le mettant en surbrillance et en sélectionnant le bouton qui ressemble à des crochets {}, ou en ajoutant 4 espaces avant votre code.
FryAmTheEggman

0

PowerShell, 50 octets

mv *(-join($f=(ls).BaseName)[$f.Length..0]+'.ps1')

Il n'y a qu'un seul fichier, donc le mv *caractère générique du shell n'aura qu'un seul résultat. Le nom de destination est celui (ls).basenamequi répertorie tous les fichiers (alias pour 'dir'), appelle la propriété BaseName - et comme il n'y a qu'un seul fichier, PowerShell décompresse le tableau à 1 élément dans une chaîne. Stockez ce nom de fichier $f, puis indexez-le avec un compte à rebours et -joinles caractères inversés sont sauvegardés dans une chaîne. Ajoutez le .ps1suffixe obligatoire .


0

AutoIt, 45 octets

$a=@ScriptName
FileMove($a,StringReverse($a))

0

Python 2.7, 68 octets

importer os; a = __ fichier __; os.rename (a, a.split ("\\") [- 1] [: - 3] [:: - 1] + ". py")

C'est probablement le meilleur que je puisse obtenir. Je viens de me prouver que j'avais tort.


0

Python (2 et 3), 88 78 octets

import os;os.rename(__file__,''.join(reversed(__file__.split(".")[0]))+".py"))

Exploite le fait que le nom de fichier est donné par sys.argv (car le répertoire de travail est le dossier dans lequel se trouve le fichier) et utilise os.rename. De manière ennuyeuse, reverse renvoie un itérateur, nous devons donc utiliser join.

Edit: enregistré 10 octets en utilisant __file__ au lieu de sys.argv [0], comme suggéré par @muddyfish à @DigitalTrauma.



0

Script Visual Basic, 44 octets

WScript.Echo(StrReverse(WScript.ScriptName))

Exemple de sortie pour le fichier appelé reverse.vbs(Exécuter avec cscript):

sbv.esrever


0

SmileBASIC 60 octets

P$=PRGNAME$()FOR I=1-LEN(P$)TO.Q$=Q$+P$[-I]NEXT
RENAME P$,Q$

Alternative:

P$=PRGNAME$()T$=P$*1WHILE""<T$Q$=Q$+POP(T$)WEND
RENAME P$,Q$
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.