g | x | w | all
Bytes Lang Time Link
150AWK241103T160530Zxrs
020Uiua241102T142930Znyxbird
nan200520T094929ZAsone Tu
017Jelly210315T231035ZUnrelate
077JavaScript Node.js200524T190801Zl4m2
096Python 3200520T225255Zlynn
100R200520T214511ZDominic
027GNU APL200520T014736ZJarmex
02005AB1E200520T110756ZKevin Cr
024MATL160302T110840ZLuis Men
131Python 3160302T091102ZErwan
025Pyth160302T091412ZJakube
093JavaScript ES6160302T093127ZNeil

AWK, 150 bytes

{gsub(/[46890]/,0);gsub(/[12357]/,1)
for(l=-NF;i++<NF;d[i]=i-l)0~$i&&l=i
l=2*NF
for(i=NF;i;i--){0~$i&&l=i
d[i]>l-i&&d[i]=l-i}for(;k++<NF;)printf d[k]}
{gsub(/[46890]/,0);gsub(/[12357]/,1)    # convert to binary string
for(l=-NF;i++<NF;d[i]=i-l)              # change digit to distance
0~$i&&l=i                               # check for 0
l=2*NF                                  # doing pass in reverse
for(i=NF;i;i--){0~$i&&l=i               # check for zero
d[i]>l-i&&d[i]=l-i}                     # use shorter distance
for(;k++<NF;)printf d[k]}               # print new string

Uiua, 20 bytes

/+≡/↧⌵⊞-⊙⊚°⊏∈"04689"

Try it

/+≡/↧⌵⊞-⊙⊚°⊏∈"04689"
              ∈"04689" # get per-digit membership within "04689"
            °⊏         # get indices
         ⊙⊚           # and locations of members
     ⌵⊞-              # tabulate with absolute difference
  ≡/↧                  # find the minimum difference for each digit
/+                     # sum

Uiua's /↧ reduce minimum defaults to on empty arrays.

Ruby (2.7+), 69 63 chars, 71 65 bytes

->n{x=!r=l=0;n.map{'04689'[_1]?x=l=0*r-=l*l/4:r+=l+=1};x ?r:?∞}

Unsupported by TIO

Ruby (other), 71 65 chars, 73 67 bytes

->n{x=!r=l=0;n.map{|c|'04689'[c]?x=l=0*r-=l*l/4:r+=l+=1};x ?r:?∞}

Try it online!

How it works:

*turns out this number depends only on the current value of the increment (l in the code), it's OEIS A002620 (quarter squares) (l*l/4 in the code).

Returns the character in case of infinity.

Interesting trick: x=l=0*r-=l*l/4 is equivalent to (r-=l*l/4;x=l=0) but using * instead of ; makes it a single statement allowing () to be dropped.

Edit: changed input type, now takes a list of characters.

Jelly, 18 17 bytes

Dµ+ỊẒµ¬TạþTṂ€µ»İS

Try it online!

-1 thanks to Jonathan Allan

Did a lot of fiddling with compressed strings and ȷ literals before I realized that division by zero gives infinity. Takes input as an integer, since conversion to a digit list is one byte shorter (D versus V€)--and since half of the test cases have leading zeroes, which the spec also guarantees an integer-input solution never has to handle, here's the string version as well.

Jonathan Allan's golf cleverly avoids having to distinguish two different sources of zeroes by not finding the distances between holy digits and themselves.

Dµ                   Consider the decimal digits of the input.
  +Ị                 Increment 0s to 1s and 1s to 2s.
    Ẓ                For each digit, is it prime?
     µ               With this list of 0s for holy digits and 1s for holy digits,
        ạþ           table the absolute differences between
      ¬T             the indices of holy digits
          T          and the indices of unholy digits.
           Ṃ€        Take the minimum from each row,
                S    and sum
              »      the maxima of those minima and
             µ İ     their inverses.

JavaScript (Node.js), 77 bytes

s=>s.reduce((m,c,i)=>m+Math.min(...s.map(c=>(i*i--)**.5+(174&1<<c?1/0:0))),0)

Try it online!

Python 3, 96 bytes

lambda s:sum(min([9e999]+[abs(i-j)for j,c in enumerate(s)if c in'04689'])for i in range(len(s)))

Try it online!

R, 100 bytes

