Insista em um novo nome de arquivo

19

No tempo de execução, continue solicitando uma linha de entrada até que a entrada do usuário não seja o nome de um arquivo ou diretório existente ou outro item do sistema de arquivos, relativo ao diretório de trabalho atual. Em seguida, retorne / imprima o último nome de arquivo digitado. Você pode assumir que todas as entradas do usuário serão nomes de arquivos válidos.

Pseudo-código 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)

Pseudocódigo 2

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

Exemplos de entrada do usuário que causarão um novo aviso quando estiver no TIO:

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

Exemplos de entrada do usuário que retornarão quando estiver no TIO:

...
env.tio
../../bin/]
/lost/found
Adão
fonte
Sou bastante novo em codificar golfe aqui e não consigo encontrar nenhuma informação sobre o que conta como solução. Preciso incluir a função main () para idiomas que a exigem em um programa ou isso pode fazer parte do cabeçalho? As instruções de importação podem fazer parte do cabeçalho no TIO ou precisam fazer parte do código e contar com a contagem de bytes? Por exemplo, eu tenho esta solução: goo.gl/8RWNgu, mas não tenho certeza se os bytes seriam legítimos.
Makotosan
2
@ Makotosan Ambas as funções e programas completos são bons, embora no caso de funções precisem ser reutilizáveis. As importações geralmente precisam ser incluídas na contagem de bytes.
Martin Ender

Respostas:

7

Lote, 37 bytes

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

(Por algum motivo, o Windows 10 atual CMD.EXEcorrompe o título quando executa o %0.)

Neil
fonte
7

Mathematica, 33 28 bytes

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

Isso pressupõe o ambiente de notebook do Mathematica, onde podemos consultar as entradas do usuário Input[]. A entrada do usuário deve ser uma literal de cadeia de caracteres real , portanto, em "ab/cd.ef"vez de apenas ab/cd.ef. A vantagem é que a entrada pode ser uma expressão arbitrária do Mathematica que calcula a sequência de entrada.

Isso define um símbolo fque, quando avaliado, executa a computação necessária e, por fim, avalia a primeira entrada de usuário inexistente. É essencialmente uma função nula, na qual não precisamos incluir ...[]para chamá-lo.

Também podemos salvar um monte de bytes em uma Ifexpressão tradicional usando o operador de substituição de padrão /..

Martin Ender
fonte
Esta falha se o usuário insere a mesma coisa duas vezes
Lukas Lang
@ Mathe172 Boa captura, muito ruim, então eu vou ter que ir com o loop chato.
Martin Ender
Acontece que não, e é ainda um byte mais curto. :)
Martin Ender
7

Perl 5 -ln , 12 10 bytes

-2 bytes graças a @DomHastings

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

Experimente online!

Ton Hospel
fonte
1
Eu acho que -eobras sem especificar $_, pode não funcionar para alguns casos que eu acho ...
Dom Hastings
@DomHastings Deve funcionar em todos os casos. Está documentado que $ _ é usado quando não há argumento para -e.
pipe
@DomHastings Obrigado. Por alguma razão eu pensei que -eera uma exceção, mas é claro que não é #
H H Ton Ton Evang
4

Bash, 29

read f
[ -e $f ]&&$0||echo $f
Trauma Digital
fonte
@ Adám Não sei por que não funciona no TIO. Basta dizer que, se você salvá-lo como um arquivo de script e executá-lo, eu acho que ele funciona como esperado
Digital Trauma
1
@ Adám Isso funciona, o problema que você tinha era que o programa estava tentando chamar o .code.tioque contém o corpo do script, mas nenhuma informação sobre como executá-lo. Não tenho certeza se existe uma boa maneira de contornar o shebang ou se esse script precisa estar no seu caminho.
FryAmTheEggman
2
Você pode contornar os dois (ao custo de dois bytes) alterando $0para . $0. Experimente online! . Desde .usa nomes de caminho relativos e o shell atual.
31418 Chris
1
O que ele pensa *como entrada?
Toby Speight
4

