原始号码


36

指导方针

情境

约翰有一个重要的数字,他不希望其他人看到它。

他决定使用以下步骤对数字进行加密:

他的号码始终是一个不递减的序列(即"1123"

他将每个数字都转换成英语单词。(即"123" -> "ONETWOTHREE"

然后,随机重新排列字母。(即"ONETWOTHREE" -> "ENOWTOHEETR"

约翰觉得这样做很安全。实际上,这样的加密很容易解密:(


任务

给定加密的字符串s,您的任务是解密它并返回原始数字。


规则

  • 这是代码高尔夫,所以最短答案以字节为单位
  • 您可以假设输入字符串始终有效
  • 输入字符串仅包含大写字母
  • 原始编号始终按升序排列
  • 您可以以字符串或整数格式返回数字
  • 字母将仅在一个单词之间而不是在整个字符串之间随机播放。
  • 这些数字只能是1到9(含)之间的数字(ONENINE

可能的未加密字符串

在将字符串从数字转换为字符串之后,下面是这些字符串的列表:

 1 -> ONE 
 2 -> TWO
 3 -> THREE
 4 -> FOUR
 5 -> FIVE
 6 -> SIX
 7 -> SEVEN
 8 -> EIGHT
 9 -> NINE

例子

"NEO" -> 1

"ENOWOT" -> 12

"EONOTWHTERE" -> 123

"SNVEEGHEITNEIN" -> 789

"ENOOWTEERHTRUOFEVIFXISNEVESTHGIEENIN" -> 123456789

"NOEWOTTOWHEERT" -> 1223


5
在所有测试用例中,仅单词内的字母被改组,单词间的字母不被改组。会一直这样吗?
xnor

1
@xnor总是这样。我已经编辑了问题。
阿莫里斯

1
那么您需要更改此“ ....(即“ ONETWOTHREE”->“ TTONWOHREEE”)“
J42161217

2
@ TessellatingHeckler:一个非严格增加的序列是下一个数字可以与先前的ex相同。1-1-1-2-2-3(非严格增加),而不是1-2-3-4-5(严格增加)
koita_pisw_sou

1
从技术上讲,这是一种编码,而不是加密,因为没有密钥。
帕特里克·罗伯茨

Answers:


5

果冻 38  37 字节

ḟ“RGS”O“OX‘,“¢©“¢¢¤‘yF×4/%74ị⁽Gל?9¤Ḍ

单字链接,其中包含字符列表(字符串)并返回整数。

在线尝试!

采用了非常不同的方法来Pietu1998的果冻的答案但有相同的字节数我真的认为它可能 它并最终成为少)!

不依赖于原始数字的单调性(HTREEWTONOE例如,输入会起作用)。

怎么样?

首先请注意,单词本身(以及因此的任何字谜)都可以通过删除Rs,Gs和Ss并用两个字符(例如“ 12”)替换任何Os和用三个字符(例如,X)替换所有长度为4的单词。说“ 345”)。

letters  -> -RGS  -> O:12, X:345
ONE         ONE      12NE
TWO         TWO      TW12
THREE       THEE     THEE
FOUR        FOU      F12U
FIVE        FIVE     FIVE
SIX         IX       I345
SEVEN       EVEN     EVEN
EIGHT       EIHT     EIHT
NINE        NINE     NINE

然后,根据我们的选择(“ 12345”),我们可以使用取模算法将那些字符的序数的乘积映射到数字1到9,然后在重新排列的数字列表中查找这些数字。该代码实际上首先转换为字符,然后替换常规字符,但是也可以在37个字节的字符中输入字符,例如“ DIAAE”(尝试一下)。

ḟ“RGS”O“OX‘,“¢©“¢¢¤‘yF×4/%74ị⁽Gל?9¤Ḍ - link: list of characters
 “RGS”                                - literal ['R','G','S']
ḟ                                     - filter discard
      O                               - convert to ordinals
       “OX‘                           - code-page indices list = [79,88]
            “¢©“¢¢¤‘                  - code-page indices lists = [[1,6],[1,1,3]]
           ,                          - pair -> [[79,88],[[1,6],[1,1,3]]]
                    y                 - translate (replace 79s (Os) with [1,6]
                                                       and 88s (Xs) with [1,1,3])
                     F                - flatten into a single list
                       4/             - 4-wise reduce by:
                      ×               -   multiplication (product of each window of four)
                         %74          - modulo 74
                                   ¤  - nilad followed by link(s) as a nilad:
                             ⁽G×      -   base 250 literal = 18768
                                œ?9   -   permutation of [1,2,3,4,5,6,7,8,9] at that
                                      -   index in a lexicographically sorted list of
                                      -   all such permutations -> [1,5,8,2,4,9,7,6,3]
                            ị         - index into
                                    Ḍ - convert from decimal digits to an integer

从字面上看,您的答案是该页面上唯一返回正确值的答案:NINEONENIENOENNNIENOENNEINEONEINEONNENIENOINNEINENINNEINENIENNIENNNNIENNEININENIENNENINEINENINENNIEINNEINNENNIENIN
魔术章鱼缸

+无限点
魔术八达通缸

谢谢!(之所以让我投掷,是因为注释中的代码块的宽度为零,但它确实起作用了
Jonathan Allan

无论如何,这不是有效的输入;)。
魔术八爪鱼缸

哦,我不知道会发生赏金-谢谢!是的,这不是要求的规格的一部分,我只是提出了一种适用于无序输入的方法。
乔纳森·艾伦

10

Python 2中,121个 117 115字节

def g(s,a=0,f=''):
 for c in s:
    a+=34**ord(c)%43;r='P!\x83u\x8eI\x92|Z'.find(chr(a))+1
    if r:f,a=f+`r`,0
 return f

-4个字节:在打完所有高尔夫球之后,我忘了插入一个一次性变量。脑放屁。
-2字节:双倍缩进→单制表符缩进(感谢Coty Johnathan Saxman);请注意,这在答案中无法正确显示。

Ungolfed(与python 3兼容):

nums = [80, 33, 131, 117, 142, 73, 146, 124, 90]

def decode(str):
    acc = 0
    final = ''
    for c in str:
        acc += (34**ord(c))%43
        if acc in nums:
            final += str(1+nums.index(acc))
            acc=0
    return final

魔术数字查找器:

#!/usr/bin/env python3
from itertools import count, permutations

def cumul(x):
    s = 0
    for v in x:
        s += v
        yield s

all_words = 'ONE TWO THREE FOUR FIVE SIX SEVEN EIGHT NINE'.split()

for modulo in range(1, 1000):
    for power in range(1, 300):
        combinations = []
        for word in all_words:
            my_combination = []
            for perm in permutations(word):
                my_combination += cumul(power**(ord(x)) % modulo for x in perm)
            combinations.append(my_combination)

        past_combinations = set(())
        past_intermediates = set(())
        collision = False
        for combination in combinations:
            final = combination[-1]
            if final in past_intermediates or any(intermediate in past_combinations for intermediate in combination):
                collision = True
                break
            past_combinations.add(final)
            past_intermediates.update(combination)

        if not collision:
            print("Good params:", power, modulo)
            print("Results:", ", ".join(str(x[-1]) for x in combinations))

说明:

我有一种感觉,我可以将ASCII位粉碎在一起,然后以某种方式将它们加总以确定我何时有完整的单词。最初,我试图弄乱3**ord(letter)并与预期结果进行比较,但是结果却很多。虽然可以将一些参数强行蛮力化是适当的,即模数(以确保数量较小)和乘数以在模数范围内以不同的方式分散数量。

我最终将乘数变量更改为一个会影响功效本身的变量,因为(通过反复试验)以某种方式设法使我得到了一个简短的高尔夫球答案。

在上方,您会看到这种蛮力和一点点打高尔夫球的结果。

之所以选择3**x原始名称,是因为我知道您可以代表那里的每个数字。任何数字最多重复的数字是2(thrEE,sEvEn,NiNe等),因此我决定将每个输入都视为以3为底的数字。这样,我可以(在心理上)将它们表示为类似的东西10100000000010020000(三个;t插槽中为1,r插槽中为1,插槽中为1,h插槽中为2 e)。通过这种方式,每个数字都有一个唯一的表示形式,可以通过迭代字符串并求和一些数字来轻松地将它们拼凑在一起,并且最终得到的结果与字母的实际顺序无关。当然,这并不是理想的解决方案,但是当前的解决方案仍然牢记这一想法。


什么是Py3K?...
CalculatorFeline

抱歉,已编辑(这是python 3的前称)
Score_Under 17'7

1
它很便宜,但是您可以通过为单个选项卡减去第二个缩进级别(两个空格)来节省2个字节(因为这是python 2)。[ tio.run/##NU7NCoJAGDy7T/…在线尝试!]
Coty Johnathan Saxman

此外,您可能能够节省使用文字6个字节\x83\x8e以及\x92在该字符串。
CalculatorFeline

@CalculatorFeline不幸的是,我的解释器不喜欢这样:SyntaxError: Non-ASCII character '\xc2' in file <stdin> on line 3, but no encoding declared; see http://python.org/dev/peps/pep-0263/ for details。如果我在coding此处添加注释,它会起作用,但这会额外增加15个字节。
Score_

6

Python 2中131个 127字节

s=input()
for y in'WXGURFSOIZ':vars()[y]=s.count(y)
while Z<9:s+=[O-U-W,W,R-U,U,F-U,X,S-X,G,I-X-G-F+U][Z]*str(Z+1);Z+=1
print s

在线尝试!

基于JavaScript Draco18s解决方案的正确版本。


多么有趣的用途vars
xnor

@xnor ovs是如何从中学到其他高尔夫知识的::)))
mdahmoune

非常聪明。为自己的答案加上+1(就像原来一样有缺陷)。
Draco18s

5

PHP,164字节

for($c=count_chars($argn);$i<9;)echo str_pad("",[$c[79]-$c[87]-$u=$c[85],$c[87],$c[72]-$g=$c[71],$u,$f=$c[70]-$u,$x=$c[88],$c[86]-$f,$g,$c[73]-$x-$f-$g][+$i],++$i);

在线尝试!

PHP,179字节

根据以前的方法,先检查偶数,然后按升序检查奇数

for($z=[$o=($c=count_chars($argn))[87],$f=$c[85],$x=$c[88],$g=$c[71],$c[79]-$o-$f,$c[72]-$g,$v=$c[70]-$f,$c[86]-$v,$c[73]-$x-$v-$g];$i<9;)echo str_repeat(++$i,$z[_405162738[$i]]);

在线尝试!

PHP,201字节

for(;$o=ord(WUXGOHFVN[$i]);$i++)for(;$r[$o]<count_chars($argn)[$o];$t[]=$i>3?2*$i-7:2+2*$i,sort($t))for(++$r[$o],$n=0;$q=ord(([TO,ORF,IS,HEIT,EN,TREE,IVE,SEEN,NIE][+$i])[$n++]);)$r[$q]++;echo join($t);

在线尝试!


失败ENOOWTWTOWOT
Titus

@Titus现在固定。我有误解的问题
约尔格Hülsermann

是的,这些例子有些令人误解。哇,那确实花了!你能把它分解吗?
泰特斯(Titus)

@Titus我想我已经达到了极限,以找到另一种方式为你的方法
约尔格Hülsermann

1
$i++<9并且$i代替$i<10and ++$i(-1字节); _405162738[$i]而不是$i%2?$i/2+4:$i/2-1(-4字节)($i/2+~($i%2*-5)也可以,但是再长一个字节。)
Titus

5

使用Javascript(ES6),288个 150 144字节

q=s=>[u=(l=t=>s.split(t).length-1)`U`,l`O`-l`W`-u,l`W`,l`R`-w,u,f=l`F`-u,x=l`X`,l`S`-x,g=l`G`,l`I`-x-g-f].map((n,i)=>`${i}`.repeat(i&&n)).join``

const testCases = ['NEO', 'ENOWOT', 'EONOTWHTERE', 'SNVEEGHEITNEIN', 'ENOOWTEERHTRUOFEVIFXISNEVESTHGIEENIN']

testCases.forEach(testCase => console.log(testCase, q(testCase)))

比其他JS条目中的另两个更长,但我认为我会放弃一种可能对另一种语言的人有用的有趣方法。

从本质上讲,我们可以确定以下内容:

W -> 2
X -> 6
G -> 8
U -> 4

这些字母的任何出现都意味着该数字存在于原始数字中。从这里我们可以推断出其余的数字:

R-U -> 3
F-U -> 5
S-X -> 7

包括两个复杂的情况:

O-(U+W) -> 1
I-(X+G+(F-U)) -> 9

两者19区域比较硬。对于ONE,它E在某些单词(SEVEN有两个)和NNINE)中显示多次(因此),因此我们不得不检查O在其他两个地方发生的情况,幸运的是,两者都很简单。

