Найкраща база - 10… Давай до неї!


40

Вхід:

Позитивне ціле число n, що складається з цифр у діапазоні 0-9 .

Виклик:

Якщо d є найвищою цифрою в цілому числу, припустимо, основою числа є d + 1 . Наприклад, якщо ціле число дорівнює 1256, то слід припустити, що воно знаходиться в базі-7 , якщо це 10110, тоді ви вважаєте, що це основа-2 (двійкове), а якщо це 159, то це десятковий.

Тепер виконайте наступне, поки ви не: 1: досягнете базового цілого числа або 2: не досягнете одноцифрового цілого числа.

  1. Перетворимо ціле число з бази- (d + 1) в основу-10
  2. Знайдіть базу цього нового цілого числа (знову ж таки, base- (d + 1), де d - найбільша цифра в новому числі)
  3. Перейдіть до першого кроку .

Приклади:

Припустимо, вхід n = 413574 . Найвища цифра d = 7 , тому це основа-8 (вісімка). Перетворіть це в десятковий і отримайте 137084 . Найвища цифра d = 8 , тому це база-9 . Перетворіть це в десятковий і отримайте 83911 . Найвища цифра - 9 , тому це десятковий номер і ми зупиняємось. Вихід повинен бути 83911 .

Припустимо, вхід n = 13552 . Найвища цифра d = 5 , тому це база-6 . Перетворіть це в десятковий і отримайте 2156 . Найвища цифра d = 6 , тому це база-7 . Перетворіть це в десятковий і отримайте 776 . Найвища цифра d = 7 , тому це база-8 . Перетворіть це в десятковий і отримайте 510 . Найвища цифра d = 5, тому це основа-6 . Перетворіть це в десятковий і отримайте 186 . Найвища цифра - 8 , тому це база-9 . Перетворіть це в десятковий і отримайте 159. Найвища цифра - 9 , тому це десятковий номер і ми зупиняємось. Вихід повинен бути 159 .

Припустимо, вхід n = 17 . Це дасть нам 15 , потім 11 , потім 3 , які ми виведемо, оскільки це одна цифра.


Тестові приклади:

5
5

17
3

999
999

87654321  (base-9 -> 42374116 in decimal -> base-7 -> 90419978 in decimal) 
9041998

41253  (5505 -> 1265 -> 488 -> 404 -> 104 -> 29)
29

Примітки:

  • Стандартні правила щодо вводу / виводу, лазівки тощо. Ви можете вводити введення як рядок
  • Пояснення заохочуються
  • Ви можете використовувати вбудовані команди базового перетворення
    • Вітаються рішення, які не використовують вбудовані функції мови в базовій конверсії (якщо вони існують), навіть якщо вони виявляються набагато довшими, ніж очевидний підхід із використанням вбудованих функцій.

Мабуть, це OEIS A091047 .


2
Мабуть, я люблю матриці , тому я подумав, що замість цього викличу базову конверсію .
Стюі Гріффін

34
"Найкраща основа - 10" ... "У якій базі записано" 10 "?
Олів’є Грегоар

5
@ OlivierGrégoire Це розумна річ ... Якою б базою ми не закінчилися, це все ще буде дійсним твердженням!
Стюі Гріффін

@StewieGriffin Але як це читати? "10" має різну назву в кожній базі.
користувач11153

10
Ну, це залежить від бази ... або як би сказала Меган, "це все в тій базі, але про цю базу, не біда" ;-)
Стюі Гріффін

Відповіді:


20

Математика, 56 байт

#//.x_/;(b=Max[d=IntegerDigits@x]+1)<11:>d~FromDigits~b&

Спробуйте в Інтернеті! (Використання математики.)

Я думав перевірити, як виглядає послідовність:

введіть тут опис зображення

Ось сюжет кількості кроків, які потрібно зробити, щоб знайти результат:

введіть тут опис зображення

(Клацніть для більшої версії. Перегляньте історію редагувань сюжетів лише до n = 1000. )

Виглядає як дуже цікава суміш великої масштабної структури та тонкого хаосу. Цікаво, що з ширшими розривами близько 30 000 і 60 000.


