编码-随机播放-解码


23

挑战

您的任务是将整数编码为ASCII字符的字符串,然后在所述字符串被随机混洗后成功解码。

您将编写两个程序/函数,分别称为EncoderDecoder

编码器

  • 输入:在范围内的整数。ñ[0231-1个]
  • 输出:一个字符串sASCII字符(不一定打印)。

解码器

  • 输入:字符串s的随机排列ss
  • 输出:整数ñ

计分

一种s在所有可能值n上的最大长度。如果编码器不确定地起作用(允许,请参见下文),则A将是s可能出现的最大长度(可能为)。sñ一种s

大号Ë编码器长度(以字节为单位),大号d解码器长度(以字节为单位)。

然后你的分数是一种大号Ë+大号d

提交的分数最低的是胜利。

时限

对于单个测试用例(即n的单个值),编码器解码器的执行时间都存在1分钟的任意时间限制ñ

目的是避免通过枚举具有某些属性的所有序列来发现强行编码的解决方案。如果您的解决方案做的比这更聪明,那么它很可能会符合时间限制,并被认为是有效的。同样,如果它在TIO上ñ一些随机选择值起作用,则将其视为有效。否则,我将在我的机器上对其进行测试,但是请注意,如果您的解决方案是纯蛮力的,则几乎肯定会失败。

规则

  • 编码器解码器必须写在同一语言
  • 对于编码器返回的字符串s的每个可能的排列s '解码器必须输出正确的整数ñss
  • 编码器解码器不会允许共享信息(通过全局变量或文件的方式,比如)以任何方式。
  • 所述的输出编码器不需要确定性的(即,相同的输入ñ如果可以产生不同的输出串的编码器被运行多次),但解码器必须始终猜测正确的整数ñ
  • 编码器解码器可以采取,并返回整数ñ任何方便的方式(例如,如果ñ=14是细的输入是14"14"[1,4])。
  • 所述编码器可输出的串s由任一印刷其上stdout 通过返回一个字符串,一个列表/字符数组或范围内的整数列表/阵列[0127] ; 请注意,解码器将接收输入的置换s被返回的编码器,所以它应该接受字符串s相同的格式s
  • 禁止出现标准漏洞
  • 如果可能,请说明您的代码如何工作以及您要求的分数为什么正确。

假设ñ=14

  • 所述编码器接收14作为输入。它可能输出"qwerty"
  • 解码器接收的置换"qwerty"作为输入,例如"tweyqr"。它必须输出14(以任何方便的格式)。

编码器可能返回[113,119,101,114,116,121],以及,在这种情况下,解码器将已收到(例如)[116,119,101,121,113,114]

请注意,编码器返回的字符串也可能包含不可打印的ASCII字符(但始终在范围内[0x00, ..., 0x7F])。


当然,输出长度不能是无穷大,您不能乱序一个无限的字符串
H.PWiz

@ H.PWiz不,不可能的,但lenght可能是无界的,如果编码器具有不确定性
Delfad0r

“不允许编码器和解码器以任何方式共享信息”这包括辅助功能吗?即一个自定义函数,它计算N阶乘加3(随机示例)
pizzapant184 '18

我们的编码器可以返回空字符串/列表吗?
pizzapant184 '18

2
@Kroppeb是的,到目前为止,规则说您应该对字节计数两次。我对看到包含两个相同程序的提交非常感兴趣。
Delfad0r

Answers:


12

果冻(17字节+ 18字节)×长度6 = 210点

b36µỤỤ +×3µŒ¿b3U +Ṣ
Ṣ:3_J
Ṣ%3Uḅ3œ?Çḅ36

在线尝试! (或带有额外的调试信息)

在解决了针对既定胜利条件的挑战之后,我认为选择一种假设的替代胜利条件会很有趣:给出了输出的最小可能最大长度。

说明

编码方式

编码的第一步是将输入表示为基数36(b36)。36 6 = 2176782336> 2147483647,因此结果中最多会有6个数字,每个数字都在0-35范围内。

