Cơ sở tốt nhất là 10 người Hãy tiếp cận nó!


40

Đầu vào:

Một số nguyên dương n bao gồm các chữ số trong phạm vi 0-9 .

Thử thách:

Nếu d là chữ số cao nhất trong số nguyên, giả sử cơ sở của số là d + 1 . Ví dụ: nếu số nguyên là 1256 thì bạn sẽ giả sử nó ở cơ sở 7 , nếu là 10110 thì bạn sẽ giả sử đó là cơ số 2 (nhị phân) và nếu là 159 thì đó là số thập phân.

Bây giờ, hãy làm như sau cho đến khi bạn, 1: đạt số nguyên cơ số 10 hoặc 2: đạt số nguyên một chữ số.

  1. Chuyển đổi số nguyên từ cơ sở- (d + 1) sang cơ sở 10
  2. Tìm cơ sở của số nguyên mới này (một lần nữa, cơ sở- (d + 1) trong đó d là chữ số cao nhất trong số mới)
  3. Chuyển đến bước 1 .

Ví dụ:

Giả sử đầu vào là n = 413574 . Chữ số cao nhất d = 7 , vì vậy đây là cơ số 8 (bát phân). Chuyển đổi này thành thập phân và nhận được 137084 . Chữ số cao nhất d = 8 , vì vậy đây là cơ sở-9 . Chuyển đổi này thành số thập phân và nhận 83911 . Chữ số cao nhất là 9 , vì vậy đây là số thập phân và chúng tôi dừng lại. Đầu ra sẽ là 83911 .

Giả sử đầu vào là n = 13552 . Chữ số cao nhất là d = 5 , vì vậy đây là cơ số 6 . Chuyển đổi này thành số thập phân và nhận 2156 . Chữ số cao nhất d = 6 , vì vậy đây là cơ số 7 . Chuyển đổi này thành thập phân và nhận 776 . Chữ số cao nhất là d = 7 , vì vậy đây là cơ số 8 . Chuyển đổi này thành thập phân và nhận 510 . Chữ số cao nhất là d = 5 nên đây là cơ số 6 . Chuyển đổi này thành thập phân và nhận được 186 . Chữ số cao nhất là 8 , vì vậy đây là cơ sở 9 . Chuyển đổi này thành số thập phân và nhận được 159. Chữ số cao nhất là 9 , vì vậy đây là số thập phân và chúng tôi dừng lại. Đầu ra sẽ là 159 .

Giả sử đầu vào là n = 17 . Điều này sẽ cung cấp cho chúng tôi 15 , rồi 11 , rồi 3 , chúng tôi sẽ xuất ra vì đó là một chữ số.


Các trường hợp thử nghiệm:

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

Ghi chú:

  • Các quy tắc chuẩn về I / O, sơ hở, v.v. Bạn có thể lấy đầu vào làm chuỗi
  • Giải thích được khuyến khích
  • Bạn có thể sử dụng các lệnh chuyển đổi cơ sở dựng sẵn
    • Các giải pháp không sử dụng các hàm chuyển đổi cơ sở dựng sẵn của ngôn ngữ (nếu chúng tồn tại) đều được hoan nghênh, ngay cả khi chúng cuối cùng dài hơn nhiều so với cách tiếp cận rõ ràng sử dụng các hàm dựng sẵn.

Rõ ràng, đây là OEIS A091047 .


2
Rõ ràng tôi yêu ma trận , vì vậy tôi nghĩ rằng tôi sẽ thực hiện một thử thách chuyển đổi cơ sở .
Stewie Griffin

34
"Cơ sở tốt nhất là 10" ... "10" được viết trong cơ sở nào?
Olivier Grégoire

5
@ OlivierGrégoire Đó là điều thông minh ... Dù chúng ta có cơ sở nào đi chăng nữa, nó vẫn sẽ là một tuyên bố hợp lệ!
Stewie Griffin

@StewieGriffin Nhưng làm thế nào để bạn đọc nó? "10" có một tên khác nhau trong mỗi cơ sở.
dùng11153

10
Chà, điều đó phụ thuộc vào căn cứ ... hoặc như Meghan sẽ nói rằng "tất cả là về căn cứ đó, 'Bout căn cứ đó, không có rắc rối nào" ;-)
Stewie Griffin