4
@StewieGriffin має бути з лівого боку. Невеликі прогалини є, тому що числа, що призводять до кратного потужності 10, містять a 9, тому вони вже є в базі 10. Але для 30k і 60k здається, що числа з 8 або навіть 7 (повинні були б Перевірте) замість цього 9 завжди стає базовою 10, щонайменше, після одного кроку
Мартін Ендер

@StewieGriffin Якщо бути точним, всі числа в діапазоні [28051, 28888] є базовими 9 і переводяться на числа форми 19xxx, таким чином, значно подвоївши цей проміжок.
cmaster

Ах, зрозумів ... :) Для запису: я знав, чому в лівій частині потужностей 10-х років з'явилися прогалини ... Дивними були лише розриви подвійного розміру (чому 30/60, а не 20 / 40/50). Зараз я бачу, що ці числа в діапазоні 28xxx -> 19xxx, але 38xxx -> 26xxx, а не 29xxx.
Стюі Гріффін

10

Java 8, 172 166 163 152 151 140 138 116 114 99 байт

s->{for(Integer b=0;b<10&s.length()>1;s=""+b.valueOf(s,b=s.chars().max().getAsInt()-47));return s;}

Приймає введення як a String.

-64 байти завдяки @ OlivierGrégoire . І тут я подумав, що мої початкові 172 не надто погані ..;)

Спробуйте тут.

Пояснення:

s->{                    // Method with String as parameter and return-type
  for(Integer b=0;b<10  //  Loop as long as the largest digit + 1 is not 10
      &s.length()>1;    //  and as long as `s` contains more than 1 digit
    s=""+               //   Replace `s` with the String representation of:
         b.valueOf(s,   //    `s` as a Base-`b` integer
          b=s.chars().max().getAsInt()-47)
                        //     where `b` is the largest digit in the String + 1
  );                    //  End of loop
  return s;             //  Return result-String
}                       // End of method

1
Обіцяєте зберігати спокій? : Р Добре ... підемо: s->{for(Integer b=0;b<10&s.length()>1;)s=""+b.valueOf(s,b=s.chars().max().getAsInt()-47);return s;}. Також я видалив більшість своїх коментарів, оскільки вони зараз абсолютно не мають значення ( bце база, ваше a; і sце число, над яким ми працюємо).
Олів'є Грегоар

1
Я намагався рекурсифікувати це, щоб відголити деякі байти за допомогою: Integer b;return(b=s.chars().max().getAsInt()-47)>9|s.length()<2?s:c(""+b.valueOf(s,b));(88), але я абсолютно новий в коді гольфу. Це фрагмент, правда? Чи є спосіб оголосити це як метод, не потребуючи додавання public String c(String s)?
Лорд Фарквад

1
@LordFarquaad Вам не потрібен public, але я боюся, що вам дійсно доведеться використовувати String c(String s){}для рекурсивних дзвінків, навіть на Java 8. Коли ви створюєте лямбда за допомогою java.util.function.Function<String, String> c=s->{Integer b;return(b=s.chars().max().getAsInt()-47)>9|s.length()<2?s:c‌.apply​(""+b.valueOf(s,b));}або інтерфейс, використовуючи interface N{String c(String s);}N n = s->{Integer b;return(b=s.chars().max().getAsInt()-47)>9|s.length()<2?s:n.c‌​(""+b.valueOf(s,b));};його, дасть " самопосилання в ініціалізаторі" помилка "в обох випадках. Але все-таки дуже приємний підхід!
Kevin Cruijssen

Ага, мабуть, тоді я зняв це кілька байтів. Але дякую за допомогу! Я матиму це на увазі, рухаючись вперед.
Lord Farquaad

8

Pyth, 9 байт

ui`GhseS`

Тестовий набір

Пояснення:

ui`GhseS`
ui`GhseS`GQ    Implicit variable introduction
u         Q    Repeatedly apply the following function until the value repeats,
               starting with Q, the input.
        `G     Convert the working value to a string.
      eS       Take its maximum.
     s         Convert to an integer.
    h          Add one.
 i`G           Convert the working value to that base

