编写一个程序来反转其源文件的名称


27

在一个文件中,编写不需要输入且不会产生输出的程序。运行时,无论名称是什么,它都应该反转其中包含的文件的名称,而无需更改代码或不会产生其他持久的副作用。

任何实现此目的的方法都可以。唯一重要的是,一旦程序运行,唯一的持久更改就是其文件名已被颠倒。例如,目录中不应有新文件。

再次运行该程序应将名称反向。实际上,该程序应该能够任意运行多次。

就此挑战而言:

  • 您可能会假设文件名始终是长度在1到127个字符之间的小写字母(az)字符串。(如果您的语言要求文件具有扩展名才能运行,则只需反转扩展名之前的部分即可,例如mycode.batedocym.bat。)
  • 您可能会认为代码文件本身位于目录中,因此它不会有命名冲突(除了自身)。
  • 您可能不会假定文件名不是回文,即取反后的名称相同。回文的文件名应该和不一样的文件名一起工作。
  • 您可以阅读文件的内容或元数据。此处没有限制。
  • 您可能会假设您的程序将在特定的,现代的,常见的操作系统(例如Windows / Linux)上运行,因为并非所有外壳程序都具有相同的命令集。

举一个具体的例子,假设您有一个Python程序mycode位于其自己目录中的文件 中。跑步

python mycode

在终端中应导致文件名被反转为 edocym。该文件edocym应仅位于其目录中-不再mycode存在任何命名的文件。跑步

python edocym

会将名称改回mycode,此时可以无限期重复此过程。

如果相同的Python文件已重命名racecar(不更改代码),然后运行

python racecar

由于“赛车”是回文,因此没有任何明显的变化。如果文件名是a或,也是如此xx

以字节为单位的最短代码获胜。决胜局是最高投票的答案。


当前工作目录重要吗?
布拉德·吉尔伯特b2gills '16

@ BradGilbertb2gills您应该能够将程序附带的文件夹复制到其他位置,并且仍然可以正常工作(假设您具有权限等)。你可以假设外壳的工作目录将是该文件的文件夹。
加尔文的嗜好

6
如果我们使用的是编译语言怎么办?可执行文件如何影响您的规则?
EMBLEM,2016年

要求澄清“不接受任何输入,不产生任何输出”。从技术上讲,文件名是必须从文件系统中检索到的输入,并且更改后的名称必须发送到文件系统。这些是输入和输出。可能需要指定不允许其他输出。
atk

此外,您是否认为使用子进程违反了输入/输出规则?也就是说,调用一个单独的进程来执行部分任务,例如反转名称,则需要向另一个进程发送名称(从代码输出并输入到应用程序),并从该进程接收值(该进程的输出)并输入到应用程序)。
atk

Answers:


41

Bash +常见的Linux utils,13个字节

我的方法类似于@DigitalTrauma的方法,但由于带有ls以下内容的管道而使方法略短:

mv * `ls|rev`

哦很好。
Digital Trauma

20
欢迎来到编程难题和代码高尔夫球!这是一个非常好的第一答案。:)
Alex A.

1
仅在目录中没有其他文件时才有效。
WGroleau'6

1
@WGroleau && terdon:您的评论都正确,但该问题已经解决了这两个假设。
朱莉·佩勒捷

@JuliePelletier啊,是的,你说的很对。我错过了文件名只能包含小写字母的情况。
terdon

14

C#,153个字节

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

OO很酷,直到您定义了一个变量为止:

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

那只是意味着


12

Bash +常见的Linux utils,15

  • @Dennis节省了1个字节

假设脚本本身位于目录中。

mv * `rev<<<$0`

6
您可以假定代码文件本身位于目录中,因此$0可以将其替换为*
丹尼斯

抱歉,您的更新中有一个小错误,无法按原样工作。最简单的解决方法是使您回到以前的状态,$0而不是最后一个状态*
朱莉·佩勒捷

@JuliePelletier在尝试之前,它似乎可以工作,但是是的,你是对的-*球形扩展不会在a的右侧发生<<<
Digital Trauma

7

朱莉娅51字节

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

尽管该程序仅在OS X上进行了测试,但它应该与操作系统无关。

取消高尔夫:

# 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
恭喜!20k !!!
路易斯·门多

大多数答案似乎都假定该文件位于当前目录中,因此我认为您不需要cd。在这种情况下f=readdir()[]甚至会更短。
丹尼斯

6

MATLAB,50 46字节

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

