Rút ngắn một con đường tuyệt đối


17

Đôi khi, một đường dẫn tuyệt đối dài, ví dụ như tham số dòng lệnh đến công cụ linux, có thể được rút ngắn, sử dụng thư mục làm việc hiện tại làm tham chiếu:

$ pwd
/home/heh

$ cat /home/heh/mydir/myfile
my stuff

$ cat mydir/myfile
my stuff

Trong thử thách này, bạn nên tạo một hàm hoặc một chương trình nhận hai tham số:

  1. Đường dẫn tuyệt đối, sử dụng định dạng linux (bắt đầu bằng /)
  2. Thư mục hiện tại, sử dụng cùng định dạng

Đầu ra ngắn hơn như sau:

  • Đầu vào 1 không thay đổi
  • Đường dẫn tương đối đề cập đến cùng tệp / thư mục là đường dẫn tuyệt đối

Điểm tốt:

  • Nếu hệ điều hành của bạn tương thích với linux, bạn có thể sử dụng thư mục hiện tại của hệ thống thay vì nhận nó làm đầu vào
  • Bạn có thể giả sử các đầu vào chỉ chứa các ký tự chữ và số (và dấu phân cách đường dẫn)
  • Bạn có thể giả sử đường dẫn tuyệt đối đầu vào không có dấu phân cách đường dẫn /ở cuối
  • Bạn có thể giả sử thư mục hiện tại đầu vào có dấu phân cách đường dẫn /ở cuối
  • Bạn không thể cho rằng đường dẫn tuyệt đối đề cập đến một tệp hiện có hoặc bất kỳ phần nào trong đó là một thư mục có thể truy cập được; tuy nhiên, thư mục hiện tại có thể được coi là hợp lệ
  • Bạn có thể cho rằng không có liên kết tượng trưng ở bất kỳ đâu gần đường dẫn - bởi vì tôi không muốn yêu cầu bất kỳ cách xử lý đặc biệt nào với liên kết tượng trưng
  • Không cần hỗ trợ trong trường hợp một trong hai đầu vào là thư mục gốc
  • "Thư mục hiện tại" phải là đầu ra dưới dạng .(một chuỗi trống không hợp lệ)

Các trường hợp thử nghiệm (input1, input2, output):

/home/user/mydir/myfile
/home/user
mydir/myfile

/var/users/admin/secret/passwd
/var/users/joe/hack
../../admin/secret/passwd

/home/user/myfile
/tmp/someplace
/home/user/myfile

/dir1/dir2
/dir1/dir2/dir3/dir4
../..

/dir1/dir2
/dir1/dir2
.

1
"Bạn có thể giả sử thư mục hiện tại đầu vào có dấu phân cách đường dẫn /ở cuối". Tuy nhiên, trong ví dụ của bạn, đây không phải là trường hợp.
Shaggy

1
Tôi thích nó theo cách này, nhưng một số người thích nó theo cách khác
anatolyg


Điều gì sẽ xảy ra nếu đường dẫn tuyệt đối và tương đối có cùng độ dài?
Dennis

1
Điều này thiếu một số trường hợp thử nghiệm quan trọng: /home/test /home/user/mydir/myfile /home/test/a/b /a/b/d/e /a/b
Nathan Merrill

Câu trả lời:


7

Julia 0,5 , 32 byte

!,~=relpath,endof
t->~t<~!t?t:!t

Điều này sử dụng thư mục làm việc hiện tại làm cơ sở và không thể được kiểm tra trên TIO tại thời điểm này.

Chạy ví dụ

Cảnh báo: Điều này sẽ thay đổi hệ thống tập tin của bạn.

$ sudo julia --quiet
julia> function test(target,base)
       mkpath(base)
       cd(base)
       shorten(target)
       end
test (generic function with 1 method)
julia> !,~=relpath,endof
(relpath,endof)

