泛指倍增


14

灵感来自这个 CMC

给定一个大于0的正整数,对其执行以下操作:

  • 如果所有十个数字(1234567890)都至少有一次,输出计数并退出程序
  • 否则,将数字加倍并重复,增加计数。

计数从0开始,是输入加倍的次数。例如,如果输入为617283945,则需要将其加倍一次,因为1234567890中包含所有10位数字。

这是一个因此最短的代码获胜。如果需要,可以将输入作为字符串。

测试用例

input => output

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

我们可以将输入作为字符串吗?
斯蒂芬

@Stephen您可以将输入作为字符串。
caird coinheringaahing

3
它是保证任何n存在一些k这样nk的pandigital?我很想看看证明。
shooqie

1
@bfontaine聊天迷你挑战赛
caird coinheringaahing

3
@shooqie证明!对于任何互质为10的​​n,它也互质为10 ^ 10,因此存在一些k,使得nk为1 mod 10 ^ 10。然后1234567890 * nk = 1234567890 mod 10 ^ 10,因此每个数字必须至少出现一次。如果不是,请根据需要乘以2、5或25,以使最后一个非零数字互质数为10,并且上述证明的一种变体有效(通常n = 10 ^ m * p,其中p满足上述条件,则上述的1234567890 * p * k是pandigital,因此1234567890 * p * k * 10 ^ m = 1234567890 * k * n是)。:)
B. Mehta

Answers:



4

J24 23字节

(]1&(+$:)2**)10>#@~.@":

在线尝试!

说明

(]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

真好 我一直在收集结果,没有考虑使用那种递归函数。
Conor O'Brien

4

05AB1E11 10字节

-1字节归功于scottinet

[D9ÝåË#·]N

在线尝试!或作为测试套件

[          // 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


@scottinet谢谢!我不知道我怎么想念它。
莱利

@riley打算说,use x但是那也是10 ...很好的答案。思想x会被淘汰D,但这是相同的想法。
魔术章鱼缸

3

Perl 631 28个字节(27个字符)

-3个字节,感谢@Joshua

{($_,2×*...*.comb.Set>9)-1}

在线尝试!

说明:仍然是相同的构造以递归生成列表。第一个元素是给定的数字($_),每个下一个元素是上一个元素的2倍(2×*—我们使用×,因为尽管2个字节的字符,它仍然比便宜1个字节2 * *),然后我们这样做直到*.comb.unique>9满足的结束条件,即数字中的唯一字符超过9个。(从技术上讲,我们使用将该字符串分解为一个字符列表,用.comb强制将其设置为一个集合.Set(当然,集合仅包含每个元素一次),然后与9进行比较,这会强制将集合置入数字上下文中,从而得出其元素的数量。)

最后,我们从该列表中减去1。同样,该列表被强制置于数字上下文中,因此我们返回的值比该列表的长度小1。


您可以使用.Set而不是.unique保存3个字节。
约书亚

@约书亚,好点!谢谢。我从没想过。
拉米利斯

3

JavaScript(ES6)+ big.js84 74 73 70字节

感谢@ ConorO'Brien通过建议big.js而不是bignumber.js节省了10个字节
感谢@Rick Hitchcock -1个字节
感谢@Shaggy -3个字节

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

将输入作为字符串;由于超出该点会发生自动科学计数转换,因此最多支持2 69个左右。

测试片段

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>

无限范围106 88 87 84字节

通过使用config选项在将数字转换为字符串时有效地禁用科学计数法,我们可以拥有几乎无限的范围。


也许您可以BigNumber通过使用big.js来缩短位?
科纳·奥布莱恩

@ ConorO'Brien肯定会有所帮助,尤其是因为new在该选项中是可选的。会更新,谢谢!
贾斯汀·马里纳

使用保存一个字节f=n=>[..."0123456789"].every(d=>RegExp(d).test(c=Big(n)))?0:1+f(c.mul(2))
里克·希区柯克

我们不需要处理大整数,因此可以根据需要删除big.js,将其减少到61个字节。你可以通过更换数字串保存3个字节"4"+2**29tio.run/##BcGxDkAwEADQb2GQO41LNBZDbX7AKgbhKkSu0jZSX1/...
长毛

2

果冻12,11个字节

QLn⁵
ḤÇпL’

在线尝试!

得快!

说明:

        # 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




2

Haskell, 44 bytes

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

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)))))

