Tính toán thư mục


19

Đối với thử thách này, bạn sẽ được cung cấp một đường dẫn tuyệt đối và một đường dẫn "mới" (có thể là tuyệt đối hoặc tương đối) và bạn cần trả về đường dẫn cuối cùng.

Ví dụ: nếu thư mục hiện tại của bạn là /var/tmp/test:

my_dirhoặc my_dir/ nên trở lại/var/tmp/test/my_dir

../../my_dir nên trở về /var/my_dir

/my_dir/./ nên trở về /my_dir

../../../../../ nên trở về /

Để được nhiều hơn phạm vi:

  • Một thư mục là một chuỗi không có sản phẩm nào bao gồm ký tự chữ và các biểu tượng -, _hoặc.
  • Đường dẫn là danh sách 0 hoặc nhiều thư mục , được phân tách bằng cách sử dụng /. Một đường dẫn tuyệt đối bắt đầu bằng một /, một đường dẫn tương đối thì không. Đường dẫn có thể bao gồm một kết thúc /.

Bạn cần "giải quyết" đường dẫn thứ hai, đưa ra đường dẫn đầu tiên.

Quá trình giải quyết là:

  1. Kiểm tra nếu đường dẫn thứ hai là tương đối. Nếu vậy, sau đó chèn các thư mục của đường dẫn tuyệt đối vào đầu đường dẫn thứ hai.
  2. Nếu bất kỳ thư mục là .., sau đó loại bỏ nó và thư mục trước. Nếu nó là thư mục đầu tiên, sau đó chỉ cần loại bỏ nó.
  3. Nếu bất kỳ thư mục là ., sau đó loại bỏ nó.
  4. Đầu ra đường dẫn tuyệt đối cuối cùng. Bạn không nên kết thúc /.

Bạn không cần phải xử lý đầu vào không chính xác. Các lệnh sẽ hoạt động, cho dù các thư mục được truyền có thực sự tồn tại trên máy của bạn hay không. Bạn có thể cho rằng mọi thứ là một thư mục, ngay cả khi nó có phần mở rộng.

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

Absolute      New          Output
"/a/b/c"      "d"       -> "/a/b/c/d" 
"/a/b/c/"     "d"       -> "/a/b/c/d"
"/a/b/c/"     "d/"      -> "/a/b/c/d"
"/a/b/c"      "/d"      -> "/d"
"/a/b/c"      "/d/"     -> "/d"
"/../a/b/c/"  "d"       -> "/a/b/c/d"
"/a/../b/c/"  "d"       -> "/b/c/d"
"/a/b/../c"   "d"       -> "/a/c/d"
"/a/b/c/.."   "d"       -> "/a/b/d"
"/a/b/c/"     ".."      -> "/a/b"
"/a/b/c"      "../d"    -> "/a/b/d"
"/a/b/c"      "/../d"   -> "/d"
"/a/b/c"      ""        -> "/a/b/c"
"/a/b/c"      "."       -> "/a/b/c"
"/a/b/c"      "./d"     -> "/a/b/c/d"
"/a/b/c"      "/./d"    -> "/d"
"/a/b/c"      "d.txt"   -> "/a/b/c/d.txt"
"/a/b/c"      "d."      -> "/a/b/c/d."
"/a/b/c"      ".txt"    -> "/a/b/c/.txt"
"/a/b/c"      ".txt/d"  -> "/a/b/c/.txt/d"
"/a/b/."      "./././." -> "/a/b"
"/direc"      "tory"    -> "/direc/tory"
"/a-_.b/"     "__._-."  -> "/a-_.b/__._-."
"/a/b"        "../.."   -> "/"
"/a/b"        "../../.."-> "/"
"/a"          "../../.."-> "/"
"/"           ""        -> "/"
"/"           "a"       -> "/a"
"/.."         "a"       -> "/a"
"/."          ""        -> "/"

Đây là một , vì vậy hãy gửi bài của bạn càng ngắn càng tốt bằng ngôn ngữ yêu thích của bạn!


Một số câu trả lời dường như cho rằng các tệp (hoặc liên kết tượng trưng) có cùng tên với bất kỳ phần nào của cây thư mục) không tồn tại trên máy. Điều đó có được phép không?
Dennis

Chúng tôi có thể lấy hai đầu vào theo bất kỳ thứ tự nào chúng tôi muốn không?
Hạ cấp

Câu hỏi ngu ngốc ... tôi có thể có tác dụng phụ? Cụ thể, tác dụng phụ như, um, mkdir $patha; cd $patha; mkdir $pathb; cd $pathb; echo `abspath`(hoặc cái gì đó)?
mèo

