당신의 모든 형용사 기지는 우리에게 속해 있습니다


25

배경

전단 사 염기 B의 기수법 , B는 양의 정수는 브랜드 중 사용하는 전단 사 위치 표기법 B 형 의 관련된 값과 심볼 1B .

궤적이 아닌 상대방과 달리 기호는 0 값을 갖지 않습니다 . 이런 식으로, 음이 아닌 각 정수 n 은 형용사 b 에서 고유 한 표현을 갖습니다 .

널리 사용되는 형용사에는 단항, 형용사베이스 2 ( bzip2의 런-렝스 인코딩에 사용됨) 및 이젝트베이스 26 (스프레드 시트의 숫자 열에 사용됨)이 포함됩니다.

정의

이 도전에서, 우리 는 심볼 들의 세트 M 을 다음과 같이 정의한다

123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz<=>

i ( '1') = 1,…, i ( '>') = 64가 되도록 M 부터 자연수 까지 의 함수 i 를 포함한다 .

164 사이 의 기본 b (둘 다 포함)가 주어지면, 음이 아닌 각 정수 n 은 문자열 a k … a 0에 해당하며, n = b k i (a k ) + 와 같이 M 의 기호로 구성됩니다. … + b 0 i (a 0 ) .

이 서신은 잘 정의되고 형 용성이 있습니다. 빈 합계는 0 으로 정의되므로 정수 0 은 빈 문자열로 인코딩 할 수 있습니다.

태스크

세 개의 문자열을 입력으로 승인하십시오.

  • bijective base 64 문자열 로 인코딩 된 164 사이 의 입력 base b .

  • 음이 아닌 정수 n 은 bijective 기본 b 문자열 로 인코딩됩니다 .

  • bijective base 64 문자열 로 인코딩 된 164 사이 의 출력 base B

이 세 가지 입력이 주어지면, n 을 bijective base B 문자열 로 인코딩하십시오 .

테스트 사례

모든 테스트 사례는 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"

규칙

  • 문자열 배열, 문자열 표현, 선택한 단일 문자 구분 기호로 분리 또는 분리하는 등의 편리한 순서로 세 문자열을 읽을 수 있습니다.

  • 출력을 STDOUT으로 인쇄하도록 선택한 경우 기호 및 선택적으로 후행 줄 바꿈 만 인쇄 할 수 있습니다.

  • 모든 종류의 기본 변환 내장이 허용됩니다.

  • 표준 규칙이 적용됩니다.

답변:


6

CJam, 43

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

Dennis의 도움으로 3 바이트를 근절 했습니다.

설명:

입력은 bnB로, 단일 문자열로 연결됩니다.

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

오, 실제로 첫 번째 기본 변환에 정규 기본 변환 연산자를 사용할 수 있습니까? 이제 솔루션에있는 모든 코드를 사용하는 것에 대해 바보 같은 느낌이 듭니다. :) 기본 범위를 벗어난 값으로 작동한다는 것을 알지 못했습니다. 글쎄, 뒤늦게 보면 왜 안되어야 할 이유가 없습니다.
Reto Koradi

@RetoKoradi 네, 그렇게 할 수 있습니다. 언젠가 그것은 문서화 될 것이다 :)
aditsu

기본 변환을 사용하도록 솔루션을 변경해도 될까요? 나는 보통 다른 솔루션에서 아이디어를 얻지 않으려 고 노력합니다. 그러나 실제로 그런 차선책으로 접근하게하는 것은 나를 버그로 만듭니다. 솔루션이 더 짧을 가능성이 높습니다.
Reto Koradi 22

@RetoKoradi 문제 없습니다, 계속
aditsu

4

핍, 84 80 78 바이트

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

Pip 용 GitHub 리포지토리

알고리즘은 Wikipedia 기사에서 수정되었습니다. 다음은 약간 ungolfed 이전 버전에 대한 설명입니다.

                 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)