Це трохи дивно, як ви використовували двозмінну лямбда в кінці, використовуючи одну змінну ... і це не кидало помилок. О, дві змінні є, Qі Qя розумію.
Ерік Аутгольфер

@EriktheOutgolfer Не зовсім. uбез третього введення застосовується до повторення, тоді як при третьому введенні його застосовують фіксовану кількість разів. uлямбда має Gі H, але вам не потрібно використовувати H.
isaacg

Насправді заміна Gна Hмав би такий самий результат ... btw неявна змінна є G?
Ерік Аутгольфер

@EriktheOutgolfer Неявна змінна - Gтак. Hнараховується від 0 при кожній ітерації, тож це зовсім інше. Я не дуже впевнений, про що ти говориш. Ось приклад програми, щоб показати вам, що відбувається: pyth.herokuapp.com/…
isaacg

6

JavaScript (ES6), 63 57 54 53 байт

f=a=>a>9&(b=Math.max(...a+""))<9?f(parseInt(a,b+1)):a

Збережено 8 байт завдяки Шаггі та Дому Гастінгсу

f=a=>a>9&(b=Math.max(...a+""))<9?f(parseInt(a,b+1)):a;

console.log(f("413574"))


Бий мене до цього. Я думаю, що ти міг би зберегти кілька байт +a>9||b<9і повернути назад трійку.
Кудлатий

1
@Shaggy редагувати: Я німий
Том

1
Не будь настільки жорсткий до себе Том! Ви не дурні ,,, але ви точно не такі розумні, як @Shaggy!
Стюі Гріффін

1
Альтернатива для 55 байтf=n=>n>9&&(k=Math.max(...n+"")+1)<10?f(parseInt(n,k)):n
Dom Hastings

@DomHastings Дякую за покращення! :)
Том

5

Пітон 3 , 91 78 76 75 73 байт

@Emigna поголив 5 байт. @FelipeNardiBatista зберег 1 байт. @ RomanGräf врятував 2 байти

i=input()
while'9'>max(i)and~-len(i):i=str(int(i,int(max(i))+1))
print(i)

Спробуйте в Інтернеті!


Пояснення

i=input()                                  - takes input and assigns it to a variable i
while '9'>max(i)and~-len(i):               - repeatedly checks if the number is still base-9 or lower and has a length greater than 1
    i=str(...)                             - assigns i to the string representation of ...
          int(i,int(max(i))+1)             - converts the current number to the real base 10 and loops back again
print(i)                                   - prints the mutated i

5

05AB1E , 10 5 байт

5 байт збережено завдяки чарівної урни восьминога

F§Z>ö

Оскільки це дуже повільно зростає для великих вкладень, я залишаю стару набагато швидшу версію для тестування. Алгоритм однаковий, відрізняється лише кількість ітерацій.

