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 '19 at 0:04
  • 3
    \$\begingroup\$ how exactly can non-integers be output as unary / church numerals? \$\endgroup\$ – Doorknob Sep 29 '19 at 3:25
  • 1
    \$\begingroup\$ @Doorknob Maybe a unary number, the dot, and another unary number? \$\endgroup\$ – HighlyRadioactive Sep 29 '19 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 '19 at 6:10
  • 1
    \$\begingroup\$ test case 4 should be 20/2410 \$\endgroup\$ – attinat Sep 29 '19 at 8:31

43 Answers 43

1 2
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\$
1
\$\begingroup\$

Zsh, 32 30 bytes

-1 thanks to @ErikF, using 1e2 instead of 100..

<<<$[1e2*$@[`<&0`]/(${@/#/+})]

Try it online! Try it online!

Accepts the list as arguments and the index on stdin.

<<<$[1e2*$@[`<&0`]/(${@/#/+})]  # $[ arithmetic ]
   $[       `<&0`            ]  # capture stdin
   $[    $@[     ]           ]  # index into the arguments
   $[1e2*$@[`<&0`]           ]  # multiply by 100.0 (casts to float)
   $[              (${@/#/+})]  # prepend each element with + and add
   $[             /          ]  # divide
<<<                              # print to stdout

Alternate 30 byte solution

\$\endgroup\$
  • 1
    \$\begingroup\$ (-1 bytes) 1e2 instead of 100. works just like in C to cast to float: Try it online! \$\endgroup\$ – ErikF Sep 30 '19 at 4:40
1
\$\begingroup\$

Racket, 81 43 bytes

Accepts a list and index. Outputs rationals (default for division in Racket). Big thanks to Galen Ivanov for finding the apply function. Still learning as I go :) .

(λ(l i)(*(/(list-ref l i)(apply + l))100))

Try it online!

\$\endgroup\$
  • 1
    \$\begingroup\$ To my understand, #lang racket is not counted into bytes if submission is a function. \$\endgroup\$ – tsh Sep 30 '19 at 6:33
  • \$\begingroup\$ I think tsh is right. You can make it work in TIO by assigning the lambda to a variable. Since this is code-golf, you need to remove all the whitespaces like this for 60 bytes \$\endgroup\$ – Galen Ivanov Sep 30 '19 at 6:39
  • \$\begingroup\$ (foldl (λ (a b) (+ a b)) 0 l) -> (apply + l) for 44 bytes \$\endgroup\$ – Galen Ivanov Sep 30 '19 at 6:44
  • 1
    \$\begingroup\$ @GalenIvanov The last ) is matched to (define and is not a part of function. So it should not be included too. \$\endgroup\$ – tsh Sep 30 '19 at 6:48
  • \$\begingroup\$ @tsh Yes, of course! I forgot to move it to the footer. So it is 43 bytes \$\endgroup\$ – Galen Ivanov Sep 30 '19 at 6:54
1
\$\begingroup\$

AWK, 43 40 bytes

{s+=a[NR]=$1}END{print 100*a[$1]/(s-$1)}

Try it online!

-3 bytes thanks to CowsQuack

Takes the index as the last line of input

\$\endgroup\$
  • \$\begingroup\$ I saw you mention in chat for more test cases, here's a bash wrapper. \$\endgroup\$ – GammaFunction Sep 29 '19 at 20:32
  • \$\begingroup\$ @GammaFunction Thanks! I had no idea you could write to the file system in TIO. \$\endgroup\$ – Jonah Sep 29 '19 at 21:04
  • \$\begingroup\$ @GammaFunction What's the reason we need the space and single quotes around EOF there to make it work? \$\endgroup\$ – Jonah Sep 29 '19 at 21:12
  • 1
    \$\begingroup\$ Single quotes prevent $expansions from happening in the heredoc. The space does nothing either way \$\endgroup\$ – GammaFunction Sep 29 '19 at 21:16
  • 1
    \$\begingroup\$ {s+=a[NR]=$1} shaves 3 bytes \$\endgroup\$ – Kritixi Lithos Sep 30 '19 at 6:41
1
\$\begingroup\$

T-SQL 2008, 41 bytes

To find the row number equal to the index:

A division of index and row number multiplied with division of row number and index, if both results are 1, index and row are the same because both are above 0 and integer division round down. This saves 1 byte compared to using IIF

a - value

b - row number

Using table variable as input. 1-indexed

SELECT max(b/@*(@/b)*a*100)/sum(a)FROM @x

Try it online

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

Julia 1.0, 21 bytes

f(l,i)=100l[i]/sum(l)

Try it online!

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

Bash, 77 75 73 72 80 76 75 bytes

a=($@)
((b=10000*${a[$1]}/(${@/%/+}-$1),b<10))
echo $[b/100].${?/1}$[b%100]

Try it online!

+8 bytes thanks to GammaFunction, who found a bug with large numbers

-5 bytes thanks to GammaFunction, who golfed his original bug fix

\$\endgroup\$
  • \$\begingroup\$ Ah, nice catch. Ty! \$\endgroup\$ – Jonah Sep 29 '19 at 20:56
  • 1
    \$\begingroup\$ Whoops, saved one more. I don't think bash is going to let me be any more clever than this, though \$\endgroup\$ – GammaFunction Sep 29 '19 at 21:28
1
\$\begingroup\$

Go, 79 bytes

func f(a[]float64,i int)float64{s:=0.;for _,v:=range a{s+=v};return a[i]/s*100}

Try it online!

This has a nice amount of accuracy. It takes a Go slice and uses range to calculate the sum.

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

Stax, 7 bytes

â└╡Æå'W

Run and debug it at staxlang.xyz!

0-indexed. Requires at least one item in the input list to be of the form N.0 rather than simply N. Replacing / in the unpacked version with :_ gets around this restriction at the cost of one byte.

Unpacked (8 bytes) and explanation:

@AJ*x|+/    Index atop the stack, with the list beneath
@           Element at index...
 AJ*        Times 100
    x|+     Sum of list
       /    Divide
\$\endgroup\$
1
\$\begingroup\$

k4, 14 bytes

{%+/x%100*x y}

can save 1 byte from @Galen Ivanov's solution (in oK) as % is inverse operation in k4 as opposed to square root

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

Clojure, 40 bytes

(fn[a b](* 1e2(/(nth a b)(apply + a))))

Try it online!

It's nice to know about the 1e2 trick. :-)

\$\endgroup\$
0
\$\begingroup\$

Canvas, 8 bytes

@;∑÷AA××

Try it here!

Uses 1-indexing.

The last half just multiplies by 100, so 4 bytes can be saved if percentage over interval [0,1] is allowed as opposed to percentage over interval [0,100].


Explanation of example run: list = [1, 2, 3, 4, 5], index = 5.

Stack Visualization                 | Executed Instruction | Explanation
------------------------------------+----------------------+-----------------------------------------------------------------------------
..., [1,2,3,4,5], 5, [1,2,3,4,5]    | (program start)      | Canvas starts with the stack populated with the inputs repeating infinitely
..., [1,2,3,4,5], 5                 | @, get item         | @NA gets the Nth item of A
..., 5, [1,2,3,4,5]                 | ;, swap two ToS     | Swaps the position of the two top items in the stack
..., 5, 15                          | ∑, sum               | Sums all items in an array
..., 0.33333333333333333333         | ÷, divide            | Divides the two top items in the stack
..., 0.33333333333333333333, 10     | A, push 10          | Pushes 10 to the stack
..., 0.33333333333333333333, 10, 10 | A, push 10          | "                    "
..., 0.33333333333333333333, 100    | ×, multiply          | Multiplies the two top items in the stack
..., 33.333333333333333333          | ×, multiply          | "                                       "
...                                 | (end of program)     | Pop and print ToS
\$\endgroup\$
0
\$\begingroup\$

Forth (gforth), 61 bytes

: f 8 * over + f@ 0e swap 0 do dup f@ f+ 8 + loop f/ 1e2 f* ;

Try it online!

It's way too painful to work with arrays in Forth...

A function that takes three items (array length, array start address, index; rightmost being the top) from the main stack, and gives the answer on the FP stack. The array contains floating-point values.

How it works

: f ( len addr idx -- F: ans )
  8 * over + ( len addr addr[idx] ) \ compute the address for the item
  f@ 0e ( len addr F:x F:sum )      \ fetch the float at addr[idx] and push 0 on FP stack
  swap 0 do ( addr F:x F:sum )      \ repeat len times..
    dup f@ f+                       \   fetch the float at addr, add it to the sum
    8 +                             \   increment the addr by one cell
  loop                              \ end loop
  f/ 1e2 f*                         \ compute x / sum * 100
;
\$\endgroup\$
1 2

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.