Napisz program, który odwraca nazwę swojego pliku źródłowego

27

W jednym pliku napisz program, który nie wymaga danych wejściowych i nie generuje danych wyjściowych. Po uruchomieniu powinien odwrócić nazwę pliku, w którym się znajduje, bez względu na nazwę , bez zmiany kodu lub wywoływania innych trwałych skutków ubocznych.

Każdy sposób osiągnięcia tego jest w porządku. Liczy się tylko to, że po uruchomieniu programu jedyną trwałą zmianą jest odwrócenie nazwy pliku. np. żadne nowe pliki nie powinny znajdować się w katalogu.

Ponowne uruchomienie programu powinno odwrócić nazwę. Rzeczywiście, program powinien być w stanie być uruchamiany dowolnie wiele razy.

Na potrzeby tego wyzwania:

  • Możesz założyć, że nazwy plików to zawsze ciągi małych liter (az) o długości od 1 do 127 znaków. (Jeśli twój język wymaga, aby pliki miały rozszerzenia do uruchomienia, po prostu odwróć część przed rozszerzeniem, np . mycode.batedocym.bat).
  • Możesz założyć, że plik kodu jest sam w katalogu, więc nie będzie miał konfliktów nazw (z wyjątkiem samego siebie).
  • Być może nie zakładamy, że nazwa pliku nie jest palindrom, czyli tyle samo, gdy odwrócony. Nazwy plików, które są palindromami, powinny działać tak samo dobrze, jak te, które nie są.
  • Możesz przeczytać zawartość pliku lub metadane. Brak ograniczenia tutaj.
  • Możesz założyć, że twój program będzie działał na określonym, nowoczesnym, powszechnym systemie operacyjnym (np. Windows / Linux), ponieważ nie wszystkie powłoki mają ten sam zestaw poleceń.

Jako konkretny przykład, powiedzmy, że masz program w języku Python w pliku o nazwie mycodew jego własnym katalogu. Bieganie

python mycode

w terminalu powinno spowodować odwrócenie nazwy pliku edocym. Plik edocympowinien być sam w swoim katalogu - żaden nazwany plik nie mycodepowinien już istnieć. Bieganie

python edocym

odwróci nazwę z powrotem do mycode, w którym to momencie proces można powtarzać w nieskończoność.

Jeśli nazwa tego samego pliku Python została zmieniona racecar(bez zmiany kodu), a następnie uruchom

python racecar

nic nie powinno się wyraźnie zmienić, ponieważ „samochód wyścigowy” to palindrom. To samo dotyczy, jeśli nazwa pliku to, powiedzmy, alub xx.

Najkrótszy kod w bajtach wygrywa. Tiebreaker jest wyżej głosowaną odpowiedzią.

Hobby Calvina
źródło
Czy aktualny katalog roboczy ma znaczenie?
Brad Gilbert b2gills
@ BradGilbertb2gills Powinieneś być w stanie skopiować folder z programem do innego miejsca i nadal mieć to działające (zakładając, że masz uprawnienia i tak dalej). Możesz założyć, że katalog roboczy powłoki będzie folderem, w którym znajduje się plik.
Calvin's Hobbies
6
Co jeśli korzystamy ze skompilowanego języka? W jaki sposób plik wykonywalny wpływa na twoje reguły?
EMBLEM
Żądanie wyjaśnienia „nie przyjmuje żadnych danych wejściowych i nie wytwarza danych wyjściowych”. Technicznie nazwa pliku to dane wejściowe, które muszą zostać pobrane z systemu plików, a zmieniona nazwa musi zostać przesłana do systemu plików. Są to dane wejściowe i wyjściowe. Warto może określić, że żadne inne dane wyjściowe nie są dozwolone.
atk
Ponadto, czy uważasz, że użycie procesów potomnych jest naruszeniem reguł wejścia / wyjścia? Oznacza to, że wywołanie osobnego procesu w celu wykonania części zadania, takiego jak odwrócenie nazwy, wymagałoby wysłania do drugiego procesu nazwy (danych wyjściowych z kodu i danych wejściowych do aplikacji) i otrzymania wartości z procesu (danych wyjściowych procesu i dane wejściowe do aplikacji).
atk

