Tất cả cơ sở phỏng đoán của bạn thuộc về chúng tôi


25

Lý lịch

Một số b cơ sở tính từ , trong đó b là một số nguyên dương, là một ký hiệu vị trí phỏng đoán sử dụng các ký hiệu b với các giá trị liên quan từ 1 đến b .

Không giống như đối tác không tính toán của nó, không có biểu tượng nào có giá trị 0 . Theo cách này, mỗi số nguyên n không âm có một biểu diễn duy nhất trong cơ sở tính toán b .

Các số tính toán phổ biến bao gồm unary, cơ sở bijective 2 (được sử dụng trong mã hóa độ dài chạy của bzip2 ) và cơ sở phỏng đoán 26 (được sử dụng để đánh số cột trong bảng tính).

Định nghĩa

Trong thử thách này, chúng tôi xác định tập hợp M của các ký hiệu là

123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz<=>

và một hàm i từ M đến số tự nhiên sao cho i ('1') = 1, Mạnh, i ('>') = 64 .

Cho một b cơ sở từ 1 đến 64 (bao gồm cả hai), chúng tôi xác định rằng mỗi số nguyên n không âm tương ứng với chuỗi a k K a a 0 , bao gồm các ký hiệu của M , sao cho n = b k i (a k ) + Cẩu + b 0 i (a 0 ) .

Sự tương ứng này được xác định rõ và phỏng đoán. Vì một tổng trống được định nghĩa là 0 , số nguyên 0 có thể được mã hóa thành một chuỗi rỗng.

Bài tập

Chấp nhận ba chuỗi làm đầu vào:

  • Một cơ sở đầu vào b từ 1 đến 64 , được mã hóa dưới dạng chuỗi 64 cơ sở phỏng đoán .

  • Một số nguyên n không âm , được mã hóa dưới dạng một chuỗi b cơ sở sinh học .

  • Một cơ sở đầu ra B nằm trong khoảng từ 1 đến 64 , được mã hóa dưới dạng chuỗi 64 cơ sở phỏng đoán .

Cho ba đầu vào này, mã hóa n dưới dạng chuỗi B cơ sở tính toán .

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

Tất cả các trường hợp thử nghiệm xác định đầu vào theo thứ tự b , n , B .

Input:  "4" "" "8"
Output: ""

Input:  "A" "16" "2"
Output: "1112"

Input:  "2" "122" "A"
Output: "A"

Input:  "3" "31" "1"
Output: "1111111111"

Input:  ">" "Fe" "a"
Output: "RS"

Quy tắc

  • Bạn có thể đọc ba chuỗi theo bất kỳ thứ tự thuận tiện nào, như vậy, một chuỗi các chuỗi, biểu diễn chuỗi của chúng, được nối hoặc phân tách bằng các ký tự phân cách một ký tự bạn chọn.

  • Nếu bạn chọn in đầu ra thành STDOUT, bạn chỉ có thể in các ký hiệu và (tùy chọn) một dòng mới.

  • Chuyển đổi cơ sở tích hợp tất cả các loại được cho phép.

  • Tiêu chuẩn quy tắc áp dụng.

Câu trả lời:


6

CJam, 43

qA,s"?[a{A<":,:^+:Mf#):B;(bLa{(Bmd)M=\j\+}j

3 byte bị xóa với sự giúp đỡ từ Dennis :) Hãy thử trực tuyến

Giải trình:

Đầu vào được lấy dưới dạng bnB, nối thành một chuỗi.

q           read the input
A,s         make an array of numbers from 0 to 9 and convert to string
"?[a{A<"    push this string, which contains the ends of 3 character ranges:
             uppercase letters: ['A'…'[')
             lowercase letters: ['a'…'{')
             "<=>": ['<'…'?')
             they're in a special order for the symmetric difference below
:,          for each character, make a range of all characters smaller than it
:^          fold/reduce these 6 ranges using symmetric difference
+           concatenate with the digits before
:M          save in M; this is like the M from the statement,
             except it starts with a zero (for matching indexes)