Câu trả lời:


20

Toán học, 56 byte

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

Hãy thử trực tuyến! (Sử dụng toán học.)

Tôi nghĩ rằng tôi sẽ kiểm tra xem chuỗi này trông như thế nào:

nhập mô tả hình ảnh ở đây

Và đây là một chuỗi các bước cần thiết để tìm ra kết quả:

nhập mô tả hình ảnh ở đây

(Nhấp vào để xem phiên bản lớn hơn. Xem lịch sử sửa đổi cho các lô chỉ tối đa n = 1000. )

Trông giống như một hỗn hợp rất thú vị của cấu trúc quy mô lớn và sự hỗn loạn quy mô tốt. Tôi tự hỏi có gì với khoảng cách rộng hơn khoảng 30.000 và 60.000.


4
@StewieGriffin nên ở phía bên trái. Các lỗ hổng nhỏ ở đó, bởi vì các số dẫn đến bội số của lũy thừa 10 chứa a 9, vì vậy chúng đã ở trong căn cứ 10. Nhưng với 30k và 60k, dường như các số có 8 hoặc thậm chí 7 (sẽ phải kiểm tra) thay cho số 9 luôn luôn trở thành cơ sở 10 sau nhiều nhất một bước.
Martin Ender

@StewieGriffin Nói chính xác, tất cả các số trong phạm vi [28051, 28888] là cơ sở 9 và dịch sang các số có dạng 19xxx, do đó nhân đôi khoảng cách đó lên gấp đôi.
cmaster

À, hiểu rồi ... :) Đối với hồ sơ: Tôi biết tại sao lại có những khoảng trống ở bên trái sức mạnh của 10 ... Đó chỉ là những khoảng trống có kích thước gấp đôi kỳ lạ (tại sao 30/60 chứ không phải 20 / 40/50). Bây giờ tôi thấy các số trong phạm vi 28xxx -> 19xxx, nhưng 38xxx -> 26xxx, không phải 29xxx.
Stewie Griffin

10

Java 8, 172 166 163 152 151 140 138 116 114 99 byte

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

Lấy đầu vào là a String.

-64 byte nhờ @ OlivierGrégoire . Và ở đây tôi nghĩ rằng 172 ban đầu của tôi không quá tệ ..;)

Hãy thử nó ở đây.

Giải trình:

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
Hứa sẽ giữ bình tĩnh? : p Ok ... chúng ta hãy đi : s->{for(Integer b=0;b<10&s.length()>1;)s=""+b.valueOf(s,b=s.chars().max().getAsInt()-47);return s;}. Ngoài ra, tôi đã xóa hầu hết các nhận xét của mình vì hiện tại chúng hoàn toàn không liên quan ( blà cơ sở, của bạn aslà số chúng tôi đang làm việc).
Olivier Grégoire

1
Tôi đã cố gắng đệ quy lại điều này để loại bỏ một số byte bằng: Integer b;return(b=s.chars().max().getAsInt()-47)>9|s.length()<2?s:c(""+b.valueOf(s,b));(88), nhưng tôi hoàn toàn mới đối với môn đánh gôn. Đây là một snipppet, phải không? Có cách nào để khai báo đây là một phương thức mà không cần thêm public String c(String s)không?
Lord Farquaad

1
@LordFarquaad Bạn không cần public, nhưng tôi e rằng bạn thực sự sẽ phải sử dụng String c(String s){}cho các cuộc gọi đệ quy, ngay cả trong Java 8. Khi bạn tạo lambda bằng 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));}giao diện hoặc sử dụng 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));};nó sẽ đưa ra " tự tham chiếu trong trình khởi tạo lỗi "trong cả hai trường hợp. Nhưng cách tiếp cận rất tốt dù sao!
Kevin Cruijssen

À, tôi đoán là tôi đã vô hiệu hóa nó vài byte rồi. Nhưng cảm ơn vì sự giúp đỡ! Tôi sẽ ghi nhớ điều này trong tâm trí.
Lord Farquaad

8

Bình thường, 9 byte

ui`GhseS`

Bộ kiểm tra

Giải trình:

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

