Where does the pivot belong?

7

You will be given a positive integer as input.

The integer is the board of a seesaw.

Th integer will not have leading zeroes. You may take this input however you like.

Your task is to output the location of the pivot point of this seesaw, such that the board would balance.

A board balances if the moments on each side are equal in magnitude. A moment is calculated by multiplying the force by the distance from the pivot point. In this case, the force is equal to the digit.

For the integer 100 with a pivot point below the first 0, the moment on the left is 1x1=1. The moment on the right is 0x1=0. If the pivot point was below the second 0, the moment on the left would be 2x1=2 (because the 1 is now 2 away from the pivot).

For example, for the integer 31532 the pivot goes underneath the number 5. This is because the moments on the left are 3x2 + 1x1 = 7 and on the right the moments are 3x1 + 2x2 = 7.

The output for this integer is 3 because the pivot goes underneath the 3rd digit.

If the integer cannot be balanced, your code does not have to do anything - it can hang, error, output nothing - whatever you want.

Note that a pivot cannot go between two numbers. The pivot location must be an integer.

Test cases:

31532 -> 3
101 -> 2
231592 -> 4
8900311672 -> 5

Standard loopholes apply, this is code golf so shortest answer wins.

Tim

Posted 2017-07-15T02:08:04.400

Reputation: 2 789

Can I not handle the last testcase if it is too large? – Leaky Nun – 2017-07-15T02:46:14.013

1Can the output be 0-indexed? – Dennis – 2017-07-15T04:41:27.897

Can the output be indexed from the front of the number? Your test cases seem to do this. – Post Rock Garf Hunter – 2017-07-15T04:42:47.167

Related – Peter Taylor – 2017-07-15T06:52:25.440

1Is a list of digits a valid input format? – Lynn – 2017-07-15T09:07:16.817

Duplicate? (balancing words on ascii value instead of numbers) – nimi – 2017-07-15T10:01:48.760

@LeakyNun that’s fine – Tim – 2017-07-15T11:02:08.273

@Dennis no, 1 indexed please – Tim – 2017-07-15T11:02:26.757

@WheatWizard it has to be indexed from the left, with the left most digit = 1 – Tim – 2017-07-15T11:03:11.960

Answers

5

Haskell, 64 62 59 57 45 35 31 bytes

d l=sum(zipWith(*)[1..]l)/sum l

Try it online!

Post Rock Garf Hunter

Posted 2017-07-15T02:08:04.400

Reputation: 55 382

(:[]) is pure. – nimi – 2017-07-15T10:04:22.737

I think testing for <1 instead of ==0 should be enough. We get a list of all not right-heavy seesaws, but we are picking the first element anyway. – nimi – 2017-07-15T10:19:31.147

@nimi doing (<1) is pretty clever. Thanks for the tips. – Post Rock Garf Hunter – 2017-07-15T13:34:00.670

@flawr It feels like I should but $ has lower precedence than < preventing me. – Post Rock Garf Hunter – 2017-07-15T15:37:38.290

Oh you're right! As an alternative I think you could use until instead of the [x|x<-...]!!0 (not tested: until(\x->sum(zipWith(*)[1-x..]l<1)(+1)0) (coding on the phone is a little bit cumbersome :P) – flawr – 2017-07-15T15:39:20.303

@flawr That works but costs me a byte. – Post Rock Garf Hunter – 2017-07-15T15:43:10.503

Huh, I must have counted wrong, sorry=/ – flawr – 2017-07-15T15:52:22.703

Ah I missed a parenthesis, by adding that it has the same length!

– flawr – 2017-07-15T16:19:05.747

4

R, 66 bytes

sum(1:length(n<-strtoi(strsplit(paste(scan()),"")[[1]]))*n)/sum(n)

Try it online!

Leaky Nun

Posted 2017-07-15T02:08:04.400

Reputation: 45 011

You can take input as string by doing scan(,'') instead of using paste. – JAD – 2017-07-15T13:46:42.660

3

Leaky Nun

Posted 2017-07-15T02:08:04.400

Reputation: 45 011

You’ve done this before for some reason? – Tim – 2017-07-15T02:11:09.030

@Tim No, it's just a formula used in physics - sum of moments / sum of digits. – Leaky Nun – 2017-07-15T02:11:32.943

3@Tim He's known for posting answers extremely quickly to questions; sometimes, he posts an answer in the same minute as the question :P – HyperNeutrino – 2017-07-15T02:29:48.050

3

J, 29 bytes

[:>:@(+/%~]+/@:*i.@$)10#.inv]

Try it online!

Leaky Nun

Posted 2017-07-15T02:08:04.400

Reputation: 45 011

