# Calculate the Lowest Even-Harmonic of the Values in a List

PROBLEM

For a list of numbers, list: Find the lowest possible integer, x, which is optimally close to the whole number even-harmonics of the values in list.

• list has a length of n, and all of the values in list are <= 2000
• x has a precision of 1.0 (integers only), and must be a value in the range [20, 100]
• An even-harmonic is a number that is divisible by list an even number of times. 20 is an even harmonic of 80 (because 80/20=4) -- but an odd harmonic of 60 (because 60/20=3).
• In this case, "optimally close" simply means to minimize the absolute cumulative remainder, relative to the nearest even harmonic of the input value(s).
• Minimizing the absolute cumulative error takes priority over choosing the "lowest allowable value" for x.
• Given list = [151, 450, 315] and a candidate guess of x=25 the absolute cumulative remainder is 0.64 because 25 goes into list [6.04, 18, 12.6] times, respectively. The nearest even-harmonics for each instance are [6, 18, 12].

EXAMPLE

list = [100, 300, 700, 1340]

• x = 20 is a bad solution because it is an exact or almost-exact odd-harmonic of all of the values of list. The number 20 goes into list [5, 15, 35, 67] times, respectively (odd numbers = odd harmonics = the opposite of even-harmonics).
• The absolute cumulative remainder is 4.0 in this case (which is the maximum possible error for this instance of list).
• x = 25 is a good solution, but not the best, because it is a exact or almost-exact even-harmonic of all of the values of list. In this case, 25 is an exact even-harmonic in all cases except for 1340. The number 25 goes into list [4, 12, 20, 53.6] times, respectively (even numbers).
• The absolute cumulative remainder is 0.4 in this case.

BONUS

Same prompt and problem, except x has a maximum precision of 0.1 (non-integer)

• Why is x=25 the best solution, and not 2? All of 100, 300, 700, and 1340 are exactly divisible by 2 an even number of times. May 27 at 17:21
• See bullet 2 in the problem statement. X must be in the range [20,100] May 27 at 17:22
• Doesn't 20 go into 700 35 times? May 27 at 17:39
• Edited - thanks May 27 at 17:40
• ...but the example you edited is the [100, 300, 700, 1340] one, for which it is not .213 May 27 at 18:30

# Jelly, 16 bytes

÷Ɱȷ2Ḃ2_«Ɗ§Ụ>Ƈ19Ḣ


A monadic Link that accepts a list of integers and yields an integer.

Try it online!

### How?

÷Ɱȷ2Ḃ2_«Ɗ§Ụ>Ƈ19Ḣ - Link: list of integers, A
ȷ2             - 10^2 = 100
Ɱ               - map across x in [1,100] with:
÷                -   A divided by x (vectorises)
Ḃ            - mod 2 (vectorises)
2           -   two
_          -   subtract v (vectorises)
«         -   minimum with v (vectorises)
§       - sums
Ụ      - grade-up (one-based indices sorted by the value at that index)
Ƈ    - filter keep if:
> 19  -   greater than 19


# Factor + math.unicode, 8378 77 bytes

[ 20 100 [a,b] [ v/n [ 2 mod dup 1 > 2 0 ? - abs ] map Σ ] with infimum-by ]


Try it online!

• 20 100 [a,b] Create a range from 20 to 100, inclusive.
• [ ... ] with infimum-by Find the number in the range that is smallest when [ ... ] is applied to it. with takes our input into the [ ... ] in such a way that it will be underneath each number in the range on the data stack.
• v/n Divide each element in the input by the current number in the range.
• [ ... ] map Σ Map each element to a new value with the [ ... ] quotation and then take the sum.
• 2 mod dup 1 > 2 0 ? - abs Find the distance to the nearest even number.

# JavaScript (ES6), 79 bytes

a=>(m=g=o=>x++>99?o:g(a.map(v=>e+=(v/=x)&1?1-v%1:v%1,e=0)|e>m?o:(m=e,x)))(x=19)


Try it online!

• Nicely done Arnauld! May 27 at 17:55

# Python 3, 75 73 bytes

lambda l:min(range(20,101),key=lambda x:sum(min(a/x%2,-a/x%2)for a in l))


Try it online!

