Peter’s blog ✴ Week 399 ✴ 9 November 2026
THE WEEKLY CHALLENGE
Longest and longest
You are given a filesystem as a string. Write a script to return the length of the longest absolute path to a file in the abstracted file system. If there is no file in the system, return 0.
dir
- subdir1
- file1.ext
- subsubdir1
- subdir2
- subsubdir2
- file2.ext
This file system can be represented as: "dir\n\tsubdir1\n\t\tfile1.ext\n\t\tsubsubdir1\n\tsubdir2 \n\t\tsubsubdir2\n\t\t\tfile2.ext"
Example 1 Input: $fs = 'dir\n\tsubdir1\n\t\tsubsubdir1\n\tsubdir2' Output: 0 There are no files in the system (a file must contain a . character separating a name and extension). Since there are no files, the answer is 0. Example 2 Input: $fs = 'file1.txt\nfile2.ext\na.png' Output: 9 All entries are located at root depth (0 tabs). Found File Paths: 'file1.txt' (length = 9) 'file2.ext' (length = 9) 'a.png' (length = 5) The longest absolute file path length is 9. Example 3 Input: $fs = 'my documents\n\tproject v1.0\n\t\tnotes v1.txt\n\timage.png' Output: 38 Notice project v1.0 is a directory (it has children beneath it), while notes v1.txt and image.png are files. Found File Paths: 'my documents/project v1.0/notes v1.txt' (length = 38) 'my documents/image.png' (length = 22) The maximum absolute length is 38. Example 4 Input: $fs = 'root\n\ta\n\t\tb\n\t\t\tc.txt\n\td\n\t\te.txt' Output: 14 Found File Paths: 'root/a/b/c.txt' => 4 + 1 + 1 + 1 + 1 + 1 + 5 = 14 'root/d/e.txt' => 4 + 1 + 1 + 1 + 5 = 12 The longest file path is 'root/a/b/c.txt' with length 14. Example 5 Input: $fs = 'a\n\tb\n\t\tc\n\t\t\td\n\t\t\t\te.txt\n\tvery_long_directory_name\ n\t\tf.txt' Output: 32 Found File Paths: 'a/b/c/d/e.txt' => 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 5 = 13 'a/very_long_directory_name/f.txt' => 1 + 1 + 24 + 1 + 5 = 32 The long directory name compensates for depth, giving a max length of 32.
This is not difficult but rather messy. I have assumed that a file can be distinguished from a directory in that a filename contains a '.' and a directory name doesn’t.
So it’s then just a case of analysing the input string using something like
$string = m|¦(\n*)([^\t]*)|g
except that it's easier to replace \t and \n with
single printable characters, for which I used ¦ and §.
The node depth is then length($1) - derived from the number of
tabs - and the node name is $2. If the node is a file - ie its
name includes a '.' -
I caculate its full path length, and I keep track of the longest path.
#!/usr/bin/perl # Blog: http://ccgi.campbellsmiths.force9.co.uk/challenge/399/2 use v5.26; # The Weekly Challenge - 2026-11-09 use utf8; # Week 399 - task 2 - Longest absolute path use warnings; # Peter Campbell Smith binmode STDOUT, ':utf8'; use Encode; longest_absolute_path('dir\n\tsubdir1\n\t\tsubsubdir1\n\tsubdir2'); longest_absolute_path('file1.txt\nfile2.ext\na.png'); longest_absolute_path('my documents\n\tproject v1.0\n\t\t' . 'notes v1.txt\n\timage.png'); longest_absolute_path('root\n\ta\n\t\tb\n\t\t\tc.txt\n\td\n\t\t' . 'e.txt'); longest_absolute_path('a\n\tb\n\t\tc\n\t\t\td\n\t\t\t\te.txt\n\t' . 'very_long_directory_name\n\t\tf.txt'); sub longest_absolute_path { my ($string, $depth, @node, $path, $length, $max_length, $longest, $string2, $line); # initialise $string = '¦' . $_[0]; $max_length = 0; $longest = ''; # loop over lines $string =~ s|\\n|¦|g; $string =~ s|\\t|§|g; while ($string =~ m|¦(§*)([^¦]*)|g) { $depth = length($1); $node[$depth] = $depth == 0 ? $2 : qq[/$2]; # make pretty dir structure $line = (' ¬ ' x $depth) . $node[$depth]; $line =~ s|§| ¬ |g; $string2 .= ' ' . $line . qq[\n]; # get file path and path length $path = ''; $path .= qq[$node[$_]] for 0 .. $depth; if ($node[$depth] =~ m|\.|) { $length = length($path); if ($length > $max_length) { $max_length = $length; $longest = $path; } elsif ($length == $max_length) { $longest .= qq[, $path]; } } } # report $string = $_[0]; $string =~ s|\\|/|g; say qq[\nInput: '$_[0]' - which is:\n$string2]; if ($max_length) { say qq[Output: longest file path = $longest]; say qq[ length = $max_length]; } else { say qq[Output: no files found]; } }
30 lines of code
Input: 'dir\n\tsubdir1\n\t\tsubsubdir1\n\tsubdir2' - which is: dir ¬ /subdir1 ¬ ¬ /subsubdir1 ¬ /subdir2 Output: no files found Input: 'file1.txt\nfile2.ext\na.png' - which is: file1.txt file2.ext a.png Output: longest file path = file1.txt, file2.ext length = 9 Input: 'my documents\n\tproject v1.0\n\t\tnotes v1.txt\n\timage.png' - which is: my documents ¬ /project v1.0 ¬ ¬ /notes v1.txt ¬ /image.png Output: longest file path = my documents/project v1.0/notes v1.txt length = 38 Input: 'root\n\ta\n\t\tb\n\t\t\tc.txt\n\td\n\t\te.txt' - which is: root ¬ /a ¬ ¬ /b ¬ ¬ ¬ /c.txt ¬ /d ¬ ¬ /e.txt Output: longest file path = root/a/b/c.txt length = 14 Input: 'a\n\tb\n\t\tc\n\t\t\td\n\t\t\t\te.txt\n\tvery_long_ directory_name\n\t\tf.txt' - which is: a ¬ /b ¬ ¬ /c ¬ ¬ ¬ /d ¬ ¬ ¬ ¬ /e.txt ¬ /very_long_directory_name ¬ ¬ /f.txt Output: longest file path = a/very_long_directory_name/f.txt length = 32
Any content of this website which has been created by Peter Campbell Smith is in the public domain