Настаивайте на новом имени файла

19

Во время выполнения продолжайте запрашивать строку ввода, пока пользовательский ввод не станет именем существующего файла или каталога или другого элемента файловой системы относительно текущего рабочего каталога. Затем верните / распечатайте последнее введенное имя файла. Вы можете предположить, что все пользовательские вводы будут действительными именами файлов.

Псевдокод 1

myform = new form("GUI")
myform.mytxt = new editfield("")
myform.ok = new button("OK")
repeat
  waitfor(myform.ok,"click")
until not filesystem.exists(myform.mytxt.content)
return(myform.mytxt.content)

Псевдокод 2

LET TEXT = "."
WHILE HASFILE(TEXT) DO
  TEXT = PROMPT("")
ENDWHILE
RETURN TEXT

Примеры пользовательского ввода, который вызовет повторный запрос при использовании TIO:

.
..
.env.tio
/
/bin/[
/lost+found

Примеры пользовательского ввода, который будет возвращаться, когда на TIO:

...
env.tio
../../bin/]
/lost/found
Адам
источник
Я довольно новичок в коде гольфа и не могу найти никакой информации о том, что считается решением. Нужно ли включать функцию main () для языков, которые требуют ее в программе, или это может быть частью заголовка? Могут ли операторы импорта быть частью заголовка в TIO или они должны быть частью кода и считаться с количеством байтов? Например, у меня есть такое решение: goo.gl/8RWNgu, но я не уверен, что байты будут легитимными.
Макотосан
2
@Makotosan Как функции, так и полные программы хороши, хотя в случае функций их необходимо многократно использовать. Импорт обычно должен быть включен в число байтов.
Мартин Эндер

Ответы:

7

Пакетный, 37 байтов

@set/ps=
@if exist %s% %0
@echo %s%

(По какой-то причине текущая Windows 10 CMD.EXEпортит заголовок при выполнении %0.)

Нил
источник
7

Mathematica, 33 28 байт

f:=Input[]/._?FileExistsQ:>f

Это предполагает среду ноутбука Mathematica, где мы можем запросить ввод от пользователя Input[]. Пользовательский ввод должен быть действительным строковым литералом , например, "ab/cd.ef"вместо just ab/cd.ef. Положительным моментом является то, что входные данные могут быть произвольным выражением Mathematica, которое вычисляет входную строку.

Это определяет символ, fкоторый при оценке выполняет требуемое вычисление и, в конечном счете, оценивает первый несуществующий пользовательский ввод. По сути, это нулевая функция, которую мы не должны включать ...[]для вызова.

Мы также можем сохранить несколько байтов поверх традиционного Ifвыражения, используя оператор подстановки шаблона /..

Мартин Эндер
источник
Это не удастся, если пользователь введет одно и то же дважды
Лукас Ланг
@ Mathe172 Хороший улов, слишком плохой, тогда мне придется пойти по скучной петле.
Мартин Эндер
Оказывается, нет, и это даже на байт короче. :)
Мартин Эндер
7

Perl 5 -ln , 12 10 байт

-2 байта благодаря @DomHastings

#!/usr/bin/perl -ln
-e||1/!say

Попробуйте онлайн!

Тон Хоспел
источник
1
Я думаю, что -eработает без указания $_, может не работать в некоторых случаях, хотя я думаю ...
Dom Hastings
@DomHastings должен работать во всех случаях. Документально подтверждено, что $ _ используется, когда аргумент -e отсутствует.
труба
@DomHastings Спасибо. По какой-то причине я подумал, что -eэто исключение, но, конечно, это не так
Тон Хоспел
4

Баш, 29

read f
[ -e $f ]&&$0||echo $f
Цифровая травма
источник
@ Adám Я не уверен, почему это не работает в TIO. Достаточно сказать, что если вы сохраните его в виде файла сценария и запустите его, я думаю, что он работает, как и ожидалось
Digital Trauma
1
@ Adám Это работает, проблема, с которой вы столкнулись, заключалась в том, что программа пыталась вызвать программу, в .code.tioкоторой содержится тело скрипта, но нет информации о том, как его запустить. Я не уверен, есть ли хороший способ обойти shebang или этот сценарий должен быть на вашем пути, хотя.
FryAmTheEggman
2
Вы можете обойти оба (за счет двух байтов), изменив $0на . $0. Попробуйте онлайн! , Так как .использует относительные имена путей и текущую оболочку.
Крис
1
Что он считает *входным?
Тоби Спейт
4

PowerShell 2 (через 6), 35 байт

while(Test-Path($x=Read-Host)){};$x