感谢@Suever删除4个字节并进行了测试!

在OS X El Capitan和Debian Jessie上都通过Matlab R2014a版进行了测试。

在Windows上,使用文件时'f'需要一个标记(e='.m';x=mfilename;movefile([x e],[flip(x) e]),'f')来更改文件名。

怎么运行的

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

'f'需要什么操作系统?
2016年

@Suever Windows。在Mac上不需要吗?
路易斯·门多

看起来在Linux的Mac上不需要。
Suever

@Suever谢谢!关闭4个字节:-)
路易斯·门多

@Suever您能指出它可以运行的确切操作系统吗?
路易斯·门多

4

Ruby,24个字节

File.rename$0,$0.reverse

相当不言自明。($0是正在执行的文件的名称。)

使用ruby whatever包含文件的目录的工作目录运行。


4

批次,109个字节

@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

注意1:批处理文件必须以.bat; 结尾 假定批处理文件是按其名称执行的,没有扩展名,并且.bat不应将其反转。例如,reverse将尝试重命名reverse.batesrever.bat
注意2:CMD.EXE重命名批处理文件后出现错误。(COMMAND.COM不会,只是首先它不能进行字符串操作。)

编辑:使用保证文件名是字母的(基于@CᴏɴᴏʀO'Bʀɪᴇɴ的注释)来保存2个字节。


3
1.为什么不喊?2.我认为您可以这样做来节省一个字节if ]%f% NEQ ] goto l
Conor O'Brien

@CᴏɴᴏʀO'Bʀɪᴇɴ啊,是的,文件名是字母顺序的,因此我实际上可以保存2个字节,但是感谢您的提示。
尼尔

1
你需要呐喊批,除非你使用OOBL AKA SMALLTALK-80

4

C,102字节

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

分解:

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

最后,挑战是C并非(毫无希望地)没有竞争力!


如果我们把“你可以假定壳的工作目录将是该文件所在的文件夹”来表示,该计划将一直被援引为./myexecutable,我们可以简化*n=strrchr(*v,47),以*n=*v+1节省10个字符,但是这并不完全有效(例如,可以将其调用././myexecutable)。


另外,如果您希望保持文件扩展名(例如“ .out”)完整无缺,则可以更改*t=strchr(b,0)*t=strrchr(b,46),花费2个字节。虽然不是必需的。


很好- rename如果src == dest,我从没想过要怎么做;看来您免费满足回文约束。
Toby Speight 2016年

请注意,这需要一个文件系统,其中代码点47是分隔符。我认为其中包括POSIX(或者是否允许EBCDIC /在极端情况下使用?)
Toby Speight,2016年

@TobySpeight是的,我检查了gnu.org/software/libc/manual/html_node/Renaming-Files.html进行了一些澄清,但我发现最接近的是“重命名的一种特殊情况是,当oldname和newname是同一文件的两个名称时处理这种情况的一致方法是删除旧名称。但是,在这种情况下,POSIX要求重命名不执行任何操作并报告成功-这是不一致的。我们不知道您的操作系统将执行什么操作。”,所以我想一个外部机会,它只会在不符合POSIX的系统上删除文件。是的,应该检查真实代码!
戴夫

我刚刚检查了linux.die.net/man/3/rename,它确认Linux可以按照POSIX进行处理:行动。”
戴夫

我正在使用Debian联机帮助页:“如果oldpathnewpath是指向相同文件的现有硬链接,则不rename()执行任何操作,并返回成功状态” -如果字符串相同,则它们指向相同的文件。
Toby Speight

3

Vitsy + * sh,15个字节

