Напишіть програму, яка перевертає назву вихідного файлу


27

У єдиний файл напишіть програму, яка не потребує введення даних і не дає результатів. Під час запуску він повинен змінити ім'я файлу, в якому він міститься, незалежно від того, що це ім’я , не змінюючи код або створюючи інші тривалі побічні ефекти.

Будь-який спосіб досягти цього - це добре. Важливо лише те, що після запуску програми єдиною тривалою зміною є те, що ім'я файлу було перевернуто. наприклад, в каталозі не повинно бути нових файлів.

Якщо запустити програму ще раз, слід змінити назву назад. Дійсно, програму слід мати можливість запускати довільно багато разів.

Для цілей цього виклику:

  • Ви можете припустити, що імена файлів завжди є рядками з малих літер (az) довжиною від 1 до 127 символів. (Якщо ваша мова вимагає, щоб файли мали розширення для запуску, просто поверніть частину перед розширенням, наприклад mycode.batedocym.bat.)
  • Ви можете припустити, що файл коду знаходиться в каталозі сам по собі, тому він не матиме конфліктів імен (за винятком самого себе).
  • Ви не можете припустити, що ім'я файлу не є паліндром, тобто те саме, коли перевертається. Імена файлів, які є паліндромами, повинні працювати так само добре, як і ті, що їх немає.
  • Ви можете прочитати вміст або метадані вашого файлу. Тут немає обмежень щодо .
  • Можна припустити, що ваша програма буде працювати в певній, сучасній, звичайній операційній системі (наприклад, Windows / Linux), оскільки не всі оболонки мають однаковий набір команд.

Як конкретний приклад, скажімо, у вас програма Python у файлі, який називається mycodeу власному каталозі. Біг

python mycode

в терміналі має призвести до повернення імені файлу edocym. Файл edocymповинен бути один у своєму каталозі - жоден іменний файл більше не mycodeповинен існувати. Біг

python edocym

поверне ім'я назад до mycode, після чого процес можна буде повторити нескінченно.

Якщо той самий файл Python було перейменовано racecar(без зміни коду), а потім запустіть

python racecar

нічого не повинно помітно змінюватися, оскільки "гоночний автомобіль" є паліндром. Це те саме, якщо ім'я файлу було, скажімо, aабо xx.

Виграє найкоротший код у байтах. Tiereaker є вищою відповіді.


Чи має значення поточний робочий каталог?
Бред Гілберт b2gills

@ BradGilbertb2gills Ви повинні бути в змозі скопіювати папку з програмою в інше місце і все-таки працювати в ній (якщо припустимо, що у вас є дозволи та інше). Ви можете припустити, що робочим каталогом оболонки буде папка, в якій знаходиться файл.
Захоплення Calvin's

6
Що робити, якщо ми використовуємо компільовану мову? Як виконуваний файл впливає на ваші правила?
ЕМБЛЕМ

Запит на уточнення "не приймає жодних даних і не видає результатів". Технічно ім'я файлу - це вхід, який не повинен бути отриманий з файлової системи, а змінене ім'я повинно бути надіслано до файлової системи. Це вхід і вихід. Можливо, варто уточнити, що інші виходи не дозволені.
atk

Крім того, чи вважаєте ви використання дочірніх процесів порушенням правил введення / виводу? Тобто, виклик окремого процесу для виконання частини завдання, наприклад, повернення імені, зажадає надіслати ім'я іншого процесу (вихід з вашого коду та введення в додаток) та отримати значення від процесу (вихід процесу та вхід у додаток).
atk

Відповіді:


41

Bash + загальні утиліти Linux, 13 байт

Мій метод схожий на @ DigitalTrauma, але трохи коротший завдяки роботі з ls:

mv * `ls|rev`

Ой - дуже добре.
Цифрова травма

20
Ласкаво просимо до головоломки програмування та коду для гольфу! Це дуже приємна перша відповідь. :)
Олексій А.

1
Працює лише, якщо в каталозі немає іншого файлу.
WGroleau

1
@WGroleau && terdon: обидва ваші коментарі вірні, але питання вже стосується цих двох припущень.
Джулі Пелтьє,

@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");}

OO круто, і все, поки у вас визначена змінна:

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

це просто означає


12

Bash + загальні утиліти Linux, 15

  • 1 байт збережено завдяки @Dennis

Передбачає, що сценарій знаходиться в каталозі сам по собі.

mv * `rev<<<$0`

6
Ви можете припустити, що файл коду знаходиться в каталозі сам по собі , тому $0його можна замінити *.
Денніс

Вибачте, але у вашому оновлення є невелика помилка, і вона не працює як є. Найпростіший виправлення - повернутися ближче до того, що ви мали раніше, $0а не до останнього *.
Джулі Пелтьє,

@JuliePelletier Здавалося, працював раніше, коли я спробував це, але так, ти маєш рацію - * розширення глобальної сфери не відбувається праворуч від <<<.
Цифрова травма

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
Вітаю! 20к !!!
Луїс Мендо

Здається, більшість відповідей припускають, що файл знаходиться в поточному каталозі, тому я не думаю, що він потрібен 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'потрібні, що потрібно?
Suever

@Suever Windows. Хіба це не потрібно на Mac?
Луїс Мендо

Мабуть, не потрібен на Mac Linux.
Suever

@Suever Дякую! 4 байти від :-)
Луїс Мендо

