Be as evil as possible

16

Introduction

This is a follow-up of this challenge where you're taking the role of that person's evil twin. Being evil you don't want to maximize your share, but rather be as unfair as possible and you're not going to make it too obvious, that's why you came up with the following scheme:

You're going to tell the others that you want to be as fair as possible like your sibling and thus you're going to split the integer into pieces of equal length. So for each integer you will come up with the right amount of people such that the difference between the largest and the smallest piece is maximal.

For example if you're given the integer 6567 you could leave it as is, split it into two pieces 65,67 or four 6,5,6,7. This gives you the following maximal differences:

6567    -> max() = 0
65,67   -> max(|65-67|) = 2
6,5,6,7 -> max(|6-5|,|6-5|,|6-6|,|6-7|,|5-6|,|5-7|,|6-7|) = 2

Since you only want to be evil you don't prefer 67 over 7 and thus you will output either 2 or 4.


Another (less special case); given the integer 121131 you could split it like this:

121131      -> max() = 0
121,131     -> max(|121-131|) = 10
12,11,31    -> max(|12-11|,|12-31|,|11-31|) = 20
1,2,1,1,3,1 -> max(…) = 2

This time there's only one solution - namely 3 - since with three people the difference is maximal.

Challenge

Given an integer determine any possible way of being maximally evil and report the number of people needed to achieve this.

Rules

  • Input will always be ≥ 1
  • Input can be either an integer, list of digits or string
  • You don't have to handle invalid inputs

Testcases

You only need to report the resulting number of people needed, the possible partitions are only for illustration:

In -> splits (difference) -> Out
1 -> [1] (0) -> 1
10 -> [1,0] (1) -> 2
11 -> [11] or [1,1] (0) -> 1 or 2
12 -> [1,2] (1) -> 2
42 -> [4,2] (2) -> 2
101 -> [1,0,1] (1) -> 3
2222 -> [2222] or [22,22] or [2,2,2,2] (0) -> 1 or 2 or 4
6567 -> [65,67] or [6,5,6,7] (2) -> 2 or 4
123000 -> [123,000] (123) -> 2
123001 -> [123,001] (122) -> 2
121131 -> [12,11,31] (20) -> 3
294884 -> [294,884] (590) -> 2
192884729 -> [192,884,729] (692) -> 3
123456189012 -> [123456,189012] (65556) -> 2
123457117346 -> [1234,5711,7346] (6112) -> 3

ბიმო

Posted 2017-12-23T16:07:11.077

Reputation: 15 345

1I wonder if someone will submit a solution in the programming language evil? :D – SK19 – 2018-03-17T00:47:42.853

Answers

5

Jelly,  16  14 bytes

Ṁ_Ṃ
sLÆD$ḌÇÞṪL

A monadic link taking a list of integers (the digits) and returning an integer.

Try it online! or see a test-suite

How?

Ṁ_Ṃ - Link 1, maximal difference: list of numbers
Ṁ   - maximum
  Ṃ - minimum
 _  - subtract

sLÆD$ḌÇÞṪL - Main link: list of numbers, theDigits  e.g. [1,2,3,0,0,1]
    $      - last two links as a monad:
 L         -   length                                    6
  ÆD       -   divisors                                  [1,2,3,6]
s          - split into chunks (vectorises)              [[[1],[2],[3],[0],[0],[1]],[[1,2],[3,0],[0,1]],[[1,2,3],[0,0,1]],[[1,2,3,0,0,1]]]
     Ḍ     - from decimal (vectorises)                   [[1,2,3,0,0,1],[12,30,1],[123,1],[123001]]
       Þ   - sort by:
      Ç    -   call last link (1) as a monad              3             29        122     0
           -                                         ... [[123001],[1,2,3,0,0,1],[12,30,1],[123,1]]
        Ṫ  - tail                                        [123,1]
         L - length                                      2

Jonathan Allan

Posted 2017-12-23T16:07:11.077

Reputation: 67 804

Yup, I know you don't know Pyth! +1 because Jelly minds think alike! Too bad ŒṖ and ./ are both longer – Mr. Xcoder – 2017-12-23T17:04:42.850

4

Pyth, 20 bytes

leoeSaM^N2vcRQ*M{yPl

Try it here!

I no longer use partitions, because it turns out to be longer!!! I ended up splitting into sublists of length equal to the divisors of the length.

Mr. Xcoder

Posted 2017-12-23T16:07:11.077

Reputation: 39 774

4

05AB1E, 12 bytes

gDÑΣôDδαà}θ÷