您可以使用every?代替以下内容来保存7个字节empty? (remove …#(loop[n % c 0](if(every?(set(str n))"1234567890")c(recur(* 2 n)(inc c)))))
bfontaine

@bfontaine哦,对了!谢谢。稍后再解决。谢谢。
Carcigenicate

2

视网膜,85字节

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

[5-9]
#$&
T`d`EE
T`_d#`d_`\d#
#
1
}`\d\b
$&@
@

在线尝试!链接包括测试用例。针对运行时间进行了略微优化。说明:

^\d*
$&¶$&

复制输入号码。

D`.(?=.*¶)

对第一个副本中的数字进行重复数据删除。

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

如果剩余10位数字,请删除两个数字,否则只需删除第一份。请注意,删除这两个数字会使循环的其余部分变为无操作状态。

[5-9]
#$&

#大数字前放置一个。

T`d`EE

每个数字加倍。

T`_d#`d_`\d#

添加进位。

#
1

处理领先的问题。

}`\d\b
$&@

附加@和循环直到找到所有10位数字。

@

打印@添加的的数量。


2

APL(Dyalog Unicode),19 + 2 = 21字节

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

在线尝试!

这是一个二元Dfnd I整流器˚F unctio Ñ),以0作为其左侧参数和整数作为右。由于输入应该只是整数,因此我为参数添加了2个字节0∘在字节数中。

f←不包含在字节数中,因为它不是必需的。它只是使构建测试用例更加容易。

怎么运行的:

标头: 在APL房间中聊天后,我从字节数中删除了标头,因为该函数执行了应做的事情,并且由于APL的REPL的默认设置,结果仅是不正确的。

⎕FR←1287F格式的R表示形式设置为128位十进制(7是APL的REPL中十进制的代码)。 ⎕PP←34设置P RINT P recision至34位。这两个都是必需的,因为APL的默认大数表示将它们转换为科学计数法(例如3.14159265359E15),这会使代码浪费大量时间。

0∘{∧/⎕D∊⍕⍵:⍺⋄⍺+12×⍵}  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.

2

Java 8,132 110 87 74字节

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

-57个字节,感谢@OlivierGrégoire

说明:

在这里尝试。(注意:的测试用例2被禁用,因为它应该在2 68处停止,但是的大小long限制为2 63 -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

旧的132个字节使用String输入和正则表达式回答:

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);}

在这里尝试。(注意:的测试用例2被禁用,因为由于稍微过多的递归而导致StackOverflowException。)

用于检查String是否包含所有9位数字的总正则表达式变为^(?=.*0)(?=.*1)(?=.*2)(?=.*3)(?=.*4)(?=.*5)(?=.*6)(?=.*7)(?=.*8)(?=.*9).*$,它对整个String使用正向预读。


1
111 bytes (yup, the byte count is a "uni-digital" ;-)
Olivier Grégoire

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

1
87 bytes. Thanks reduce \o/
Olivier Grégoire

1
74 bytes. Stopping here ;-)
Olivier Grégoire

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

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)

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!


2
46 bytes: If[Tr[1^Union@IntegerDigits@#]<10,#0[2#]+1,0]&
J42161217

Mathematica allows for anonymous recursive functions. :o Thanks!
totallyhuman

2
38 bytes: If[!FreeQ[DigitCount@#,0],#0[2#]+1,0]&
J42161217

Oh, thanks! BTW, ` ` can be used for code but leading whitespace is not allowed. a will work but ` a` won't.
totallyhuman

sure!BTW you can use this footer in TIO Print/@f/@{617283945,2,66833,1234567890,100,42}
J42161217

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.


using c(x,"") is a neat trick for el(strsplit(...))
Giuseppe

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.


Could you use le9 instead of ne10? I'm not familiar with powershell, but that might save a byte.
Roland Heath

@RolandHeath Indeed; good call. Thanks!
AdmBorkBork



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.


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.


1
it doesn't wok because the var is 64 bits. There a lot of other answers with same problem.
Naresh


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

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

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

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.


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'

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

0

REXX, 57 bytes

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

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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.