Bersikeras nama file baru


19

Pada saat runtime, teruslah meminta jalur input sampai input pengguna bukan nama file atau direktori yang ada atau item sistem file lainnya, relatif terhadap direktori kerja saat ini. Kemudian kembalikan / cetak nama file yang terakhir dimasukkan. Anda dapat mengasumsikan bahwa semua input pengguna akan menjadi nama file yang valid.

Kode semu 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)

Kode semu 2

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

Contoh input pengguna yang akan menyebabkan permintaan kembali saat di TIO:

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

Contoh input pengguna yang akan kembali ketika di TIO:

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

Saya cukup baru untuk kode golf di sini dan tampaknya tidak dapat menemukan informasi apa pun yang dianggap sebagai solusi. Apakah saya perlu memasukkan fungsi utama () untuk bahasa yang memerlukannya dalam program, atau bisakah itu menjadi bagian dari header? Bisakah mengimpor pernyataan menjadi bagian dari header di TIO, atau apakah mereka perlu menjadi bagian dari kode dan menghitung terhadap jumlah byte? Sebagai contoh, saya punya solusi ini: goo.gl/8RWNgu tetapi tidak yakin apakah byte akan sah.
Makotosan

2
@Makotosan Baik fungsi dan program lengkap baik-baik saja, meskipun dalam hal fungsi mereka harus dapat digunakan kembali. Impor umumnya perlu dimasukkan dalam hitungan byte.
Martin Ender

Jawaban:


7

Batch, 37 byte

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

(Untuk beberapa alasan Windows 10 saat ini CMD.EXEmerusak judul ketika mengeksekusi %0.)


7

Mathematica, 33 28 byte

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

Ini mengasumsikan lingkungan notebook Mathematica tempat kami dapat meminta input dari pengguna Input[]. Input pengguna harus berupa string literal aktual , jadi misal "ab/cd.ef"alih-alih adil ab/cd.ef. Sisi positifnya adalah input dapat berupa ekspresi Mathematica yang berubah-ubah yang menghitung string input.

Ini mendefinisikan simbol fyang, ketika dievaluasi melakukan perhitungan yang diperlukan dan akhirnya mengevaluasi ke input pengguna pertama yang tidak ada. Ini pada dasarnya fungsi nullary, di mana kita tidak harus memasukkan ...[]untuk memanggilnya.

Kita juga dapat menyimpan banyak byte pada Ifekspresi tradisional dengan memanfaatkan operator substitusi pola /..


Ini gagal jika pengguna memasukkan hal yang sama dua kali
Lukas Lang

@ Mathe172 Tangkapan bagus, terlalu buruk, maka saya harus pergi dengan loop membosankan.
Martin Ender

Ternyata saya tidak, dan itu bahkan satu byte lebih pendek. :)
Martin Ender

7

Perl 5 -ln , 12 10 byte

-2 byte terima kasih kepada @DomHastings

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

Cobalah online!


1
Saya pikir -ebekerja tanpa menentukan $_, mungkin tidak bekerja untuk beberapa kasus meskipun saya kira ...
Dom Hastings

@HomHastings Harus bekerja dalam semua kasus. Didokumentasikan bahwa $ _ digunakan ketika tidak ada argumen untuk -e.
pipa

@HomHastings Terima kasih. Untuk beberapa alasan saya pikir -eitu pengecualian tapi tentu saja tidak
Ton Hospel

4

Bash, 29

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


@ Adam, saya tidak yakin mengapa itu tidak bekerja di TIO. Cukuplah untuk mengatakan jika Anda menyimpannya sebagai file skrip dan menjalankannya, saya pikir itu berfungsi seperti yang diharapkan
Digital Trauma

1
@ Adám Ini berfungsi, masalah yang Anda miliki adalah program mencoba menelepon .code.tioyang berisi isi skrip, tetapi tidak ada informasi tentang cara menjalankannya. Saya tidak yakin apakah ada cara yang bagus untuk bekerja di sekitar shebang atau skrip ini perlu berada di jalur Anda.
FryAmTheEggman

2
Anda dapat berkeliling keduanya (dengan biaya dua byte) dengan mengubah $0ke . $0. Cobalah online! . Karena .menggunakan nama jalur relatif dan shell saat ini.
Chris

1
Apa yang dianggapnya *sebagai input?
Toby Speight

4

PowerShell 2 (hingga 6), 35 byte

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

Read-Hostmenunggu input (jika diberi string sebagai parameter, gunakan string sebagai prompt). Jika input yang disediakan adalah nama file (atau nama folder) untuk yang ada, Test-Pathkembali $true, dan blok do-nothing {}dieksekusi, dan ia kembali meminta input. Jika Test-Pathkembali $falsekarena input bukan file atau folder yang masih ada, blok do-nothing tidak mengeksekusi, dan nama input dicetak.


1
Selamat datang di PPCG!
Martin Ender

Anda tidak perlu titik koma setelah {} untuk menyimpan byte.
Veskah

@ Veska - saya lakukan di PS2, dan itu tidak merusak PS3 +
Jeff Zeitlin

Ah, salahku. Tidak mengujinya dalam 2.
Veskah

4

C (gcc) , 62 byte

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

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

Selamat datang di PPCG! Anda dapat menggunakannya while(gets(b),!access(b,0));untuk menyimpan 7 byte.
Dennis

3

Funky , 40 byte

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

Dalam gaya funky yang sebenarnya, ini menggunakan kata kunci yang macet terhadap satu sama lain, tanda kurung yang tidak cocok dan kata kunci tersirat. Dibersihkan, ini terlihat seperti:

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

Kerusakan

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]

Cobalah online!