Thật kỳ lạ khi bạn sử dụng lambda hai biến kết thúc bằng một biến ... và nó không đưa ra lỗi. Ồ, hai biến là QQ, tôi hiểu rồi.
Erik the Outgolfer

@EriktheOutgolfer Không chính xác. ukhông có đầu vào thứ ba của nó được áp dụng cho đến khi lặp lại, trong khi với đầu vào thứ ba, nó được áp dụng một số lần cố định. ulambda có GH, nhưng bạn không cần sử dụng H.
isaacg

Trên thực tế, thay thế Gbằng Hsẽ có kết quả tương tự ... btw biến ẩn là G?
Erik the Outgolfer

@EriktheOutgolfer Biến ẩn là G, có. Hđếm từ 0 với mỗi lần lặp, vì vậy nó hoàn toàn khác nhau. Tôi không thực sự chắc chắn những gì bạn đang nói về. Đây là một chương trình ví dụ để cho bạn thấy những gì đang diễn ra: pyth.herokuapp.com/,
isaacg

6

JavaScript (ES6), 63 57 54 53 byte

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

Đã lưu 8 byte nhờ Shaggy và Dom Hastings

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

console.log(f("413574"))


Đánh tôi với nó Tôi nghĩ rằng bạn có thể tiết kiệm một vài byte với +a>9||b<9và đảo ngược ternary.
Xù xì

1
@Shaggy chỉnh sửa: Tôi thật ngốc
Tom

1
Đừng quá khó khăn với chính mình Tom! Bạn không ngu ngốc ,,, nhưng bạn chắc chắn không thông minh như @Shaggy!
Stewie Griffin

1
Thay thế cho 55 bytef=n=>n>9&&(k=Math.max(...n+"")+1)<10?f(parseInt(n,k)):n
Dom Hastings

@DomHastings Cảm ơn những cải tiến! :)
Tom

5

Python 3 , 91 78 76 75 73 byte

@Emigna cạo đi 5 byte. @FelipeNardiBatista đã lưu 1 byte. @ RomanGräf đã lưu 2 byte

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

Hãy thử trực tuyến!


Giải trình

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 byte

5 byte được lưu nhờ Magic Octopus Urn

F§Z>ö

Vì điều này phát triển rất chậm cho đầu vào lớn, tôi sẽ để phiên bản cũ nhanh hơn nhiều ở đây để thử nghiệm. Thuật toán là như nhau, chỉ có số lần lặp khác nhau.

