이진수를 십진수로 변환


32

이진수를 십진수로 변환

내가 볼 수있는 한, 간단한 이진수를 십진수로 변환하는 도전은 없습니다.


양의 이진 정수를 취하여 십진수 값을 출력하는 프로그램 또는 함수를 작성하십시오.

내장 된 기본 변환 기능을 사용할 수 없습니다. 정수에서 10 진 함수 (예 : 또는 101010로 변하는 함수 )는이 규칙에서 제외되므로 허용됩니다.[1, 0, 1, 0, 1, 0]"101010"

규칙 :

  • 코드는 언어가 지원하는 최대 숫자 값 (기본적으로)까지 이진수를 지원해야합니다.
  • 이진 표현에서 선행 0을 갖도록 선택할 수 있습니다
  • 10 진수 출력에는 선행 0이 없을 수 있습니다.
  • 입력 및 출력 형식은 선택 사항이지만 숫자 사이에는 구분 기호를 사용할 수 없습니다. (1,0,1,0,1,0,1,0)유효한 입력 형식은 아니지만 10101010(["10101010"])입니다.
    • "정상"방향으로 입력해야합니다. 1110이다 14없습니다 7.

테스트 사례 :

1
1

10
2

101010
42

1101111111010101100101110111001110001000110100110011100000111
2016120520371234567

이 과제는 몇 가지 다른 과제 (예 : this , thisthis) 와 관련 있습니다.



출력에 서명이 없어야합니까 아니면 서명 할 수 있습니까? 또한 언어가 값의 길이에 따라 32 비트와 64 비트 정수 사이에서 자동으로 전환되는 경우 두 범위에서 출력에 서명 할 수 있습니까? 예 : 10 진수 -1( 32 1's64 1's) 로 변환 할 2 개의 이진 값이 있습니다
milk

또한 출력이 부동 일 수 있습니까? 정수 여야합니까?
Carcigenicate

@Carcigenicate 정수 여야하지만 모든 데이터 유형이 될 수 있습니다. 만큼 round(x)==x당신이있는 거 벌금 :) 2.000의 출력을 허용됩니다 10.
Stewie Griffin

이거 정말 달콤 하네. 감사.
Carcigenicate

답변:


56

젤리 , 5 바이트

DḤ+¥/

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

설명

enter image description here

캐스트

  • D모나드 (단일 인수 함수) : 숫자로 변환 1234됩니다 [1, 2, 3, 4].

  • 단일 인수를 두 배로 늘리는 모나드입니다.

  • + 왼쪽과 오른쪽 인수를 추가하는 dyad (두 인수 함수)입니다.

거기에서 조금 까다로워집니다.

구문 분석시 발생하는 상황은 다음과 같습니다.

  • D, +읽습니다. 체인은 다음과 같습니다 [D, Ḥ, +].

  • 다음 두 문자는 quicks 인데, 지금까지 읽은 링크 (함수)에서 구문 분석 후 접미사 연산자처럼 작동합니다.

  • ¥읽기, 마지막 두 개의 링크가 튀어 그들을 구성에 의해 형성된 양자 관계와 같은 역할을 링크로 대체 얻을. 이제 체인은 다음과 같습니다 [D, dyad(Ḥ+)].

  • /읽기, 마지막 링크는 (어떤이 다이 애드되어야한다) 팝과 모나드로 대체됩니다 주름 이 다이 애드을 사용하여 (직관적으로 : f/목록을 소요와의 쉼표를 대체 f하고 결과를 평가합니다.)

  • 마지막 체인은 [D, fold(dyad(Ḥ+))]두 개의 모나드 처럼 보입니다 .

런타임시 발생하는 상황은 다음과 같습니다.

  • 입력 (숫자)은 암시 적으로 작업 값으로 읽습니다 (예 :) 101010.

  • D작업 값을 숫자 ( [1,0,1,0,1,0])로 바꾸어 실행 됩니다.

  • fold(dyad(Ḥ+))작업 값을로 바꾸고 실행되는 1∗0∗1∗0∗1∗0은 dyad Ḥ+입니다.

그래서 무엇을 x∗y평가합니까?

  • 이진 정의에서 작업 값은 처음에 왼쪽 인수 x입니다.

  • 이중 모나드는,이 값을 두 배로. 작업 가치는 이제 2x입니다.

  • +, 플러스 dyad에는 올바른 인수가 없기 때문에 이것은 후크입니다 .이 dyad의 올바른 인수가에 삽입되는 특수한 구문 패턴 +입니다. 2x + y최종 작업 값으로 산출 되어 반환됩니다.

따라서 전체 표현은 다음과 같이 평가됩니다.

1∗0∗1∗0∗1∗0 = 2×(2×(2×(2×(2×1+0)+1)+0)+1)+0
            = 32×1 + 16×0 + 8×1 + 4×0 + 2×1 + 1×0
            = 42

10
설명이 점점 좋아지고 있습니다 :-)
Luis Mendo

2
허, 지금부터하는 것 같아? 대단해요, +1
Outgolfer Erik

