2017-01-02 7 views
4

사람이 다음 코드를 이해하는데 좀 도와 줄래 : -이 코드를 이해할 수 없습니까?

int r, countIt(int n) { 
    while (r += "   2 "[n % 10] & 3, n /= 10); 
    return r; 
} 

나는 이것은 구멍의 수를 카운트하는 솔루션입니다 https://codefights.com/challenge/v5Zg8trjoun3PTxrZ/solutions/Aj3ppbhSShixt4nBi

codefights.com의 과제 중 하나에서이 코드를 발견 번호.
예 :

1111 = 0 
0000 = 4 
1234 = 0 
8888 = 8 

나는 다음과 같은 일들을 이해할 수 없습니다입니다 :

2. 쉼표 (,) 연산자 함수의
3. []의 반환 데이터 형식에 사용되는 코드의 1. 논리 문자열 뒤에 연산자.
4. 실제로 코드 전체.

+2

두 선언이 결합 된 것입니다. 'int x, y;와 똑같은 것은'int x; int y;', 당신이 보여줄 코드는'int r; int countIt (int n) {...}'. 변수 정의와 함수 정의를 병합하는 것은 혼동하는 역할을합니다. 코드에서 그렇게하지 마십시오. 단 한번 설명했을 때 시원할 수도 있습니다. –

+1

와우, 상당히 영리합니다. 무서운, 그러나 우습다. :) –

+0

감사합니다. @IgorTandetnik. 그 끈 부분? –

답변

1

내가 제공 한 링크를 찾았습니다. 신중하게 코드를 관찰 한 결과 나는 결론을 내렸다.

int r, countIt(int n) {.....} 

while (r += "   2 "[n % 10] & 3, n /= 10); 

이제

int r; 
int countIt(int n){.....} 

로 쓰기에 해당하는 것과 같습니다

do{ 
    r += "   2 "[n % 10] & 3; 
    n/=10; 
}while(n); 

이제 코드의 논리적 인 부분을 제공

r += "   2 "[n % 10] & 3; 

몇 가지 기본 사항을 알려 드리겠습니다. C에서

  1. ++

cout<<"abcde"[2];

당신이이 같은 그 무언가를 제공하는 링크에서주의 깊게 코드를 보면, 지금 당신에게 출력

c 

을 줄 것이다 :

를 ,210

이 코드 구멍의 수를 계산하는 방법을 설명하기 위해 지금

r += "TAB,SPACE,SPACE,SPACE,SPACE,SPACE,TAB,SPACE,2,TAB"[n % 10] & 3; 

의 시간에 불과하다. TAB의 ASCII 값은 이진 값이 1001 인 9입니다. SPACE의 ASCII 값은 이진 값이 100000 인 32입니다.(3) 따라서이

를 쓰기로 결론 0

  100000 & 000011 = 000000 which is 0 

교체 1 탭과 공간을 초래할 것이다와

3

그래서 비트 현명한 AND 연산 TAB는

  1001 & 0011 = 0001 which is 1 

비트 현명한 AND 작업 공간을 초래할 것

do{ 
    r += "1000001021"[n % 10] & 3; 
    n/=10; 
}while(n); 

n % 10은 n의 하위 10 진수입니다. 이를 문자열 리터럴에 대한 인덱스로 사용합니다.이 리터럴에는 저수위 십진수에 홀 수가 몇 개 있는지에 대한 정보가 포함되어 결과 r에이를 추가합니다.

+0

한 가지 더. 변수 r은 전역 또는 로컬입니까? –

+0

옙 글로벌 변수. – BlessonThomas

9

obfuscated C contest 제출일까요? 또는 code golf?


처음에는 이상한 선언입니다. 관련없는 두 선언을 한 줄에 결합하는 것입니다.

int x, y; 

int x; 
int y; 

에 해당 것처럼 그래서 C 문법을 거의 사용 특질, 그것은 다행히도, 작은 알려진 그리고

int r; 
int countIt(int n) {...} 

로 코드와 동일 당신이 할 수있는 그렇게. 이 방법을 쓸 경우


루프는 명확하게 될 것입니다 : n의 진수 표현에 자리 이상

do { 
    r += "   2 "[n % 10] & 3; 
    n /= 10; 
} while (n); 

그것은 기본적으로 반복합니다. 이제


r += " 2 "[n % 10] & 3;의 일부입니다. n % 10n의 하위 자리 10 진수입니다. 이를 문자열 리터럴 (단지 char의 배열)에 대한 인덱스로 사용하고 문자의 ASCII 코드에서 두 개의 하위 비트를 추출하고 나머지는 버립니다. 나는 원래 프로그램에서이 코드를 복사했는데 그 문자가 공백이 아니라 오히려 특정 인쇄 할 수없는 문자가 ASCII 코드의 두 하위 비트가 정확히 해당 숫자의 "구멍"의 수 2 문자는 빨간색 청어입니다. 위치는 12이지만 문자 0-9가 실제로 사용됩니다.

은 즉,이 부분은 더 명확하게 이런 식으로 쓸 수있다 :


static const int numHoles[10] = {1, 0, 0, 0, 1, 0, 1, 0, 2, 1}; 
int digit = n % 10; 
r += numHoles[digit]; 
함께 넣어, 우리는이 : 브라우저에서 특수 문자를 사용

int countIt(int n) { 
    // number of holes in digit  0 1 2 3 4 5 6 7 8 9 
    static const int numHoles[10] = {1, 0, 0, 0, 1, 0, 1, 0, 2, 1}; 
    int r = 0; 
    do { 
    int digit = n % 10; 
    r += numHoles[digit]; 
    n /= 10; 
    } while (n); 
    return r; 
}; 
+0

저는 실제로 그가 준 링크를 보았습니다. 그리고 그가 찾고있는 대답에는 공백이 있습니다. 대부분의 테스트에서는 실패했습니다. –

+1

@TomTanner 아마도 저자의 기계에서 작동하지만, 인쇄 할 수없는 문자는 복사/붙여 넣기를 할 때 브라우저를 통과하지 못했습니다. 반으로 너무 영리 해. –

+0

그들은 공백이 아니며 단지 그 것처럼 보입니다. – James

0

이 문제가 될 수있다 Ascii Table에서 0에서 2 또는 4에서 6까지 8 진수로 끝나는 모든 문자를이 2 비트를 사용하여 숫자에 몇 개의 구멍이 있는지 알 수 있습니다 (% 3% 0b11과 같음) 그리고 마지막 2 비트로). 아스키 문자와

하나 개의 솔루션은 다음과 같습니다

int countIt(int n) { 
    int r; 
    while (r += "1000101021"[n % 10] & 3, n /= 10); 
    return r; 
} 

대신 "0" "2", 나는 이런 식으로 뭔가 사용할 수에 : 나는 무엇을 그가를가 문자 모르는

int countIt(int n) { 
    int r; 
    while (r += "! X0) [email protected]*9"[n % 10] & 3, n /= 10); 
    return r; 
} 

을 사용하려고 시도했지만 도전 웹 사이트에서 작동하지 않았습니다.