最短代码按位反转二进制字符串


79

我认为这里没有足够的简单问题供初学者尝试!

挑战:给定随机输入字符串1和0,例如:

10101110101010010100010001010110101001010

编写输出最短代码的最短代码,如下所示:

01010001010101101011101110101001010110101

Answers:


88

J,5个字节

假设输入字符串在variable中b

b='0'

这并没有大多数语言所能做的...

歼比较操作仅仅是==:=.是全局和局部的分配,分别)。但是,=它不能像普通==运算符一样工作:它逐项进行比较。请记住,数组是这样形成的:0 2 3 2 3 1 2 3 42 = 0 2 3 2 3 1 2 3 4给出0 1 0 1 0 0 1 0 0的例子。这是一个字符串类似:'a'='abcadcadda'不只是返回0,返回1 0 0 1 0 0 1 0 0 1(这可以推断是指0*/,这基本上意味着all)。在这种情况下,但是,这种行为是外观极好,因为我们要一和零的字符串,或对与错。由于J的布尔变量 10,这导致阵列1的和0的(它们不是字符串,除此以外的所有其他字符1也都将导致0此数组。)这不需要打印:J自动打印表达式的结果。我希望这是足够的解释,否则请提出一些尚不清楚的意见。这个答案也可以是'0'&=(或=&'0'),但是我觉得这b='0'很清楚。


1
我尝试过J。我不能屈服于此。猜猜我还没有找到好的文档。在这里,为狂人+1。
seequ 2014年

1
这就是为什么我永远不会使用J.
的Qix

2
@Qix就像J一样难以理解,这对我来说实际上是有意义的,并且其他具有使用矢量LHS和标量RHS的运算符的语言的行为也类似。
2014年

1
什么?它没有返回正确的结果,是吗?结果应该是一个文本字符串(无空格),但我有限的J知识,我认为这会返回一个布尔值列表以0 1 0 1 0的显示格式...
亚当

4
这是不允许的,因为您不能假定输入存储在某个变量中。=&'0'适用于相同数量的字节。
硕果累累

43

GolfScript,5个字节

{1^}%

在线尝试。

这个怎么运作

  • GolfScript从STDIN读取整个输入,并将其作为字符串放在堆栈中。

  • {}% 遍历字符串中的所有字符,并对所有字符执行代码块。

  • 1^ 计算字符ASCII码与1的异或。“ 0”对应于ASCII码48,“ 1”对应于ASCII码49。

    由于48 ^ 1 = 4949 ^ 1 = 48,这将0变成1,将1变成0。

  • 完成后,GolfScript将打印修改后的字符串。


6
等等,golfscript
ToonAlfrink 2014年

我误解了你的问题。立即修复。
丹尼斯

1
@tolos:我已经编辑了答案。
丹尼斯2014年

5
@ToonAlfrink高尔夫语言(例如GolfScript)在所有挑战中都可以接受,只要它们是“通用的”即可,这意味着它们并非针对特定挑战而设计。
kitcar2000 2014年

4
@ kitcar2000我认为他更惊讶于这种语言的存在,而不是让有人敢于在代码高尔夫球问题中使用GolfScript感到震惊;)
Chris Cirefice 2014年

35

果酱-4

q1f^

这个xor的每个字符都带有1。
与其他CJam答案不同,我不认为输入已经在堆栈上。

http://cjam.aditsu.net/上尝试


2
就是您的使用方式f
丹尼斯

@丹尼斯确实。您可以使用sf论坛问问题btw :)
aditsu

30

DOS上的x86机器代码- 14 13 11字节

好吧,它确实又变短了!在写完一个无关紧要的挑战的解决方案之后,我注意到即使在这里也可以应用相同的技巧。所以我们开始:

00000000  b4 08 cd 21 35 01 0a 86  c2 eb f7                 |...!5......|
0000000b

评论程序集:

    org 100h

section .text

start:
    mov ah,8        ; start with "read character with no echo"
lop:
    ; this loop runs twice per character read; first with ah=8,
    ; so "read character with no echo", then with ah=2, so
    ; "write character"; the switch is performed by the xor below
    int 21h         ; perform syscall
    ; ah is the syscall number; xor with 0x0a changes 8 to 2 and
    ; viceversa (so, switch read <=> write)
    ; al is the read character (when we did read); xor the low
    ; bit to change 0 to 1 and reverse
    xor ax,0x0a01
    mov dl,al       ; put the read (and inverted character) in dl,
                    ; where syscall 2 looks for the character to print
    jmp lop         ; loop

先前的解决方案-13个字节

我认为它不会比这短得多。实际上,确实如此!感谢@ninjalj削减了一个字节。