对于NINE而言,无论您如何分割,九都很难。

因此,我们最终得到此地图:

[u=(l=t=>s.split(t).length-1)`U`,  //unused 0; precompute 'U's
 l`O`-l`W`-u,    //1
 l`W`,           //2
 l`R`-w,         //3
 u,              //4
 f=l`F`-u,       //5
 x=l`X`,         //6
 l`S`-x,         //7
 g=l`G`,         //8
 l`I`-x-g-f]     //9

9能够使用变量分配向后引用siX,eiGht和5(具有5个向后引用格式),从而节省了字节。多亏了Neil,它使用了我非常不熟悉的JS的几个功能(('例如,将两半剥离的反勾号),并且实际上更接近于我在纸上尝试之前写出来的想法。 (我将9保留为“剩下的内容”,以为它是“如果我看到一个X我可以将其和an Sand I从字符串中删除,然后...”,以便在四个简单的情况之后,接下来的3个将成为简单)。

此项有趣的原因是因为它可以处理任何改组的字符串作为输入。也就是说,我们可以将整个字符串都进行混洗,而不是将单个单词混排,这是我原本以为John所做的:

q=s=>[u=(l=t=>s.split(t).length-1)`U`,l`O`-l`W`-u,l`W`,l`R`-w,u,f=l`F`-u,x=l`X`,l`S`-x,g=l`G`,l`I`-x-g-f].map((n,i)=>`${i}`.repeat(i&&n)).join``

const testCases = ['XENSENINEVSI']

testCases.forEach(testCase => console.log(testCase, q(testCase)))


1
太好了,但计数9还是有问题...我认为可能是ixg-f + u
mdahmoune

@mdahmoune射击,您是对的。我搞砸了那个。:<
Draco18s

使用保存4个字节,使用保存s.split(t).length-12个字节s.repeat(n>0&&n)(为什么n总是小于零?保存7个字节)。通过声明g范围来节省一堆字节,s这样您就不必一直传递它,更好的是,您可以将其制作为带标签的模板,总共节省55个字节(在进行9个更正之前)。通过将重复的值保存在临时文件中来节省更多的字节,而我使用map:则节省了一些时间s=>[,(l=t=>s.split(t).length-1)`O`-l`W`-l`U`,w=l`W`,l`R`-w,u=l`U`,l`F`-u,x=l`X`,l`S`-x,g=l`G`,l`I`-x-g].map((n,i)=>`${i}`.repeat(n)).join``
尼尔

@Neil我不确定为什么N最终小于零,但是在测试三个时确实如此。我不断收到错误消息,调查发现这是必需的,但我仍然不确定。您在那里拥有的模板化库映射是JavaScript,我什至不知道如何阅读。:D
Draco18s

@Neil啊,对,用于检查n个理由> 0:如果一个两个,而是无三。R = 0,W =1。0-1= -1。一个小时前我很难弄清楚那件事,我知道它与3格检查有关,但是在解决它的过程中却有一段时间的魔鬼(缺少咖啡)。
Draco18s

4

Mathematica,133个字节

(s={};c=Characters;j=c@#;Table[If[FreeQ[j~Count~#&/@c[#[[i]]]&@ToUpperCase@IntegerName@Range@9,0],s~AppendTo~i],{i,9}];FromDigits@s)&


输入

“ VENESGTHIEENNI”

输出

789


您可以用c@#[[i]]代替节省一个额外的字节c[#[[i]]]吗?您可能能够通过使用中缀语法才能拯救他人字节~Table
numbermaniac

4

C#,218个字节

简洁版本:

string q(string s){var n="ONE,TWO,THREE,FOUR,FIVE,SIX,SEVEN,EIGHT,NINE".Split(',');for(inti=0,j;;i++)for(j=0;n[i].IndexOf(s[j])>=0;){if(++j==n[i].Length){var r=++i+"";for(;j<s.Length;r+=++i)j+=n[i].Length;return r;}}}

扩展版本:

string q(string s)
{
    var n = "ONE,TWO,THREE,FOUR,FIVE,SIX,SEVEN,EIGHT,NINE".Split(',');
    for (int i = 0, j; ; i++)
        for (j = 0; n[i].IndexOf(s[j]) >= 0;)
        {
            if (++j == n[i].Length)
            {
                var r = ++i + "";
                for (; j < s.Length; r += ++i)
                    j += n[i].Length;
                return r;
            }
        }
}

尝试在线!

作为我的第一篇文章,我不确定规则...我只是在计算用于解密的类的大小,而不是测试它的代码,对吧?

编辑

有趣的是-这是我开始做的,而不是阅读完整的规则:S- 在IdeOne上查看。即使可以将一位数字的字符加扰到字符串中的任何位置,它也会解密。

编辑2

根据TheLethalCoder的提示进行了缩短。谢谢!

编辑3

现在,Titus剃了几个字节。谢谢!


2
您好,欢迎来到PPCG!您只需要包括该方法,就可以从中删除public static它。您可以转换成类似的匿名方法s=>{<do stuff>return"";}。您可以使用var几次,一起声明变量可以节省字节,即int i=1,j;。从字符串创建数组并对其进行拆分通常会更短(尽管在这种情况下我没有检查),即"ONE|TWO".Split('|')。您可以使用<0,而不是==-1
TheLethalCoder


@TheLethalCoder很棒的提示,谢谢!
SamWhan

完全没有经过测试,但我相信以下内容相当于您的221个字节的代码:s=>{var n="ONE|TWO|THREE|FOUR|FIVE|SIX|SEVEN|EIGHT|NINE".Split('|');for(int i=0,j;++i<= 9;)for(j=0;n[i-1].IndexOf(s[j])<0;){if(++j==n[i-1].Length){var r=i+"";while(j<s.Length){j+=n[i].Length;r+=++i;}return r;}}return "";}
TheLethalCoder

附带一提,通常将TIO用于您的TIO 更容易!
TheLethalCoder

3

的JavaScript(ES6),142个 139字节

感谢Neil,节省了3个字节。

当前不利用数字总是按升序排列的优势

f=s=>s?'ENO|OTW|EEHRT|FORU|EFIV|ISX|EENSV|EGHIT|EINN'.split`|`.findIndex(w=>[...s.slice(0,y=w.length)].sort().join``==w)+1+f(s.slice(y)):''

f=s=>s?'ENO|OTW|EEHRT|FORU|EFIV|ISX|EENSV|EGHIT|EINN'.split`|`.findIndex(w=>[...s.slice(0,y=w.length)].sort().join``==w)+1+f(s.slice(y)):''

const testCases = ['NEO', 'ENOWOT', 'EONOTWHTERE', 'SNVEEGHEITNEIN', 'ENOOWTEERHTRUOFEVIFXISNEVESTHGIEENIN']

testCases.forEach(testCase => console.log(testCase, f(testCase)))


等等什么?"axbxc".split`x`.join``。这个怎么称呼?似乎在Google上找不到任何内容。
Qwerty

@Qwerty-它们被标记为模板文字,这是一种ES6功能,我通过使用ES6功能来节省一些字节,并且splitjoin
Craig Ayre

你回答了。我知道标记的模板文字,但是我还没有意识到您也可以在这些函数上使用它。谢谢。
Qwerty

它们略有不同,您具有模板文字(例如x=`foo${5+5}bar`),当您在不使用括号的情况下使用它们调用函数时会对其进行标记:foo`foo${5+5}bar`这与foo(['foo','bar'], 10)
Craig Ayre

1
f(s.slice(y))总是一个字符串,因此您不需要''+在它之前。
尼尔

2

果冻,38个字节

Dị“©ȯ¿w¶&ÇhṆỌƘ#Ȯʋ~¢CNẓ_»Ḳ¤FṢŒu
L3*Ç€iṢ

在线尝试!

说明

L3*Ç€iṢ    Main link. Argument: s (string)
L            Get length of s.
 3*          Raise 3 to that power. This will always be greater than n.
   ǀ        Get the name of each of the numbers using the helper link.
     iṢ      Find the position of the sorted input.

Dị“©ȯ¿w¶&ÇhṆỌƘ#Ȯʋ~¢CNẓ_»Ḳ¤FṢŒu    Helper link. Argument: n (number)
D                                   Get digits of n.
  “©ȯ¿w¶&ÇhṆỌƘ#Ȯʋ~¢CNẓ_»            The string "one two (...) eight nine AA".
                        Ḳ           Split that string at spaces.
 ị                                  Get name of each digit in the list.
                          F         Flatten to a single string.
                           Ṣ        Sort the characters.
                            Œu      Make uppercase.

您的代码有问题。尝试将字符串传递给"EIGHTNINE"它:)
Amorris '17

@Amorris固定为0个字节。
PurkkaKoodari '17

我认为它不适用于“ VENESGTHIEENNI”
J42161217 '17

我第二个@Jenny_mathy
Amorris

@Jenny_mathy该程序效率很低,并且长时间输入会耗尽时间和内存(我知道,这确实很糟糕)。您可以替换为32.2以使用较小的上限,这样您可以轻松计算789而无需更改工作原理。 2会很好,但是对于某些输入很多的输入,它几乎不会失败。
PurkkaKoodari

2

Javascript(ES6),221个字节

s=>(m=btoa`8Ñ>Mc¾LtDáNQ!Q>HþHA7átþ4Ò`.split`+`.map(s=>RegExp(s.replace(/(.)\1*/g,c=>`(?=(.*${c[0]}){${c.length}})`))),t=0,r=0,[...s].map(c=>(t+=c,d=1,n=0,m.map((r,i)=>t.match(r)&&(d--,n=i)),d||(r=r*10+n+1,t=0))),r)

示例代码段:

f=

s=>(m=btoa`8Ñ>Mc¾LtDáNQ…!Q>H…þHA7átþ4Ò`.split`+`.map(s=>RegExp(s.replace(/(.)\1*/g,c=>`(?=(.*${c[0]}){${c.length}})`))),t=0,r=0,[...s].map(c=>(t+=c,d=1,n=0,m.map((r,i)=>t.match(r)&&(d--,n=i)),d||(r=r*10+n+1,t=0))),r)

console.log(f("NEO"))
console.log(f("ENOWOT"))
console.log(f("EONOTWHTERE"))
console.log(f("SNVEEGHEITNEIN"))
console.log(f("ENOOWTEERHTRUOFEVIFXISNEVESTHGIEENIN"))


2

视网膜,160字节

([ONE]{3})*([TWO]{3})*([THRE]{5})*([FOUR]{4})*([FIVE]{4})*([SIX]{3})*([SEVN]{5})*([EIGHT]{5})*([NIE]{4})*
$#1$*1$#2$*2$#3$*3$#4$*4$#5$*5$#6$*6$#7$*7$#8$*8$#9$*9

在线尝试!松散地基于@TessellatingHeckler的PowerShell答案。


2

视网膜,88字节

[EFIST]

^(ON|NO)*
$#1$*1
O

W
2
HR|RH
3
UR|RU
4
X
6
GH|HG
8
(NN)*$
$#1$*9
r`NV|VN
7
V
5

在线尝试!

说明

  • 首先,删除一堆不必要的字符,以实现鲜明性
  • 从前面拾取1(这使我们可以立即丢弃其余的O,并在到达5、7、9混乱之前清除一些N)。
  • 2、3、4、6和8现在微不足道
  • 9是双NN,因此在处理5和7之前先将它们拿掉
  • 从右侧替换7s(因此我们不会将VNV降低到75,而不是57)
  • 剩下的Vs是5s

如果将%(G`添加到标题中,则可以使用原始代码,它将分别评估输入的每一行: TIO
PunPun1000

谢谢@ PunPun1000。我认为一定有办法做到这一点,但是在没有很快找到它之后就放弃了。
凯瑟隆'17

1

PowerShell,182字节

[regex]::Replace("$args",'(?<1>[ONE]{3z2>[TWO]{3z3>[THRE]{5z4>[FOUR]{4z5>[FIVE]{4z6>[SIX]{3z7>[SVEN]{5z8>[EIGHT]{5z9>[NIE]{4})'.replace('z','})|(?<'),{$args.groups.captures[1].name})

在线尝试!

取消引用但无效的代码:

[System.Text.RegularExpressions.Regex]::Replace("$args",

    '(?<1>[ONE]{3})       
    |(?<2>[TWO]{3})
    |(?<3>[THRE]{5})
    |(?<4>[FOUR]{4})
    |(?<5>[FIVE]{4})
    |(?<6>[SIX]{3})
    |(?<7>[SVEN]{5})
    |(?<8>[EIGHT]{5})
    |(?<9>[NIE]{4})'

    ,{$args.groups.captures[1].name}
)

例如,(?<3>[THRE]{5})匹配字符类THRE,因此它可以无序匹配它们,并且必须将这些字符中的任何一个相邻匹配五次,并且捕获组被命名为“ 3”以将名称映射为数字。

通过交换文本重复初步压缩})|(?<为一个z


1

C ++,296、288字节

简洁版本:

#define T string
using namespace std;T N[]={"ONE","TWO","THREE","FOUR","FIVE","SIX","SEVEN","EIGHT","NINE"};T Q(T S){T R="";for(int i=0;i<9;i++){do{if(S.find(N[i])!=T::npos){S.erase(S.find(N[i]),N[i].size());R+=to_string(i+1);}}while(next_permutation(N[i].begin(),N[i].end()));}return R;}

完整版本:

#define T string
using namespace std;

T N[]={"ONE","TWO","THREE","FOUR","FIVE","SIX","SEVEN","EIGHT","NINE"};

T Q(T S)
{
    T R="";
    for(int i=0;i<9;i++)                             //for all possible                             
                                                     //codewords (ONE,TWO...NINE)   
    {
        do
        {   
            if(S.find(N[i])!=T::npos)                //if found in encrypted word
            {
                S.erase(S.find(N[i]),N[i].size());  //erase it from the word
                R+=to_string(i+1);                  //save integer to the result string
            }
                                                    //check next permuation of codeword  

        } while(next_permutation(N[i].begin(),N[i].end())); 
    }                                                   

    return R;
}

尝试在线!

编辑:
1)200-> 296字节,用于在计数中包括名称空间和N的定义,如orlp建议的2)296-> 288,用于使用宏,这要感谢Zacharý