Try it online!

05AB1E, 12 bytes

gDÑΣôàsß-}θ÷

Try it online!

How it works

gDÑΣôDδαà}θ÷ | Full program.

g            | Length (count of digits).
 D           | Duplicate (push two copies of the length to the stack).
  Ñ          | Get the divisors (of the top of the stack).
   Σ     }   | Sort by a key function.
--------------------------------------------------------------
    ôDδαà    | Key function #1.
    ô          | Split (the input) into chunks of that size.
     D         | Duplicate.
      δα       | Outer product of absolute difference.
        à      | Get the maximum.
    ôàsß-    | Key function #2 (alternative).
    ô          | Split (the input) into chunks of that size.
     à         | Maximum.
      s        | Swap top two elements.
       ß       | Minimum.
        -      | Subtract.
--------------------------------------------------------------
          θ÷ | Divide the length by the maximum element using the custom sorting.

05AB1E is just incredibly terse for this challenge.

Mr. Xcoder

Posted 2017-12-23T16:07:11.077

Reputation: 39 774

4

JavaScript (ES6), 118 115 bytes

Saved 3 bytes thanks to @edc65

Takes input as a string.

f=(s,k=l=s.length,m)=>k?f(s,k-1,l%k||(d=Math.max(...a=s.match(eval(`/.{${l/k}}/g`)))-Math.min(...a))<m?m:(r=k,d)):r

Test cases

f=(s,k=l=s.length,m)=>k?f(s,k-1,l%k||(d=Math.max(...a=s.match(eval(`/.{${l/k}}/g`)))-Math.min(...a))<m?m:(r=k,d)):r

console.log(f('1')) // [1] (0) -> 1
console.log(f('10')) // [1,0] (1) -> 2
console.log(f('11')) // [11] or [1,1] (0) -> 1 or 2
console.log(f('12')) // [1,2] (1) -> 2
console.log(f('42')) // [4,2] (2) -> 2
console.log(f('101')) // [1,0,1] (1) -> 3
console.log(f('2222')) // [2222] or [22,22] or [2,2,2,2] (0) -> 1 or 2 or 4
console.log(f('6567')) // [65,67] or [6,5,6,7] (2) -> 2 or 4
console.log(f('123000')) // [123,0] (123) -> 2
console.log(f('123001')) // [123,1] (122) -> 2
console.log(f('121131')) // [12,11,31] (20) -> 3
console.log(f('294884')) // [294,884] (590) -> 2
console.log(f('192884729')) // [192,884,729] (692) -> 3
console.log(f('123456189012')) // [123456,189012] (65556) -> 2
console.log(f('123457117346')) // [1234,5711,7346] (6112) -> 3

Arnauld

Posted 2017-12-23T16:07:11.077

Reputation: 111 334

1Did you try eval instead of RegExp ? – edc65 – 2017-12-23T21:00:44.940

@edc65 I keep forgetting about that one. Thank you! – Arnauld – 2017-12-23T21:47:28.920

1

Python 2, 138 132 bytes

n=input()
l=len(n)
print len(max([[int(n[l/i*j:][:l/i])for j in range(i)]for i in range(1,l+1)if l%i<1],key=lambda a:max(a)-min(a)))

Try it online!

ovs

Posted 2017-12-23T16:07:11.077

Reputation: 21 408

1

Haskell, 114 bytes

f n|l<-length n=snd$maximum[(a-b,div l i)|i<-[1..l],mod l i<1,a<-i%n,b<-i%n]
i%[]=[]
i%n=read(take i n):i%drop i n

Try it online!

Laikoni

Posted 2017-12-23T16:07:11.077

Reputation: 23 676

1

Perl 5, 70 bytes

s%.%/A/g;/$/,map$;[$-=$`-$_]=@1,@1for@1=(/.{@{+}}/gc)x!/./g%eg;$_=pop@

Try it online!

Ton Hospel

Posted 2017-12-23T16:07:11.077

Reputation: 14 114

0

Jelly, 20 bytes

ŒṖL€E$ÐfḌạþ`ẎṀ$$ÐṀḢL

Try it online!

Erik the Outgolfer

Posted 2017-12-23T16:07:11.077

Reputation: 38 134