├── .gitignore ├── README.md ├── build.gradle └── src ├── main └── java │ └── me │ └── rexim │ └── fiveproblems │ ├── Problem1.java │ ├── Problem2.java │ ├── Problem3.java │ ├── Problem4.java │ └── Problem5.java └── test └── java └── me └── rexim └── fiveproblems └── test ├── Problem1Test.java ├── Problem2Test.java ├── Problem3Test.java ├── Problem4Test.java └── Problem5Test.java /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by https://www.gitignore.io 2 | 3 | ### Intellij ### 4 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm 5 | 6 | *.iml 7 | 8 | ## Directory-based project format: 9 | .idea/ 10 | # if you remove the above rule, at least ignore the following: 11 | 12 | # User-specific stuff: 13 | # .idea/workspace.xml 14 | # .idea/tasks.xml 15 | # .idea/dictionaries 16 | 17 | # Sensitive or high-churn files: 18 | # .idea/dataSources.ids 19 | # .idea/dataSources.xml 20 | # .idea/sqlDataSources.xml 21 | # .idea/dynamic.xml 22 | # .idea/uiDesigner.xml 23 | 24 | # Gradle: 25 | # .idea/gradle.xml 26 | # .idea/libraries 27 | 28 | # Mongo Explorer plugin: 29 | # .idea/mongoSettings.xml 30 | 31 | ## File-based project format: 32 | *.ipr 33 | *.iws 34 | 35 | ## Plugin-specific files: 36 | 37 | # IntelliJ 38 | /out/ 39 | 40 | # mpeltonen/sbt-idea plugin 41 | .idea_modules/ 42 | 43 | # JIRA plugin 44 | atlassian-ide-plugin.xml 45 | 46 | # Crashlytics plugin (for Android Studio and IntelliJ) 47 | com_crashlytics_export_strings.xml 48 | crashlytics.properties 49 | crashlytics-build.properties 50 | 51 | 52 | ### Emacs ### 53 | # -*- mode: gitignore; -*- 54 | *~ 55 | \#*\# 56 | /.emacs.desktop 57 | /.emacs.desktop.lock 58 | *.elc 59 | auto-save-list 60 | tramp 61 | .\#* 62 | 63 | # Org-mode 64 | .org-id-locations 65 | *_archive 66 | 67 | # flymake-mode 68 | *_flymake.* 69 | 70 | # eshell files 71 | /eshell/history 72 | /eshell/lastdir 73 | 74 | # elpa packages 75 | /elpa/ 76 | 77 | # reftex files 78 | *.rel 79 | 80 | # AUCTeX auto folder 81 | /auto/ 82 | 83 | # cask packages 84 | .cask/ 85 | 86 | 87 | ### Gradle ### 88 | .gradle 89 | build/ 90 | 91 | # Ignore Gradle GUI config 92 | gradle-app.setting 93 | 94 | # Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) 95 | !gradle-wrapper.jar 96 | 97 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Five Programming Problems # 2 | 3 | Inspired by [Five programming problems every Software Engineer should be able to solve in less than 1 hour](https://blog.svpino.com/2015/05/07/five-programming-problems-every-software-engineer-should-be-able-to-solve-in-less-than-1-hour) 4 | 5 | ## Problems ## 6 | 7 | ### Problem 1 ### 8 | 9 | > Write three functions that compute the sum of the numbers in a given 10 | > list using a for-loop, a while-loop, and recursion. 11 | 12 | ### Problem 2 ### 13 | 14 | > Write a function that combines two lists by alternatingly taking 15 | > elements. For example: given the two lists `[a, b, c]` and 16 | > `[1, 2, 3]`, the function should return `[a, 1, b, 2, c, 3]`. 17 | 18 | ### Problem 3 ### 19 | 20 | > Write a function that computes the list of the first 100 Fibonacci 21 | > numbers. By definition, the first two numbers in the Fibonacci 22 | > sequence are 0 and 1, and each subsequent number is the sum of the 23 | > previous two. As an example, here are the first 10 Fibonnaci 24 | > numbers: 0, 1, 1, 2, 3, 5, 8, 13, 21, and 34. 25 | 26 | ### Problem 4 ### 27 | 28 | > Write a function that given a list of non negative integers, 29 | > arranges them such that they form the largest possible number. For 30 | > example, given [50, 2, 1, 9], the largest formed number is 95021. 31 | 32 | ### Problem 5 ### 33 | 34 | > Write a program that outputs all possibilities to put + or - or 35 | > nothing between the numbers 1, 2, ..., 9 (in this order) such that 36 | > the result is always 100. For example: 1 + 2 + 34 – 5 + 67 – 8 + 9 = 37 | > 100. 38 | 39 | ## Test ## 40 | 41 | $ gradle test 42 | 43 | ## Commentary ## 44 | 45 | Nope, I didn't solve these problems in less then 1 hour. :) Mostly 46 | because I was doing this at the weekend and I had plenty of other 47 | things to do. 48 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'java' 2 | 3 | repositories { 4 | mavenCentral() 5 | } 6 | 7 | dependencies { 8 | compile( 9 | ) 10 | 11 | testCompile( 12 | ['org.testng:testng:6.8.8'], 13 | ) 14 | } 15 | test { 16 | useTestNG(); 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/me/rexim/fiveproblems/Problem1.java: -------------------------------------------------------------------------------- 1 | package me.rexim.fiveproblems; 2 | 3 | public class Problem1 { 4 | public static int sumFor(int[] xs) { 5 | int s = 0; 6 | for (int x : xs) { 7 | s += x; 8 | } 9 | return s; 10 | } 11 | 12 | public static int sumWhile(int[] xs) { 13 | int s = 0; 14 | int i = 0; 15 | while (i < xs.length) { 16 | s += xs[i]; 17 | ++i; 18 | } 19 | return s; 20 | } 21 | 22 | public static int sumRecursion(int[] xs) { 23 | return sumRecursionImpl(xs, 0); 24 | } 25 | 26 | private static int sumRecursionImpl(int[] xs, int i) { 27 | if (i < xs.length) { 28 | return xs[i] + sumRecursionImpl(xs, i + 1); 29 | } else { 30 | return 0; 31 | } 32 | } 33 | 34 | public static int sumRecursionAcc(int[] xs) { 35 | return sumRecursionAccImpl(xs, 0, 0); 36 | } 37 | 38 | private static int sumRecursionAccImpl(int[] xs, int i, int acc) { 39 | if (i < xs.length) { 40 | return sumRecursionAccImpl(xs, i + 1, xs[i] + acc); 41 | } else { 42 | return acc; 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/me/rexim/fiveproblems/Problem2.java: -------------------------------------------------------------------------------- 1 | package me.rexim.fiveproblems; 2 | 3 | public class Problem2 { 4 | public static String[] interleave(String[] xs, String[] ys) { 5 | String[] zs = new String[xs.length + ys.length]; 6 | int j = 0; 7 | int size = Math.max(xs.length, ys.length); 8 | 9 | for (int i = 0; i < size; ++i) { 10 | if (i < xs.length) { 11 | zs[j++] = xs[i]; 12 | } 13 | if (i < ys.length) { 14 | zs[j++] = ys[i]; 15 | } 16 | } 17 | 18 | return zs; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/me/rexim/fiveproblems/Problem3.java: -------------------------------------------------------------------------------- 1 | package me.rexim.fiveproblems; 2 | 3 | public class Problem3 { 4 | public static int[] generateFirst100FibonacciNumbers() { 5 | int[] xs = new int[100]; 6 | xs[0] = 0; 7 | xs[1] = 1; 8 | 9 | for (int i = 2; i < 100; ++i) { 10 | xs[i] = xs[i - 1] + xs[i - 2]; 11 | } 12 | 13 | return xs; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/me/rexim/fiveproblems/Problem4.java: -------------------------------------------------------------------------------- 1 | package me.rexim.fiveproblems; 2 | 3 | import java.util.Arrays; 4 | import java.util.Comparator; 5 | 6 | public class Problem4 { 7 | public static int formLargestNumber(int[] xs) { 8 | String[] ys = new String[xs.length]; 9 | 10 | for (int i = 0; i < ys.length; ++i) { 11 | ys[i] = Integer.toString(xs[i]); 12 | } 13 | 14 | Arrays.sort(ys, new Comparator() { 15 | @Override 16 | public int compare(String s1, String s2) { 17 | return s2.compareTo(s1); 18 | } 19 | }); 20 | 21 | int s = 0; 22 | 23 | for (String y : ys) { 24 | for (int i = 0; i < y.length(); ++i) { 25 | s = y.charAt(i) - '0' + s * 10; 26 | } 27 | } 28 | 29 | return s; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/me/rexim/fiveproblems/Problem5.java: -------------------------------------------------------------------------------- 1 | package me.rexim.fiveproblems; 2 | 3 | import java.util.ArrayList; 4 | import static java.lang.Math.*; 5 | 6 | public class Problem5 { 7 | public static String[] possibleExpressions() { 8 | ArrayList result = new ArrayList<>(); 9 | possibleExpressionsImpl(2, 1, 1, "1", result); 10 | return result.toArray(new String[result.size()]); 11 | } 12 | 13 | private static void possibleExpressionsImpl(int i, int sum, int f, String expr, ArrayList acc) { 14 | if (i > 9) { 15 | if (sum == 100) { 16 | acc.add(expr); 17 | } 18 | return; 19 | } 20 | 21 | possibleExpressionsImpl(i + 1, sum + i, i, expr + " + " + i, acc); 22 | possibleExpressionsImpl(i + 1, sum - i, -i, expr + " - " + i, acc); 23 | possibleExpressionsImpl(i + 1, sum + f * 9 + i * dir(f), f * 10 + i * dir(f), expr + i, acc); 24 | } 25 | 26 | private static int dir(int x) { 27 | return x / abs(x); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/test/java/me/rexim/fiveproblems/test/Problem1Test.java: -------------------------------------------------------------------------------- 1 | package me.rexim.fiveproblems.test; 2 | 3 | import me.rexim.fiveproblems.Problem1; 4 | import org.testng.annotations.*; 5 | import static org.testng.AssertJUnit.*; 6 | 7 | public class Problem1Test { 8 | @Test 9 | public void testSumFor() throws Exception { 10 | int[] xs = {1, 2, 3, 4, 5}; 11 | assertEquals(15, Problem1.sumFor(xs)); 12 | } 13 | 14 | @Test 15 | public void testSumWhile() throws Exception { 16 | int[] xs = {1, 2, 3, 4, 5}; 17 | assertEquals(15, Problem1.sumWhile(xs)); 18 | } 19 | 20 | @Test 21 | public void testSumRecursion() throws Exception { 22 | int[] xs = {1, 2, 3, 4, 5}; 23 | assertEquals(15, Problem1.sumRecursion(xs)); 24 | } 25 | 26 | @Test 27 | public void testSumRecursionAcc() throws Exception { 28 | int[] xs = {1, 2, 3, 4, 5}; 29 | assertEquals(15, Problem1.sumRecursionAcc(xs)); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/test/java/me/rexim/fiveproblems/test/Problem2Test.java: -------------------------------------------------------------------------------- 1 | package me.rexim.fiveproblems.test; 2 | 3 | import org.testng.annotations.*; 4 | import static org.testng.AssertJUnit.*; 5 | import me.rexim.fiveproblems.Problem2; 6 | 7 | public class Problem2Test { 8 | @Test 9 | public void testInterleaveSameSize() throws Exception { 10 | String[] xs = { 11 | "a", "b", "c" 12 | }; 13 | 14 | String[] ys = { 15 | "1", "2", "3" 16 | }; 17 | 18 | String[] zs = { 19 | "a", "1", "b", "2", "c", "3" 20 | }; 21 | 22 | assertArrayEquals(zs, Problem2.interleave(xs, ys)); 23 | } 24 | 25 | @Test 26 | public void testInterleaveDifferentSize() throws Exception { 27 | String[] xs = { 28 | "a", "b", "c" 29 | }; 30 | 31 | String[] ys = { 32 | "1", "2", "3", "4" 33 | }; 34 | 35 | String[] zs = { 36 | "a", "1", "b", "2", "c", "3", "4" 37 | }; 38 | 39 | assertArrayEquals(zs, Problem2.interleave(xs, ys)); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/test/java/me/rexim/fiveproblems/test/Problem3Test.java: -------------------------------------------------------------------------------- 1 | package me.rexim.fiveproblems.test; 2 | 3 | import me.rexim.fiveproblems.Problem3; 4 | import org.testng.annotations.*; 5 | import static org.testng.AssertJUnit.*; 6 | 7 | public class Problem3Test { 8 | @Test 9 | public void testGenerateFirst100FibonacciNumbers() throws Exception { 10 | int[] fibonacci100 = Problem3.generateFirst100FibonacciNumbers(); 11 | assertNotNull(fibonacci100); 12 | assertEquals(100, fibonacci100.length); 13 | assertEquals(0, fibonacci100[0]); 14 | assertEquals(1, fibonacci100[1]); 15 | 16 | for (int i = 2; i < 100; ++i) { 17 | assertTrue(fibonacci100[i] == fibonacci100[i - 1] + fibonacci100[i - 2]); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/test/java/me/rexim/fiveproblems/test/Problem4Test.java: -------------------------------------------------------------------------------- 1 | package me.rexim.fiveproblems.test; 2 | 3 | import me.rexim.fiveproblems.Problem4; 4 | import org.testng.annotations.*; 5 | import static org.testng.AssertJUnit.*; 6 | 7 | public class Problem4Test { 8 | @Test 9 | public void testFormLargestNumber() throws Exception { 10 | assertEquals(95021, Problem4.formLargestNumber(new int[] {50, 2, 1, 9})); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/test/java/me/rexim/fiveproblems/test/Problem5Test.java: -------------------------------------------------------------------------------- 1 | package me.rexim.fiveproblems.test; 2 | 3 | import me.rexim.fiveproblems.Problem5; 4 | import org.testng.annotations.*; 5 | import static org.testng.Assert.*; 6 | 7 | public class Problem5Test { 8 | @Test 9 | public void testPossibleExpressions() throws Exception { 10 | String[] expectedExpressions = new String[] { 11 | "1 + 2 + 3 - 4 + 5 + 6 + 78 + 9", 12 | "1 + 2 + 34 - 5 + 67 - 8 + 9", 13 | "1 + 23 - 4 + 5 + 6 + 78 - 9", 14 | "1 + 23 - 4 + 56 + 7 + 8 + 9", 15 | "12 + 3 + 4 + 5 - 6 - 7 + 89", 16 | "12 + 3 - 4 + 5 + 67 + 8 + 9", 17 | "12 - 3 - 4 + 5 - 6 + 7 + 89", 18 | "123 + 4 - 5 + 67 - 89", 19 | "123 + 45 - 67 + 8 - 9", 20 | "123 - 4 - 5 - 6 - 7 + 8 - 9", 21 | "123 - 45 - 67 + 89" 22 | }; 23 | 24 | String[] actualExpressions = Problem5.possibleExpressions(); 25 | 26 | // for (String expression : actualExpressions) { 27 | // System.out.println(expression); 28 | // } 29 | 30 | assertEqualsNoOrder(actualExpressions, expectedExpressions); 31 | } 32 | } 33 | --------------------------------------------------------------------------------