Read-Hostожидает ввода (если задана строка в качестве параметра, используется строка в качестве подсказки). Если предоставленным вводом является имя файла (или имя папки) для существующего, Test-Pathвозвращается $true, и блок бездействия {}выполняется, и он повторно запрашивает ввод. Если Test-Pathвозвращается, $falseпотому что ввод не является существующим файлом или папкой, блок «ничего не делать» не выполняется, и имя ввода печатается.

Джефф Цейтлин
источник
1
Добро пожаловать в PPCG!
Мартин Эндер
Вам не нужна точка с запятой после {}, чтобы сохранить байт.
Веска
@Veskah - я сделал в PS2, и он не сломал PS3 +
Джефф Цейтлин
Ах, мой плохой. Не проверял это в 2.
Веска
4

C (gcc) , 62 байта

main(){char b[99];while(scanf("%s",b)&&!access(b,0));puts(b);}

Попробуйте онлайн!

main(){
    char b[99]; // Declare buffer b
    while (scanf("%s",b)&&!access(b,0));    // Take one line of input, and test if file is accessible (exists)
    puts (b);   // If doesn't exist, loop ends and print file
}
Арктическая кона
источник
Добро пожаловать в PPCG! Вы можете использовать, while(gets(b),!access(b,0));чтобы сохранить 7 байтов.
Деннис
3

Фанки , 40 байт

tryfor)io.open(s=io.read())catchprint(s)

В стиле фанк, здесь используются ключевые слова, заклинивающие друг друга, непревзойденные скобки и неявные ключевые слова. Вычищен, это выглядит так:

try{
    while(true){
        s = io.read()
        io.open(s)
    }
}catch(e){
    print(s)
}

Сломать

try                                     // Try statement, this one is expected to fail.
   for)                                 // for) is a for loop with no arguments, which is functionally equivilent to a while(true) loop, much like for(;;)
       io.open(                         // Try to open a file relative to the CWD. If this fails to find a file, it will throw an error and escape the try/catch
               s=io.read()              // Read a line from STDIN and store it as s, this will still pass it to the arguments of the call.
                          )
                           catch        // When io.open fails
                                print(s)// Print out the last entered line.
Ataco
источник
3

Haskell , 76 байт

import System.Directory
f=do x<-getLine;b<-doesPathExist x;last$pure x:[f|b]

Попробуйте онлайн!

Возвращает IO xгде xвведенное имя файла, который не существует.

Ungolfed

import System.Directory

insist = do { file <- getLine;
              exists <- doesPathExist file;
              if exists then insist else pure file }
totallyhuman
источник
3

R , 66 51 байт

while((s=readline())%in%list.files(a=T)){};print(s)

-15 байт благодаря планнапу

Запускает потенциально бесконечный цикл, где на каждой итерации

  1. Одна строка пользовательского ввода хранится в переменной s
  2. Мы проверяем, есть ли входные данные в списке имен файлов для рабочего каталога ( a=Tопция list.files()должна использоваться, чтобы подобрать такие вещи, как ..)
  3. Если sв этом списке, мы переходим к следующей итерации; если нет, мы разрываем цикл и печатаем s.
duckmayr
источник
Как насчет сокращения его до while((s=readline())%in%list.files(a=T)){};print(s)?
plannapus
@plannapus Отличная идея! Incorporated.
duckmayr
Пожалуйста. Кроме того, я не думал об этом сразу, но функционирует list.filesи dirявляется синонимом, так что вы можете заменить его dirздесь.
plannapus
Вы также можете заменить readline()наscan(,'')
JAD
И printсcat
JAD
3

Python 3 , 55 байт

import glob
s="."
while glob.glob(s):s=input()
print(s)

Попробуйте онлайн!

-4 байта благодаря ManfP
-6 байтов благодаря Рику Ронгену

HyperNeutrino
источник
2
@ Adám ужасная неверная интерпретация, извините
HyperNeutrino
Вы можете заменить первый input()на"."
ManfP
1
import osи os.path.existsна три байта короче.
Джонатан Аллан
1
Рик Ронген предложил import globи while glob.glob(s):...в редакции.
Мартин Эндер
@MartinEnder спасибо за сообщение :)
HyperNeutrino
3

C #, 101 байт

()=>{var s="";try{for(;;System.IO.File.GetAttributes(s=System.Console.ReadLine()));}catch{}return s;}

Для каждого из 4 действительных возвращаемых значений:

Ungolfed

() =>
{
    var s = "";
    try
    {
        for(;; System.IO.File.GetAttributes(s = System.Console.ReadLine()));
    }
    catch {}
    return s;
}

объяснение

опирается на тот факт, что File.GetAttributes () создает исключение, если объект файловой системы, указанный в его аргументе, не существует.

Ричард II
источник
2

Powershell 3.0, 75 байт

