11
\$\begingroup\$

Expand a number

Your task is to expand an integer greater than 0 in the following manner:

Split the number into decimal digits and for each digit generate a list according to these rules:

  • if the digit is odd, the list starts with the digit and goes down to 1;
  • if the digit is even, the list starts with the digit and goes up to 9.
  • if the digit is 0, the list is empty.

Write down the lists for the odd numbers below the digits, and above for the even ones. Then top-align the columns and collect the digits in each row to make integers. As a final step add up the numbers to find the expansion of the number.

Here's an example of the above rules applied to 34607:

 9          
 8          
 79         
 68         
 57         
346 7 ->  399 7 -> 3997 -> 9418
2   6     288 6    2886
1   5     177 5    1775
    4      66 4     664
    3      5  3      53
    2      4  2      42 
    1         1       1

Here are the test cases:

1: 1
2: 44
3: 6
44: 429
217: 1270
911: 947
2345: 26114
20067: 3450
34875632: 70664504
9348765347634763: 18406119382875401

This is , so the shortest answers in bytes in each language win.

\$\endgroup\$
6
  • 1
    \$\begingroup\$ Can we take input as a string? Or as an array of digits? \$\endgroup\$
    – Arnauld
    Nov 8, 2017 at 21:56
  • \$\begingroup\$ @Arnauld It must be an integer, and to split it to digits with your program/function \$\endgroup\$ Nov 8, 2017 at 21:59
  • \$\begingroup\$ @GalenIvanov But if input is from stdin, I suppose that's ok (even though technically a string), right? \$\endgroup\$
    – Adám
    Nov 8, 2017 at 22:05
  • \$\begingroup\$ @Adám Yes, technically it's a string, so that's ok. \$\endgroup\$ Nov 9, 2017 at 6:03
  • \$\begingroup\$ And here I thought it would be an expansion like this. \$\endgroup\$ Nov 9, 2017 at 14:29

14 Answers 14

8
\$\begingroup\$

Jelly, 13 bytes

Dḟ0RrḂ?€9UZḌS

A monadic link taking and returning positive integers.

Try it online! or see the test-suite.

How?

Dḟ0RrḂ?€9UZḌS - Link: positive integer           e.g. 702
D             - cast to a decimal list                [7,0,2]
  0           - literal zero                          0
 ḟ            - filter discard                        [7,2]
        9     - literal nine
       €      - for each:
      ?       -   if:
     Ḃ        -   ...condition: bit (modulo by 2)      1              ,0
   R          -   ...then: range ([1,...n])            [1,2,3,4,5,6,7],n/a
    r         -   ...else: inclusive range ([n,...9])  n/a            ,[2,3,4,5,6,7,8,9]
         U    - upend                                 [[7,6,5,4,3,2,1],[9,8,7,6,5,4,3,2]]
          Z   - transpose                             [[7,9],[6,8],[5,7],[4,6],[3,5],[2,4],[1,3],2]
           Ḍ  - cast from decimal lists               [79,68,57,46,35,24,13,2]
            S - sum                                   324
\$\endgroup\$
4
\$\begingroup\$

Perl 6,  68  66 bytes

{sum roundrobin(.comb».&{$_%2??($_...1)!!(9...+$_) if +$_})».join}

Try it

{sum roundrobin(.comb».&{[R,] $_%2??1..$_!!$_..9 if +$_})».join}

Try it

Expanded:

{  # bare block lambda with implicit parameter 「$_」

  sum

    roundrobin( # grab from the sub lists in a round robin fashion

      .comb\             # split the input into digits
      ».&{               # for each digit do this

        [R,]             # reduce with reversed &infix:«,» (shorter than reverse)

              $_ % 2     # is the digit not divisible by 2?
          ??  1  .. $_   # from 1 to the digit
          !!  $_ ..  9   # from the digit to 9

        if +$_           # only do the above if the current digit isn't 0
                         # (has the effect of removing 0 from the list)
     }

    )».join     # join each of the sub-lists from roundrobin
}
\$\endgroup\$
3
\$\begingroup\$

APL (Dyalog), 39 bytes

Full program body. Prompts for input from STDIN. Prints result to STDOUT.

+/10⊥¨0~⍨¨↓⍉↑{2|⍵:⌽⍳⍵⋄×⍵:⌽⍵,⍵↓⍳9⋄⍬}¨⍎¨⍞

Try it online!

To display the last test case correctly, ⎕FR (Floating-point Representation) has been set to 128-bit Decimal and ⎕PP (Print Precision) has been set to 34 digits.

 prompt for text input from STDIN

