9
\$\begingroup\$

Introduction:

In Dutch, the words leading and suffering, being 'leiden' and 'lijden' respectively, are pronounced the same way. One is written with a "short ei", and one with a "long ij", as we Dutchman would say, but both 'ei' and 'ij' are pronounced [ɛi].

Challenge:

Given a list of numbers, determine which (if any) are leading, and which (if any) are suffering.

A leading number is:

  • A positive number
  • Has at least four digits
  • Is in the highest 50% of the list in terms of value
  • Is still in the highest 50% of the list in terms of value, if it's 3rd digit is replaced with its 2nd digit, and it's 2nd digit-position is filled with a 0 (i.e. 1234 would become 1024)

A suffering number is:

  • A negative number
  • Has at least four digits
  • Is in the lowest 50% of the list in terms of value
  • Is still in the lowest 50% of the list in terms of value, if it's 3rd digit is replaced with its 2nd digit, and it's 2nd digit-position is filled with a 0 (i.e. -4321 would become -4031)

Example:

Input: [5827, 281993, 3918, 3854, -32781, -2739, 37819, 0, 37298, -389]
Output: leading: [5827, 281993, 37819, 37298]; suffering: [-32781, -2739]

Explanation:

If we sort and split the numbers into two halves, it would be:

[[-32781, -2739, -389, 0, 3798], [3854, 3918, 5827, 37819, 281993]]

There are only two negative numbers with at least four digits: [-32781, -2739]. Changing the digits as described above wouldn't change their position, so they are both suffering numbers.
For the largest halve, all the numbers have at least four digits: [3854, 3918, 5827, 37819, 281993]. Changing the digits as described above would change some of their positions however. The 3854 would become 3084, putting it below 3798 which is in the lowest 50%, so 3854 is not a leading number in this list. The same applies to 3918 which would become 3098, also putting it below 3798. The other three numbers are leading, as 5827 which would become 5087, which is still above 3798 and is in fact still at the same index of the sorted list. So [5827, 37819, 281993] are the leading numbers.

Challenge rules:

  • I/O is flexible. Input-list can be a list of integers, 2D digit lists, list of strings, etc. Output can be a list of lists of integers, two separated lists, two strings, both printed to STDOUT, etc.
  • When determining if a number is leading/suffering, we only look at its new position of that number if only its digits are changed accordingly, not after we've applied the modifications to all numbers.
  • We output the original numbers, not the modified ones.
  • The numbers in the leading and suffering output-lists can be in any order.
  • If the size of the input-list is odd, the number at the center doesn't belong to either halve.
  • Numbers are guaranteed to remain unique after its modification. So a list like [0, 1, 1045, 1485] isn't a valid input-list, since 1485 would be equal to 1045 after it's modification.

General rules:

  • This is , so shortest answer in bytes wins.
    Don't let code-golf languages discourage you from posting answers with non-codegolfing languages. Try to come up with an as short as possible answer for 'any' programming language.
  • Standard rules apply for your answer with default I/O rules, so you are allowed to use STDIN/STDOUT, functions/method with the proper parameters and return-type, full programs. Your call.
  • Default Loopholes are forbidden.
  • If possible, please add a link with a test for your code (i.e. TIO).
  • Also, adding an explanation for your answer is highly recommended.

Test cases:

Input: [5827, 281993, 3918, 3854, -32781, -2739, 37819, 0, 37298, -389]
Output: leading: [5827, 281993, 37819, 37298]; suffering: [-32781, -2739]

Input: [-100, 472, 413, -1782]
Output: leading: []; suffering: [-1782]

Input: [-1234, -1235, -1236, 1234, 1235, 1236]
Output: leading: [1234, 1235, 1236]; suffering: [-1234, -1235, -1236]

Input: [-1919, -1819, -1719, -1619, -1500, -1444, 40, 4444, 18]
Output: leading: [4444]; suffering: []

Input: [-1004, -1111, -1000]
Output: leading: []; suffering: [-1111]

Input: [-1004, -1111, -1010, 1000]
Output: leading: [1000]; suffering: [-1111]

Input: [1000, -1000]
Output: leading: [1000]; suffering: [-1000]

Input: [1000, -5000, 4000]
Output: leading: [4000]; suffering: [-5000]
\$\endgroup\$
3
  • \$\begingroup\$ Judging from the test cases, it seems you mean for the 50% to round down when the list's length is odd. You might want to specify that explicitly. \$\endgroup\$
    – Grimmy
    Commented May 27, 2019 at 13:07
  • \$\begingroup\$ Suggested test case: [1000, -1000] \$\endgroup\$
    – Grimmy
    Commented May 27, 2019 at 13:16
  • \$\begingroup\$ @Grimy As for your first comment, the rule "If the size of the input-list is odd, the number at the center doesn't belong to either halve" should cover that, right? And added the suggested test case. \$\endgroup\$ Commented May 27, 2019 at 13:21