25 bytes [:(+/<.@%~]+/ .*#\),.&.": using a different method to get the list of digits. – miles – 2017-07-15T06:38:02.740

Nice, didn't see this before I posted mine. You beat me by a margin! And @miles made it even better. – Dan Bron – 2017-07-16T01:45:50.837

1In all honesty I don't think I've seen this many J golfers (5) in one place before :P – Conor O'Brien – 2017-07-16T04:00:05.813

3

Brain-Flak, 64 bytes

({({}[((((()()()){}){}){}){}]<>{})<>}<>)({()<({}[({})])>}<>)

Try it online!

60+4 bytes for the -ar flags.

Explanation

 {                                  }     for each digit in input (starting at the end)
   {}                                     get digit as ASCII code
     [((((()()()){}){}){}){}]             subtract 48 to get digit as number
  (                          <>{})<>      add to cumulative sum on second stack
(                                    <>)  push total of all cumulative sums (the sum of moments)

 {              }       while sum of moments != 0
     ({}[({})])         subtract sum of weights
  ()<          >        count the number of iterations needed
(                <>)    push onto first stack and implicitly output

Nitrodon

Posted 2017-07-15T02:08:04.400

Reputation: 9 181

Usually you can save bytes by using BrainHack instead of -a, but BrainHack doesn't have -r yet so you wont be able to this time.

– Post Rock Garf Hunter – 2017-07-15T14:21:07.207

Also because of the flexible input it seems you can take input as a list of ints instead of requiring a string. This could save you a bunch of bytes. – Post Rock Garf Hunter – 2017-07-16T03:23:06.837

2

Python 3, 66 bytes

f=lambda n,a=0,b=0,c=1:n and f(n//10,a+n%10*c,b+n%10,c+1)or c-a//b

Try it online!

Leaky Nun

Posted 2017-07-15T02:08:04.400

Reputation: 45 011

+1, Exactly half the length of my answer.... :D – officialaimm – 2017-07-15T03:26:53.027

2

Brachylog, 14 bytes

ẹ⟨{iᶠ×ᵐ+}÷+⟩+₁

Try it online!

Leaky Nun

Posted 2017-07-15T02:08:04.400

Reputation: 45 011

2

GolfScript (24 bytes)

0:i.@{15&.@+@@i):i*+\}//

Online demo

Peter Taylor

Posted 2017-07-15T02:08:04.400

Reputation: 41 901

1

Python 3, 69 bytes

x=[*map(int,input())]
print(sum(v*k for k,v in enumerate(x))//sum(x))

Try it online!

-7 bytes and fixed thanks to ovs

HyperNeutrino

Posted 2017-07-15T02:08:04.400

Reputation: 26 575

But it doesn't even work – Leaky Nun – 2017-07-15T02:36:13.237

Adding a closing bracket to the first line fixes the syntax, but then 3 is printed instead of 2. – Leaky Nun – 2017-07-15T02:37:14.680

Slightly golfed and fixed – ovs – 2017-07-15T06:52:19.050

@LeakyNun It outputs 2 for me, which seems to be right to me if this is 0-indexed. – ovs – 2017-07-15T06:53:31.937

@ovs Thanks for the fix+golf – HyperNeutrino – 2017-07-15T15:26:50.363

@LeakyNun Fixed. – HyperNeutrino – 2017-07-15T15:26:55.307

1

C (gcc), 72 bytes

a,b,c;f(long n){a=b=c=0;for(;n;a+=n%10*++c,n/=10)b+=n%10;return-~c-a/b;}

Try it online!

Leaky Nun

Posted 2017-07-15T02:08:04.400

Reputation: 45 011

2Since a,b,c are declared in an enclosing scope, they can be initialised in the initialiser of the for loop, saving a semicolon. – Peter Taylor – 2017-07-15T12:55:45.723

funnily also a valid solution in JS (slightly altered) f=n=>{for(a=b=c=0;n;a+=n%10*++c,n=n/10|0)b+=n%10;return-~c-a/b} – Oki – 2017-07-15T22:50:32.457

1

MATL, 12 bytes

48-ttn:*sws/

Try it online!

Leaky Nun

Posted 2017-07-15T02:08:04.400

Reputation: 45 011

1

Mathematica, 42 bytes

Range@Length@#.#/Total@#&@IntegerDigits@#&

Try it online! (Mathics)

Leaky Nun

Posted 2017-07-15T02:08:04.400

Reputation: 45 011

Tr saves 4 byte, but breaks Mathics compatibility. – user202729 – 2017-07-15T07:34:52.600

0

Pyth, 14 bytes

h/s.e*bkJjQTsJ

Test suite.

Leaky Nun

Posted 2017-07-15T02:08:04.400

Reputation: 45 011

0

Actually, 10 bytes

♂≡;Σ@;r*\u

Try it online!

Leaky Nun

Posted 2017-07-15T02:08:04.400

Reputation: 45 011

0

Cheddar, 63 bytes

n->(a->a.map((x,y)->x*y).sum/a.sum+1)(("%d"%n).bytes=>((-)&48))

Try it online!

Leaky Nun

Posted 2017-07-15T02:08:04.400

Reputation: 45 011

0

Python 2, 132 134 126 112 bytes

  • Thanks @ovs for 14 bytes.
n,m=map(int,input()),0
z=lambda a,b:sum(n[j]*abs(m-j)for j in range(a,b))
while z(0,m)<z(m,len(n)):m+=1
print-~m

Try it online!

officialaimm

Posted 2017-07-15T02:08:04.400

Reputation: 2 739

1But it prints 4 instead of 5 – Leaky Nun – 2017-07-15T03:30:01.430

Yes, it is 0-indexed. Should I change it? 2 bytes trade though.. – officialaimm – 2017-07-15T03:36:11.400

1Some bytes off – ovs – 2017-07-15T12:15:19.720

0

Retina, 43 bytes

$
;$`
(?=(.*);)
$1
\d
$*
^(1+)(\1)*;\1$
$#2

Try it online!

Leaky Nun

Posted 2017-07-15T02:08:04.400

Reputation: 45 011

0

Java (OpenJDK 8), 80 bytes

int f(long n){int a=0,b=0,c=0;for(;n>0;a+=n%10*++c,n/=10)b+=n%10;return-~c-a/b;}

Try it online!

Leaky Nun

Posted 2017-07-15T02:08:04.400

Reputation: 45 011

You could make this shorter with a lambda expression, n->{...} – Pavel – 2017-07-15T05:24:06.327

0

05AB1E, 10 bytes

TвÐgL*OsO÷

Try it online!

Leaky Nun

Posted 2017-07-15T02:08:04.400

Reputation: 45 011

0

GolfScript, 33 bytes

{48-}%.[.,,]zip{{*}*}%{+}*\{+}*/)

Try it online!

Leaky Nun

Posted 2017-07-15T02:08:04.400

Reputation: 45 011

0

Retina, 30 bytes


$'¶
1>`¶

.
$*
(1+)¶(\1)+
$#2

Try it online! Link includes test cases. Explanation: The first stage sneakily creates newline-delimited duplicates of all the suffixes of the original string. This means that the each digit appears after the first newline the number of times according to how far away it is from the left, effectively multiplying to give its moment. The second stage deletes all the newlines after the first, completing the calculation of the moments. The third stage converts the digits to unary, summing them, and the fourth stage divides the sums (exact division is assumed to apply here).

Neil

Posted 2017-07-15T02:08:04.400

Reputation: 95 035

0

J, 29 bytes

(0 i.~]+/ .*[:-/~#\)@(,.&.":)

J executes verbs right-to-left, so let's start at the end and work our way towards the beginning.

Explanation

         ,.&.":      NB. Explode integer into digits
         #\          NB. 0 .. N-1, where N=number of digits
         -/~         NB. Distance table, one row per digit
         ] +/ .* …   NB. Forces at each pivot (F=digit * distance)
         0 i.~ …     NB. Digit index where F=0

Note that J is an index-origin 0 language, so it would be more natural and idiomatic for the answer to 8900311672 to be 4 rather than 5, for 231592 to be 3 rather than 4, etc, and so that's the way this function is written.

But if the index-origin 1 is required for output, then add 1+ before 0 i.~ and add 2 bytes to the score, bringing it up from 29 to 31.

Dan Bron

Posted 2017-07-15T02:08:04.400

Reputation: 421

This does not work. Replace #.~&10^:_1 with (,.&.":) to fix. – rdm – 2017-07-16T03:04:15.677

@rdm Thanks, I originally had (10&#.^:_1) but I wanted to remove the parens, and quick independent testing showed #.~&10^:_1, but of course as you observed the composition doesn't. I'll fix. Thanks for the shortening. – Dan Bron – 2017-07-16T03:07:24.313

0

Python 3, 127 bytes

I am a newbie golfer. All suggestions and tips are greatly apreciated :).

lambda x:min([(abs(eval("+".join(list(x[:i+1])))-eval("+".join(list(x[i:])))),i+1)for i in range(len(x))],key=lambda x:x[0])[1]

Try it Online!

Zachary Cotton

Posted 2017-07-15T02:08:04.400

Reputation: 679

0

C# (.NET Core), 84 bytes

a=>{int p=0,q=0,i=1;for(;i<=a.Length;p+=a[i-1],q+=i*a[i++-1]);return q/(q%p>0?0:p);}

Try it online!

Takes in an array of single digits as the 'integer' input. Uses the image moments approach for finding the centre of mass. Throws a divide by zero if the seesaw is unbalanced.

DeGolfed

a=>{
    int p=0, // used to store the image moment of order 0
        q=0, // used to store the image moment of order 1
        i=1; // array index, offset to 1 as 1 based indexing is required

    for (; i <= a.Length; // go through the array
        p += a[i-1],      // getting the order 0 image moment value
        q += i*a[i++-1]); //     and the order 1 image moment value

    // q / p is the centre of mass, but as an exact integer pivot is required,
    // if q is not evenly divisible by p,
    // then throw a divide by zero error.
    // otherwise return q / p
    return q / ( q % p > 0? 0 : p);
}

Ayb4btu

Posted 2017-07-15T02:08:04.400

Reputation: 541