⍎¨ execute each (gets each digit as a number)

{ for each element, apply the following function where the argument is represented by :

2|⍵: if odd (lit. "if" division remainder when divided by 2), then:

   reverse

   the ɩntegers from 1 until

   the argument

 else

×⍵: if the argument is positive (lit. "if" signum), then:

   reverse

   the argument

  , followed by

   argument

   elements dropped from

  ⍳9 the the ɩntegers from 1 until 9

 else

   empty list

 mix (combine) this list of lists into a single matrix, padding with zeros on the right

 transpose

 split this matrix into a list of lists

0~⍨¨ remove all zeros from each list

10⊥¨ convert each from base-10 to normal numbers (this collects the digits)

+/ sum the numbers

\$\endgroup\$
1
  • 2
    \$\begingroup\$ Thank you for your explanation. Just to let you know that I discovered code golf after watching you in the APL code golf video. \$\endgroup\$ Nov 9, 2017 at 6:13
3
\$\begingroup\$

JavaScript (ES6), 88 83 82 bytes

f=(n,k=0)=>k<9&&+[...n+''].map(x=>+x&&(x=x&1?x:9-k<x||9)>k?x-k:'').join``+f(n,k+1)

Note

9 - k < x || 9 saves a byte over 9 - k >= x && 9 but generates 1 instead of 0 if the inequality is verified. It would be a problem if it leaded to 1 > k, triggering the wrong path in the outer ternary. But it would mean that k = 0 and therefore 9 - k = 9, so we can't possibly have 9 - k < x at the same time.

Test cases

NB: Removed the last test case which exceeds JS number precision.

f=(n,k=0)=>k<9&&+[...n+''].map(x=>+x&&(x=x&1?x:9-k<x||9)>k?x-k:'').join``+f(n,k+1)

console.log(f(1))                // 1
console.log(f(2))                // 44
console.log(f(3))                // 6
console.log(f(44))               // 429
console.log(f(217))              // 1270
console.log(f(911))              // 947
console.log(f(2345))             // 26114
console.log(f(20067))            // 3450
console.log(f(34875632))         // 70664504

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

Japt, 18 bytes

ì f ®òZu ª9 wÃy xì

Try it online!

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

Java 11, 210 209 191 181 bytes

n->{long r=0;var a="0".repeat(9).split("");for(int d:(n+"").getBytes())for(int k=0,x=d-48,y=9;x>0&(k<1||(d%2<1?y-->x:x-->1));a[k++]+=d%2<1?y:x);for(var q:a)r+=new Long(q);return r;}

Ok, this took quite a while (mainly because I made a mistake at first, so had to write down each step to better understand what I did wrong). Can most likely be golfed some more.

-18 bytes thanks to @ceilingcat.

Explanation:

Try it here.

n->{                             // Method with long as both parameter and return-type
  long r=0;                      //  Result-long `r`, starting at 0
  var a="0".repeat(9).split(""); //  String array `a`, filled with nine String zeroes
  for(int d:(n+"").getBytes())   //  Cast the input to a String,
                                 //   and loop over its codepoints as integers:
    for(int k=0,                 //   Row-index `k`, starting at
        x=d-48,                  //   Temp integer `x`, set to the current digit
        y=9                      //   Temp integer `y`, set to 9
        ;                        //   Inner loop, if:
         x>0                     //     The current digit is not a 0,
          &(k<1                  //     and if this is the first iteration,
             ||(d%2<1?           //     or if the digit is even:
                 y-->x           //      And `y` is larger than the digit
                                 //      (and afterwards decrease `y` by 1 with `y--`)
                :                //     or if the digit is odd:
                 x-->1));        //      And `x` is larger than 1
                                 //      (and afterwards decrease `x` by 1 with `x--`)
      a[k++]+=                   //    Append the current row with:
                                 //    (and afterwards increase `k` by 1 with `k++`)
       d%2<1?                    //     If the digit is even:
        y                        //      Append the row with `y`
       :                         //     Else (the digit is odd):
        x);                      //      Append the row with `x`
  for(var q:a)                   //  Loop over the String rows in the array:
    r+=new Long(q);              //   Convert it to a long, and add it to the result-sum
  return r;}                     //  Return the result
\$\endgroup\$
0
2
\$\begingroup\$

Pip, 28 bytes

J_MS(RV{a?a%2?\,aa,tl}Ma)ZDx

Try it online!

Explanation

                      Ma      Map this function to the digits of the 1st cmdline arg:
        a?                     If digit != 0:
          a%2?                  If digit is odd:
              \,a                Inclusive-range(digit)
                 a,t            Else (digit is even), range from digit to 10 (exclusive)
                    l          Else (digit is 0), empty list
     RV{             }         Apply reverse to the result before returning it
                              This gives us a list of lists like [9 8 7 6] or [3 2 1]
    (                   )ZDx  Zip, with a default value of empty string
J_MS                          Use map-sum to join each sublist and sum the results
                              Autoprint (implicit)

How the steps proceed with 34607 as the argument:

34607
[[1 2 3] [4 5 6 7 8 9] [6 7 8 9] [] [1 2 3 4 5 6 7]]
[[3 2 1] [9 8 7 6 5 4] [9 8 7 6] [] [7 6 5 4 3 2 1]]
[[3 9 9 "" 7] [2 8 8 "" 6] [1 7 7 "" 5] ["" 6 6 "" 4] ["" 5 "" "" 3] ["" 4 "" "" 2] ["" "" "" "" 1]]
[3997 2886 1775 664 53 42 1]
9418
\$\endgroup\$
2
\$\begingroup\$

Pyth - 23 bytes

siRT.Tm*!!d@,}9d}d1dsMz