Odpowiedzi:

41

Bash + wspólne narzędzia linux, 13 bajtów

Moja metoda jest podobna do @ DigitalTrauma, ale nieco krótsza ze względu na potok z ls:

mv * `ls|rev`
Julie Pelletier
źródło
O bardzo dobrze.
Digital Trauma
20
Witamy w Programowaniu Puzzle i Code Golf! To bardzo miła pierwsza odpowiedź. :)
Alex A.
1
Działa tylko wtedy, gdy w katalogu nie ma innego pliku.
WGroleau,
1
@WGroleau && terdon: oba twoje komentarze są słuszne, ale pytanie już obsługuje te 2 założenia.
Julie Pelletier,
@JuliePelletier ah, tak, masz całkowitą rację. Przegapiłem, że nazwy plików mogą składać się tylko z małych liter.
terdon
14

C #, 153 bajty

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

OO jest fajne i dopóki nie zdefiniujesz zmiennej:

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

to po prostu znaczy

downrep_nation
źródło
12

Bash + wspólne narzędzia linux, 15

  • 1 bajt zapisany dzięki @Dennis

Zakłada, że ​​skrypt jest sam w katalogu.

mv * `rev<<<$0`
Cyfrowa trauma
źródło
6
Możesz założyć, że plik kodu jest sam w katalogu , więc $0możesz go zastąpić *.
Dennis
Przepraszamy, ale aktualizacja zawiera mały błąd i nie działa tak, jak jest. Najprostszym rozwiązaniem jest powrót do $0poprzedniej wersji *.
Julie Pelletier,
@JuliePelletier Wydawało się, że działało to wcześniej, kiedy go wypróbowałem, ale tak, masz rację - * rozszerzenie globbing nie dzieje się po prawej stronie <<<.
Digital Trauma
7

Julia, 51 bajtów

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

Ten program powinien być niezależny od systemu operacyjnego, chociaż był testowany tylko na OS X.

Nie golfowany:

# 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.
źródło
8
Gratulacje! 20k !!!
Luis Mendo,
Większość odpowiedzi wydaje się zakładać, że plik znajduje się w bieżącym katalogu, więc nie sądzę, żebyś go potrzebował cd. W takim przypadku f=readdir()[]byłby jeszcze krótszy.
Dennis
6

MATLAB, 50 46 bajtów

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

Dzięki @Suever za usunięcie 4 bajtów i za testowanie!

Testowane na OS X El Capitan i Debian Jessie, oba z wersją Matlab R2014a.

W systemie Windows 'f'potrzebna jest flaga ( e='.m';x=mfilename;movefile([x e],[flip(x) e]),'f') do zmiany nazwy pliku podczas jego używania.

Jak to działa

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
źródło
Jaki system operacyjny 'f'jest wymagany?
Suever
@Suever Windows. Czy to nie jest potrzebne na Macu?
Luis Mendo,
Wygląda na to, że nie jest potrzebny na Macu w systemie Linux.
Suever,
@Suever Thanks! 4 bajty wyłączone :-)
Luis Mendo
@Suever Czy możesz wskazać dokładny system operacyjny, na którym działa?
Luis Mendo,
4

Ruby, 24 bajty

File.rename$0,$0.reverse

Dość oczywiste. ( $0to nazwa wykonywanego pliku).

Uruchom z ruby whateverdziałającym katalogiem katalogu zawierającego plik.

Klamka
źródło
4

Partia, 109 bajtów

@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

Uwaga 1: Pliki wsadowe muszą kończyć się na .bat; zakłada się, że plik wsadowy jest wykonywany według jego nazwy bez rozszerzenia i że .batnie można go odwrócić. Na przykład reversepróbowałby zmienić nazwę reverse.batna esrever.bat.
Uwaga 2: CMD.EXEbłędy występują po zmianie nazwy pliku wsadowego. ( COMMAND.COMnie, poza tym, że przede wszystkim nie jest w stanie manipulować łańcuchem znaków).

