Insistere su un nuovo nome file


19

In fase di esecuzione, continuare a richiedere una riga di input fino a quando l'input dell'utente non è il nome di un file o directory esistente o di un altro elemento del file system, rispetto alla directory di lavoro corrente. Quindi restituire / stampare l'ultimo nome file inserito. Puoi presumere che tutti gli input dell'utente saranno nomi di file validi.

Pseudo-codice 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)

Pseudo-codice 2

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

Esempi di input dell'utente che causeranno un nuovo prompt quando su TIO:

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

Esempi di input dell'utente che verranno restituiti su TIO:

...
env.tio
../../bin/]
/lost/found

Sono abbastanza nuovo per programmare il golf qui e non riesco a trovare alcuna informazione su ciò che conta come soluzione. Devo includere la funzione main () per le lingue che la richiedono in un programma o può far parte dell'intestazione? Le istruzioni di importazione possono far parte dell'intestazione in TIO o devono essere parte del codice e contare rispetto al conteggio dei byte? Ad esempio, ho questa soluzione: goo.gl/8RWNgu ma non sono sicuro che i byte siano legittimi.
Makotosan,

2
@Makotosan Sia le funzioni che i programmi completi vanno bene, anche se nel caso delle funzioni devono essere riutilizzabili. Le importazioni in genere devono essere incluse nel conteggio dei byte.
Martin Ender,

Risposte:


7

Lotto, 37 byte

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

(Per qualche motivo l'attuale Windows 10 CMD.EXEcorrompe il titolo quando esegue il %0.)


7

Mathematica, 33 28 byte

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

Questo presuppone l'ambiente per notebook di Mathematica in cui possiamo interrogare l'input dell'utente Input[]. L'input dell'utente dovrebbe essere una stringa effettiva letterale , quindi ad es. "ab/cd.ef"Anziché solo ab/cd.ef. Il lato positivo è che l'input può essere un'espressione Mathematica arbitraria che calcola la stringa di input.

Questo definisce un simbolo fche, quando valutato, esegue il calcolo richiesto e alla fine valuta il primo input dell'utente inesistente. È essenzialmente una funzione nulla, in cui non è necessario includere ...[]per chiamarla.

Possiamo anche salvare un sacco di byte su Ifun'espressione tradizionale facendo uso dell'operatore di sostituzione del modello /..


Questo fallisce se l'utente inserisce la stessa cosa due volte
Lukas Lang

@ Mathe172 Buona cattura, peccato, poi dovrò andare con il ciclo noioso.
Martin Ender,

Si scopre di no, ed è anche un byte più breve. :)
Martin Ender,

7

Perl 5 -ln , 12 10 byte

-2 byte grazie a @DomHastings

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

Provalo online!


1
Penso che funzioni -esenza specificare $_, potrebbe non funzionare per alcuni casi anche se immagino ...
Dom Hastings

@DomHastings Dovrebbe funzionare in tutti i casi. È documentato che $ _ viene usato quando non c'è argomento per -e.
pipe

@DomHastings Thanks.Per qualche ragione ho pensato che -efosse un'eccezione, ma ovviamente non lo è
Ton Hospel

4

Bash, 29

read f
[ -e $f ]&&$0||echo $f


@Adám Non sono sicuro del perché non funzioni in TIO. Basti dire che se lo salvi come file di script ed eseguilo, penso che funzioni come previsto
Digital Trauma

1
@ Adám Questo funziona, il problema che avevo era che il programma stava cercando di chiamata .code.tioche contiene il corpo dello script, ma nessuna informazione su come eseguirlo. Non sono sicuro che ci sia un buon modo per aggirare lo shebang o che questa sceneggiatura debba essere sulla tua strada.
FryAmTheEggman

2
Puoi aggirare entrambi (al costo di due byte) cambiando $0in . $0. Provalo online! . Poiché .utilizza nomi di percorso relativi e la shell corrente.
Chris

1
Cosa pensa *come input?
Toby Speight,

4

PowerShell 2 (attraverso 6), 35 byte

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

Read-Hostattende l'input (se viene fornita una stringa come parametro, utilizza la stringa come prompt). Se l'input fornito è un nome file (o nome cartella) per uno esistente, Test-Pathritorna $truee {}viene eseguito il blocco do-nothing e richiede nuovamente l'input. Se Test-Pathrestituisce $falseperché l'input non è un file o una cartella esistenti, il blocco do-nothing non viene eseguito e il nome di input viene stampato.


1
Benvenuti in PPCG!
Martin Ender,

Non è necessario il punto e virgola dopo il {} per salvare un byte.
Veskah,

@Veskah - L'ho fatto su PS2 e non si rompe PS3 +
Jeff Zeitlin,

Ah, mio ​​cattivo. Non l'ho provato in 2.
Veskah,

4

C (gcc) , 62 byte

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

Provalo 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
}

Benvenuti in PPCG! È possibile utilizzare while(gets(b),!access(b,0));per salvare 7 byte.
Dennis,

3

Funky , 40 byte

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

In un vero stile funky, utilizza parole chiave bloccate l'una contro l'altra, parentesi senza pari e parole chiave implicite. Pulito, questo assomiglia a:

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

Abbattersi

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.

3

Haskell , 76 byte

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

Provalo online!

