Find common directory path: Difference between revisions
(→{{header|PureBasic}}: Although there are only three paths in the example the task asks for a routine that works on an arbitrary set of paths, and the separator should also be an argument to the r) |
(Updated the task description to say what I meant. Less mind reading now needed to complete the task :-) .) |
||
Line 1: | Line 1: | ||
{{task}} |
{{task}} |
||
Create a routine that given a set of strings representing directory paths and a single character directory separator; return a string representing that part of the directory tree that is common to all the directories. |
|||
Test your routine using the forward slash '/' character as the directory separator and the following three strings as input paths: |
Test your routine using the forward slash '/' character as the directory separator and the following three strings as input paths: |
Revision as of 10:00, 24 March 2010
You are encouraged to solve this task according to the task description, using any language you may know.
Create a routine that given a set of strings representing directory paths and a single character directory separator; return a string representing that part of the directory tree that is common to all the directories.
Test your routine using the forward slash '/' character as the directory separator and the following three strings as input paths:
'/home/user1/tmp/coverage/test' '/home/user1/tmp/covert/operator' '/home/user1/tmp/coven/members'
Note: The resultant path should be the valid directory '/home/user1/tmp'
and not the longest common string '/home/user1/tmp/cove'
.
If your language has a routine that performs this function (even if it does not have a changeable separator character, then mention it as part of the task)
J
Solution: <lang j>parseDirs =: (PATHSEP_j_&= <;.2 ])@jhostpath getCommonPrefix =: ([: *./\ *./@({. ="1 }.)) ;@# {.
getCommonDirPath=: [: getCommonPrefix parseDirs&></lang>
Example: <lang j> paths=: '/home/user1/tmp/coverage/test';'/home/user1/tmp/covert/operator';'/home/user1/tmp/coven/members'
getCommonPrefix >paths
/home/user1/tmp/cove
getCommonDirPath paths
/home/user1/tmp/</lang>
PureBasic
PureBasic don't have a path comparator directly but instead have powerful string tools.
Simply by checking the catalog names until they mismatch and add up the correct parts, the task is accomplished. <lang PureBasic>S1$="/home/user1/tmp/coverage/test" S2$="/home/user1/tmp/covert/operator" S3$="/home/user1/tmp/coven/members" SOut$="" i=1
While (StringField(S1$,i,"/")=StringField(S2$,i,"/")) And (StringField(S1$,i,"/")=StringField(S3$,i,"/"))
SOut$+StringField(S1$,i,"/")+"/" i+1
Wend </lang>
Python
The Python os.path.commonprefix function is broken as it returns common characters that may not form a valid directory path: <lang python>>>> import os >>> os.path.commonprefix(['/home/user1/tmp/coverage/test', '/home/user1/tmp/covert/operator', '/home/user1/tmp/coven/members']) '/home/user1/tmp/cove'</lang>
This result can be fixed: <lang python>>>> def commonprefix(*args, sep='/'): return os.path.commonprefix(*args).rpartition(sep)[0]
>>> commonprefix(['/home/user1/tmp/coverage/test', '/home/user1/tmp/covert/operator', '/home/user1/tmp/coven/members']) '/home/user1/tmp'</lang>
But it may be better to not rely on the faulty implementation at all: <lang python>>>> from itertools import takewhile >>> def allnamesequal(name): return all(n==name[0] for n in name[1:])
>>> def commonprefix(paths, sep='/'): bydirectorylevels = zip(*[p.split(sep) for p in paths]) return sep.join(x[0] for x in takewhile(allnamesequal, bydirectorylevels))
>>> commonprefix(['/home/user1/tmp/coverage/test', '/home/user1/tmp/covert/operator', '/home/user1/tmp/coven/members']) '/home/user1/tmp'</lang>
Tcl
<lang tcl>package require Tcl 8.5 proc pop {varname} {
upvar 1 $varname var set var [lassign $var head] return $head
}
proc common_prefix {dirs {separator "/"}} {
set parts [split [pop dirs] $separator] while {[llength $dirs]} { set r {} foreach cmp $parts elt [split [pop dirs] $separator] { if {$cmp ne $elt} break lappend r $cmp } set parts $r } return [join $parts $separator]
}</lang>
% common_prefix {/home/user1/tmp/coverage/test /home/user1/tmp/covert/operator /home/user1/tmp/coven/members} /home/user1/tmp