Ad
  • Custom User Avatar

    First element of the array should be 0; you had -6. So your code is wrong.
    hint: operator precedence.

  • Custom User Avatar

    45762893920 is bigger than Integer.MAX_VALUE and java can't use it as an int. You have to tell java to treat it as a long by adding an L
    45762893920L will work.

  • Custom User Avatar

    This comment is hidden because it contains spoiler information about the solution

  • Custom User Avatar

    It fails since digitize(0L) will return an empty array instead of returning {0}

  • Custom User Avatar

    Thanks for introducing me to the stream methods available, really nice pattern.

  • Custom User Avatar

    Approved by author secretly

  • Custom User Avatar

    This comment is hidden because it contains spoiler information about the solution

  • Custom User Avatar

    I agree that the division introduces a loss of precision, that is the problem when calculating with floating numbers. And that's why it is recommended to compare doubles with an offset.

    Mathematically
    (navg - (sum / newSize)) * newSize and navg * newSize - sum are the same, the later being the simplified version. I unfortunately did not saw at first sight that it could be simplified. That was my mistake.

  • Default User Avatar

    I looked at your solution. I am rather sure that the problem comes from your division (division introduces an added error, error "multiplied" by a multiplication) in your calculation of "newAvg". I re-wrote that line and then your solution passes every time.

  • Custom User Avatar

    "navg = 115053.00000000001" is the input, not the result of the function.

    The random tests are failing randomly with my solution.

    The test randomFailure above which I extracted from the tests is failing everytime with my solution.

    I had to modify the testing method like explained above to make it pass.

  • Default User Avatar

    Thanks for your work! I see that you finally passed the kata. The description says:

    The function new_avg(arr, navg) should return the expected donation (rounded up to the next integer) that will permit to reach the average navg.

    The answer must be an integer so I don't see a reason to use a tolerance.
    To get "navg = 115053.00000000001" I suppose that in a first approach you didn't round up(?).

  • Custom User Avatar

    There is definitely rounding issues in java (and probably other language) (for example if you don't simplify the calculation like my solution, sorry)
    Here is an example of a failing random test that I have extracted through my solution:

    @Test
      void randomFailure() {
        /*navg = 115053.00000000001
    
    org.opentest4j.AssertionFailedError: with input: [12606.000000000002, 12305.7, 58834.600000000006, 193865.1, 187534.6, 124480.40000000001, 198598.40000000002, 35432.100000000006, 122622.50000000001, 102648.70000000001, 171003.80000000002, 109582.00000000001, 42407.200000000004, 206789.00000000003, 62075.200000000004, 34480.600000000006, 47493.600000000006, 165237.6, 65851.5, 21859.2, 128783.6, 151025.6, 64681.100000000006, 186109.00000000003, 157986.40000000002, 193981.7, 53033.200000000004, 162363.30000000002, 112138.40000000001, 190469.40000000002, 36756.5, 158272.40000000002, 97413.8, 36326.4, 73132.40000000001, 171483.40000000002, 151926.5, 134115.30000000002, 187492.80000000002, 3529.9, 8530.5, 13292.400000000001, 189390.30000000002, 191782.80000000002, 86762.5, 30859.4, 35411.200000000004, 104005.00000000001, 138333.80000000002, 151695.5, 146759.80000000002, 34190.200000000004, 112161.50000000001, 20353.300000000003, 187680.90000000002, 45405.8, 114075.50000000001, 71197.5, 185266.40000000002, 123247.3, 91846.70000000001, 120688.70000000001, 163160.80000000002, 153929.6, 118747.20000000001, 83893.70000000001, 69951.20000000001, 63078.40000000001, 198354.2, 98181.6, 28441.600000000002, 25290.100000000002, 89560.90000000001, 159317.40000000002, 174311.5, 180329.6, 133917.30000000002] ==>
    Expected :604004
    Actual   :604003*/
        double[] arr      = new double[] {12606.000000000002, 12305.7, 58834.600000000006, 193865.1, 187534.6, 124480.40000000001, 198598.40000000002, 35432.100000000006, 122622.50000000001, 102648.70000000001, 171003.80000000002, 109582.00000000001, 42407.200000000004, 206789.00000000003, 62075.200000000004, 34480.600000000006, 47493.600000000006, 165237.6, 65851.5, 21859.2, 128783.6, 151025.6, 64681.100000000006, 186109.00000000003, 157986.40000000002, 193981.7, 53033.200000000004, 162363.30000000002, 112138.40000000001, 190469.40000000002, 36756.5, 158272.40000000002, 97413.8, 36326.4, 73132.40000000001, 171483.40000000002, 151926.5, 134115.30000000002, 187492.80000000002, 3529.9, 8530.5, 13292.400000000001, 189390.30000000002, 191782.80000000002, 86762.5, 30859.4, 35411.200000000004, 104005.00000000001, 138333.80000000002, 151695.5, 146759.80000000002, 34190.200000000004, 112161.50000000001, 20353.300000000003, 187680.90000000002, 45405.8, 114075.50000000001, 71197.5, 185266.40000000002, 123247.3, 91846.70000000001, 120688.70000000001, 163160.80000000002, 153929.6, 118747.20000000001, 83893.70000000001, 69951.20000000001, 63078.40000000001, 198354.2, 98181.6, 28441.600000000002, 25290.100000000002, 89560.90000000001, 159317.40000000002, 174311.5, 180329.6, 133917.30000000002};
        double   sum      = Arrays.stream(arr).sum();
        double   theirAvg = (sum + 604004) / (arr.length + 1);
        double   myAvg = (sum + 604003) / (arr.length + 1);
        System.out.println("myAvg = " + myAvg);
        System.out.println("theirAvg = " + theirAvg);
        testing(newAvg(arr, 115053.00000000001), 604004, arr);
      }
    

    and her the output of that test:

    myAvg = 115053.0
    theirAvg = 115053.01282051283
    navg = 115053.00000000001
    

    My suggestion to avoid that is that the testing method should recalculate the average from the input and then doing a comparison with delta if expected and actual are not equal:

    private static void testing(long actual, long expected, double[] input, double navg) {
        if (expected == actual) {
          assertEquals(expected, actual, "with input: " + Arrays.toString(input));
        } else {
          // check for rounding issues
          double sum = Arrays.stream(input).sum();
          double actualAvg   = (sum + actual) / (input.length + 1);
          assertEquals(navg, actualAvg, 1.0E-10, "with input: " + Arrays.toString(input));
        }
      }
    
  • Custom User Avatar

    very good solution, but you could also have used your formatter DTF for the parsing, instead splitting on the PIPE:
    LocalTime.parse(s, DTF).toSecondOfDay

    sorry, I didn't saw that the inputs have randomly 1 or two numbers, so the Formatter can't be used for Parsing; you would need a FORMATTER and a PARSER, where the PARSER will use optional section:

    private static final DateTimeFormatter PARSER = DateTimeFormatter.ofPattern("H[H]|m[m]|s[s]");
    private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("HH|mm|ss");
    
  • Custom User Avatar

    Ok, thanks for your reply.
    It's all clear now.

  • Default User Avatar

    Sorry I didn't understand your post.
    When I wrote: Substrings in the input string are separated by , or ," I didn't mean that in each language there would be the two types of separator; I meant that the types could be one or the other depending on the language. It happens that Kotlin has the first type of separator and Swift has the other type. Anyway with a regex (as yo did) the difference is not a problem. I added that sentence after a post from ByteEater that you can see below.

  • Loading more items...