4
나는 이것이 내가 이해 한 첫 번째 젤리라고 생각한다. +1!
Blue

브라보. 나는 실제로 처음에 생각했던 것이 무작위로 보이는 캐릭터의 혼란이라고 생각합니다. 훌륭한 설명.
swinefish

1
@Mark Jelly는 자체 코드 페이지 를 가지고 있어 프로그램을보기 좋게 읽을 수 있지만 바이트 열일 수도 있습니다.
Lynn

20

파이썬 2, 49 37 31 30 바이트

파이썬은 임의로 큰 정수를 처리 할 수 ​​있기 때문에 이제 10 진수로 이진수를 사용할 것입니다.

b=lambda n:n and n%2+2*b(n/10)

바이트를 저장 한 xnor 덕분에 :)

이것이 어떻게 작동하는지 확인하는 가장 쉬운 방법은 이진수를 십진수로 변환하는 기본 공식을 보는 것입니다.

= 101010 
= 1*(2^5) + 0*(2^4) + 1*(2^3) + 0*(2^2) + 1*(2^1) + 0*(2^0)
= 1*32 + 0*16 + 1*8 + 0*4 + 1*2 + 0*1
= 42

이것은 '표준'변환 방법입니다. 다음과 같이 세 번째 줄을 확장 할 수 있습니다.

= ((((1*2 + 0)*2 + 1)*2 + 0)*2 + 1)*2 + 0

그리고 이것은 본질적으로 내가 만든 재귀 방법이하는 것입니다.

내가 가진 대체 솔루션 :

b=lambda n:n and n%10+2*b(n/10)
b=lambda n:n%10+2*(n and b(n/10))
b=lambda n:0if n<1else n%10+2*b(n/10)
b=lambda n:0**(n/10)or n%10+2*b(n/10)
b=lambda n,o=0:o*(n<'0')or b(n[1:],2*o+int(n[0]))
lambda j:sum(int(b)*2**a for a,b in enumerate(j,1))

6
대신 n%5또는 n%2대신 할 수 있습니다 n%10.
xnor

@ xnor 아아, 내가 그것을 어떻게 그리웠는지 모르겠다! 감사합니다 :)
Kade

12

05AB1E , 6 바이트

암호:

$¦v·y+

외식을 위해 101010 예제를 보자 . 우리는 숫자 1 (첫 번째 숫자로 표시)로 시작합니다. 그 후 두 가지 경우가 있습니다.

  • 숫자가 0 이면 숫자에 2를 곱하십시오.
  • 숫자가 1 이면 숫자에 2를 곱하고 1을 더하십시오.

따라서 101010의 경우 다음이 계산됩니다.

  • 1 01010, 숫자 1로 시작하십시오 .
  • 1 0 곱셈 결과로 두 의해 1010 2 .
  • 10 1 010에 2를 곱하고 1을 더하여 5로 만듭니다.
  • 101 0 10에 2를 곱하면 10이 됩니다.
  • 1010 1 0에 2를 곱하고 1을 더하여 21로 만듭니다.
  • 10101 0 에 2를 곱하여 42를 얻습니다 . 이것이 원하는 결과입니다.

코드 설명 :

$         # Push 1 and input
 ¦        # Remove the first character
  v       # For each character (starting with the first)
   ·      #   Multiply the carry number by two
    y+    #   Add the current character (converted automatically to a number)

CP-1252 인코딩을 사용합니다 . 온라인으로 사용해보십시오!


좋은 것! (방금 주목했지만 0에서는 작동하지 않습니다)
Emigna

@Emigna Yep, 운 좋게도 코드는 양의 이진수에만 작동해야합니다.
Adnan

그 부분조차 보지 못했습니다. 아주 좋은 그때 :)
Emigna

9

하스켈, 16 111 + 57 = 168 바이트

import Data.String
instance IsString[Int]where fromString=map((-48+).fromEnum)
f::[Int]->Int
f=foldl1((+).(2*))

컴파일 플래그의 경우 +57 바이트 -XOverloadedStrings , -XOverlappingInstances-XFlexibleInstances.

도전에는 몇 가지가 있습니다 데이터 유형이 소스 코드로 표현되는 방식에 크게 의존하기 때문에 번거로운 IO 형식 이 있습니다. 첫 번째 버전 (16 바이트)

foldl1((+).(2*))

예를 들어 정수 [1,0,1,0,1,0]Haskell 목록이 ,요소 사이에 있기 때문에 정수 목록을 가져옵니다 . 목록 자체는 금지되지 않습니다. 새 버전에서는 이름이 같은 동일한 기능을 사용 f하지만 "Quote closed character sequence"를 오버로드합니다. 유형 주석에서 볼 수 있듯이 함수는 여전히 정수 목록을 가져옵니다.[Int] -> Int 하지만, 한 자리 정수를 목록 지금처럼 쓸 수있다 "1234", 예를 들어,

f "101010"

로 평가됩니다 42. 기본 목록 형식이 챌린지 규칙에 맞지 않기 때문에 불행한 Haskell. Btw, f [1,0,1,0,1,0]여전히 작동합니다.


