Escribe un programa que invierta el nombre de su archivo fuente


27

En un solo archivo, escriba un programa que no requiera entrada y no produzca salida. Cuando se ejecuta, debe invertir el nombre del archivo que contiene, independientemente de cuál sea el nombre , sin alterar el código ni producir otros efectos secundarios duraderos.

Cualquier forma de lograr esto está bien. Solo importa que una vez que se ejecute el programa, el único cambio duradero sea que su nombre de archivo se haya revertido. por ejemplo, no deben estar nuevos archivos en el directorio.

Ejecutar el programa nuevamente debería revertir el nombre. De hecho, el programa debería poder ejecutarse arbitrariamente muchas veces.

Para los propósitos de este desafío:

  • Puede suponer que los nombres de archivo son siempre cadenas de letras minúsculas (az) entre 1 y 127 caracteres de longitud. (Si su idioma requiere que los archivos tengan extensiones para ejecutarse, simplemente invierta la parte anterior a la extensión, por ejemplo, mycode.batedocym.bat).
  • Puede suponer que el archivo de código está en un directorio por sí mismo, por lo que no tendrá conflictos de nombres (excepto consigo mismo).
  • Es posible que no asume el nombre de archivo no es un palíndromo, es decir, la misma cuando se invierte. Los nombres de archivo que son palíndromos deberían funcionar tan bien como los que no lo son.
  • Puede leer los contenidos o metadatos de su archivo. No hay restricciones de aquí.
  • Puede suponer que su programa se ejecutará en un sistema operativo particular, moderno y común (por ejemplo, Windows / Linux), ya que no todos los shells tienen el mismo conjunto de comandos.

Como ejemplo concreto, supongamos que tiene un programa Python en un archivo llamado mycodeen su propio directorio. Corriendo

python mycode

en el terminal debe dar como resultado que se invierta el nombre del archivo edocym. El archivo edocymdebe estar solo en su directorio; ya no mycodedebe existir ningún archivo con el nombre . Corriendo

python edocym

revertirá el nombre nuevamente mycode, en cuyo punto el proceso puede repetirse indefinidamente.

Si se cambió el nombre del mismo archivo de Python racecar(sin cambiar el código) y luego se ejecuta

python racecar

nada debería cambiar visiblemente ya que el "auto de carreras" es un palíndromo. Lo mismo ocurre si el nombre de archivo fuera, digamos, ao xx.

El código más corto en bytes gana. Tiebreaker es la respuesta más votada.


¿Importa el directorio de trabajo actual?
Brad Gilbert b2gills

@ BradGilbertb2gills Debería poder copiar la carpeta con el programa en otro lugar y aún así hacer que funcione (suponiendo que tenga permisos y demás). Puede suponer que el directorio de trabajo del shell será la carpeta en la que se encuentra el archivo.
Calvin's Hobbies

66
¿Qué pasa si estamos usando un lenguaje compilado? ¿Cómo afecta el ejecutable a tus reglas?
EMBLEMA

Solicitud para aclarar 'no acepta entrada y no produce salida'. Técnicamente, el nombre del archivo es una entrada que no debe recuperarse del sistema de archivos y el nombre cambiado debe enviarse al sistema de archivos. Estos son de entrada y salida. Puede valer la pena especificar que no se permiten otras salidas.
atk

Además, ¿considera que el uso de procesos secundarios es una violación de las reglas de entrada / salida? Es decir, llamar a un proceso separado para realizar parte de la tarea, como invertir el nombre, requeriría enviar el nombre del otro proceso (salida de su código y entrada a la aplicación) y recibir el valor del proceso (salida del proceso y entrada a la aplicación).
atk

Respuestas:


41

Bash + utilidades comunes de Linux, 13 bytes

Mi método es similar al de @ DigitalTrauma pero un poco más corto debido a la tubería con ls:

mv * `ls|rev`

Oh muy bien.
Trauma digital

20
¡Bienvenido a Programming Puzzles & Code Golf! Esta es una muy buena primera respuesta. :)
Alex A.

1
Solo funciona si no hay otro archivo en el directorio.
WGroleau

1
@WGroleau && terdon: ambos comentarios son correctos, pero la pregunta ya maneja esos 2 supuestos.
Julie Pelletier

