Pandigital Doubling

14

1

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

caird coinheringaahing

Posted 2017-09-14T19:14:13.620

Reputation: 13 702

Can we take input as a string? – Stephen – 2017-09-14T19:18:30.977

@Stephen you may take input as a string. – caird coinheringaahing – 2017-09-14T19:19:15.637

@Shaggy what do you think they should be? Also, its 66833 with 2 3s – caird coinheringaahing – 2017-09-14T20:25:03.587

@Shaggy It might be that test case 2 will need a big integer since doubling 2 67 times gives 2^68 – miles – 2017-09-14T20:27:24.533

@Shaggy as with all challenges, no. – caird coinheringaahing – 2017-09-14T20:31:06.340

3Is it guaranteed that for any n there exists some k such that nk is pandigital? I'd love to see a proof. – shooqie – 2017-09-14T20:57:27.583

@shooqie That question was asked in the Maths chat room, but wasn't answered. I think that every n greater than 0 can be doubled into pandigitality. (Is that the right word?) – caird coinheringaahing – 2017-09-14T20:59:11.043

I checked all inputs up to 100,000 and the largest value for n was 78 given an input of 1471. There may be a larger n for long numbers but my stupid VBA solution takes about 8 seconds per 1,000 inputs and I don't want to wait that long. I did find an interesting pattern, though. For the first 100,000 inputs, the number of times a certain n occurred fits a normal distribution.

– Engineer Toast – 2017-09-15T13:19:59.743

What does "CMC" mean? – bfontaine – 2017-09-15T20:04:08.560

1@bfontaine Chat Mini Challenge – caird coinheringaahing – 2017-09-15T20:04:29.827

3@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*k10^m = 1234567890k*n is). :) – B. Mehta – 2017-09-17T01:43:47.090

A similar idea of modular inverses proves this nicely if the question asked about tripling instead, doubling only seems a little harder. – B. Mehta – 2017-09-17T01:53:49.780

@EngineerToast 1471 stays the largest up to 1 000 000, and is in fact the last value for which the output reaches 78 below a million. – B. Mehta – 2017-09-17T02:33:32.927

@B.Mehta Both are true up to at least 160 868 750, too. – Engineer Toast – 2017-10-12T21:24:30.360

There's no result higher than 78 in the first 1,000,000,000 values - is there a mathematician who can tell us whether any larger results can be proved or disproved? – Toby Speight – 2017-11-21T09:10:19.350

Answers

6

Python 3, 39 bytes

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

Try it online!

Outputs False for 0.

Leaky Nun

Posted 2017-09-14T19:14:13.620

Reputation: 45 011

4

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

Riley

Posted 2017-09-14T19:14:13.620

Reputation: 11 345

-1 byte – scottinet – 2017-09-15T11:07:31.223

@scottinet Thanks! I don't know how I missed that. – Riley – 2017-09-15T13:32:57.507

@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. – Magic Octopus Urn – 2017-09-15T20:42:37.810

4

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

miles

Posted 2017-09-14T19:14:13.620

Reputation: 15 654

Nice. I was stuck on collecting the results, didn't think about using that type of recursive function. – Conor O'Brien – 2017-09-14T20:54:52.680

3

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.

Ramillies

Posted 2017-09-14T19:14:13.620

Reputation: 1 923

You can use .Set instead of .unique to save 3 bytes. – Joshua – 2017-09-15T05:07:14.077

@Joshua, good point! Thank you. I never thought of this. – Ramillies – 2017-09-15T10:12:34.113

3

JavaScript (ES6) + big.js, 84 74 73 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, 106 88 87 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>

Justin Mariner

Posted 2017-09-14T19:14:13.620

Reputation: 4 746

Maybe you could shorten the BigNumber bit by using big.js?

– Conor O'Brien – 2017-09-15T01:41:59.237

@ConorO'Brien That will definitely help, especially because new is optional in that one. Will update, thanks! – Justin Mariner – 2017-09-15T01:45:23.773