2
불행히도 목록은 유효한 입력이 아닙니다.
Jonathan Allan

@JonathanAllan : 왜요? 그렇다면 어떻게 입력해야합니까? Haskell에서 문자열은 문자 목록입니다.
nimi

난 이유를 모르겠어 ...하지만 초기에 이것에 대해 물었다과 편집이 추가되었다 " (1,0,1,0,1,0,1,0)유효한 입력 형식이 아니라 모두 10101010하고 (["10101010"])있습니다." 또한 주석은 문자열 입력이 해석되는 방식 인 경우 문자 배열이 허용됨을 나타냅니다.
Jonathan Allan

1
@JonathanAllan : "이진 정수"(우리가 입력해야하는 입력)는 본질적으로 분리되어 있으며 2의 거듭 제곱입니다. 제한은 명시적인 구분 기호 (숫자 사이)에 관한 것이지 분리에 관한 것이 아닙니다. 어떻게 든 분리 된 숫자를 가져 와야합니다.
nimi

2
여기에서 선택하십시오 : 10101010, "10101010"또는 이와 비슷한 것을 입력 하고 작동하게하면 제출이 유효합니다. 문자열, 목록, 정수 또는 무엇이든 호출 할 수 있습니다. 입력 [1][0][1][0]중이거나 정상 [1,0,1,0]이 아닙니다. 기본적으로 어딘가에 연속으로 1과 0의 무리를 치는 것이 가능해야합니다. 이것이 분명합니까?
스튜이 그리핀

7

레티 나, 15 바이트

이진수를 단항으로 변환 한 다음 단항을 십진수로 변환합니다.

1
01
+`10
011
1

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


내장 된 기본 변환 기능을 사용할 수 없습니다. ~ OP
Roman Gräf

10
@ RomanGräf 없습니다. 나는 단순히 내 솔루션의 과정을 설명하고있었습니다.
mbomb007

7

PHP, 44 바이트

for(;""<$c=$argv[1][$i++];)$n+=$n+$c;echo$n;

나는 그 질문을 전에 본 것을 맹세 할 수있었습니다. 그러나 잘.

왼쪽에서 오른쪽으로 숫자를 읽고 왼쪽으로 이동하여 현재 비트를 추가합니다.


7

자바 스크립트 (ES6), 33 31 바이트

s=>[...s].map(c=>r+=+c+r,r=0)|r

편집 : 짧지 만 덜 달콤한 : @ETHproductions 덕분에 2 바이트가 절약되었습니다.


종종 그렇듯이, .map더 짧습니다 :s=>[...s].map(c=>+c+r+r,r=0)|r
ETHproductions

@ETHproductions 함수가 0 이외의 것을 어떻게 반환합니까?
Neil

죄송합니다s=>[...s].map(c=>r+=+c+r,r=0)|r
ETHproductions

7

미로 , 17 15 바이트

-+:
8 +
4_,`)/!

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

Image of the code

미로는 2 차원의 스택 기반 언어입니다. 미로에서, 코드 실행은 벽으로 작용하고 가장 왼쪽이 아닌 비 공백 문자에서 시작하는 공백이있는 미로처럼 코드의 경로를 따릅니다. 코드 흐름은 스택 상단의 부호로 결정됩니다. 스택의 맨 아래에는 암시 적 0이 있으므로 처음 네 개의 명령어 (-+:+ )는 영향을 미치지 않습니다.

에서 시작하는 루프 ,

  • , 다음 입력 문자의 ASCII 코드 값을 스택의 중지 위치로 푸시하거나 EOF 인 경우 -1을 누르십시오.
  • _48 스택 맨 위로 48을 밉니다
  • -팝 y, 팝 x를 누릅니다 x-y. 이전 명령어는 "0"에 대해서는 0을, "1"에 대해서는 1을 산출하는 입력에서 48을 빼는 효과가 있습니다.
  • +팝 y, 팝 x를 누릅니다 x+y.
  • : 스택 상단 복제
  • + 이 명령과 이전 명령에는 현재 값에 2를 곱한 효과가 있습니다.

실제로 코드의 원형 부분은 현재 숫자에 2를 곱하고 문자 1 또는 0이 입력되었는지에 따라 1 또는 0을 더합니다.

꼬리

스택의 상단이 음수이면 (EOF가 발견되었다는 의미) 코드가 교차점에서 왼쪽으로 바뀝니다 (세미콜론으로 이동).

  • ```스택의 상단을 무효화하여 1을 얻습니다.
  • ) 스택 맨 위를 증가시켜 2를 얻습니다.
  • /팝 y, 팝 x, x / y (정수 나누기)를 누릅니다. 이것은 마지막을 취소하는 효과가 있습니다*2 루프 있습니다.
  • !스택 상단의 정수 표현을 출력합니다. 이 시점에서 프로그램은 막 다른 골목에 부딪쳐 돌아 서서 0으로 나누려고하기 때문에 오류와 함께 종료됩니다.

저에게 2 바이트를 절약 해 준 @Martin Ender 에게 감사드립니다 .


대신 _48-간단하게 할 수는 #%있지만 불행히도 바이트 수에 어떻게 도움이되는지 알 수 없습니다.
Martin Ender

그래도 대신 바이트를 저장할 수 있습니다 . `);_2
Martin Ender