Restituisce IO xdove xè il nome inserito del file che non esiste.

Ungolfed

import System.Directory

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

3

R , 66 51 byte

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

-15 byte grazie a plannapus

Esegue un ciclo potenzialmente infinito, dove su ogni iterazione

  1. Una singola riga di input dell'utente è memorizzata nella variabile s
  2. Controlliamo se l'input è nella lista dei nomi dei file per la directory di lavoro (l' a=Topzione per list.files()deve essere usata per raccogliere cose come ..)
  3. Se sè in quella lista, andiamo alla prossima iterazione; in caso contrario, interrompiamo il ciclo e stampiamo s.

Che ne dici di accorciarlo while((s=readline())%in%list.files(a=T)){};print(s)?
plannapus,

@plannapus Ottima idea! Incorporated.
duckmayr,

Prego. Inoltre, non ci ho pensato subito, ma funziona list.filese dirsono sinonimi, quindi puoi sostituirlo con dirqui.
plannapus,

potresti anche sostituirlo readline()conscan(,'')
JAD

E printconcat
JAD

3

Python 3 , 55 byte

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

Provalo online!

-4 byte grazie a ManfP
-6 byte grazie a Rick Rongen


2
@ Adám terribile errata interpretazione, scusa
HyperNeutrino

È possibile sostituire il primo input()con"."
ManfP

1
import osed os.path.existsè più breve di tre byte.
Jonathan Allan,

1
Rick Rongen ha suggerito import globe while glob.glob(s):...in una modifica.
Martin Ender,

@MartinEnder grazie per avermelo detto :)
HyperNeutrino

3

C #, 101 byte

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

Per ciascuno dei 4 valori di ritorno validi:

Ungolfed

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

Spiegazione

si basa sul fatto che File.GetAttributes () genera un'eccezione se l'oggetto del file system specificato nel suo argomento non esiste.


2

Powershell 3.0, 75 byte

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

Primo tentativo; Sono sicuro che ci sono alcune ottimizzazioni che potrei fare.

Una forma leggermente più leggibile:

$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.

Non funzionerebbe nemmeno senza $PSScriptRoot\?
Adám,

Benvenuti in PPCG! Alcuni campi da golf veloci: è possibile utilizzare un forloop, che consente di spostare l'inizializzazione nel costruttore del loop for($x=1;$x){...}. In secondo luogo, puoi sbarazzartene dal Write-Hostmomento che c'è un implicito Write-Outputal completamento del programma per tutto ciò che rimane sulla pipeline, quindi è sufficiente lasciarlo $ilì.
AdmBorkBork

Vedi la mia soluzione di seguito; Ho dimezzato il conteggio dei byte.
Jeff Zeitlin,

@Adám: forse! In realtà non l'avevo considerato. : P AdmBorkBork Grazie! Ho trascorso molto tempo in agguato. Quelle sono buone idee; l'output implicito non mi è nemmeno passato per la testa ...
Arkitekt

2

Java 9, 87 byte

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

Ungolfed

Apparentemente la JVM di TIO non ha un sistemaConsole , quindi non è testabile lì (vedi 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 byte

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

Provalo online!

Ringraziamo @ ConorO'Brien per aver escogitato una versione più breve. Oggetti incorporati anziché utilizzare i costi e utilizzare la condizione di uscita dell'errore anziché uscire esplicitamente.


1
Bella risposta finora, ma c'è spazio per il potenziale. Puoi golfare questo approccio in alcuni modi: puoi ometterli entrambi conste puoi anche sostituire ogni variabile con la sua definizione. Quindi, invece di utilizzare s=>{if(...){...}}, è possibile utilizzare s=>require('fs').existsSync(s)||process.exit(console.log(s)). Inoltre, puoi uscire con un errore, quindi puoi scrivere lambda come s=>require('fs').existsSync(s)||--console.log(s). Provalo online!
Conor O'Brien,

Grandi idee! Grazie!
Makotosan

1

Pulito , 100 94 byte

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

Provalo online!

versione a singola espressione:

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

Provalo online!


1

Perl 6, 39 byte

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

Questo funziona nel REPL, ma non sembra funzionare correttamente in TIO.


Che dire di say first !*.IO.e,lines(23 byte)?
nwellnhof,

Quanto sopra probabilmente si blocca indefinitamente quando eseguito sulla riga di comando, ma qualcosa del genere {}while ($_=get).IO.e;.saydovrebbe funzionare.
nwellnhof,

1

PHP, 43 byte

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

Esegui come CLI. Abbastanza facile da capire



1

APL (Dyalog) , 17 byte

{⍞}⍣{~⎕NEXISTS⍺}⍬

Provalo online!


Restituisce il secondo input inesistente, ( the_prev_wasnt_filenameinvece di env.tio). Cambia e poi puoi anche sbarazzartene '.'.
Adám,


1

Attache , 35 byte

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

Provalo online!

Soluzioni alternative

35 byte {If[FileExists[x:=Prompt[]],$[],x]} :, funzione ricorsiva.

37 byte {NestWhile[p:=Prompt,p[],FileExists]} :, funzione iterativa.


1

Min , 38 byte

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

Lascia l'ultimo nome file inserito nello stack.

Spiegazione

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

0

SmileBASIC, 27 byte

INPUT S$EXEC!CHKFILE(S$)?S$
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.