Scrivi un programma che inverte il nome del suo file sorgente


27

In un singolo file, scrivi un programma che non richiede input e non produce output. Quando eseguito, dovrebbe invertire il nome del file in cui è contenuto, indipendentemente dal nome , senza alterare il codice o produrre altri effetti collaterali duraturi.

Qualsiasi modo per raggiungere questo obiettivo va bene. Importa solo che una volta eseguito il programma l'unica modifica permanente è che il nome del suo file è stato invertito. ad es. nessun nuovo file dovrebbe essere nella directory.

Eseguire nuovamente il programma dovrebbe invertire il nome indietro. In effetti, il programma dovrebbe poter essere eseguito arbitrariamente molte volte.

Ai fini di questa sfida:

  • Puoi presumere che i nomi dei file siano sempre stringhe di lettere minuscole (az) tra 1 e 127 caratteri. (Se la tua lingua richiede l'esecuzione di estensioni per i file, inverti la parte prima dell'estensione, ad es . mycode.batedocym.bat.)
  • Puoi presumere che il file di codice sia in una directory da solo, quindi non avrà conflitti di denominazione (tranne con se stesso).
  • Si può non assumere il nome del file non è un palindromo, vale a dire lo stesso quando invertito. I nomi di file che sono palindromi dovrebbero funzionare altrettanto bene di quelli che non lo sono.
  • Puoi leggere il contenuto o i metadati del tuo file. Non ci sono restrizioni qui.
  • Si può presumere che il programma verrà eseguito su un sistema operativo particolare, moderno e comune (ad esempio Windows / Linux), poiché non tutte le shell hanno lo stesso set di comandi.

Ad esempio concreto, supponiamo di avere un programma Python in un file chiamato mycodenella sua directory. In esecuzione

python mycode

nel terminale dovrebbe comportare l'inversione del nome file edocym. Il file edocymdovrebbe trovarsi da solo nella sua directory - nessun file nominato mycodedovrebbe esistere più. In esecuzione

python edocym

ripristinerà il nome a mycode, a quel punto il processo può essere ripetuto indefinitamente.

Se lo stesso file Python è stato rinominato racecar(senza modificare il codice) e quindi eseguito

python racecar

nulla dovrebbe cambiare visibilmente poiché "racecar" è un palindromo. Lo stesso vale se il nome file fosse, diciamo, ao xx.

Vince il codice più breve in byte. Tiebreaker è la risposta più votata.


La directory di lavoro corrente è importante?
Brad Gilbert b2gills l'

