Bestehen Sie auf einem neuen Dateinamen

19

Fordern Sie zur Laufzeit so lange eine Eingabezeile an, bis die Benutzereingabe erfolgt nicht mehr der Name einer vorhandenen Datei oder eines vorhandenen Verzeichnisses oder eines anderen Dateisystemelements im Verhältnis zum aktuellen Arbeitsverzeichnis ist. Geben Sie dann den zuletzt eingegebenen Dateinamen zurück bzw. drucken Sie ihn aus. Sie können davon ausgehen, dass alle Benutzereingaben gültige Dateinamen sind.

Pseudocode 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)

Pseudocode 2

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

Beispiele für Benutzereingaben, die bei Aktivierung von TIO zu einer erneuten Aufforderung führen:

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

Beispiele für Benutzereingaben, die bei TIO zurückgegeben werden:

...
env.tio
../../bin/]
/lost/found
Adam
quelle
Ich bin ziemlich neu darin, Golf zu programmieren und kann anscheinend keine Informationen darüber finden, was als Lösung gilt. Muss ich die main () - Funktion für Sprachen in ein Programm einbinden, die dies erfordern, oder kann das Teil des Headers sein? Können Importanweisungen Teil des Headers in TIO sein oder müssen sie Teil des Codes sein und gegen die Byteanzahl zählen? Zum Beispiel habe ich diese Lösung: goo.gl/8RWNgu aber nicht sicher, ob es die Bytes legitim wäre.
Makotosan
2
@Makotosan Sowohl Funktionen als auch vollständige Programme sind in Ordnung, obwohl sie im Falle von Funktionen wiederverwendbar sein müssen. Importe müssen in der Regel in die Byteanzahl einbezogen werden.
Martin Ender

Antworten:

7

Batch, 37 Bytes

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

(Aus irgendeinem Grund CMD.EXEbeschädigt aktuelles Windows 10 den Titel, wenn es das ausführt %0.)

Neil
quelle
7

Mathematica, 33 28 Bytes

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

Dies setzt die Notebook-Umgebung von Mathematica voraus, in der Eingaben des Benutzers abgefragt werden können Input[]. Die Benutzereingabe sollte ein tatsächliches String-Literal sein , also zB "ab/cd.ef"statt nurab/cd.ef . Der Vorteil ist, dass die Eingabe ein beliebiger Mathematica-Ausdruck sein kann, der die Eingabezeichenfolge berechnet.

Dies definiert ein Symbol, fdas bei der Auswertung die erforderliche Berechnung durchführt und letztendlich zur ersten nicht vorhandenen Benutzereingabe auswertet. Es handelt sich im Wesentlichen um eine Nullfunktion, bei der keine Einbeziehung erforderlich ist...[] sie aufzurufen.

Wir können auch eine Menge Bytes gegenüber einem herkömmlichen IfAusdruck sparen, indem wir den Operator für die Mustersubstitution verwenden /..

Martin Ender
quelle
Dies schlägt fehl, wenn der Benutzer zweimal dasselbe
Lukas Lang
@ Mathe172 Guter Fang, schade, dann muss ich mit der langweiligen Schleife fahren.
Martin Ender
Es stellt sich heraus, dass ich es nicht tue, und es ist sogar ein Byte kürzer. :)
Martin Ender
7

Perl 5 -ln , 12 10 Bytes

-2 Bytes dank @DomHastings

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

Probieren Sie es online!

Tonne Hospel
quelle
1
Ich denke, -efunktioniert ohne Angabe $_, könnte in einigen Fällen nicht funktionieren, obwohl ich denke ...
Dom Hastings
@DomHastings Sollte in allen Fällen funktionieren. Es ist dokumentiert, dass $ _ verwendet wird, wenn es kein Argument für -e gibt.
Pipe
@DomHastings Danke. Aus irgendeinem Grund dachte ich, es -esei eine Ausnahme, aber das ist es natürlich nicht
Ton Hospel
4

Bash, 29