4 Answers 4

6
\$\begingroup\$

05AB1E, 27 24 23 22 21 bytes

(‚εÅmyεD1è0šāǝ}‹y*₄@Ï

Try it online!

\$\endgroup\$
5
  • 1
    \$\begingroup\$ 22 bytes based on your current 23-byter \$\endgroup\$ Commented May 27, 2019 at 13:53
  • \$\begingroup\$ @KevinCruijssen I just edited my answer to another 22 I found independently. Now to see if we can combine those optimizations for a 21... \$\endgroup\$
    – Grimmy
    Commented May 27, 2019 at 14:03
  • 1
    \$\begingroup\$ Probably not. I used the © and ®Åm instead of your ÅmUy and X to save a byte, but you now removed the UX as well by doing the Åm ... ‹y after the map, so it's a similar optimization. I actually like yours better, since it doesn't use any unnecessary variables in that case. :) \$\endgroup\$ Commented May 27, 2019 at 14:07
  • \$\begingroup\$ Dang, very nice find with 0šāǝ! :D Would have never thought of that! \$\endgroup\$ Commented May 27, 2019 at 17:27
  • \$\begingroup\$ @KevinCruijssen Thanks! There's also D¦0š2Lǝ, which is the same byte-count as D1è0šāǝ. \$\endgroup\$
    – Grimmy
    Commented May 27, 2019 at 19:33
5
\$\begingroup\$

Python 2, 119 118 111 107 bytes

lambda a:[[n for n in a if sorted(a)[::d][~len(a)/2]*d<int('0'.join(`n*d`[:2])+`n*d`[3:])>999]for d in-1,1]

Try it online!

Outputs as suffering, leading.

\$\endgroup\$
2
\$\begingroup\$

Jelly, 30 bytes

,NµD2ị;0Ʋ2,3¦ḌƊ>ẠɗƇÆṁ;999Ɗ)N2¦

Try it online!

Given the length of Grimy’s 05AB1E answer, I’m sure this can be golfed better, but here it is.

\$\endgroup\$
1
\$\begingroup\$

JavaScript (Node.js), 162 bytes

a=>[(g=i=>a.filter(n=>n*i>999&(h=t=>a.reduce((a,c)=>a+(c!=n&i*c<i*t(n)),0)>=a.length/2)(x=>x)&h(m=x=>x<0?-m(-x):x>999?m(x/10)*10+x%10:x-x%100+x/10%10)))(1),g(-1)]

Try it online!

Anonymous function that take an array of numbers as input and outputs a 2-element array as output. The first element in the output array is an array of leading numbers, the second element in the output array is an array of following numbers.

// a: input array of numbers
a=>
  // begin output array
  [
    // define a function g with input i
    // when i is 1, generate leading
    // when i is -1, generate following
    (g=i=>
      // function g returns a subset of a,
      // use filter() to select elements
      a.filter(n=>
        // n must be 4 digits and explicitly
        // positive or negative depending
        // on whether we are calculating
        // leading or following numbers
        n*i>999&
        // function h determines whether
        // the current number is in the
        // larger or smaller half,
        // depending on whether we are
        // calculating the leading or
        // following numbers.
        // argument t defines a
        // transformation that should
        // be applied to th current number
        (h=t=>
          // use reduce() to count the
          // number of numbers greater or
          // less than the transformed
          // current number
          a.reduce((a,c)=>
            // add the current total to...
            a+
            // either 0 or 1 depending on
            // whether the transformed
            // current number is in the
            // opposite group (leading vs
            // following
            (c!=n&i*c<i*t(n)),0)>=
          // are at least half in the
          // opposite group?
          a.length/2)
          // invoke h with the identity
          // transform
          (x=>x)&
          // invoke h again with a
          // transform m that moves the
          // 2nd digit to the 3rd digit and
          // 0's out the 2nd digit.
          // input for m is number x
          h(m=x=>
            // is x negative?
            x<0
              // invoke m with negated input
              // to force it to a positive value
              // and negate the result to
              // convert back to negative
              ?-m(-x)
              // otherwise, does x have 4 or
              // more digits?
              :x>999
                // recursively call m with 1
                // fewer digit, then add digit
                // back to the result
                ?m(x/10)*10+x%10
                // 3 or fewer digits, move
                // the 2nd digit to the 3rd
                // and 0 put the 2nd digit
                :x-x%100+x/10%10
        )
      )
    )
    // invoke g with input 1 for leading
    (1),
    // invoke g with input -1 for following
    g(-1)
  ]
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.