Mengembalikan IO xtempat xnama nama file yang dimasukkan tidak ada.

Tidak disatukan

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 terima kasih kepada plannapus

Menjalankan loop berpotensi tak terbatas, di mana pada setiap iterasi

  1. Satu baris input pengguna disimpan dalam variabel s
  2. Kami memeriksa apakah input ada dalam daftar nama file untuk direktori kerja ( a=Topsi untuk list.files()harus digunakan untuk mengambil hal-hal seperti ..)
  3. Jika sada dalam daftar itu, kita pergi ke iterasi berikutnya; jika tidak, kita putuskan loop dan cetak s.

Bagaimana dengan memperpendeknya while((s=readline())%in%list.files(a=T)){};print(s)?
plannapus

@plannapus Ide bagus! Tergabung.
duckmayr

Sama-sama. Juga, saya tidak langsung memikirkannya tetapi berfungsi list.filesdan dirsinonim, jadi Anda bisa menggantinya dengan di dirsini.
plannapus

Anda juga bisa mengganti readline()denganscan(,'')
JAD

Dan printdengancat
JAD

3

Python 3 , 55 byte

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

Cobalah online!

-4 bytes berkat ManfP
-6 bytes berkat Rick Rongen


2
@ Adám kesalahpahaman yang mengerikan, maaf
HyperNeutrino

Anda bisa mengganti yang pertama input()dengan"."
ManfP

1
import osdan os.path.existstiga byte lebih pendek.
Jonathan Allan

1
Rick Rongen menyarankan import globdan while glob.glob(s):...mengedit.
Martin Ender

@MartinEnder terima kasih sudah memberi tahu saya :)
HyperNeutrino

3

C #, 101 byte

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

Untuk masing-masing dari 4 nilai pengembalian yang valid:

Tidak disatukan

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

Penjelasan

bergantung pada kenyataan bahwa File.GetAttributes () melempar pengecualian jika objek sistem file yang ditentukan dalam argumennya tidak ada.


2

Powershell 3.0, 75 byte

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

Percobaan pertama; Saya yakin ada beberapa optimasi yang bisa saya lakukan.

Bentuk yang sedikit lebih mudah dibaca:

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

Bukankah itu akan berhasil bahkan tanpa itu $PSScriptRoot\?
Adám

Selamat datang di PPCG! Beberapa golf cepat - Anda bisa menggunakan forloop, yang memungkinkan Anda untuk memindahkan inisialisasi ke konstruktor loop for($x=1;$x){...}. Kedua, Anda dapat menyingkirkannya Write-Hostkarena ada implisit Write-Outputpada penyelesaian program untuk apa pun yang tersisa di dalam pipa, jadi hanya meninggalkannya saja $isudah cukup.
AdmBorkBork

Lihat solusi saya di bawah ini; Saya telah mengurangi separuh jumlah byte Anda.
Jeff Zeitlin

@ Adám: Mungkin! Aku sebenarnya tidak mempertimbangkan itu. : P AdmBorkBork Terima kasih! Saya menghabiskan waktu lama mengintai. Itu adalah ide bagus; keluaran implisitnya bahkan tidak terlintas di benak saya ...
Arkitekt

2

Java 9, 87 byte

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

Tidak disatukan

JVM TIO tampaknya tidak memiliki sistemConsole , jadi tidak dapat diuji di sana (lihat 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))

Cobalah online!

Kredit ke @ ConorO'Brien untuk versi yang lebih pendek. Objek yang disorot bukannya menggunakan const dan memanfaatkan kondisi keluar kesalahan alih-alih keluar secara eksplisit.


1
Jawaban yang bagus sejauh ini, tetapi ada ruang untuk potensi. Anda dapat menggunakan pendekatan ini dalam beberapa cara: Anda dapat menghilangkan keduanya const, dan Anda juga dapat mengganti setiap variabel dengan definisi itu. Kemudian, alih-alih menggunakan s=>{if(...){...}}, Anda bisa menggunakan s=>require('fs').existsSync(s)||process.exit(console.log(s)). Selain itu, Anda dapat keluar dengan kesalahan, sehingga Anda dapat menulis lambda sebagai s=>require('fs').existsSync(s)||--console.log(s). Cobalah online!
Conor O'Brien

Ide bagus! Terima kasih!
Makotosan

1

Bersih , 100 94 byte

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

Cobalah online!

versi ekspresi tunggal:

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

Cobalah online!


1

Perl 6, 39 byte

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

Ini berfungsi di REPL, tetapi sepertinya tidak berfungsi dengan baik di TIO.


Bagaimana dengan say first !*.IO.e,lines(23 byte)?
nwellnhof

Blok di atas mungkin memblok tanpa batas waktu ketika dijalankan pada baris perintah, tetapi sesuatu seperti {}while ($_=get).IO.e;.sayseharusnya berfungsi.
nwellnhof

1

PHP, 43 byte

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

Jalankan sebagai CLI. Cukup mudah dimengerti.



1

APL (Dyalog) , 17 byte

{⍞}⍣{~⎕NEXISTS⍺}⍬

Cobalah online!


Mengembalikan input kedua yang tidak ada, ( the_prev_wasnt_filenamebukan env.tio) Ubah lalu Anda bisa menyingkirkannya '.'juga.
Adám


1

Attache , 35 byte

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

Cobalah online!

Solusi alternatif

35 byte: {If[FileExists[x:=Prompt[]],$[],x]} :, fungsi rekursif.

37 byte {NestWhile[p:=Prompt,p[],FileExists]} :, fungsi berulang.


1

Min , 38 byte

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

Meninggalkan nama file yang terakhir dimasukkan pada tumpukan.

Penjelasan

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

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.