ソースファイルの名前を逆にするプログラムを書く


27

単一のファイルに、入力を必要とせず、出力も生成しないプログラムを作成します。実行すると、コードが変更されたり、その他の永続的な副作用が発生したりすることなく、名前が何であるか関係なく、含まれているファイルの名前が逆になります。

これを達成する方法はどれでも結構です。プログラムが実行されると、唯一の永続的な変更は、そのファイル名が逆になっていることだけです。たとえば、ディレクトリに新しいファイルを配置しないでください。

プログラムを再度実行すると、名前が逆になります。実際、プログラムは何度でも任意に実行できるはずです。

この課題のために:

  • ファイル名は、常に1〜127文字の小文字(az)の文字列であると想定できます。(実行するために拡張子がファイルに必要な場合は、拡張子の前の部分を逆にします。例:mycode.batedocym.bat
  • コードファイルはそれ自体がディレクトリにあるため、名前の競合はありません(それ自体を除く)。
  • あなたはありません逆にするときと同じつまり、ファイル名は回文ではないと仮定します。パリンドロームであるファイル名は、そうでないファイル名と同じように機能するはずです。
  • ファイルのコンテンツまたはメタデータを読むことができます。ここに制限はありません。
  • すべてのシェルに同じコマンドセットがあるわけではないため、プログラムは特定の最新の一般的なオペレーティングシステム(Windows / Linuxなど)で実行されると仮定できます。

具体的な例として、mycode独自のディレクトリで呼び出されるファイルにPythonプログラムがあるとします 。ランニング

python mycode

ターミナルでは、ファイル名がに逆になるはず edocymです。ファイルedocymはディレクトリ内で単独である必要があります-指定されたファイルmycodeはもう存在しないはずです。ランニング

python edocym

名前をに戻しmycode、その時点でプロセスを無期限に繰り返すことができます。

racecar(コードを変更せずに)同じPythonファイルの名前を変更してから実行した場合

python racecar

「レースカー」はパリンドロームであるため、目に見える変化はありません。ファイル名が、たとえば、aまたはの場合も同様xxです。

バイト単位の最短コードが優先されます。Tiebreakerは、より高い投票数の回答です。


現在の作業ディレクトリは重要ですか?
ブラッドギルバートb2gills

@ BradGilbertb2gillsプログラムを含むフォルダーを他の場所にコピーし、それでも機能するようにする必要があります(アクセス許可などがあると仮定して)。あなたは、シェルの作業ディレクトリにファイルが入っているフォルダになりますと仮定することができます。
カルバンの趣味

6
コンパイルされた言語を使用している場合はどうなりますか?実行可能ファイルはルールにどのように影響しますか?
エンブレム

「入力を受け入れず、出力も生成しない」ことを明確にするよう要求します。技術的には、ファイルの名前は入力であり、ファイルシステムから取得する必要があり、変更した名前をファイルシステムに送信する必要があります。これらは入力と出力です。他の出力が許可されないように指定することは価値があります。
atk

また、子プロセスの使用は入出力ルールの違反と見なしますか?つまり、名前の反転など、タスクの一部を実行するために別のプロセスを呼び出すには、他のプロセスに名前を送信し(コードからの出力とアプリへの入力)、プロセスから値を受け取る(プロセスの出力)必要がありますアプリへの入力)。
atk

回答:


41

Bash +一般的なLinuxユーティリティ、13バイト

私の方法は@DigitalTraumaの方法と似ていますが、次のようなパイプがあるため少し短くなっていlsます。

mv * `ls|rev`

おー、とてもいいね。
デジタル外傷

20
プログラミングパズルとコードゴルフへようこそ!これは非常に良い最初の答えです。:)
アレックスA.

1
ディレクトリに他のファイルがない場合にのみ機能します。
WGroleau

1
@WGroleau && terdon:どちらのコメントも正しいが、質問はすでにこれら2つの仮定を処理している。
ジュリーペレティエ

@JuliePelletierああ、はい、あなたはまったく正しいです。ファイル名は小文字のみで構成されていることに気が付きませんでした。
テルドン

14

C#、153バイト

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

オブジェクト指向はクールで、変数が定義されるまではすべて:

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

それはただ意味する


12

Bash +一般的なLinuxユーティリティ、15

  • @Dennisのおかげで1バイト節約

スクリプトが単独でディレクトリにあると仮定します。

mv * `rev<<<$0`

6
あなたは、コードファイル自体がディレクトリであると仮定して、これ$0と交換することができます*
デニス

申し訳ありませんが、アップデートに小さなバグがあり、そのままでは機能しません。最も簡単な修正は$0、最後のものの代わりに以前に持っていたものに近づくことです*
ジュリーペレティエ

@JuliePelletier私がそれを試したとき、それは前に動作するように見えましたが、はい、あなたは正しいです-*グロブ展開は、の右側には起こりません<<<
デジタル外傷

7

ジュリア、51バイト

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

このプログラムはOSに依存しないはずですが、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])

4バイトを削除してテストしてくれた@Sueverに感謝します!

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

必要なOSは何'f'ですか?
-Suever

@Suever Windows。Macでは必要ないのですか?
ルイスメンドー

LinuxのMacでは必要ないようです。
-Suever

@Sueverありがとう!4バイトオフ:-)
ルイスメンド

@Sueverこれが動作する正確なOSを指定できますか?
ルイスメンドー

4

ルビー、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.batを変更しようとしesrever.batます。
注2:CMD.EXEバッチファイルの名前を変更するとエラーが発生します。(COMMAND.COM最初は文字列操作ができないことを除いて、そうではありません。)

