역 XOR 계산


13

하자 f비트 필드 (매핑 함수가 될 {0 1}크기)을 n+1크기의 비트 필드에 n적용하여 XOR받는 i번째 및 i+1번째 비트 새로운 비트 필드의 결과를 기록.

예: f("0101") = "111"

비공식 계산 :

0 XOR 1 = 1

1 XOR 0 = 1

0 XOR 1 = 1

f_inverse의 역함수로 합시다 f. 역수가 고유하지 않으므로 f_inverse하나의 유효한 솔루션을 반환합니다.

입력 : 비트 필드 (문자열 "0101111101011") 및 주어진 자연수k

출력 : 비트 필드를 문자열로, 입력 비트 필드 f_inversek시간 이 적용되는 경우 문자열에 결과 가 포함됩니다 . (즉 f_inverse(f_inverse(f_inverse(input))))

승리 기준 : 가장 적은 문자

보너스:

-25f_inverse재귀 적 / 반복적으로 적용되지 않는 경우 대신 출력 문자열이 직접 계산됩니다.

테스트 스크립트 :

a = "011001"
k = 3

def f(a):
    k = len(a)
    r = ""
    for i in xrange(k-1):
        r += str(int(a[i]) ^ int(a[i+1]))
    return r

def iterate_f(a, k):
    print "Input ", a
    for i in xrange(k):
        a = f(a)
        print "Step " + str(i+1), a

iterate_f(a, k)

예를 들어 여기에 붙여 넣은 다음 사용해 볼 수 있습니다.


3
검증 할 테스트 사례를 줄 수 있습니까?
Optimizer

3
{0-1}비트 필드 (Bitfields) 라고 부르지 말아 주시겠습니까? 또한의 정의를 이해하지 못합니다 f. 출처는 i어디입니까? XOR의 두 번째 주장은 무엇입니까? 우리는 어떻게받을 수 있나요 111에서 0101?
nini

더 나은 이름은 무엇입니까? 나는 인덱스를 나타냅니다
nvidia

"비트 필드"만 가능합니다. / value /는 i무엇입니까? "0 XOR 1" = 1 "1 XOR 0" = 1 "0 XOR 1" = 1XOR 작동 방식을 알고 있지만 XOR이 정확히 무엇이며 결과를 어디에 저장합니까?
nini

9
나는 그가 의미하는 것 : f([a,b,c,d]) = [a^b, b^c, c^d]. 그리고 그는, 즉 그 함수의 역, 원하는 f'([x,y,z]) = [a,b,c,d]그러한가 a^b=x, b^c=y, c^d=z.
marinus

답변:


14

피스, 33 30-25 = 5 바이트

Jiz8K+lzQ%"%0*o",KuxG/G8rQ^2KJ

