\begingroup

今天的任务很简单。给定一个长度为 2 的整数幂减一的字符串,将其分成长度加倍的段。

例如对于字符串abcdefghijklmno结果应该a,,,bcdefghijklmno

abcdefghijklmno  (length 15)

a                 length 1
 bc               length 2
   defg           length 4
       hijklmno   length 8

输入不会是空字符串。

这是;每种语言的最短解决方案获胜。

\endgroup

1

  • \begingroup

    \endgroup


    – 


29 个解决方案
29

\begingroup

,46字节

\(x)substring(x,a<-2^(0:log2(nchar(x))),2*a-1)

将输入作为字符串并输出字符串向量。


,44字节

\(x)split(x,rep(i<-2^(0:log2(length(x))),i))

将输入作为字符向量并输出字符向量列表。

\endgroup

\begingroup

,16字节

{(&*/'2\'!#x)_x}

这是我自己的 J 解决方案的近乎反向移植。它不是检查每个基于 1 的索引是否恰好有一个 1 位,而是检查每个基于 0 的索引是否都是二进制 1。这在 K 中有效(2\0是一个空数组,其乘积为 1),但在 J 中无效(而#:0不是0一个空数组)。

,17字节

{(|1_(-2!)\#x)_x}

与 Jelly 类似(在指定的索引处x_y切割),但必须小心避免生成大索引或非递增顺序的索引(这会导致域错误)。yx

我最初的方法使用2\(整数转换为二进制向量)和2/(二进制向量转换为整数),但我意识到只需反复将长度除以 2 即可得到正确的切割索引。

{(|1_(-2!)\#x)_x}    Input: a string of length 2^n-1 (example: "abcdefg")
 (         #x)       length of x = 7
     (-2!)\          repeatedly floor-divide by 2 until convergence and collect:
                     (7 3 1 0)
   1_                remove head which is too large (3 1 0)
  |                  reverse (0 1 3)
              _x     cut x with those indices ("a"; "bc"; "defg")

\endgroup

\begingroup

,16 字节

匿名隐式前缀函数。需要基于 0 的索引 ( ⎕IO←0),这是许多系统的默认设置。

⊢⊂⍨≢↑∘∊1↑¨⍨2*⍳∘≢

 争论……

⊂⍨ 被…分割

 争论的长度……

↑∘∊ 扁平的前缀…

1↑¨⍨ 前缀 1 (末尾填充 0) 的长度…

2* 2 的…次方

⍳∘≢ 参数长度的索引 (0…n−1)

\endgroup

\begingroup

,26字节

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

输出由制表符 (ASCII 9) 分隔,末尾有一些额外的制表符。

\endgroup

\begingroup

 66   65   50   49   46  42 字节

-1 字节,通过取消 int.bit_length()
-15 字节:递归获胜!
-1 字节,通过使用列表解包而不是 list()
-3 字节,通过移动一些内容。
-4 字节,通过使用 and 而不是三元组 ... if ... else ...

f=lambda x,n=1:[*x]and[x[:n]]+f(x[n:],2*n)

\endgroup

\begingroup

,38 字节

x=>x.replace(/|/g,_=>i&++i?'':' ',i=0)

用空格隔开

\endgroup

1

  • \begingroup
    通过将字符数组作为输入,得到
    \endgroup


    – 

\begingroup

,5字节

JxËᶻL

JxËᶻL
J       Split the input into a list of substrings
 x      Push [0, ..., length of the list - 1]
  Ë     Power of 2
   ᶻL   Check that each substring has the corresponding length

\endgroup

\begingroup

, 58

f(s,i)char*s;{while(putchar(*s++))if(!(++i&i-1))puts("");}

\endgroup

3

  • 1
    \begingroup
    我喜欢有条件地打印换行符而不是改变打印的字符数的想法。
    \endgroup


    – 

  • \begingroup

    \endgroup


    – 

  • \begingroup
    话虽如此,我认为您不能强制i调用者进行初始化。因此它可能更像是
    \endgroup


    – 


\begingroup

,13字节

E↨Lθ²×ψX²κ↑¤θ

链接为代码的详细版本。说明:

E↨Lθ²×ψX²κ

保留与输入长度的1基数表示中的 s 相对应的多行,每行的长度根据其索引依次为 的每个幂。22

↑¤θ

使用原始输入字符串填充该保留区域,从而根据需要对其进行分区。

\endgroup

\begingroup

34 32字节

$=>[i:1chunk&=>[2i'i+1ceil log]]

解释

$=>[]        ; a function where input is assigned to &
i:1          ; assign 1 to i
chunk&=>[]   ; split input by...
2i ceil log  ; bit length of i
'i+1         ; increment i

\endgroup

2

  • \begingroup
    我真的要学习 Arturo。它太漂亮了!
    \endgroup


    – 

  • \begingroup
    @noodleperson 我喜欢打高尔夫,因为你可以用令人惊讶的多种顺序做事,以及前缀、中缀和后缀,所有这些在不同情况下都更短。
    \endgroup


    – 

\begingroup

Google 表格,41 字节

=index(let(i,2^(row(A:A)-1),mid(A1,i,i)))

截屏

\endgroup

2

  • 1
    \begingroup
    您可以使用2^(row(1:99)-1)而不是2^sequence(99,1,)和来节省 10 个字节2^(1+sequence(99,1,-1))
    \endgroup


    – 

  • 1
    \begingroup
    @z.. 对。我一开始就愚蠢地使用了两个不同的序列。let()又节省了 6 个。
    \endgroup


    – 


\begingroup

,6

gÝo£õÜ

或者次要替代方案:

ā<o£ʒĀ

解释:

g       #  Push the length of the (implicit) input-list
 Ý      #  Pop and push a list in the range [0,length]
        # OR:
ā       #  Push a list in the range [1, (implicit) input-length]
 <      #  Decrease each by 1 to the range [0,length)
  o     # Map each value to 2 to the power this value
   £    # Split the (implicit) input-string into parts of those sizes
    õÜ  #  Trim all trailing ""
        # OR:
    ʒ   #  Filter these string-parts:
     Ā  #   Check if truthy (where "" is falsey)
        # (after which the result is output implicitly)

\endgroup

\begingroup

,3字节

ẏEẇ

高尔夫球 pilled sbcs maxxer。

解释

ẏEẇ­⁡​‎‎⁡⁠⁡‏‏​⁡⁠⁡‌⁢​‎‎⁡⁠⁢‏‏​⁡⁠⁡‌⁣​‎‎⁡⁠⁣‏‏​⁡⁠⁡‌­
ẏ    # ‎⁡Range [0, len input)
 E   # ‎⁢Each to the power of 2
  ẇ  # ‎⁣Partition the string into groups corresponding to each length
💎

的帮助下创建

\endgroup

\begingroup

,5

J2*œṖ

接受一个列表并产生一个列表列表的单子链接。

如何?

J2*œṖ - Link: List of characters, S
J     - indices -> [1..len(S)]
 2*   - two exponentiate {that}
   œṖ - partition {S} at {those} indices

\endgroup

\begingroup

,16字节

<;.1~1=1#.[:#:#\

<;.1~1=1#.[:#:#\     Input: string of length 2^n-1 (example: 'abcdefg')
              #\     1-based indices (1 2 3 4 5 6 7)
          [:#:       each number to binary (0 0 1; 0 1 0; 0 1 1; 1 0 0; ...; 1 1 1)
       1#.           sum the bits of each number (1 1 2 1 2 2 3)
     1=              is it 1? (1 1 0 1 0 0 0)
<;.1~                cut at 1s and box each word ('a'; 'bc'; 'defg')

\endgroup

\begingroup

Excel,35 字节

=LET(i,2^(ROW(1:99)-1),MID(A1,i,i))

\endgroup

1

  • \begingroup
    替换1:99A:A以节省一个字节?
    \endgroup


    – 


\begingroup

APL+WIN,20字节

提示输入字符串。输出嵌套的段向量。索引原点 = 0

(∊n⍴¨n←2*⍳⌈2⍟⍴s)⊂s←⎕

\endgroup

\begingroup

9 7 5

输入为字符数组,输出为二维字符数组

Wv2pV

\endgroup

1

  • \begingroup
    非常好。TIL-m为 U、V、W 提供了标准的 .map 参数,我想这很有意义。顺便说一句,我正在开发 Japt 的精神继承者 Vascri,理论上它和 Jelly 一样短,同时保持了 Japt/JS 的熟悉度。它几乎准备好发布 0.1 版本了,所以你应该很快就会看到 Vascri 中的一些解决方案出现 🙂
    \endgroup


    – 

\begingroup

55 53 47 字节

f=->s,v=[],a=1{s ?f[s[a..],v<<s[0..a-1],a*2]:v}

@OP 只是想让你知道,简单的任务是受欢迎的!:)

我构建了一个包含三个变量的递归:原始字符串、输出向量和计数器。该函数会切分字符串片段,将其添加到向量并更新计数器,直到字符串为空。

\endgroup

1

  • 1
    \begingroup
    我喜欢递归方式,直观但简短。至于简单挑战,我尝试将它们与中等难度的挑战混合在一起,因为这些挑战往往更有趣。但如果我没有主意了,我总是会准备一些这样的挑战 😛
    \endgroup


    – 

\begingroup

,15字节

{x@.=+|\2\!-#x}

x:"abcdefg"
!-#x          / integers from -length to -1
  -7 -6 -5 -4 -3 -2 -1
2\!-#x        / convert to base 2
  -1 -1 -1 -1 -1 -1 -1
   0  0  0  1  1  1  1
   0  1  1  0  0  1  1
   1  0  1  0  1  0  1
|\2\!-#x      / maximum scan
  -1 -1 -1 -1 -1 -1 -1
   0  0  0  1  1  1  1
   0  1  1  1  1  1  1
   1  1  1  1  1  1  1
.=+|\2\!-#x   / group identical columns
   (,0; 1 2; 3 4 5 6)
x@.=+|\2\!-#x / index back into the input string
   (,"a"; "bc"; "defg")

\endgroup

1

  • \begingroup
    噢,喜欢它!|\2\!-#x很聪明
    \endgroup


    – 

\begingroup

-n 5,28 字节

($.*=2)&say$&while s/.{$.}//

\endgroup

\begingroup

字节

!`(?<=(.)*).(?<-1>.)*

说明:如果没有替换模式,则最后一个阶段默认为匹配阶段。将!输出从匹配数(十进制)更改为匹配本身(在单独的行上)。然后,该模式使用 .NET 平衡组来计算其匹配索引(将比 的幂小一),2并允许匹配比该多一个字符。

\endgroup

\begingroup

Uiua,11字节

⊕□⊚⍜ₙ⇡2+1⧻.

简洁又好用!(group)和(where)是绝佳的组合。

⊕□⊚⍜ₙ⇡2+1⧻.  # input string on the right.   "abcdefghijklmno"
       +1⧻.  # length + 1                   16
   ⍜ₙ⇡2      # 2^( range( log_2( that )))   [1 2 4 8]
⊕□⊚          # group into pieces that size  {"a" "bc" "defg" "hijklmno"}

⍜ₙ⇡2表示范围 ( ) “在” ( ) 对数底数为 2 的范围内。应用一个函数,然后应用第二个函数,然后应用第一个函数的反函数。在这里,我们应用log_2(x),然后应用range,然后应用 的反函数log_2(x)2^x

从字面上理解,⊕□⊚确实如此:

     #                              [1 2 4 8]
⊚    # these repeat the naturals:   [0 1 1 2 2 2 2 3 3 3 3 3 3 3 3]
⊕□   # group by boxing the chars     a b c d e f g h i j k l m n o
     # corresponding with indices   {"a" "bc" "defg" "hijklmno"}

\endgroup

\begingroup

Uiua,9字节

该解决方案是由 Uiua 的创建者 Kai Schmidt 编写的,而不是我编写的,所以我将其制作成社区维基。

⊕□⌊ₙ2+1°⊏

这是一个非常简单的解决方案,而且非常简短:取 0 到输入长度之间的范围,对每个范围加一,取以 2 为底的对数,然后向下取整。此列表包含长度加倍的自然数,因此我们将其作为一个组,将输入的每个部分放入一个框列表中。

\endgroup

\begingroup

,43 字节

%{for($i=1;$_[$i];$i*=2){$_|% S*g($i-1)$i}}

简单直接:在两倍的起始索引处提取两倍长度的子字符串。

相关高尔夫:

  • 循环退出条件$_[$i]仅测试当前索引处是否仍有字符;比$i-lt$_.Length
  • $_|% S*g($i-1)$i获取输入字符串$_,将其通过管道传输到%(ForEach-Object 的别名),调用字符串对象的成员“Substring”(唯一匹配的成员S*g),传递要检索的子字符串的起始索引和长度。短于$_.Substring($i-1,$i)

\endgroup

\begingroup

,5字节

C:1İ2

C       # cut input into chunks with lengths:
 :1     # prepend 1 to
   İ2   # infinite sequence of powers of 2
        # (starting at 2)

\endgroup

\begingroup

,20字节

-1%.,{.,2/)/~}*]`-1%

输出如下,如果您认为这是有效输出:]"a" "bc" "defg" "hijklmno"[

另外两个具有奇怪输出格式的 20 字节解决方案:

.,,{2\?(" "*}%n*]zip
1/.,,{2+.(&!n*}%]zip

\endgroup

\begingroup

12 11

hâΣÆïó‼<≥;]

解释:

步骤 1:计算我们需要输出的零件数量,基本上日志2长度t + 1 )日志2nGH+1\log_2(length+1)手动:

          #  (e.g. input = "abcdefghijklmno")
h         # Push the length of the (implicit) input-string
          #  → 15
 â        # Convert it to a binary list
          #  → [1,1,1,1]
  Σ       # Sum this list of 1-bits
          #  → 4

第 2 步:将输入实际分成 2 个部分的幂:

Æ         # Loop in the range [0,value],
          # using 5 characters as inner code-block:
 ï        #  Push the current 0-based loop-index
  ó       #  Pop and convert it to 2 to the power this index#  Apply the next two operators separately on the current stack:
    <     #   Slice to substring [0,val)#   Slice to substring [val,length)
      ;   # After the loop: discard the trailing no-op part
       ]  # Wrap all correct parts on the stack into a list
          # (after which the entire stack is output implicitly as result)

\endgroup

4

  • 1
    \begingroup
    我很惊讶名称中带有“数学”的语言没有内置对数,而是选择内置“5 个字符的块”,哈哈。(h╥(âΣ只是 log_2 的上限)
    \endgroup


    – 


  • \begingroup
    @noodleperson ikr.. 我以前一直缺少这种语言中除了对数之外的许多与数学相关的内置函数,例如正弦/余弦/正切;舍入;二进制/十六进制之外的基数转换;AND/OR/XOR 等按位运算;等等。
    \endgroup


    – 

  • \begingroup
    哇,它为什么叫 MathGolf?!是不是因为它Σ表示求和?:P
    \endgroup


    – 

  • \begingroup
    @noodleperson 我认为这个想法最终是要添加所有其他内容,但它基本上被放弃了。不过,它确实有 59 个不同的 1 字节数字常量()。xD
    \endgroup


    – 


\begingroup

1.0,54 字节

~s=[s[2^i:2*2^i-1] for i=0:floor(Int,log2(length(s)))]

使用数组推导来生成索引对。相关解决方案map占用相同数量的字节:

1.0,54 字节

~s=map(i->s[2^i:2*2^i-1],0:floor(Int,log2(length(s))))

\endgroup