@MartinEnder,에 대한 귀하의 의견을 이해하지 못합니다 #%. _48-ascii에서 int로 변환 하기위한 대체품으로 어떻게 작동하는지 설명 할 수 있습니까? )팁 주셔서 감사합니다 . 변경하겠습니다.
Robert Hickman 2016

프로그램의 시점에서 스택에는 항상 두 개의 값이 있으므로 #짧습니다 _2. 하지만 _2%정수 ASCII에 대한 일반적인 변환 방법이 아닙니다 만 가능 입력으로 처음 두 자릿수에 관심이 있기 때문에, 여기 작동합니다. 대안은 _1&(모듈로 2가 단순히 최하위 비트를 추출하기 때문에)입니다.
Martin Ender

오. 훌륭합니다. 그러나 그래, 대체 ( #%)를 사용 하여 전체 코드를 줄이는 방법을 잘 모르겠습니다 .
Robert Hickman

6

Brain-Flak , 46 , 28 바이트

([]){{}({}<>({}){})<>([])}<>

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

@Riley 덕분에 많은 바이트가 절약되었습니다!

brain-flak는 이진 입력을 사용할 수 없으므로 입력은 '0'과 '1'의 목록입니다.

설명:

#Push the height of the stack
([])

#While true:
{

 #Pop the height of the stack
 {}

 #Push this top number to (the other stack * 2)
 ({}<>({}){})

 #Toggle back on to the main stack
 <>

 #Push the new height of the stack
 ([])

#endwhile
}

#Toggle back to the other stack, implicitly display.
<>

설명을 사랑하십시오! 그것없이 뇌-플랙을 읽기 어렵습니다 :)
Emigna

2
^. 의견을 남기지 않으면 내 프로그램을 읽을 수도 없습니다.
Riley

if 부분 전체를 제거하여 32 바이트로 줄일 수 있으며 "다른 스택에 번호 추가"단계에서 (다른 스택) * 2에 추가하십시오. ([]){({}[()]<({}<>({}){})><>)}<>
Riley

그리고 당신은 단지 시작시에 터지는 다음 끝에 높이를 다시 밀어서 또 다른 4를 저장할 수 있습니다. ([]){{}({}<>({}){})<>([])}<>
Riley

@Riley 오 세상에, 천재입니다. 대단히 감사합니다!
DJMcMayhem

6

자바, 84 79 46 48 바이트

  • 버전 3.1

long/ 48 바이트로 변경 :

s->{long x=0;for(char c:s)x=c-48l+x*2;return x;}
  • 버전 3.0

일부 골프 / 46 바이트를 했습니까?

s->{int x=0;for(char c:s)x=c-48+x*2;return x;}
  • 버전 2.0

@Geobits 덕분에! / 79 바이트 :

s->{int i=Math.pow(2,s.length-1),j=0;for(char c:s){j+=c>48?i:0;i/=2;}return j;}
  • 버전 1.0

84 바이트 :

s->{for(int i=-1,j=0;++i<s.length;)if(s[i]>48)j+=Math.pow(2,s.length-i+1);return j;}

1
반복적 인 솔루션을 수행해야한다고 생각합니다. lulz. 잘 했어
Poke

입력 유형이 List <Character> 또는 String입니까? 후자라면 Java8이 그렇게 할 수 있다는 것을 몰랐습니다! 전자의 경우 도전에 의해 허용되는 것입니까?
Poke

s이어야합니다 char[]. 나는이 허용 바란다 ...
로마 그라프

반품 유형은 무엇입니까? "코드가 OP에서 언어가 지원하는 최대 숫자 값까지 이진수를 지원해야하기 때문에"길어야한다고 생각하지만 값이 작을수록 int를 반환한다고 생각합니다.
Poke

1
이것 에 따라 입력 유형 아마 좋을 것입니다 입니다. 출력 imo에 대해 2 바이트 적중을 원할 수 있습니다.
Poke

4

Befunge-98, 12 바이트

2j@.~2%\2*+

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

입력에서 한 번에 하나의 문자를 읽고, modulo 2 값 (0은 char (48), 1은 char (49))을 취하여 0 또는 1로 변환 한 다음 현재 값을 두 배로 늘리고 추가하는 일반적인 알고리즘을 사용합니다. 매번 새로운 숫자.

보너스 : 이것은 모든 종류의 입력 문자열과 함께 작동하지만 재미있는 입력-> 출력 조합을 찾기 위해 잠시 동안 노력했지만 아무 것도 생산 할 수 없었습니다 (슬픈, "answer"= 46). 너는 할수 있니?


LOL. 나는 내 대답으로 같은 게임을하고있었습니다. 내가 생성 할 수있는 가장 흥미로운 숫자는 666 입니다.
James Holderness

