13
\$\begingroup\$

Write a program that takes two integers as an input; the first can be any integer and the second is less than or equal to the number of digits in the first number. Let these numbers be a and b respectively.

The program will do the following

  • Concatenate a minimal number of 1s to the end of a so the number of digits in a is divisible by b.
  • Split a along every b digits.
  • Multiply the digits in each section together.
  • Concatenate the products together (if one of the numbers is zero, then concatenate 0).
  • Repeat this process until a number with strictly fewer than b digits is formed. Print this as the output, as well as the number of the process is repeated. Units are not necessary, but some form of separation between the final number and number of iterations is.

In the following test cases, the individual steps are shown for the purpose of understanding. It is not necessary for your program to display the steps.

Test case 1

1883915502469, 3

Steps

1883915502469          //Iteration 1
188391550246911
188 391 550 246 911
64 27 0 48 9
64270489               //Iteration 2
642704891
642 704 891
48 0 72
48072                  //Iteration 3
480721
480 721
0 14
014                    //Iteration 4
0

Sample Output: 0, 4

Test case 2

792624998126442, 4

Steps

792624998126442        //Iteration 1
7926249981264421
7926 2499 8126 4421
756 648 96 32
7566489632             //Iteration 2
756648963211
7566 4896 3211
1260 1728 6
126017286              //Iteration 3
126017286111
1260 1728 6111
0 112 6
01126                  //Iteration 4
01126111
0112 6111
0 6
06

Sample Output: 06, 4


The program must return an error (or just not print anything) if b>len(a). Also, b cannot equal 1 or the program will result in an infinite loop.


This is code golf, so standard rules apply. Shortest code in bytes wins.

\$\endgroup\$
5
  • \$\begingroup\$ Does it need to be a complete program, or is a function enough? \$\endgroup\$
    – Ypnypn
    Commented Nov 3, 2015 at 16:01
  • \$\begingroup\$ @Ypnypn A complete program. \$\endgroup\$
    – Arcturus
    Commented Nov 3, 2015 at 16:02
  • \$\begingroup\$ So leading zeros count towards the length of a and are also included in the output? \$\endgroup\$
    – mbomb007
    Commented Nov 3, 2015 at 22:44
  • \$\begingroup\$ @mbomb007 Yes, but only in the initial number. The chain of zeroes would be shortened to single zeroes in the concatenation of products. \$\endgroup\$
    – Arcturus
    Commented Nov 4, 2015 at 3:04
  • \$\begingroup\$ @ypnypn you should say that explicitly in the question. The "standard rules"from the tag wiki say "the following defaults ... Answers may be either full programs or functions (or equivalent)." \$\endgroup\$ Commented Nov 7, 2015 at 1:15

6 Answers 6

3
\$\begingroup\$

Python, 156 bytes

g=lambda a,d,c=0,k=-1,j=''.join:d>(l:=len(a))and(a,c/c*c)or g(j([str(-[k:=k*x for x in map(int,j((a+l%d*"1")[i:i+d]))][k:=-1])for i in range(0,l,d)]),d,-~c)

Attempt This Online!

Takes in a string and an integer, causes a DivideByZero error if the input is invalid.


Python 3 + functools + operator, 137 bytes

g=lambda a,d,c=0,j=''.join:d>(l:=len(a))and(a,c/c*c)or g(j([str(reduce(mul,map(int,j((a+l%d*"1")[i:i+d]))))for i in range(0,l,d)]),d,-~c)

Attempt This Online!

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

Perl 6, 116 bytes

my ($a,$b)=@*ARGS;for 0..* {if $b>$a.chars {$_&&say "$a,$_";last};$a=map({[*] @_},($a~1 x$b-1).comb.rotor($b)).join}
my ($a,$b)=@*ARGS;
for 0..* {
  if $b>$a.chars {$_&&say "$a,$_";last}; # you need a 「;」 if you remove the newline
  $a=map(
    {[*] @_},
    ($a~1 x$b-1).comb.rotor($b)
  ).join
}
\$\endgroup\$
2
+500
\$\begingroup\$

Python 3 + functools + operator, 242 241 205 bytes

Shorter version (thanks 97.100.97.109!)

def g(a,b):
 c,d,j=0,int(b),''.join
 while len(a)>=d:a=j(map(str,[reduce(mul,map(int,[*j(u)]))for u in zip(*[iter([a+"1"*n for n in range(d)if not len(a+"1"*n)%d][0//(d<=len(a))])]*d)]));c+=1
 return (a,c)

Original explained version:

def g(a,b):
 c=0
 while len(a)>=int(b):a="".join(map(str,[reduce(mul,map(int,u))for u in map(list,map(''.join,zip(*[iter([a+"1"*n for n in range(int(b))if not len(a+"1"*n)%int(b)][0])]*int(b))))]));c+=1
 return None if int(b)>len(a)else(a,c)

This was a fun one! I wish I could've made it a one-liner but there was no real way to do that without massively increasing the length. Takes input as two strings, returns a 2-tuple of a string and an int (or None if b>len(a))

Explanation

def challenge(a,b):
  c=0
  while len(a) >= int(b):
    a="".join(
      map(str,[
        reduce(mul,map(int,u)) # Multiply the digits together. Uses reduce from functools and mul from operator, works similarly to sum() but for multiplication
        for u in map(list,map(''.join,
                              zip(*[iter(
                                [a+"1"*n for n in range(int(b)) if not len(a+"1"*n)%int(b)][0] # Do the 1 concatenation
                              )]*int(b))
                             ) # Split a along every b digits
                    ) # Split those strings into lists
      ]) # Convert to a list of strings
    ) # Concatenate the products together
    c+=1
  return None if int(b)>len(a) else(a,c) # I don't really like the "return None if invalid input" requirement, but ah well
\$\endgroup\$
3
1
\$\begingroup\$

CJam, 42 bytes

q~:N;Ab{_N(>}{_N/)N1e]a+::*s:~}w])S@,_])g*

Test it here.

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

Pyth, 32 bytes

IglzQf<l=zjk*MsMMc+z*\1%_lzQQQ)z

Demonstration

Takes input on two lines, a followed by b. Gives output on two lines, operations followed by result.

Pad: +z*\1%_lzQ

Chop: c ... Q

Convert to list of ints: sMM

Take products: *M

Convert back to str: jk

Assign back: =z

Check for termination: <l ... Q

Print iterations taken: f ... )

Print result: z

Initial check of whether to print anything at all: IglzQ

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

Ruby, 139 bytes

f=->n,b,i=1{c=[*n.scan(/.{#{b=b.to_i}}/),*$'[0]&&$'.ljust(b,?1)].map{_1.chars.map(&:to_i).reduce:*}*""
c.size<b ?[c,i]:f[c,b,i+1]}
p f[*$*]

Attempt This Online!

Explanation

f = ->n,b,i=1{                    # Recursive lambda definition; n is the number, b is the target length, i is the number of iterations
  c = [                             # Make an array of...
    *n.scan(/.{#{b=b.to_i}}/),        # the whole sections of length b
    *$'[0] && $'.ljust(b, ?1)         # plus, if there’s stray letters, the final section padded to length b
  ].map{
    _1.chars.map(&:to_i).reduce :*    # Multiply each section’s digits
  } * ""                            # Join back together

  c.size < b ?                      # If we’re under the target length...
    [c, i] :                          # return the remaining string and iteration count
    f[c, b, i+1]                      # otherwise call itself recursively, incrementing the iteration count
}

p f[*$*]                          # $* is ARGV; splat it into f's arguments
\$\endgroup\$

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