@dennis. Đầu ra của các chương trình phải độc lập với hệ thống tệp
Nathan Merrill

@downgoat không sao cả
Nathan Merrill

Câu trả lời:


7

Võng mạc , 44 byte

+`.+ /| |/\.?/
/
+1`/?[^/]*/\.\.|/\.?$

^$
/

Đầu vào dự kiến ​​là hai đường dẫn cách nhau bởi một khoảng trắng.

Hãy thử trực tuyến! (Dòng đầu tiên cho phép bộ kiểm tra được phân tách bằng nguồn cấp.)


3

Python, 53 byte

from os.path import*;p=lambda a,n:normpath(join(a,n))

3

Mẻ, 282 281 279 276 byte

@echo off
set a=\
set r=%~2
if "%r%"=="" set r=%~1
if not %r:~,1%==/ set r=%~1/%~2
for %%a in (%r:/= %)do call:x %%a
if not %a%==\ set a=%a:~,-1%
echo %a:\=/%
exit/b
:x
if %1==. exit/b
if not %1==.. set a=%a%%1\&exit/b
if not %a%==\ for %%a in (%a:~,-1%)do set a=%%~pa

Các biểu thức Batch gây khó chịu thường không giống như các biến rỗng. Chỉnh sửa: Đã lưu 1 byte nhờ @ CᴏɴᴏʀO'Bʀɪᴇɴ và 2 byte nhờ @ EʀɪᴋᴛʜᴇGᴏʟғᴇʀ (và một loạt các byte trên các câu trả lời khác, mặc dù than ôi không được công nhận).