좋은 것! 나는 666 : D에 적합한 것을 찾지 못했습니다. 대문자가 가치에 영향을 주면 훨씬 쉬울 것입니다 ...
Leo

@ James Holderness-나는 똑같은 일을하고 366 년을 되 찾을 'theleapyear'만 찾았습니다. 정말 좋습니다.
청록 펠리칸

4

자바 스크립트 (ES7) 41 40 36 바이트

f=([c,...b])=>c?c*2**b.length+f(b):0

문자열을 입력으로받습니다

ETH 프로덕션 덕분에 바이트를 깎았습니다.

f=([c,...b])=>c?c*2**b.length+f(b):0
document.write([
    f('101010'),
    f('11010'),
    f('10111111110'),
    f('1011110010110'),
].join("<br>"))


1
오른쪽에서 왼쪽으로의 연관성 **은 이상하지만 여기서 사용하는 것은 훌륭합니다. 1<<b.length같은 작업을 수행하지만 괄호는로 구문 분석되지 않도록해야합니다 (c*1)<<(b.length+...). 나는 당신이 대체하여 바이트를 저장할 수 있습니다 생각 b[0]b+b( 여기 참조 ).
ETHproductions

4

C # 6, 85 37 36 바이트

long b(long n)=>n>0?n%2+2*b(n/10):0;
  • Kade 덕분에41 바이트를 절약 한 에게 !
  • C # 6으로 변경하면 7 바이트가 더 절약되었습니다.

어쩌면 이것이 영감을 줄 수 있습니까? ;)
Kade

@ 감사합니다, 감사합니다! 나는 당신이 연결된 동일한 순간에 동일한 기술을 사용하여 파이썬 답변을 찾고 있었어요 : DI는 C # 6. 심지어 짧은 얻을 수 있습니다
Yytsi


3

C, 53

v(char*s){int v=0,c;while(c=*s++)v+=v+c-48;return v;}

내 자바 스크립트 답변과 동일

Ideone 테스트


다음 vc같이 선언 하여 전역 변수로 4 바이트를 절약 할 수 있습니다 ( v이미 함수 이름이므로의 이름을 변경해야하지만 ) :w=0;c;v(char*s){while(c=*s++)w+=w+c-48;return w;}
Steadybox

@Steadybox는 가능 w,c;하지만 답변이 함수 일 때 (글로벌 골프에서도) 전역을 사용하고 싶지 않습니다.
edc65

@Steadybox Globals의 기본값도 0이므로을 삭제할 수 있습니다 =0.
algmyr

3

펄, 25 바이트

@Dom Hastings 덕분에 -3 바이트

코드의 24 바이트 + -p플래그의 경우 1 바이트

$\|=$&<<$v++while s/.$//

그것을 실행하려면 :

perl -pe '$\|=$&<<$v++while s/.$//' <<< 101010

설명 :

$\|=$&<<$v++  # Note that: we use $\ to store the result
              # at first $v=0, and each time it's incremented by one
              # $& contains the current bit (matched with the regex, see bellow)
              # So this operation sets a $v-th bit of $\ to the value of the $v-th bit of the input
while         # keep doing this while...
s/.$//        #  ... there is a character at the end of the string, which we remove.
         # $\ is implicitly printed thanks to -p flag

3

Pushy , 10 바이트

명령 행에서 0/1의 목록으로 입력을 $ pushy binary.pshy 1,0,1,0,1,0받습니다.

L:vK2*;OS#

이 알고리즘은 실제로 두 번째 스택을 갖는 아름다움을 보여줍니다.

            \ Implicit: Input on stack
L:    ;     \ len(input) times do:
  v         \   Push last number to auxiliary stack
   K2*      \   Double all items
       OS#  \ Output sum of auxiliary stack

이 방법은 stack length - nnumber n에 도달하기 전에 스택이 두 배로 증가한 후 나중에 두 번째 스택으로 덤프 되기 때문에 작동합니다 . 입력 과정은 다음과 같습니다 101010.

1 : [1,0,1,0,1,0]
2 : []

1 : [2,0,2,0,2]
2 : [0]

1 : [4,0,4,0]
2 : [2]

1 : [8,0,8]
2 : [2,0]

1 : [16,0]
2 : [2,0,8]

1 : [32]
2 : [2,0,8,0]

1: []
2 : [2,0,8,0,32]

2 + 8 + 32-> 42

3

Matlab, 30 바이트

@(x)sum(2.^find(flip(x)-48)/2)

마지막 테스트 사례는 (때문에 double) 반올림 오류가 있으므로 전체 정밀도가 필요한 경우 :

@(x)sum(2.^uint64(find(flip(x)-48))/2,'native')

47 바이트


나는 이것을 테스트 할 수 없지만 @(x)sum(2.^(find(flip(x)-48)-1))32 바이트에 대한 모든 경우에 올바른 결과를 줄 것이라고 믿습니다 . 1 차원 인 경우 flip처럼 작동 합니다. fliplrx
Stewie Griffin

