15
\$\begingroup\$

We haven't had any nice, easy challenges in a while, so here we go.

Given a list of integers each greater than \$0\$ and an index as input, output the percentage of the item at the given index of the total sum of the list.

Output should be whatever the natural representation for floats/integers is in your language (unary, decimal, Church numerals etc.). If you choose to round the output in any way, it must have at minimum 2 decimal places (when reasonable. \$1.2\$ doesn't need to be rounded, but \$1.20\$ is also perfectly acceptable).

Indexes can be either 1-indexed or 0-indexed, and will always be within the bounds of the array.

This is , so the shortest code in bytes wins!

Examples

Using 1-indexed and rounded to 2 d.p

list, index                    =>         output
[1, 2, 3, 4, 5], 5             => 5 / 15    => 33.33
[7, 3, 19], 1                  => 7 / 29    => 24.14
[1, 1, 1, 1, 1, 1, 1, 1, 1], 6 => 1 / 9     => 11.11
[20, 176, 194, 2017, 3], 1     => 20 / 2410 => 0.83
[712], 1                       => 712 / 712 => 100

Or, as three lists:

[[1, 2, 3, 4, 5], [7, 3, 19], [1, 1, 1, 1, 1, 1, 1, 1, 1], [20, 176, 194, 2017, 3], [712]]
[5, 1, 6, 1, 1]
[33.33, 24.14, 11.11, 0.83, 100]
\$\endgroup\$
  • \$\begingroup\$ Sandbox post (now deleted) \$\endgroup\$ – caird coinheringaahing Sep 29 at 0:04
  • 3
    \$\begingroup\$ how exactly can non-integers be output as unary / church numerals? \$\endgroup\$ – Doorknob Sep 29 at 3:25
  • 1
    \$\begingroup\$ @Doorknob Maybe a unary number, the dot, and another unary number? \$\endgroup\$ – HighlyRadioactive Sep 29 at 5:32
  • \$\begingroup\$ Since the output can be rounded to two decimal places, it might also be permissible to output rounded times 100? \$\endgroup\$ – Unrelated String Sep 29 at 6:10
  • 1
    \$\begingroup\$ test case 4 should be 20/2410 \$\endgroup\$ – attinat Sep 29 at 8:31

41 Answers 41

6
\$\begingroup\$

APL (Dyalog Unicode), 9 bytesSBCS

Anonymous tacit infix function. Takes index as left argument and list as right argument.

100×⌷÷1⊥⊢

Try it online!

100 one hundred

× times

 the indexed element

÷ divided by

1⊥ the sum (lit. the base-1 evaluation) of

 the right argument

\$\endgroup\$
6
\$\begingroup\$

C# (Visual C# Interactive Compiler), 22 bytes

x=>y=>x[y]*100/x.Sum()

Try it online!

\$\endgroup\$
6
\$\begingroup\$

Python 3, 26 bytes

lambda i,a:a[i]/sum(a)*100

An unnamed function accepting an integer (0-indexed index) and a list which returns the percentage.

Try it online!

\$\endgroup\$
5
\$\begingroup\$

Jelly, 7 bytes

ị÷S}ȷ2×

A dyadic Link accepting an integer, one-based index on the left and a list of numbers on the right which yields the percentage.

Try it online!

How?

ị÷S}ȷ2× - Link: integer, i; list, L
ị       - (i) index into (L)
   }    - use right argument:
  S     -   sum (L)
 ÷      - divide
    ȷ2  - literal 10^2 = 100
      × - multiply
\$\endgroup\$
  • 1
    \$\begingroup\$ Nice! That's byte for byte what I had :P \$\endgroup\$ – caird coinheringaahing Sep 29 at 0:20
5
\$\begingroup\$

05AB1E, 6 bytes

è²O/т*

A full program taking the index then the list. Uses 0-indexing.

Try it online!

How?