00000000  b4 08 cd 21 34 01 92 b4  02 cd 21 eb f3           |...!4.....!..|
0000000d

该版本具有高级交互性™ -从命令行运行后,只要您输入输入数字(不回显),它就会吐出“反转”字符。要退出,只需执行Ctrl-C。

与以前的解决方案不同,在DosBox中运行会遇到一些麻烦-由于DosBox 不正确地支持Ctrl-C,如果要退出,将被迫关闭DosBox窗口。相反,在具有DOS 6.0的VM中,它将按预期运行。

NASM来源:

org 100h

section .text

start:
    mov ah,8
    int 21h
    xor al,1
    xchg dx,ax
    mov ah,2
    int 21h
    jmp start

旧解决方案- 27 25 22字节

这从命令行接受了它的输入。作为DosBox中的.COM文件平稳运行。

00000000  bb 01 00 b4 02 8a 97 81  00 80 f2 01 cd 21 43 3a  |.............!C:|
00000010  1e 80 00 7c f0 c3                                 |...|..|

NASM输入:

    org 100h

section .text

start:
    mov bx, 1
    mov ah, 2
loop:
    mov dl, byte[bx+81h]
    xor dl, 1
    int 21h
    inc bx
    cmp bl, byte[80h]
    jl loop
exit:
    ret

2
+1代码可能并不多。
Knerd 2014年

1
xchg dx,axmov dl,al
ninjalj,2016年

@ninjalj:哇,谢谢!它没有得到毕竟短!
Matteo Italia

26

Bash + coreutils,8个字节

tr 01 10

接受来自STDIN的输入。


要么

sed,8个字节

y/01/10/

2
我最近为Bash github.com/professorfish/bash-shelf制作了一个高尔夫库/别名集。您可以使用以下方式y 01 10

1
BASH在这里涉及什么?BASH具体是什么?每个炮弹都可以呼叫tr...
Yeti

1
@yeti并非每个sh​​ell都调用bash或zsh之类的命令。在某些Shell中,仅代码就是语法错误
mniip 2014年

5
可以肯定地假设“ shell”在这里表示“ POSIX兼容外壳” ...
FireFly 2014年

@professorfish,您可以剃除一个字符,然后通过包含该函数来添加48。胜利如何?
Steven Penny 2014年

20

CJam,4个字节

:~:!

假定原始字符串已经在堆栈上。打印修改后的字符串。

通过粘贴以下代码在线尝试

"10101110101010010100010001010110101001010":~:!

这个怎么运作

  • :~计算字符串中的每个字符,即用整数 0 替换字符 0。

  • :!计算每个整数的逻辑非。这会将0变成1,将1变成0。


19

操脑(70 71)

>,[>,]<[<]>[<+++++++[>-------<-]<+>>[++<]<[>]++++++++[>++++++<-]>.[-]>]

说明:

>,[>,]                       Read characters until there are none left.
<[<]                         Return to start
>[<                          Loop as long as there are characters to invert
  +++++++[>-------<-]        Subtract 49 (ASCII value of 1)
  >[++<]                     If not 0, add 2
  +++[<++++>-]<[>>++++<<-]>> Add 48
  .                          Print
  [-]                        Set current cell to 0
>]                           Loop

1
++++++++ [<++++++>-]为什么不使用48?8 * 6 vs. 4 * 4 * 3
Cruncher 2014年

@Cruncher添加了。
kitcar2000 2014年

为什么变长了?是因为“错误修复”吗?
Cruncher 2014年

1
@Cruncher是的,我不得不修复一个bug哪里会输出a11
kitcar2000 2014年

16

PHP-19个字节

<?=strtr($s,[1,0]);

是的,我想这不是真正的原创!


11

煎饼堆,532字节