f#          find the indexes in M of all characters from the input string
)           take out the last value from the array
:B;         save it in B and pop it
(           take out the first value
b           use it as a base and convert the remaining array to a number
             this works even if some of the digits are not in the "normal" range
La{…}j      calculate with memoized recursion, using an empty string for value 0
  (         decrement the number
  Bmd       divide by B and get the quotient and remainder
  )         increment the remainder (this is the last digit in bijective base B)
  M=        get the corresponding character from M
  \j        swap with the quotient, and convert the quotient recursively
  \+        swap again and concatenate

Ồ, bạn thực sự có thể sử dụng toán tử chuyển đổi cơ sở thông thường cho chuyển đổi cơ sở đầu tiên? Bây giờ tôi cảm thấy ngớ ngẩn vì đã sử dụng tất cả các mã tôi có trong giải pháp của mình. :) Tôi đã không nhận ra rằng nó sẽ hoạt động với các giá trị nằm ngoài phạm vi của cơ sở. Chà, nhìn chung, không có lý do chính đáng tại sao nó không nên.
Reto Koradi

@RetoKoradi vâng, bạn có thể làm điều đó; một ngày nào đó nó sẽ được ghi lại :)
aditsu

Bạn có phiền nếu tôi thay đổi giải pháp của mình để sử dụng chuyển đổi cơ sở không? Tôi thường cố gắng tránh lấy ý tưởng từ các giải pháp khác. Nhưng nó thực sự làm tôi khó chịu khi để tôi đứng vững với cách tiếp cận tối ưu như vậy. Rất có khả năng giải pháp của bạn sẽ vẫn ngắn hơn.
Reto Koradi

@RetoKoradi không có vấn đề gì, hãy tiếp tục
aditsu

4

Pip, 84 80 78 byte

m:J[,tAZLCAZ"<=>"]p:$+(m@?^b)*(m@?a)**RV,#bs:m@?cWn:px:(mn-(p:n//s-!n%s)*s).xx

Kho GitHub cho Pip

Các thuật toán thích nghi từ bài viết Wikipedia. Đây là lời giải thích cho một phiên bản trước đó hơi vô căn cứ:

                 Implicit: initialize a,b,c from cmdline args; t=10;
                 AZ=uppercase alphabet; x=""
m:               Build lookup table m:
 (J,t)             0123456789 (i.e. join(range(10)))...
 .AZ               plus A-Z...
 .LCAZ             plus lowercase a-z...
 ."<=>"            plus <=>
f:{              Define f(a,b) to convert a from bijective base b to decimal:
 $+                Sum of...
  (m@?^a)            list of index of each character of a in m
  *                  multiplied item-wise by 
  b**RV,#a           b to the power of each number in reverse(range(len(a)))
}
t:{              Define t(a,b) to convert a from decimal to bijective base b:
 x:""              Reset x to empty string (not needed if only calling the function once)
 Wa{               While a is not zero:
  p:a//b-!a%b        p = ceil(a/b) - 1 (= a//b if a%b!=0, a//b-1 otherwise)
  x:m@(a-p*b).x      Calculate digit a-p*b, look up the corresponding character in m, and
                     prepend to x
  a:p                p becomes the new a
 }
 x                 Return x
}
(t               Return result of calling t with these arguments:
 (f                Result of calling f with these arguments:
  b                  2nd cmdline arg
  m@?a)              1st cmdline arg's decimal value
 m@?c              3rd cmdline arg's decimal value
)
                 Print (implicit)

Chạy mẫu:

dlosc@dlosc:~/golf$ python pip.py bijectivebase.pip ">" "Fe" "a"
RS

4

Octave, 166 byte

function z=b(o,x,n)
M=['1':'9','A':'Z','a':'z','<=>'];N(M)=1:64;n=N(n);x=polyval(N(x),N(o));z='';while x>0 r=mod(x,n);t=n;if r t=r;end;z=[M(t),z];x=fix(x/n)-(r<1);end

Phiên bản nhiều dòng:

function z=b(o,x,n)
   M=['1':'9','A':'Z','a':'z','<=>'];
   N(M)=1:64;
   n=N(n);
   x=polyval(N(x),N(o));
   z='';
   while x>0
      r=mod(x,n);
      t=n;if r t=r;end;
      z=[M(t),z];
      x=fix(x/n)-(r<1);
   end
%end // implicit - not included above

