Самая маленькая нулевая база


28

Учитывая положительное целое число n, выведите наименьшую базу, в b >= 2которой представление nв базе bбез начальных нулей не содержит a 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.
— Мего


1
@ Titus Это хороший момент. Я ограничу базу чем-то разумным.
— Mego

1
@Mego: Попробуйте 232792560. Это lcm 2,3, ..., 20, поэтому в каждой базе <= 20 он имеет 0 как наименее значащая цифра.
— Нейт

Ответы:


15

Pyth , 6 байт

f*FjQT

Проверьте все контрольные примеры.

Как это работает

f * FjQT ~ Полная программа.

f ~ Первое положительное целое число, если условие истинно.
   jQT ~ Ввод преобразуется в базу текущего элемента.
 * F ~ Продукт. Если список содержит 0, то это 0, иначе он строго положительный.
          0 -> Ложь; > 0 -> Правда.
        ~ Вывести результат неявно.

Хотя Pyth fработает 1, 2, 3, 4, ...(начиная с 1), Pyth рассматривает числа в базе 1 (унарные) как группу нулей, поэтому база 1 игнорируется.


Хорошее злоупотребление тем фактом, что представление Пайта в base-1 - все нули.
— Эрик Outgolfer

@EriktheOutgolfer Спасибо! Я добавлю объяснение по этому поводу.
— г-н Xcoder

Pyth - не единственный язык, унарное представление которого использует нули в качестве намеков на цифры : P
— Mego

Вы написали 0 -> Falsy; > 0 -> Truthy. Это преднамеренное, что 0и то, Truthyи другое Falsyв этой ситуации?
— Брайан Д.

@BrianJ Перед вторым есть >знак 0, который означает, что все, что выше 0, является правдой.
— г-н Xcoder

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
@ Это C .. он выдаст много предупреждений, но скомпилирует. пока вы найдете компилятор, который работает для вашего кода, у вас все в порядке
— Фелипе Нарди Батиста,

1
@ Blacksilver k%i- это троичная проверка здесь. Более читаемый вариант был бы k=(k%i?k:n*++i);или даже более понятен if(k%i){k=k;}else{k=n*++i;}.
— Кевин Круйссен,

1
Также вы можете играть в гольф как по 2 байта: так 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и я думаю, вы можете опустить скобки #.
— Лайкони

2
Преступный недооцененный until :: (a → Bool) → (a → a) → a → aэкономит четыре байта:f n=until(#n)(+1)2
— Линн







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 байта благодаря @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;}
— Невай

2

Japt , 8 байт

@ìX e}a2

Попробуйте онлайн!

объяснение

@    }a2

Вернуть первое число ( X) для прохождения функции, начиная с2

ìX

Преобразуйте входной номер в массив базовых Xцифр.

e

Проверьте правильность всех цифр.


Разве это не сработает, если массив содержит несколько кратных 10?
— Лохматый

@ Shaggy Насколько я понимаю, согласно комментариям OP, цифры для баз выше 9 не считаются нулями.
— Джастин Маринер

Ах, я вижу это сейчас. Есть проблема с формулировкой задачи, поэтому (или я просто слишком устал!).
— Лохматый

2

JavaScript (ES6), 43 41 37 байт

n=>(g=x=>x?g(x%b++?x/--b|0:n):b)(b=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 thanks to Felipe Nardi Batista.
-2 thanks to Lynn (and now this is a dupe of her solution :D)


59 bytes by changing a,b=a+c,d to a+=c;b=d
— Felipe Nardi Batista

I think you can replace while m>1 by while m (and then we’re tied!)
— Lynn

@Lynn That's why I commented on your solution, it would be exactly the same then.
— Erik the Outgolfer


1
@Lynn I already knew :p otherwise I'd have asked you to delete yours.
— Erik the Outgolfer

2

APL (Dyalog), 20 19 bytes

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

Try it online!

As usual, thanks to @Adám for helping out in chat and getting the code to work in TIO. Also, saving 1 byte.

This is tradfn (traditional function) body. To use it, you need to assign it a name (which is in TIO's header field), enclose it in ∇s (one before the name and one in TIO's footer field), and then call it using its name. Since it uses a quad (⎕) to take the user's input, it's called as f \n input instead of the usual f input

How?

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)

The function then returns the resulting base.


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.



Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.