read f
[ -e $f ]&&$0||echo $f
Digitales Trauma
quelle
@Adam Ich bin mir nicht sicher, warum es in TIO nicht funktioniert. Es genügt zu sagen, wenn Sie es als Skriptdatei speichern und ausführen, ich denke, es funktioniert wie erwartet
Digital Trauma
1
@ Adám Das funktioniert, das Problem, das Sie hatten, war, dass das Programm versuchte aufzurufen, .code.tiodas den Hauptteil des Skripts enthielt, aber keine Informationen darüber, wie es ausgeführt werden sollte. Ich bin mir nicht sicher, ob es einen guten Weg gibt, um den Schebang zu umgehen, oder ob dieses Skript auf deinem Weg sein muss.
FryAmTheEggman
2
Sie können beide (auf Kosten von zwei Bytes) erhalten um durch Änderung $0zu . $0. Probieren Sie es online! . Da .werden relative Pfadnamen und die aktuelle Shell verwendet.
Chris
1
Was versteht es *unter Input?
Toby Speight
4

PowerShell 2 (bis 6), 35 Byte

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

Read-Hostwartet auf Eingabe (wenn eine Zeichenfolge als Parameter angegeben wird, wird die Zeichenfolge als Eingabeaufforderung verwendet). Wenn die mitgelieferte Eingabe ein Dateiname (oder Ordnername) für eine ist , die vorhanden ist , Test-Pathkehrt $true, und die do-nothing - Block {}ausgeführt wird , und es erneut Aufforderungen zur Eingabe. Wenn der Test-PathWert zurückgegeben wird, $falseweil die Eingabe keine vorhandene Datei oder kein vorhandener Ordner ist, wird der Nichtbearbeitungsblock nicht ausgeführt, und der Eingabename wird gedruckt.

Jeff Zeitlin
quelle
1
Willkommen bei PPCG!
Martin Ender
You don't need the semi-colon after the {} to save a byte.
Veskah
@Veskah - I did in PS2, and it doesn't break PS3+
Jeff Zeitlin
Ah, my bad. Didn't test it in 2.
Veskah
4

C (gcc), 62 bytes

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

Try it 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
}
Arctic Kona
quelle
Welcome to PPCG! You can use while(gets(b),!access(b,0)); to save 7 bytes.
Dennis
3

Funky, 40 bytes

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

In true funky style, this uses keywords jammed against eachother, unmatching brackets and implicit keywords. Cleaned up, this looks like:

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

Breakdown

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

Haskell, 76 bytes

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

Try it online!

Returns IO x where x is the inputted name of the file that does not exist.

Ungolfed

import System.Directory

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

R, 66 51 bytes

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

-15 bytes thanks to plannapus

Runs a potentially infinite loop, where on each iteration

  1. A single line of user input is stored in the variable s
  2. We check if the input is in the list of filenames for the working directory (the a=T option for list.files() must be used to pick up things like ..)
  3. If s is in that list, we go to the next iteration; if not, we break the loop and print s.
duckmayr
quelle
How about shortening it to while((s=readline())%in%list.files(a=T)){};print(s)?
plannapus
@plannapus Great idea! Incorporated.
duckmayr
You're welcome. Also, I didn't think of it right away but functions list.files and dir are synonyms, so you can replace it with dir here.
plannapus
you could also replace readline() with scan(,'')
JAD
And print with cat
JAD
3

Python 3, 55 bytes

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

Try it online!

-4 bytes thanks to ManfP
-6 bytes thanks to Rick Rongen

HyperNeutrino
quelle
2
@Adám terrible misinterpretation, sorry
HyperNeutrino
You could replace the first input() with "."
ManfP
1
import os and os.path.exists is three bytes shorter.
Jonathan Allan
1
Rick Rongen suggested import glob and while glob.glob(s):... in an edit.
Martin Ender
@MartinEnder thanks for telling me :)
HyperNeutrino
3

C#, 101 bytes

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

