Tulis program yang membalikkan nama file sumbernya

27

Dalam satu file, tulis sebuah program yang tidak memerlukan input dan tidak menghasilkan output. Ketika menjalankannya harus membalikkan nama file yang terkandung di dalamnya, terlepas dari apa namanya , tanpa mengubah kode atau menghasilkan efek samping yang bertahan lama.

Cara apa pun untuk mencapai ini baik-baik saja. Yang penting adalah bahwa begitu program dijalankan, satu-satunya perubahan yang bertahan lama adalah bahwa nama filenya telah dibalik. misalnya tidak ada file baru di direktori.

Menjalankan program lagi harus membalikkan nama kembali. Memang, program harus dapat dijalankan secara sewenang-wenang berkali-kali.

Untuk keperluan tantangan ini:

  • Anda dapat menganggap nama file selalu terdiri dari huruf kecil (az) dengan panjang antara 1 dan 127 karakter. (Jika bahasa Anda memerlukan file untuk menjalankan ekstensi, balikkan saja bagian sebelum ekstensi, mis . mycode.batedocym.bat.)
  • Anda dapat menganggap file kode berada dalam direktori dengan sendirinya sehingga tidak akan ada konflik penamaan (kecuali dengan dirinya sendiri).
  • Anda mungkin tidak menganggap nama file bukan palindrom, yaitu sama ketika terbalik. Nama file yang merupakan palindrom harus bekerja sama baiknya dengan yang tidak.
  • Anda dapat membaca konten atau metadata file Anda. Tidak ada batasan sini.
  • Anda dapat mengasumsikan program Anda akan dijalankan pada sistem operasi tertentu, modern, dan umum (misalnya Windows / Linux), karena tidak semua shell memiliki set perintah yang sama.

Sebagai contoh konkret, katakan Anda memiliki program Python dalam file yang disebut mycodedi direktori sendiri. Lari

python mycode

di terminal harus menghasilkan nama file yang dibalik edocym. File tersebut edocymharus sendirian di direktori - tidak ada file bernama mycodeharus ada lagi. Lari

python edocym

akan membalikkan nama kembali ke mycode, di mana titik proses dapat diulang tanpa batas waktu.

Jika file Python yang sama diganti namanya racecar(tanpa mengubah kode) dan kemudian jalankan

python racecar

tidak ada yang terlihat berubah karena "mobil balap" adalah palindrom. Hal yang sama berlaku jika nama file itu, katakanlah, aatau xx.

Kode terpendek dalam byte menang. Tiebreaker adalah jawaban dengan suara lebih tinggi.

Hobi Calvin
sumber
Apakah direktori kerja saat ini penting?
Brad Gilbert b2gills
@ BradGilbertb2gills Anda harus dapat menyalin folder dengan program ke tempat lain dan tetap berfungsi (dengan asumsi Anda memiliki izin dan yang lainnya). Anda dapat mengasumsikan direktori kerja dari shell akan menjadi folder tempat file tersebut berada.
Calvin's Hobbies
6
Bagaimana jika kita menggunakan bahasa yang dikompilasi? Bagaimana eksekusi dapat memengaruhi aturan Anda?
EMBLEM
Permintaan untuk mengklarifikasi 'tidak menerima input dan tidak menghasilkan output'. Secara teknis, nama file adalah input yang harus diambil dari sistem file dan nama yang diubah harus dikirim ke sistem file. Ini adalah input dan output. Mungkin bermanfaat untuk menentukan bahwa tidak ada output lain yang diizinkan.
atk
Selain itu, apakah Anda menganggap penggunaan proses anak sebagai pelanggaran aturan input / output? Yaitu, memanggil proses terpisah untuk melakukan bagian dari tugas, seperti membalikkan nama, akan memerlukan mengirimkan proses lain nama (output dari kode Anda dan input ke aplikasi) dan menerima nilai dari proses (output dari proses dan masukan ke aplikasi).
atk

Jawaban:

41

Bash + utilitas linux umum, 13 byte

Metode saya mirip dengan @ DigitalTrauma tetapi sedikit lebih pendek karena pipa dengan ls:

mv * `ls|rev`
Julie Pelletier
sumber
Oh sangat bagus.
Trauma Digital
20
Selamat Datang di Programming Puzzles & Code Golf! Ini jawaban pertama yang sangat bagus. :)
Alex A.
1
Hanya berfungsi jika tidak ada file lain di direktori.
WGroleau
1
@WGroleau && terdon: kedua komentar Anda benar tetapi pertanyaannya sudah menangani 2 asumsi tersebut.
Julie Pelletier
@JuliePelletier ah, ya, Anda benar sekali. Saya melewatkan bahwa nama file hanya dapat terdiri dari huruf kecil.
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 keren dan semua sampai Anda memiliki variabel yang ditentukan:

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

itu hanya berarti

downrep_nation
sumber
12

Bash + utilitas linux umum, 15

  • 1 byte disimpan berkat @Dennis

Diasumsikan bahwa skrip berada dalam direktori dengan sendirinya.

mv * `rev<<<$0`
Trauma Digital
sumber
6
Anda dapat menganggap file kode berada dalam direktori dengan sendirinya , sehingga $0dapat diganti dengan *.
Dennis
Maaf tapi ada bug kecil di pembaruan Anda dan tidak berfungsi sebagaimana mestinya. Perbaikan paling sederhana adalah kembali lebih dekat dengan apa yang Anda miliki sebelumnya $0daripada yang terakhir *.
Julie Pelletier
@JuliePelletier Sepertinya berhasil sebelumnya ketika saya mencobanya, tapi ya, Anda benar - * ekspansi globbing tidak terjadi di sebelah kanan a <<<.
Trauma Digital
7

Julia, 51 byte

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

Program ini harus merupakan sistem operasi agnostik, meskipun hanya diuji pada OS X.

Tidak Disatukan:

# 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
Alex A.
sumber
8
Selamat! 20k !!!
Luis Mendo
Sebagian besar jawaban tampaknya menganggap bahwa file tersebut ada di direktori saat ini, jadi saya rasa Anda tidak memerlukannya cd. Dalam hal ini f=readdir()[]akan lebih pendek.
Dennis
6

MATLAB, 50 46 byte

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

Terima kasih kepada @Suever untuk menghapus 4 byte dan untuk pengujian!

Diuji pada OS X El Capitan dan Debian Jessie, keduanya dengan versi Matlab R2014a.

Di Windows diperlukan bendera 'f'( e='.m';x=mfilename;movefile([x e],[flip(x) e]),'f') untuk mengubah nama file saat file sedang digunakan.

Bagaimana itu bekerja

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
Luis Mendo
sumber
OS apa yang Anda gunakan 'f'?
Suever
@Suever Windows. Bukankah itu dibutuhkan di Mac?
Luis Mendo
Sepertinya tidak diperlukan di Mac Linux.
Suever
@Suever Terima kasih! Diskon 4 byte :-)
Luis Mendo
@Suever Bisakah Anda menunjukkan OS yang tepat ini berfungsi?
Luis Mendo
4

Ruby, 24 byte

File.rename$0,$0.reverse

Cukup jelas. ( $0adalah nama file yang dieksekusi.)

Jalankan dengan ruby whateverdirektori kerja dari direktori yang berisi file tersebut.

Gagang pintu
sumber
4

Batch, 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

Catatan 1: File batch harus diakhiri .bat; diasumsikan bahwa file batch dijalankan dengan namanya tanpa ekstensi, dan bahwa file .battersebut tidak dapat dibalik. Misalnya, reverseakan mencoba mengubah nama reverse.batmenjadi esrever.bat.
Catatan 2: CMD.EXEkesalahan keluar setelah mengganti nama file batch. ( COMMAND.COMtidak akan, kecuali bahwa itu tidak mampu memanipulasi string di tempat pertama.)