좋은 해결책! 또한 수정에 감사합니다. 반올림 오류가 발생했습니다. x의 형식은 무엇입니까? 숫자에 대해 flip 또는 fliplr을 호출하면 해당 숫자가 반환됩니다.
MattWH

x는 이진 문자열이므로로 호출하십시오 f=@(x)..; f('1111001010').
Jonas

3

망막 , 12 바이트

바이트 수는 ISO 8859-1 인코딩을 가정합니다.

+%`\B
¶$`:
1

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

대체 솔루션 :

+1`\B
:$`:
1

설명

이것은 아마도 오래된 골프 버전을 기반으로 설명하기가 더 쉬울 것이며 어떻게 단축했는지 보여줄 것입니다. 나는 바이너리를 십진수로 다음과 같이 변환했다.

^
,
+`,(.)
$`$1,
1

Retina에서 십진수를 구성하는 유일한 현명한 방법은 물건을 세는 것입니다 (Retina에는 금액을 나타내는 소수를 인쇄 할 수있는 몇 가지 기능이 있기 때문에). 따라서 실제로 가능한 유일한 방법은 이진을 단항으로 변환 한 다음 단항 자릿수를 계산하는 것입니다. 마지막 줄은 계산을 수행하므로 처음 네 개는 이진을 단항으로 변환합니다.

우리는 어떻게합니까? 일반적으로 비트 목록을 정수로 변환하기 위해 결과를 초기화 0한 다음 가장 중요한 비트부터 가장 중요하지 않은 비트까지갑니다. 이미 가지고있는 값을 두 배로 늘리고 현재 비트를 추가합니다. 예를 들어 이진수가 1011인 경우 실제로 계산합니다.

(((0 * 2 + 1) * 2 + 0) * 2 + 1) * 2 + 1 = 11
           ^        ^        ^        ^

명확성을 위해 개별 비트를 표시 한 위치

단항식 에서이 작업을 수행하는 트릭은 a) 두 배가되면 숫자를 반복한다는 의미입니다 .b) 1끝에 s를 계산하기 때문에 프로세스에서 0s와 1s 를 구분할 필요조차 없습니다 . 이것은 곧 더 명확해질 것입니다.

프로그램이하는 일은 먼저 이미 처리 한 입력량을 나타내는 마커로 시작 부분에 쉼표를 추가한다는 것입니다.

^
,

마커의 왼쪽에는 누적되는 값 (0의 단항 표현으로 올바르게 초기화 됨)이 있으며 값의 오른쪽이 처리 할 다음 비트입니다. 이제 다음 대체를 루프에 적용합니다.

,(.)
$`$1,

,(.)and을 보면 $1,매번 마커가 오른쪽으로 1 비트 씩 이동합니다. 그러나 또한 $`마커 앞에있는 모든 것, 즉 현재 값이 두 배가되는을 삽입합니다. input을 처리 할 때의 개별 단계는 다음과 같습니다. 여기 1011에서 $`각 줄 위에 삽입 한 결과를 표시했습니다 (첫 번째 단계에서는 비어 있음).

,1011

1,011
 _
110,11
   ___
1101101,1
       _______
110110111011011,

우리는 다른 모든 것들과 함께 0을 유지하고 두 배로 늘렸다는 것을 알 수 있습니다. 그러나 우리는 마지막에 그것들을 무시하기 때문에 1s의 수는 옳은. 당신이 그들을 세면11 이 그들을 세면, 그들 중 우리가 필요한 것만 있습니다.

그래서 이것을 12 바이트로 골프하는 법에 대한 질문이 남습니다. 18 바이트 버전에서 가장 비싼 부분은 마커를 사용해야합니다. 목표는 그것을 제거하는 것입니다. 우리는 모든 비트의 접두사를 두 배로 늘리기를 원하므로 첫 번째 아이디어는 다음과 같습니다.

.
$`$&