[©Z>öD®Q#§

Спробуйте в Інтернеті!

Пояснення

[             # start a loop
 ©            # store a copy of the current value in the register
  Z>          # get the maximum (digit) and increment
    ö         # convert the current value to base-10 from this base
     D        # duplicate
      ®Q#     # break loop if the new value is the same as the stored value
         §    # convert to string (to prevent Z from taking the maximum int on the stack)

Крім того, ви не можете просто використовувати тFZ>ö§? Бачачи, як кількість ітерацій ( як це бачимо тут ) здається плато? Якщо ви хочете отримати технічну інформацію, швидкість, з якою піднімаються ітерації, ймовірно, логарифмічна ... Отже, ви можете просто використовувати щось на кшталт: DFZ>ö§і заявити, що воно не буде працювати великим n. А може, навіть: T.n>FZ>ö§безпосередньо обчислити кількість ітерацій як log_10(n).
Magic Octopus Urn

@MagicOctopusUrn: Так, тепер, коли ви згадуєте про це, оскільки послідовність, безумовно, здається повільнішою, ніж лінійна, F§Z>öслід зробити трюк.
Емінья

Я думаю, ви можете видалити §.
Ерік Аутгольфер

@EriktheOutgolfer: На жаль, ні. Якщо ми видалимо §, Zбуде взято найбільше число в стеку замість найвищої цифри цифри вгорі стека.
Емінья


3

APL (Dyalog) , 20 16 байт

Бере і повертає рядок

((⍕⊢⊥⍨1+⌈/)⍎¨)⍣≡

()⍣≡ Застосовувати таку функцію, поки два послідовні умови не будуть однаковими:

⍎¨ виконати кожен символ (перетворює рядок у список чисел)

() Застосувати до цього таку негласну функцію:

  ⌈/ знайти максимум аргументу

  1+ додати одну

  ⊢⊥⍨ оцініть аргумент на цій базі

   формат (розшифруйте під час підготовки до іншого застосування зовнішньої функції)

Спробуйте в Інтернеті!



3

Математика, 52 байти

FromDigits[s=IntegerDigits@#,Max@s+1]&~FixedPoint~#&

Чиста функція, що приймає як вхідне ціле невід’ємне ціле число і повертає негативне ціле число. Використовує той же основний механік FromDigits[s=IntegerDigits@#,Max@s+1]як відповідь Jenny_mathy в , але використовує FixedPointдля виконання ітерації.


3

Perl 6 , 49 байт

{($_,{.Str.parse-base(1+.comb.max)}...*==*).tail}

Перевірте це

Розширено:

{
  (

    $_,                 # seed the sequence with the input

    {
      .Str
      .parse-base(      # parse in base:
        1 + .comb.max   # largest digit + 1
      )
    }

    ...                 # keep generating values until

    * == *              # two of them match (should only be in base 10)

  ).tail                # get the last value from the sequence
}


2

Піп , 17 байт

Wa>9>YMXaaFB:1+ya

Вводиться як аргумент командного рядка. Спробуйте в Інтернеті!

Пояснення

Це було весело - мені довелося витягти операторів порівняння ланцюгів.

Ми хочемо циклічно, поки число не буде одноцифровим АБО не містить 9. Еквівалентно, ми хочемо циклічно, поки число є багатозначним І не містить 9. Еквівалентно, циклічне, тоді як число більше 9 І максимальна цифра дорівнює менш ніж 9: a>9>MXa.

Wa>9>YMXaaFB:1+ya
                   a is 1st cmdline arg (implicit)
     YMXa          Yank a's maximum digit into the y variable
Wa>9>              While a is greater than 9 and 9 is greater than a's max digit:
         aFB:1+y    Convert a from base 1+y to decimal and assign back to a
                a  At the end of the program, print a

2

Python 2 , 60 59 56 53 байт

Збережено 4 байти завдяки Felipe Nardi Batista.
Збережено 3 байти завдяки ovs

f=lambda x,y=0:x*(x==y)or f(`int(x,int(max(x))+1)`,x)

Спробуйте в Інтернеті!

Використовуючи рекурсивну лямбда, порівнюючи результат базової конверсії з попередньою ітерацією.


чому б не використовувати так, x==y and x or ...як xніколи не буде 0(база 1). чи навіть(x==y)*x or ...
Феліпе Нарді Батіста

@FelipeNardiBatista: Дякую! Я спробував, x and x==y or ...що не вийшло, але я не надто знаю ці хитрощі, тому не зрозумів, що зможу це переламати :)
Emigna

@ovs: Право ти є. Дякую!
Емінья

@FelipeNardiBatista "Введення: додатне ціле число n, що складається з цифр у діапазоні 0-9." 0 все ще є дійсним введенням, і тепер код відкидає його.
Щогла

@Mast: На щастя для нас, 0 не є додатним цілим числом, тому його не подаватимуть як вхідний.
Емінья

2

C #, 257 244 243 244 233 222 байти

using System.Linq;z=m=>{int b=int.Parse(m.OrderBy(s=>int.Parse(s+"")).Last()+""),n=0,p=0;if(b<9&m.Length>1){for(int i=m.Length-1;i>=0;i--)n+=int.Parse(m[i]+"")*(int)System.Math.Pow(b+1,p++);return z(n+"");}else return m;};

Ну, C # завжди займає багато байтів, але це просто смішно. Жоден із вбудованих не може обробляти довільну базу, тому мені довелося самому обчислити перетворення. Безголовки:

using System.Linq;
z = m => {
int b = int.Parse(m.OrderBy(s => int.Parse(s + "")).Last()+""), n = 0, p = 0; //Get the max digit in the string
if (b < 9 & m.Length > 1) //if conditions not satisfied, process and recurse
{
    for (int i = m.Length - 1; i >= 0; i--)
        n += int.Parse(m[i] + "") * (int)System.Math.Pow(b+1, p++); //convert each base-b+1 representation to base-10
    return z(n + ""); //recurse
}
else return m; };

1

Математика, 92 байти

f[x_]:=FromDigits[s=IntegerDigits@x,d=Max@s+1];(z=f@#;While[d!=10&&Length@s>1,h=f@z;z=h];z)&

1

Javascript (ES6) з функцією 0 стрілок, 74 байти

function f(a){a>9&&b=Math.max(...a)<9&&f(parseInt(a,b+1));alert(a)}f('11')

3
Ласкаво просимо до PPCG! :) Це, мабуть, дуже приємна відповідь, але я не можу сказати без пояснень. Я (і, мабуть, інші) ніколи не підтримую відповіді, які не містять пояснень.
Стюі Гріффін

1
Чому ви дзвоните f('11')після функції? Якщо я не пропускаю щось, що виглядає лише як використання, насправді не є частиною подання. Якщо це так, вам слід вийняти його з розділу коду і ввести його у своє пояснення (коли ви додасте його) та оновити кількість байтів до 67.
PunPun1000

1

К4 , 19 байт

Рішення:

{(1+|/x)/:x:10\:x}/

Приклади:

q)\
  {(1+|/x)/:x:10\:x}/413574
83911
  {(1+|/x)/:x:10\:x}/13552
159
  {(1+|/x)/:x:10\:x}/17
3
  {(1+|/x)/:x:10\:x}/41253
29    

Пояснення:

Використовуйте /:вбудований для перетворення бази.

{(1+|/x)/:x:10\:x}/ / the solution
{                }/ / converge lambda, repeat until same result returned
            10\:x   / convert input x to base 10 (.:'$x would do the same)
          x:        / store in variable x
 (     )/:          / convert to base given by the result of the brackets
    |/x             / max (|) over (/) input, ie return largest
  1+                / add 1 to this

1

Котлін , 97 байт

fun String.f():String=if(length==1||contains("9"))this else "${toInt(map{it-'0'}.max()!!+1)}".f()

Прикрасили

fun String.f(): String = if (length == 1 || contains("9")) this else "${toInt(map { it - '0' }.max()!! + 1)}".f()

Тест

fun String.f():String=if(length==1||contains("9"))this else "${toInt(map{it-'0'}.max()!!+1)}".f()
val tests = listOf(
        5 to 5,
        17 to 3,
        999 to 999,
        87654321 to 9041998,
        41253 to 29
)

fun main(args: Array<String>) {
    tests.forEach { (input, output) ->
        val answer = input.toString().f()
        if (answer != output.toString()) {
            throw AssertionError()
        }
    }
}

ТІО

TryItOnline




0

C, 159 157 байт

#include <stdlib.h>
char b[99];i=0;m=-1;c(n){do{m=-1;sprintf(b,"%d",n);i=0;while(b[i]){m=max(b[i]-48,m);i++;}n=strtol(b,0,++m);}while(b[1]&&m<10);return n;}

0

Scala , 119 байт

if(x.max==57|x.length==1)x else{val l=x.length-1
f((0 to l).map(k=>(((x(k)-48)*math.pow(x.max-47,l-k))) toInt).sum+"")}

Спробуйте в Інтернеті!

Scala , 119 байт

if(x.max==57|x.length==1)x else f((0 to x.length-1).map(k=>(((x(k)-48)*math.pow(x.max-47,x.length-1-k))) toInt).sum+"")

Спробуйте в Інтернеті!

Обидва методи працюють однаково, але в першому я ввожу x.length-1змінну, а в другому - ні.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.