編集:ファイル名がアルファベット(@CᴏɴᴏʀO'Bʀɪᴇɴのコメントに基づく)であることを保証して、2バイトを保存しました。


3
1.なぜあなたは叫んでいないのですか?2.こうすることでバイトを節約できると思うif ]%f% NEQ ] goto l
コナーオブライエン

@CᴏɴᴏʀO'Bʀɪᴇɴああ、ファイル名はアルファベットなので、実際には2バイト節約できますが、ヒントをありがとう。
ニール

1
あなたが使用している場合を除き、お客様はバッチでSHOUTする必要が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、10文字を保存する*n=strrchr(*v,47)よう*n=*v+1に簡略化できますが、これは完全に有効ではありません(././myexecutableたとえば、として呼び出すことができます)。


あなたは、インタクトファイルの拡張子(例:「の.out」)を維持したい場合にも、あなたは変更することができます*t=strchr(b,0)*t=strrchr(b,46)2バイトの原価計算します、。ただし必要ありません。


ニースrename-src == destの場合はどうなるか見たことがありません。パリンドロームの制約を無料で満たすようです。
トビースパイト

これには、コードポイント47が区切り文字であるファイルシステムが必要であることに注意してください。これにはPOSIXが含まれていると思います(または、EBCDIC /をコーナーケースで許可しますか?)
Toby Speight

@TobySpeightええ、私はチェックしました gnu.org/software/libc/manual/html_node/Renaming-Files.htmlをいくつかの明確化のために、しかし、私が見つけた最も近いOLDNAMEとnewnameのは、同じファイルのための2つの名前があるときに、名前変更のための一つの特殊なケースがある」でしたこのケースを処理する一貫した方法は、oldnameを削除することです。ただし、この場合、POSIXでは、renameが何もせず、成功を報告する必要があります。これは矛盾しています。オペレーティングシステムが何をするかわかりません。」外部の可能性は、POSIXに準拠していないシステム上のファイルを削除するだけです。ええ、実際のコードで確認する必要があります!
デイブ

linux.die.net/man/3/renameを確認しましたし、それがLinuxのハンドルがそれPOSIX従順ことを確認:「、同じ既存のファイルへの古い引数と新しい引数の解決された場合、リネーム()が正常に戻り、他を実行してはなりませんアクション。"
デイブ

私はDebianのマンページに行きました:「同じファイルを参照している既存のハードリンクがある場合oldpath、何もせず、成功ステータスを返します」newpathrename() -文字列が同一の場合、それらは同じファイルを参照します。
トビースパイト

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を使用する必要があることに注意してください(Try It Onlineでは行えません!)


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

これには印刷できないものが含まれているため、16進ダンプを次に示します。

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バイトのトリックを行う必要があります
デジタルトラウマ

f [::-1]を実行すると、ファイル名だけでなくパス全体も反転します。ただし、os.rename()機能を紹介してくれてありがとう。
マゼンタ

@Magenta私にとってはsys.argv[0]、スクリプトがそれ自体で直接実行される場合、パスなしでファイル名のみを返します。 Helkaはこれが問題ないことを示しました
デジタル外傷

@DigitalTraumaがプログラムを単独で実行すると、sys.arg [0]は完全なパスを返しました。sys.argv [0]が単なるファイル名である2番目のソリューションを追加します。
マゼンタ

2

PHP、 8470、54バイト

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


編集:insertusernamehereコメントのおかげで14バイトを削除しました
編集:Martijnコメントのおかげで16バイトを削除しました


2
70バイトまで下げることができますrename($f=__FILE__,__DIR__."/".strrev(pathinfo($f)[filename]).".php");
ユーザー名をここに挿入します

素晴らしい!!! しかし、あなたのコードは良いです、あなたは31バイトを得ました
-tttony

相対化できませんか?WOuldは7バイトを節約します:rename($f=__FILE__,"./".strrev(pathinfo($f)[filename]).".php");
Martijn

またはさらに小さい:rename(__FILE__,strrev(basename(__FILE__,'.php')).'.php');
Martijn

クール!変数を追加すると、54バイトになりました
-tttony

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バイト

いいえ正規表現イェーイ!

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__し、変数に保存して、2回使用するとバイトを節約します。

注:これは、ファイル名が常にであると想定しています*.py。2文字のファイル拡張子を処理できるもう少し汎用的なソリューションは、1バイトの追加コストでa[-3:]を置き換えるために使用すること".py"です。

更新:a[-4::-1]で分割してから元に戻すのではなく、リストスライシングトリックを使用してファイル拡張子を削除することで12バイトを保存しましたa.split(".")[0][::-1]


1

Powershell、112バイト

UNIXのコマンドに勝るものではなく、楽しみのために2ペンス追加するだけです:-)

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

PPCGへようこそ!回答にはスコアを表示する必要があるため、編集しました。また、コードを強調表示して角かっこ{}に似たボタンを選択するか、コードの前に4つのスペースを追加することで、コードをフォーマットできます。
FryAmTheEggman

0

PowerShell、50バイト

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

ファイルは1つしかないため、mv *シェルワイルドカードには1つの結果しかありません。宛先名は(ls).basename、すべてのファイル(「dir」のエイリアス)をリストし、BaseNameプロパティを呼び出します。ファイルは1つしかないため、PowerShellは1項目配列を文字列にアンパックします。そのファイル名を$fに保存してから、カウントダウンでインデックスを作成し-join、逆の文字を文字列に戻します。必須を追加.ps1サフィックスます。



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を使用する必要があります。

編集:@muddyfishが@DigitalTraumaに提案したように、sys.argv [0]の代わりに__file__を使用して10バイトを保存しました。



0

Visual Basicスクリプト、44バイト

WScript.Echo(StrReverse(WScript.ScriptName))

reverse.vbs(cscriptで実行)というファイルの出力例:

sbv.esrever


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$
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.