@ BradGilbertb2gills Dovresti essere in grado di copiare la cartella con il programma da qualche altra parte e farlo funzionare ancora (supponendo che tu abbia i permessi e quant'altro). Puoi presumere che la directory di lavoro della shell sia la cartella in cui si trova il file.
Calvin's Hobbies

6
E se stiamo usando un linguaggio compilato? In che modo l'eseguibile influenza le tue regole?
EMBLEMA

Richiesta di chiarimento "non accetta input e non produce output". Tecnicamente, il nome del file è un input che deve essere recuperato dal file system e il nome modificato deve essere inviato al file system. Questi sono input e output. Potrebbe essere utile specificare che non sono consentite altre uscite.
att

Inoltre, ritieni che l'uso dei processi figlio sia una violazione delle regole di input / output? Cioè, chiamare un processo separato per eseguire parte dell'attività, come invertire il nome, richiederebbe di inviare all'altro processo il nome (output dal tuo codice e input all'app) e ricevere il valore dal processo (output del processo e input per l'app).
atk,

Risposte:


41

Bash + utility Linux comuni, 13 byte

Il mio metodo è simile a quello di @ DigitalTrauma ma un po 'più corto a causa della pipe con ls:

mv * `ls|rev`

Oh molto bene.
Digital Trauma,

20
Benvenuto in Programmazione di puzzle e codice golf! Questa è un'ottima prima risposta. :)
Alex A.

1
Funziona solo se non ci sono altri file nella directory.
WGroleau,

1
@WGroleau && terdon: entrambi i tuoi commenti sono giusti, ma la domanda gestisce già quei 2 presupposti.
Julie Pelletier,

@JuliePelletier ah, sì, hai perfettamente ragione. Ho perso che i nomi dei file possono consistere solo di lettere minuscole.
terdon,

14

C #, 153 byte

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

OO è interessante e fino a quando non hai definito una variabile:

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

questo è solo cattivo


12

Bash + utility Linux comuni, 15

  • 1 byte salvato grazie a @Dennis

Presuppone che lo script si trovi in ​​una directory da solo.

mv * `rev<<<$0`

6
Si può presumere che il file di codice sia in una directory da solo , quindi $0può essere sostituito con *.
Dennis,

Siamo spiacenti ma c'è un piccolo bug nel tuo aggiornamento e non funziona così com'è. La soluzione più semplice è tornare più vicino a quello che avevi prima $0invece dell'ultimo *.
Julie Pelletier,

@JuliePelletier Sembrava funzionare prima quando l'ho provato, ma sì, hai ragione - * l'espansione travolgente non avviene a destra di a <<<.
Digital Trauma,

7

Julia, 51 byte

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

Questo programma dovrebbe essere indipendente dal sistema operativo, sebbene sia stato testato solo su OS X.

Ungolfed:

# 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
Congratulazioni! 20k !!!
Luis Mendo,

La maggior parte delle risposte sembra presupporre che il file si trovi nella directory corrente, quindi non credo che sia necessario cd. In questo caso f=readdir()[]sarebbe ancora più breve.
Dennis,

6

MATLAB, 50 46 byte

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

Grazie a @Suever per la rimozione di 4 byte e per i test!

Testato su OS X El Capitan e Debian Jessie, entrambi con Matlab versione R2014a.

Su Windows 'f'è necessario un flag ( e='.m';x=mfilename;movefile([x e],[flip(x) e]),'f') per modificare il nome del file durante l'utilizzo del file.

Come funziona

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

Su quale sistema operativo sei 'f'richiesto?
Suever,

@Suever Windows. Non è necessario su Mac?
Luis Mendo,

Sembra non necessario su Mac di Linux.
Suever,

@ Grazie Grazie! 4 byte di sconto :-)
Luis Mendo l'

@Suever Puoi indicare il sistema operativo esatto su cui funziona?
Luis Mendo,

4

Rubino, 24 byte

File.rename$0,$0.reverse

Abbastanza autoesplicativo. ( $0è il nome del file in esecuzione.)

Esegui con ruby whateveruna directory di lavoro della directory che contiene il file.


4

Lotto, 109 byte

@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

Nota 1: i file batch devono terminare .bat; si presume che il file batch sia eseguito con il suo nome senza estensione e che .batnon debba essere invertito. Ad esempio, reversetenterebbe di rinominare reverse.batin esrever.bat.
Nota 2: CMD.EXEerrori dopo la ridenominazione del file batch. ( COMMAND.COMno, tranne che non è in grado di manipolare le stringhe in primo luogo.)

Modifica: salvato 2 byte usando la garanzia che il nome del file è alfabetico (basato sul commento di @ CᴏɴᴏʀO'Bʀɪᴇɴ).


3
1. PERCHÉ NON STAI GRIDANDO? 2. Penso che puoi salvare un byte facendoif ]%f% NEQ ] goto l
Conor O'Brien l'

@ CᴏɴᴏʀO'Bʀɪᴇɴ Ah sì, il nome del file è alfabetico, quindi posso salvare 2 byte, ma grazie per il suggerimento.
Neil,

1
È NECESSARIO ESTRARRE IN LOTTO A MENO CHE NON STAI
gatto

4

C, 102 byte

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

Abbattersi:

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

Finalmente una sfida in cui C non è (quasi così irrimediabilmente) non competitivo!


Se prendiamo "Si può presumere la directory di lavoro del guscio sarà la cartella il file è in" per indicare che il programma sarà sempre invocato come ./myexecutable, possiamo semplificare *n=strrchr(*v,47)per *n=*v+1salvare 10 caratteri, ma questo non è del tutto valido ( potrebbe essere invocato come ././myexecutable, ad esempio).


Inoltre, se si desidera mantenere un'estensione di file (ad esempio ".out") in contatto, è possibile modificare *t=strchr(b,0) a *t=strrchr(b,46), costando 2 byte. Non richiesto però.


Bello - Non avrei mai cercato di vedere cosa renamesuccede se src == dest; sembra che soddisfi il vincolo palindromo gratuitamente.
Toby Speight,

