最小零基数


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。这是故意这0既Truthy与Falsy这样的境地?
— 布赖恩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

Haskell,56 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,d为a+=c;b=d
— Felipe Nardi Batista

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

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


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

2

APL(Dyalog),20 19 字节

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

在线尝试!

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

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

怎么样?

1+⍣{~0∊⍺⊥⍣¯1⊢n}≢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.