最小零基数


28

给定一个正整数n,输出最小的底数b >= 2,其中n底数b中没有前导零的表示不包含0。您可能会假设b <= 256所有输入都是这样。

测试用例

1 -> 2 (1)
2 -> 3 (2)
3 -> 2 (11)
4 -> 3 (11)
5 -> 3 (12)
6 -> 4 (12)
7 -> 2 (111)
10 -> 4 (22)
17 -> 3 (122)
20 -> 6 (32)
50 -> 3 (1212)
100 -> 6 (244)
777 -> 6 (3333)
999 -> 4 (33213)
1000 -> 6 (4344)
1179360 -> 23 ([12, 9, 21, 4, 4])
232792560 -> 23 ([15, 12, 2, 20, 3, 13, 1])
2329089562800 -> 31 ([20, 3, 18, 2, 24, 9, 20, 22, 2])
69720375229712477164533808935312303556800 -> 101 ([37, 17, 10, 60, 39, 32, 21, 87, 80, 71, 82, 14, 68, 99, 95, 4, 53, 44, 10, 72, 5])
8337245403447921335829504375888192675135162254454825924977726845769444687965016467695833282339504042669808000 -> 256 ([128, 153, 236, 224, 97, 21, 177, 119, 159, 45, 133, 161, 113, 172, 138, 130, 229, 183, 58, 35, 99, 184, 186, 197, 207, 20, 183, 191, 181, 250, 130, 153, 230, 61, 136, 142, 35, 54, 199, 213, 170, 214, 139, 202, 140, 3])

1
在您使用的较高的基数中,十,十一等的值是多少?它们是否包含零?
斯蒂芬,

19
@Stephen为上面的数字选择的值9无关紧要,因为它们不是0
Mego

9
这是OEIS A106370
工程师吐司

1
@Titus很好。我将基数限制在合理范围内。
Mego

1
@Mego:尝试232792560。它是2、3,...,20的lcm,所以在每个基数<= 20中,它的最低有效位数为0。
Nate Eldredge

Answers:


15

Pyth,6个字节

f*FjQT

验证所有测试用例。

怎么运行的

f * FjQT〜完整程序。

f〜条件为真的第一个正整数。
   jQT〜将输入转换为当前元素的基数。
 * F〜产品。如果列表包含0,则为0,否则严格为正。
          0->虚假;> 0-> Truthy。
        〜隐式输出结果。

尽管Pyth的f运算1, 2, 3, 4, ...从1开始,但Pyth会将以1为底的数字(一元)视为一堆零,因此忽略以1为底的数字。


很好地滥用了Pyth的base-1表示为全零的事实。
暴民埃里克(Erik the Outgolfer)'17年

@EriktheOutgolfer谢谢!我将对此添加一个解释。
Xcoder先生17年

Pyth并不是唯一一元表示使用零作为数字提示的语言:P
Mego

你写了0 -> Falsy; > 0 -> Truthy。这是故意这0TruthyFalsy这样的境地?
布赖恩J

@BrianJ有一个>在所述第二前标志0,这意味着一切高于0是truthy。
Xcoder先生17年

11

C, 52  50字节

i,k;f(n){for(i=2,k=n;k;)k=k%i++?k/--i:n;return i;}

在线尝试!

C(gcc), 47个  45字节

i,k;f(n){for(i=2,k=n;k;)k=k%i++?k/--i:n;n=i;}

在线尝试!


感谢@Nevay对@Kevin Cruijssen的回答,节省了两个字节!


2
即使您坚持使用特定的编译器,后一个版本也只能靠运气工作。而且,当然,两个版本都不是真正的
C。– AnT

3
@AnT是C ..它会给出很多警告,但会编译。只要找到适合您代码的编译器,就可以了
Felipe Nardi Batista

1
@Blacksilver k%i在这里是三元检查。一个更可读的变种会k=(k%i?k:n*++i);甚至更明确:if(k%i){k=k;}else{k=n*++i;}
凯文·克鲁伊森

1
此外,您还可以打高尔夫球两个字节:i,k;f(n){for(i=2,k=n;k;)k=k%i++?k/--i:n;return i;}i,k;f(n){for(i=2,k=n;k;)k=k%i++?k/--i:n;n=i;}。一切归功于@Nevay谁张贴在这个建议我移植的Java 8回答
凯文·克鲁伊森

1
@Felipe Nardi Batista:我知道CodeGolf规则会说“只要编译即可”,等等。但是,它“编译”的事实并不能以任何方式证明它是C。这不是C。无类型声明类似于i, k;并且f(n)存在于C的古代版本(K&R)中,而仅在那个时代return需要在其周围用圆括号括起来论点。如果要与K&R一起使用i,k;,则还必须使用return(i);。上面可能是gnuc,但不是
C。– AnT

8

Haskell56 52 48字节