PowerShell 2 (até 6), 35 bytes

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

Read-Hostaguarda a entrada (se for fornecida uma string como parâmetro, a usará como um prompt). Se a entrada fornecida for um nome de arquivo (ou nome de pasta) para um que exista, Test-Pathretornará $truee o bloco do-nothing será {}executado e solicitará novamente a entrada. Se Test-Pathretornar $falseporque a entrada não é um arquivo ou pasta existente, o bloco do-nothing não é executado e o nome da entrada é impresso.

Jeff Zeitlin
fonte
1
Bem-vindo ao PPCG!
Martin Ender
Você não precisa de ponto e vírgula após o {} para salvar um byte.
Veskah
@Veskah - eu fiz no PS2, e não quebrar PS3 +
Jeff Zeitlin
Ah, meu mal. Não testei em 2.
Veskah 23/05
4

C (gcc) , 62 bytes

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

Experimente online!

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
}
Arcona Kona
fonte
Bem-vindo ao PPCG! Você pode usar while(gets(b),!access(b,0));para salvar 7 bytes.
Dennis
3

Funky , 40 bytes

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

No verdadeiro estilo descolado, ele usa palavras-chave encravadas uma na outra, colchetes inigualáveis ​​e palavras-chave implícitas. Limpo, parece com:

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

Demolir

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
fonte
3

Haskell , 76 bytes

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

Experimente online!

Retorna IO xonde xé o nome inserido do arquivo que não existe.

Ungolfed

import System.Directory

insist = do { file <- getLine;
              exists <- doesPathExist file;
              if exists then insist else pure file }
totalmente humano
fonte
3

R , 66 51 bytes

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

-15 bytes graças ao plannapus

Executa um loop potencialmente infinito, em que em cada iteração

  1. Uma única linha de entrada do usuário é armazenada na variável s
  2. Verificamos se a entrada está na lista de nomes de arquivos para o diretório ativo (a a=Topção list.files()deve ser usada para selecionar coisas como ..)
  3. Se sestiver nessa lista, vamos para a próxima iteração; caso contrário, quebramos o loop e imprimimos s.
duckmayr
fonte
Que tal encurtá-lo while((s=readline())%in%list.files(a=T)){};print(s)?
plannapus
@plannapus Ótima idéia! Incorporado.
duckmayr
Seja bem-vindo. Além disso, eu não pensei nisso imediatamente, mas funciona list.filese diré sinônimo, então você pode substituí-lo por diraqui.
plannapus
você também pode substituir readline()porscan(,'')
JAD
E printcomcat
JAD
3

Python 3 , 55 bytes

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

Experimente online!

-4 bytes graças ao ManfP
-6 bytes graças ao Rick Rongen

HyperNeutrino
fonte
2
@ Adám péssima interpretação, desculpe
HyperNeutrino 15/0318
Você pode substituir o primeiro input()por"."
ManfP
1
import ose os.path.existsé três bytes mais curto.
Jonathan Allan
1
Rick Rongen sugeriu import globe while glob.glob(s):...em uma edição.
Martin Ender
@MartinEnder Obrigado por me dizer :)
HyperNeutrino
3

C #, 101 bytes

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

Para cada um dos 4 valores de retorno válidos:

Ungolfed

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

Explicação

depende do fato de que File.GetAttributes () lança uma exceção se o objeto do sistema de arquivos especificado em seu argumento não existir.

Richard II
fonte
2

Powershell 3.0, 75 bytes

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

Primeira tentativa; Tenho certeza de que há algumas otimizações que eu poderia fazer.

Uma forma um pouco mais legível:

$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
fonte
Não funcionaria mesmo sem $PSScriptRoot\?
Adám 16/03/18
Bem-vindo ao PPCG! Alguns golpes rápidos - você pode usar um forloop, o que permite mover a inicialização para o construtor de loop for($x=1;$x){...}. Em segundo lugar, você pode se livrar do fato de Write-Hostque há um implícito Write-Outputna conclusão do programa para qualquer coisa restante no pipeline, portanto, apenas sair $idali será suficiente.
AdmBorkBork 16/03/19
Veja minha solução abaixo; Reduzi pela metade a contagem de bytes.
9138 Jeff Zeitlin #:
@ Adám: Talvez! Na verdade, eu não tinha considerado isso. : P AdmBorkBork Obrigado! Passei muito tempo à espreita. Essas são boas idéias; a saída implícita nem sequer pela minha cabeça ...
Arkitekt
2

Java 9, 87 bytes

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

Ungolfed

A JVM da TIO aparentemente não tem sistemaConsole , portanto não pode ser testada lá (consulte 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));
  }
}
Olivier Grégoire
fonte
2

JavaScript (Node.js) , 158 118 bytes

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

Experimente online!

Os nossos agradecimentos a @ ConorO'Brien por ter apresentado a versão mais curta. Objetos embutidos em vez de usar consts e utilizar a condição de saída de erro em vez de sair explicitamente.

Makotosan
fonte
1
Ótima resposta até agora, mas há espaço para potencial. Você pode usar esta abordagem de várias maneiras: você pode omitir as duas conste também pode substituir cada variável por sua definição. Então, em vez de usar s=>{if(...){...}}, você pode usar s=>require('fs').existsSync(s)||process.exit(console.log(s)). Além disso, você pode sair com um erro, para poder escrever o lambda como s=>require('fs').existsSync(s)||--console.log(s). Experimente online!
Conor O'Brien
Ótimas ideias! Obrigado!
Makotosan
1

Limpo , 100 94 bytes

import System.IO,System.File
Start w#(s,w)=evalIO getLine w
#(b,w)=fileExists s w
|b=Start w=s

Experimente online!

versão de expressão única:

import System.IO,System.File
Start w=(\(s,v)=(\(b,w)|b=Start w=s)(fileExists s v))(evalIO getLine w)

Experimente online!

Furioso
fonte
1

Perl 6, 39 bytes

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

Isso funciona no REPL, mas não parece funcionar corretamente no TIO.

mattchuranu
fonte
E quanto a say first !*.IO.e,lines(23 bytes)?
Nwellnhof 17/0318
O exemplo acima provavelmente bloqueia indefinidamente quando executado na linha de comando, mas algo como {}while ($_=get).IO.e;.saydeve funcionar.
Nwellnhof 17/0318
1

PHP, 43 bytes

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

Execute como CLI. Muito fácil de entender.

tsh
fonte
1

Ruby , 40 39 37 bytes

{}while File.exist? gets.chomp
$><<$_

Experimente online!

Cristian Lupascu
fonte
1

APL (Dyalog) , 17 bytes

{⍞}⍣{~⎕NEXISTS⍺}⍬

Experimente online!

Uriel
fonte
Retorna a segunda entrada inexistente (em the_prev_wasnt_filenamevez de env.tio). Alterar e depois você pode se livrar '.'também.
Adám 16/03/19
1

Kotlin , 67 bytes

val f={var s="."
while(java.io.File(s).exists()){s=readLine()!!}
s}

Experimente online!

Makotosan
fonte
1

Anexo , 35 bytes

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

Experimente online!

Soluções alternativas

35 bytes: {If[FileExists[x:=Prompt[]],$[],x]} :, função recursiva.

37 bytes {NestWhile[p:=Prompt,p[],FileExists]} :, função iterativa.

Conor O'Brien
fonte
1

Mínimo , 38 bytes

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

Deixa o último nome de arquivo digitado na pilha.

Explicação

"."         ; 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
fonte
0

SmileBASIC, 27 bytes

INPUT S$EXEC!CHKFILE(S$)?S$
12Me21
fonte