샘플 실행 :

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

4

옥타브, 166 바이트

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

여러 줄 버전 :

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

문자를 색인 값으로 변환하는 맵을 작성하는 대신 NASCII 값에 대한 역 찾아보기 테이블 을 작성 1..'z'하고 적절한 값의 색인으로 채 웁니다.

polyval 방정식을 평가

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

10 진수로 변환 된 입력 값을 계수 벡터로 사용 c하고 원래 밑을로 사용 x합니다. (아쉽게도 Octave의 base2dec()거부 기호는 정상 범위를 벗어났습니다.)

베이스 10에 입력 값이 있으면 새베이스의 값 계산이 간단합니다.

테스트 드라이버 :

% 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);

결과 :

>> bijecttest

1112
A
1111111111
RS
>>

2

펄, 261 248 229 바이트

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)

여러 줄, while 루프는 ungolfed :

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)

t주어진 밑의 형용사 문자열에서 숫자를 파싱하는 함수입니다. r주어진 염기의 이젝트-베이스 문자열을 숫자에서 생성하는 함수입니다. 3 개의 쉼표로 구분 된 매개 변수는 stdin에서 구문 분석되고 필요에 따라 함수가 호출됩니다.

양수를 이형 기준 문자열로 변환하는 것은 일반 기준과 유사합니다. 그러나 일반베이스에 대해 이와 같은 작업을 수행하는 위치 :

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 
}

0에서 base-1 대신 1에서 base까지 범위를 제공하도록 모드를 조정합니다.

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

2

파이썬 2, ... 317 307 298 311 바이트

확실히 골프. 문자열에 항목 할당이없고 목록에없는 항목이 정말 싫어요 find. 지금 가지고있는 빠른 수정보다 더 나은 방법을 살펴 보겠습니다.

내 방법은 입력을 10 진수로 변환 한 다음 출력 기준으로 변환 한 다음이를 형용사 기준으로 변환하는 것입니다.

편집 : 단항으로 변환 할 때 내 프로그램이 작동하지 않는 것을 발견했습니다. e=F(o)<2등 으로 수정하는 데 13 바이트가 소요되었습니다 .

여기 사용해보십시오

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
나는 당신의 파이썬 애완 동물 친구들에 동의합니다.
DLosc

@DLosc 골프 도움을 주셔서 감사합니다.
mbomb007

코드 볼링 입니까? : P
Optimizer

리스트에는 .index()메소드가 있습니다. find 대신이를 사용하지 않는 이유는 무엇입니까? 또한 변수 를 저장 F(b)하고 저장하는 대신 F(o)한 번만 사용하므로 필요한 곳에 하위 변수를 넣으십시오. 마지막으로 (백틱의 아포스트로피를 대체) 'n'[2::5]보다 짧습니다 ''.join(n).
Kade

또한, 나는 당신이 이것을 너무 복잡하게 생각합니다. bijective base B의 문자열에 대한 십진법은 그 이상이 아닙니다.
Kade

2

파이썬 2, 167 바이트

[2::5]더 적은 바이트 수로 캐릭터 세트를 얻는 슬라이싱을 제외하고는 여기에 특별한 트릭이 없습니다 .

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

테스트 :

"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 바이트

최신 버전은 @aditsu의 솔루션을 볼 때까지 생각하지 않은 소스 기반의 변환에 CJam 기본 변환 연산자를 사용합니다. 또한 "숫자"문자열 ( /codegolf//a/54348/32852 ) 을 구성하는 데 @Dennis의 최근 팁 과 채팅에서 공유되는 다른 아이디어를 적용합니다.

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

입력 형식은 값과 그 뒤에 소스 및 대상베이스가 있으며 각각은 별도의 행에 있습니다. 빈 문자열의 경우 첫 번째 줄을 비워 두십시오. 입력 예 :

122
2
A

온라인으로 사용해보십시오

설명:

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.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.