b#n=n<1||mod n b>0&&b#div n b
f n=until(#n)(+1)2

在线尝试!

很基本,但是想不出什么好办法来缩短它

编辑:感谢Laikoni为我节省了4个字节!不知道为什么我从未想过!!0。我可能应该尝试删除这些括号,但是当您尝试一起使用||和时,我对某些奇怪的错误有模糊的记忆&&。也许我将其与相等运算符混淆了。

编辑2:感谢@Lynn剃了另外4个字节!不知道我以前从未知道until过。


1
您用几乎完全相同的解决方案击败了我一分钟。:) !!0比短head,我认为您可以在中删除括号#
Laikoni '17

2
被刑事低估的until :: (a → Bool) → (a → a) → a → a字节会保存四个字节:f n=until(#n)(+1)2
林恩(Lynn)


6

外壳,7个字节

→V▼MBtN

在线尝试!

说明

→V▼MBtN
     tN    list of natural numbers starting from 2
   MB      convert the (implicit) input to each of those bases
 V▼        find the (1-based) index of the first result where the minimum digit is truthy
→          add 1 to this index

5

Python 2,57字节

n=x=input()
b=2
while x:z=x%b<1;b+=z;x=[x/b,n][z]
print b

在线尝试!

这比递归函数短一个字节:

f=lambda n,b=1,x=1:b*(x<1)or f(n,b+(x%b<1),[x/b,n][x%b<1])

1
顺便说一句,这与我的解决方案非常相似。
Erik the Outgolfer



3

外壳,9个字节

←foΠ`B⁰tN

在线尝试!

说明

            -- input N
        tN  -- tail of [1..] == [2..]
←f(    )    -- filter with the following:
    `B⁰     --   convert N to that base
   Π        --   product (0 if it contains 0)
←           -- only keep first element

3

Java 8,61 56 54字节

n->{int b=2,t=n;for(;t>0;)t=t%b++<1?n:t/--b;return b;}

在这里尝试。

说明:

n->{            // Method with integer as both parameter and return-type
  int b=2,      //  Base-integer, starting at 2
      t=n;      //  Temp-integer, copy of the input
  for(;t>0;)    //  Loop as long as `t` is not 0
    t=t%b++<1?  //   If `t` is divisible by the base `b`
                //   (and increase the base `b` by 1 afterwards with `b++`)
       n        //    Set `t` to the input `n`
      :         //   Else:
       t/--b;   //    Divide `t` by the `b-1`
                //    (by decreasing the base `b` by 1 first with `--b`)
                //  End of loop (implicit / single-line body)
  return b;     //  Return the resulting base
}               // End of method

我觉得可以使用算术方法进行练习。它的确可以,用的端口@Steadybox” C的答案,然后由于2个字节golfed @Nevay

旧(61字节)答案:

n->{int b=1;for(;n.toString(n,++b).contains("0"););return b;}

在这里尝试。

说明:

n->{         // Method with Integer as both parameter and return-type
  int b=1;   //  Base-integer, starting at 1
  for(;n.toString(n,++b).contains("0"););
             //  Loop as long as the input in base-`b` does contain a 0,
             //  after we've first increased `b` by 1 before every iteration with `++b`
  return b;  //  Return the resulting base
}            // End of method

2
54个字节:n->{int b=2,t=n;for(;t>0;)t=t%b++<1?n:t/--b;return b;}
Nevay

2

Japt,8字节

@ìX e}a2

在线尝试!

说明

@    }a2

返回第一个数字(X)以通过该函数,从2

ìX

将输入数字转换为基数数组X

e

检查所有数字是否真实。


如果数组包含任何倍数,这不会失败10吗?
毛茸茸的

@Shaggy我的理解是,根据行动党的评论,高于9的基数不算作零。
贾斯汀·马里纳

啊,我现在明白了。挑战的措词有问题,所以(或者我太累了!)。
毛茸茸的

2

JavaScript(ES6),43 41 37字节

n=>(g=x=>x?g(x%b++?x/--b|0:n):b)(b=1)

测试用例


2

Brachylog,11个字节

;.≜ḃ₎¬∋0∧1¬

在线尝试!

说明

;.≜ḃ₎           The Input represented in base Output…
     ¬∋0        …contains no 0
        ∧1¬     And Output ≠ 1

2

Python 2,57字节

n=m=input()
b=2
while m:c=m%b<1;b+=c;m=(m/b,n)[c]
print b

在线尝试!

-1感谢Felipe Nardi Batista
-2感谢Lynn(现在这是她的解决方案的伪装:D)


更改a,b=a+c,da+=c;b=d
Felipe Nardi Batista

我认为您可以替换while m>1while m(然后我们就被捆绑了!)
Lynn

@Lynn这就是为什么我评论您的解决方案的原因,那将是完全一样的。
暴民埃里克(Erik the Outgolfer)


1
@Lynn我已经知道了:p,否则我会要求您删除您的。
暴民埃里克(Erik the Outgolfer)'17年

2

APL(Dyalog)20 19 字节

1+⍣{~0∊⍺⊥⍣¯1n}≢n←⎕

在线尝试!

和往常一样,感谢@Adám在聊天中提供帮助,并使代码在TIO中起作用。另外,保存1个字节。

