15
\$\begingroup\$

Description

You have a list of integers and start counting from the first term to the next and continue from that to the next and so on..
How many times have you counted?

For example given [ 2, 5, 3, 8 ]
you start at 2 and count to 5 -> 3 4 5 (3 times)
then from 5.. 4 3 (2 times)
and finally 4 5 6 7 8 (5 times)
You counted 10 times.

With ragged lists, when you have a sublist just count the sublist and use that result.

for example [ 1, [ 3, 6 ] ]
1 to ( count[ 3, 6 ] ->3 )
1 to 3 -> 2

For empty lists you count 0 times, the same applies for lists of one element or lists of equal elements.
[ ] -> 0
[ 99 ] -> 0
[ 8, 8, 8 ] -> 0

Task
Given a ragged list of non negative integers count it as described above.

Test cases

[] -> 0
[[2,5]] -> 0
[99] -> 0
[8,8,8] -> 0
[1,1] -> 0
[0,9] -> 9
[2,5,3,8] -> 10
[1,[3,6]] -> 2
[[],4,[[5,3],2]] -> 8
[100,100,[7,[[[6]]]],[[4,8]]] -> 100
[[9,5],0] -> 4
[[],[]] -> 0
[[],3,[]] -> 6
[1,[2,5,10]] -> 7
[2,6,9] -> 7
[[1,2],[1,3],[1,4]] -> 2
[1,99] -> 98
[11,9,6] -> 5
[0,1,2,3,4] -> 4
[2,3,3,3,2] -> 2
[0,1,0,1] -> 3

This is , all usual golfing rules apply.

\$\endgroup\$
0

14 Answers 14

6
\$\begingroup\$

Haskell + free, 36 bytes

iter$sum.map abs.(zipWith(-)<*>tail)

Try it online!

To represent a ragged list we use a free monad. Then this process is just iteration. Our iterative step is sum.map abs.(zipWith(-)<*>tail) which calculates the absolute differences and then sums them.

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

Jelly, 11 10 bytes

߀IASƲ⁸ŒḊ?

Try it online!

Walkthrough

         ?   If
       ŒḊ    Depth (of input) != 0?
 €                Foreach
ß                     call this link
  I               consecutive differences
   A              Absolute of each
    SƲ           sum
      ⁸      If == 0? return the link argument
\$\endgroup\$
1
  • 2
    \$\begingroup\$ Welcome to Code Golf, and nice answer! \$\endgroup\$ Jan 27 at 5:22
5
\$\begingroup\$

R, 87 86 bytes

Edit: -1 byte thanks to pajonk

f=function(l,`+`=sapply)`if`(length(m<-l+is.list),{l[m]=l[m]+f;sum(abs(diff(l+c)))},0)

Try it online!

Ungolfed

