एक निरपेक्ष मार्ग को छोटा करें


17

कभी-कभी एक लंबा निरपेक्ष पथ, उदाहरण के लिए एक लाइन-टूल के लिए एक कमांड-लाइन पैरामीटर, संदर्भ के रूप में वर्तमान कार्य निर्देशिका का उपयोग करके छोटा किया जा सकता है:

$ pwd
/home/heh

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

$ cat mydir/myfile
my stuff

इस चुनौती में, आपको एक फ़ंक्शन या एक प्रोग्राम बनाना चाहिए जो दो पैरामीटर प्राप्त करता है:

  1. पूर्ण पथ, लिनक्स प्रारूप का उपयोग करके (के साथ शुरू होता है) / )
  2. एक ही प्रारूप का उपयोग करके वर्तमान निर्देशिका

आउटपुट निम्न में से छोटा है:

  • इनपुट 1 अपरिवर्तित
  • सापेक्ष पथ जो पूर्ण पथ के समान फ़ाइल / निर्देशिका को संदर्भित करता है

ठीक अंक:

  • यदि आपका ऑपरेटिंग सिस्टम लिनक्स के साथ संगत है, तो आप इसे इनपुट के रूप में प्राप्त करने के बजाय सिस्टम की वर्तमान निर्देशिका का उपयोग कर सकते हैं
  • आप मान सकते हैं कि इनपुट में केवल अल्फ़ान्यूमेरिक वर्ण (और पथ विभाजक) हैं
  • आप मान सकते हैं कि इनपुट निरपेक्ष पथ /के अंत में एक पथ विभाजक नहीं है
  • आप मान सकते हैं कि इनपुट करंट डायरेक्टरी में /अंत में एक पथ विभाजक है
  • आप यह नहीं मान सकते कि निरपेक्ष पथ एक मौजूदा फ़ाइल को संदर्भित करता है, या इसका कोई भी हिस्सा एक सुलभ निर्देशिका है; हालाँकि, वर्तमान निर्देशिका को मान्य माना जा सकता है
  • आप मान सकते हैं कि किसी भी मार्ग के पास कहीं भी सिम्बलिंक नहीं हैं - क्योंकि मुझे सिम्बलिंक से निपटने के लिए किसी विशेष तरीके की आवश्यकता नहीं है
  • उस मामले का समर्थन करने की आवश्यकता नहीं है जहां या तो इनपुट मूल निर्देशिका है
  • "वर्तमान निर्देशिका" को आउटपुट होना चाहिए .(एक रिक्त स्ट्रिंग मान्य नहीं है)

टेस्ट केस (इनपुट 1, इनपुट 2, आउटपुट):

/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
"आप मान सकते हैं कि इनपुट वर्तमान निर्देशिका /के अंत में एक पथ विभाजक है "। हालांकि, आपके उदाहरणों में, यह मामला नहीं है।
झबरा

1
मुझे यह इस तरह से पसंद है, लेकिन कुछ लोग इसे दूसरे तरीके से पसंद करते हैं
एनाटॉलीग


यदि निरपेक्ष और सापेक्ष पथ समान लंबाई के हों तो क्या होना चाहिए?
डेनिस

1
यह कुछ महत्वपूर्ण परीक्षण मामलों को याद कर रहा है: /home/test /home/user/mydir/myfile /home/testऔर/a/b /a/b/d/e /a/b
नाथन मेरिल

जवाबों:


7

जूलिया 0.5 , 32 बाइट्स

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

यह वर्तमान कार्यशील निर्देशिका को आधार के रूप में उपयोग करता है और फिलहाल TIO पर परीक्षण नहीं किया जा सकता है।

उदाहरण चलाते हैं

चेतावनी: यह आपकी फ़ाइल प्रणाली को बदल देगा।

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

वैकल्पिक संस्करण, 35 बाइट्स (डायडिक)

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

