Insister sur un nouveau nom de fichier

19

Lors de l'exécution, continuez à demander une ligne d'entrée jusqu'à ce que l'entrée utilisateur ne soit pas le nom d'un fichier ou d'un répertoire existant ou d'un autre élément du système de fichiers, par rapport au répertoire de travail actuel. Puis retournez / imprimez le dernier nom de fichier entré. Vous pouvez supposer que toutes les entrées utilisateur seront des noms de fichiers valides.

Pseudo-code 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-code 2

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

Exemples de saisie utilisateur qui entraîneront une nouvelle invite lorsque sur TIO:

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

Exemples d'entrées utilisateur qui seront renvoyées sur TIO:

...
env.tio
../../bin/]
/lost/found
Adam
la source
Je suis assez nouveau pour coder le golf ici et ne semble pas trouver d'informations sur ce qui compte comme solution. Dois-je inclure la fonction main () pour les langues qui en ont besoin dans un programme, ou cela peut-il faire partie de l'en-tête? Les instructions d'importation peuvent-elles faire partie de l'en-tête dans TIO, ou doivent-elles faire partie du code et compter par rapport au nombre d'octets? Par exemple, j'ai cette solution: goo.gl/8RWNgu mais je ne sais pas si les octets seraient légitimes.
Makotosan
2
@Makotosan Les fonctions et les programmes complets conviennent, bien que dans le cas des fonctions, ils doivent être réutilisables. Les importations doivent généralement être incluses dans le nombre d'octets.
Martin Ender

Réponses:

7

Lot, 37 octets

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