f=function(l){                  # argument = l = ragged list
  m=sapply(l,is.list)           # m = elements of l that themselves are lists
  if(length(l)){                # if l isn't an empty list
    l[m]=sapply(l[m],f)         #   replace its list elements by recursive call
    sum(abs(diff(unlist(l)))    #   and now count from each to the next and so on
  } else 0                      # otherwise ( it's an empty list ) return zero.

Note: we use sapply twice above, so to save bytes we re-assign the + infix operator as sapply. Once we've done that, we might as well use it wherever we can: unlist() is a bit long, so instead we can sapply the identity function c() to all elements of a list, to get them unlisted: hence l+c instead of unlist(l)....

\$\endgroup\$
2
  • \$\begingroup\$ -1 byte. Also, could you please add some explanation? I don't quite grasp the l+c trick. \$\endgroup\$
    – pajonk
    Jan 28 at 18:59
  • \$\begingroup\$ @pajonk - Thanks & explanation added. \$\endgroup\$ Jan 28 at 22:59
5
\$\begingroup\$

Vyxal, 9 bytes

λIȧ[vx¯ȧ∑

Try it Online!

-1 thanks to lyxal.

Or if we can assume no empty lists, 8 bytes:

λ-[vx¯ȧ∑

Try it Online!

Both are essentially the same, just with different is_array checks.

λ          # Create a recursive lambda...
  - [      # If the input is a list...
  -        # int - int = 0 (falsy), lst - lst = list of zeros, truthy
 Iȧ        # If n is int, remove_whitespace(" " * n) which is falsy.
           # If n is list, split into two halves and take the absolute value.
     vx    # Call the lambda on each element of the list
       ¯   # Get differences between pairs of elements
        ȧ  # Take the absolute value of those
         ∑ # Sum
\$\endgroup\$
3
  • 1
    \$\begingroup\$ @KevinCruijssen Fixed. \$\endgroup\$
    – emanresu A
    Jan 27 at 19:10
  • \$\begingroup\$ ƛ;⁼ -> for -1 \$\endgroup\$
    – lyxal
    Mar 16 at 13:00
  • \$\begingroup\$ @lyxal Nice! I'll add that to the tip. \$\endgroup\$
    – emanresu A
    Mar 16 at 19:08
4
\$\begingroup\$

Python, 68 bytes

f=lambda x:sum(abs(f(j)-f(k))for j,k in zip(x,x[1:]))if 0!=x*0else x

Try it online!

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

Wolfram Language (Mathematica), 33 bytes (@att)

Tr@Abs@Differences@{##}&@@#&//@#&

Try it online!


Wolfram Language (Mathematica), 35 bytes

Map[Tr@*Abs@*Differences,#,{0,-2}]&

Try it online!


Wolfram Language (Mathematica), 35 bytes

#/.x:List->Tr@*Abs@*Differences@*x&

Try it online!

\$\endgroup\$
1
  • 2
    \$\begingroup\$ 33 bytes \$\endgroup\$
    – att
    Jan 27 at 7:33
3
\$\begingroup\$

Retina 0.8.2, 72 bytes

\d+
$*
\[
<;
{`(<1*);(1*)(1*),\2(1*)(,|])
$1$3$4;$2$4$5
}`<(1*);1*]
$1
1

Try it online! Link includes test cases. Explanation:

\d+
$*

Convert to unary.

\[
<;

Place markers at the start of each sublist.

{`
}`

Repeat until no more replacements can be made.

(<1*);(1*)(1*),\2(1*)(,|])
$1$3$4;$2$4$5

If a sublist starts with two integers, then remove the first and insert the difference before the marker, which tracks the cumulative absolute total.

<(1*);1*]
$1

When a sublist runs out of integers then simply replace it with its total.

1

Convert to decimal.

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

Charcoal, 56 bytes

⊞υθFυFιF⁼κ⁺⟦⟧κ⊞υκWυ«≔⊟υι≔⟦⟧ηWι⊞ηΣ⁺⟦⁰⟧⊟ι⊞ι↨EΦηλ↔⁻κ§ηλ¹»Iθ

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

⊞υθFυ

Start extracting all of the sublists.

FιF⁼κ⁺⟦⟧κ⊞υκ

Loop over all the lists and when a sublist is found then push it to the predefined empty list.

Wυ«

Process all of the sublists.

≔⊟υι

Get the deepest remaining sublist.

≔⟦⟧η

Start collecting the terms in this sublist.

Wι⊞ηΣ⁺⟦⁰⟧⊟ι

Remove the terms from the list and push their numeric value to the temporary list. Any sublists will have been reduced to their count as a single term [n] at this point, so prepending [0] results in [0, n] and taking the sum returns n, while adding [0] to an integer n results in [n] and then taking the sum returns n again.

⊞ι↨EΦηλ↔⁻κ§ηλ¹

Compute the absolute pairwise differences and push the total to the list.

»Iθ

Output the final total of the original list.

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

JavaScript, 60 52 bytes

f=(a,t=0)=>p=a.map?.(p=x=>t+=Math.abs(p-f(x)|0))?t:a

f=(a,t=0)=>p=a.map?.(p=x=>t+=Math.abs(p-f(x)|0))?t:a

console.log(f([]))
console.log(f([[2,5]]))
console.log(f([99]))
console.log(f([8,8,8]))
console.log(f([1,1]))
console.log(f([0,9]))
console.log(f([2,5,3,8]))
console.log(f([1,[3,6]]))

Saved 8 bytes thanks to tsh.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ f=(a,t=0)=>p=a.map?.(p=x=>t+=Math.abs(p-f(x)|0))?t:a \$\endgroup\$
    – tsh
    Jan 27 at 5:39
3
\$\begingroup\$

SWI-Prolog, 123 105 bytes

[]+0.
[_]+0.
[H,S|T]+C:-(is_list(H)->H+G;G is H),(is_list(S)->S+Q;Q is S),D is abs(Q-G),[S|T]+R,C is D+R.

-18 bytes thanks to Wheat Wizard!

Try it online!

\$\endgroup\$
4
  • \$\begingroup\$ Can't f be an infix? \$\endgroup\$
    – Wheat Wizard
    Jan 27 at 9:37
  • \$\begingroup\$ Try it online! \$\endgroup\$
    – Wheat Wizard
    Jan 27 at 10:00
  • \$\begingroup\$ @WheatWizard I... never learned about infixes... I should probably read the Prolog tips thread, huh? Thanks! \$\endgroup\$
    – hakr14
    Jan 27 at 17:50
  • \$\begingroup\$ Think you can also shorten the base case somewhat. \$\endgroup\$ Mar 17 at 8:43
1
\$\begingroup\$

Ruby, 75 bytes

f=->a{a*0==0?a:([a[0]]*(a.size%2)+a).map(&f).each_cons(2).sum{(_2-_1).abs}}

Attempt This Online!

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

05AB1E, 21 bytes

"ИÊi®δ.V}ИQi¥ÄO"©.V

Ugh.. :/

Try it online or verify all test cases.

Explanation:

"..."        # Define the recursive string below
     ©       # Store it in variable `®` (without popping)
      .V     # Evaluate and execute it as 05AB1E code, using the (implicit)
             # input-list as argument
             # (after which the result is output implicitly)

Ð˜Ê          #  Check if there is an inner list:
Ð            #   Triplicate the current list
 ˜           #   Flatten it
  Ê          #   Check if the top two lists are NOT the same
   i         #  If this is truthy:
     δ       #   Map over each inner item:
    ® .V     #    Do a recursive call
   }         #  After the if-statement, whether we executed its body or not:
    ИQ      #  Check if this is a 1D list:
    Ð        #   Triplicate the current list
     ˜       #   Flatten it
      Q      #   Check if the top two lists are equal
       i     #  If this is truthy:
        ¥    #   Pop the list, and push its deltas/forward-differences
         Ä   #   Convert each to its absolute value
          O  #   And then sum this list
\$\endgroup\$
1
\$\begingroup\$

Python NumPy, 69 bytes

f=lambda s:sum(abs(s*-1or diff([*map(f,s or[])])))
from numpy import*

Attempt This Online!

I suspect it's 66 bytes in Python2 but have no way of checking.

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

Perl 5, 88 bytes

sub f{$_=pop;1while s!\[[\d,]*\]!@a=$&=~/\d+/g;0+sum map abs$a[$_-1]-$a[$_],1..$#a!e;$_}

Try it online!

\$\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.