$x=1;while($x){$i=Read-Host;$x=Test-Path("$PSScriptRoot\$i")};Write-Host $i

Первая попытка; Я уверен, что есть несколько оптимизаций, которые я мог бы сделать.

Немного более читаемая форма:

$x=1;                                                                       # Make sure we enter our while loop.
     while($x){                                                             # While we keep getting file names,                   
               $i=Read-Host;                                                # Get input from the user
                            $x=Test-Path("$PSScriptRoot\$i")};              # Combine our path with the user input, and see if it already exists.
                                                              Write-Host $i # Return the final (valid) file name.
Arkitekt
источник
Разве это не будет работать даже без $PSScriptRoot\?
Адам
Добро пожаловать в PPCG! Несколько быстрых игр - forвместо этого вы можете использовать цикл, который позволяет перенести инициализацию в конструктор циклаfor($x=1;$x){...} . Во-вторых, вы можете избавиться от того Write-Host, что Write-Outputпри завершении программы есть неявное завершение всего, что осталось в конвейере, поэтому достаточно просто уйти $iоттуда.
AdmBorkBork
Смотрите мое решение ниже; Я уменьшил вдвое количество ваших байтов.
Джефф Цейтлин
@ Adám: Возможно! Я на самом деле не учел это. : P AdmBorkBork Спасибо! Я долго скрывался. Это хорошие идеи; неявный вывод даже не приходил мне в голову ...
Арктект
2

Java 9, 87 байт

v->{String s;for(;new java.io.File(s=System.console().readLine()).exists(););return s;}

Ungolfed

JVM от TIO, по-видимому, не имеет системыConsole , поэтому она там не тестируется (см. System.console()).

import java.util.function.*;
class Main {
  public static void main(String[] args) {
    Function<Void,String> f =


v->{
  String s;
  for(;new java.io.File(s=System.console().readLine()).exists(););
  return s;
}


;
    System.out.println(f.apply(null));
  }
}
Оливье Грегуар
источник
2

JavaScript (Node.js) , 158 118 байт

require('readline').createInterface({input:process.stdin}).on('line',s=>require('fs').existsSync(s)||--console.log(s))

Попробуйте онлайн!

Благодарим @ ConorO'Brien за более короткую версию. Встроенные объекты вместо использования consts и использования условия выхода из ошибки вместо явного выхода.

Makotosan
источник
1
Хороший ответ пока, но есть место для потенциала. Вы можете использовать этот подход несколькими способами: вы можете опустить оба const, и вы также можете заменить каждую переменную ее определением. Тогда вместо использования s=>{if(...){...}}вы можете использовать s=>require('fs').existsSync(s)||process.exit(console.log(s)). Кроме того, вы можете выйти с ошибкой, поэтому вы можете записать лямбда как s=>require('fs').existsSync(s)||--console.log(s). Попробуйте онлайн!
Конор О'Брайен
Отличные идеи! Благодарность!
Макотосан
1

Perl 6, 39 байт

my$f=".";while $f.IO.e {$f=get};say $f;

Это работает в REPL, но, похоже, не работает должным образом в TIO.

mattchuranu
источник
Как насчет say first !*.IO.e,lines(23 байта)?
nwellnhof
Выше, вероятно, блокируется на неопределенный срок при запуске из командной строки, но что-то вроде {}while ($_=get).IO.e;.sayдолжно работать.
nwellnhof
1

PHP, 43 байта

<?for(;file_exists($f=readline()););echo$f;

Запустите как CLI. Довольно легко понять.

ТТГ
источник
1

APL (Dyalog) , 17 байт

{⍞}⍣{~⎕NEXISTS⍺}⍬

Попробуйте онлайн!

Уриэль
источник
Возвращает второй несуществующий вход ( the_prev_wasnt_filenameвместо env.tio). Изменить и тогда вы тоже можете избавиться '.'.
Адам
1

Атташе , 35 байт

{While[FileExists[x:=Prompt[]],0]x}

Попробуйте онлайн!

Альтернативные решения

35 байт: {If[FileExists[x:=Prompt[]],$[],x]} рекурсивная функция.

37 байт: {NestWhile[p:=Prompt,p[],FileExists]} итерационная функция.

Конор О'Брайен
источник
1

Мин , 38 байт

"." :a (a exists?) ("" ask @a) while a

Оставляет последнее введенное имя файла в стеке.

объяснение

"."         ; Put . on the stack. Every directory should contain this...
:a          ; Assign to a
(a exists?) ; A quot that checks if a exists in current directory
("" ask @a) ; Read line from stdin, assign to a
while       ; Do the second quote while the first leaves true on the stack
a           ; Leave a on the stack
Panda0nEarth
источник