펄, 137 자
($x,$y)=<>;while($x=~s/.. *//s){$e=hex$&;$i=0;$s=$r[$i]+=$e*hex,$r[$i]&=255,$r[++$i]+=$s>>8 for$y=~/.. */gs;$y="00$y"}printf'%02x 'x@r,@r
경고
- 때때로
00결과의 끝에 여분의 바이트를 인쇄합니다 . 물론 여분의 바이트를 사용해도 결과는 여전히 정확합니다.
- 결과에서 마지막 16 진 바이트 다음에 추가 공간을 인쇄합니다.
설명
설명은 약간 길지만 여기에있는 대부분의 사람들은 흥미로울 것입니다.
우선 10 살 때 다음과 같은 작은 요령을 배웠습니다. 이 두 양수를 곱할 수 있습니다. 이것을 13 × 47의 예를 사용하여 설명하겠습니다. 첫 번째 숫자 인 13을 쓰고 1에 도달 할 때까지 숫자 를 2로 나눕니다 .
13
6
3
1
이제 13 옆에 다른 숫자 47을 쓰고 같은 수의 2를 계속 곱 하십시오.
13 47
6 94
3 188
1 376
이제 왼쪽의 숫자가 짝수 인 모든 줄을 건너 뜁니다 . 이 경우 이것은 6입니다. (코드에서 취소 선을 사용할 수 없으므로 제거하겠습니다.) 마지막으로 오른쪽에 나머지 숫자를 모두 추가합니다.
13 47
3 188
1 376
----
611
그리고 이것이 정답입니다. 13 × 47 = 611.
이제 여러분은 모두 컴퓨터 전문가이기 때문에 왼쪽 및 오른쪽 열에서 실제로 수행하는 작업은 각각 x >> 1및 y << 1입니다. 또한 yif 만 추가합니다 x & 1 == 1. 이것은 알고리즘으로 직접 변환되어 의사 코드로 작성합니다.
input x, y
result = 0
while x > 0:
if x & 1 == 1:
result = result + y
x = x >> 1
y = y << 1
print result
if곱셈을 사용 하도록를 다시 쓴 다음 비트 단위 대신 바이트 단위로 작동하도록 쉽게 변경할 수 있습니다.
input x, y
result = 0
while x > 0:
result = result + (y * (x & 255))
x = x >> 8
y = y << 8
print result
여기에는 여전히 y임의의 크기 인 와의 곱셈이 포함되어 있으므로 루프로도 변경해야합니다. 우리는 펄에서 그렇게 할 것입니다.
이제 모든 것을 Perl로 번역하십시오 :
$x그리고 $y16 진수 형식의 입력이므로 가장 중요하지 않은 바이트가 먼저 있습니다.
따라서, 대신 x >> 8내가 할 $x =~ s/.. *//s. 마지막 바이트에는 공백이 없을 수도 있으므로 space + star가 필요합니다 (space + ?도 사용할 수 있음 ). 제거 된 바이트 ( x & 255)를 자동으로에 넣 습니다 $&.
y << 8간단 $y = "00$y"합니다.
이 result실제로 숫자 배열이다 @r. 마지막에의 각 요소 @r에는 1 바이트의 답변 이 포함되지만 계산의 중간에는 2 바이트 이상이 포함될 수 있습니다. 아래에서 각 값이 2 바이트 (16 비트)를 넘지 않으며 결과가 항상 1 바이트임을 확인합니다.
Perl 코드는 다음과 같습니다.
# Input x and y
($x, $y) = <>;
# Do the equivalent of $& = x & 255, x = x >> 8
while ($x =~ s/.. *//s)
{
# Let e = x & 255
$e = hex $&;
# For every byte in y... (notice this sets $_ to each byte)
$i = 0;
for ($y =~ /.. */gs)
{
# Do the multiplication of two single-byte values.
$s = $r[$i] += $e*hex,
# Truncate the value in $r[$i] to one byte. The rest of it is still in $s
$r[$i] &= 255,
# Move to the next array item and add the carry there.
$r[++$i] += $s >> 8
}
# Do the equivalent of y = y << 8
$y = "00$y"
}
# Output the result in hex format.
printf '%02x ' x @r, @r
이제 이것이 항상 bytes를 출력 하고 계산이 2 바이트 보다 큰 값을 생성하지 않는다는 증거입니다 . while루프를 통해 유도하여 이것을 증명할 것입니다 .
이것으로 놀랍고 흥미로운 도전이 끝납니다. 게시 해 주셔서 감사합니다!