sum(sapply(0:(d=log10(n<-scan()))+1,function(x)min(abs(x-which(n%/%10^(0:d)%%10%in%c(0,4,6,8,9))))))

Try it online!

GNU APL, 27 bytes

{+/⌊/|(⍳⍴⍵)∘.-(⍵⍳⍕⍟788)~⍴⍵}

Try it online!

To try it out using the above link, IO must be set to 0 and the input is provided as a string. For example:

⎕IO←0
{+/⌊/|(⍳⍴⍵)∘.-(⍵⍳⍕⍟788)~⍴⍵}'017552857'

Explanation

{+/⌊/|(⍳⍴⍵)∘.-(⍵⍳⍕⍟788)~⍴⍵}  ⍝ Note: below explanation uses as example input 017552857 
{                            ⍝ dfn
                  ⍟788       ⍝ computes natural log of 788, which happens to be 6.66949809, containing only (and all) holy digits
                 ⍕           ⍝ Converts this number to a string
               ⍵⍳            ⍝ Finds the indexes of chars in the right argument ⍵ which are present in the computed decimal. Items not found map to the length of the list, e.g. '017552857'⍳'6.66949809' -> 9 9 9 9 9 9 9 6 0 9
                      ~⍴⍵    ⍝ Removed all non-found indexes from the list 9 9 9 9 9 9 9 6 0 9 -> 6 0
      (⍳⍴⍵)                  ⍝ List of ascending integers up the length of the argument ⍵: 0 1 2 3 4 5 6 7 8
           ∘.-               ⍝ Inner product of the ascending integers 0..8 minus the match indexes 6 0. Result is ¯6 0, ¯5 1, .., 2 8
     |                       ⍝ Absolute value of all elements
   ⌊/                        ⍝ Take the minimum of each pair to get the closest distance to a Holy number 0 1 2 3 2 1 0 1 2
 +/                          ⍝ Sum this list

The reason for choosing GNU APL is that handily it will return the internal representation of infinity, '∞', when calculating the minimum value of the empty list. Summing this still retains ∞, which is then returned.

⍟788 was a cheeky way to lose a byte. I ended up writing a program to brute force inputs to functions until I found a suitable result which contained only holy numbers. Brute force program below:

    (,(⍳99)∘.{∧/(~'12357'∊c),'04689'∊(c←⍕b←⍺÷⍵):(⍺,'f',⍵,'=',b,'|') ⋄ 0}⍳99)~0

In this case it sees if any values of ⍺÷⍵ in 0 < ⍺,⍵ < 100 meet the condition. I manually played around with the functions to test.

It's a bit of a shame that this challenge doesn't allow undefined behaviour for the infinity case or that Dyalog doesn't return an infinite data type instead of throwing an error, otherwise the following solution would work in Dyalog APL:

APL (Dyalog Unicode), 23 bytes

{+/⌊/|(⍳⍴⍵)∘.-⍸⍵∊⍕⍟788}

Try it online!

05AB1E, 20 bytes

ŽāĀISåƶZĀiāδαø€ßOë'∞

Try it online or verify all test cases.

Explanation:

ŽāĀ                # Push compressed integer 40689
   IS              # Push the input-string, converted to a list of digits
                   #  i.e. "085281755283" → [0,8,5,2,8,1,7,5,5,2,8,3]
     å             # Check for each digit if it's in 40689 (1 if truthy; 0 if falsey)
                   #  → [1,1,0,0,1,0,0,0,0,0,1,0]
      ƶ            # Multiply each value by its 1-based index
                   #  → [1,2,0,0,5,0,0,0,0,0,11,0]
       Z           # Push the maximum of this list (without popping)
                   #  → 11
        Āi         # If this maximum is not 0 (so there are holy digits present):
                   #   → 1 (truthy)
          ā        #  Push a list in the range [1, list-length] (without popping the list)
                   #   → [1,2,3,4,5,6,7,8,9,10,11,12]
           δ       #  Apply double-vectorized:
            α      #   Take the absolute difference between each value
                   #    → [[0,1,2,3,4,5,6,7,8,9,10,11],[1,0,1,2,3,4,5,6,7,8,9,10],
                   #       [1,2,3,4,5,6,7,8,9,10,11,12],[1,2,3,4,5,6,7,8,9,10,11,12],
                   #       [4,3,2,1,0,1,2,3,4,5,6,7],[1,2,3,4,5,6,7,8,9,10,11,12],
                   #       [1,2,3,4,5,6,7,8,9,10,11,12],[1,2,3,4,5,6,7,8,9,10,11,12],
                   #       [1,2,3,4,5,6,7,8,9,10,11,12],[1,2,3,4,5,6,7,8,9,10,11,12],
                   #       [10,9,8,7,6,5,4,3,2,1,0,1],[1,2,3,4,5,6,7,8,9,10,11,12]]
             ø     #  Then zip/transpose the list of lists; swapping rows/columns
                   #   → [[0,1,1,1,4,1,1,1,1,1,10,1],[1,0,2,2,3,2,2,2,2,2,9,2],
                   #      [2,1,3,3,2,3,3,3,3,3,8,3],[3,2,4,4,1,4,4,4,4,4,7,4],
                   #      [4,3,5,5,0,5,5,5,5,5,6,5],[5,4,6,6,1,6,6,6,6,6,5,6],
                   #      [6,5,7,7,2,7,7,7,7,7,4,7],[7,6,8,8,3,8,8,8,8,8,3,8],
                   #      [8,7,9,9,4,9,9,9,9,9,2,9],[9,8,10,10,5,10,10,10,10,10,1,10],
                   #      [10,9,11,11,6,11,11,11,11,11,0,11],[11,10,12,12,7,12,12,12,12,12,1,12]]
              ۧ   #  Get the minimum of each inner list
                   #   → [0,0,1,1,0,1,2,3,2,1,0,1]
                O  #  And sum everything together
                   #   → 12
         ë         # Else (no holy digits are present)
          '∞      '#  Push string "∞" instead
                   # (after which the top of the stack is output implicitly as result)

See this 05AB1E tip of mine (section How to compress large integers?) to understand why ŽāĀ is 40689.

MATL, 25 24 bytes

7Zq1hVmt~f!wf-|X<st~?xYY

Try it online!

Input is a string. In the output, infinity is natively displayed as Inf.

Explanation

7         % number literal                                 
Zq        % prime numbers up to a 7: [2 3 5 7]
1         % number literal                        
h         % horizontal concatenation                       
V         % convert numbers to string: '2  3  5  7  1'
m         % take input implicitly. Determine which digits are 1,2,3,5,7
t         % duplicate
~         % element-wise negate: which digits are 4,6,8,9,0
f         % indices of occurrences of digits 4,6,8,9,0
!         % transpose into column array
w         % swap elements in stack           
f         % indices of occurrences of digits 1,2,3,5,7  
-         % element-wise subtraction with broadcast. Gives 2D array
|         % element-wise absolute value                          
X<        % minimum of each column
s         % sum of elements of array
t         % duplicate                       
~         % element-wise negate
?         % if all elements are true                            
  x       %   delete                                         
  YY      %   push infinity                                       
          % (implicit) end if
          % (implicit) convert to string and display  

Python (3), 137 131 bytes

def f(s):
 l=range(len(s))
 r=[min(i)for i in zip(*[[abs(j-i)for j in l]for i in l if s[i]in'46890'])]
 return sum(r)if r else'∞'

Results

>>> [f(i) for i in ['85587', '012321857', '157321', '04689']]
[3, 12, '∞', 0]

Pyth, 31 29 27 25 bytes

smhS.e?}b"04689"akd.n4zUz

Try it online: Demonstration or Test Suite

For each digit I compute the distances to each number. A distance is infinty, if the second digit is not holy. From these lists I take the minimal distance and sum it up.

Explanation:

smhS.e?}b"04689"akd.n4zUz  implicit: z = input string of numbers
 m                     Uz  map each d in [0, 1, ..., len(z)-1] to:
    .e                z      map each k (index), b (value) of b to:
                akd            absolute difference between k and d

      ?}b"04689"               if b in "04689" else
                   .n4         infinity
   S                           sort
  h                            take the first element (=minimum)
s                              print the sum

JavaScript (ES6), 93 bytes

s=>[...s].map(n=>/[12357]/.test(n)?++u:u=0,u=1/0).reverse().map(n=>r+=n?n<++u?n:u:u=0,r=0)&&r

If Infinity isn't a legal infinity, then add 13 bytes for ==1/0?'∞':r.