Найкраща база - 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().ge‌tAsInt()-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.