julia> shorten = t->~t<~!t?t:!t
(::#1) (generic function with 1 method)

julia> test("/home/user/mydir/myfile","/home/user")
"mydir/myfile"

julia> test("/var/users/admin/secret/passwd","/var/users/joe/hack")
"../../admin/secret/passwd"

julia> test("/home/user/myfile","/tmp/someplace")
"/home/user/myfile"

julia> test("/dir1/dir2","/dir1/dir2/dir3/dir4")
"../.."

julia> test("/dir1/dir2","/dir1/dir2")
"."

Phiên bản thay thế, 35 byte (dyadic)

^,~=relpath,endof
t-b=~t<~t^b?t:t^b

Cái này lấy thư mục cơ sở làm đầu vào, vì vậy nó có thể được kiểm tra mà không cần sửa đổi hệ thống tập tin.

Hãy thử trực tuyến!


Xác định lại Base.-lỗi trừ khi được nhập rõ ràng, không?
Julian Wolf

Trong 0,5, nó có thể bị lỗi, nhưng chỉ khi bạn sử dụng -trước khi xác định lại. Trong 0,4, nó in một cảnh báo cho dù bạn sử dụng nó trước khi xác định lại hay không.
Dennis

9

JavaScript (ES6), 107 106 byte

Lấy đường dẫn tuyệt đối avà đường dẫn hiện tại ctheo cú pháp currying (a)(c).

a=>c=>(A=a.split`/`,s='',c.split`/`.map(d=>!s&A[0]==d?A.shift():s+='../'),s+=A.join`/`)[a.length]?a:s||'.'

Các trường hợp thử nghiệm


Một mẹo rất hay với [a.length]! Tôi có thể mượn nó để cải thiện câu trả lời Node.js của mình không?
zeppelin

@zeppelin Chắc chắn rồi. Cứ liều thử đi!
Arnauld


5

ES6 (Node.js REPL), 56, 54, 46, 45 byte

  • Sử dụng chuỗi rỗng, thay vì "." để biểu thị thư mục hiện tại (trên đầu vào), -1 byte
  • Mượn [f.length]mẹo từ câu trả lời của @ Arnauld , -6 byte
  • Sử dụng thư mục hiện tại thay vì tham số thư mục rõ ràng, -2 byte
  • Đã xóa các dấu ngoặc đơn thừa, -2 byte

Chơi gôn

f=>(r=path.relative("",f))[f.length]?f:r||"."

Kiểm tra

> F=f=>(r=path.relative("",f))[f.length]?f:r||"."
[Function: F]

> F("/home/user/mydir/myfile")
'mydir/myfile'

> F("/var/users/admin/secret/passwd")
'../../admin/secret/passwd'

> F("/home/user/myfile")
'/home/user/myfile'

> F("/dir1/dir2")
'../..'

> F("/dir1/dir2")
'.'

Chúng tôi không cho phép các hàm node.js?
Hạ cấp

@Downgoat Javascript lambdas được chấp nhận rộng rãi, như một dạng câu trả lời, vì vậy tôi không hiểu tại sao Node.js nên được xử lý khác nhau.
zeppelin

4

Python 2, 135 144 byte

i=0
a,c=input()
b,d=a.split('/')*(a!=c),c.split('/')
while b[:i+1]==d[:i+1]:i+=1
print'.'[i:]or min('/'.join(['..']*len(d[i:])+b[i:]),a,key=len)

Hãy thử trực tuyến!

Khá lâu, nhưng tôi muốn thực hiện một giải pháp mà không có các hàm đường dẫn tích hợp.

Chỉnh sửa: 9 byte được thêm vào tài khoản cho trường hợp thử nghiệm được cung cấp bởi Nathan Merrill



2

Python 3 - 53 byte

Sử dụng os.path:

import os
lambda x:min(x,os.path.relpath(x),key=len)

Chương trình đầy đủ (61 byte):

import os
x=input();print(min(x,os.path.relpath(x),key=len))

Oo, điểm tốt (s). Python đang dẫn đầu, yay!
matjoyce

@anatolyg Ha, tôi biết tôi đã bỏ lỡ ít nhất một trường hợp thử nghiệm ... Tất cả đã được sửa.
matjoyce

1

PHP, 204 byte

[,$l,$p]=$argv;$z=($d=array_diff_assoc)($y=($w=explode)("/",$p),$x=$w("/",$l));$m=str_pad("",3*count($z)-1,"../");$j=join("/",$r=$d($x,$y));echo$l!=$p?strlen($u=$m&&$j?"$m/$j":$m.$j)<strlen($l)?$u:$l:".";

Tủ thử

Mở rộng

[,$l,$p]=$argv;
$z=($d=array_diff_assoc)($y=($w=explode)("/",$p),$x=$w("/",$l));
$m=str_pad("",3*count($z)-1,"../");
$j=join("/",$r=$d($x,$y));
echo$l!=$p
    ?strlen($u=$m&&$j?"$m/$j":$m.$j)<strlen($l)
      ?$u
      :$l
    :".";

nếu một Đầu ra ../../thay thế of ../..được cho phép, nó có thể rút ngắn xuống còn 175 Byte

[,$l,$p]=$argv;$z=($d=array_diff_assoc)($y=($w=explode)("/",$p),$x=$w("/",$l));echo$l!=$p?strlen($m=str_pad("",3*count($z),"../").join("/",$r=$d($x,$y)))<strlen($l)?$m:$l:".";

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.