Si noti che ciò richiede un file system in cui codepoint 47 è il separatore. Penso che questo includa POSIX (o ciò consente EBCDIC /in un caso angolare?)
Toby Speight,

@TobySpeight sì, ho controllato gnu.org/software/libc/manual/html_node/Renaming-Files.html per alcuni chiarimenti, ma il più vicino che ho trovato è stato "Un caso speciale per rinominare è quando oldname e newname sono due nomi per lo stesso file Il modo coerente di gestire questo caso è quello di eliminare il vecchio nome. Tuttavia, in questo caso POSIX richiede che la ridenominazione non faccia nulla e riporti il ​​successo, il che è incoerente. Non sappiamo cosa farà il tuo sistema operativo. ", Quindi immagino che ci sia un'occasione esterna eliminerà semplicemente il file su sistemi non POSIX compatibili. Quindi sì, il vero codice dovrebbe controllare!
Dave,

Ho appena controllato linux.die.net/man/3/rename e conferma che Linux lo gestisce in modo conforme POSIX: "Se il vecchio argomento e il nuovo argomento si risolvono nello stesso file esistente, rename () restituirà correttamente e non eseguirà nessun altro azione."
Dave,

Stavo andando con la manpage Debian: "Se oldpathe ci newpathsono collegamenti reali esistenti che si riferiscono allo stesso file, allora rename()non fa nulla e restituisce uno stato di successo" - se le stringhe sono identiche, si riferiscono allo stesso file.
Toby Speight,

3

Vitsy + * sh, 15 byte