Put this tasty pancake on top!
[]
Put this delicious pancake on top!
[#]
Put this  pancake on top!
How about a hotcake?
If the pancake is tasty, go over to "#".
Eat all of the pancakes!
Put this supercalifragilisticexpialidociouseventhoughtheso pancake on top!
Flip the pancakes on top!
Take from the top pancakes!
Flip the pancakes on top!
Take from the top pancakes!
Put this supercalifragilisticexpialidociouseventhoughthes pancake on top!
Put the top pancakes together!
Show me a pancake!
If the pancake is tasty, go over to "".

假定输入以空字符终止。该策略如下:

  • 输入字符
  • 1从中减去其ascii值。
  • 减去01如果有00则为a,如果有,则为1
  • 0为其添加ascii值
  • 打印字符。
  • 重复

10

C:29

i(char*s){*s^=*s?i(s+1),1:0;}

在这里在线尝试。

感谢您指出XOR技巧,Dennis。


8
更简单更短:i(char*s){while(*s)*s++^=1;}
edc65 2014年

1
谢谢@ edc65!但是,我不会使用它,因为它是一种迭代解决方案,而不是递归解决方案。我不想为此功劳。值得注意的是,您仍然用长度为28个字符whilefor静态结果替换了您。
millinon 2014年

6
根据你喜欢的。不需要递归解决方案,并且我认为,只要有可能,迭代解决方案就比递归解决方案更好。将此递归调用应用于10k字符串很有趣。
edc65 2014年

1
由于除最后一个调用之外的每个调用都是尾部递归调用,因此我敢打赌,编译器会将其转换为循环以便重新使用堆栈框架。
millinon 2014年

1
@millinon证明!
deed02392 2014年

9

Python 2.7 – 34 *

哦,这第一个吸了多少钱。非常难看,这是。63个字符。

print''.join([bin(~0)[3:] if x == '0' else bin(~1)[4:] for x in ''])

这个比较好一点,但仍然不那么花哨。44个字符。

print''.join([str(int(not(int(x)))) for x in ''])

由于int(x) and 1回报率int(x),如果它不是0,否则返回False。解决方案可以进一步减少到36个字符。

print''.join([str(1-int(x)) for x in ''])

由于join()带有发电机,因此可以卸下支架。32个字符。

print''.join(str(1-int(x))for x in'')

反引号可以代替 str()

print''.join(`1-int(x)`for x in'')

@@ Rare的指针使指针从34减少到44

在python中很难找到一个补码,因为bin(-int)返回-0bxxx就是这样。


2
Ya'know(int(x) and 1) == int(x)
seequ 2014年

@TheRare我没有,谢谢:)
Bassem

1
记录:零为false,非零为true。对于任何种类的序列(列表,字符串...),都应用相同的规则,但是要从序列的长度进行检查。因此,'' == False以及'hi' == True
seequ 2014年

1
好像您错过了一些空格。同样,反引号可用于替换repr()。''.join(`1-int(x)`for x in'')
seequ 2014年

1
Fyi,repr(x)因为x <maxint等于str(x)
Seequ 2014年

7

Perl,9个字符

'y/10/01/'

第9个字符是'p'标志

用法:

$ echo '10101001' | perl -pe 'y/10/01/'

2
也可以用作sed脚本,y/10/01/但因为不需要任何标志而缩短了一个字符

4
您在这里不需要单引号。
Konrad Borowski14年

7

Javascript(ES6)36

alert(prompt().replace(/./g,x=>x^1))

在假设输入ss.replace(/./g,x=>x^1)22个字符。
Oriol 2014年

2
我喜欢实际输出和输入。
nderscore 2014年

@nderscore节省2个字符:p=prompt(p().replace(/./g,x=>x^1))
Gaurang Tandon 2014年

@GaurangTandon一定是这样,(p=prompt)(p().replace(/./g,x=>x^1))并且长度是一样的。
nderscore 2014年

@nderscore我也认为是那样,但是奇怪的是,它也没有括号也可以工作。
Gaurang Tandon 2014年

7

迷宫,6字节

(迷宫比这个挑战要新,所以这个答案没有竞争-并不是说它一直在赢...)

1,
.$@

该代码假定STDIN 包含数字(特别是没有尾随换行符)。

指令指针(IP)从右上角的左上角开始。虽然有要读取的数字,但它会在左侧的2x2块中紧密循环:1按1,,读取数字,将$其与1进行XOR运算以切换最后一位,然后.打印结果。IP进行此循环是因为堆栈的顶部在XOR之后为正,因此需要右转。当我们命中EOF时,,返回-1。然后,XOR将产生,-2并且在此负值的情况下,IP向左转弯@,程序结束。

这个解决方案应该迷宫是最理想的:你需要,.一个I / O环和@终止程序。您至少需要两个字符(此处1$)来切换最后一位。并且您至少需要一个换行符来终止循环。

除非...如果我们忽略STDERR,即允许以错误终止,则可以保存,@并且我们也不需要任何方法在两条路径之间进行切换。我们一直保持阅读和打印,直到我们不小心尝试打印负值(-2)。这允许至少两个5字节解决方案:

1,
.$
,_1$.



4

Python 2.x-44字节

print''.join(`1-int(x)`for x in raw_input())

为什么要使其复杂或使用一些欺骗性变量?


可以这样保存一些额外的字符:print''.join('1-int(x)'for x in'input()')。我无法在注释代码中找到反引号,因此将其替换为'。
威廉2014年