stdin의 입력으로 실행하십시오 (온라인 인터프리터 : https://pyth.herokuapp.com/ ).

111
3

결과는 stdout에 기록됩니다.

이것은 다음의 직접 번역입니다.

파이썬 2, 127 118 79-25 = 54 바이트

def i(s,k):
 l=int(s,8);t=len(s)+k
 while k<1<<t:l^=l/8;k+=1
 print'%0*o'%(t,l)

처럼 호출 i("111", 3)하면 결과가 stdout에 기록됩니다.

코드 골프 목적으로 내부 루프가 O (2 k ) 시간 동안 실행되므로 k가 너무 크지 않을 것으로 예상 합니다.


우리는 보통이 작업을 "xorshift"라고 부릅니다. 입력을 빅 엔디안 정수로 표현하면 함수 f 는 다음과 같습니다.

  • f (x) = x ⊕ (x ≫ 1)

f를 두 번 적용 하면 다음을 얻을 수 있습니다.

  • f 2 (x) = x ⊕ (x ≫ 2)

그러나 3 번 적용하면 패턴이 다릅니다.

  • f 3 (x) = x ⊕ (x ≫ 1) ⊕ (x ≫ 2) ⊕ (x ≫ 3)

4 번 적용하면 기본 형식으로 돌아갑니다.

  • f 4 (x) = x ⊕ (x ≫ 4)

등등:

  • f 2 k (x) = x ⊕ (x ≫ 2 k )

우리가 충분히 큰 2 k를 선택한다면 , (x ≫ 2 k ) = 0, 즉 f 2 k (x) = x를 의미하고, 그 역함수는 사소한 아이덴티티 함수입니다!

따라서 f -1 (x) 를 전혀 호출하지 않고 f -k (x) 를 찾는 전략 은 다음과 같습니다.

  1. 다음과 같은 K를 찾으십시오.

    • K ≥ k
    • K> 로그 2 x
    • K는 2의 거듭 제곱입니다.
  2. 표현 f -k (x) = f -K + (Kk) (x) = f -K (f K-k (x)) = f K-k (x)

  3. 따라서 결과는 fKk 시간이라고합니다

  4. 25 문자 이익 : p


업데이트 1 : 이진 대신 8 진 표현을 사용 %하여 많은 바이트를 절약하기 위해 형식을 사용할 수 있습니다 .

업데이트 2 :의 주기적 구조를 이용하십시오 f. 반복적이지 않은 버전은 -25 바이트 보너스 없이도 더 짧아서 반복 버전이 중단되었습니다.

업데이트 3 : Pyth에서 3 바이트가 줄었습니다. isaacg!


팁 : codegolf.stackexchange.com/a/45280/20080에 설명 된대로 for 루프 및 할당을 다음과 같이 줄임표로 바꿀 수 있습니다.Jiz8K+lzQ%"%0*o",KuxG/G8rQ^2KJ
isaacg

11

CJam, 15 14 바이트

l~{0\{1$^}/]}*

다음과 같은 입력을받습니다.

"111" 3

여기에서 테스트하십시오.

설명

l~{0\{1$^}/]}*
l~             "Read and evaluate input.";
  {         }* "Repeat k times.";
   0\          "Push a 0 and swap it with the string/array.";
     {   }/    "For each element in the string/array.";
      1$       "Copy the previous element.";
        ^      "XOR.";
           ]   "Wrap everything in a string/array again.";

결과는 프로그램 끝에서 자동으로 인쇄됩니다.

문자열 (문자 배열)로 시작하기 때문에 "문자열 / 배열"이라고 말하지만 XOR을 숫자와 숫자 사이에서 계속 사용합니다. Character Character ^정수 (코드 포인트의 XOR을 기준으로) Character Integer ^Integer Character ^제공하고 문자 (코드 포인트가있는 숫자의 XOR을 기반으로-코드 포인트로 해석)를 제공합니다. 그리고 Integer Integer ^물론 단지 정수를 제공합니다.

종류가 운이 좋게 여기 저기 비행,하지만 그래서 내가 정수있을 때마다, 그것은 하나의 0또는 1내가 문자를 가지고 때마다 중 하나입니다 '0'1및 결과는 항상 인은 (두 유형의) 하나를 원했다. 문자열은 단지 문자 배열이므로 문자를 숫자와 혼합하는 것은 전혀 문제가되지 않습니다. 마지막으로 모든 것이 인쇄되면 문자는 특수 구분 기호를 얻지 않으므로 어떤 비트가 숫자 또는 문자로 표시되는지에 따라 출력에 영향을 미치지 않습니다.


CJam의 문자 / 숫자 유형 동작에 대한 훌륭한 설명은 25-25 = 0 바이트에 도달하여 솔루션 에서 1 바이트를 줄입니다. 감사합니다. +1!
Ilmari Karonen

2
그 유형의 행동은 끔찍합니다 (+1).
ballesta25

8

J, 17 자