Tôi nghĩ bạn có thể xóa khoảng calltrắng giữa và: x`, không?
Conor O'Brien

@ CᴏɴᴏʀO'Bʀɪᴇɴ Huh, vì vậy bạn có thể. Tôi đã có một loạt các câu trả lời cần cập nhật trong trường hợp đó ...
Neil

2

Python 2, 265 260 254 byte

y=lambda:[x for x in raw_input().split("/")if x!=""and x!="."]
a=y();n=y();m=len(a)-1
while m>0:
 if a[m]==".."and m>0:del a[m];del a[m-1];m-=1
 elif a[m]=="..":del a[m]
 m-=1
for i in n:
 if i==".."and len(a)>0:del a[-1]
 else:a+=i,
print"/"+"/".join(a)

1

Python, 142 137 byte

def p(a,n,r=[],S="/"):
 for s in[s for s in((n[:1]!=S)*a+S+n).split(S)if"."!=s and s]:e=s!="..";r=[s]*e+r[1-e:]
 return S+S.join(r[::-1])

1

Bash, 41 byte

Tập lệnh bash này có tác dụng phụ là tạo thư mục nếu chúng không tồn tại, nhưng nó phải đáp ứng các yêu cầu. Cảm ơn KarlNeil vì những cải tiến của bạn.

mkdir -p $1;cd $1;mkdir -p $2;cd "$2";pwd

Cách sử dụng: bash getpath.sh "tuyệt đối" "mới"

Nếu bạn không thích thiết bị lỗi chuẩn khi đối số thứ hai là một chuỗi rỗng, bạn có thể kiểm tra nó như sau (48 byte):

mkdir -p $1;cd $1;[ $2 ]&&mkdir -p $2&&cd $2;pwd

Nỗ lực 30 byte trước đó (yêu cầu tồn tại các thư mục): cd $ 1; [$ 2] && cd $ 2; echopwd


Câu hỏi cho biết Các lệnh sẽ hoạt động, cho dù các thư mục được truyền có thực sự tồn tại trên máy của bạn hay không.
Dennis

Ah tôi thấy. Quá tệ.
Bryn

Xin chào, và chào mừng đến với PPCG! Thông thường, nếu câu trả lời của bạn không hoạt động, bạn xóa nó đi. Bạn có thể nhấp vào liên kết xóa phía trên bình luận này.
NoOneIsHãy

Bạn có thể mkdir -pchắc chắn rằng chúng tồn tại.
Karl Napf 16/07/2016

Cảm ơn, tôi đang thử một phiên bản với mkdir. Tôi sẽ xóa câu trả lời này và thêm một câu trả lời mới nếu tôi tìm ra nó.
Bryn

1

C #, 43 byte

(x,y)=>Path.GetFullPath(Path.Combine(x,y));

Đã lưu 1 byte nhờ vào @aloitorg

Path.Combineđặt các đối số lại với nhau và Path.GetFullPathgiải quyết ..\s


Xin chào, và chào mừng đến với PPCG! Đây không phải là một chương trình hợp lệ - bao gồm mainvà một lớp, hoặc thay đổi nó thành một lanbda: a,b->...
NoOneIsHere 16/07/2016

Tôi sẽ gửi nó :) Gửi đầu tiên tốt đẹp! bạn có thể xóa khoảng ,(x, y)(x,y)
trắng

Ngoài ra các mẹo C # cho chủ đề chơi golf có thể bạn quan tâm.
aloisdg nói Phục hồi lại

1

Nút REPL, 8 12 byte

path.resolve

May mắn thay, bạn không phải require()mô-đun chuẩn trong REPL.

Phòng thử nghiệm

https://repl.it/Cclo/1

(Nếu đầu ra ở cuối là true, nó khớp)


1

Javascript, 210 byte

function p(a,b){d='.';e=d+d;s='/';t='split';u='splice';r=(b[0]===s?[]:a[t](s)).concat(b[t](s));for(i=0;i<r.length;r[i]===e&&r[u](i?i-1:i,i?2:1)?(i&&i--):i++)(!r[i]||r[i]===d)&&r[u](i,1)&&i--;return s+r.join(s)}

Đây là bộ thử nghiệm

Với dấu ngắt dòng thay vì dấu chấm phẩy:

function p(a,b) {
    d='.'
    e=d+d
    s='/'
    t='split'
    u='splice'

    r=(b[0]===s?[]:a[t](s)).concat(b[t](s))

    for(i=0;i<r.length;r[i]===e&&r[u](i?i-1:i,i?2:1)?(i&&i--):i++)
        (!r[i]||r[i]===d)&&r[u](i,1)&&i--

    return s+r.join(s)
}

0

Java 7, 83 byte

String p(String a,String b){return Paths.get(a).resolve(b).normalize().toString();}

normalizelà cần thiết để đối phó với các tài liệu tham khảo tương đối. addđược sử dụng để xử lý đường dẫn thứ hai bắt đầu bằng /, đường dẫn này Paths.get(a, b)sẽ không xử lý như được chỉ định.


Xin chào, và chào mừng đến với PPCG! Đây là một bài viết đầu tiên tốt!
NoOneIsHãy

0

Bash, 38 byte

[[ $2 = /* ]]||p=$1
realpath -sm $p/$2

Không yêu cầu quyền root và không đưa ra giả định nào về các tệp, thư mục hoặc liên kết tượng trưng hiện có hoặc không tồn tại.

Kiểm tra nó trên Ideone .

Làm thế nào nó hoạt động

[[ $2 = /* ]]kiểm tra nếu đối số dòng lệnh thứ hai bắt đầu bằng /.

Nếu không, đường dẫn là tương đối và p=$1đặt biến p thành đối số dòng lệnh đầu tiên.

Cách này $p/$2/$2nếu $2là một con đường tuyệt đối và $1/$2nếu nó là một con đường thực tế .

Cuối cùng, realpath -sm $p/$2in đường dẫn tuyệt đối chính tắc của $p/$2. Công -stắc làm cho realpath bỏ qua các liên kết tượng trưng và công -mtắc thiếu các thành phần.


0

Ruby, 16 byte

Vì rõ ràng sử dụng một phương thức từ thư viện chuẩn được cho phép:

File.expand_path

Xem các bộ kiểm tra trên repl.it .


Nhập thông qua các biến không được phép, nhưng chức năng gửi, có nghĩa là bạn nên rút ngắn nó xuống File.expand_path:)
Nathan Merrill

Tôi cũng khuyên bạn nên thực sự thử nghiệm nó với bộ thử nghiệm để đảm bảo rằng nó hoạt động chính xác trên tất cả các trường hợp thử nghiệm.
Nathan Merrill

@NathanMerrill Tôi đã làm, nhưng tôi sẽ tiếp tục và đưa ra một cái gì đó trên repl.it.
Jordan

Chỉnh sửa để bao gồm liên kết bộ thử nghiệm.
Jordan

0

GNU sed , 81 59 + 1 = 60 byte

+1 byte cho -rcờ. Yêu cầu đầu vào trên STDIN phân tách bằng một khoảng trắng.

s:.+ /::
s:/? :/:
:
s:/$|[^/]+/+\.\.|\.(/|$):\1:
t
s:^/*:/:

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

Giải trình

s:.+ /::  # If the second argument starts with a slash, drop the first argument
s:/? :/:  # Join the first and second arguments with a slash, dropping duplicate slashes
:
  s:/$|[^/]+/+\.\.|\.(/|$):\1:  # Drop trailing slashes, resolve double and single dots
  t                             # If the above substitution was made, branch to :
s:^/*:/:  # Ensure output begins with a single slash

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.