यह आधार निर्देशिका को इनपुट के रूप में लेता है, इसलिए इसे फ़ाइल सिस्टम को संशोधित किए बिना परीक्षण किया जा सकता है।

इसे ऑनलाइन आज़माएं!


Base.-त्रुटियों को फिर से परिभाषित करना जब तक कि स्पष्ट रूप से आयात नहीं किया जाता है, नहीं?
जूलियन वुल्फ

0.5 में, यह त्रुटि हो सकती है, लेकिन केवल अगर आप -इसे फिर से परिभाषित करने से पहले उपयोग करते हैं। 0.4 में, यह एक चेतावनी प्रिंट करता है कि क्या आप इसे पुन: परिभाषित करने से पहले उपयोग करते हैं या नहीं।
डेनिस

9

जावास्क्रिप्ट (ईएस 6), 107 106 बाइट्स

सिंटेक्स में पूर्ण पथ aऔर वर्तमान पथ cको ले जाता है (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||'.'

परीक्षण के मामलों


साथ एक बहुत अच्छी चाल [a.length]! क्या मैंने अपने Node.js उत्तर को बेहतर बनाने के लिए इसे उधार लिया है?
ज़ेपेलिन

@zeppelin ज़रूर। इसका लाभ उठाएं!
अरनौलड


5

ES6 (Node.js REPL), 56, 54, 46, 45 बाइट्स

  • "के बजाय खाली स्ट्रिंग का उपयोग करें।" वर्तमान निर्देशिका (इनपुट पर), -1 बाइट को निरूपित करने के लिए
  • उधार [f.length]@ Arnauld से चाल जवाब , -6 बाइट्स
  • एक स्पष्ट निर्देशिका पैरामीटर के बजाय वर्तमान निर्देशिका का उपयोग करें, -2 बाइट्स
  • हटाए गए शानदार कोष्ठक, -2 बाइट्स

golfed

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

परीक्षा

> 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")
'.'

क्या हम नोड.जेएस कार्यों की अनुमति नहीं देते हैं?
डाउनगोट

@Downgoat जावास्क्रिप्ट लैम्ब्डा व्यापक रूप से स्वीकार किए जाते हैं, उत्तर के रूप में, इसलिए मैं यह नहीं देखता कि Node.js को अलग तरीके से क्यों संभाला जाना चाहिए।
zeppelin

4

पायथन 2, 135 144 बाइट्स

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)

इसे ऑनलाइन आज़माएं!

लंबे समय से, लेकिन मैं अंतर्निहित पथ कार्यों के बिना एक समाधान करना चाहता था।

संपादित करें: नाथन मेरिल द्वारा प्रदान किए गए परीक्षण मामले के लिए 9 बाइट्स को जोड़ा गया


3

Zsh + realpath, 58 बाइट्स

r=`realpath -m --relative-to=$*`
(($#2<$#r))&&r=$2
echo $r

इसे ऑनलाइन आज़माएं!

बैश संस्करण, 62 बाइट्स

r=`realpath -m --relative-to=$*`
((${#2}<${#r}))&&r=$2
echo $r

इसे ऑनलाइन आज़माएं!


इसे दो अलग-अलग उत्तरों में क्यों नहीं पोस्ट करें? हर भाषा मायने रखती है!
गाबर्सच

2

पायथन 3 - 53 बाइट्स

का उपयोग कर os.path:

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

पूर्ण कार्यक्रम (61 बाइट्स):

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

ऊ, अच्छा बिंदु (s)। पायथन के नेतृत्व में अब, याय!
मत्सजॉय

@anatolyg हा, मुझे पता था कि मुझे कम से कम एक परीक्षा का मामला याद होगा ... अब सब तय हो गया है।
मत्सजॉय

1

PHP, 204 बाइट्स

[,$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:".";

परीक्षण के मामलों

विस्तारित

[,$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
    :".";

यदि ../../इसके बजाय एक आउटपुट of ../..की अनुमति है तो इसे 175 बाइट्स तक छोटा किया जा सकता है

[,$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:".";

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.