è²O/т*
è      - index (input 1) into (input 2)
 ²     - push 2nd input
  O    - sum
   /   - divide
    т  - push 100
     * - multiply
       - print top of stack
\$\endgroup\$
4
\$\begingroup\$

R 28 bytes

function(n,l)100*l[n]/sum(l)

Try it online!

\$\endgroup\$
  • \$\begingroup\$ I don't know R, but this doesn't look like it works (not sure how to test it on TIO with arbitrary arrays), as you are supposed to retrieve the element of l at index n, not just divide by n (see the [7, 3, 19], 1 testcase) \$\endgroup\$ – caird coinheringaahing Sep 29 at 12:02
  • \$\begingroup\$ @cairdcoinheringaahing My bad, had a typo (forgot the l[] around the n) \$\endgroup\$ – niko Sep 29 at 12:31
  • \$\begingroup\$ There's a thing on the TIO link page that can format this for you. \$\endgroup\$ – JL2210 Oct 1 at 18:00
4
\$\begingroup\$

C (gcc), 64 bytes

0-indexed. The only fun bit was the realization that 1e2 is a double, saving a byte over 100.!

float f(v,n,t)int*v;{n=v[n];for(t=0;*v;t+=*v++);return n*1e2/t;}

Try it online!

\$\endgroup\$
4
\$\begingroup\$

Java (JDK), 47 bytes

a->i->1e2*a[i]/java.util.Arrays.stream(a).sum()

Try it online!

\$\endgroup\$
  • \$\begingroup\$ Why did you wrote 1e2 instead of 100? Is it because 100 is integer and 1e2 is considered as a floating point number? \$\endgroup\$ – Ismael Miguel Oct 1 at 15:09
  • 1
    \$\begingroup\$ @IsmaelMiguel Yes: 1e2 carries the double type, which a[i] and the sum don't. Since the challenge requires to return floating point numbers, that's where I can use it. \$\endgroup\$ – Olivier Grégoire Oct 1 at 15:16
  • \$\begingroup\$ Change it to a BiFunction<int[], Integer, Double> and you can save 10 bytes with this: (a,i)->1e2*a[i]/IntStream.of(a).sum(). Edit: >:( my poor lambda arrow \$\endgroup\$ – Avi Oct 1 at 15:31
  • \$\begingroup\$ @Avi The import is still required, so I'd have to write: (a,i)->1e2*a[i]/java.util.stream.IntStream.of(a).sum(), which is 54 bytes long. My current answer is only 47 bytes long. Also, a->i-> is one byte shorter than (a,i)->. \$\endgroup\$ – Olivier Grégoire Oct 1 at 15:34
  • 1
    \$\begingroup\$ @Avi Yes, they are required, and it's usually shorter to write the full class name instead of the import, so that's what I do here \$\endgroup\$ – Olivier Grégoire Oct 1 at 15:37
3
\$\begingroup\$

Haskell,  20  18 bytes

i?a=a!!i/sum a*100

A dyadic operator (?) taking the (0-indexed) index on the left and a list on the right which yields the percentage.

Try it online!

\$\endgroup\$
3
\$\begingroup\$

J, 10 bytes

100*{%1#.]

Try it online!

0-indexed

\$\endgroup\$
3
\$\begingroup\$

Wolfram Language (Mathematica), 15 bytes

100##[[]]/Tr@#&

Try it online!

Input as list, index

\$\endgroup\$
  • \$\begingroup\$ ##[[]] is awesome! \$\endgroup\$ – Greg Martin Sep 29 at 16:47
3
\$\begingroup\$

JavaScript (ES6), 30 bytes

Takes input as (array)(index), where index is 0-based.

a=>n=>a[n]*100/eval(a.join`+`)

Try it online!

\$\endgroup\$
3
\$\begingroup\$

MATL, 9 bytes

)1Gs/100*

Try it online!

Explanation

          implicitly take two inputs
)         get the entry within the first input at the index specified by the second
 1G       push the first input onto the stack again
   s      compute the sum 
    /     divide first entry of the stack by this number (the sum) 
     100* multiply by 100