Sunting: Disimpan 2 byte dengan menggunakan jaminan bahwa nama file itu alfabet (berdasarkan komentar @ CᴏɴᴏʀO'Bʀɪᴇɴ).

Neil
sumber
3
1. MENGAPA TIDAK ANDA BERHENTI? 2. Saya pikir Anda dapat menyimpan byte dengan melakukanif ]%f% NEQ ] goto l
Conor O'Brien
@ CᴏɴᴏʀO'Bʀɪᴇɴ Ah ya, nama file itu alfabet, jadi saya sebenarnya bisa menghemat 2 byte, tapi terima kasih atas petunjuknya.
Neil
1
ANDA PERLU BERGERAK DI BATCH KECUALI JIKA ANDA MENGGUNAKAN OOBL AKA SMALLTALK-80
cat
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);}

Kerusakan:

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

Akhirnya sebuah tantangan di mana C tidak (sangat putus asa) tidak kompetitif!


Jika kita mengambil "Anda dapat menganggap direktori kerja shell akan menjadi folder file tersebut di" berarti bahwa program ini akan selalu dipanggil sebagai ./myexecutable, kita dapat menyederhanakan *n=strrchr(*v,47)untuk *n=*v+1menyimpan 10 karakter, tapi ini tidak sepenuhnya valid ( itu bisa dipanggil sebagai ././myexecutable, misalnya).


Juga jika Anda ingin mempertahankan ekstensi file (mis. ".Out"), Anda dapat mengubahnya *t=strchr(b,0)menjadi *t=strrchr(b,46), dengan biaya 2 byte. Namun tidak diperlukan.

Dave
sumber
Bagus - Saya tidak pernah melihat apa yang renameterjadi jika src == dest; tampaknya Anda memenuhi batasan palindrome secara gratis.
Toby Speight
Perhatikan bahwa ini membutuhkan sistem file di mana codepoint 47 adalah pemisah. Saya pikir ini termasuk POSIX (atau apakah itu memungkinkan EBCDIC /dalam kasus sudut?)
Toby Speight
@TobySpeight ya saya memeriksa gnu.org/software/libc/manual/html_node/Renaming-Files.html untuk beberapa klarifikasi, tetapi yang paling dekat yang saya temukan adalah "Satu kasus khusus untuk penggantian nama adalah ketika nama lama dan nama baru adalah dua nama untuk file yang sama Cara yang konsisten untuk menangani kasus ini adalah dengan menghapus nama lama. Namun, dalam hal ini POSIX mengharuskan penggantian nama tidak melakukan apa-apa dan melaporkan keberhasilan — yang tidak konsisten. Kami tidak tahu apa yang akan dilakukan sistem operasi Anda. ", Jadi saya kira ada kemungkinan luar itu hanya akan menghapus file pada sistem yang tidak sesuai dengan POSIX. Jadi ya, kode asli harus diperiksa!
Dave
Saya baru saja memeriksa linux.die.net/man/3/rename dan mengkonfirmasi bahwa Linux menanganinya dengan POSIX: "Jika argumen lama dan argumen baru menyelesaikan file yang sama, rename () akan kembali dengan sukses dan tidak melakukan yang lain tindakan."
Dave
Saya pergi dengan halaman manual Debian: "Jika oldpathdan newpathada tautan keras yang merujuk ke file yang sama, maka rename()tidak melakukan apa-apa, dan mengembalikan status keberhasilan" - jika string identik, mereka merujuk ke file yang sama.
Toby Speight
3

Vitsy + * sh, 15 byte

