public static SingleLL Sum(SingleLL numOne, SingleLL numTwo) { SingleLL result = new SingleLL(); SingleLL.Node currOne = numOne.root; SingleLL.Node currTwo = numTwo.root; bool remainder = false; while (currOne != null || currTwo != null) { // Add digits together, plus remainder if necessary int sum = remainder ? 1 : 0; sum += currOne == null ? 0 : currOne.val; sum += currTwo == null ? 0 : currTwo.val; // Only add ones place, tens place turns into remainder result.AddLast(sum % 10); remainder = sum > 9; currOne = currOne?.next; currTwo = currTwo?.next; } // Has one more digit if a remainder still exists if (remainder) { result.AddLast(1); } return(result); }
// Goes through currNode.next until it reaches end of list. // As it recurses back, it first checks if compareTo and currNode are equal. // Then it increments compareTo. // Since compareTo is by ref, this means compareTo starts at the beginning and moves forward // while currNode is unwinding and effectively starts at the end and moves backward. public static bool IsPalindromeRecurse(ref SingleLL.Node compareTo, SingleLL.Node currNode) { if (currNode == null) { return(true); } if (!IsPalindromeRecurse(ref compareTo, currNode.next) || compareTo.val != currNode.val) { return(false); } compareTo = compareTo.next; return(true); }
// Shorthand for more complex uses of AddTestRun(). protected override void AddTestRun(params object[] args) { int[] valsStart = (int[])args[0]; int[] valsLoop = (int[])args[1]; bool expectedResult = (bool)args[2]; SingleLL listStart = new SingleLL(valsStart); SingleLL listLoop = new SingleLL(valsLoop); SingleLL.Node loopRoot = listLoop.root; listStart.AddLast(listLoop); listLoop.GetLast().next = loopRoot; base.AddTestRun(listStart, expectedResult); }
// Recursively go through and add digits together. // Return true if adding current digits has a remainder. private static bool SumRecurse(SingleLL result, SingleLL.Node currOne, SingleLL.Node currTwo) { if (currOne == null && currTwo == null) { return(false); } // Add digits together, plus remainder if necessary int sum = SumRecurse(result, currOne?.next, currTwo?.next) ? 1 : 0; sum += currOne == null ? 0 : currOne.val; sum += currTwo == null ? 0 : currTwo.val; // Only add ones place, tens place turns into remainder result.AddFirst(sum % 10); return(sum > 9); }
public static void PartitionList(int partVal, SingleLL list) { SingleLL.Node lowLead = null; SingleLL.Node highRoot = null; SingleLL.Node currNode = list.root; while (currNode != null) { // Store for later because the if statement damages currNode.next connection SingleLL.Node nextNode = currNode.next; // High value, add currNode after highRoot if (currNode.val >= partVal) { currNode.next = highRoot; highRoot = currNode; } // Low value, add currNode after lowLead else { if (lowLead == null) { list.root = currNode; } else { lowLead.next = currNode; } lowLead = currNode; } currNode = nextNode; } // Link low and high sublists, or if no low values were found set root to be high sublist's root if (lowLead != null) { lowLead.next = highRoot; } else { list.root = highRoot; } }
// Write description of this particular RunStep(), namely to identify the current runData. protected override void StateTest(SingleLL runData) { // TODO: Hacky hacky hard-coded 10 :( StringBuilder builder = new StringBuilder(); SingleLL.Node currNode = runData.root; for (int i = 0; i < 10; i++) { builder.Append(currNode); if (i < 9) { builder.Append(", "); } currNode = currNode.next; } Console.WriteLine("- Finding if loop exists in: [" + builder + "]"); }
// Use runData to perform desired operation and return the result. protected override SingleLL RunTest(SingleLL runData) { if (runData.GetLength() < 3) { Console.WriteLine(" !!!!! -> List too small to have a middle node"); return(runData); } int stopIndex = runData.GetLength() / 2; SingleLL.Node middleNode = runData.root; for (int i = 0; i < stopIndex; i++) { middleNode = middleNode.next; } RemoveMiddle(middleNode); return(runData); }
public static bool HasLoop(SingleLL list) { /*if (SingleLL.IsNullOrEmpty (list)) * return false;*/ while (!SingleLL.IsNullOrEmpty(list)) { if (Object.ReferenceEquals(list.root, list.root.next)) { return(true); } if (Object.ReferenceEquals(list.root.next, list.root.next.next)) { return(true); } SingleLL.Node rootNext = list.root.next; list.root.next = list.root.next.next; rootNext.next = null; } return(false); }
// True if result matches expectedResult or passes some other verification. protected override bool VerifyResult(PartitionData result, PartitionData expectedResult) { bool foundPart = false; SingleLL.Node currNode = result.list.root; while (currNode != null) { // If first part has just been found then toggle foundPart if (!foundPart && currNode.val >= result.partValue) { foundPart = true; } // If part was already found and any value that should be to the left is found, fail else if (foundPart && currNode.val < result.partValue) { return(false); } currNode = currNode.next; } return(true); }
public static bool IsPalindrome(SingleLL list) { if (list == null) { return(false); } if (list.IsEmpty()) { return(false); } // Find halfway mark // If length is odd, middle value ends up being skipped // Middle value can be anything so this is fine int halfCount = (list.GetLength() + 1) / 2; SingleLL.Node middleNode = list.root; for (int i = 0; i < halfCount; i++) { middleNode = middleNode.next; } return(IsPalindromeRecurse(ref list.root, middleNode)); }
public static void RemoveMiddle(SingleLL.Node theNode) { theNode.val = theNode.next.val; theNode.next = theNode.next.next; }