您需要包括的定义N,并using namespace std;为您的字节数。
orlp

我应该更具体一点,不仅将其包括在您的字节数中,还应将其包括在您的答案中。您的答案必须能够仅通过Q在其后立即调用而无需添加任何其他内容即可运行。
orlp

我重新编辑以包含所有内容。对于N的定义,我不确定自己,但对于命名空间,我通常不将其包括在内(将其作为库内容处理)。不过,在当前代码中,字符串的工作至关重要
koita_pisw_sou

1
您可以定义一个宏来保存几个字节吗?repl.it/JY7k
扎卡里

1

红宝石,138个 114 110字节

gsub(/#{"3ONE3TWO5THRE4FOUR4FIVE3SIX5SEVN5EIGHT4NIE".gsub(/(.)(\D+)/,'([\2]{\1})|')}/){(1..9).find{|i|$~[i]}}

字节数包括1个字节的-p选项。

什么?

这个:

/#{"3ONE3TWO5THRE4FOUR4FIVE3SIX5SEVN5EIGHT4NIE".gsub(/(.)(\D+)/,'([\2]{\1})|')}/

是一个正则表达式文字,它通过字符串插值计算为:

/([ONE]{3})|([TWO]{3})|([THRE]{5})|([FOUR]{4})|([FIVE]{4})|([SIX]{3})|([SEVN]{5})|([EIGHT]{5})|([NIE]{4})|/

如果我们将其分配给regex,则其余代码在某种程度上很容易理解:输入中的每个匹配都替换为捕获组的编号,该捕获组是从$~包含当前匹配数据的魔术变量中提取的:

gsub(regex){(1..9).find{|i|$~[i]}}

在线尝试!


1

Java 8,198 256字节

s->{String r="",x=r;for(String n:"ONE TWO THREE FOUR FIVE SIX SEVEN EIGHT NINE".split(" ")){for(char c:n.toCharArray())x+="(?=.*"+c+")";x+="["+n+"]{"+n.length()+"}x";}for(int i=0,q;i<9;)for(q=(s+" ").split(x.split("x")[i++]).length-1;q-->0;)r+=i;return r;}

+58个字节..由于先前版本的正则表达式无法正常工作(它也与“ EEE”;“ EEN”;等匹配)

说明:

在这里尝试。

s->{                     // Method with String as parameter and return-type
  String r="",           //  Result-String
         x=r;            //  Regex-String
  for(String n:"ONE TWO THREE FOUR FIVE SIX SEVEN EIGHT NINE".split(" ")){
                         //  Loop (1) from "ONE" through "NINE":
    for(char c:n.toCharArray())
                         //   Inner loop (2) over the characters of this String
      x+="(?=.*"+c+")";  //    Append regex-group `(?=\w*c)` where `c` is the capital character
                         //   End of inner loop (2) (implicit / single-line body)
    x+="["+n+"]{"+n.length()+"}x";
                         //   Append regex part `[s]{n}` where `s` is the String, and `n` is the length
  }                      //  End of loop (1)
  // The regex now looks like this, which we can split on "x":
  // (?=.*O)(?=.*N)(?=.*E)[ONE]{3}x(?=.*T)(?=.*W)(?=.*O)[TWO]{3}x(?=.*T)(?=.*H)(?=.*R)(?=.*E)(?=.*E)[THREE]{5}x(?=.*F)(?=.*O)(?=.*U)(?=.*R)[FOUR]{4}x(?=.*F)(?=.*I)(?=.*V)(?=.*E)[FIVE]{4}x(?=.*S)(?=.*I)(?=.*X)[SIX]{3}x(?=.*S)(?=.*E)(?=.*V)(?=.*E)(?=.*N)[SEVEN]{5}x(?=.*E)(?=.*I)(?=.*G)(?=.*H)(?=.*T)[EIGHT]{5}x(?=.*N)(?=.*I)(?=.*N)(?=.*E)[NINE]{4}x
  for(int i=0,q;i<9;)    //  Loop (3) from 0 through 9 (exclusive)
    for(q=(s+" ").split(x.split("x")[i++]).length-1;
                         //   Split the input on the current regex-part,
                         //   and save the length - 1 in `q`
        q-->0;           //   Inner loop (4) over `q`
      r+=i               //    And append the result-String with the current index (+1)
    );                   //   End of inner loop (4)
                         //  End of loop (3) (implicit / single-line body)
  return r;              //  Return the result-String
}                        // End of method

1
Erf ...错误的结果:"ENOOWTEERHTRUOFEVIFXISNEVESTHGIEENIN"
OlivierGrégoire17年

是的,这是阻止我对此+1的唯一原因!我的解决方案是240字节...在您击败我之前。
奥利维尔·格雷戈尔

@OlivierGrégoire随意发布您的240字节解决方案,因为我找不到解决方案。.缺点[ONE]{3}是它EEN在该测试用例的末尾也与EIGHT和NINE的一部分匹配。.我怀疑是否存在正则表达式匹配所有这些:ENO|EON|NEO|NOE|OEN|ONE不匹配也EEE;EEN;EEO;...所有短于40个字节的数字..也许我可以用做一些substring和反向检查数字,但我真的没有现在弄明白的时候..
凯文·克鲁伊森(Kevin Cruijssen)

@OlivierGrégoire如果您仍然有240字节的答案,请随时发布。只是碰到这种挑战又来了,并通过使新的正则表达式+58个字节的固定我的答案..
凯文Cruijssen

1
好吧,看来在重做这项挑战时发现了一个更短的方法:p
OlivierGrégoire17年

1

Java(OpenJDK 8),181字节

s->{String x="",r;for(int i=0,l;i<9;)for(r="ONE,TWO,THREE,FOUR,FIVE,SIX,SEVEN,EIGHT,NINE".split(",")[i++],l=r.length();s.matches("["+r+"]{"+l+"}.*");s=s.substring(l))x+=i;return x;}

在线尝试!

我自由地重用了Kevin Cruyssen的TIO模板。希望你不介意;)