@willem供将来参​​考,您可以使用反斜杠将它们转义:`a\`b`-> a`b
nyuszika7h 2014年

@willem对于以0开头的输入或大于maxint的输入(在base10中)不起作用。
seequ 2014年

感谢@ nyuszika7h,没有考虑TheRare的这些情况,因此您的解决方案很好
Willem

@willem Real很容易忘记这样的东西。:)
seequ 2014年

4

R,27个字符

chartr("01","10",scan(,""))

用法:

> chartr("01","10",scan(,""))
1: 10101110101010010100010001010110101001010
2: 
Read 1 item
[1] "01010001010101101011101110101001010110101"



3

TI-BASIC,7个字节

此函数将二进制字符串(通过Ans)作为输入,并按指定的反向(非反向)字符串返回输出。要获得更多帮助,您可以not(在TI-BASIC Wiki上通读列表应用程序。我使用的是编译版本,因为它较小:

»*r>Õ¸r

十六进制:

BB 2A 72 3E D5 B8 72

说明

»*r -将函数输入作为字符串并转换为列表

> -将给定列表传递给下一个运算符

Õ¸r -返回列表的倒数


末尾的空格是»*r>Õ¸r 什么?
kitcar2000 2014年

@ kitcar2000糟糕,此后我曾经使用过HEX。但是,在我移动它之后,我忘记了删除空格...我现在已经完成了。
Timtech

需要注意的是:1.在计算器上显示为expr(Ans:Returnnot(Ans;2.因为该字符串没有用逗号分隔,并且它不是以a开头{,所以它将评估为整数,例如1000010011,而不是列表;3. Return不符合您的编写方式;4.这将输出作为列表而不是字符串。
lirtosiast,2015年

3

Haskell,22个字节

map(\c->"10"!!read[c])

Haskell缺乏应对这一挑战的解决方案令我感到惊讶,所以这里就是一个。它的计算结果是一个接受字符串并返回其逆值的函数。

说明

这里没什么好看的。

map(\c->             )  -- For each character c in the input string:
                  [c]   -- wrap c into a string,
              read      -- convert to integer,
        "10"!!          -- and index the string "10" with it.

3

Befunge 93,25个字节

0>~1+:#v_$>:#,_@
 ^   -1<

假设堆栈为空且EOF均为-1。

0 将\ 0作为空终止符

>~1+:#v_ 是一个输入循环,它读取ascii,加1,检查EOF + 1 = 0,

^ -1< 否则减去1并将推入的ascii值保留在堆栈中。

$>:#,_@ 将多余的零副本放到栈顶,然后从顶部到底部打印二进制字符串

如果空堆栈读取0,则用2保存字节

>~:1+#v_$>:#,_@
^   -1<

如果EOF = 0,则使用相同的算法可以实现大约15个字节的版本,但是我没有这样的实现可以方便地进行测试。


3

Javascript ES6,26个字符

s=>s.replace(/\d/g,x=>x^1)

3
为什么/ \ d / g不/./g
l4m2


2

Python3,39

Methinks Python并不是最好的语言。:)

for i in input():print(1-int(i),end='')

如果您想在输出之后添加换行符,请使用以下43个字符的替代方法:

print(''.join("01"[i<"1"]for i in input()))

代码将工作,而不end=''只是,会做:) -除非你在乎那里是没有空间
哈利比德尔

@BritishColour,不,那是Python2。Python3的print功能需要调整end参数以在每次打印结束时禁止换行。另外,根据OP的规范,我认为我确实关心没有空格。:)不过,谢谢你的评论!
DLosc

噢,酷,我不知道!我主要在2.7工作:/
哈里·比德尔2014年

2

J-11个字符

J中的布尔值表示为整数01,它们当然也是数组的有效索引(在这种情况下,为2个字符的数组'01'

'01'{~'0'&=

我认为这个答案在技术上比最上面的J答案更正确,后者给出的是布尔数组而不是字符串。
gar 2014年

实际上,我发布时并没有注意到排名靠前的J解决方案(不知道我怎么错过它,但是我做到了)。为了公平起见,该解决方案确实明确表示“这没有其他解决方案所能做的”。顺便说一句,另一种方式来表达在11个字符此(字面输出)的解决方案是[:,“:@ =‘’0‘’
丹布隆

嗨,谢谢您提供另一个代码!我将向你们学习更多的J。关于该声明,我认为他指的是等号,它比较每个项目而不是赋值。
gar 2014年

2

C#,131个字节

派对晚了一点,但是这是我的。:)

using System;class R{static void Main(string[]a){foreach(var v in a[0].ToCharArray()){Console.Write(int.Parse(v.ToString())^1);}}}

2

MATLAB,13个字节

@(x)[97-x '']

运行上述命令后,只需使用输入字符串调用该函数即可获取反向字符串。例如运行:

ans('10101110101010010100010001010110101001010')

印刷品:

01010001010101101011101110101001010110101

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.