[©Z>öD®Q#§

Hãy thử trực tuyến!

Giải trình

[             # 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)

Ngoài ra, bạn không thể sử dụng тFZ>ö§? Xem như số lần lặp ( như đã thấy ở đây ) dường như cao nguyên? Nếu bạn muốn có được kỹ thuật, tốc độ lặp lại có thể là logarit ... Vì vậy, bạn có thể sử dụng một cái gì đó như: DFZ>ö§và nói rằng nó sẽ không chạy lớn n. HOẶC thậm chí có thể: T.n>FZ>ö§để tính trực tiếp số lần lặp là log_10(n).
Bạch tuộc ma thuật Urn

@MagicOctopusUrn: Vâng, bây giờ bạn đề cập đến nó, vì trình tự chắc chắn có vẻ chậm hơn tuyến tính, F§Z>önên thực hiện thủ thuật.
Emigna

Tôi nghĩ rằng bạn có thể loại bỏ §.
Erik the Outgolfer 19/07/17

@EriktheOutgolfer: Thật không may. Nếu chúng ta loại bỏ §, Zsẽ lấy số cao nhất trên ngăn xếp thay vì chữ số cao nhất trong số trên đầu ngăn xếp.
Emigna


3

APL (Dyalog) , 20 16 byte

Lấy và trả về một chuỗi

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

(... )⍣≡ áp dụng các chức năng sau đây cho đến hai nhiệm kỳ liên tiếp là giống hệt nhau:

⍎¨ thực hiện mỗi ký tự (biến chuỗi thành một danh sách các số)

(... ) áp dụng các chức năng ngầm sau đó:

  ⌈/ tìm tối đa của đối số

  1+ cộng một

  ⊢⊥⍨ đánh giá lập luận trong cơ sở đó

   định dạng (xâu chuỗi, để chuẩn bị cho một ứng dụng khác của hàm ngoài)

Hãy thử trực tuyến!



3

Toán học, 52 byte

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

Hàm thuần túy lấy một số nguyên không âm làm đầu vào và trả về một số nguyên không âm. Sử dụng cơ chế cốt lõi FromDigits[s=IntegerDigits@#,Max@s+1]giống như câu trả lời của Jenny_mathy , nhưng khai thác FixedPointđể thực hiện việc lặp lại.


3

Perl 6 , 49 byte

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

Kiểm tra nó

Mở rộng:

{
  (

    $_,                 # 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

Pip , 17 byte

Wa>9>YMXaaFB:1+ya

Đưa đầu vào làm đối số dòng lệnh. Hãy thử trực tuyến!

Giải trình

Điều này thật thú vị - tôi đã rút ra các toán tử so sánh chuỗi.

Chúng tôi muốn lặp cho đến khi số đó là một chữ số HOẶC chứa 9. Tương đương, chúng tôi muốn lặp trong khi số đó có nhiều chữ số VÀ không chứa 9. Tương đương, lặp trong khi số lớn hơn 9 VÀ chữ số tối đa là ít hơn 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 byte

Đã lưu 4 byte nhờ Felipe Nardi Batista
Lưu 3 byte nhờ vào lò nướng

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

Hãy thử trực tuyến!

Sử dụng lambda đệ quy, so sánh kết quả của chuyển đổi cơ sở với lần lặp trước.


tại sao không sử dụng x==y and x or ...như xsẽ không bao giờ được 0(cơ sở 1). hoặc thậm chí(x==y)*x or ...
Felipe Nardi Batista

@FelipeNardiBatista: Cảm ơn! Tôi đã thử x and x==y or ...mà không hiệu quả, nhưng tôi không thành thạo các thủ thuật này vì vậy tôi không nhận ra mình có thể đảo ngược nó :)
Emigna

@ovs: Đúng rồi bạn. Cảm ơn!
Emigna

@FelipeNardiBatista "Đầu vào: Một số nguyên dương n bao gồm các chữ số trong phạm vi 0-9." 0 vẫn là đầu vào hợp lệ và bây giờ mã từ chối nó.
Cột

@Mast: May mắn thay cho chúng tôi, 0 không phải là số nguyên dương nên sẽ không được cung cấp làm đầu vào.
Emigna

2

C #, 257 244 243 244 233 222 byte

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;};

Chà, C # luôn mất rất nhiều byte nhưng điều này thật vô lý. Không có phần mềm dựng sẵn nào có thể xử lý một cơ sở tùy ý, vì vậy tôi phải tự tính toán chuyển đổi. Ung dung:

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

Toán học, 92 byte

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) với chức năng mũi tên 0, 74 byte

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

3
Chào mừng đến với PPCG! :) Đây có lẽ là một câu trả lời rất hay, nhưng tôi không thể nói mà không có lời giải thích. Tôi (và có lẽ những người khác) không bao giờ nêu lên câu trả lời không chứa lời giải thích.
Stewie Griffin

1
Tại sao bạn gọi f('11')sau chức năng? Trừ khi tôi thiếu một cái gì đó chỉ có vẻ là việc sử dụng không thực sự là một phần của bài nộp. Nếu vậy, bạn nên lấy nó ra khỏi phần mã và đưa nó vào phần giải thích của bạn (khi bạn thêm một) và cập nhật số byte của bạn thành 67.
PunPun1000

1

K4 , 19 byte

Giải pháp:

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

Ví dụ:

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    

Giải trình:

Sử dụng tích /:hợp để chuyển đổi cơ sở.

{(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

Kotlin , 97 byte

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

Làm đẹp

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

Kiểm tra

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()
        }
    }
}

TIO

Dùng thử




0

C, 159 157 byte

#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 byte

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+"")}

Hãy thử trực tuyến!

Scala , 119 byte

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+"")

Hãy thử trực tuyến!

Cả hai phương thức đều hoạt động theo cùng một cách, nhưng trong phương thức thứ nhất tôi đặt x.length-1một biến và trong phương thức thứ hai thì không.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.