Thay vì tạo bản đồ để chuyển đổi một ký tự thành giá trị chỉ mục, tôi chỉ tạo bảng tra cứu ngược Ncho các giá trị ascii 1..'z'và điền nó với các chỉ số ở các giá trị thích hợp.

polyval đánh giá phương trình

c 1 x k + c 2 x k-1 + ... + c k x 0

sử dụng giá trị đầu vào được chuyển đổi thập phân làm vectơ của các hệ số cvà cơ sở ban đầu là x. (Thật không may, Octave base2dec()từ chối các biểu tượng ra khỏi phạm vi bình thường.)

Khi chúng ta có giá trị đầu vào trong cơ sở 10, việc tính toán giá trị trong cơ sở mới là đơn giản.

Lái thử:

% script bijecttest.m
a=b('4','','8');
disp(a);
a=b('A','16','2');
disp(a);
a=b('2','122','A');
disp(a);
a=b('3','31','1');
disp(a);
a=b('>','Fe','a');
disp(a);

Các kết quả:

>> bijecttest

1112
A
1111111111
RS
>>

2

Perl, 261 248 229 byte

sub t{$b=0;$b*=$_[1],$b+=ord($1=~y/0-9A-Za-z<=>/\0-A/r)while$_[0]=~/(.)/g;return$b}sub r{$n=$_[0];$n-=$m=($n-1)%$_[1]+1,$d=(chr$m)=~y/\0-A/0-9A-Za-z<=>/r.$d,$n/=$_[1]while$n;print$d}@a=split/,/,<>;r(t(@a[1],t@a[0],64),t@a[2],64)

đa dòng, trong khi các vòng lặp không được chỉnh sửa:

sub t{ # convert bijective base string to number
    $b=0;
    while($_[0]=~/(.)/g)
        {$b*=$_[1];$b+=ord($1=~y/0-9A-Za-z<=>/\0-A/r)}
    return$b}
sub r{ # convert number to bijective base string
    $n=$_[0];
    while($n)
        {$n-=$m=($n-1)%$_[1]+1;$d=(chr$m)=~y/\0-A/0-9A-Za-z<=>/r.$d;$n/=$_[1]}
    print$d}
@a=split/,/,<>; # parse input
r(t(@a[1],t@a[0],64),t@a[2],64)

tlà một hàm để phân tích một số từ một chuỗi cơ sở sinh học của một cơ sở nhất định. rlà một hàm để tạo ra một chuỗi cơ sở sinh học của một cơ sở nhất định từ một số. 3 tham số được phân tách bằng dấu phẩy được phân tích cú pháp từ stdin và các hàm được gọi là cần thiết.

Chuyển đổi một số dương thành chuỗi cơ sở sinh học tương tự như một cơ sở bình thường. Tuy nhiên, nơi bạn sẽ làm một cái gì đó như thế này cho một cơ sở bình thường:

string s = ""
while(n)
{
    c = (n % base)
    s = (c + '0') + s
    n -= c // not necessary because the division will take care of it
    n /= base 
}

bạn điều chỉnh mod để đưa ra phạm vi từ 1 đến cơ sở thay vì 0 đến cơ sở - 1:

string s = ""
while(n)
{
    c = (((n-1) % base)+1)
    s = (c + '0') + s
    n -= c  // necessary in the case c = base
    n /= base 
}

2

Python 2, ... 317 307 298 311 byte

Chắc chắn là golf. Tôi thực sự ghét cách chuỗi không có sự phân công mục và danh sách không có find. Tôi sẽ xem xét một cách tốt hơn so với cách khắc phục nhanh mà tôi có bây giờ.

Phương pháp của tôi là chuyển đổi đầu vào thành một số thập phân, sau đó đến cơ sở đầu ra, sau đó chuyển đổi nó thành cơ sở tính toán.

Chỉnh sửa : Nhận thấy rằng chương trình của tôi không hoạt động khi chuyển đổi sang Unary. Nó tốn 13 byte để sửa e=F(o)<2, v.v.

Hãy thử nó ở đây

R=range;M="".join(map(chr,R(48,58)+R(65,91)+R(97,123)))+"<=>"
b,s,o=input()
F=M.find
e=F(o)<2
B=lambda n:n and B(n/F(o)-e)+M[n%F(o)+e]or""
n=B(sum(F(s[~j])*F(b)**j for j in R(len(s))))
i=n.find('0')
n=list(n)
while-~i:n=n[:i-1]+[M[F(n[i-1])-1]]+[o]+n[i+1:];n=n["0"==n[0]:];i="".join(n).find('0')
print"".join(n)

