Earlier quoted context omitted.
They have references (at least python, lisp that I know of, likely the others as well), which is enough to implement linked lists.
The ability to implement linked lists != pointers and references Behind the scene, yes, every Python variable is a reference to an object. It's not addressable, however, and in the case of immutable objects (like strings), you can't modify the underlying object and keep all references pointed at that updated object.
The Programming Interview from Hell
121–130 of 147 posts
Re: The Programming Interview from Hell
#122Earlier quoted context omitted.
Knowing of data structures is more important IMO. The hoops I've seen people jump through in code because they don't know about sets.
And when you see that do you wish they'd never been hired due to this insurmountable hole in their knowledge of data structures or do you take 30 seconds to tell them about sets?
Re: The Programming Interview from Hell
#123Re: The Programming Interview from Hell
#124Re: The Programming Interview from Hell
#125Re: The Programming Interview from Hell
#126Earlier quoted context omitted.
I think the original intent of the linked list question was to see if the candidate knew pointers. Implementing in a non pointer language would be trivial and definitely not complex.
Are linked lists even a difficult example of pointer use? You don't exactly have to do fancy pointer arithmetic with them. You just have to be a little bit careful when inserting or deleting nodes.
Re: The Programming Interview from Hell
#127The hiring manager of a small software company gave me a quick brief before handing me off to his technical heavy. "He's hard to get along with, but he's really smart. Oh, and he has two PhDs. He'll tell you that." I was ushered in. The Guy with Two PhDs (he showed me his business card first, and there were indeed two PhDs on it) asked me: "What is the simplest way to synchronize two threads?" I rattled off some sync…
Re: The Programming Interview from Hell
#128Here's a hint - I trussed natd while it was running. Ooops.
Re: The Programming Interview from Hell
#129Linked Lists are terrible. They're one of the reasons why early 2000's natd in FreeBSD was terrible. Ask me how I know! Here's a hint - I trussed natd while it was running. Ooops.
Re: The Programming Interview from Hell
#130OK - but here's a genuine problem that came up the other day in my work (reconciling two datasets - we have various many-to-one mappings of ids that we then want to reconcile against each other). I think it's quite a neat computer science/algorithm challenge, so here goes: Write a function which takes as input a list of sets, many of which are not disjoint, but will output a list of sets where all of the non-disjoint…
Input: one file per set, with names of the form set.X. Format of the file is one value per line. E.g., the set (1, 2, 3) might be in file set.0 with contents
1
2
3
Output: each run of the script will merge overlapping set.X files, deleting files that are made redundant. It will tell you how many sets were merged.Run the script repeatedly until it says "merged 0".
#!/bin/bash
for i in set.*
do
sed -e "s/$/ $i/" m.$$
last_val=-1
last_set=
merged=0
while read in
do
set x $in
if [ $2 -eq $last_val ]
then
if [ -f $3 ]
then
cat $last_set $3 | sort -n | uniq > t
mv t $last_set
rm $3
merged=$((merged + 1))
fi
else
last_val=$2
last_set=$3
fi
done
The above does more passes over the complete set of elements than is necessary, in order to minimize memory use. At the cost of a little more memory, it could write the commands done in the while loop (cat|sort|uniq;mv;rm) out to a file, and then edit that file to adjust it to take into account the affect of the rm's, and then do one pass of merging.That would look something like this. First, you'd run this script once:
#!/bin/bash
for i in set.*; do sed -e "s/$/ $i/" m
last_val=-1
last_set=
line=2
> s
while read in
do
set x $in
if [ $2 -eq $last_val ]
then
#echo "if [ -f $3 ]; then cat $last_set $3 | sort -n | uniq > t; mv t $last_set; rm $3; fi"
echo "cat $last_set $3 | sort -n | uniq > t; mv t $last_set; rm $3"
echo "$line,\$s/$3/$last_set/g" >> s
line=$((line + 1))
else
last_val=$2
last_set=$3
fi
done c
That gives an output command file, c, that looks like this: cat set.4 set.7 | sort -n | uniq > t; mv t set.4; rm set.7
cat set.0 set.5 | sort -n | uniq > t; mv t set.0; rm set.5
cat set.1 set.5 | sort -n | uniq > t; mv t set.1; rm set.5
cat set.5 set.7 | sort -n | uniq > t; mv t set.5; rm set.7
cat set.2 set.6 | sort -n | uniq > t; mv t set.2; rm set.6
cat set.3 set.6 | sort -n | uniq > t; mv t set.3; rm set.6
Note the problem with this. Line #1 removes set.7 after merging it with set.4. But line #4 refers to set.7. Since 7 was merged into 4, it needs to refer to set.4 at that point, not set.7.The script that made c also outputs a file, s, with sed commands to do the above fix. For the above example, it looks like this:
2,$s/set.7/set.4/g
3,$s/set.5/set.0/g
4,$s/set.5/set.1/g
5,$s/set.7/set.5/g
6,$s/set.6/set.2/g
7,$s/set.6/set.3/g
There is still a problem, because note that s suffers from the same problem that c does! Line #4 of s also refers to set.7, but at that point it should be set.4.So, before using s to fix s, we have to use s to fix s: "sed -f s s2", giving this for s2:
2,$s/set.7/set.4/g
3,$s/set.5/set.0/g
4,$s/set.0/set.1/g
5,$s/set.4/set.0/g
6,$s/set.6/set.2/g
7,$s/set.2/set.3/g
In this case, that is sufficient. We could now "sed -f s2 c2" and then "bash c2", and we'd be left with set.1 and set.3, with the other sets properly merged in.However, in more complicated cases one application of s to itself is not always enough. What we really should do is keep applying it to itself until we hit a fixed point, so "sed -f s2 s3" giving:
2,$s/set.7/set.4/g
3,$s/set.5/set.0/g
4,$s/set.0/set.1/g
5,$s/set.4/set.1/g
6,$s/set.6/set.2/g
7,$s/set.2/set.3/g
and if you them apply s3 to itself, you will see that there is no change, so s3 is our fixed point. We could then "sed -f s3 c3". Turns out that c3 is identical to c2, so we get the same results as earlier.