字符串到位转换


10

任务

给定一个或多个ASCII字符的输入字符串,其代码点在0到128之间(不包括),请执行以下操作:

  1. 将每个字符转换为其7位ASCII码(如果ASCII码少于7位,则将前导零位放入)
  2. 连接所有位(这导致7*nn是字符数)
  3. 对于此位流中的每一位,如果它与前一位不同,则打印1,否则打印0。第一个输出位始终为1。

输入:

Hi

输出:

11011001011101

说明:

字符串“ Hi”具有ASCII码

72 105

在位是:

1001000 1101001

过渡位指示器:

11011001011101

这是代码高尔夫。最低字节数获胜。

测试用例

测试用例1:

Hello World!
110110010101110011010101101010110001110000111110000110000001011101101010101100110001

测试案例2:

%% COMMENT %%
1110111111011111100001100010010100001010110101011010011101010011111110011000001101111110111

测试案例3(归Luis Mendo所有):

##
11100101110010

恭喜路易斯·门多(Luis Mendo)提供了9个字节的MATL最短解决方案!


2
建议的测试用例##(前导0位;一些答案因此失败)
Luis Mendo

4
这与曼彻斯特编码挑战赛有何相似之处?我想念什么吗?
gastropner '19

2
另一个挑战是将位的输入流转换成双倍速率的输出流,每个输入'1'转换为'01',每个输入'0'转换为'10'。所以我认为不要欺骗。如果有很多人支持上面的@gastropner的评论,则我可以取消重复(或具有此功能的任何其他用户)
Luis Mendo

1
@Shaggy:两个测试用例都包含一个空格,该空格仅设置了一个位,而不是第7个。因此,我认为问题陈述不能保证每个ascii代码的长度恰好为7位。
递归

1
@SmileAndNod再三考虑,我认为您不需要处理空字符串。
justhalf

Answers:


4

MATL,9个字节

Hj7&B!hdg

在线尝试!

说明

H     % Push 2
j     % Read line of input, unevaluated
7&B   % Convert to binary with 7 bits. Gives a 7-column matrix
!     % Transpose
h     % Concatenate horiontally. The matrix is read in column-major order
d     % Consecutive differences
g     % Convert to logical. Implicitly display

1
这是迄今为止最短的时间。+1。具有内置的连续差异很有趣。
Justhalf


4

Japt -P,11个字节

利用了这样的事实:0在尝试对数学执行算术运算或在这种情况下按位运算时,可以在JavaScript中将空格强制转换为事实。

c_¤ù7Ãä^ i1

尝试运行所有测试用例

c_¤ù7Ãä^ i1     :Implicit input of string
c_              :Map codepoints
  ¤             :  Convert to binary string
   ù7           :  Left pad with spaces to length 7
     Ã          :End map
      ä^        :XOR consecutive pairs
         i1     :Prepend 1
                :Implicitly join and output

7位表示如果为32(用于空格字符),则为0100000。同样,%字符(37)为0100101
一半

现在正在工作。+1
justhalf '19

2

CJam,21个字节

