Perl、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歳のときに、次の小さなトリックを教えられました。これで任意の2つの正数を乗算できます。これについては、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であることに気付くでしょう。さらに、yのみを追加し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でそれを行います。
すべてをPerlに変換します。
$xそして、$y16進形式の入力ですので、彼らは持っている最も重要なバイトを最初に。
したがって、x >> 8私がする代わりに$x =~ s/.. *//s。最後のバイトにスペースがない場合があるため、スペース+スターが必要です(スペース+ ?も使用できます)。これは削除されたバイト(x & 255)を自動的に入れ$&ます。
y << 8は単純$y = "00$y"です。
result実際の数値配列です@r。最後に、の各要素に@rは1バイトの回答が含まれますが、計算の途中で複数のバイトが含まれることがあります。各値が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ループ上の帰納法でこれを証明します。
これで、すばらしい刺激的な挑戦が終わりました。投稿してくれてありがとう!