iG:`?r.iG' mr',

说明

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.

请注意,此提交必须使用Vitsy的非安全版本(不能在“在线试用”中完成!)


3

Perl 5,18个字节

有点像Ruby(运行perl nameofscript):

rename$0,reverse$0

考虑可能的路径比较麻烦(47个字节)

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

1
您好,欢迎来到PPCG!很棒的第一篇文章!
NoOneIsHere

2

V29 26字节

:se ri
izyw:!mv z "
dd

由于其中包含不可打印的内容,因此这里是一个十六进制转储:

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

注意:由于TIO不允许文件访问,因此无法在v.tryitonline.net上运行。

说明:

: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个字节

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

-Alex.A删除了1个字节。

-Digital Trauma向我显示了os.rename(),该文件占用了62个字节。

-muddyfish删除了7个字节。


我想你可以通过在逗号后移除空间节省字节import
亚历A.

import os,sys;f=sys.argv[0];os.rename(f,f[::-1])应该可以达到48字节的效果
Digital Trauma

执行f [::-1]不仅会反转文件名,还会反转整个路径。但是,感谢您向我介绍os.rename()功能。
洋红色2016年

@Magenta对我来说,sys.argv[0]仅直接运行脚本时,仅返回文件名而没有路径。 Helka表示没关系
Digital Trauma

@DigitalTrauma当我自己运行程序时,sys.arg [0]返回了完整路径。麻烦添加第二个解决方案,其中sys.argv [0]只是文件名。
洋红色2016年

2

PHP, 8470,54字节

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


编辑:除去14字节由于insertusernamehere在评论
编辑:除去16字节由于Martijn在评论


2
您可以减少到70个字节rename($f=__FILE__,__DIR__."/".strrev(pathinfo($f)[filename]).".php");
插入用户名

优秀!!! 但是您的代码更好,哇,您有31个字节
-tttony

你不能使它相对吗?将节省7个字节:rename($f=__FILE__,"./".strrev(pathinfo($f)[filename]).".php");
Martijn

甚至更小:rename(__FILE__,strrev(basename(__FILE__,'.php')).'.php');
Martijn

凉!添加变量我现在有54个字节
tttony 2013年

2

PowerShell,39个字节

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

嗨,欢迎来到PPCG!不错的第一篇文章!
Rɪᴋᴇʀ



1

Perl 6的 70   27个字节

如果需要在其他工作目录中工作,则需要类似以下内容:

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

由于工作目录与程序位于同一目录,因此可以简化为:

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

说明:

$_ = $*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(节点),108个 104 68字节

感谢Downgoat,节省了36个字节!

Windows版本:

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

其他版本:

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

@Upgoat我不需要,我不认为。我js在文件路径的末尾匹配一个字符。这将永远是一个.
科纳·奥布莱恩

1

JavaScript ES6(Node.js)70字节

没有正则表达式Yay!

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

任何帮助表示赞赏


1

PowerShell v4 +,68个字节

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

仅可以使用,因为可以保证脚本本身完全位于目录中。执行ls(的别名Get-ChildItem)并获取.Name结果对象的。我们先将其存储在中$c,然后-split在字面上将其存储,以获取文件名和扩展名,然后分别将它们存储在$a和中$b

接下来是mv(别名Move-Item)命令,在这里我们要搬家$c$a(逆转).$b

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或3.4 +),61 49字节

我相信这接近最佳的Python解决方案:

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

s4b3r6的回答启发,但使用列表切片而不是反向切片,并且__file__使用两次时会保存到变量以保存字节。

注意:这假定文件名始终为*.py。可以处理任何两个字符的文件扩展名的更通用的解决方案是使用a[-3:]replace ".py",但要多花1个字节。

更新:使用列表切片技巧a[-4::-1]删除文件扩展名,而不是先拆分再反转,从而节省了12个字节a.split(".")[0][::-1]


1

Powershell,112字节

我不会打败unix cmds,只是添加我的两便士就可以了:-)

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

欢迎来到PPCG!我们要求答案显示分数,所以我为您编辑了分数。另外,您可以通过突出显示代码并选择类似于方括号的按钮来设置代码格式{},或者在代码之前添加4个空格。
FryAmTheEggman'7

0

PowerShell,50个字节

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

只有一个文件,因此mv *shell通配符将只有一个结果。目的地名称是(ls).basename列出所有文件(“ dir”的别名)的名称,并调用BaseName属性-并且由于只有一个文件,PowerShell会将1-item数组解压缩为字符串。将该文件名存储在中$f,然后用倒计时-join将其编入索引,并将反向字符备份到字符串中。添加必需的.ps1后缀。


0

AutoIt,45个字节

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

0

Python 2.7,68个字节

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

这可能是我能得到的最好的。 我只是证明自己错了。


0

Python(2&3),88 78字节

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

利用文件名由sys.argv给出的事实(因为工作目录是文件所在的文件夹),并利用os.rename。令人讨厌的是,reversed返回一个迭代器,因此我们必须使用join。

编辑:通过使用__file__而不是sys.argv [0]保存了10个字节,如@muddyfish向@DigitalTrauma建议的那样。





0

SmileBASIC 60字节

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

选择:

P$=PRGNAME$()T$=P$*1WHILE""<T$Q$=Q$+POP(T$)WEND
RENAME P$,Q$
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.