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\$
  • 1
    \$\begingroup\$ Can we take input as a string? Or as an array of digits? \$\endgroup\$ – Arnauld Nov 8 '17 at 21:56
  • \$\begingroup\$ @Arnauld It must be an integer, and to split it to digits with your program/function \$\endgroup\$ – Galen Ivanov Nov 8 '17 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 '17 at 22:05
  • \$\begingroup\$ @Adám Yes, technically it's a string, so that's ok. \$\endgroup\$ – Galen Ivanov Nov 9 '17 at 6:03
  • \$\begingroup\$ And here I thought it would be an expansion like this. \$\endgroup\$ – Engineer Toast Nov 9 '17 at 14:29

12 Answers 12

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
    \$\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\$ – Galen Ivanov Nov 9 '17 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\$
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\$

Java 8, 210 209 bytes

n->{long r=0;String[]a=new String[9];int i=0,k,x,y;for(;i<9;a[i++]="0");for(int d:(n+"").getBytes())for(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(String 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.

Explanation:

Try it here.

n->{                            // Method with long as both parameter and return-type
  long r=0;                     //  Result-long, starting at 0
  String[]a=new String[9];      //  String-array of length 9, initially all are `null`
  int i=0,k,                    //  Index-integers
      x,y;                      //  Temp-integers
  for(;i<9;                     //  Loop (1) from 0 to 9 (exclusive)
    a[i++]="0"                  //   Fill the array with nine String zeroes
  );                            //  End of loop (1)
  for(int d:(n+"").getBytes())  //  Loop (2) over the digits of the input
    for(k=0,                    //   Reset row-index `k` to 0
        x=d-48,                 //   Set `x` to the current digit
        y=9                     //   Set `y` to 9
        ;                       //   Inner loop (3) 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`
    );                          //   End of inner loop (3)
                                //  End of loop (2) (implicit / single-line body)
  for(String q:a)               //  Loop (4) over the String rows in the array
    r+=new Long(q);             //   Convert it to a long, and add it to the result
                                //  End of loop (4) (implicit / single-line body)
  return r;                     //  Return the result
}                               // End of method
\$\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\$
  • \$\begingroup\$ You can save a bit by taking n as an integer and converting to digits using one of your tricks! 146 bytes \$\endgroup\$ – user2390246 Nov 9 '17 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 '17 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\$

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.