@JuliePelletier ah, sí, tienes toda la razón. Eché de menos que los nombres de archivo solo pueden consistir en letras minúsculas.
terdon

14

C #, 153 bytes

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

OO es genial y todo hasta que tenga una variable definida:

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

eso solo significa


12

Bash + utilidades comunes de Linux, 15

  • 1 byte guardado gracias a @Dennis

Asume que el script está en un directorio por sí mismo.

mv * `rev<<<$0`

66
Usted puede asumir el archivo de código está en un directorio por sí mismo , por lo que $0se puede reemplazar con *.
Dennis

Lo sentimos, pero hay un pequeño error en su actualización y no funciona como está. La solución más simple es volver más cerca de lo que tenía antes en $0lugar de la última *.
Julie Pelletier

@JuliePelletier Parecía funcionar antes cuando lo probé, pero sí, tienes razón: * la expansión global no ocurre a la derecha de a <<<.
Trauma digital

7

Julia, 51 bytes

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

Este programa debería ser independiente del sistema operativo, aunque solo se probó en OS X.

Sin 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
¡Felicidades! 20k !!!
Luis Mendo

La mayoría de las respuestas parecen suponer que el archivo está en el directorio actual, por lo que no creo que necesite el cd. En este caso f=readdir()[]sería aún más corto.
Dennis

6

MATLAB, 50 46 bytes

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

¡Gracias a @Suever por eliminar 4 bytes y por las pruebas!

Probado en OS X El Capitan y Debian Jessie, ambos con la versión R2014a de Matlab.

En Windows 'f'se necesita un indicador ( e='.m';x=mfilename;movefile([x e],[flip(x) e]),'f') para cambiar el nombre del archivo mientras se está utilizando el archivo.

Cómo funciona

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

¿En qué sistema operativo estás que 'f'se requiere?
Suever

@Suever Windows. ¿No es necesario en Mac?
Luis Mendo

No es necesario en Mac de Linux, parece.
Suever

@Suever ¡Gracias! 4 bytes de descuento :-)
Luis Mendo

@Suever ¿Puede indicar el sistema operativo exacto en el que funciona?
Luis Mendo

4

Rubí, 24 bytes

File.rename$0,$0.reverse

Bastante autoexplicativo. ( $0es el nombre del archivo que se está ejecutando).

Ejecute con ruby whateverun directorio de trabajo del directorio que contiene el archivo.


4

Lote, 109 bytes

@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: los archivos por lotes deben terminar en .bat; se supone que el archivo por lotes se ejecuta por su nombre sin extensión y que .batno se debe revertir. Por ejemplo, reverseintentaría cambiar el nombre reverse.bata esrever.bat.
Nota 2: CMD.EXEerrores después de cambiar el nombre del archivo por lotes. ( COMMAND.COMno, excepto que es incapaz de manipular cuerdas en primer lugar)

Editar: se guardaron 2 bytes utilizando la garantía de que el nombre del archivo es alfabético (según el comentario de @ CᴏɴᴏʀO'Bʀɪᴇɴ).


3
1. ¿POR QUÉ NO ESTÁS GRITANDO? 2. Creo que puedes salvar un byte haciendoif ]%f% NEQ ] goto l
Conor O'Brien

@ CᴏɴᴏʀO'Bʀɪᴇɴ Ah sí, el nombre del archivo es alfabético, por lo que de hecho puedo guardar 2 bytes, pero gracias por la pista.
Neil

1
USTED DEBE GRITAR EN LOTE A MENOS QUE ESTÉ USANDO OOBL AKA SMALLTALK-80
cat

4

C, 102 bytes

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

Descompostura:

                            // 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 un desafío donde C no es (tan desesperadamente) poco competitivo!


Si tomamos "Se puede suponer el directorio de trabajo de la cáscara será la carpeta del archivo está en" el sentido de que el programa siempre será invocado como ./myexecutable, podemos simplificar *n=strrchr(*v,47)a *n=*v+1ahorrar 10 caracteres, pero esto no es del todo válida ( podría invocarse como ././myexecutable, por ejemplo).