Save one byte with f=n=>[..."0123456789"].every(d=>RegExp(d).test(c=Big(n)))?0:1+f(c.mul(2)). – Rick Hitchcock – 2017-09-15T14:27:09.707

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: https://tio.run/##BcGxDkAwEADQb2GQO41LNBZDbX7AKgbhKkSu0jZSX1/vXeu7hs2fT2zE7ZyzNWKGYiaisiuVrmvdL8Qv@w@SGSY@xvRAQoocIghiVVkQJajavDkJ7ma63QEWOo2Yfw

– Shaggy – 2017-09-15T16:37:40.923

2

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

James

Posted 2017-09-14T19:14:13.620

Reputation: 54 537

Test suite – caird coinheringaahing – 2017-09-14T19:24:02.643

2

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!

Conor O'Brien

Posted 2017-09-14T19:14:13.620

Reputation: 36 228

There’s no need for recursion, use ^:a:: 1#@}.+:^:(10>#@~.@":)^:a: – FrownyFrog – 2017-11-13T19:33:36.480

2

Haskell, 46 bytes

f n|all(`elem`show n)['0'..'9']=0|1<3=1+f(2*n)

Try it online!

Laikoni

Posted 2017-09-14T19:14:13.620

Reputation: 23 676

2

Clojure, 115 89 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)))))

Carcigenicate

Posted 2017-09-14T19:14:13.620

Reputation: 3 295

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))))) – bfontaine – 2017-09-15T19:54:22.660

@bfontaine Oh, you're right! Thanks. I'll fix that later. Thanks. – Carcigenicate – 2017-09-15T21:33:43.540

2

Haskell, 44 bytes

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

jkabrg

Posted 2017-09-14T19:14:13.620

Reputation: 299

2

Retina, 85 bytes

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

[5-9]
#$&
T`d`EE
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.

T`d`EE

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.

Neil

Posted 2017-09-14T19:14:13.620

Reputation: 95 035

2

Java 8, 132 110 87 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.

Kevin Cruijssen

Posted 2017-09-14T19:14:13.620

Reputation: 67 575

1111 bytes (yup, the byte count is a "uni-digital" ;-) – Olivier Grégoire – 2017-11-14T09:25:07.350

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. – Olivier Grégoire – 2017-11-14T09:30:47.347

@OlivierGrégoire Thanks! And 1 more byte saved by putting the ints inside the loop. – Kevin Cruijssen – 2017-11-14T09:39:30.057

Yeah, kind of forgot that. I liked my "uni-digital", though ^^ – Olivier Grégoire – 2017-11-14T09:42:15.620

187 bytes. Thanks reduce \o/ – Olivier Grégoire – 2017-11-14T09:50:23.143

174 bytes. Stopping here ;-) – Olivier Grégoire – 2017-11-14T10:10:10.243

@OlivierGrégoire Ah nice, of course. (n+"").chars().distinct().count()!=10 if the number contains all ten digits. Smart, smart. – Kevin Cruijssen – 2017-11-14T11:34:55.410

1@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} – jaytea – 2017-11-18T13:33:19.387

@jaytea Ah nice, that's 81 bytes, which isn't too bad either: n->{int c=0;for(;!(n+"").matches("(?:.*?(\\d)(?!.*\\1)){10}");n*=2)c++;return c;}. Feel free to post it as an alternative answer if you want. – Kevin Cruijssen – 2017-11-18T15:14:47.483

2

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.

J. Sallé

Posted 2017-09-14T19:14:13.620

Reputation: 3 233

1

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)

H.PWiz

Posted 2017-09-14T19:14:13.620

Reputation: 10 962

1

Mathematica, 59 48 47 46 38 bytes

-9 bytes thanks to Jenny_mathy.