문제는 이러한 대체가 동시에 발생하므로 첫 번째 비트는 각 비트마다 두 배가 되지 않지만 매번 한 번만 복사된다는 것입니다. 입력 1011을 위해 우리는 (삽입 된 표시 $`)을 얻습니다 .

 _ __ ___
1101011011

배가 된 첫 번째 접두사가 두 번째로 다시 두 배가되도록 입력을 재귀 적으로 처리해야합니다. 한 가지 아이디어는 마커를 어디에나 삽입하고 반복적으로 접두어로 대체하는 것입니다.

\B
,
+%`,
¶$`

각 마커를 접두사로 처음 교체 한 후 입력 시작 위치를 기억해야하므로 줄 바꿈을 삽입하고 %옵션을 사용 하여 다음 $`줄이 가장 가까운 줄 바꿈을 선택하도록합니다.

이것은 작동하지만 여전히 너무 깁니다 ( 1끝에 s를 세면 16 바이트 ). 우리는 어떻습니까? 마커를 삽입하려는 \B위치는 (두 자리 사이의 위치) 로 식별됩니다 . 왜 우리는 단순히 그 위치에 접두사를 삽입하지 않습니까? 이것은 거의 효과가 있지만 이전 솔루션에서는 실제로 각 대체에서 하나의 마커를 제거했으며 프로세스를 종료하는 것이 중요하다는 차이점이 있습니다. 그러나 \B캐릭터가 아니라 위치이므로 제거되지 않습니다. 그러나 우리 \B 대신이 자리에 숫자가 아닌 문자를 삽입하여 일치에서. 이는 단어가 아닌 경계를 단어 경계로 바꾸는데, 이는 이전에 마커 문자를 제거하는 것과 같습니다. 이것이 12 바이트 솔루션의 기능입니다.

+%`\B
¶$`:

완전성을 위해 다음은 1011각 단계마다 빈 줄 이있는 개별 처리 단계입니다.

1
1:0
10:1
101:1

1
1:0
1
1:0:1
1
1:0
10:1:1

1
1:0
1
1:0:1
1
1:0
1
1:0:1:1

다시 말하지만, 마지막 결과에는 정확히 11 1초가 포함되어 있습니다 .

독자를위한 연습으로, 이것이 다른베이스에 얼마나 쉽게 일반화되는지 (베이스의 증분 당 몇 바이트 추가) 어떻게 알 수 있습니까?


2

T-SQL, 202 바이트

DECLARE @b varchar(max)='1',@ int=1 declare @l int=LEN(@b)declare @o bigint=CAST(SUBSTRING(@b,@l,1)AS bigint)WHILE @<@l BEGIN SET @o=@o+POWER(CAST(SUBSTRING(@b,@l-@,1)*2AS bigint),@)SET @=@+1 END PRINT @o

2

PHP, 64 바이트

foreach(str_split(strrev($argv[1]))as$k=>$v)$t+=$v*2**$k;echo$t;

We reverse our binary number, split it into its component digits, and sum them based on position.


2

Bash + GNU utilities, 29 bytes

sed 's/./2*&+/g;s/.*/K&p/'|dc

I/O via stdin/stdout.

The sed expression splits the binary up into each digit and builds a RPN expression for dc to evaluate.


2

PowerShell v2+, 55 bytes

param($n)$j=1;$n[$n.length..0]|%{$i+=+"$_"*$j;$j*=2};$i

Feels too long ... Can't seem to golf it down any -- tips appreciated.

Explanation

param($n)$j=1;$n[$n.length..0]|%{$i+=+"$_"*$j;$j*=2};$i
param($n)$j=1;                                          # Take input $n as string, set $j=1
              $n[$n.length..0]                          # Reverses, also converts to char-array
                              |%{                  };   # Loop over that array
                                 $i+=+"$_"*$j;          # Increment by current value of $j times current digit
                                              $j*=2     # Increase $j for next loop iteration
                                                     $i # Leave $i on pipeline
                                                        # Implicit output

2

JavaScript (ES6), 32 bytes

f=([...n])=>n+n&&+n.pop()+2*f(n)

Recursion saves the day again! Though the parameterization seems a little long...


Since it's a single "argument", does [...n] need to be surrounded in parentheses?
Cyoce

@Cyoce Unfortunately, yes, or JS throws a SyntaxError.
ETHproductions

2

Mathematica, 27 13 11 bytes

Fold[#+##&]

Accepts a List of bits as input (e.g. {1, 0, 1, 1, 0} -- Mathematica's binary representation of the number 22)


Following up from the comment on Greg's answer, how is "splitting all the digits in the input" not a base conversion function?
Martin Ender

@MartinEnder I'm using it like the Characters function.
JungHwan Min

@MartinEnder Actually, as seen in @nimi's answer, I could just accept a list of 1s and 0s because that is the only way to represent a binary number in Mathematica, meaning I don't need IntegerDigits in the first place.
JungHwan Min

That assumes that base 10 is the "natural" representation of an integer. An actual integer value has no preferred base attached to it (I guess you could say the way it's stored is probably base 256 or maybe even base 2 but that's an implementation detail). Just because we (normally) use base 10 to write integer literals there doesn't mean integer values are already in base 10.
Martin Ender

@MartinEnder @Lynn's Jelly code uses D, which does the same thing as IntegerDigits
JungHwan Min

2

Clojure, 114 105 63 41 bytes

V4: 41 bytes

-22 bytes thanks to @cliffroot. Since digit is a character, it can be converted to it's code via int, then have 48 subtracted from it to get the actual number. The map was also factored out. I don't know why it seemed necessary.

#(reduce(fn[a d](+(* a 2)(-(int d)48)))%)

V3: 63 bytes

(fn[s](reduce #(+(* %1 2)%2)(map #(Integer/parseInt(str %))s)))

-42 bytes (!) by peeking at other answers. My "zipping" was evidently very naïve. Instead of raising 2 to the current place's power, then multiplying it by the current digit and adding the result to the accumulator, it just multiplies the accumulator by 2, adds on the current digit, then adds it to the accumulator. Also converted the reducing function to a macro to shave off a bit.

Thanks to @nimi, and @Adnan!

Ungolfed:

(defn to-dec [binary-str]
  (reduce (fn [acc digit]
            (+ (* acc 2) digit))
          (map #(Integer/parseInt (str %)) binary-str)))

V2: 105 bytes

#(reduce(fn[a[p d]](+ a(*(Integer/parseInt(str d))(long(Math/pow 2 p)))))0(map vector(range)(reverse %)))

-9 bytes by reversing the string so I don't need to create an awkward descending range.

V1: 114 bytes

Well, I'm certainly not winning! In my defense, this is the first program I've ever written that converts between bases, so I had to learn how to do it. It also doesn't help that Math/pow returns a double that requires converting from, and Integer/parseInt doesn't accept a character, so the digit needs to be wrapped prior to passing.

#(reduce(fn[a[p d]](+ a(*(Integer/parseInt(str d))(long(Math/pow 2 p)))))0(map vector(range(dec(count %))-1 -1)%))

Zips the string with a descending index representing the place number. Reduces over the resulting list.

Ungolfed:

(defn to-dec [binary-str]
  (reduce (fn [acc [place digit]]
            (let [parsed-digit (Integer/parseInt (str digit))
                  place-value (long (Math/pow 2 place))]
              (+ acc (* parsed-digit place-value))))
          0
          (map vector (range (dec (count binary-str)) -1 -1) binary-str)))

#(reduce(fn[a b](+(* a 2)(-(int b)48)))0 %) improved version. Moved map part of code directly into reduce, changed integer parsing method, make external function with shorthand lambda syntax.
cliffroot

@cliffroot int can be used to parse!? That'll knock off like 10 bytes in every challenge I've done here lol.
Carcigenicate

Oh, I see what you're doing. Taking the ascii code, then subtracting to get the value. I guess this would only work in select circumstances only. Oh well, thanks for the tip.
Carcigenicate

2

Perl, 21 19 16 + 4 = 20 bytes

-4 bytes thanks to @Dada

Run with -F -p (including the extra space after the F). Pipe values to the function using echo -n

$\+=$_+$\for@F}{

Run as echo -n "101010" | perl -F -pE '$\+=$_+$\for@F}{'

I feel this is sufficiently different from @Dada's answer that it merits its own entry.

Explanation:

-F                              #Splits the input character by character into the @F array
-p                              #Wraps the entire program in while(<>){ ... print} turning it into
while(<>){$\+=$_+$\for@F}{print}
                   for@F        #Loops through the @F array in order ($_ as alias), and...
          $\+=$_+$\             #...doubles $\, and then adds $_ to it (0 or 1)...
while(<>){              }       #...as long as there is input.
                         {print}#Prints the contents of $_ (empty outside of its scope), followed by the output record separator $\

This uses my personal algorithm of choice for binary-to-decimal conversion. Given a binary number, start your accumulator at 0, and go through its bits one by one. Double the accumulator each bit, then add the bit itself to your accumulator, and you end up with the decimal value. It works because each bit ends up being doubled the appropriate number of times for its position based on how many more bits are left in the original binary number.


Even shorter : perl -F -pE '$\+=$_+$\for@F}{'
Dada

I honestly laughed at how short this is now. Thank you.
Gabriel Benamy

Yea, it's pretty neat, well done!
Dada

2

R (32-bit), 64 Bytes

Input for the function should be given as character. The base functions of R support 32-bit integers.

Input:

# 32-bit version (base)
f=function(x)sum(as.double(el(strsplit(x,"")))*2^(nchar(x):1-1))
f("1")
f("10")
f("101010")
f("1101111111010101100101110111001110001000110100110011100000111")

Output:

> f("1")
[1] 1
> f("10")
[1] 2
> f("101010")
[1] 42
> f("1101111111010101100101110111001110001000110100110011100000111")
[1] 2.016121e+18

R (64-bit), 74 Bytes

Input for the function should be given as character. The package bit64 has to be used for 64-bit integers.

Input:

# 64-bit version (bit64)
g=function(x)sum(bit64::as.integer64(el(strsplit(x,"")))*2^(nchar(x):1-1))
g("1")
g("10")
g("101010")
g("1101111111010101100101110111001110001000110100110011100000111")

Output:

> g("1")
integer64
[1] 1
> g("10")
integer64
[1] 2
> g("101010")
integer64
[1] 42
> g("1101111111010101100101110111001110001000110100110011100000111")
integer64
[1] 2016120520371234567

2
You can do: el(strsplit(x,"")) instead of strsplit(x,split="")[[1]] to save a couple of bytes.
Billywob

Thanks a lot! Especially for the el function - I was not aware of it.
djhurio

2

Dyalog APL, 12 bytes

(++⊢)/⌽⍎¨⍞

get string input

⍎¨ convert each character to number

reverse

(...)/ insert the following function between the numbers

++⊢ the sum of the arguments plus the right argument


ngn shaved 2 bytes.


1

k, 8 bytes

Same method as the Haskell answer above.

{y+2*x}/

Example:

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