Saved 2 bytes thanks to Steffan!!!

Inputs a list of integers.
Returns the lowest even harmonic.

• Nice! FYI this breaks if you feed it only a single list. Accepting multiple list inputs is not a requirement so you may be able to reduce this further by eliminating that functionality May 27 at 23:58
• @AustinPrater Are you confusing my test harness (which works on multiple lists) with my solution (which inputs a single list)? The test harness doesn't break on a single list. It uses tuples so you need to put a comma after a single element (eg tuple of $1$: (1,)). May 28 at 0:11
• I see -- makes sense May 28 at 0:24
• 73 May 28 at 0:37

# Burlesque, 49 bytes

bc20 100r@)td{?/{JR_2./2.*.-ab}ms}Z]ziq[~<m-]20.+


Try it online!

bc       # Repeat input list
20 100r@ # Range [20..100]
)td      # As doubles
{
?/      # Divide each
{       # -- Find difference with nearest 2
J      # Duplicate
R_     # Round
2./2.* # Closest multiple of 2
.-     # Difference
ab     # Abs
}
ms      # Map sum
}Z]      # Zip range with input and evaluate
zi       # Zip indices
q[~<m-]  # Index of minimum
20.+     # +20


# R, 72 bytes

\(l,m=20:200,x=outer(l,m,/)%%2/2)m[order(colSums(abs(x-round(x))))]

Attempt This Online!

# Vyxal, 19 bytes

20₁ṡµ⁰$/:1%$∷1=+∑;h


Try it Online!

-2 bytes thanks to emanresu A, and another -3 by porting 05AB1E

• I have no idea how this works but here's 22 May 28 at 2:53

# Charcoal, 25 bytes

≔Ｅ⁸¹Σ↔⊖﹪⊕∕θ⁺²⁰ι²ηＩ⁺²⁰⌕η⌊η


Try it online! Link is to verbose version of code. Explanation:

  ⁸¹                        Literal integer 80
Ｅ                          Map over implicit range
θ                 Input array
∕                  Vectorised divide
ι             Current value
⁺                Plus
²⁰              Literal integer 20
⊕                   Vectorised increment
﹪                    Vectorised modulo
²            Literal integer 2
⊖                     Vectorised decrement
↔                      Vectorised absolute
Σ                       Take the sum
≔               η           Store in variable
η   List of absolute cumulative errors
⌊    Find the minimum
⌕      Find index in
η     List of absolute cumulative errors
⁺         Plus
²⁰       Literal integer 20
Ｉ          Cast to string
Implicitly print


# APL+WIN, 43 bytes

Prompts for vector of numbers in list

(m=⌊/m←+/¨|¨m-⌊¨m+1≤¨2|¨m←(⊂⎕)÷¨n)/n←19+⍳81


Try it online! Thanks to Dyalog Classic

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

a=>Enumerable.Range(20,81).OrderBy(x=>a.Sum(k=>Math.Min(2-k/x%2,k/x%2))).First()


Try it online!

# 05AB1E, 15 bytes

20тŸΣ/D1%sÉ+O}н


Explanation:

20тŸ         # Push a list in the range [20,100]
Σ        # Sort it by:
/       #  Divide the (implicit) input-list by this value
D      #  Duplicate the decimal values
1%    #  Modulo-1 to only keep the decimal portion
s      #  Swap so the entire values are at the top again
É     #  Check which ones are odd (ignoring the decimal portions)
+   #  Add the values at the same positions together
O  #  Sum this list together
}н       # After the sort-by, keep just the first element
# (so Σ...}н basically acted as a minimum-by builtin)
# (which is output implicitly as result)


# C, 122 bytes

i,j,k;f(n,m)int*n;{float a=m,b,c;for(i=19;99/i++;k=b<a?a=b,i:k)for(j=b=0;j<m;b+=fabs(c-rint(c))*2)c=n[j++]/2./i;return k;}


Try it online!

# C, 134 bytes

i,j,k;float f(n,m)int*n;{float a=m,b,c;for(i=199;999/i++;k=b<a?a=b,i:k)for(j=b=0;j<m;b+=fabs(c-rint(c))*2)c=n[j++]/.2/i;return k/10.;}


Try it online!