|
Thread Rules 1. This is not a "do my homework for me" thread. If you have specific questions, ask, but don't post an assignment or homework problem and expect an exact solution. 2. No recruiting for your cockamamie projects (you won't replace facebook with 3 dudes you found on the internet and $20) 3. If you can't articulate why a language is bad, don't start slinging shit about it. Just remember that nothing is worse than making CSS IE6 compatible. 4. Use [code] tags to format code blocks. |
On October 25 2016 23:44 Manit0u wrote:Show nested quote +On October 25 2016 23:40 Hhanh00 wrote:On October 25 2016 23:26 Manit0u wrote:On October 25 2016 22:59 Acrofales wrote: Lol. Travis, were you expecting this? :D Hehe. I guess that no one could've predicted that  Also, I've learned today that JVM has full support for dynamic typing, TCO and other funky shit - just not for Java  JVM has no support for TCO. In Scala, TRE is done by the compiler but does not cover mutual recursion. That's why there are trampolines in scalaz. But from what I've read most of the recursion in scala is translated into loops anyway. Only a subset of all recursive functions can be translated into loops. If Scala is good at this translation, it will convert a large portion of that subset, but sometimes it's straight up impossible.
|
You need to annotate your function as @tailrec and the compiler will do TRE if possible. If not, it produces a compilation error. Essentially, TRE turns the recursion into a loop (i.e. a goto).
|
On October 25 2016 23:27 travis wrote: lol no this is great, love the participation.
I'll post the "hard" exercise that was included since you guys seem to enjoy this. I haven't tried it yet, I might this weekend but now I have to study for my calc 2 exam until friday.
Hard exercise:
Your method parameter is an array of ints. The method is a boolean. The goal is to look at the ints and see if you could possibly return 2 arrays from it, both having the same "total" within it.
For example if you were passed {2, 2} it would be true. {2, 3, 2, 3} would be true. {2, 3} would be false. {5, 2, 3} would be true. {5, 2, 4} would be false. {2, 6, 2, 2} would be true. Etc. Have fun!
Oh and it's supposed to use recursion, so no loops. You can make a recursive helper method, though.
You mean something like that?
public static void main (String[] args) { import java.util.Arrays;
int[] testArr = {5, 2, 3}; int[] testArr2 = {5, 1, 4}; int[] testArr3 = {5, 1, 2}; String t1 = Arrays.toString(testArr); String t2 = Arrays.toString(testArr2); String t3 = Arrays.toString(testArr3);
System.out.println("Can" + (canSplit(testArr, new int[testArr.length], 0) ? " " : "'t ") + "split " + t1 ); System.out.println("Can" + (canSplit(testArr2, new int[testArr2.length], 0) ? " " : "'t ") + "split " + t2 ); System.out.println("Can" + (canSplit(testArr3, new int[testArr3.length], 0) ? " " : "'t ") + "split " + t3 ); }
public static int arraySum(int[] arr, int idx, int sum) { if (idx == arr.length) { return sum; }
return arraySum(arr, idx + 1, sum + arr[idx]); } public static Boolean arrayCompare(int[] a, int[] b) { return arraySum(a, 0, 0) == arraySum(b, 0, 0); } public static Boolean canSplit(int[] a, int[] b, int idx) { if (idx == 0 && arraySum(a, 0, 0) % 2 != 0) { return false; }
if (idx == a.length) { return false; }
if (arrayCompare(a, b)) { return true; }
b[idx] = a[idx]; a[idx] = 0; return canSplit(a, b, idx + 1); }
Sorry if the code is a bit crap. I've had to google how to write HelloWorld in Java today 
Edit: I guess that my solution is wrong, but I don't have any more heart to deal with Java bullshit today  I know you have to add highest and lowest and compare them with the rest etc. but I've no brain left for that.
|
On October 26 2016 00:22 Manit0u wrote:Show nested quote +On October 25 2016 23:27 travis wrote: lol no this is great, love the participation.
I'll post the "hard" exercise that was included since you guys seem to enjoy this. I haven't tried it yet, I might this weekend but now I have to study for my calc 2 exam until friday.
Hard exercise:
Your method parameter is an array of ints. The method is a boolean. The goal is to look at the ints and see if you could possibly return 2 arrays from it, both having the same "total" within it.
For example if you were passed {2, 2} it would be true. {2, 3, 2, 3} would be true. {2, 3} would be false. {5, 2, 3} would be true. {5, 2, 4} would be false. {2, 6, 2, 2} would be true. Etc. Have fun!
Oh and it's supposed to use recursion, so no loops. You can make a recursive helper method, though.
You mean something like that? public static void main (String[] args) { import java.util.Arrays;
int[] testArr = {5, 2, 3}; int[] testArr2 = {5, 1, 4}; int[] testArr3 = {5, 1, 2}; String t1 = Arrays.toString(testArr); String t2 = Arrays.toString(testArr2); String t3 = Arrays.toString(testArr3); System.out.println("Can" + (canSplit(testArr, new int[testArr.length], 0) ? " " : "'t ") + "split " + t1 ); System.out.println("Can" + (canSplit(testArr2, new int[testArr2.length], 0) ? " " : "'t ") + "split " + t2 ); System.out.println("Can" + (canSplit(testArr3, new int[testArr3.length], 0) ? " " : "'t ") + "split " + t3 ); } public static int arraySum(int[] arr, int idx, int sum) { if (idx == arr.length) { return sum; } return arraySum(arr, idx + 1, sum + arr[idx]); } public static Boolean arrayCompare(int[] a, int[] b) { return arraySum(a, 0, 0) == arraySum(b, 0, 0); } public static Boolean canSplit(int[] a, int[] b, int idx) { if (idx == a.length) { return false; } if (arrayCompare(a, b)) { return true; } b[idx] = a[idx]; a[idx] = 0; return canSplit(a, b, idx + 1); }
Sorry if the code is a bit crap. I've had to google how to write HelloWorld in Java today  Don't think this works. It wouldn't work on his test array [2, 6, 2, 2], which is supposed to return true. Simply splitting the array was my first thought too, but you have to go through all permutations.
Anyway, the first thing I'd do is simply sum the initial array. If it's odd, it's impossible. After that, some type of dynamic programming is needed. It's been a while since I had to do assignments like this, but I will play with it. It's pretty easy to find a terrible solution, but my gut says it should be easy to find one in O(n^2) or so.
|
|
Yeah, but that is the trivial solution in O(2^n) time, or am I missing something?
|
On October 25 2016 23:27 travis wrote: lol no this is great, love the participation.
I'll post the "hard" exercise that was included since you guys seem to enjoy this. I haven't tried it yet, I might this weekend but now I have to study for my calc 2 exam until friday.
Hard exercise:
Your method parameter is an array of ints. The method is a boolean. The goal is to look at the ints and see if you could possibly return 2 arrays from it, both having the same "total" within it.
For example if you were passed {2, 2} it would be true. {2, 3, 2, 3} would be true. {2, 3} would be false. {5, 2, 3} would be true. {5, 2, 4} would be false. {2, 6, 2, 2} would be true. Etc. Have fun!
Oh and it's supposed to use recursion, so no loops. You can make a recursive helper method, though.
Wooo exponential time! Also I'm stealing arraySum from Manitou since I don't want to write it:
public static bool subsetMatch(int[] arr) { if (arr.length < 2) { return false; } ArrayList<int> subset1 = new ArrayList<int>(); ArrayList<int> subset2 = new ArrayList<int>(); return subsetMatchHelper(arr, 0, subset1, subset2); }
public static bool subsetMatchHelper(int[] arr, index, ArrayList<int> subset1, ArrayList<int> subset2) { if (arr.length == index) { return arraySum(subset1, 0, 0) == arraySum(subset2, 0, 0); } else { return (subsetMatchHelper(arr, index + 1, subset1.add(arr[index]), subset2) || subsetMatchHelper(arr, index + 1, subset1, subset2.add(arr[index])); } }
I'm pretty confident that this is actually incorrect, since my subsets' .add calls will be modifying themselves, which will muck up the other call. But this is the logic that you want.
On another note, the problem as stated is actually ambiguous, we just make an assumption about it. It isn't clear whether or not the two subsets must union to the whole set, or if you can ignore numbers.
EDIT: Acrofales, I'm pretty sure that if you're using recursion, the only solution is the 2^n solution. I haven't thought about whether you can use DP to make this polynomial, though it is suspiciously similar to the NP-hard subset sum problem, so I'm not 100% sure you can.
|
On October 26 2016 00:40 Nesserev wrote:This is quite trivial in Haskell via backtracking. + Show Spoiler [old solution] +f :: [Int] -> Bool f [] = True -- is this the intended behavior? f xs = f_internal xs [] []
f_internal :: [Int] -> [Int] -> [Int] -> Bool f_internal [] ys zs = sum ys == sum zs f_internal (x:xs) ys zs = f_internal xs (x:ys) zs || f_internal xs ys (x:zs)
+ Show Spoiler [unit tests] + import Test.HUnit
testFinternal = TestCase (do -- base case assertBool "" (f_internal [] [] [] assertBool "" (f_internal [] [4] [2,2] assertBool "" (not $ f_internal [] [1] [] assertBool "" (not $ f_internal [] [2,7] [3,2,1] -- success assertBool "" (f_internal [1] [3] [4] assertBool "" (f_internal [1] [4] [3] -- fail assertBool "" (not $ f_internal [1] [] [] assertBool "" (not $ f_internal [2] [5,3] [8,1] )
testF = TestCase (do assertBool "example1" (f [2,2] assertBool "example2" (f [2,3,2,3] assertBool "example3" (not $ f [2,3] assertBool "example4" (f [5,2,3] assertBool "example5" (not $ f [5,2,4] assertBool "example6" (f [2,6,2,2] )
------------------------------------------------------------------------------
tests = TestList [ TestLabel "testFinternal" testFinternal, TestLabel "testF" testF ]
------------------------------------------------------------------------------
main :: IO Counts main = runTestTT $ tests
EDIT: Better solution: f :: [Int] -> Bool f xs = f_internal xs 0 0
f_internal :: [Int] -> Int -> Int -> Bool f_internal [] y z = y == z f_internal (x:xs) y z = f_internal xs (x+y) z || f_internal xs y (x+z)
It's not hard to translate that into Java. Nothing really changes, you just add a bit of syntax overhead.
The second version is a lot better since it should reduce the runtime complexity by a factor of n (runtime complexity for recursion is hard on my brain). Might not matter too much in the presence of exponential complexity though.
For me this also seems awfully similar to the knapsack problem, which is NP-complete.
|
Can we have a warning that pops up when I accidentally quote instead of edit the last post in the thread?
|
|
Ah, that was it! I knew I had seen this problem before.
|
Aha! And now the real fun starts. I didn't spend enough time thinking about it, but Wikipedia says there is a DP solution in pseudo-polynomial time (my knowledge of complexity theory doesn't reach far enough to know what that means, but I'll assume it's something like polynomial for most cases, but there are corner cases where it fails?)
Anyway. More interesting than finding the obvious solution, let's find the DP solution without peeking at the reset if the Wikipedia article or the rest of the internet!
|
On October 26 2016 00:40 Nesserev wrote:This is quite trivial in Haskell via backtracking. + Show Spoiler [old solution] +f :: [Int] -> Bool f [] = True -- is this the intended behavior? f xs = f_internal xs [] []
f_internal :: [Int] -> [Int] -> [Int] -> Bool f_internal [] ys zs = sum ys == sum zs f_internal (x:xs) ys zs = f_internal xs (x:ys) zs || f_internal xs ys (x:zs)
+ Show Spoiler [unit tests] + import Test.HUnit
testFinternal = TestCase (do -- base case assertBool "" (f_internal [] [] [] assertBool "" (f_internal [] [4] [2,2] assertBool "" (not $ f_internal [] [1] [] assertBool "" (not $ f_internal [] [2,7] [3,2,1] -- success assertBool "" (f_internal [1] [3] [4] assertBool "" (f_internal [1] [4] [3] -- fail assertBool "" (not $ f_internal [1] [] [] assertBool "" (not $ f_internal [2] [5,3] [8,1] )
testF = TestCase (do assertBool "example1" (f [2,2] assertBool "example2" (f [2,3,2,3] assertBool "example3" (not $ f [2,3] assertBool "example4" (f [5,2,3] assertBool "example5" (not $ f [5,2,4] assertBool "example6" (f [2,6,2,2] )
------------------------------------------------------------------------------
tests = TestList [ TestLabel "testFinternal" testFinternal, TestLabel "testF" testF ]
------------------------------------------------------------------------------
main :: IO Counts main = runTestTT $ tests
EDIT: Better solution: f :: [Int] -> Bool f xs = f_internal xs 0 0
f_internal :: [Int] -> Int -> Int -> Bool f_internal [] y z = y == z f_internal (x:xs) y z = f_internal xs (x+y) z || f_internal xs y (x+z)
Thought I'd just add a Haskell solution to the previous problem since Nesserev already solved the above one so nicely.
star :: String -> String star "" = "" star (x:"") = (x:"") star (x:y:rest) | x == y = x:'*':star (y:rest) | otherwise = x:star (y:rest)
|
On October 26 2016 04:23 Acrofales wrote:Aha! And now the real fun starts. I didn't spend enough time thinking about it, but Wikipedia says there is a DP solution in pseudo-polynomial time (my knowledge of complexity theory doesn't reach far enough to know what that means, but I'll assume it's something like polynomial for most cases, but there are corner cases where it fails?) Anyway. More interesting than finding the obvious solution, let's find the DP solution without peeking at the reset if the Wikipedia article or the rest of the internet! Pseudo-polynomial is more that the algorithm appears to have polynomial running time based on the numeric value of the input, but actually has exponential running time based on the size of the input (i.e. how many bits it's represented by, though the particular base doesn't matter).
For example, consider primality testing by trial division for a number n. To check if n is prime, you will attempt to divide it by everything in the range [2, sqrt(n)]. In the numeric value of n, this looks polynomial, because we're doing sqrt(n) divisions, but in the actual input size, the number of bits to represent n, the amount of work is exponential.
I'm on my phone, so I can't get too detailed, but I hope this helps explain.
|
On October 26 2016 05:19 Mr. Wiggles wrote:Show nested quote +On October 26 2016 04:23 Acrofales wrote:Aha! And now the real fun starts. I didn't spend enough time thinking about it, but Wikipedia says there is a DP solution in pseudo-polynomial time (my knowledge of complexity theory doesn't reach far enough to know what that means, but I'll assume it's something like polynomial for most cases, but there are corner cases where it fails?) Anyway. More interesting than finding the obvious solution, let's find the DP solution without peeking at the reset if the Wikipedia article or the rest of the internet! Pseudo-polynomial is more that the algorithm appears to have polynomial running time based on the numeric value of the input, but actually has exponential running time based on the size of the input (i.e. how many bits it's represented by, though the particular base doesn't matter). For example, consider primality testing by trial division for a number n. To check if n is prime, you will attempt to divide it by everything in the range [2, sqrt(n)]. In the numeric value of n, this looks polynomial, because we're doing sqrt(n) divisions, but in the actual input size, the number of bits to represent n, the amount of work is exponential. I'm on my phone, so I can't get too detailed, but I hope this helps explain.
As an additional note to the prime-checking pseudopolynomial example, consider what happens when you multiply a given input by 4. Your algorithm now needs to do twice as many checks, but the size of the input has only gone up by two bits (assuming base 2). When the work of the algorithm grows multiplicatively for a constant addition of input size, that's exponential.
If that doesn't help, ignore it, it just helps me to understand why pseudopolynomial solutions look like they're polynomial but are actually exponential. If it depends on the value of a variable itself, and not the number of values, then you're likely in trouble (without a log to cancel it out).
|
|
|
On October 28 2016 02:44 Nesserev wrote:ftfy, efficiency matters
premature optimization is the root of all evil. :D
|
C# solution (so probably works in Java with minimal changes I suppose) also O(n^2) obv
bool HasTwoSubArraysWithSameTotal(int[] values){ return HasTwoSubArraysWithSameTotal(values, 0, 0, 0); }
bool HasTwoSubArraysWithSameTotal(int[] values, int sumA, int sumB, int index){ return values.Length == index ? sumA == sumB : HasTwoSubArraysWithSameTotal(values, sumA + values[index], sumB, index + 1) || HasTwoSubArraysWithSameTotal(values, sumA, sumB + values[index], index + 1); }
|
Anyone around good at java that can help me for a little bit? (maybe half hour or hour or something?)
edit: nevermind I finally got everything working. wow what a pain lol
|
|
|
|