Además, si desea mantener una extensión de archivo (por ejemplo, ".out") intacta, puede cambiar *t=strchr(b,0)a *t=strrchr(b,46), con un costo de 2 bytes. Aunque no es obligatorio.


Agradable: nunca había buscado ver qué renamehace si src == dest; parece que satisfaces la restricción del palíndromo de forma gratuita.
Toby Speight

Tenga en cuenta que esto requiere un sistema de archivos donde el punto de código 47 es el separador. Creo que esto incluye POSIX (¿o eso permite EBCDIC /en un caso de esquina?)
Toby Speight

@TobySpeight, sí, revisé gnu.org/software/libc/manual/html_node/Renaming-Files.html para obtener algunas aclaraciones, pero lo más cercano que encontré fue "Un caso especial para cambiar el nombre es cuando oldname y newname son dos nombres para el mismo archivo . La forma coherente de manejar este caso es eliminar el nombre antiguo. Sin embargo, en este caso POSIX requiere que renombrar no haga nada e informe el éxito, lo cual es inconsistente. No sabemos qué hará su sistema operativo ", así que supongo que hay una posibilidad externa simplemente eliminará el archivo en sistemas que no sean compatibles con POSIX. Así que sí, ¡el código real debería verificar!
Dave

Acabo de comprobar linux.die.net/man/3/rename y confirma que Linux lo maneja en conformidad con POSIX: "Si el argumento anterior y el nuevo argumento se resuelven en el mismo archivo existente, rename () volverá con éxito y no realizará ninguna otra acción."
Dave

Iba con la página de manual de Debian: "Si oldpathy newpathhay enlaces duros existentes que se refieren al mismo archivo, rename()no hace nada y devuelve un estado de éxito" - si las cadenas son idénticas, se refieren al mismo archivo.
Toby Speight

3

Vitsy + * sh, 15 bytes