这tradfn(TRAD itional ˚F unctio Ñ)体。要使用它,您需要为其分配一个名称(在TIO的标题字段中),将其括在s中(名称前一个,在TIO的页脚字段中一个),然后使用其名称进行调用。由于它使用四边形()来接受用户的输入,因此称为,f \n input而不是通常的f input

怎么样?

1+⍣{~0∊⍺⊥⍣¯1n}≢n←⎕   Main function.
                  n←⎕  Assigns the input to the variable n
1+⍣{           }≢      Starting with 1, add 1 until the expression in braces is truthy
    ~0                returns falsy if 0 "is in"
                      convert
            n         the input
         ⍣¯1           to base
                      left argument (which starts at 1 and increments by 1)

然后该函数返回结果基数。


1
Golfing tip: since n←⎕ will be a simple number and you need 1 as initial argument to the rest of the code, you can just count the number of elements in n (which is 1), by replacing 1⊣ with . Try it online!
Adám


1

R, 79 71 66 63 65 bytes

function(n){while(!{T=T+1;all(n%/%T^(0:floor(log(n,T)))%%T)})T
T}

Try it online!

This answer is based on Giuseppe's re-arrangement in one single loop.

Saved 8 bytes thanks to JDL, and 6 bytes thanks to Giuseppe.


1
You can sub b for T, which starts out defined as TRUE == 1, removing the need for b=1. Similarly you can sub F for k (F is FALSE)
JDL

I see what you did there. That's a useful one to know!
NofP

1
66 bytes using m%/%T (integer division) instead of (m-m%%T)/T
Giuseppe

65 bytes. it was a bit messy but I suspected getting rid of the nested loops would save something; I just thought it would be more than 1 byte :(
Giuseppe

1

MATL, 13 12 bytes

`G@Q_YAA~}@Q

Try it online!

-1 byte thanks to Luis Mendo. This program does not handle testcases bigger than 2^53 (flintmax, the maximum consecutive integer representable by a floating point type), as the default datatype is double in MATL. However, it should be able to find any arbitrary zeroless base below that number.

`            % Do while
 G           %  Push input
  @ _        %  Outputs the iteration number, negate.
     YA      %  Convert input to base given by the iteration number, the negative number is to instruct MATL we want an arbitrary high base with a integer vector rather than the default character vector we know from hexadecimal
       A~    %  If they're not all ones, repeat
         }   % But if they are equal, we finally
          @  %  Push the last base
   Q       Q %  As base 1 makes no sense, to prevent MATL from errors we always increase the iteration number by one.

@LuisMendo I should really start reading the docs better. Thanks.
Sanchises

This doesn't seem to work for the larger test cases, but I don't know enough about MATL/Matlab to know if that's caused by integer limits or not.
Mego

@Mego I tested my 13 byte version which should be equivalent to the current version up to 1e6, on MATLAB R2017a. What test setup resulted in problems for you?
Sanchises

The last 2 test cases cause errors.
Mego

@Mego Ah I didn't see those testcases before. This is due to the implementation of MATLs YA using doubles internally, so it can only handle inputs up to the maximum consecutive integer representable by a double (see flintmax). Does this invalidate the answer? In principle the algorithm works for arbitrary base, I've explicitly worked around another command that would only do up to base 36.
Sanchises

0

PHP, 59+1 bytes

using builtins, max base 36:

for($b=1;strpos(_.base_convert($argn,10,++$b),48););echo$b;

no builtins, 6360+1 bytes, any base:

for($n=$b=1;$n&&++$b;)for($n=$argn;$n%$b;$n=$n/$b|0);echo$b;

Run as pipe with -nR or try them online.



0

J, 26 bytes

]>:@]^:(0 e.]#.inv[)^:_ 2:

Would love to know if this can be improved.

The main verb is a the dyadic phrase:

>:@]^:(0 e.]#.inv[)^:_

which is given the input on the left and the constant 2 on the right. That main verb phrase then uses J's Do..While construct, incrementing the right y argument as long as 0 is an element of e. the original argument in base y.

Try it online!



0

Milky Way, 38 bytes

^^'%{255£2+>:>R&{~^?{_>:<;m_+¡}}^^^}

usage: ./mw base.mwg -i 3


Explanation

code                                 explanation                    stack layout

^^                                   clear the preinitialized stack []
  '                                  push the input                 [input]
   %{                              } for loop
     255£                             push next value from 0..254   [input, base-2]
         2+                           add 2 to the get the base     [input, base]
           >                          rotate stack right            [base, input]
            :                         duplicate ToS                 [base, input, input]
             >                        rotate stack right            [input, base, input]
              R                       push 1                        [input, base, input, 1]
               &{~             }      while ToS (=remainder) is true ...
                  ^                    pop ToS                      [input, base, number]
                   ?{         }        if ToS (=quotient) ...
                     _>:<;              modify stack                [input, base, number, base]
                           m            divmod                      [input, base, quotient, remainder]
                           _+¡         else: output ToS (0) + SoS and exit
                                ^^^   pop everything but the input.

I'm sure this can be shortened using a while-loop instead of a for loop, but I couldn't get it to work.



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.