# Pandigital Doubling

Inspired by this CMC

Given a positive integer greater than 0, perform the following operation on it:

• If all ten single digits (1234567890) are in the number at least once, output the count and exit the program
• Otherwise, double the number and repeat, incrementing the count.

The count starts at 0 and is the number of times the input was doubled. For example, if the input were 617283945, it would need to be doubled once because 1234567890 has all 10 digits in it.

This is a so shortest code wins. Input may be taken as a string, if you want.

## Test cases

input => output

617283945 => 1
2 => 67
66833 => 44
1234567890 => 0
100 => 51
42 => 55

• Can we take input as a string? Commented Sep 14, 2017 at 19:18
• @Stephen you may take input as a string. Commented Sep 14, 2017 at 19:19
• Is it guaranteed that for any n there exists some k such that nk is pandigital? I'd love to see a proof. Commented Sep 14, 2017 at 20:57
• @bfontaine Chat Mini Challenge Commented Sep 15, 2017 at 20:04
• @shooqie Proof! For any n which is coprime to 10, it's also coprime to 10^10, and so there exists some k such that nk is 1 mod 10^10. Then 1234567890*nk = 1234567890 mod 10^10, so each digit necessarily appears at least once. If not, multiply by 2, 5, or 25 as necessary to make the last non-zero digit coprime with 10, and a variant of the above proof works (formally, n = 10^m * p, where p satisfies the above condition, then 1234567890*p*k as above is pandigital, so 1234567890*p*k*10^m = 1234567890*k*n is). :) Commented Sep 17, 2017 at 1:43

# Python 3, 39 bytes

f=lambda n:len({*str(n)})<10and-~f(n*2)


Try it online!

Outputs False for 0.

# J, 24 23 bytes

(]1&(+$:)2**)10>#@~.@":  Try it online! ## Explanation (]1&(+$:)2**)10>#@~.@":  Input: integer n
":  Format as string
~.@    Unique
#@       Length
10>         Less than 10
*             Multiply, gives n if previous was true, else 0
2*              Multiply by 2
]                       Get the previous condition
1&(   )                Execute this if true on 2n, else return 0
$: Recurse 1 + Add 1  • Nice. I was stuck on collecting the results, didn't think about using that type of recursive function. Commented Sep 14, 2017 at 20:54 # 05AB1E, 11 10 bytes -1 byte thanks to scottinet [D9ÝåË#·]N  Try it online! or as a Test Suite [ // Start infinity loop D // Duplicate current value (or input) 9Ý // Push [0,1,2,3,4,5,6,7,8,9] å // Does each exist in the current value Ë# // Break if all equal (if every digit exists) · // Else double the current value ]N // End loop and print the number of times through the loop  • -1 byte Commented Sep 15, 2017 at 11:07 • @scottinet Thanks! I don't know how I missed that. Commented Sep 15, 2017 at 13:32 • @riley was going to say use x but that's 10 too... Nice answer. Thought x would get rid of D, but it's the same idea. Commented Sep 15, 2017 at 20:42 # Perl 6, 31 28 bytes (27 chars) -3 bytes thanks to @Joshua {($_,2×*...*.comb.Set>9)-1}


Try it online!