1q{i2b7Te[}%e__(;.^);

在线尝试!

说明

显示带有示例输入的堆栈5

1 q      e# Push 1 and then the whole input: 1 "5"
{
  i      e# Convert to its char code: 1 [53]
  2 b    e# Convert to binary: 1 [[1 1 0 1 0 1]]
  7 T e[ e# Left-pad with 0 to length 7: 1 [[0 1 1 0 1 0 1]]
} %      e# Map this block over every character in the string
e_       e# Flatten array: 1 [0 1 1 0 1 0 1]
_ ( ;    e# Duplicate array and remove its first element: 1 [0 1 1 0 1 0 1] [1 1 0 1 0 1]
. ^      e# Element-wise xor: 1 [1 0 1 1 1 1 1]
) ;      e# Remove and pop the last element of the array: 1 [1 0 1 1 1 1]
         e# Stack implicitly printed: 1101111

要查看某个位是否与前一个位不同,我们在位数组和没有第一个元素的位数组之间进行向量(元素方向)异或。我们还删除了结果的最后一位,因为它始终是较长数组的最后一位不变。


2

APL(Dyalog Unicode),16 字节SBCS

完整程序。提示输入来自stdin的字符串。

1,2≠/∊1↓¨11DR¨⍞

在线尝试!

 提示输入(“控制台中的引号”)

11⎕DR¨ 每个字符改变为位布尔d ATA ř epresentation

1↓¨ 删除每个的第一位

ε NLIST(扁平化)

2≠/ 成对差异

1, 前置一个



2

木炭,25字节

⭆θ◧⍘℅鲦⁷←Wⅈ←I﹪⍘KD²←01 ²1

在线尝试!链接是详细版本的代码。说明:

⭆θ◧⍘℅鲦⁷←

将所有字符转换为二进制并将其填充为7的长度,然后打印它们,但将光标放在最后一位上。

Wⅈ

重复直到光标位于第一位。

←I﹪⍘KD²←01 ²

计算数字是否不同,并用差异覆盖每个数字。

1

用覆盖第一个数字1





1

Python 2,104个字节

lambda w:reduce(lambda(A,P),C:(A+'10'[P==C],C),bin(reduce(lambda a,c:a*128+ord(c),w,1))[3:],('','x'))[0]

在线尝试!

快速刺中它。


巧招a*128+ord(c)!但不是reducelambda那种昂贵吗?
Justhalf

1

飞镖213个 168字节

f(s,{t,i}){t=s.runes.map((r)=>r.toRadixString(2).padLeft(7,'0')).join().split('').toList();for(i=t.length-1;i>0;i--)t[i]=t[i]==t[i-1]?'0':'1';t[0]='1';return t.join();}

以前的单线

f(String s)=>'1'+s.runes.map((r)=>r.toRadixString(2).padLeft(7,'0')).join().split('').toList().reversed.reduce((p,e)=>p.substring(0,p.length-1)+(p[p.length-1]==e?'0':'1')+e).split('').reversed.join().substring(1);

在线尝试!

这种冗长和缺乏容易构建的插件确实杀死了这个。仍然设法拉一线。

  • -45字节,不使用一个衬板,而是使用for循环


1

Kotlin,182字节

var l='6'
fun f(b:String)=b.fold(""){t,i->t+"".a(i.toInt())}.map{if(l==it){l=it;0} else {l=it;1}}
fun String.a(v:Int):String=if(v<=0)"${this}0".reversed() else "${this}${v%2}".a(v/2)

在线尝试!

希望我能尽快改善这一点,我觉得必须有一些改进之处,但我现在不认为



1

C(gcc(MinGW)),90个字节

需要提供的编译器itoa()

n[9],b,c;f(char*s){for(b=*s<64;c=*s++;printf("%07s",itoa((c^c/2)&127,n,2)))c|=b<<7,b=c&1;}


1

Ruby -p,50个字节

gsub(/./){"%07b"%$&.ord}
gsub(/./){$`=~/#$&$/?0:1}

在线尝试!

说明

第一行,与Value Ink的答案相同:

gsub(/./){       $&    }   # Replace each character $&…
                   .ord    # …with its ASCII code…
                %          # …formatted as…
          "%07b"           # …binary digits padded to 7 places.

第二行:

gsub(/./){      $&      }  # Replace each character $&…
          $`               # …if the text to its left…
            =~             # …matches…
              /#  $/       # …the Regexp /c$/ where "c" is the character…
                    ?0:1   # …with 0, or 1 otherwise.

在Ruby中,你可以在正则表达式的文字,例如使用插值/Hello #{name}/,并与开始的变量$或者@你可以省略花括号,所以如果例如$&"0"那么grawlixy /#$&$//0$/


1

K(ngn / k)9 13字节

解:

~=':,/(7#2)\'

在线尝试!

说明:

~=':,/(7#2)\' / the solution
           \' / convert each
      (   )   / do this together
       7#2    / 2 2 2 2 2 2 2
    ,/        / flatten
 =':          / equal to each-previous?
~             / not

笔记:

  • +4个字节以支持仅由6位字符组成的字符串

例如,这对于输入似乎失败#(输出仅具有6位)
Luis Mendo

@streetster,您要发布固定版本吗?
Justhalf

1

表情符号,263字节

🏁🍇🔤🔤➡️🖍🆕s🔂b📇🆕🔡👂🏼❗️❗️🍇🍪s🔪🔡🔢b❗️➕128 2❗️1 7❗️🍪➡️🖍s🍉🔤?🔤➡️🖍🆕p🔂b s🍇↪️b🙌p🍇👄🔤0🔤❗️🍉🙅🍇👄🔤1🔤❗️🍉b➡️🖍p🍉🍉

在这里在线尝试

取消高尔夫:

🏁 🍇  💭 Main code block
    🔤🔤 ➡️ 🖍 🆕 s  💭 Start with s as the empty string
    🔂 b 📇 🆕 🔡 👂🏼  💭 For each byte b in the input ...
    ❗️ ❗️ 🍇
        🍪 s  💭 ... append ...
           🔪 🔡 🔢 b ❗️ ➕ 128  💭 ... b + 128 (this gives the leading zero(s) in case the binary representation of b is shorter than 7 digits) ...

                 2  💭 ... in binary ...
              ❗️
              1 7  💭 ... without the leading one ...
           ❗️
        🍪
        ➡️ 🖍 s  💭 ... to s
    🍉
    🔤?🔤 ➡️ 🖍 🆕 p  💭 This will be used as the previous character, by assigning it neither 0 nor 1 we assure the first bit output is always a one
    🔂 b s 🍇  💭 For each character in s:
        ↪️ b 🙌 p 🍇  💭 If it is the same as the previous character ...
            👄 🔤0🔤 ❗️  💭 ... output a zero ...
        🍉 🙅 🍇  💭  ... else ...
            👄 🔤1🔤 ❗️ 💭 ... output a one
        🍉
        b ➡️ 🖍 p  💭 And the current character becomes the new previous character.
    🍉
🍉


1

Python3.8,72个字节

解:

lambda a:["10"[a==(a:=x)]for x in"".join(bin(ord(i)+128)[3:]for i in a)]

说明:

自从Python 3.8引入赋值表达式(而不是标准赋值语句)以来,我一直想在需要记住最后一项的列表理解中使用它们。这不是执行此操作的最佳方法,但演示了一种使用赋值表达式的有趣方法。

该代码创建一个lambda函数,该函数采用必需的参数,该参数是要转换的字符串。调用时,该函数按如下进行。a中的每个字符都将转换为其字符代码,并添加128以处理6位字符(二进制表示始终为8位,我们可以截取第一位)。该数字将转换为二进制数,并且将标题(0x)和加法运算符128中的首字母1截去。然后将这些新的字符串连接成一个更大的字符串。

对于此新字符串(包含文本的级联7位表示形式)中的每个字符,将检查该字符是否与先前的字符相同。第一个字符会怎样?第一个结果字符应始终为“ 1”,因此我们只需要确保最后一个字符变量中的内容既不是“ 1”也不是“ 0”。现在,由于我们不再使用原始参数,因此可以通过重用原始参数来实现。如果原始字符串是单个“ 0”(碰巧可以使用单个“ 1”),这可能是一个问题,但是我们将忽略它。

在比较期间,首先评估了先前字符,因此当我们使用赋值表达式将先前字符变量设置为当前字符时,它不会影响比较表达式的评估。

比较会产生True或False,它们在Python中也可以分别用作1或0,因此它们用于在字符串中查找“ 1”或“ 0”


您可以使用字符串格式文字来保存一些字节:bin(ord(i)+128)[3:]->f"{ord(i):07b}"
movatica

1

TCL215 167 140个字节

{{s {B binary} {X ~$w/64}} {join [lmap c [split $s {}] {$B scan $c c w;$B scan [$B format i [expr 2*$w^$w^$X<<7]] B7 r;set X $w;set r}] ""}}

在线尝试!

使用“一移”和“异或”来检测过渡。将当前字符的lsb传送到下一个字符的msb。通过加入lmap返回的列表来组合每个字符的输出。

使用带有默认参数的lambda来保存初始化和重复命令时的字节。

严重依赖于操作顺序。适用于空字符串。


1

05AB1E(旧版),12 个字节

Çb7jð0:¥ÄJ1ì

使用05AB1E的旧版本,因为j隐含加入串在一起,这需要一个明确Jj在05AB1E的新版本。

在线尝试验证所有测试用例

说明:

Ç             # Convert the (implicit) input-string to a list of ASCII code-points
              #  i.e. "Hi#" → [72,105,35]
 b            # Convert each integer to a binary string
              #  → ["1001000","1101001","100011"]
  7j          # Prepend each with spaces to make them length 7,
              # and join everything together to a single string implicitly
              #  → "10010001101001 100011"
    ð0:       # Replace all those spaces with 0s
              #  → "100100011010010100011"
       ¥      # Get the deltas of each pair of 1s/0s
              #  → [-1,0,1,-1,0,0,1,0,-1,1,-1,0,1,-1,1,-1,0,0,1,0]
        Ä     # Get the absolute value of this
              #  → [1,0,1,1,0,0,1,0,1,1,1,0,1,1,1,1,0,0,1,0]
         J    # Join them all together
              #  → "10110010111011110010"
          1ì  # And prepend a 1
              #  → "110110010111011110010"
              # (after which the result is output implicitly)

1

137字节的Haskell

import Data.Char
b 0=[]
b n=odd n:b(n`div`2)
d x|x='1'|1<2='0'
c=('1':).map d.(zipWith(/=)<*>tail).concatMap(reverse.take 7.b.(+128).ord)

在线尝试!

这里最大的问题是将布尔值(XOR的结果)转换为“ 0” /“ 1”。





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.