Test Suite.

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

Haskell, 106 104 bytes

import Data.List
f n=sum$map read$transpose$[reverse$[[c..'9'],['1'..c]]!!mod(read[c])2|c<-show n,c>'0']

Try it online!

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

R, 153 146 bytes

function(n,m=n%/%10^(nchar(n):0)%%10)sum(strtoi(apply(sapply(m[m>0],function(x)c(r<-"if"(x%%2,x:1,9:x),rep("",9-sum(r|1)))),1,paste,collapse="")))

Try it online!

Sometimes, I can't tell if I'm just garbage at golfing, or if R is.... It's definitely me, saved 7 bytes thanks to user2390246, who reminded me of another way to extract digits (that I suggested myself).

You may replace strtoi with as.double to get 18406718084351604 for the last test case (which is wrong); R only has 32-bit integers.

\$\endgroup\$
2
  • \$\begingroup\$ You can save a bit by taking n as an integer and converting to digits using one of your tricks! 146 bytes \$\endgroup\$ Nov 9, 2017 at 13:50
  • \$\begingroup\$ @user2390246 you know, I tried that, but I think I was fixated on using the implicit conversion to character->int when I called : and then used strtoi anyway! \$\endgroup\$
    – Giuseppe
    Nov 9, 2017 at 14:10
1
\$\begingroup\$

Perl 5, 120 + 1 (-a) = 121 bytes

$p=y/01357/ /r;$n=y/02468/ /r;map{$p=~s/9/ /g;$p=~s/\d/$&+1/ge;$n=~s/\d/$&-1/ge;$n=~s/0/ /g;@F=($p,@F,$n)}0..7;say for@F

Try it online!

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

Python 2, 131 bytes

lambda n:sum(int(''.join(`n`for n in l if n))for l in map(None,*[range(n and(n%2*n or 9),(n%2<1)*~-n,-1)for n in map(int,`n*10`)]))

Try it online!

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

05AB1E, 16 bytes

0KεDÈi9ŸëL]íõζJO

Try it online or verify all test cases.

Or alternatively:

0KεDÈ8*>Ÿ{R}õζJO
0Kε9Ÿ¬L‚yèR}õζJO

Explanation:

0K        # Remove all 0s from the (implicit) input-integer
  ε       #  Map each digit to:
   D      #   Duplicate the digit
    Èi    #   If it's even:
      9Ÿ  #    Pop and push a list in the range [digit, 9]
     ë    #   Else (the digit is odd):
      L   #    Pop and push a list in the range [1, digit]
  ]       # Close both the if-else statement and map
   í      # Reverse each inner ranged list
     ζ    # Zip/transpose, swapping rows and columns,
    õ     # with an empty string as filler
      J   # Join each inner list together
       O  # And sum that list
          # (after which the result is output implicitly)
\$\endgroup\$
1
\$\begingroup\$

Burlesque, 39 bytes

riXX:nz{J2dv{{9r@}{ro}}che!<-}m[tp)im++

Try it online!

ri      #Read as int
XX      #Return list of digits
:nz     #Filter for non-zero
{
 J2dv   #Divisible by 2?
 {
  {9r@} #Range a, 9
  {ro}  #Range 1, a
 }che!  #Run based on if divisible
 <-     #Reverse the range
}m[     #Apply to each digit
tp      #Transpose digits
)im     #Join each list into single int
++      #Sum each int
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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