항상 선행 숫자로 0을 사용하십시오.

   (~:/\@]^:[,~[$0:)

   3 (~:/\@]^:[,~[$0:) 1 1 1 
0 0 0 1 0 0

맨 위 행의 128 1 상태 (왼쪽)와 임의 상태 (오른쪽)부터 시작하여 처음 129 반복에서 마지막 128 자리를 표시합니다.

   viewmat (~:/\)^:(<129) 128$1               viewmat (~:/\)^:(<129) ?128$2

음모 음모


6

APL 11

((0,≠\)⍣⎕)⎕

설명:

≠\  compare increasing number of elements (1 1 1 ->1 0 1)
0,    add a starting zero
()⍣⎕  repeat the function in parenthesis ⎕ times, ⎕ is the second argument
()⎕   apply all to ⎕, that is first argument

tryapl.org에서 사용해보십시오


tryapl에서 실행할 수 없지만 (입력 방법은 무엇입니까?) ≠\ 대신 작동하지 2|+\ 않습니까?
randomra

⎕는 입력입니다. 내가 쓴 것과 동일한 표현을 사용하면 프로그램은 먼저 원하는 이진수 벡터를 요청한 다음 반복 횟수를 두 번째로 묻습니다. 나는 링크에서 a와 b를 사용하여 tryapl을 사용했기 때문에 스킨없이 실행됩니다. 또한 ≠ \ !!
Moris Zucca

복사 ((0,≠\)⍣⎕)⎕하면 유효하지 않은 토큰이 표시됩니다. Tryapl은 입력을 처리 할 수 ​​없습니까?
randomra

1
흠 ... 네 말이 맞아, 나도 마찬가지야. 나는 Dyalog APL을 사용하고 있으며 여기에 게시하려고 시도하기 때문에 눈치 채지 못했습니다. 미안합니다.
Moris Zucca

5

CJam, 25-25 = 0 바이트

q~1,*_@{[\{1$^}/_](;)\}/;

Martin Büttner의 답변 을 읽은 후 CJam의 정수 및 문자 유형 처리로 인해 1 바이트를 절약 할 수 있다는 것을 알았 으므로 이것은 아래 GolfScript 답변의 직선 CJam 포트입니다 . (기본적으로 CJam은 1&GolfScript 코드에서 ASCII 문자를 비트로 강제 하는 데 사용될 필요는 없지만 q입력을 읽는 데 선행을 요구합니다 .) 일반적으로 그러한 사소한 포트를 저렴한 트릭으로 생각하지만 점수는 0으로 만듭니다. 가치있는 IMO.

어쨌든이 프로그램은 아래의 원본 GolfScript 프로그램과 동일하게 작동하므로 설명 및 사용 지침을 참조하십시오. 평소와 같이이 온라인 인터프리터를 사용하여 CJam 버전을 테스트 할 수 있습니다 .


GolfScript, 26 − 25 = 1 바이트

~1,*.@{[1&\{1$^}/.](;)\}/;

이 솔루션은 입력 문자열을 한 번만 반복하므로 −25 바이트 보너스를받을 자격이 있다고 생각합니다. 그것은 각각의 k 사전- 테이트 레이트의 현재 비트를 저장 하는 k- 요소 배열을 내부적으로 유지함으로써 작동한다 .

입력은 stdin을 통해 형식으로 "1111111" 3, 즉 따옴표로 묶은 문자열 01문자, 숫자 k로 제공해야 합니다. 따옴표가없는 비트 열로 출력됩니다.

이 코드를 온라인으로 테스트하십시오. (프로그램 시간이 초과되면 다시 실행 해보십시오. Web GolfScript 서버는 임의 시간 초과로 악명이 높습니다.)


다음은이 프로그램의 확장 된 버전과 설명입니다.

~             # eval the input, leaving a string and the number k on the stack

1,*           # turn the number k into an array of k zeros ("the state array")
.             # make a copy of the array; it will be left on the stack, making up the
              # first k bits of the output (which are always zeros)

@             # move the input string to the top of the stack, to be iterated over
{
  [           # place a start-of-array marker on the stack, for later use
  1&          # zero out all but the lowest bit of this input byte
  \           # move the state array to the top of the stack, to be iterated over

  { 1$^ } /   # iterate over each element of the state array, XORing each
              # element with the previous value on the stack, and leave
              # the results on the stack

  .           # duplicate the last value on the stack (which is the output bit we want)
  ]           # collect all values put on the stack since the last [ into an array
  (;          # remove the first element of the array (the input bit)
  )           # pop the last element (the duplicated output bit) off the array
  \           # move the popped bit below the new state array on the stack
}
/             # iterate the preceding code block over the bytes in the input string

;             # discard the state array, leaving just the output bits on the stack

기본적으로 대부분의 반복 솔루션과 마찬가지로이 코드는 반복을 적용하는 것으로 이해 될 수 있습니다.

        b i , j : = b i , ( j -1)b ( i -1), ( j -1) ,

여기서 b 0, jj 번째 입력 비트 ( j ≥ 1의 경우), b k , jj 번째 출력 비트, b i , 0 = 0입니다. 차이점은 반복적 인 솔루션은 사실상 반복적으로 "행 단위"(즉, 첫 번째 b 1, j 는 모든 j , b 2, j 등)를 계산하지만이 솔루션은 대신 "열 기준"을 계산한다는 점입니다. 열 "(또는보다 정확하게는"대각선에 의한 대각선 "), 먼저 계산 b i , i 1 ≤ iKB , 나는 후, B I , I +2

이 방법의 한 가지 (이론적) 장점은 원칙적으로이 방법이 O ( k ) 스토리지 만 사용하여 임의로 긴 입력 문자열을 처리 할 수 ​​있다는 것 입니다. 물론 GolfScript 인터프리터는 프로그램을 실행하기 전에 모든 입력을 메모리에 자동으로 읽어 들여 대부분의 이점을 무시합니다.


2

파이썬, 94 78

한 번에 적어도 실행하므로 대해 동일한 결과를 제공 할 것인가 n=0n=1

def f(x,n):
 c='0'
 for i in x:c+='10'[i==c[-1]]
 return f(c,n-1)if n>1 else c

문자열을 숫자 형 배열로 변환하고 모듈로 2를 "통합"하는 이전 버전

from numpy import*
g=lambda x,n:g(''.join(map(str,cumsum(map(int,'0'+x))%2)),n-1)if n>0 else x

2

파이썬 2, 68

g=lambda l,n,s=0:n and g(`s`+(l and g(l[1:],1,s^(l>='1'))),n-1)or l

완전히 기억에 남는 솔루션. 두 가지 기능으로 나뉘면 이해하기가 더 쉽습니다.

f=lambda l,s=0:`s`+(l and f(l[1:],s^(l>='1')))
g=lambda l,n:n and g(f(l),n-1)or l

어디 f연속적인 차이와 계산 g구성하는 f자체 n 번과를.

이 함수 f는의 누적 XOR 합계를 계산하는데 l, 이는 연속 XOR 차이에 대한 역 연산입니다. 입력은 문자열로 주어지기 때문에 추출해야 int(l[0])하지만 문자열 비교로 짧아집니다 l>='1'.


파이썬 2, 69

exec루프를 사용하는 반복 솔루션은 1 문자 더 길었습니다.

l,n=input()
exec"r=l;l='0'\nfor x in r:l+='10'[l[-1]==x]\n"*n
print l

문자열을 처리하는 더 짧은 방법이있을 수 있습니다. 입력 / 출력이 숫자 목록이 될 수 있다면 5자를 절약 할 수 있습니다

l,n=input()
exec"r=l;l=[0]\nfor x in r:l+=[l[-1]^x]\n"*n
print l

1

펄 5, 34

#!perl -p
s/ .*//;eval's/^|./$%^=$&/eg;'x$&

공백으로 구분 된 표준 입력에 제공된 매개 변수.

$ perl a.pl  <<<"1101 20"
101111011011011011010110

1

자바 스크립트 ES6, 47 자

f=(s,k)=>k?f(0+s.replace(s=/./g,x=>s^=x),--k):s

그건 그렇고, 부작용이 없습니다 :)


반복 횟수에 대해 ak 매개 변수를 승인해야합니다. (-25 보너스는 실제로 반복을 수행하지 않고 반복의 결과를 계산하는 것입니다.)
Brilliand

사양을주의 깊게 읽어야합니다 (facepalm)
Qwertiy

1

C 번호 - 178 161 115 자

static string I(string a, int k){var s = "0";foreach(var c in a)s+=c==s[s.Length-1]?'0':'1';return k<2?s:I(s,--k);}

하네스

using System;
using System.Text;

namespace InverseXOR
{
    class Program
    {
        static string I(string a, int k)
        {
            var s = "0";
            foreach (var c in a)
                s += c == s[s.Length - 1] ? '0' : '1';
            return k < 2 ? s : I(s, --k);
        }

        static void Main(string[] args)
        {
            Console.WriteLine(I(args[0], Convert.ToInt32(args[1])));
        }
    }
}

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