iG:`?r.iG' mr',

Spiegazione

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.

Nota che questa presentazione deve utilizzare la versione non sicura di Vitsy (non può essere eseguita su Try It Online!)


3

Perl 5, 18 byte

Un po 'come quello di Ruby (corri perl nameofscript):

rename$0,reverse$0

Prendere in considerazione un possibile percorso è più brutto (47 byte)

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

1
Ciao e benvenuto in PPCG! Ottimo primo post!
NoOneIsHere il

2

V , 29 26 byte

:se ri
izyw:!mv z "
dd

Poiché questo contiene non stampabili, ecco un dump esadecimale:

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

Nota: questo non funzionerà su v.tryitonline.net poiché TIO non consente l'accesso ai file.

Spiegazione:

: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 byte

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

-Alex.A rimosso 1 byte.

-Digital Trauma mi ha mostrato os.rename () che ha portato via 62 byte.

-muddyfish rimosso 7 byte.


Penso che puoi salvare un byte rimuovendo lo spazio dopo la virgola inimport
Alex A.

import os,sys;f=sys.argv[0];os.rename(f,f[::-1])dovrebbe fare il trucco per 48 byte
Digital Trauma,

fare f [:: - 1] inverte non solo il nome del file, ma l'intero percorso. Tuttavia, grazie per avermi introdotto alla funzione os.rename ().
Magenta,

@Magenta Per me, sys.argv[0]restituisce il nome del file solo senza il percorso quando lo script viene eseguito direttamente nel proprio. Helka ha indicato che va bene
Digital Trauma,

@DigitalTrauma quando ho eseguito il programma da solo, sys.arg [0] ha restituito il percorso completo. Aggiungerò una seconda soluzione in cui sys.argv [0] è solo il nome del file.
Magenta,

2

PHP, 84, 70, 54 byte

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


EDIT: rimosso 14 byte grazie a insertusernameherenei commenti
EDIT: rimosso 16 byte grazie a Martijnnei commenti


2
È possibile ottenere fino a 70 byte : rename($f=__FILE__,__DIR__."/".strrev(pathinfo($f)[filename]).".php");.
insertusernamehere

Excelent !!! ma il tuo codice è migliore, wow hai 31 byte
tttony

Non puoi renderlo relativo? Potrebbe salvare 7 byte:rename($f=__FILE__,"./".strrev(pathinfo($f)[filename]).".php");
Martijn,

o anche più piccoli:rename(__FILE__,strrev(basename(__FILE__,'.php')).'.php');
Martijn,

Freddo! Aggiungendo Vars ora ho 54 byte
tttony

2

PowerShell, 39 byte

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

Ciao e benvenuto in PPCG! Bel primo post!
Rɪᴋᴇʀ

2

Python 2 , 41 byte

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

Demo su Bash.

A Python non interessa davvero l'estensione del file, quindi possiamo semplicemente capovolgere l'intero nome del file.



1

Perl 6 ,  70   27 byte

Se dovesse funzionare in un'altra directory di lavoro, avresti bisogno di qualcosa del genere:

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

Poiché la directory di lavoro sarà la stessa directory del programma, può essere semplificata semplicemente:

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

Spiegazione:

$_ = $*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 (nodo), 108 104 68 byte

36 byte salvati, grazie a Downgoat!

Versione di Windows:

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

Altra versione:

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

@Upgoat Non ho bisogno, non credo. Sto abbinando jsalla fine del percorso del file, preceduto da un carattere. Questo sarà sempre un ..
Conor O'Brien,

1

JavaScript ES6 (Node.js) 70 byte

No Regex Yay!

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

Qualsiasi aiuto è apprezzato


1

PowerShell v4 +, 68 byte

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

Funziona solo perché lo script è garantito per essere in una directory da solo. Esegue unls (alias per Get-ChildItem) e accetta gli .Nameoggetti risultanti. Lo memorizziamo in $ce poi -splitin un periodo letterale per ottenere il nome del file e l'estensione, e memorizziamo quelli in $ae $b, rispettivamente.

Il prossimo è il comando mv(alias per Move-Item), dove ci stiamo spostando $csu $a(invertiti).$b .

Esempio

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 o 3.4+), 61 49 byte

Credo che questo sia vicino alla soluzione ottimale di Python:

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

Ispirato da s4b3r6 risposta, ma utilizza lo slicing dell'elenco anziché il contrario, e salva __file__in una variabile per salvare byte quando lo si utilizza due volte.

Nota: ciò presuppone che il nome file sia sempre *.py. Una soluzione leggermente più generica in grado di gestire qualsiasi estensione di file di due caratteri sarebbe da utilizzarea[-3:] di sostituirla".py" , al costo di 1 byte extra.

Aggiornamento: salvato 12 byte utilizzando il trucco a[-4::-1]di suddivisione in elenchi per rimuovere l'estensione del file, anziché dividere e quindi invertire con a.split(".")[0][::-1].


1

Powershell, 112 byte

Non ho intenzione di battere i cmds unix, solo aggiungendo i miei due penny per divertimento :-)

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

Benvenuti in PPCG! Richiediamo che le risposte visualizzino il loro punteggio, quindi l'ho modificato per te. Inoltre, puoi formattare il codice evidenziandolo e selezionando il pulsante che appare tra parentesi {}o aggiungendo 4 spazi prima del codice.
FryAmTheEggman,

0

PowerShell, 50 byte

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

Esiste un solo file, quindi il mv *carattere jolly della shell avrà un solo risultato. Il nome di destinazione è (ls).basenameche elenca tutti i file (alias per 'dir'), chiama la proprietà BaseName e, dato che esiste un solo file, PowerShell decomprime l'array a 1 elemento in una stringa. Memorizza quel nome file $f, quindi indicizzalo con un conto alla rovescia e -joini caratteri invertiti eseguono il backup in una stringa. Aggiungi il .ps1suffisso obbligatorio .


0

AutoIt, 45 byte

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

0

Python 2.7, 68 byte

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

Questo è probabilmente il migliore che posso ottenere. Mi sono appena smentito.


0

Python (2 e 3), 88 78 byte

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

Sfrutta il fatto che il nome file è dato da sys.argv (poiché la directory di lavoro è la cartella in cui si trova il file) e utilizza os.rename. In modo fastidioso, invertito restituisce un iteratore, quindi dobbiamo usare join.

Modifica: salvato 10 byte utilizzando __file__ invece di sys.argv [0], come suggerito da @muddyfish a @DigitalTrauma.


0

tcl, 42

file rename $argv0 [string reverse $argv0]

0

Script di Visual Basic, 44 byte

WScript.Echo(StrReverse(WScript.ScriptName))

Esempio di output per il file chiamato reverse.vbs(Esegui con cscript):

sbv.esrever


0

SmileBASIC 60 byte

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

Alternativa:

P$=PRGNAME$()T$=P$*1WHILE""<T$Q$=Q$+POP(T$)WEND
RENAME P$,Q$
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.