接下来,我们将其转换为包含6个不同数字的表示形式。有多种可能的算法,但是这里使用的一种算法是将1加到最小的数字上,将2加到第二小的数字上,将3加到第三小数字上,依此类推。这意味着,如果两个数字相同,则其中一个数字将被任意认为更小,因此它们将变得不同;很明显,该算法不能使两个不同的数字变为相同的数字。为了在Jelly中表示这一点,我们使用(“按值对索引进行排序”)来获得按排序顺序排列的索引列表。再次将其反转,有效地将原始元素的每个元素按排序顺序映射到其位置;和µ…+将原件添加到新列表中。结果是将输入数字表示为1–41范围内的六个不同数字(最小0 + 1,最大35 + 6)。

一个:然后,我们拆分此成另一种形式中排序的在1-41范围内的数字的列表,沿着从1到720的数,表示所述720所可能的排列的数字是在(该。Œ¿提取置换数量和排序分别列出。)

最后,我们将数字从1转换为720,将其转换为基数3(b3),对其进行反转(U),然后使用反向divmod将它们分别包装成一个ASCII字符,从而对6个基数3个数字和6个1–41位数字进行编码(字符mod 3是基数3,数字除以3是1–41。结果的可能范围最小为(1×3)+ 0 = 3,最大为(41×3)+ 2 = 125,符合我们的ASCII范围。打包是通过×3和完成的+,再加上其他内容µ,以确保每个命令都对正确的数据位进行操作。(这里有一个打高尔夫球的技巧,因为我们提取排列之前将乘数乘以3 ;这样就无需在分组字符上花一个字节。)

顺便说一句,反转基数3的原因是因为它的位数可能少于1到41的数字。(它不能有更多;n!> 3 n的最小数字略大于6)。Jelly在将两个不同长度的数字相加时有效地插入尾随零,以使它们匹配。尾随零会影响到数字的解释,但领先的零不肯,所以反向使用,以确保额外的零结束的地方,不会弄乱我们的答案。

解码

解码的第一步是提取两个数字(基数3和1–41数)。我们分别用除法(:3)和模(%3)可以很容易地得到它们的数字,但是如何知道它们的顺序呢?好吧,1-41号的数字是按顺序排列的,并且两个数字在相应位置的数字以相同的字符存储;因此,我们可以算出1–41的数字被按顺序排列(通过查看它们的相对值),并知道以3为底的数字必须按相同的方式被按顺序排列。实际上,由于我们ASCII编码的字符与1–41数字的数字排序方式相同(这些数字都是不同的,并且比基数3的数字更重要),。因此,两次提取均以,后跟%3:3酌情开始。

虽然1到41的数字仍然是按顺序排列的,但是我们有一种非常方便/简洁的方法可以返回到以36为基数的0到35位数。只需从第一个减去1,从第二个减去2,从第三个减去3,依此类推。在Jelly中,我们可以使用_J(“减索引”)来做到这一点。

同时,在解码的另一个分支中,我们将以3为底的数字反转为order(U),然后将其从以3为底的数字转换回置换索引ḅ3

然后,我们可以将两个分支结合在一起œ?Çœ?表示“在给定此置换索引的情况下进行置换”,Ç表示“在上方应用行的结果”,即告诉Jelly在同一输入上分别运行两行的原因。

现在,我们得到的是原始数字的数字,以36为底数(由于_J),并且以原始顺序(由于œ?),所以我们只需执行a ḅ36即可从36底数转换回单个整数。

评论

TIO!上面的链接使用312699167作为要编码的数字。基数36中的这个数字是[5, 6, 6, 8, 7, 35],因此可以显示编码的各个方面:35测试了我们拥有的0–127范围的限制;重复的6s测试原始基数36中相同数字的分辨率;数字几乎(但不完全)被排序的事实意味着排列数字非常小,比基数36的数字少很多,因此需要在将其添加到原始数字之前对其进行反转。

所有常量如何组合在一起真的很方便。36 6刚好高到足以适应2 31,3 6刚好高到足以适应6!和(36 + 6)×3仅只是足够高,以适合128点的可能性,我们有内。(这里的最后一个约束是最不严格的,因为我们可以使用0索引而不是1索引来使用0-2范围内的字符。不过,这只给了足够的空间来使用37作为基数,而不是比36.)


9

果冻((4 3字节+ 6 5字节)×长度8 = 80 64点

ṢŻ

在线尝试!

果冻((2 1字节+ 4 3字节)×长度10 = 60 40点

一种
ṢŻ我

在线尝试!

说明

解决方案1

这与大多数其他答案使用的算法不同。b⁴与其他答案一样,我们先将值编码为十六进制(),然后取一个累加和(Ä)。每个输入显然都会提供不同的输出(因为这两个操作都是可逆的),并且十六进制编码最多包含8个数字,其最大值分别为7(对于最后8位)和15(对于最后7位)最后一位数字),则输出列表中的最大数字将为7+(7×15)= 112,小于问题要求的127。另外,输出将必须按排序顺序,从而使我们能够逆序洗牌。

对于解码器,我们首先使用sort()反转随机播放;然后通过加零(Ż)并取连续对的差()来反转累积和I。然后从十六进制(ḅ⁴)转换回来。

解决方案2

这个问题实际上允许我们将输入作为(大概是十进制)数字的列表,因此我们可以通过简单地删除基本转换来“作弊”。那么输出中使用的最大数量将是2 +(9×9)= 83(实际上是82,因为2999999999超出范围,所以最差的输入是1999999999)。随着用于该问题的编码的进行,所得到的编码非常可怕,但是它具有生成非常简洁的优点,这超过了编码的冗长性。

这个答案感觉很像作弊,这不是我解决该问题的主要方法,但似乎值得添加,因为它在技术上符合规则并能获得更高的分数。

评论

我考虑到一些算法来使长度小于8,但似乎不太可能在≤9字节(非作弊)或≤5字节(作弊)中实现长度为7的算法,因此通过对问题进行评分可能是最好的方法。(尽管如此,我还是可以尝试解决“最小化编码的长度”挑战的替代方法,只是为了好玩。)

与某些解决方案不同,此处以16为基数不是关键。对于长度为8的解决方案,还有很多其他数字(例如18)。我为第一个解决方案选择了16个,仅是因为Jelly有一个1字节的方式来表示,而其他可行的基础将需要用完程序中的多个字节。当然,第二个解决方案需要使用10作为基础,以利用漏洞。

感谢@Dennis指出了一些更新的Jelly命令,这些命令使该算法甚至更难以编写。


3
Ä简称+\Ż简称0;
丹尼斯

7

莎士比亚编程语言,10 *(264 + 494)= 8650 7910 7580

编码器:264字节

,.Ajax,.Ford,.Act I:.Scene I:.[Exeunt][Enter Ajax and Ford]Ajax:Open mind.Be you nicer zero?You be the sum ofyou the product ofthe sum ofI a big big pig the sum ofa big big big big cat a big big pig.If soSpeak thy.Ford:You are the sum ofyou a cat.If soLet usAct I.

在线尝试!

解码器:494

,.Ajax,.Ford,.Page,.Act I:.Scene I:.[Exeunt][Enter Ajax and Ford]Ajax:Open mind.Is you nicer a pig?If soRemember you.If soLet usAct I.Scene V:.Ford:Remember I.Ajax:Recall.Is you worse the sum ofPage twice the sum ofa big big cat a cat?If soYou be the difference betweenyou Page.If soOpen heart.If notlet usScene V.Scene X:.Ford:Recall.Ajax:Be I nicer zero?If soRemember I.If soLet usScene X.[Exit Ajax][Enter Page]Ford:You be the sum ofyou twice twice the sum ofa big big cat a pig.Let usAct I.

在线尝试!

这是一回事。

编码器将每个数字编码为数字加上数字的索引乘以十二。解码器将所有输入存储在福特的内存中,然后在计数器上循环,输出然后删除低于计数器* 12 + 10的每个数字。

说明:

编码器

,.Ajax,.Ford,.Act I:.Scene I:.      Boilerplate introducing the two characters
[Exeunt][Enter Ajax and Ford]       Enter the two characters Ajax and Ford
                                    Ford will be handling the input
                                    Ajax will be the counter
Ajax:Open mind.                     Set Ford to the next character of input
Be you nicer zero?                  Check if it is EOF
You be the sum of                   Set Ford to the sum of 
    you                             His original value (48 to 58)
    the product of                 
          the sum of               
              I                     Ajax's value
              a big big pig         Minus 4 (this handles the offset of 48)
          the sum of                Multiplied by
              a big big big big cat 2^4
              a big big pig.        + -2^2 = 12
                                    This essentially sets Ford to (F+12*(A-4))
If soSpeak thy.                      If not EOF, print Ford's value
Ford:You are the sum ofyou a cat.   Increment Ajax's value
If soLet usAct I.                   If not EOF, Repeat again.

解码器

,.Ajax,.Ford,.Page,.Act I:.Scene I:.  Boilerplate introducing three characters
                                      Ajax is the spare stack
                                      Ford is the storage stack
                                      Puck is the counter, increasing by 12
[Exeunt][Enter Ajax and Ford]            Enter Ajax and Ford onto the stage
Ajax:Open mind.                          Get the next character of input
Is you nicer a pig?                      If not EOF
If soRemember you.                         Store the value in Ford's memory
If soLet usAct I.                          And repeat the loop
Scene V:.                                Otherwise move to the next scene
Ford:Remember I.                         Store Ford's value (initially -1 from EOF) in Ajax's memory
Ajax:Recall.                             Get the next value from Ford's memory
Is you worse the sum of                  Is the value smaller than
        Puck                                  Puck's value
        twice the sum ofa big big cat a cat?  + 10 ?
                                              i.e. is it the next digit?
If soYou be the difference betweenyou Puck.   If so, subtract Puck's value from Ford
If soOpen heart.                              And print Ford's value
If notlet usScene V.                     If that was not the digit, repeat
Scene X:.
Ford:Recall.                             Get the next value from Ajax's memory
Ajax:Be I nicer zero?                    Until the -1
If soRemember I.                         Returning the values to Ford's memory
If soLet us Scene X.                     Repeat until Ajax's memory is exhausted
[Exit Ajax][Enter Page]                  Swap Ajax and Page
Ford:You be the sum of                   Set Puck's value to
              you                        Puck +   
              twice twice the sum of     2*2*(
                           a big big cat      4
                           a pig.             -1) = 12
Let usAct I.                             And start from the beginning again, having removed one number

5

Python 2.7、31 *(52 + 37)= 2759

编码器(69 52字节):

lambda n:[chr(i)if n&(1<<i)else""for i in range(32)]

解码器(41 37字节):

lambda s:sum([1<<(ord(c))for c in s])

将输入数字中的所有非零位存储为ascii值。ascii字符的值存储设置位的位置。例如,值“ a”表示第97位被设置。

有了@ Delfad0r,有了一些改进

在线尝试!


欢迎来到PPGC!您可以在开始时删除e = 和,d = 匿名函数非常好。另外,请注意,问题说明清楚地表明,编码器可能会返回整数列表,而不是字符列表,因此可以避免整数-> character-> integer转换。此外,您可以使用n&(1<<i)代替n&(1<<i)>0并保存2个字节。最后,i(127)的上限太大了,32就足够了,并节省了1个字节。
Delfad0r

1
请根据问题说明中的“ 评分”部分说明您的分数。
Delfad0r

@ Delfad0r分数现在正确了吗?并感谢您的提示。
Hein Wessels

我认为分数是(52+37)*31=2759因为最长的是设置所有31位时。
乔纳森·艾伦

编码器可以lambda n:[chr(i)*(n&1<<i>0)for i in range(32)]节省6个字节。
mypetlion 18/09/24

5

Stax,得分8×(10 + 9)= 152

编码器,10 个字节

Ç·MÉJ'♀τ│½

运行并调试

16|E{i16*+m Full program, implicit input
16|E        Get hexadecimal digits
    {     m Map:
     i16*+    Add 16 * loop index
            Implicit output as string

编码器以升序输出字符串。

解码器,9 个字节

üL∟n╫k∞‼9

运行并调试

o{16%m16|E Full program, implicit input
o          Sort string
 {16%m     Module each element by 16
      16|E Interpret as array of hex digits


5

Python 3,8 *(45 + 38)= 664

编码器(45字节):

lambda n:[16*i+(n>>4*i)%16 for i in range(8)]

解码器(38个字节):

lambda l:sum(x%16<<x//16*4 for x in l)

在线尝试!


1
您可以删除“ for”之前的空格,lambda l:sum(x%16<<x//16*4for x in l)效果很好:)
FatalError

4
这是行不通的。输出不是纯ASCII(在0..127范围内)
GB

2
@GB我的错。我在上次编辑时破坏了它。现在还原
Curtis Bechtel

在编码器中保存3个字节:lambda n:[n>>4*i&15|i<<4for i in range(8)]在解码器中保存1个字节:lambda l:sum(x%16<<x//16*4for x in l)总分632
Aaron

4

JavaScript(ES6),8 *(40 + 32)= 576

08

编码器(40字节)

E=(n,k=0)=>n?[k|n&15,...E(n>>4,k+16)]:[]

解码器(32字节)

s=>s.map(c=>s|=c%16<<(c/4&~3))|s

演示版

在线尝试!

怎么样?

输入分为8个4位的块,每个块用16个可能的字符中的1个进行编码。永远不会设置最后一块的最高有效位。

       3222222222211111111110000000000
bit:   0987654321098765432109876543210
       \_/\__/\__/\__/\__/\__/\__/\__/
block:  7  6   5   4   3   2   1   0

block #0 is encoded with char. 00 to 0F (NUL to SI)
block #1 is encoded with char. 10 to 1F (DLE to ES)
block #2 is encoded with char. 20 to 2F (' ' to '/')
block #3 is encoded with char. 30 to 3F ('0' to '?')
block #4 is encoded with char. 40 to 4F ('@' to 'O')
block #5 is encoded with char. 50 to 5F ('P' to '_')
block #6 is encoded with char. 60 to 6F ('`' to 'o')
block #7 is encoded with char. 70 to 77 ('p' to 'w')

4

果冻(8 + 9)个字节 * 8个最大长度= 136

b⁴+J’Ɗ⁴¡

编码器(为清晰起见,页脚使用Python格式化列表)

Ṣ_J‘Ɗ⁴¡ḅ⁴

解码器

从理论上讲,最大长度可以为6,可以用22个字节或更少的字节来完成吗?

一世=0一世=5127+一世127=321402081<231-1个

怎么样?

231-1个7fffffff[7,15,15,15,15,15,15,15][7,15,15,15,15,15,15,15] + [0,16,32,48,64,80,96,112] = [7,31,47,63,79,95,111,127]

编码器

b⁴+J’Ɗ⁴¡ - Link: integer, n    e.g. 1234
 ⁴       - literal 16               16          
b        - convert to base          [4,13,2]
       ¡ - repeat...
      ⁴  - ...16 times:
     Ɗ   -   last 3 links as a monad:
   J     -     range of length        [1,2,3]     iter 2    iter 3    ...  iter 16
  +      -     add                    [5,15,5]   [5,16,7]   [5,17,9]  ...  [5,30,35]
    ’    -     decrement              [4,14,4]   [4,15,6]   [4,16,8]  ...  [4,29,34]
         -                                                                 [4,29,34]

解码器

Ṣ_J‘Ɗ⁴¡ḅ⁴ - Link: list of integers   e.g. [29,34,4]
Ṣ         - sort                          [4,29,34]
      ¡   - repeat...
     ⁴    - ...16 times:
    Ɗ     -   last 3 links as a monad:
  J       -     range of length           [1,2,3]
 _        -     subtract                  [3,27,31]   [3,26,29]   [3,25,27]  ...  [3,12,1]
   ‘      -     increment                 [4,28,32]   [4,27,30]   [4,26,28]  ...  [4,13,2] 
        ⁴ - literal 16                    16
       ḅ  - from base                     1234

当然是“十六进制数字”。(“使用普通十六进制的数字会更长,而单独使用”数字”就意味着十进制。)
Erik the Outgolfer

我更改了它,尽管它从上下文中应该是显而易见的,然后我立即提到了十六进制数字。
乔纳森·艾伦,

你的计算是关闭的一种:有321402081个组合与置换为5的最大长度,和与7177979809 6的最大长度
安德斯Kaseorg

@AndersKaseorg糟糕,因此-最大长度为6 ...可以使用22个字节!
乔纳森·艾伦,

4

莎士比亚编程语言,31 *(472 + 383 379 344)= 26505 26381 25296

以前的分数:16909322 *(246 + 217)= 7829016086

这仍然很高,但这是我现在能想到的最低水平。

编码器:

,.Ajax,.Ford,.Act I:.Scene I:.[Enter Ajax and Ford]Ajax:Remember a pig.Ford:Listen tothy.Scene V:.Ajax:Remember the remainder of the quotient betweenI a big cat.Ford:You be the quotient betweenyou a big cat.Be you nicer zero?If solet usScene V.Remember a pig.Scene X:.Ajax:Recall.Ford:Am I worse zero?If notremember I.If notlet usScene X.Ajax:You zero.Scene L:.Ford:Recall.Ajax:You be the sum ofyou a cat.Am I nicer zero?If sospeak thy.Am I worse zero?If notlet usScene L.

在线尝试!

解码器:

,.Ajax,.Ford,.Page,.Act I:.Scene I:.[Exeunt][Enter Ajax and Ford]Ajax:You cat.Ford:Open mind.Remember the sum ofyou I.Scene V:.Ajax:Am I nicer a cat?If soyou be twice you.Ford:If soyou be the sum ofyou a pig.If solet usScene V.[Exit Ford][Enter Page]Page:Recall.Ajax:Am I worse a cat?If notyou be the sum ofyou Ford.If notlet usAct I.Open heart

在线尝试!

基本上,如果字符串包含具有ASCII码(n + 1)的字符,则设置第n个二进制数字。


344字节的解码器
乔金

3

Python 3,(208字节+ 200字节)* 6长度= 2448

在线尝试!(包含两者,多余的字节是它们之间的换行符)。

通过使用空列表-4字节(-24分数)(允许更多内容从0开始)

编码器(208字节)

def E(n,h=128):
    T=lambda n,d:n*T(n+1,d-1)//d if d>1else d and n or 1
    d=l=0
    s=[]
    while n>=T(h,d):
        n-=T(h,d)
        d+=1
    for i in range(d):
        while n>=T(h-l,d+~i):
            n-=T(h-l,d+~i)
            l+=1
        s+=[l]
    return s

解码器(200字节)

def D(s):
    T=lambda n,d:n*T(n+1,d-1)//d if d>1else d and n or 1
    s.sort()
    l=0
    d=len(s)
    n=sum(T(128,D)for D in range(d))
    for i in s:
        for j in range(l,i):
            n+=T(128-j,d-1)
        l=i
        d-=1
    return n

观察结果:

  • 对于严格不增加(即已排序)的列表,可以无损地逆转混洗。

  • 相同长度的严格不递增的数字列表可以完全排序(就像在Python中一样)。

  • 我们可以定义列表首先按长度排序,以形成所有排序列表的总顺序。

  • 如果我们定义列表中唯一的有效值是整数from 0127inclusive(即,存在有限数量的length的有效列表L),则可以形成这些列表的可索引序列。

战略:

  • 编码器:给定一个数字N,找到N第一个有效的严格非递增列表。

  • 解码器:给定一个(经过改组的)有效列表,对其进行排序,并按有效列表的顺序返回其索引。

通用代码说明:

  • T=lambda n,d:n*T(n+1,d-1)//d if d>1else d and n or 1

  • 计算nd单纯形数

    • 对于d=0,始终1

    • 对于d=1n(长度为点的一行中的点数n

    • d=2一世=1个ñ一世n

    • d=3Ĵ=1个ñ一世=1个Ĵ一世n

编码器说明:

  • def E(n,h=128): d=l=0s=[]

  • n是输入数字,h是“高值”(即允许的最大数字+1),d是输出将要的长度,s是输出,l是“低值”(从0开始,将在后面详细说明)

  • while n>=T(h,d):n-=T(h,d)d+=1

  • 存在T(h,d)有效的长度d列表,并且如果n是相对于列表[0]*d的索引(在index处0)而不是实际索引,则我们的计算会更容易,因此相应地递减nd对于给定的,这也会调整(长度)以使其正确n

  • for i in range(d):

  • 有效地:“对于i+1列表中的th号”

    • 这就是我要解释l的“低价值”

    • 将数字放入列表后,添加的数字不得少于列表中的数字(以使其保持排序),l最后一个添加到列表中的数字也是如此。

    • while n>=T(h-l,d+~i):n-=T(h-l,d+~i)i+=1

    • 如果n太大而无法l在此“数字”处使用进行编码,则进行相应调整n并递增l

    • s+=[l]

    • 编码nl在这个“数字”。

    • 首先,我们可以h选择接下来要输入的“数字”,但是一旦输入了“数字”(分配给l),就只能h-l使用下一个“数字”的选项。

    • 最初有T(h,d)有效列表,但是我们添加了一个“数字” l,减少了剩余的“数字” d-1数量,并将有效的下一个“数字” h-l的数量减少至,因此此后的有效列表数量为T(h-l,d-1)

解码器说明:

  • def D(s):s.sort()l=0d=len(s)

  • s是(改组后的)输入列表,因此s.sort()l是“低值”(h“高值”只是128代码中要保存字节的文字s),n是输出数字,d是长度。

  • n=sum(T(128,D)for D in range(d))

  • 调整n到顺序中的点[0]*length

  • for i in s:

  • 对于每个数字:

    • for j in range(l,i):n+=T(128-j,d-1)

    • 调整n到顺序中的点[...prevdigits, thisdigit, 0...]

      • l=i:将“低值”设置为最新数字

      • d-=1:因为我们使用了数字,所以减少了长度

  • return nn对所有数字进行调整后,它是正确的数字;把它返还。

抱歉,如果不清楚,但是这是我原来的非高尔夫调试版本,请在线尝试!,它不使用空列表,因此与该版本中使用的所有数字都相差1


3

红宝石(36 + 29字节)* 8,得分520

编码:

->n{(0..7).map{|x|(n>>x*=4)%16+x*4}}

在线尝试!

解码:

->a{a.sum{|x|x%16<<(x/4&28)}}

在线尝试!

怎么运行的:

该数字使用4位块和3位索引进行编码。

解码器获取输入数组,并将每个半字节再次放入其位置。


3

木炭,得分10 *(10 + 15)= 250。

使用十进制;基于16先前基本溶液得分328 296 264。

可能输出不可打印的字符。特别是,字符10很难输入到木炭中。

编码器,10个字节:

⭆⮌S℅⁺Iι×χκ

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

解码器,15个字节:

IΣES×﹪℅ιχXχ÷℅ιχ

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

使用整数列表的版本得分为360 296(基数为16;十进制为310):

编码器,19个字节:

NθIE⁸⁺﹪÷θX¹⁶ι¹⁶×¹⁶ι

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

解码器,18个字节:

IΣEE⁸N×﹪ι¹⁶X¹⁶÷ι¹⁶

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

使用版本可打印字符得分360(状态416 384 368在基部16):

编码器,19个字节:

⭆⮌S℅⁺Iι×χ⁺κ×⁵⊕׳÷κ⁵

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

解码器,17个字节:

Fθ⊞υ⌈Φθ¬№υκ⭆υ﹪℅ιχ

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


2

Brachylog,17 + 18字节* 8长度= 280

编码器:

ḃ₁₆I∧7⟧₁;Iz₁~ḃ₁₆ᵐ

解码器:

ḃ₁₆I∧7⟧₁;Iz₁~ḃ₁₆ᵐp

可以将p添加到编码器的末尾,而不会生效。通过将(混洗后的)结果作为输出并在输入中获取原始编号来运行解码器。

如果将有一个(正确实施的)累积总和谓词,则得分可能会下降到20

在线尝试!


@ Delfad0r将p添加到编码器将使其成为用于编码和解码的相同代码
Kroppeb

2

05AB1E,得分:(2 + 2 个字节)* 11最大长度= 44

编码器(2 个字节):

在线尝试。

解码器(2 个字节):

在线尝试。

编码器的输入和解码器的输出是数字列表。

@ ais523的第二个果冻港口。

说明:

    # Undelta (automatically prepends a 0)
      #  i.e. [3,0,4,7,8,2,0,1,9] → [0,3,3,7,14,22,24,24,25,34]

{     # Sort
      #  i.e. [14,7,22,25,24,3,0,24,34,3] → [0,3,3,7,14,22,24,24,25,34]
 ¥    # Deltas
      #  i.e. [0,3,3,7,14,22,24,24,25,34] → [3,0,4,7,8,2,0,1,9]

231-1个


2

高尔> <>,8 *(14 + 13)= 216

编码器在线尝试!,14个字节:

I8FfPSD8*L+o|;

解码器在线尝试!,13个字节:

iEh8SD4*2$X*+

由于它可以输出无法打印的ascii字符,从而使解码器混乱,因此现在有一个在输出/输入中使用数字的版本:

编码器在线尝试!,14个字节:

I8FfPSD8*L+N|;

解码器在线尝试!,13个字节:

IEh8SD4*2$X*+

编码方式:

编码通过将给定的数字分成8 x 4位的块来工作。然后,将这些块右移3位,并将块的原始位置附加为末尾的0到7之间的数字。因此,编码如下所示:

0AAAABBB
 |__|    -> the original part of the number
     |_| -> the position of the chunk inside the original number 0 = LSB and 7 = MSB

2

Perl 6的,10 *(10 + 12)= 340 220

编码器:

{^@_ Z~@_}

解码器:

{.sort X%10}

在线尝试!

编码器功能使用数字的0索引压缩每个数字。然后,编码器对数字列表进行排序,并以10为模,即数字的第二位。

总数为10,因为这是2 31 -1 的最大长度。


1

Haskell,10 *(23 + 51)= 740

这是一个对值进行编码,改组,解码和验证的程序:在线尝试!

编码器,23个字节

zipWith((+).(10*))[0..]

在线尝试!

解码器,51字节

map snd.sortOn fst.map(`divMod`10)
import Data.List

在线尝试!

说明

由于允许使用input作为十进制数字,因此我们将使用它。.编码器将出现的每个数字映射为10*index + digit,请注意,所有digits都将存在,[0..9]因此我们可以使用来反转上述内容divMod。恢复索引和数字后,只需按索引排序并删除它们即可。

231-1个=214748364799=81<128



1

大号Ë+大号d=36;一种=8288

d←{16n-16×⍳≢n←⍵[⍋⍵]}
e←(⊢+16×⍳∘≢)16⊥⍣¯1

在线尝试!(包含5个额外的字节用于分配和换行符)。

用途 ⎕IO←0

怎么样:

(⊢+16×⍳∘≢)16⊥⍣¯1  Encoder; input 1234
          16⊥⍣¯1  Convert input to base 16  4 13 2
      ⍳∘≢           [0..length of the list-1]  0 1 2
   16×              times 16  0 16 32
 ⊢+                 plus the original list  4 29 34

{16n-16×⍳≢n←⍵[⍋⍵]}  Decoder; input   34 4 29
              [⍋⍵]   Grade  up  2 0 1
                    Index  with that list  4 29 34
           n        assign that to n
      16×⍳≢          16×[0..length(n)-1]  0 16 32
    n-               subtract that from n  4 13 2
 16                 Decode from base 16  1234

1

PHP,8 *(44 + 53)= 776

编码器,44个字节:

for(;$n=&$argn;$n>>=4)echo$n&15|16*$i++," ";

打印以空格分隔的整数列表。与一起作为管道运行-nR

最多8个字节,带有4个数据位(低半字节)和3个权重位(高半字节)。

简而言之:
将每个十六进制数字放在一个自己的字符中,并使用字节的上半部分存储数字的位置。

例:

14578938910x56e5b203)将变成
0x030x100x220x3b0x450x5e0x660x75
3 16 34 59 69 94 102 117

解码器,53个字节:

while($i++<8)$n+=(15&$x=$argv[$i])<<($x>>4)*4;echo$n;

要么

while($i++<8)$n+=(15&$x=$argv[$i])<<($x/4&~3);echo$n;

要么

for(;$i<9;$x=$argv[++$i])$n+=$x%16<<($x/4&~3);echo$n;

从命令行参数中获取整数。用运行-nr


在线试用它们


0

Python 2,10 *(68 + 54)= 1220

e=lambda n:"".join(chr(int(`i`+j))for i,j in enumerate(`n`)if j<'L')
d=lambda s:int("".join(`ord(c)%10`for c in sorted(s)))

在线尝试!

编辑:感谢Jo King的指示-回顾一下,我不确定为什么我要抵消32。

从NUL字节0x0的[space](位置0,值0)开始,将每个位置的位置和值编码为单个字符。

解码依据:

  • 对字符串进行排序(Python将按其序号对字符进行排序)
  • 将每个字符转换为其顺序值
  • 取每个有序整数的最后一位
  • 将整数连接成字符串
  • 将连接的字符串转换回int

您需要32补偿吗?此外,[-1]也可能%10在正确的位置
Jo King

0

C(gcc),10 * 112 = 1120

c,i;e(i,s)char*s;{for(c=1;i;c+=10,i/=10)*s++=c+i%10;*s=0;}
d(char*s){for(i=0;c=*s++;i+=--c%10*pow(10,c/10));s=i;}

在线尝试!

我有全局变量,但是它们实际上并没有在两个函数之间传递任何信息。c在两个函数中都使用了变量声明,从而节省了2个字节的代码长度。

这里仅使用可打印ASCII的3 5字节惩罚版本:

c,i;e(i,s)char*s;{for(c=32;i;c+=10,i/=10)*s++=c+i%10;*s=0;}
d(char*s){for(i=0;c=*s++;i+=(c-=32)%10*pow(10,c/10));s=i;}

感谢@ceilingcat改进了70点。

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.