Edycja: Zapisano 2 bajty, używając gwarancji, że nazwa pliku jest alfabetyczna (na podstawie komentarza @ CᴏɴᴏʀO'Bʀɪᴇɴ).

Neil
źródło
3
1. DLACZEGO NIE MASZ? 2. Myślę, że możesz uratować bajt, robiącif ]%f% NEQ ] goto l
Conor O'Brien
@ CᴏɴᴏʀO'Bʀɪᴇɴ Ach, tak, nazwa pliku jest alfabetyczna, więc w rzeczywistości mogę zapisać 2 bajty, ale dziękuję za podpowiedź.
Neil
1
POTRZEBUJESZ SHOUTA W SERII, JEŻELI NIE WYKORZYSTASZ OOBL AKA SMALLTALK-80
kot
4

C, 102 bajty

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

Awaria:

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

Wreszcie wyzwanie, w którym C nie jest (tak beznadziejnie) niekonkurencyjne!


Jeśli weźmiemy „Można założyć, katalog roboczy powłoki będzie folder plik znajduje się” oznacza, że program będzie zawsze wywoływana jak ./myexecutablemożemy uprościć *n=strrchr(*v,47)aby *n=*v+1zapisać 10 znaków, ale to nie jest do końca poprawny ( można ././myexecutablena przykład wywołać ).


Również jeśli chcesz zachować rozszerzenie pliku (np. „.Out”), możesz zmienić *t=strchr(b,0)na *t=strrchr(b,46), kosztując 2 bajty. Nie jest to jednak wymagane.

Dave
źródło
Fajnie - nigdy nie szukałem, co się stanie rename, jeśli src == dest; wydaje się, że spełniasz ograniczenie palindromu za darmo.
Toby Speight
Zauważ, że wymaga to systemu plików, w którym separator stanowi punkt kodowy 47. Myślę, że obejmuje to POSIX (czy to pozwala EBCDIC /w przypadku narożnym?)
Toby Speight
@TobySpeight tak, sprawdziłem gnu.org/software/libc/manual/html_node/Renaming-Files.html w celu uzyskania wyjaśnień, ale najbliższe, jakie znalazłem, to: „Jednym szczególnym przypadkiem zmiany nazwy jest sytuacja, gdy stara nazwa i nowa nazwa to dwie nazwy tego samego pliku Konsekwentnym sposobem obsługi tego przypadku jest usunięcie starej nazwy. Jednak w tym przypadku POSIX wymaga, aby zmiana nazwy nic nie robiła i informowała o sukcesie - co jest niespójne. Nie wiemy, co zrobi twój system operacyjny. ”, Więc myślę, że jest szansa zewnętrzna po prostu usunie plik w systemach niezgodnych z POSIX. Tak, prawdziwy kod powinien sprawdzić!
Dave
Właśnie sprawdziłem linux.die.net/man/3/rename i potwierdza, że ​​Linux obsługuje go zgodnie z POSIX- em : „Jeśli stary argument i nowy argument rozstrzygną ten sam istniejący plik, rename () zwróci się pomyślnie i nie wykona żadnego innego akcja."
Dave
Byłem na stronie podręcznika Debiana: „Jeśli istnieją oldpathi newpathistnieją twarde linki odnoszące się do tego samego pliku, to rename()nic nie robi i zwraca status powodzenia” - jeśli ciągi są identyczne, odnoszą się do tego samego pliku.
Toby Speight,
3

Vitsy + * sh, 15 bajtów

