Cracking the Coding Interview Chapter 2 Solutions in PeopleCode
/* Application Package Name : CTCI_LL_AP */
class ListItem
method ListItem(&data As any);
method linkTo(&item As CTCI_LL_AP:ListItem);
method next() Returns CTCI_LL_AP:ListItem;
method getData() Returns any;
private
instance CTCI_LL_AP:ListItem &nextItem_;
instance any &data_;
end-class;
method ListItem
/+ &data as Any +/
%This.data_ = &data;
end-method;
method linkTo
/+ &item as CTCI_LL_AP:ListItem +/
&item.nextItem_ = %This;
end-method;
method next
/+ Returns CTCI_LL_AP:ListItem +/
Return %This.nextItem_;
end-method;
method getData
/+ Returns Any +/
Return %This.data_
end-method;
import CTCI_LL_AP:*;
class ListItemExt
method ListItemExt(&data As any);
method linkTo(&item As CTCI_LL_AP:ListItemExt);
method next() Returns CTCI_LL_AP:ListItemExt;
method prev() Returns CTCI_LL_AP:ListItemExt;
method remove() Returns CTCI_LL_AP:ListItemExt;
method getData() Returns any;
private
instance CTCI_LL_AP:ListItemExt &nextItem_;
instance CTCI_LL_AP:ListItemExt &prevItem_;
instance any &data_;
end-class;
method ListItemExt
/+ &data as Any +/
%This.data_ = &data;
end-method;
method linkTo
/+ &item as CTCI_LL_AP:ListItemExt +/
REM ** manipulate previous sibling;
&item.nextItem_ = %This;
%This.prevItem_ = &item;
end-method;
method next
/+ Returns CTCI_LL_AP:ListItemExt +/
Return %This.nextItem_;
end-method;
method prev
/+ Returns CTCI_LL_AP:ListItemExt +/
Return %This.prevItem_;
end-method;
method remove
/+ Returns CTCI_LL_AP:ListItemExt +/
%This.nextItem_.linkTo(%This.prevItem_);
REM ** Or manipulate both siblings;
REM %This.prevItem_.nextItem_ = %This.nextItem_;
REM %This.nextItem_.prevItem_ = %This.prevItem_;
Return %This.prevItem_;
end-method;
method getData
/+ Returns Any +/
Return %This.data_;
end-method;
/* Functions represent solutions 1 to 8 in ascending order */
import CTCI_LL_AP:*;
Function removeDups(&head As CTCI_LL_AP:ListItem) Returns CTCI_LL_AP:ListItem
Local CTCI_LL_AP:ListItem &leader;
Local CTCI_LL_AP:ListItem &runner;
Local CTCI_LL_AP:ListItem &prev;
&leader = &head;
While &leader.next() <> Null
&prev = &leader;
&runner = &prev.next();
Repeat
If &leader.getData() = &runner.getData() Then
&runner.next().linkTo(&prev);
End-If;
&prev = &prev.next();
&runner = &prev.next();
Until All(&runner);
&leader = &leader.next();
End-While;
CollectGarbage();
Return &head;
End-Function;
Function k2Last(&head As CTCI_LL_AP:ListItem, &K As number) Returns CTCI_LL_AP:ListItem
Local CTCI_LL_AP:ListItem &runner;
Local number &I = 1;
&runner = &head;
While &runner.next() <> Null
&runner = &runner.next();
&I = &I + 1;
If &I = &K Then
Break;
End-If;
End-While;
Return &runner;
End-Function;
Function removeMiddle(&head As CTCI_LL_AP:ListItem, &c As any)
Local CTCI_LL_AP:ListItem &prev;
Local CTCI_LL_AP:ListItem &runner;
Local CTCI_LL_AP:ListItem &tail;
&prev = &head;
&runner = &prev.next();
&tail = &runner.next();
While All(&tail)
If &runner.getData() = &c Then
&tail.linkTo(&prev);
Break;
End-If;
&prev = &runner;
&runner = &prev.next();
&tail = &runner.next();
End-While;
CollectGarbage();
End-Function;
Function partitionll(&head As CTCI_LL_AP:ListItem, &x As any) Returns CTCI_LL_AP:ListItem
Local CTCI_LL_AP:ListItem &prev;
Local CTCI_LL_AP:ListItem &runner;
Local CTCI_LL_AP:ListItem &tail;
Local array &prevArray, &tailArray;
Local any &hold;
Local number &pI, &tI, &pJ, &tJ;
&runner = &head;
&prevArray = CreateArray();
&tailArray = CreateArray();
&pI = 1;
&tI = 1;
Repeat
&hold = &runner.getData();
If &hold < &x Then
&prevArray [&pI] = create CTCI_LL_AP:ListItem(&hold);
&pI = &pI + 1;
Else
&tailArray [&tI] = create CTCI_LL_AP:ListItem(&hold);
&tI = &tI + 1;
End-If;
&runner = &runner.next();
Until All(&runner);
&pJ = 1;
While &prevArray.Next(&pJ)
&prevArray [&pJ].linkto(&prevArray [&pJ - 1]);
End-While;
&tJ = 1;
While &tailArray.Next(&pJ)
&tailArray [&tJ].linkto(&tailArray [&tJ - 1]);
End-While;
&tailArray [1].linkto(&prevArray [&pJ - 1]);
Return &prevArray [1];
End-Function;
Function sumList(&head As CTCI_LL_AP:ListItem, &order As string) Returns CTCI_LL_AP:ListItem
Local CTCI_LL_AP:ListItem &runner;
Local array &listArray;
Local array of string &n2sArr;
Local number &total, &I, &J, &K, &M, &N, &P, &Q, &temp;
Local array of any &holder;
&runner = &head;
&holder = CreateArray();
&listArray = CreateArray();
&n2sArr = CreateArrayRept("", 0);
Evaluate &order
When "reverse"
&total = &runner.getData();
&I = 10;
While &runner.next() <> Null
&runner = &runner.next();
&total = &total + Product(&runner.getData(), &I);
&I = Product(&I, 10);
End-While;
&n2sArr = Split(NumberToString("*", &total));
&N = 1;
For &M = &n2sArr.Len To 1 Step - 1
&listArray [&N] = create CTCI_LL_AP:ListItem(Value(&n2sArr [&M]));
&N = &N + 1;
End-For;
Break;
When "straight"
&holder [1] = &runner.getData();
While &runner.next() <> Null
&runner = &runner.next();
&holder.Push(&runner.getData());
End-While;
&K = 10;
&total = &holder [&holder.Len];
&temp = &holder.Len - 1;
For &J = &temp To 1 Step - 1
&total = &total + Product(&holder [&J], &K);
&K = Product(&K, 10);
End-For;
&n2sArr = Split(NumberToString("*", &total));
For &P = 1 To &n2sArr.Len Step 1
&listArray [&P] = create CTCI_LL_AP:ListItem(Value(&n2sArr [&P]));
End-For;
Break;
End-Evaluate;
&Q = 1;
While &listArray.Next(&Q)
&listArray [&Q].linkto(&listArray [&Q - 1]);
End-While;
Return &listArray [1];
End-Function;
Function palindromeCheck(&head As CTCI_LL_AP:ListItemExt) Returns boolean
Local CTCI_LL_AP:ListItemExt &start, &end, &runner;
Local number &midpoint, &listLength, &P;
&midpoint = 0;
&listLength = 1;
If &head.next() = Null Then
Return True;
Else
&start = &head;
&runner = &start.next();
While All(&runner)
&listLength = &listLength + 1;
&end = &runner;
&runner = &runner.next();
End-While;
&midpoint = Idiv(&listLength, 2);
For &P = 1 To &midpoint Step 1
If &start.getData() <> &end.getData() Then
Return False;
Else
&start = &start.next();
&end = &end.prev();
End-If;
End-For;
End-If;
Return True;
End-Function;
Function intersectCheck(&head1 As CTCI_LL_AP:ListItem, &head2 As CTCI_LL_AP:ListItem) Returns boolean
Local CTCI_LL_AP:ListItem &runner1, &runner2;
&runner1 = &head1;
&runner2 = &head2;
While All(&runner1)
While All(&runner2)
If &runner1 = &runner2 Then
Return True;
End-If;
&runner2 = &runner2.next();
End-While;
&runner1 = &runner1.next();
End-While;
Return False;
End-Function;
Function circularCheck(&head As CTCI_LL_AP:ListItem) Returns CTCI_LL_AP:ListItem
Local CTCI_LL_AP:ListItem &start, &runner;
&slow = &head;
&fast = &head;
While All(&fast)
&slow = &slow.next();
&fast = &fast.next();
&fast = &fast.next();
if &slow = &fast then
break;
end-if;
End-While;
If None(&fast) Or None(&fast.next()) Then
Return null;
end-if;
&slow = &head;
While &slow <> &fast
&slow = &slow.next();
&fast = &fast.next();
End-While;
Return &slow;
End-Function;
class ListItem
method ListItem(&data As any);
method linkTo(&item As CTCI_LL_AP:ListItem);
method next() Returns CTCI_LL_AP:ListItem;
method getData() Returns any;
private
instance CTCI_LL_AP:ListItem &nextItem_;
instance any &data_;
end-class;
method ListItem
/+ &data as Any +/
%This.data_ = &data;
end-method;
method linkTo
/+ &item as CTCI_LL_AP:ListItem +/
&item.nextItem_ = %This;
end-method;
method next
/+ Returns CTCI_LL_AP:ListItem +/
Return %This.nextItem_;
end-method;
method getData
/+ Returns Any +/
Return %This.data_
end-method;
import CTCI_LL_AP:*;
class ListItemExt
method ListItemExt(&data As any);
method linkTo(&item As CTCI_LL_AP:ListItemExt);
method next() Returns CTCI_LL_AP:ListItemExt;
method prev() Returns CTCI_LL_AP:ListItemExt;
method remove() Returns CTCI_LL_AP:ListItemExt;
method getData() Returns any;
private
instance CTCI_LL_AP:ListItemExt &nextItem_;
instance CTCI_LL_AP:ListItemExt &prevItem_;
instance any &data_;
end-class;
method ListItemExt
/+ &data as Any +/
%This.data_ = &data;
end-method;
method linkTo
/+ &item as CTCI_LL_AP:ListItemExt +/
REM ** manipulate previous sibling;
&item.nextItem_ = %This;
%This.prevItem_ = &item;
end-method;
method next
/+ Returns CTCI_LL_AP:ListItemExt +/
Return %This.nextItem_;
end-method;
method prev
/+ Returns CTCI_LL_AP:ListItemExt +/
Return %This.prevItem_;
end-method;
method remove
/+ Returns CTCI_LL_AP:ListItemExt +/
%This.nextItem_.linkTo(%This.prevItem_);
REM ** Or manipulate both siblings;
REM %This.prevItem_.nextItem_ = %This.nextItem_;
REM %This.nextItem_.prevItem_ = %This.prevItem_;
Return %This.prevItem_;
end-method;
method getData
/+ Returns Any +/
Return %This.data_;
end-method;
/* Functions represent solutions 1 to 8 in ascending order */
import CTCI_LL_AP:*;
Function removeDups(&head As CTCI_LL_AP:ListItem) Returns CTCI_LL_AP:ListItem
Local CTCI_LL_AP:ListItem &leader;
Local CTCI_LL_AP:ListItem &runner;
Local CTCI_LL_AP:ListItem &prev;
&leader = &head;
While &leader.next() <> Null
&prev = &leader;
&runner = &prev.next();
Repeat
If &leader.getData() = &runner.getData() Then
&runner.next().linkTo(&prev);
End-If;
&prev = &prev.next();
&runner = &prev.next();
Until All(&runner);
&leader = &leader.next();
End-While;
CollectGarbage();
Return &head;
End-Function;
Function k2Last(&head As CTCI_LL_AP:ListItem, &K As number) Returns CTCI_LL_AP:ListItem
Local CTCI_LL_AP:ListItem &runner;
Local number &I = 1;
&runner = &head;
While &runner.next() <> Null
&runner = &runner.next();
&I = &I + 1;
If &I = &K Then
Break;
End-If;
End-While;
Return &runner;
End-Function;
Function removeMiddle(&head As CTCI_LL_AP:ListItem, &c As any)
Local CTCI_LL_AP:ListItem &prev;
Local CTCI_LL_AP:ListItem &runner;
Local CTCI_LL_AP:ListItem &tail;
&prev = &head;
&runner = &prev.next();
&tail = &runner.next();
While All(&tail)
If &runner.getData() = &c Then
&tail.linkTo(&prev);
Break;
End-If;
&prev = &runner;
&runner = &prev.next();
&tail = &runner.next();
End-While;
CollectGarbage();
End-Function;
Function partitionll(&head As CTCI_LL_AP:ListItem, &x As any) Returns CTCI_LL_AP:ListItem
Local CTCI_LL_AP:ListItem &prev;
Local CTCI_LL_AP:ListItem &runner;
Local CTCI_LL_AP:ListItem &tail;
Local array &prevArray, &tailArray;
Local any &hold;
Local number &pI, &tI, &pJ, &tJ;
&runner = &head;
&prevArray = CreateArray();
&tailArray = CreateArray();
&pI = 1;
&tI = 1;
Repeat
&hold = &runner.getData();
If &hold < &x Then
&prevArray [&pI] = create CTCI_LL_AP:ListItem(&hold);
&pI = &pI + 1;
Else
&tailArray [&tI] = create CTCI_LL_AP:ListItem(&hold);
&tI = &tI + 1;
End-If;
&runner = &runner.next();
Until All(&runner);
&pJ = 1;
While &prevArray.Next(&pJ)
&prevArray [&pJ].linkto(&prevArray [&pJ - 1]);
End-While;
&tJ = 1;
While &tailArray.Next(&pJ)
&tailArray [&tJ].linkto(&tailArray [&tJ - 1]);
End-While;
&tailArray [1].linkto(&prevArray [&pJ - 1]);
Return &prevArray [1];
End-Function;
Function sumList(&head As CTCI_LL_AP:ListItem, &order As string) Returns CTCI_LL_AP:ListItem
Local CTCI_LL_AP:ListItem &runner;
Local array &listArray;
Local array of string &n2sArr;
Local number &total, &I, &J, &K, &M, &N, &P, &Q, &temp;
Local array of any &holder;
&runner = &head;
&holder = CreateArray();
&listArray = CreateArray();
&n2sArr = CreateArrayRept("", 0);
Evaluate &order
When "reverse"
&total = &runner.getData();
&I = 10;
While &runner.next() <> Null
&runner = &runner.next();
&total = &total + Product(&runner.getData(), &I);
&I = Product(&I, 10);
End-While;
&n2sArr = Split(NumberToString("*", &total));
&N = 1;
For &M = &n2sArr.Len To 1 Step - 1
&listArray [&N] = create CTCI_LL_AP:ListItem(Value(&n2sArr [&M]));
&N = &N + 1;
End-For;
Break;
When "straight"
&holder [1] = &runner.getData();
While &runner.next() <> Null
&runner = &runner.next();
&holder.Push(&runner.getData());
End-While;
&K = 10;
&total = &holder [&holder.Len];
&temp = &holder.Len - 1;
For &J = &temp To 1 Step - 1
&total = &total + Product(&holder [&J], &K);
&K = Product(&K, 10);
End-For;
&n2sArr = Split(NumberToString("*", &total));
For &P = 1 To &n2sArr.Len Step 1
&listArray [&P] = create CTCI_LL_AP:ListItem(Value(&n2sArr [&P]));
End-For;
Break;
End-Evaluate;
&Q = 1;
While &listArray.Next(&Q)
&listArray [&Q].linkto(&listArray [&Q - 1]);
End-While;
Return &listArray [1];
End-Function;
Function palindromeCheck(&head As CTCI_LL_AP:ListItemExt) Returns boolean
Local CTCI_LL_AP:ListItemExt &start, &end, &runner;
Local number &midpoint, &listLength, &P;
&midpoint = 0;
&listLength = 1;
If &head.next() = Null Then
Return True;
Else
&start = &head;
&runner = &start.next();
While All(&runner)
&listLength = &listLength + 1;
&end = &runner;
&runner = &runner.next();
End-While;
&midpoint = Idiv(&listLength, 2);
For &P = 1 To &midpoint Step 1
If &start.getData() <> &end.getData() Then
Return False;
Else
&start = &start.next();
&end = &end.prev();
End-If;
End-For;
End-If;
Return True;
End-Function;
Function intersectCheck(&head1 As CTCI_LL_AP:ListItem, &head2 As CTCI_LL_AP:ListItem) Returns boolean
Local CTCI_LL_AP:ListItem &runner1, &runner2;
&runner1 = &head1;
&runner2 = &head2;
While All(&runner1)
While All(&runner2)
If &runner1 = &runner2 Then
Return True;
End-If;
&runner2 = &runner2.next();
End-While;
&runner1 = &runner1.next();
End-While;
Return False;
End-Function;
Function circularCheck(&head As CTCI_LL_AP:ListItem) Returns CTCI_LL_AP:ListItem
Local CTCI_LL_AP:ListItem &start, &runner;
&slow = &head;
&fast = &head;
While All(&fast)
&slow = &slow.next();
&fast = &fast.next();
&fast = &fast.next();
if &slow = &fast then
break;
end-if;
End-While;
If None(&fast) Or None(&fast.next()) Then
Return null;
end-if;
&slow = &head;
While &slow <> &fast
&slow = &slow.next();
&fast = &fast.next();
End-While;
Return &slow;
End-Function;
Comments
Post a Comment