代码高尔夫 - 十六进制到(原始)二进制转换 [英] Code golf - hex to (raw) binary conversion

查看:16
本文介绍了代码高尔夫 - 十六进制到(原始)二进制转换的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

针对这个问题询问十六进制到(原始)二进制转换的问题,一条评论建议它可以用5-10 行 C 或任何其他语言"来解决.

In response to this question asking about hex to (raw) binary conversion, a comment suggested that it could be solved in "5-10 lines of C, or any other language."

我确信对于(某些)脚本语言可以实现,并且想看看如何实现.我们能否证明该评论对于 C 也是正确的?

I'm sure that for (some) scripting languages that could be achieved, and would like to see how. Can we prove that comment true, for C, too?

注意:这并不意味着 ASCII 二进制的十六进制 - 特别是输出应该是对应于输入 ASCII 十六进制的原始八位字节流.此外,输入解析器应跳过/忽略空格.

NB: this doesn't mean hex to ASCII binary - specifically the output should be a raw octet stream corresponding to the input ASCII hex. Also, the input parser should skip/ignore white space.

编辑(作者:Brian Campbell)为了保持一致性,我可以提出以下规则吗?如果您认为这些内容没有帮助,请随意编辑或删除这些内容,但我认为由于已经讨论了某些情况应该如何工作,因此进行一些澄清会有所帮助.

edit (by Brian Campbell) May I propose the following rules, for consistency? Feel free to edit or delete these if you don't think these are helpful, but I think that since there has been some discussion of how certain cases should work, some clarification would be helpful.

  1. 程序必须从标准输入读取并写入标准输出(我们也可以允许读取和写入通过命令行传入的文件,但我无法想象在任何语言中这会比标准输入和标准输出更短)
  2. 该程序必须仅使用您的基本标准语言发行版中包含的软件包.对于 C/C++,这意味着它们各自的标准库,而不是 POSIX.
  3. 程序必须在没有传递给编译器或解释器的任何特殊选项的情况下编译或运行(因此,'gcc myprog.c' 或 'python myprog.py' 或 'ruby myprog.rb' 都可以,而 'ruby -rscanf不允许使用 myprog.rb';需要/导入模块会影响您的字符数).
  4. 程序应读取由成对的相邻十六进制数字(大写、小写或混合大小写)表示的整数字节,可选用空格分隔,并将相应的字节写入输出.每对十六进制数字都以最重要的半字节在前写入.
  5. 程序对无效输入的行为(除了 [a-fA-F ] 之外的字符,在单个字节中分隔两个字符的空格,奇数个十六进制数输入中的数字)未定义;错误输入的任何行为(除了主动损坏用户计算机或其他东西)都是可以接受的(抛出错误、停止输出、忽略错误字符、将单个字符视为一个字节的值,都可以)
  6. 程序可能不会写入额外的字节来输出.
  7. 代码按源文件中最少的总字节数计分.(或者,如果我们想更忠实于最初的挑战,分数将基于最少的代码行数;在这种情况下,我会限制每行 80 个字符,否则你会得到一堆并列 1 行).
  1. The program must read from stdin and write to stdout (we could also allow reading from and writing to files passed in on the command line, but I can't imagine that would be shorter in any language than stdin and stdout)
  2. The program must use only packages included with your base, standard language distribution. In the case of C/C++, this means their respective standard libraries, and not POSIX.
  3. The program must compile or run without any special options passed to the compiler or interpreter (so, 'gcc myprog.c' or 'python myprog.py' or 'ruby myprog.rb' are OK, while 'ruby -rscanf myprog.rb' is not allowed; requiring/importing modules counts against your character count).
  4. The program should read integer bytes represented by pairs of adjacent hexadecimal digits (upper, lower, or mixed case), optionally separated by whitespace, and write the corresponding bytes to output. Each pair of hexadecimal digits is written with most significant nibble first.
  5. The behavior of the program on invalid input (characters besides [a-fA-F ], spaces separating the two characters in an individual byte, an odd number of hex digits in the input) is undefined; any behavior (other than actively damaging the user's computer or something) on bad input is acceptable (throwing an error, stopping output, ignoring bad characters, treating a single character as the value of one byte, are all OK)
  6. The program may write no additional bytes to output.
  7. Code is scored by fewest total bytes in the source file. (Or, if we wanted to be more true to the original challenge, the score would be based on lowest number of lines of code; I would impose an 80 character limit per line in that case, since otherwise you'd get a bunch of ties for 1 line).

推荐答案

edit Checkers 已将我的 C 解决方案简化为 46 字节,然后由于 BillyONEal 的提示加上我的错误修复而减少到 44 字节(不再有无限循环错误的输入,现在它只是终止循环).请感谢 Checkers 将其从 77 字节减少到 46 字节:

edit Checkers has reduced my C solution to 46 bytes, which was then reduced to 44 bytes thanks to a tip from BillyONeal plus a bugfix on my part (no more infinite loop on bad input, now it just terminates the loop). Please give credit to Checkers for reducing this from 77 to 46 bytes:

main(i){while(scanf("%2x",&i)>0)putchar(i);}

我有一个比上一个更好的 Ruby 解决方案,在 42 38 个字节(感谢 Joshua Swank 的正则表达式建议):

And I have a much better Ruby solution than my last, in 42 38 bytes (thanks to Joshua Swank for the regexp suggestion):

STDIN.read.scan(/SS/){|x|putc x.hex}

原创解决方案

C,77 字节,或两行代码(如果您可以将 #include 放在同一行,则为 1).请注意,这对错误输入有一个无限循环;在 Checkers 和 BillyONEal 的帮助下,44 字节解决方案修复了错误,并在输入错误时停止.

C, in 77 bytes, or two lines of code (would be 1 if you could put the #include on the same line). Note that this has an infinite loop on bad input; the 44 byte solution with the help of Checkers and BillyONeal fixes the bug, and simply stops on bad input.

#include <stdio.h>
int main(){char c;while(scanf("%2x",&c)!=EOF)putchar(c);}

如果你正常格式化它甚至只有6行:

It's even just 6 lines if you format it normally:

#include <stdio.h>
int main() {
  char c;
  while (scanf("%2x",&c) != EOF)
    putchar(c);
}

Ruby,79 字节(我相信这可以改进):

Ruby, 79 bytes (I'm sure this can be improved):

STDOUT.write STDIN.read.scan(/[^s]s*[^s]s*/).map{|x|x.to_i(16)}.pack("c*")

这些都从 STDIN 获取输入并写入 STDOUT

These both take input from STDIN and write to STDOUT

这篇关于代码高尔夫 - 十六进制到(原始)二进制转换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