If[!FreeQ[DigitCount@#,0],#0[2#]+1,0]&

Try it online using Mathics!

totallyhuman

Posted 2017-09-14T19:14:13.620

Reputation: 15 378

246 bytes: If[Tr[1^Union@IntegerDigits@#]<10,#0[2#]+1,0]& – J42161217 – 2017-09-14T21:18:49.680

Mathematica allows for anonymous recursive functions. :o Thanks! – totallyhuman – 2017-09-14T21:22:14.280

238 bytes: If[!FreeQ[DigitCount@#,0],#0[2#]+1,0]& – J42161217 – 2017-09-14T21:32:42.813

Oh, thanks! BTW, can be used for code but leading whitespace is not allowed. a will work but a won't. – totallyhuman – 2017-09-14T21:56:20.857

sure!BTW you can use this footer in TIO Print/@f/@{617283945,2,66833,1234567890,100,42} – J42161217 – 2017-09-14T22:01:30.700

1

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.

AdmBorkBork

Posted 2017-09-14T19:14:13.620

Reputation: 41 581

Could you use le9 instead of ne10? I'm not familiar with powershell, but that might save a byte. – Roland Heath – 2017-09-15T06:42:31.280

@RolandHeath Indeed; good call. Thanks! – AdmBorkBork – 2017-09-15T12:27:53.890

1

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.

user2390246

Posted 2017-09-14T19:14:13.620

Reputation: 1 391

using c(x,"") is a neat trick for el(strsplit(...)) – Giuseppe – 2017-09-15T21:36:51.427

0

Pyth, 11 bytes

f>l{`.<QT9Z

Test suite.

First natural number T where input << T meets the requirement.

Leaky Nun

Posted 2017-09-14T19:14:13.620

Reputation: 45 011

0

Perl 5, 52 + 1 (-p) = 53 bytes

$/=10;for$i(0..9){$/-=/$i/}$_*=2;++$\;$/&&redo}{$\--

Try it online!

Xcali

Posted 2017-09-14T19:14:13.620

Reputation: 7 671

0

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.

user73921

Posted 2017-09-14T19:14:13.620

Reputation:

0

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.

Naresh

Posted 2017-09-14T19:14:13.620

Reputation: 131

1it doesn't wok because the var is 64 bits. There a lot of other answers with same problem. – Naresh – 2017-09-15T13:30:26.557

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. – Post Rock Garf Hunter – 2017-09-15T14:01:32.983

1@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. – caird coinheringaahing – 2017-09-15T14:07:50.870

0

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.

Convert to a string, get the length and convert back to an integer.

¥A

Check for equality with 10.

Shaggy

Posted 2017-09-14T19:14:13.620

Reputation: 24 623

0

Ruby, 46 45 39 38 bytes

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

Try it online!

Updates:

  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

bfontaine

Posted 2017-09-14T19:14:13.620

Reputation: 133

0

QBIC, 48 bytes, nc

{q=1[z|q=q*instr(!:$,!a-1$)]~q>0|_Xp\p=p+1┘b=b*2

This should work, in theory. However, in practice this fails because QBasic casts ten-digit numbers (at least needed to get all digits) to scientific notation... I've marked it as non-competing because of that.

Explanation

{             DO ad infinitum
q=1           set q to 1
[z|           FOR a = 1 to 10
q=q*instr     multiply q by the position
(!:$             - in 'b' (read from cmd line at start) cast to string (! ... $)
,!a-1$)          - of the number a-1 [0-9] cast to string
]             NEXT
~q>0          IF any character was not found, instr gave a 0. If q != 0 all digits were present
|_Xp          THEN quit, printing  p (is 0 at start)
\p=p+1        ELSE increase step counter p
┘b=b*2        and double 'b'

steenbergh

Posted 2017-09-14T19:14:13.620

Reputation: 7 772

0

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 '[I~1r:ad0<s]ss[d1+r;a1=p]sp[dd+lfx]sh[0Sadlsxlpx11!=h]dsfxz1-' \
       -e p
done
617283945 => 1
2 => 67
66833 => 44
1234567890 => 0
100 => 51
42 => 55

Toby Speight

Posted 2017-09-14T19:14:13.620

Reputation: 5 058

0

REXX, 57 bytes

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

idrougge

Posted 2017-09-14T19:14:13.620

Reputation: 641

0

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

streetster

Posted 2017-09-14T19:14:13.620

Reputation: 3 635