(Pour une raison quelconque, Windows 10 actuel CMD.EXEcorrompt le titre lorsqu'il exécute le %0.)

Neil
la source
7

Mathematica, 33 28 octets

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

Cela suppose l'environnement de bloc-notes de Mathematica dans lequel nous pouvons interroger les entrées de l'utilisateur avec Input[]. L'entrée utilisateur doit être un littéral de chaîne réel , par exemple "ab/cd.ef"au lieu de simplement ab/cd.ef. L'avantage est que l'entrée peut être une expression Mathematica arbitraire qui calcule la chaîne d'entrée.

Ceci définit un symbole fqui, une fois évalué, effectue le calcul requis et évalue finalement la première entrée utilisateur inexistante. C'est essentiellement une fonction nulle, où nous n'avons pas à l'inclure ...[]pour l'appeler.

Nous pouvons également enregistrer un tas d'octets sur une Ifexpression traditionnelle en utilisant l'opérateur de substitution de modèle /..

Martin Ender
la source
Cela échoue si l'utilisateur entre deux fois la même chose
Lukas Lang
@ Mathe172 Bonne prise, tant pis, alors je vais devoir suivre la boucle ennuyeuse.
Martin Ender
Il s'avère que ce n'est pas le cas, et c'est même un octet plus court. :)
Martin Ender
7

Perl 5 -ln , 12 10 octets

-2 octets grâce à @DomHastings

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

Essayez-le en ligne!

Ton Hospel
la source
1
Je pense que cela -efonctionne sans précision $_, peut ne pas fonctionner dans certains cas, bien que je suppose ...
Dom Hastings
@DomHastings Devrait fonctionner dans tous les cas. Il est documenté que $ _ est utilisé lorsqu'il n'y a pas d'argument pour -e.
pipe
@DomHastings Thanks.Pour une raison quelconque, je pensais que -ec'était une exception, mais bien sûr que ce n'est pas le cas
Ton Hospel
4

Bash, 29

read f
[ -e $f ]&&$0||echo $f
Traumatisme numérique
la source
@ Adám, je ne sais pas pourquoi cela ne fonctionne pas dans TIO. Il suffit de dire que si vous l'enregistrez en tant que fichier de script et l'exécutez, je pense que cela fonctionne comme prévu
Digital Trauma
1
@ Adám Cela fonctionne, le problème que vous aviez était que le programme essayait d'appeler .code.tioqui contient le corps du script, mais aucune information sur la façon de l'exécuter. Je ne sais pas s'il existe une bonne façon de contourner le shebang ou si ce script doit être sur votre chemin, cependant.
FryAmTheEggman
2
Vous pouvez contourner les deux (au prix de deux octets) en passant $0à . $0. Essayez-le en ligne! . Depuis .utilise des noms de chemin relatifs et le shell actuel.
Chris
1
Que pense-t-il *comme entrée?
Toby Speight
4

PowerShell 2 (jusqu'à 6), 35 octets

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

Read-Hostattend l'entrée (si une chaîne est donnée en paramètre, utilise la chaîne comme invite). Si l'entrée fournie est un nom de fichier (ou un nom de dossier) pour celui qui existe, Test-Pathretourne $trueet le bloc de ne rien faire {}s'exécute, et il ré-invite à entrer. Si Test-Pathrenvoie $falsecar l'entrée n'est pas un fichier ou un dossier existant, le bloc ne rien faire ne s'exécute pas et le nom de l'entrée est imprimé.

Jeff Zeitlin
la source
1
Bienvenue chez PPCG!
Martin Ender
Vous n'avez pas besoin du point-virgule après le {} pour enregistrer un octet.
Veskah
@Veskah - Je l'ai fait sur PS2, et ça ne casse pas PS3 +
Jeff Zeitlin
Ah, ma mauvaise. Je ne l'ai pas testé en 2.
Veskah
4

C (gcc) , 62 octets

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

Essayez-le en ligne!

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
la source
Bienvenue chez PPCG! Vous pouvez utiliser while(gets(b),!access(b,0));pour enregistrer 7 octets.
Dennis
3

Funky , 40 octets

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

Dans un véritable style funky, cela utilise des mots clés coincés les uns contre les autres, des crochets inégalés et des mots clés implicites. Nettoyé, cela ressemble à:

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

Panne

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
la source
3

Haskell , 76 octets

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

Essayez-le en ligne!

Renvoie IO xxest le nom entré du fichier qui n'existe pas.

Non golfé

import System.Directory

insist = do { file <- getLine;
              exists <- doesPathExist file;
              if exists then insist else pure file }
totalement humain
la source
3

R , 66 51 octets

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

-15 octets grâce à plannapus

Exécute une boucle potentiellement infinie, où à chaque itération

  1. Une seule ligne d'entrée utilisateur est stockée dans la variable s
  2. Nous vérifions si l'entrée est dans la liste des noms de fichiers pour le répertoire de travail (l' a=Toption pour list.files()doit être utilisée pour ramasser des choses comme ..)
  3. Si sest dans cette liste, nous passons à l'itération suivante; sinon, nous rompons la boucle et imprimons s.
duckmayr
la source
Que diriez-vous de le raccourcir while((s=readline())%in%list.files(a=T)){};print(s)?
plannapus
@plannapus Excellente idée! Incorporé.
duckmayr
Je vous en prie. De plus, je n'y ai pas pensé tout de suite mais fonctionne list.fileset dirsont des synonymes, vous pouvez donc le remplacer par dirici.
plannapus
vous pouvez également remplacer readline()parscan(,'')
JAD
Et printaveccat
JAD
3

Python 3 , 55 octets

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

Essayez-le en ligne!

-4 octets grâce à ManfP
-6 octets grâce à Rick Rongen

HyperNeutrino
la source
2
@ Adám terrible mauvaise interprétation, désolé
HyperNeutrino
Vous pouvez remplacer le premier input()par"."
ManfP
1
import oset os.path.existsest de trois octets plus court.
Jonathan Allan
1
Rick Rongen a suggéré import globet while glob.glob(s):...dans une édition.
Martin Ender
@MartinEnder merci de me l'avoir dit :)
HyperNeutrino
3

C #, 101 octets

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

Pour chacune des 4 valeurs de retour valides:

Non golfé

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

Explication

repose sur le fait que File.GetAttributes () lève une exception si l'objet du système de fichiers spécifié dans son argument n'existe pas.

Richard II
la source
2

Powershell 3.0, 75 octets

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

Premier essai; Je suis sûr qu'il y a quelques optimisations que je pourrais faire.

Une forme un peu plus lisible:

$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
la source
Cela ne fonctionnerait-il pas même sans $PSScriptRoot\?
2018
Bienvenue chez PPCG! Quelques golfs rapides - vous pouvez utiliser une forboucle à la place, ce qui vous permet de déplacer l'initialisation dans le constructeur de la boucle for($x=1;$x){...}. Deuxièmement, vous pouvez vous débarrasser du Write-Hostcar il y a un implicite Write-Outputà la fin du programme pour tout ce qui reste sur le pipeline, donc il suffit de le laisser $i.
AdmBorkBork
Voir ma solution ci-dessous; J'ai divisé par deux votre nombre d'octets.
Jeff Zeitlin
@ Adám: Peut-être! Je n'avais pas vraiment envisagé cela. : P AdmBorkBork Merci! J'ai passé longtemps à me cacher. Ce sont de bonnes idées; la sortie implicite ne m'a même pas traversé l'esprit ...
Arkitekt
2

Java 9, 87 octets

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

Non golfé

La JVM de TIO n'a apparemment pas de systèmeConsole , elle n'est donc pas testable (voir 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
la source
2

JavaScript (Node.js) , 158 118 octets

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

Essayez-le en ligne!

Nous remercions @ ConorO'Brien d'avoir proposé une version plus courte. Objets alignés au lieu d'utiliser des consts et d'utiliser une condition de sortie d'erreur au lieu de quitter explicitement.

Makotosan
la source
1
Belle réponse jusqu'à présent, mais il y a du potentiel. Vous pouvez jouer cette approche de plusieurs manières: vous pouvez omettre les deux const, et vous pouvez également remplacer chaque variable par sa définition. Ensuite, au lieu d'utiliser s=>{if(...){...}}, vous pouvez utiliser s=>require('fs').existsSync(s)||process.exit(console.log(s)). De plus, vous pouvez quitter avec une erreur, vous pouvez donc écrire le lambda en tant que s=>require('fs').existsSync(s)||--console.log(s). Essayez-le en ligne!
Conor O'Brien
Bonnes idées! Merci!
Makotosan
1

Nettoyer , 100 94 octets

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

Essayez-le en ligne!

version à expression simple:

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

Essayez-le en ligne!

Οurous
la source
1

Perl 6, 39 octets

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

Cela fonctionne dans le REPL, mais il ne semble pas fonctionner correctement dans TIO.

mattchuranu
la source
Et say first !*.IO.e,lines(23 octets)?
nwellnhof
Ce qui précède se bloque probablement indéfiniment lorsqu'il est exécuté sur la ligne de commande, mais quelque chose comme ça {}while ($_=get).IO.e;.saydevrait fonctionner.
nwellnhof
1

PHP, 43 octets

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

Exécuter en tant que CLI. Assez facile à comprendre.

tsh
la source
1

APL (Dyalog) , 17 octets

{⍞}⍣{~⎕NEXISTS⍺}⍬

Essayez-le en ligne!

Uriel
la source
Renvoie la deuxième entrée inexistante ( the_prev_wasnt_filenameau lieu de env.tio). Changez et vous pourrez vous en débarrasser '.'aussi.
Adám
1

Kotlin , 67 octets

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

Essayez-le en ligne!

Makotosan
la source
1

Attaché , 35 octets

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

Essayez-le en ligne!

Solutions alternatives

35 octets {If[FileExists[x:=Prompt[]],$[],x]} :, fonction récursive.

37 octets {NestWhile[p:=Prompt,p[],FileExists]} :, fonction itérative.

Conor O'Brien
la source
1

Min , 38 octets

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

Laisse le dernier nom de fichier entré sur la pile.

Explication

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

SmileBASIC, 27 octets

INPUT S$EXEC!CHKFILE(S$)?S$
12Me21
la source