@Suever Чи можете ви вказати точну ОС, на якій працює?
Луїс Мендо

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не буде, за винятком того, що це в першу чергу нездатне до маніпуляцій з рядками.)

Редагувати: збережено 2 байти, використовуючи гарантію, що ім'я файлу є алфавітним (на основі коментаря @ CᴏɴᴏʀO'Bʀɪᴇɴ).


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

Зауважте, що для цього потрібна файлова система, де кодова точка 47 є роздільником. Я думаю, що це включає POSIX (чи це дозволяє EBCDIC /у кутовому випадку?)
Toby Speight,

@TobySpeight так, я перевірив gnu.org/software/libc/manual/html_node/Renaming-Files.html для уточнення, але найближчим моїм висновком було "Один особливий випадок перейменування - це коли прізвище та нове ім'я - це два імені для одного файлу . Послідовним способом вирішення цього випадку є видалення старого імені. Однак у цьому випадку POSIX вимагає, щоб перейменування нічого не робило та повідомляло про успіх - що непослідовно. Ми не знаємо, що зробить ваша операційна система ", тому я думаю, що є зовнішній шанс, він просто видалить файл у системах, що не підтримують POSIX. Так що, справжній код повинен перевірити!
Дейв

Я щойно перевірив linux.die.net/man/3/rename, і це підтверджує, що Linux обробляє це POSIX сумісно: "Якщо старий аргумент і новий аргумент вирішуються в тому ж існуючому файлі, перейменування () повернеться успішно і не виконає жодного іншого дії ".
Дейв

Я збирався зі сторінкою Debian: "Якщо oldpathі newpathіснують жорсткі посилання, що посилаються на один і той же файл, тоді rename()нічого не робиться, і повертає статус успіху" - якщо рядки однакові, вони посилаються на той самий файл.
Toby Speight

3

Віци + * ш, 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

V , 29 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

Примітка: це не буде працювати на v.tryitonline.net, оскільки TIO не дозволяє доступ до файлів.

Пояснення:

: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 байти.

-мудріф видалив 7 байт.


Я думаю, що ви можете зберегти байт, видаливши пробіл після коми черезimport
Алекс А.

import os,sys;f=sys.argv[0];os.rename(f,f[::-1])повинні зробити трюк на 48 байт
Digital Trauma

виконуючи функцію f [:: - 1], повертає не тільки ім'я файлу, але й увесь шлях. Однак дякую, що познайомив мене з функцією os.rename ().
Маджента

@Magenta Для мене sys.argv[0]просто повертає ім'я файлу лише без шляху, коли сценарій запускається самостійно. Хелка вказала, що це нормально
Digital Trauma

@DigitalTrauma, коли я запустив програму самостійно, sys.arg [0] повернув повний шлях. Не можу додати друге рішення, де sys.argv [0] - лише ім'я файлу.
Маджента

2

PHP, 84, 70, 54 байти

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


EDIT: видалено 14 байт завдяки insertusernamehereкоментарям
EDIT: видалено 16 байт завдяки Martijnкоментарям


2
Ви можете отримати його до 70 байт : rename($f=__FILE__,__DIR__."/".strrev(pathinfo($f)[filename]).".php");.
insertusernamehere

Відмінно !!! але ваш код краще,
уау

Ви не можете зробити це відносним? Врятував 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ɪᴋᴇʀ

2

Python 2 , 41 байт

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

Демо на Bash.

Python насправді не хвилює розширення файлу, тому ми можемо просто перевернути все ім’я файлу.



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 байт

36 байтів збережено, завдяки Downgoat!

Версія Windows:

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

Інша версія:

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

@Upgoat мені не потрібно, я не думаю. Я співставляю jsв кінці файлового шляху, якому передує символ. Це завжди буде ..
Conor O'Brien

1

JavaScript ES6 (Node.js) 70 байт

Немає Regex 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's, але використовує нарізку списку замість зворотного і зберігає __file__змінну, щоб зберегти байти при використанні її двічі.

Примітка. Це передбачає, що ім'я файлу завжди *.py. Трохи більш загальне рішення, яке може обробити будь-яке розширення двох символів, було б використовувати a[-3:]для заміни ".py"ціною 1 зайвий байт.

Оновлення. Збережено 12 байтів, використовуючи трюк нарізки списку, a[-4::-1]щоб видалити розширення файлу, а не розбивати його, а потім реверсувати 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

0

PowerShell, 50 байт

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

Існує лише один файл, тому mv *підстановочний символ оболонки матиме лише один результат. Назва призначення - (ls).basenameце список усіх файлів (псевдонім для 'dir'), вимагає властивості BaseName - а оскільки є лише один файл, PowerShell розпакує масив 1-го елемента в рядок. Збережіть це ім'я файлу $f, а потім індексуйте його за допомогою зворотного відліку, а -joinсимволи повернуті назад - у рядок. Додайте обов’язковий .ps1суфікс.



0

Python 2.7, 68 байт

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

Це, мабуть, найкраще, що я можу отримати. Я просто довів себе неправильним.


0

Пітон (2 і 3), 88 78 байт

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

Експлуатує той факт, що ім'я файлу задається sys.argv (як робоча директорія - це папка, у якій знаходиться файл), і використовує os.rename. Прикро, повернутий назад повертає ітератор, тому нам доводиться використовувати приєднання.

Редагувати: збережено 10 байтів, використовуючи __file__ замість sys.argv [0], як запропонував @muddyfish @DigitalTrauma.



0

Візуальний базовий сценарій, 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$
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.