iG:`?r.iG' mr',

Explicación

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.

Tenga en cuenta que esta presentación debe utilizar la versión no segura de Vitsy (¡no se puede hacer en Pruébelo en línea!)


3

Perl 5, 18 bytes

Un poco como el Ruby (ejecutar perl nameofscript):

rename$0,reverse$0

Tener en cuenta una posible ruta es más feo (47 bytes)

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

1
Hola y bienvenidos a PPCG! Gran primer post!
NoOneIsHere

2

V , 29 26 bytes

:se ri
izyw:!mv z "
dd

Como esto contiene elementos no imprimibles, aquí hay un volcado hexadecimal:

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: esto no se ejecutará en v.tryitonline.net ya que TIO no permite el acceso a archivos.

Explicación:

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

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

-Alex.A eliminado 1 byte.

-Digital Trauma me mostró os.rename () que eliminó 62 bytes.

-muddyfish eliminó 7 bytes.


Creo que se puede guardar un byte quitando el espacio después de la coma en elimport
Alex A.

import os,sys;f=sys.argv[0];os.rename(f,f[::-1])debería hacer el truco para 48 bytes
Digital Trauma

haciendo f [:: - 1] invierte no solo el nombre del archivo, sino toda la ruta. Sin embargo, gracias por presentarme la función os.rename ().
Magenta

@Magenta Para mí, sys.argv[0]solo devuelve el nombre del archivo solo sin la ruta cuando el script se ejecuta directamente. Helka indicó que esto está bien
Trauma digital

@DigitalTrauma cuando ejecuté el programa solo, sys.arg [0] devolvió la ruta completa. Agregaré una segunda solución donde sys.argv [0] es solo el nombre del archivo.
Magenta

2

PHP 84, 7054 bytes

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


EDITAR: eliminado 14 bytes gracias a insertusernamehereen los comentarios
EDITAR: eliminado 16 bytes gracias a Martijnen los comentarios


2
Se puede conseguir hasta 70 bytes : rename($f=__FILE__,__DIR__."/".strrev(pathinfo($f)[filename]).".php");.
insertusernamehere

Excelente !!! pero tu código es mejor, wow tienes 31 bytes
tttony

¿No puedes hacerlo relativo? Ahorraría 7 bytes:rename($f=__FILE__,"./".strrev(pathinfo($f)[filename]).".php");
Martijn

o incluso menor:rename(__FILE__,strrev(basename(__FILE__,'.php')).'.php');
Martijn

¡Guay! Agregando vars ahora tengo 54 bytes
tttony

2

PowerShell, 39 bytes

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

Hola y bienvenidos a PPCG! Bonito primer post!
Rɪᴋᴇʀ

2

Python 2 , 41 bytes

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

Demo en Bash.

Python realmente no le importa la extensión del archivo, por lo que podemos voltear todo el nombre del archivo.



1

Perl 6 ,  70   27 bytes

Si necesitara trabajar en un directorio de trabajo diferente, necesitaría algo como esto:

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

Dado que el directorio de trabajo será el mismo directorio que el programa, puede simplificarse simplemente:

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

Explicación:

$_ = $*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 bytes

36 bytes guardados, gracias a Downgoat!

Versión de Windows:

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

Otra versión:

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

@ Upgoat No necesito, no lo creo. Estoy haciendo coincidir jsal final de la ruta del archivo, precedido por un personaje. Esto siempre será a ..
Conor O'Brien

1

JavaScript ES6 (Node.js) 70 Bytes

No Regex Yay!

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

Cualquier ayuda es apreciada


1

PowerShell v4 +, 68 bytes

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

Solo funciona porque se garantiza que el script esté en un directorio por sí solo. Realiza un ls(alias para Get-ChildItem) y toma el .Namede los objetos resultantes. Lo almacenamos en $cy luego -spliten un período literal para obtener el nombre de archivo y la extensión, y los almacenamos en $ay $b, respectivamente.

El siguiente es el comando mv(alias para Move-Item), donde nos estamos moviendo $ca $a(invertido) .$b.

Ejemplo

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 bytes

Creo que esto está cerca de la solución óptima de Python:

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

Inspirado por s4b3r6la respuesta de, pero usa el corte de la lista en lugar del reverso, y guarda __file__en una variable para guardar bytes cuando lo usa dos veces.

Nota: Esto supone que el nombre del archivo es siempre *.py. Una solución un poco más genérica que pueda manejar cualquier extensión de archivo de dos caracteres sería usar a[-3:]para reemplazar ".py", al costo de 1 byte adicional.

Actualización: se guardaron 12 bytes usando el truco de corte de lista a[-4::-1]para eliminar la extensión del archivo, en lugar de dividir y luego revertir con a.split(".")[0][::-1].


1

Powershell, 112 bytes

No voy a superar los cmds de Unix, solo agrego mis dos peniques por diversión :-)

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

Bienvenido a PPCG! Requerimos que las respuestas muestren su puntaje, así que lo he editado para usted. Además, puede formatear su código resaltándolo y seleccionando el botón que parece un paréntesis {}, o agregando 4 espacios antes de su código.
FryAmTheEggman

0

PowerShell, 50 bytes

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

Solo hay un archivo, por lo que el mv *comodín de shell solo tendrá un resultado. El nombre de destino es el (ls).basenameque enumera todos los archivos (alias para 'dir'), solicita la propiedad BaseName, y dado que solo hay un archivo, PowerShell desempaquetará la matriz de 1 elemento en una cadena. Almacene ese nombre de archivo $f, luego indexe con una cuenta regresiva y -joinlos caracteres invertidos vuelvan a formar una cadena. Agregue el .ps1sufijo obligatorio .


0

AutoIt, 45 bytes

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

0

Python 2.7, 68 bytes

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

Esto es probablemente lo mejor que puedo conseguir. Solo demostré que estaba equivocado.


0

Python (2 y 3), 88 78 bytes

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

Explota el hecho de que sys.argv proporciona el nombre de archivo (ya que el directorio de trabajo es la carpeta en la que se encuentra el archivo) y utiliza os.rename. Molesto, invertido devuelve un iterador, por lo que tenemos que usar join.

Editar: Guardado 10 bytes usando __file__ en lugar de sys.argv [0], como lo sugiere @muddyfish a @DigitalTrauma.



0

Script de Visual Basic, 44 bytes

WScript.Echo(StrReverse(WScript.ScriptName))

Ejemplo de salida para el archivo llamado reverse.vbs(Ejecutar con cscript):

sbv.esrever


0

SmileBASIC 60 bytes

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$
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.