iG:`?r.iG' mr',

Wyjaśnienie

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.

Pamiętaj, że w tym zgłoszeniu należy użyć niezabezpieczonej wersji Vitsy (nie można tego zrobić w Try It Online!)

Addison Crump
źródło
3

Perl 5, 18 bajtów

Trochę jak Ruby (uruchom perl nameofscript):

rename$0,reverse$0

Biorąc pod uwagę możliwą ścieżkę, jest brzydsza (47 bajtów)

($a,$b)=$0=~/(.*\/)?(.*)/;rename$0,$a.reverse$b
ilkkachu
źródło
1
Witaj i witaj w PPCG! Świetny pierwszy post!
NoOneIsHere
2

V , 29 26 bajtów

:se ri
izyw:!mv z "
dd

Ponieważ zawiera to niedrukowalne, oto zrzut heksowy:

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

Uwaga: nie będzie działać na v.tryitonline.net, ponieważ TIO nie zezwala na dostęp do plików.

Wyjaśnienie:

: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
źródło
2

Python 3, 105 bajtów

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

-Aleks.A usunięto 1 bajt.

-Digital Trauma pokazał mi os.rename (), który zabrał 62 bajty.

-muddyfish usunął 7 bajtów.

Magenta
źródło
Myślę, że możesz uratować bajt, usuwając spację po przecinku wimport
Alex A.
import os,sys;f=sys.argv[0];os.rename(f,f[::-1])powinien załatwić sprawę za 48 bajtów
Digital Trauma
wykonanie f [:: - 1] odwraca nie tylko nazwę pliku, ale całą ścieżkę. Jednak dzięki za zapoznanie się z funkcją os.rename ().
Magenta
@Magenta Dla mnie sys.argv[0]po prostu zwraca nazwę pliku bez ścieżki, gdy skrypt jest uruchamiany bezpośrednio we własnym. Helka wskazała, że ​​to w porządku
Digital Trauma
@DigitalTrauma, kiedy uruchomiłem program samodzielnie, sys.arg [0] zwrócił pełną ścieżkę. Dodam drugie rozwiązanie, w którym sys.argv [0] to tylko nazwa pliku.
Magenta
2

PHP, 84, 70, 54 bajty

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


EDYCJA: usunięto 14 bajtów dzięki insertusernameherew komentarzach
EDYCJA: usunięto 16 bajtów dzięki Martijnw komentarzach

tttony
źródło
2
Można je dostać w dół do 70 bajtów : rename($f=__FILE__,__DIR__."/".strrev(pathinfo($f)[filename]).".php");.
inserttusernamehere
Doskonały !!! ale twój kod jest lepszy, wow, masz 31 bajtów
tttony
Czy nie możesz uczynić go względnym? Oszczędź 7 bajtów:rename($f=__FILE__,"./".strrev(pathinfo($f)[filename]).".php");
Martijn,
lub nawet mniejszy:rename(__FILE__,strrev(basename(__FILE__,'.php')).'.php');
Martijn,
Fajne! Dodając zmienne mam teraz 54 bajty
tttony
2

PowerShell, 39 bajtów

mi *(-join((ls).name)[-5..-999]+'.ps1')
Bevo
źródło
Cześć, witamy w PPCG! Miły pierwszy post!
Rɪᴋᴇʀ
2

Python 2 , 41 bajtów

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

Demo na Bash.

Python naprawdę nie dba o rozszerzenie pliku, więc możemy po prostu przerzucić całą nazwę pliku.

Bubbler
źródło
1

PHP, 31 bajtów

Chyba nic wielkiego do wyjaśnienia:

rename($x=$argv[0],strrev($x));
wstawić nazwę tutaj
źródło
1

Perl 6 ,  70   27 bajtów

Gdyby musiał pracować w innym katalogu roboczym, potrzebujesz czegoś takiego:

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

Ponieważ katalog roboczy będzie tym samym katalogiem co program, można go uprościć po prostu:

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

Wyjaśnienie:

$_ = $*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
źródło
1

JavaScript (węzeł), 108 104 68 bajtów

36 bajtów zapisanych, dzięki Downgoat!

Wersja Windows:

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

Inna wersja:

require("fs").rename(F=__filename,F.split(/.*\/|/).reverse().join``)
Conor O'Brien
źródło
@Upgoat Nie muszę, nie sądzę. Dopasowuję jsna końcu ścieżki pliku, poprzedzonej znakiem. To zawsze będzie ..
Conor O'Brien
1

JavaScript ES6 (Node.js) 70 bajtów

No Regex Yay!

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

Każda pomoc jest mile widziana

MayorMonty
źródło
1

PowerShell v4 +, 68 bajtów

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

Działa tylko, ponieważ skrypt ma gwarancję, że sam znajdzie się w katalogu. Wykonuje ls(alias dla Get-ChildItem) i pobiera .Namewynikowe obiekty. Przechowujemy to w, $ca następnie -splitw dosłownym okresie, aby uzyskać nazwę pliku i rozszerzenie oraz przechowywać je odpowiednio w $ai $b.

Dalej jest polecenie mv(alias dla Move-Item), w którym przechodzimy $cdo $a(odwróconego) .$b.

Przykład

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
źródło
1

Python (2.7 lub 3.4+), 61 49 bajtów

Uważam, że jest to zbliżone do optymalnego rozwiązania Python:

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

Zainspirowany s4b3r6odpowiedzią, ale używa wycinania list zamiast odwrotnego i zapisuje __file__zmienną w celu zapisania bajtów przy dwukrotnym użyciu.

Uwaga: Zakłada się, że nazwa pliku jest zawsze *.py. Nieco bardziej ogólnym rozwiązaniem, które może obsłużyć dowolne dwuznakowe rozszerzenie pliku, byłoby a[-3:]zastąpienie ".py"go kosztem 1 dodatkowego bajtu.

Aktualizacja: Zapisano 12 bajtów, używając sztuczki wycinania list, a[-4::-1]aby usunąć rozszerzenie pliku, zamiast dzielić, a następnie cofać a.split(".")[0][::-1].

Jaden Burt
źródło
1

PowerShell, 112 bajtów

Nie zamierzam pobić cmdów unixowych, dodając tylko dwa pensy dla zabawy :-)

gci * | % { $n=($_.basename[-1..-(($_.basename).length)] -join “”)+$_.Extension; mv -Path $_.Fullname -Dest $n }
rb101
źródło
Witamy w PPCG! Wymagamy, aby odpowiedzi wyświetlały ich wynik, więc edytowałem go dla Ciebie. Możesz także sformatować kod, podświetlając go i wybierając przycisk, który wygląda jak nawiasy {}, lub dodając 4 spacje przed kodem.
FryAmTheEggman
0

PowerShell, 50 bajtów

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

Jest tylko jeden plik, więc mv *symbol wieloznaczny powłoki będzie miał tylko jeden wynik. Nazwą docelową jest (ls).basenamelista wszystkich plików (alias „dir”), wywoływana jest właściwość BaseName - a ponieważ jest tylko jeden plik, PowerShell rozpakuje tablicę 1-elementową w ciąg. Zapisz nazwę pliku $f, a następnie zindeksuj odliczanie, a -joinodwrócone znaki z powrotem w łańcuch. Dodaj obowiązkowy .ps1sufiks.

TessellatingHeckler
źródło
0

AutoIt, 45 bajtów

$a=@ScriptName
FileMove($a,StringReverse($a))
Daniel
źródło
0

Python 2.7, 68 bajtów

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

To chyba najlepsze, co mogę dostać. Właśnie udowodniłem, że się mylę.

Alex
źródło
0

Python (2 i 3), 88 78 bajtów

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

Wykorzystuje fakt, że nazwa pliku jest podawana przez sys.argv (ponieważ katalog roboczy to folder, w którym znajduje się plik) i korzysta z os.rename. Irytujące, odwrócone zwraca iterator, więc musimy użyć łączyć.

Edycja: Zapisano 10 bajtów, używając __plik___ zamiast sys.argv [0], jak sugeruje @muddyfish dla @DigitalTrauma.

s4b3r6
źródło
0

tcl, 42

file rename $argv0 [string reverse $argv0]
sergiol
źródło
0

Skrypt Visual Basic, 44 bajtów

WScript.Echo(StrReverse(WScript.ScriptName))

Przykładowe dane wyjściowe dla pliku o nazwie reverse.vbs(Uruchom z cscript):

sbv.esrever
Gabriel Mills
źródło
0

SmileBASIC 60 bajtów

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

Alternatywny:

P$=PRGNAME$()T$=P$*1WHILE""<T$Q$=Q$+POP(T$)WEND
RENAME P$,Q$
12Me21
źródło