1
Tôi đồng ý với thú cưng Python của bạn.
DLosc

@DLosc Cảm ơn sự giúp đỡ của golf.
mbomb007

Đây có phải là trò bowling không? : P
Trình tối ưu hóa

Danh sách có .index()phương thức .. Tại sao không sử dụng thay vì tìm? Ngoài ra, thay vì lưu F(b)F(o)vào các biến, bạn chỉ sử dụng chúng một lần, vì vậy chỉ cần phụ chúng vào nơi cần thiết. Cuối cùng, 'n'[2::5]ngắn hơn ''.join(n)(thay thế dấu nháy đơn cho backticks).
Kade

Ngoài ra, tôi nghĩ rằng bạn đang quá phức tạp điều này .. Chuyển đổi từ một chuỗi cơ sở sinh học M sang số thập phân không nên mất hơn 35-40 byte. Số thập phân cho một chuỗi cơ sở phỏng đoán B sẽ không nhiều hơn thế.
Kade

2

Python 2, 167 byte

Không có thủ thuật đặc biệt nào ở đây thực sự, ngoại trừ việc [2::5]cắt để lấy bộ ký tự ở số byte thấp hơn.

x=range;A=`map(chr,x(49,58)+x(65,91)+x(97,123))`[2::5]+'<=>'
r=A.find
b,n,B=input()
B=r(B)+1
d=0;s=''
for c in n:d=d*-~r(b)+r(c)+1
while d:d-=1;s=A[d%B]+s;d/=B
print s

Các xét nghiệm:

"4","","8"     >>> (empty string)
">","Fe","a"   >>> RS
"3","31","1"   >>> 1111111111
"A","16","2"   >>> 1112
"2","122","A"  >>> A

2

CJam, 73 70 69 55 51 48 byte

Phiên bản mới nhất sử dụng toán tử chuyển đổi cơ sở CJam để chuyển đổi từ cơ sở nguồn, điều mà tôi chưa từng nghĩ đến cho đến khi tôi thấy giải pháp của @ aditsu. Nó cũng áp dụng một mẹo gần đây của @Dennis để xây dựng chuỗi "chữ số" ( /codegolf//a/54348/32852 ), cũng như một số ý tưởng khác được chia sẻ trên trò chuyện.

lA,s'[,_el^+"<=>"+:Lf#Ll#bLl#:K;{(Kmd)L=\}hs-]W%

Định dạng đầu vào là giá trị, theo sau là cơ sở nguồn và đích, với mỗi cái trên một dòng riêng biệt. Đối với chuỗi trống, để trống dòng đầu tiên. Ví dụ đầu vào:

122
2
A

Dùng thử trực tuyến

Giải trình:

l       Get and interpret value from input.
A,s     Build the list of 64 "digits". Start with [0..9]
'[,     Build character sequence from \0 to Z.
_el     Lower case copy of the same sequence.
^       Symmetric set difference gives only letters from both sequences.
+       Concatenate with sequence of decimal digits, creating [0..9A..Za..z].
"<=>"   Remaining 4 characters.
+       Concatenate, resulting in full 64 character "digit" string.
:L      ... and store it in variable L for repeated use.
f#      Look up input characters in digit list.
Ll#     Get source base from input, and look up value in digit list.
b       Base conversion. This produces the input value.
Ll#     Get destination base from input, and look up value in digit list.
:K;     Store it in variable K for use in loop, and pop it off stack.
{       Loop for generating output digits.
  (       Decrement to get ceiling minus 1 after division.
  Kmd     Calculate divmod of current value with destination base.
  )       Increment mod to get 1-based value for digit.
  L=      Look up digit character for digit value.
  \       Swap. Digit stays on stack for output, remaining value is processed
          in next loop iteration until it is 0.
}h      End of loop for generating output digits.
s       Final value is 0. Covert it to a string.
-       And subtract it from second but last value. This eliminates the 0,
        as well as the second but last value if it was a \0 character.
]       Wrap digits in array.
W%      Reverse array, to get result from MSB to LSB.

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.