Try it online!

\$\endgroup\$
3
\$\begingroup\$

PHP (7.4), 35 bytes

fn($l,$i)=>100/array_sum($l)*$l[$i]

Try it online!

Input index is 0-based.

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

Red, 31 29 bytes

-2 bytes thanks to ErikF

func[b i][1e2 * b/:i / sum b]

Try it online!

\$\endgroup\$
  • 1
    \$\begingroup\$ (-2 bytes) suggest using 1e2 instead of 100.0: Try it online!. It's pretty neat how many languages can use this trick! \$\endgroup\$ – ErikF Sep 30 at 4:44
  • \$\begingroup\$ @ErikF Thank you! I know this in theory, but as it seems, I forgot to use it :) \$\endgroup\$ – Galen Ivanov Sep 30 at 6:29
2
\$\begingroup\$

PowerShell, 34 bytes

param($l,$n)$l|%{$i+=$_};$l[$n]/$i

Try it online!

Shame parameters are so dang expensive in Powershell.

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

Scratch 3.0 24 23 blocks/239 228 bytes

-11 bytes thanks to @JoKing

Alternatively in SB syntax

when gf clicked
set[s v]to(0
ask()and wait
repeat until<(answer)=(
add(answer)to[m v
ask()and wait
end
set[n v]to(item(length of(n))of(m
repeat(length of((m)-(1
change[s v]by(item(1)of[m v
delete (1)of[m v
end
say(((n)/(s))*(100

Saved 11 bytes thanks to @JoKing

Try it on scratch

Answer History

Oh Scratchblocks, why so long?

Alternatively in SB syntax

when gf clicked
set[s v]to(0
ask()and wait
repeat until<(answer)=(
add(answer)to[m v
ask()and wait
end
set[n v]to(item(length of(n))of(m
delete(n)of[m v
repeat(length of(m
change[s v]by(item(1)of[m v
delete (1)of[m v
end
say(((n)/(s))*(100

Try it on scratch

Input is in the form of:

item1
item2
...
itemN
index

I really should stop doing this to myself. But it is very fun!

\$\endgroup\$
  • \$\begingroup\$ Can you change repeat length of m to length of m-1 and save yourself the delete n? \$\endgroup\$ – Jo King Oct 3 at 5:43
  • \$\begingroup\$ No, because if I did, it wouldn't tally the last item. \$\endgroup\$ – Jono 2906 Oct 3 at 5:46
  • \$\begingroup\$ Well, if you remove the delete n of m like I suggested then it would \$\endgroup\$ – Jo King Oct 3 at 6:09
2
\$\begingroup\$

K (oK), 15 14 bytes

-1 byte thanks to ngn!

{100*x[y]%+/x}

Try it online!

0-indexed

\$\endgroup\$
  • 1
    \$\begingroup\$ (x@y) -> x[y] \$\endgroup\$ – ngn Oct 10 at 13:42
  • \$\begingroup\$ @ngn Thanks you! \$\endgroup\$ – Galen Ivanov Oct 10 at 14:08
1
\$\begingroup\$

Perl 5 -ap -MList::Util=Sum, 19 bytes

$_=100*$F[<>]/sum@F

Try it online!

Take the list, space separated on the first line, the index (0-based) on the second.

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

Japt, 8 bytes

gV
*L/Vx

Try it

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

TI-Basic, 12 bytes (12 tokens)

Prompt X
Ans(X)E2/sum(Ans

1-indexed

Takes the list in Ans and prompts the user for the index

Example run

Explanation:

Prompt X         # Prompt the user for the index
Ans(X)E2/sum(Ans
Ans(X)           # The value at the Xth index in the list
      E2         # times 100
        /sum(Ans # Divided by the sum of the list
                 # The result of the last expression in a program is implicitly returned
\$\endgroup\$
1
\$\begingroup\$

Retina 0.8.2, 102 bytes

\d+
$*
^(1)+((?<-1>.(1+))+)
$3$2
,

\G1
10000$*
;(1+)\1
$1;$1$1
r`.*(\2)*;(1+)
$#1
+`^..?$
0$&
..$
.$&

Try it online! Link includes test cases. Takes input as index;list,.... Explanation:

\d+
$*

Convert to unary.

^(1)+((?<-1>.(1+))+)
$3$2

Index into the list.

,

Sum the list.

\G1
10000$*
;(1+)\1
$1;$1$1
r`.*(\2)*;(1+)
$#1

Multiply the desired value by 10000 and divide by the sum with rounding by adding on half of the sum first.

+`^..?$
0$&

Ensure that the result has at least three digits.

..$
.$&

Insert a decimal point at the second last position.

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

Ruby, 25 23 21 bytes

->a,i{1e2*a[i]/a.sum}

Try it online!

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

Perl 6, 21 bytes

{100*@^a[$^b]/@a.sum}

Try it online!

The simple solution, since I can't use curried parameters with the $b parameter being indexed. A funner solution that doesn't have to handle two parameters by using the rotate function instead:

{100*.[0]/.sum}o&rotate

Try it online!

But it is unfortunately two bytes longer

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

Octave, 21 bytes

@(a,n)a(n)/sum(a)*100

Try it online!

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

MathGolf, 7 6 bytes

§\Σ/♀*

0-based indexing.

Try it online.

Explanation:

§       # Index the (implicit) second input-integer into the first (implicit) input-list,
        # which apparently doesn't pop the list
 \      # Swap so this list is at the top of the stack now
  Σ     # Take the sum of that list
   /    # Divide the earlier number we indexed by this sum
    ♀*  # Multiply it by 100
        # (after which the entire stack joined together is output implicitly as result)
\$\endgroup\$
1
\$\begingroup\$

Icon, 53 bytes

procedure f(L,i)
s:=0;s+:=!L&\z
return 1e2*L[i]/s
end

Try it online!

The only interesting thing here is finding the sum. Icon was one of the first languages to have generators. ! generates all the values of the list L that are accumulated to s. Normally we need to write every s+:=!L, but I used backtracking with &\z, which checks if the non-existent z variable is non-null, which is not, and extracts the next value from the list until exhaustion.

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

Factor, 46 bytes

: f ( i l -- n ) dup [ nth ] dip sum / 1e2 * ;

Try it online!

0-indexed

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

Batch, 111 bytes

@shift
@set s=%*
@call set/as=%s: =+%-%0,s=(%%%0*10000+s/2)/s,h=s%%%%10,t=s/10%%%%10,s/=100
@echo %s%.%t%%h%

Takes input as index and list as command-line arguments. Note: Only works for index values from 1 to 9 due to limitations of Batch; a 0-indexed version could be written which would be able to index the first 10 elements. Explanation:

@shift

Shift the index to %0 and the list to %1...%9 (or less). Note however that Batch's shift does not affect %*.

@set s=%*

Get all of the parameters, space separated.

@call set/as=%s: =+%-%0,s=(%%%0*10000+s/2)/s,h=s%%%%10,t=s/10%%%%10,s/=100

Change the spaces to +s and evaluate arithmetically, thus taking the sum, but subtract the index. Then index into the list, multiply by 10000, add half of the sum, and divide by the sum. Finally perform divmod by 10 twice to generate the decimal places. (The % arithmetic operator has special meaning in Batch and normally needs to be doubled but the call then requires a further doubling.)

@echo %s%.%t%%h%

Output the result and the decimal places.

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

Swift, 60 bytes

{(n:[Int],i)->Float in
1e2*Float(n[i])/Float(n.reduce(0,+))}

Try it online!

I picked Swift to participate and bumped into its type sensitivity !

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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