सापेक्ष पथ मुद्रित करें


15

विवरण

स्रोत पथ और गंतव्य पथ को देखते हुए, स्रोत के संबंध में गंतव्य के सापेक्ष पथ को आउटपुट करता है।

नियम

  1. इनपुट स्टड से या प्रोग्राम / फ़ंक्शन के तर्क के रूप में आ सकता है।

  2. विंडोज और यूनिक्स शैली के रास्ते दोनों का समर्थन किया जाना चाहिए।

  3. आउटपुट पथ उपयोग कर सकता है /और / या \पथ विभाजक के लिए (आपकी पसंद और संयोजन दोनों ठीक है)।

  4. आप मान सकते हैं कि एक रिश्तेदार मार्ग संभव है।

  5. बाहरी कार्यक्रमों का उपयोग, अंतर्निहित पथ या पुस्तकालय कार्यों के सापेक्ष पथ की गणना करने के लिए निषिद्ध है (जैसे पायथन का os.path.relpath)

  6. यह

    संपादित करें: टिप्पणियों से नया नियम।

  7. सापेक्षिक पथ संभवतया सबसे छोटा सापेक्ष पथ होना चाहिए।

  8. मान लें कि गंतव्य पथ स्रोत पथ से भिन्न है।

उदाहरण 1

# In
/usr/share/geany/colorschemes
/usr/share/vim/vim73/ftplugin

# Out
../../vim/vim73/ftplugin

उदाहरण 2

# In
C:\Windows\System32\drivers
C:\Windows\System32\WindowsPowerShell\v1.0

# Out
..\WindowsPowerShell\v1.0

नियम # 3 के बारे में - क्या मिश्रण ठीक है? जैसे ../../vim\vim73\ftplugin
डंकन जोन्स

1
क्या हमें सबसे छोटा सापेक्ष पथ वापस करना है या किसी भी पथ का निर्माण करना ठीक है?
हावर्ड

@ डंकन हाँ, एक मिश्रण ठीक है।
रिनेंट

1
@ हावर्ड, यह सबसे छोटा सापेक्ष पथ होना चाहिए।
रिनेंट

पहला उदाहरण नहीं होना चाहिए ../vim/vim73/ftplugin?
Martijn

जवाबों:


2

सीजेएम, 46 बाइट्स

ll]{'\/'/f/:~}/W{)__3$=4$@==}g@,1$-"../"*o>'/*

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

उदाहरण

$ echo '/usr/share/geany/colorschemes
> /usr/share/vim/vim73/ftplugin' | cjam path.cjam; echo
../../vim/vim73/ftplugin
$ echo 'C:\Windows\System32\drivers
> C:\Windows\System32\WindowsPowerShell\v1.0' | cjam path.cjam; echo
../WindowsPowerShell/v1.0

यह काम किस प्रकार करता है

ll]         " Read two lines from STDIN and wrap them in an array.                       ";
{           " For each line:                                                             ";
  '\/       " Split by “\”.                                                              ";
  '/f/      " Split each chunk by “/”.                                                   ";
  :~        " Flatten the array of chunks.                                               ";
}/          "                                                                            ";
W           " Push -1 (accumulator).                                                     ";
{           "                                                                            ";
  )__       " Increment and duplicate twice.                                             ";
  3$=       " Extract the corresponding chunk from the first line.                       ";
  4$@=      " Extract the corresponding chunk from the second line.                      ";
  =         " If the are equal,                                                          ";
}g          " repeat the loop.                                                           ";
@,          " Rotate the array of chunks of the first line on top and get its length.    ";
1$-         " Subtract the value of the accumulator.                                     ";
"../"*o     " Print the string “../” repeated that many times.                           ";
>           " Remove all chunks with index less than the accumulator of the second line. ";
'/*         " Join the chunks with “/”.                                                  ";

1
इसका एक बग है। के /aa/xसाथ प्रयास करें /ab/y
jimmy23013

@ user23013: फिक्स्ड।
डेनिस

2

बैश + कोरुटिल्स, 116

गेंद को रोल करने के लिए यहां एक शेल स्क्रिप्ट है। बहुत यकीन है कि छोटे जवाब होंगे:

n=`cmp <(echo $1) <(echo $2)|grep -Po "\d+(?=,)"`
printf -vs %`grep -o /<<<${1:n-1}|wc -l`s
echo ${s// /../}${2:n-1}

आउटपुट:

$ ./rel.sh /usr/share/geany/colorschemes /usr/share/vim/vim73/ftplugin
../vim/vim73/ftplugin
$ ./rel.sh /usr/share/geany/colorschemes/ /usr/share/vim/vim73/ftplugin/
../../vim/vim73/ftplugin/
$ ./rel.sh /usr/share/vim/vim73/ftplugin /usr/share/geany/colorschemes
../../geany/colorschemes
$ 

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

व्हॉट्सएप या अन्य मजेदार पात्रों वाले रास्तों को नहीं संभालेंगे। निश्चित नहीं है कि आवश्यकता है या नहीं। बस कुछ अतिरिक्त उद्धरण की आवश्यकता होगी।


2

जावास्क्रिप्ट (E6) 104

आउटपुट के लिए जोड़ा गया अलर्ट संपादित करें

R=(s,d)=>alert(s.split(x=/\/|\\/).map(a=>a==d[0]?d.shift()&&'':'../',d=d.split(x)).join('')+d.join('/'))

Ungolfed

R (s,d) => // a single espression is returned, no {} or () needed
  s.split(x=/\/|\\/) // split string at / or \, save regexp in X for later
  .map( // create a new array from s
     a => a == d[0] // check if current of s and d equals
          ? d.shift() && '' // map to '' and cut 1 element of d
          : '../', // else map to '../'
     d=d.split(x)) // second param of map is useless, so split d here
  .join('')+d.join('/') // join map and concat to rest of d adding separators

परीक्षा

R('C:\\Windows\\System32\\drivers','C:\\Windows\\System32\\WindowsPowerShell\\v1.0')

../WindowsPowerShell/v1.0

R('/usr/share/geany/colorschemes','/usr/share/vim/vim73/ftplugin')

../../vim/vim73/ftplugin


2

रूबी> = 1.9, 89 94 पात्र

$;=/\\|\//
a,b=$*.map &:split
puts"../"*(a.size-r=a.index{a[$.+=1]!=b[$.]}+1)+b[r..-1]*?/

कमांड लाइन तर्कों के माध्यम से इनपुट। दोनों UNIX- और विंडोज-शैली पथों के लिए काम करता है, जिसमें दोहराया फ़ोल्डर नामों के साथ पथ शामिल हैं:

$ ruby relpath.rb /usr/share/geany/colorschemes /usr/share/vim/vim73/ftplugin
../../vim/vim73/ftplugin
$ ruby relpath.rb 'C:\Windows\System32\drivers' 'C:\Windows\System32\WindowsPowerShell\v1.0'
../WindowsPowerShell/v1.0
$ ruby relpath.rb /foo/bar/foo/bar /foo/qux/foo/bar
../../../qux/foo/bar

2

जे - 63 चार

बाईं ओर पुराना पथ और दाईं ओर नया पथ लेने वाला कार्य।

}.@;@(c=.c&}.`(,~(<'/..')"0)@.(~:&{.))&('/'<;.1@,'\/'&charsub)~

यह घोल तीन भागों में मिलता है, जैसा दिखता है post@loop&pre~। विस्फोट से समझाया:

post @ loop & pre ~   NB. the full golf
                  ~   NB. swap the arguments: new on left, old on right
            & pre     NB. apply pre to each argument
       loop           NB. run the recursive loop on both
post @                NB. apply post to the final result

'/'<;.1@,'\/'&charsub  NB. pre
         '\/'&charsub  NB. replace every \ char with /
'/'     ,              NB. prepend a / char
   <;.1@               NB. split string on the first char (/)

c=.c&}.`(,~(<'/..')"0)@.(~:&{.)  NB. loop
                      @.(~:&{.)  NB. if the top folders match:
    &}.                          NB.   chop off the top folders
   c                             NB.   recurse
       `                         NB. else:
           (<'/..')"0            NB.   change remaining old folders to /..
         ,~                      NB.   append to front of remaining new folders
c=.                              NB. call this loop c to recurse later

}.@;  NB. post
   ;  NB. turn the list of folders into a string
}.@   NB. chop off the / in the front

ध्यान दें कि हम /बंटवारे से पहले प्रत्येक पथ के लिए एक अग्रणी जोड़ते हैं , ताकि हम C:"फ़ोल्डर" में बनाकर विंडोज-शैली पथों को संभाल सकें । यह यूनिक्स-शैली पथों की शुरुआत में एक खाली फ़ोल्डर में परिणत होता है, लेकिन यह हमेशा लूप द्वारा हटा दिया जाता है।

इसे कार्रवाई में देखें:

   NB. you can use it without a name if you want, we will for brevity
   relpath =. }.@;@(c=.c&}.`(,~(<'/..')"0)@.(~:&{.))&('/'<;.1@,'\/'&charsub)~
   '/usr/share/geany/colorschemes' relpath '/usr/share/vim/vim73/ftplugin'
../../vim/vim73/ftplugin
   'C:\Windows\System32\drivers' relpath 'C:\Windows\System32\WindowsPowerShell\v1.0'
../WindowsPowerShell/v1.0

आप इसे tryj.tk पर स्वयं भी आज़मा सकते हैं ।


2

बैश, 69 66

मैंने इसे पोस्ट नहीं किया क्योंकि मुझे लगा कि किसी को इसे बेहतर तरीके से करने में सक्षम होना चाहिए। लेकिन स्पष्ट रूप से यह इतना आसान नहीं है।

sed -r 'N;s/(.*[/\])(.*)\n\1/\2\n/'|sed '1s/[^/\]*/../g;N;s!\n!/!'

Nsedमैच दो लाइनों को एक साथ बनाता है । पहली अभिव्यक्ति के साथ /या समाप्त होने वाले सामान्य उपसर्ग को हटा देता है \। दूसरी अभिव्यक्ति निर्देशिका नामों ..को पहली पंक्ति में बदल देती है । अंत में यह विभाजक के साथ दो रेखाओं को मिलाता है।

3 पात्रों के लिए हस्त्कुर्क धन्यवाद।


दिलचस्प लग रहा है! क्या आप एक स्पष्टीकरण जोड़ सकते हैं?
डिजिटल ट्रामा

1
@DigitalTrauma जोड़ा गया। लेकिन मूल रूप से वे सिर्फ नियमित अभिव्यक्ति हैं।
jimmy23013

धन्यवाद! मैं इसके साथ खेलने जा रहा हूँ अगली बार मैं एक टर्मिनल पर हूँ
डिजिटल ट्रॉमा

आपको वास्तव में sedदो बार चलाने की आवश्यकता नहीं है , आप एक स्क्रिप्ट के साथ ऐसा कर सकते हैं।
हस्त्कर्ण

@Hasturkun लेकिन मुझे इसके साथ काम करने का कोई तरीका नहीं मिला N। शायद आप इस उत्तर को संपादित कर सकते हैं यदि आप जानते हैं कि कैसे।
jimmy23013

1

सी, 119 106

void p(char*s,char* d){while(*s==*d){s++;d++;}s--;while(*s){if(*s==47||*s==92)printf("../");s++;}puts(d);}

p(char*s,char*d){for(;*s;)*s++-*d?*s-47||printf("../"):d++;puts(d);}68 चरस w / o बैकस्लैश
bebe

धन्यवाद! लेकिन नियम 2 कहता है कि दोनों का समर्थन होना चाहिए। यह आउटपुट में है जहां मैं एक या दूसरे को चुन सकता हूं (नियम 3)।
kwokkie

1

अजगर 3, 120

a,b=(i.split('\\/'['/'in i])for i in map(input,'  '))
while[]<a[:1]==b[:1]:del a[0],b[0]
print('../'*len(a)+'/'.join(b))

उदाहरण:

$ python3 path.py
 /usr/share/geany/colorschemes
/usr/share/vim/vim73/ftplugin 
../../vim/vim73/ftplugin

हो सकता है कि लाइन 1 execऔर स्ट्रिंग ऑपरेशन के साथ एक छोटा तरीका हो ?
xnor

@xnor हो सकता है, लेकिन मैं इसे नहीं देख सकता।
GRC

हो सकता है map(input,' ')के लिए काम `(इनपुट (), इनपुट ())? (मैं खुद इसका परीक्षण नहीं कर सकता)
xnor

@xnor हाँ जो काम करता है धन्यवाद!
जीसी

1

रूबी - 89

r=/\/|\\/
s = ARGV[0].split r
d = ARGV[1].split r
puts ("../"*(s-d).size)+((d-s).join"/")

उपयोग:

ruby relative.rb working/directory destination/directory

3
इस तरह के तर्कों के लिए विफल रहता है /foo/bar/foo/barऔर /foo/qux/foo/bar
वेंटरो

और विंडोज स्टाइल पथ के लिए विफल रहता है
edc65

@ edc65 नियम यह नहीं कहते कि दोनों पथ स्वरूपों का समर्थन करना आवश्यक है, आप दोनों में से कोई एक कर सकते हैं।
अंडर

@nderscore नियम 2 विंडोज और यूनिक्स शैली के रास्ते दोनों का समर्थन किया जाना चाहिए।
edc65

1
@ जॉस्टी: ठीक है, यह सौंदर्य है, है ना? एक समाधान के साथ आ रहा है जो छोटा और सही दोनों है। मेरे पास अतीत में ऐसे मामले हैं जहां मुझे एक अनदेखी बढ़त मामले के कारण उत्तर को पूरी तरह से संशोधित करना पड़ा। अब, इस मामले में मैं दोष को आंशिक रूप से कार्य पर भी डाल देता हूं, क्योंकि मेरा मानना ​​है कि परीक्षण मामलों का एक ठोस सेट हर कार्य के साथ होना चाहिए, लेकिन अच्छी तरह से।
जॉय

0

जावास्क्रिप्ट - 155

function p(s,d){s=s.split(/\\|\//g);d=d.split(/\\|\//g);o=[];for(i=0;s[i]==d[i];i++);for(j=s.length-i;j--;)o[j]="..";return o.concat(d.slice(i)).join("/")}

पार्स या तो पथ प्रारूप लेकिन /विभाजक के साथ आउटपुट ।

console.log(p("/usr/share/geany/colorschemes","/usr/share/vim/vim73/ftplugin"));
../../vim/vim73/ftplugin
console.log(p("/usr/share/geany/colorschemes/test/this","/usr/share/vim/vim73/ftplugin/this/is/a/test"));
../../../../vim/vim73/ftplugin/this/is/a/test
console.log(p("c:\\windows\\system32\\drivers\\etc\\host","c:\\windows\\system\\drivers\\etc\host"));
../../../../system/drivers/etchost

0

पीएचपी, 158 151

function r($a,$b){$a=explode('/',$a);$b=explode('/',$b);foreach($a as $k=>$v){if($v==$b[$k])$b[$k]='..';else break;}unset($b[0]);echo implode('/',$b);}

Ungolfed:

function r($a,$b){
    $a=explode('/',$a);
    $b=explode('/',$b);
    foreach($a as $k=>$v){
        if($v==$b[$k])$b[$k]='..';
        else break; 
    }
    unset($b[0]);
    echo implode('/',$b);
}
// these lines are not included in count:
r('/test/test2/abc','/test/test3/abcd'); // ../test3/abcd
r('/test/test2/abc','/test/test2/abcd'); // ../../abcd

आपका उत्तर सही नहीं है। इस dirs और बनाने का प्रयास करें cdएक और :) करने के लिए प्रपत्र एक
core1024

0

ग्रूवी - 144 वर्ण

एक हल:

x=args[0][1]!=':'?'/':'\\'
f={args[it].tokenize x}
s=f 0
d=f 1
n=0
while(s[n]==d[n++]);
u="..$x"*(s.size-(--n))
println "$u${d.drop(n).join x}"

उदाहरण आउटपुट:

bash$ groovy P.groovy C:\\Windows\\System32\\drivers C:\\Windows\\System32\\WindowsPowerShell\\v1.0
..\WindowsPowerShell\v1.0

bash$ groovy P.groovy /usr/share/geany/colorschemes /usr/share/vim/vim73/ftplugin
../../vim/vim73/ftplugin

bash$ groovy P.groovy /foo/bar/foo/bar /foo/qux/foo/bar
../../../qux/foo/bar

ungolfed:

// fs = file seperator, / or \
fs = args[0][1]!=':'?'/':'\\'

s = args[0].tokenize fs
d = args[1].tokenize fs

// n = # of matching dirs from root + 1
n = 0
while (s[n] == d[n++]) ;

// up = the up-prefix. e.g. "../../..", for instance 
n--
up = "..${fs}" * (s.size-n)

println "$up${d.drop(n).join fs}"
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.