Explanation: Still the same construct to recursively generate lists. The first element is the given number ($_), each next element is 2 times the previous (2×* — we use ×, because, although 2 byte character, it's still 1 byte cheaper than 2 * *), and we do this until the end condition of *.comb.unique>9 is satisfied, i. e. when there is more than 9 unique characters in the number. (Technically, we break the string down to a list of characters with .comb, force it to a set with .Set (of course, Sets contain each element only once), and compare with 9, which forces the set into numerical context, which in turn gives its number of elements.) Finally, we subtract 1 from this list. Again, the list is forced into numerical context, so what we return is 1 less than the length of that list. • You can use .Set instead of .unique to save 3 bytes. Commented Sep 15, 2017 at 5:07 • @Joshua, good point! Thank you. I never thought of this. Commented Sep 15, 2017 at 10:12 # JavaScript (ES6) + big.js, 847473 70 bytes Thanks @ConorO'Brien for saving 10 bytes by suggesting big.js instead of bignumber.js Thanks to @Rick Hitchcock for -1 byte Thanks to @Shaggy for -3 bytes f=n=>[..."4"+2**29].every(d=>RegExp(d).test(c=Big(n)))?0:1+f(c.mul(2))  Takes input as string; supports up to around 269 due to automatic scientific notation conversion occurring beyond that point. ## Test Snippet f=n=>[..."4"+2**29].every(d=>RegExp(d).test(c=Big(n)))?0:1+f(c.mul(2)) ;[617283945, 2, 66833, 1234567890, 100, 42].forEach(t=>console.log(f(${t}) = +f(t)))
<script src="https://cdn.rawgit.com/MikeMcl/big.js/c6fadd08/big.min.js"></script>

## Infinite range, 1068887 84 bytes

By using the config option to effectively disable scientific notation when converting numbers to strings, we can have nearly infinite range.

f=n=>[..."4"+2**29].every(d=>RegExp(d).test(c=Big(n)),Big.E_POS=1e9)?0:1+f(c.mul(2))

let num = ${Math.random()*1e6|0}.repeat(100) O.innerText=f(\n${num}\n) = ${f(num)} <script src="https://cdn.rawgit.com/MikeMcl/big.js/c6fadd08/big.min.js"></script> <pre id=O style="width:100%;white-space:normal;overflow-wrap:break-word"></pre> • Maybe you could shorten the BigNumber bit by using big.js? Commented Sep 15, 2017 at 1:41 • @ConorO'Brien That will definitely help, especially because new is optional in that one. Will update, thanks! Commented Sep 15, 2017 at 1:45 • Save one byte with f=n=>[..."0123456789"].every(d=>RegExp(d).test(c=Big(n)))?0:1+f(c.mul(2)). Commented Sep 15, 2017 at 14:27 • We don't need to handle big integers so you could drop big.js if you wanted, bringing you down to 61 bytes. And you can save 3 bytes by replacing the string of digits with "4"+2**29: tio.run/##BcGxDkAwEADQb2GQO41LNBZDbX7AKgbhKkSu0jZSX1/… Commented Sep 15, 2017 at 16:37 # Jelly, 12, 11 bytes QLn⁵ ḤÇÐ¿L’  Try it online! Gotta go fast! Explanation:  # Helper link, takes one argument 'z' Q # The unique digits of 'z' L # Length n # Does not equal ⁵ # 10 # # Main link Ð¿ # While <condition> is true, run <body> and return all intermediate results # Condition: Ç # The helper link # Body: Ḥ # Double the input # Now we have a list of all the 'z's that we passed to the helper link L # Return it's length ’ # minus one  • Test suite Commented Sep 14, 2017 at 19:24 # Haskell, 46 bytes f n|all(elemshow n)['0'..'9']=0|1<3=1+f(2*n)  Try it online! # J, 43 bytes f=:(,$:@+:@{.)[@.(9<[:#@~.10&#.inv)
<:@#@f


Try it online!

Defines an anonymous function. Collects results quite suboptimally. Check out miles's superior answer here!

• There’s no need for recursion, use ^:a:: 1#@}.+:^:(10>#@~.@":)^:a: Commented Nov 13, 2017 at 19:33

until(\c->all(elemshow(n*2^c))['0'..'9'])(+1)0


# Clojure, 11589 82 bytes

-26 bytes by just using a string to represent the list of characters (duh, in retrospect), and changing from using recursion to loop, which allowed me to make a couple of optimizations.

-7 bytes by getting rid of the call to bigint. Apparently we only need to handle input that won't cause an overflow.

#(loop[n % c 0](if(empty?(remove(set(str n))"1234567890"))c(recur(* 2 n)(inc c))))


Pregolfed:

(defn pan [num]
(loop [n num
cnt 0]

; Remove all the characters from the stringified input
;  that are numeric. If the result is an empty list, all
;  the numbers were present.
(if (empty? (remove (set (str n)) "1234567890"))
cnt
(recur (* 2 n) (inc cnt)))))

• You can save 7 bytes by using every? instead of empty? (remove …: #(loop[n % c 0](if(every?(set(str n))"1234567890")c(recur(* 2 n)(inc c))))) Commented Sep 15, 2017 at 19:54
• @bfontaine Oh, you're right! Thanks. I'll fix that later. Thanks. Commented Sep 15, 2017 at 21:33

# Retina, 85 bytes

^\d*
$&¶$&
D.(?=.*¶)
\d{10}¶\d+|\d*¶

[5-9]
#$& TdEE T_d#d_\d# # 1 }\d\b$&@
@


Try it online! Link includes test cases. Slightly optimised for run time. Explanation:

^\d*
$&¶$&


Duplicate the input number.

D.(?=.*¶)


Deduplicate the digits in the first copy.

\d{10}¶\d+|\d*¶


If 10 digits remain, delete both numbers, otherwise just delete the first copy. Note that deleting both numbers causes the rest of the loop to no-op.

[5-9]
#$&  Place a # before large digits. TdEE  Double each digit. T_d#d_\d#  Add in the carries. # 1  Deal with a leading carry. }\d\b$&@


Append an @ and loop until all 10 digits are found.

@


Print the number of @s added.

# APL (Dyalog Unicode), 19 + 2 = 21 bytes

0∘{∧/⎕D∊⍕⍵:⍺⋄⍺+1∇2×⍵}


Try it online!

This is a dyadic Dfn (direct function), taking 0 as its left argument and the integer as the right. Since the input is supposed to be only the integer, I added 2 bytes for the argument 0∘ to the byte count.

f← is not included in the byte count, since it's not necessary. It just makes it easier to build the test cases.

### How it works:

The headers: I removed those from the byte count after some chatting in the APL room, since the function does what it's supposed to do and the results are only incorrect because of the default settings of APL's REPL.

⎕FR←1287 Sets the Float Representation to 128-bit decimal (7 is the code for decimal in APL's REPL). ⎕PP←34 Sets the Print Precision to 34 digits. Both of these are needed, since APL's default representation for big numbers transforms them to scientific notation (e.g. 3.14159265359E15) which messes up the code big time.

0∘{∧/⎕D∊⍕⍵:⍺⋄⍺+1∇2×⍵} ⍝ Dyadic Dfn
0∘                     ⍝ Fixes 0 as the left argument
:            ⍝ If
⎕D                ⍝ String representation of all digits [0, 9]
∊               ⍝ "is in"
⍕⍵             ⍝ String representation of the input
∧/                  ⍝ AND-reduction. Yields 1 (true) iff all digits are in the right argument.
⍺           ⍝ return the left argument
⋄          ⍝ Else
2×⍵   ⍝ Double the right arg
⍺+1       ⍝ increment the left arg
∇      ⍝ Recursively call this function with the new arguments.


# Java 8, 13211087 74 bytes

n->{int c=0;for(;(n+"").chars().distinct().count()!=10;n*=2)c++;return c;}


-57 bytes thanks to @OlivierGrégoire.

Explanation:

Try it here. (Note: test case for 2 is disabled because it should stop at 268, but the size of long is limited to 263-1.)

n->          // Method with long parameter and integer return-type
int c=0;   //  Count-integer, starting at 0
for(;(n+"").chars().distinct().count()!=10;
//  Loop (1) as long as the unique amount of digits in the number are not 10
n*=2)    //    After every iteration: multiply the input by 2
c++;      //   Increase the count by 1
//  End of loop (1) (implicit / single-line body)
return c;  //  Return the counter
}            // End of method


Old 132 bytes answer using a String input and regex:

n->f(n,0)int f(String n,int c){String t="";for(int i=0;i<10;t+="(?=.*"+i+++")");return n.matches(t+".*")?c:f(new Long(n)*2+"",c+1);}


Try it here. (Note: test case for 2 is disabled because it causes a StackOverflowException due to slightly too much recursion.)

The total regex to check if the String contains all 9 digits becomes ^(?=.*0)(?=.*1)(?=.*2)(?=.*3)(?=.*4)(?=.*5)(?=.*6)(?=.*7)(?=.*8)(?=.*9).*$, which uses a positive look-ahead for the entire String. • 111 bytes (yup, the byte count is a "uni-digital" ;-) Commented Nov 14, 2017 at 9:25 • Note that 2 will never work because we expect 2^68 as first pandigital number, but longs in Java are limited to 2^63-1. Commented Nov 14, 2017 at 9:30 • 87 bytes. Thanks reduce \o/ Commented Nov 14, 2017 at 9:50 • 74 bytes. Stopping here ;-) Commented Nov 14, 2017 at 10:10 • @KevinCruijssen I know you obliterated your old method, but just want to point out that you can use the following regex to match all 10 digits: (?:.*?(\d)(?!.*\1)){10} Commented Nov 18, 2017 at 13:33 # Husk, 10 bytes ←Vö>9Lud¡D  Try it online! ### Explanation  ¡D Repeatedly double the input, collecting results in a list V Return the first index where the following is true L The length of d the digits u with duplicates removed ö>9 is greater than 9 ← Decrement (as Husk uses 1-indexing)  # Mathematica, 59484746 38 bytes -9 bytes thanks to Jenny_mathy. If[!FreeQ[DigitCount@#,0],#0[2#]+1,0]&  Try it online using Mathics! • 46 bytes: If[Tr[1^Union@IntegerDigits@#]<10,#0[2#]+1,0]& Commented Sep 14, 2017 at 21:18 • Mathematica allows for anonymous recursive functions. :o Thanks! Commented Sep 14, 2017 at 21:22 • 38 bytes: If[!FreeQ[DigitCount@#,0],#0[2#]+1,0]& Commented Sep 14, 2017 at 21:32 • Oh, thanks! BTW,   can be used for code but leading whitespace is not allowed. a will work but  a won't. Commented Sep 14, 2017 at 21:56 • sure!BTW you can use this footer in TIO Print/@f/@{617283945,2,66833,1234567890,100,42} Commented Sep 14, 2017 at 22:01 # R, 74 bytes function(x){while(!all(0:9%in%el(strsplit(c(x,""),"")))){F=F+1;x=2*x};F*1}  Try it online! Note that R will give the wrong answer to f(2) due to limitations of how the language stores large integers. Explanation: For the test of pandigitality, the input is coerced to a character vector by joining with an empty string and then split into individual digits. We then check whether all of 0:9 are present in the resulting vector; if not, we increment the counter, double the input and repeat. The counter uses F which initialises as FALSE. To make sure it is coerced to numeric, we multiply by one before returning. • using c(x,"") is a neat trick for el(strsplit(...)) Commented Sep 15, 2017 at 21:36 # PowerShell, 70 69 bytes for($n=[bigint]$args[0];([char[]]"$n"|group).count-le9;$n*=2){$i++}$i  Try it online! (Nearly twice as long as the Python answer :-\ ) Takes input $args[0], casts it as a [bigint], saves it to $n. Enters a for loop. Each iteration we check against whether the $number converted to a string then to a char-array, when Group-Object'd together, has a .count -less than or equal to 9. Meaning, the only way that it equals 10 is if at least one digit of every number 1234567890 is present. If yes, we exit the loop. If not, we $n*=2 and continue. Each iteration inside the loop, we're simply incrementing $i. When we exit the loop, we simply output $i. Note that for input like 1234567890 where every digit is already accounted for, this will output nothing, which is a falsey value in PowerShell, and equivalent to 0 when cast as an [int]. If that's not OK, we can simply put a + in front of the output $i to explicitly cast it as an integer.

Saved a byte thanks to Roland Heath.

• Could you use le9 instead of ne10? I'm not familiar with powershell, but that might save a byte. Commented Sep 15, 2017 at 6:42
• @RolandHeath Indeed; good call. Thanks! Commented Sep 15, 2017 at 12:27

# Ruby, 464539 38 bytes

def f n;n.digits.uniq[9]?0:1+f(n*2)end


Try it online!

1. -1 by using def f n; instead of def f(n);.
2. -6 by using …[9] instead of ….size==10
3. -1 by removing a semicolon

# q/kdb+, 33 bytes

Solution:

(#)1_{x*2 1 min!:[10]in 10 vs x}\


Examples:

q)(#)1_{x*2 1 min!:[10]in 10 vs x}\[100]
51
q)(#)1_{x*2 1 min!:[10]in 10 vs x}\[1234567890]
0
q)(#)1_{x*2 1 min!:[10]in 10 vs x}\[42]
55


Explanation:

All the bytes are in the equality, might be able to golf this one down a little further. Utilises q's scan adverb:

count 1_{x*2 1 min til[10] in 10 vs x}\ / ungolfed solution
{                            }\ / scan over this lambda until it yields same result
10 vs x   / convert to base 10
in           / left list in right list, returns boolean list
til[10]              / range 0..9
min                      / return the minimum of the list, 0 or 1
2 1                          / list (2;1) indexed into with 0 or 1
x*                             / return x multiplied by either 2 or 1
1_                                / 1 drop, drop one element from front of list
count                                   / count the length of the list


Notes:

If we drop to the k prompt then we can have a 25 byte solution. Converts the number to a list of characters:

q)\
#1_{x*2 1@&/($!10)in$$x}\[100] 51  # Pyth, 11 bytes f>l{.<QT9Z  First natural number T where input << T meets the requirement. # Perl 5, 52 + 1 (-p) = 53 bytes $/=10;for$i(0..9){$/-=/$i/}$_*=2;++$\;$/&&redo}{$\--  Try it online! # Perl, 43 + 1 bytes for$x(0..9){$_*=2,++$\,redo LINE if!/$x/}}{  Using the -p flag. This builds on the solution provided by Xcali above. # Swift 4, 111 bytes func p(_ x:Int,_ c:Int=0)->Int{if !(String(Set(String(x)).sorted())=="0123456789"){return p(x*2,c+1)};return c}  Note: Won't work for x = 2, because of overflow. Explanation - Input x is first typecasted to string. Then Set() removes the repeating characters. Then it is sorted to match the result. If it doesn't match, x is doubles and counter is incremented. • it doesn't wok because the var is 64 bits. There a lot of other answers with same problem. Commented Sep 15, 2017 at 13:30 • Commented Sep 15, 2017 at 13:56 • If you think that this should be allowed bring it up with the OP. It may be common practice but the OP has not specifically allowed it and the testcases seem to suggest you need to support 2. Commented Sep 15, 2017 at 14:01 • @FunkyComputerMan actually, I did allow answers that can't handle numbers outside the bounds of the language, but Shaggy seems to have deleted the comment asking about that. This answer is fine. Commented Sep 15, 2017 at 14:07 # Japt, 15 bytes LÆ*2pXÃbì_â Ê¥A  Try it ## Explanation Implicit input of integer U. LÆ Ã  Create an array of integers from 0 to 99 and pass each through a function where X is the current element. *2pX  U multiplied by 2 raised to the power of X. b  Get the index of the first element thay returns true when passed through the following function. ì_â  Split to an array of digits and remove the duplicates. Ê¥A  Get the length of the array and check for equality with 10. ## Alternative, 15 bytes @*2pX)ìâ sÊ¥A}a  Try it ### Explanation Implicit input of integer U. @ }a  Starting with 0, return the first number that returns true when passed through the following function, with X being the current number. *2pX)  As above, multiply U by 2 to the power of X. ìâ  Split to an array of digits, remove duplicates and rejoin to an integer. sÊ  Convert to a string, get the length and convert back to an integer. ¥A  Check for equality with 10. # GNU dc, 61 bytes Input is copied from top of stack (which must be otherwise empty); output is pushed to top of stack. [I~1r:ad0<s]ss[d1+r;a1=p]sp[d2*lfx]sh[0Sadlsxlpx11!=h]dsfxz1-  ## Explanation We use the array variable a, storing a 1 in a[d] if digit d is present, otherwise falling back to 0 there. We use the GNU extension ~ to obtain quotient and remainder in a single command. # populate a[0-9] from the digits [I~1r:ad0<s]ss # check pandigit # return 1 more than lowest unset element of a[] # start with stack=0 [d1+r;a1=p]sp # Test for pandigit; double and repeat if needed [dd+lfx]sh [0Sadlsxlpx11!=h]dsfx # We left one value on the stack for each doubling, plus the original z1-  As a bonus, this will work in arbitrary number bases (not only decimal): simply set the input radix as required (the constant 11 in the definition of f will be read using that number base, so is automatically correct). ## Test for i in 617283945 2 66833 1234567890 100 42 do printf '%s => '$i
dc -e \$i \
-e p
done

617283945 => 1
2 => 67
66833 => 44
1234567890 => 0
100 => 51
42 => 55


## REXX, 57 bytes

arg n
do b=0 while verify(0123456789,n)>0
n=n*2
end
say b