iG:`?r.iG' mr',

Penjelasan

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.

Perhatikan bahwa pengajuan ini harus menggunakan versi Vitsy yang tidak aman (tidak dapat dilakukan di Try It Online!)

Addison Crump
sumber
3

Perl 5, 18 byte

Sedikit seperti yang Ruby (jalankan perl nameofscript):

rename$0,reverse$0

Memperhatikan kemungkinan jalur ke akun lebih buruk (47 byte)

($a,$b)=$0=~/(.*\/)?(.*)/;rename$0,$a.reverse$b
ilkkachu
sumber
1
Halo, dan selamat datang di PPCG! Pos pertama yang bagus!
NoOneIsHere
2

V , 29 26 byte

:se ri
izyw:!mv z "
dd

Karena ini mengandung unsintables, berikut adalah hex dump:

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

Catatan: ini tidak akan berjalan di v.tryitonline.net karena TIO tidak mengizinkan akses file.

Penjelasan:

: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.
DJMcMayhem
sumber
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 dihapus 1 byte.

-Digital Trauma menunjukkan saya os.rename () yang mengambil 62 byte.

-muddyfish dihapus 7 byte.

Magenta
sumber
Saya pikir Anda dapat menyimpan byte dengan menghapus spasi setelah koma diimport
Alex A.
import os,sys;f=sys.argv[0];os.rename(f,f[::-1])harus melakukan trik selama 48 byte
Digital Trauma
melakukan f [:: - 1] membalikkan tidak hanya nama file, tetapi seluruh path. Namun, terima kasih telah memperkenalkan saya ke fitur os.rename ().
Magenta
@ Magenta Bagi saya, sys.argv[0]hanya mengembalikan nama file saja tanpa path ketika skrip dijalankan secara langsung. Helka mengindikasikan ini tidak masalah
Digital Trauma
@DigitalTrauma ketika saya menjalankan programnya sendiri, sys.arg [0] mengembalikan path lengkapnya. Saya akan menambahkan solusi kedua di mana sys.argv [0] hanyalah nama file.
Magenta
2

PHP, 84, 70, 54 byte

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


EDIT: dihapus 14 byte terima kasih insertusernameheredi komentar
EDIT: dihapus 16 bytes berkat Martijnkomentar

tttony
sumber
2
Anda bisa mendapatkannya turun ke 70 bytes : rename($f=__FILE__,__DIR__."/".strrev(pathinfo($f)[filename]).".php");.
masukkan nama pengguna di sini
Excelent !!! tetapi kode Anda lebih baik, wow Anda mendapat 31 byte
tttony
Tidak bisakah Anda membuatnya relatif? AKAN menyimpan 7 byte:rename($f=__FILE__,"./".strrev(pathinfo($f)[filename]).".php");
Martijn
atau bahkan lebih kecil:rename(__FILE__,strrev(basename(__FILE__,'.php')).'.php');
Martijn
Keren! Menambahkan vars yang saya dapatkan sekarang 54 byte
tttony
2

PowerShell, 39 byte

mi *(-join((ls).name)[-5..-999]+'.ps1')
Bevo
sumber
Hai, dan selamat datang di PPCG! Posting pertama yang bagus!
R
2

Python 2 , 41 byte

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

Demo di Bash.

Python benar-benar tidak peduli dengan ekstensi file, jadi kita bisa membalik seluruh nama file.

Bubbler
sumber
1

PHP, 31 byte

Tidak banyak yang bisa saya jelaskan:

rename($x=$argv[0],strrev($x));
masukkan nama pengguna di sini
sumber
1

Perl 6 ,  70   27 byte

Jika perlu bekerja di direktori kerja yang berbeda, Anda akan membutuhkan sesuatu seperti ini:

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

Karena direktori kerja akan menjadi direktori yang sama dengan program, maka dapat disederhanakan menjadi:

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

Penjelasan:

$_ = $*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
Brad Gilbert b2gills
sumber
1

JavaScript (Node), 108 104 68 byte

36 byte disimpan, terima kasih untuk Downgoat!

Versi Windows:

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

Versi lain:

require("fs").rename(F=__filename,F.split(/.*\/|/).reverse().join``)
Conor O'Brien
sumber
@Upgoat saya tidak perlu, saya tidak berpikir. Saya cocok jsdi akhir filepath, didahului oleh karakter. Ini akan selalu menjadi ..
Conor O'Brien
1

JavaScript ES6 (Node.js) 70 Bytes

Tidak Regex Yay!

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

Bantuan apa pun dihargai

MayorMonty
sumber
1

PowerShell v4 +, 68 byte

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

Hanya berfungsi karena skrip dijamin berada dalam direktori dengan sendirinya. Melakukan suatuls (alias untuk Get-ChildItem) dan mengambil .Nameobjek yang dihasilkan. Kami menyimpannya di $cdan kemudian -splitpada periode literal untuk mendapatkan nama file dan ekstensi, dan menyimpannya di $adan $b, masing-masing.

Berikutnya adalah perintah mv(alias untuk Move-Item), tempat kami pindah $cke $a(terbalik) .$b.

Contoh

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
AdmBorkBork
sumber
1

Python (2,7 atau 3,4+), 61 49 byte

Saya percaya ini dekat dengan solusi Python optimal:

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

Terinspirasi oleh s4b3r6jawaban, tetapi menggunakan pengiris daftar alih-alih terbalik, dan menyimpan__file__ ke variabel untuk menyimpan byte saat menggunakannya dua kali.

Catatan: Ini mengasumsikan bahwa nama file selalu *.py. Solusi yang sedikit lebih umum yang dapat menangani ekstensi file dua karakter apa pun akan digunakan a[-3:]untuk menggantikan".py" , dengan biaya 1 byte tambahan.

Pembaruan: Disimpan 12 byte dengan menggunakan trik pengiris daftar a[-4::-1]untuk menghapus ekstensi file, alih-alih membelah dan kemudian membalik dengan a.split(".")[0][::-1].

Jaden Burt
sumber
1

Powershell, 112 byte

Saya tidak akan mengalahkan cmds unix, hanya menambahkan dua pence saya untuk bersenang-senang :-)

gci * | % { $n=($_.basename[-1..-(($_.basename).length)] -join “”)+$_.Extension; mv -Path $_.Fullname -Dest $n }
rb101
sumber
Selamat datang di PPCG! Kami meminta jawaban menampilkan skor mereka, jadi saya telah mengeditnya untuk Anda. Anda juga dapat memformat kode Anda dengan menyorotnya dan memilih tombol yang tampak seperti tanda kurung {}, atau dengan menambahkan 4 spasi sebelum kode Anda.
FryAmTheEggman
0

PowerShell, 50 byte

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

Hanya ada satu file, jadi mv *shell wildcard hanya akan memiliki satu hasil. Nama tujuan adalah (ls).basenameyang mencantumkan semua file (alias untuk 'dir'), panggilan untuk properti BaseName - dan karena hanya ada satu file, PowerShell akan membongkar array 1-item ke dalam sebuah string. Simpan nama file itu $f, kemudian indekskan dengan hitung mundur dan -joinkarakter yang terbalik dicadangkan menjadi string. Tambahkan .ps1akhiran wajib .

TessellatingHeckler
sumber
0

Otomatis, 45 byte

$a=@ScriptName
FileMove($a,StringReverse($a))
Daniel
sumber
0

Python 2.7, 68 byte

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

Ini mungkin yang terbaik yang bisa saya dapatkan. Saya hanya membuktikan diri saya salah.

Alex
sumber
0

Python (2 & 3), 88 78 byte

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

Mengeksploitasi fakta bahwa nama file diberikan oleh sys.argv (karena direktori kerja adalah folder tempat file berada), dan menggunakan os.rename. Yang menjengkelkan, membalikkan mengembalikan iterator, jadi kita harus menggunakan gabungan.

Sunting: Disimpan 10 byte dengan menggunakan __file__ alih-alih sys.argv [0], seperti yang disarankan oleh @muddyfish ke @DigitalTrauma.

s4b3r6
sumber
0

tcl, 42

file rename $argv0 [string reverse $argv0]
sergiol
sumber
0

Visual Basic Script, 44 Bytes

WScript.Echo(StrReverse(WScript.ScriptName))

Contoh output untuk file bernama reverse.vbs(Jalankan dengan cscript):

sbv.esrever
Gabriel Mills
sumber
0

sfk , 83 byte

list -maxfiles=1 . +setvar n +getvar n +swap +setvar m +ren -var . /#(n)/#(m)/ -yes

Cobalah online!

Suram
sumber
0

SmileBASIC 60 byte

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

Alternatif:

P$=PRGNAME$()T$=P$*1WHILE""<T$Q$=Q$+POP(T$)WEND
RENAME P$,Q$
12Me21
sumber