啊,没关系我以前的评论。。您构建正则表达式,而不是遍历正则表达式。但是,如果仅使用过,我就接近第一个答案s.substring。最糟糕的部分是,我正在使用s.substring当前的答案,哈哈。嗯,好吧,我+1。很高兴它几乎周末..
凯文Cruijssen

1

05AB1E36 31字节

‘€µ‚•„í†ìˆÈŒšï¿Ÿ¯¥Š‘#vyœN>UvyX:

在线尝试!


查看其运行于调试: TIO与调试

‘€µ‚•„í†ìˆÈŒšï¿Ÿ¯¥Š‘# | Push ['ONE', 'TWO', 'THREE', 'FOUR', 'FIVE', 'SIX', 'SEVEN', 'EIGHT', 'NINE']
vyœ                   | For each list of permutations of that word...
   N>U                | Push index + 1 into register X.          
      vyX:            | Replace each permutation with X.

我只是建议你有绿色标记,而不是我,我发现了一个错误:FURONESEV回报FUR1SEV:(
乔纳森·艾伦

1

Perl 5,102 +1(-n)= 103字节

for$i(map{"[$_]{".length.'}'}ONE,TWO,THREE,FOUR,FIVE,SIX,SEVEN,EIGHT,NINE){$,++;print$,while(s/^$i//)}

在线尝试!


真好!几个有用的技巧:map{...}经常可以替换为map...,length并且y///c通常也可以互换($_虽然在不使用时并不总是较小!),而不是while++$,x s/^$i//更短,如果更改-n-p可以附加到$ $后面的电话print在线尝试!
Dom Hastings

另外,希望您不要介意我发布任何建议,如果您希望我不要这样做。:)
Dom Hastings

0

Python 3中238个 236字节

def f(s):
 e=''
 while len(s):
  for i in range(9):
   for r in[''.join(p)for p in permutations('ONE TWO THREE FOUR FIVE SIX SEVEN EIGHT NINE'.split()[i])]: 
    if s[:len(r)]==r:e+=str(i+1);s=s[len(r):]
 return e
from itertools import*

在线尝试!


蛮力解决方案没有利用数字的非递减性。


感谢@先生。Xcoder可节省2个字节!


你必须包括def f(s):在你的字节数,这不是一个anonymouos功能
Xcoder先生

您也可以替换while len(s)>0while len(s)
Xcoder先生,2017年

@ Mr.Xcoder感谢您的澄清
Chase Vogeli '17

您可以将e-1 的声明移到函数头中。此外,exec列表推导可能会在缩进时节省字节。
CalculatorFeline

0

PHP,141字节

for($a=count_chars($argn);$c=ord($s[++$p]?:$s=[OWU,W,HG,U,FU,X,SX,G,N17.$p=0][$i-print str_repeat($i++,$x)]);)$x=$a[$i+48]+=($p?-1:1)*$a[$c];

较早的版本,151个字节

for($a=count_chars($argn,1);$s=[OWU,W,HG,U,FU,X,SX,G,N17][+$i++];print str_repeat($i,$a[$i+48]))for($p=0;$c=ord($s[$p]);)$a[$i+48]+=($p++?-1:1)*$a[$c];

循环从1到9的数字,对单词中的唯一字符进行计数,然后减去非唯一字符的计数,即可随时随地打印数字。
尽管它是随时随地打印的,但必须存储数字计数才能使9表壳起作用。

与管道一起运行-nR在线尝试

它将另外节省4个字节来存储数字计数$a[$i]$a[$i+48]并使用ASCII 17(用引号引起来)而不是数字字符本身。

分解

for(
    $a=count_chars($argn,1);                # count character occurences in input
    $s=[OWU,W,HG,U,FU,X,SX,G,N17][+$i++];   # loop through digit names
    print str_repeat($i,$a[$i+48])              # print digit repeatedly
)
    for($p=0;$c=ord($s[$p]);)                   # loop through name
        $a[$i+48]+=                                 # add to digit count
        ($p++?-1:1)*                                # (add first, subtract other)
        $a[$c];                                     # character occurences

ONE不是带有的唯一单词O,因此它需要减去W(仅出现在中TWO)和U(仅出现在中FOUR)的计数,依此类推。
NINE之所以很特别,是因为如果我使用字母(这将需要I-X-G-F+UN-O-S+W+U+X),就无法直接减去,因此我会使用数字计数。

PHP,160字节

$a=count_chars($argn);foreach([W2O,U4FOR,X6SI,G8I,F5I,O1,R3,S7,I9]as$s)for(${$s[$p=1]}+=$n=$a[ord($s)];$c=ord($s[++$p]);)$a[$c]-=$n;while($$i--?print$i:$i++<9);

假定所有大写输入;字符可能会乱七八糟。
与管道一起运行-nR在线尝试

说明

循环遍历数字字,计算其唯一字符在输入中的出现次数,并在此过程中减少其他字符的计数。“其他字符” 可能表示单词中的所有其他字符;但仅考虑到以后需要的那些,才节省了19个字节。

str_repeat循环转换为组合循环可节省5个字节。

使用变量变量进行数字计数又节省了8。

分解

$a=count_chars($argn);                              # count character occurences in input
foreach([W2O,U4FOR,X6SI,G8I,F5I,O1,R3,S7,I9]as$s)   # loop through digit names
    for(${$s[$p=1]}+=                                   # 2. add to digits count
        $n=$a[ord($s)];                                 # 1. get count of unique character
        $c=ord($s[++$p]);)                              # 3. loop through other characters
        $a[$c]-=$n;                                         # reduce character count
while(
    $$i--?print$i                                       # print digit repeatedly
    :$i++<9);                                       # loop through digits
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.