For each of the 4 valid return values:

Ungolfed

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

Explanation

relies on the fact that File.GetAttributes() throws an exception if file system object specified in its argument doesn't exist.

Richard II
quelle
2

Powershell 3.0, 75 bytes

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

First attempt; I'm sure there are a few optimizations I could make.

A slightly more readable form:

$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
quelle
Wouldn't it work even without $PSScriptRoot\?
Adám
Welcome to PPCG! A few quick golfs -- you can use a for loop instead, which allows you to move the initialization into the loop constructor for($x=1;$x){...}. Secondly, you can get rid of the Write-Host since there's an implicit Write-Output at program completion for anything left on the pipeline, so just leaving $i there will suffice.
AdmBorkBork
See my solution below; I've halved your byte count.
Jeff Zeitlin
@Adam: Vielleicht! Das hatte ich eigentlich nicht bedacht. : P AdmBorkBork Danke! Ich habe lange gelauert. Das sind gute Ideen; Die implizite Ausgabe kam mir nicht einmal in den Sinn ...
Arkitekt
2

Java 9, 87 Bytes

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

Ungolfed

Die JVM von TIO hat anscheinend kein SystemConsole , daher kann sie dort nicht getestet werden (siehe 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
quelle
2

JavaScript (Node.js) , 158 - 118 Byte

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

Probieren Sie es online!

Dank an @ ConorO'Brien für die kürzere Version. Inline-Objekte anstelle der Verwendung von consts und der Verwendung der Fehler-Exit-Bedingung anstelle des expliziten Exits.

Makotosan
quelle
1
Gute Antwort bisher, aber es gibt Raum für Potenzial. Sie können diesen Ansatz auf verschiedene Arten umsetzen: Sie können beides weglassen constund jede Variable durch ihre Definition ersetzen. Dann s=>{if(...){...}}könnten Sie anstelle von verwenden verwenden s=>require('fs').existsSync(s)||process.exit(console.log(s)). Darüber hinaus können Sie mit einem Fehler beenden, so dass Sie das Lambda als schreiben können s=>require('fs').existsSync(s)||--console.log(s). Probieren Sie es online!
Conor O'Brien
Tolle Ideen! Vielen Dank!
Makotosan
1

Sauber , 100 94 Bytes

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

Probieren Sie es online!

Version mit einem Ausdruck:

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

Probieren Sie es online!

Οurous
quelle
1

Perl 6, 39 Bytes

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

Dies funktioniert in der REPL, aber in TIO scheint es nicht richtig zu funktionieren.

Mattchuranu
quelle
Was ist mit say first !*.IO.e,lines(23 Bytes)?
Nwellnhof
Das obige blockiert wahrscheinlich auf unbestimmte Zeit, wenn es in der Befehlszeile ausgeführt wird, aber so etwas {}while ($_=get).IO.e;.saysollte funktionieren.
Nwellnhof
1

PHP, 43 Bytes

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

Als CLI ausführen. Ganz einfach zu verstehen.

tsh
quelle
1

APL (Dyalog) , 17 Bytes

{⍞}⍣{~⎕NEXISTS⍺}⍬

Probieren Sie es online!

Uriel
quelle
Gibt die zweite nicht vorhandene Eingabe zurück ( the_prev_wasnt_filenameanstelle von env.tio). Ändern und dann können Sie auch loswerden '.'.
Adám
1

Kotlin , 67 Bytes

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

Probieren Sie es online!

Makotosan
quelle
1

Attache , 35 Bytes

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

Probieren Sie es online!

Alternativlösungen

35 Bytes: {If[FileExists[x:=Prompt[]],$[],x]} rekursive Funktion.

37 Bytes: {NestWhile[p:=Prompt,p[],FileExists]} iterative Funktion.

Conor O'Brien
quelle
1

Min , 38 Bytes

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

Lässt den zuletzt eingegebenen Dateinamen auf dem Stapel.

Erläuterung

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

SmileBASIC, 27 Bytes

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