排序拼写清楚的序列号


17

给定两个或两个以上长度相等且大于2的拼写完整序列号的列表,例如

[[ "three" , "one"  , "four"  ],
 [ "one"   , "five" , "nine"  ],
 [ "two"   , "six"  , "five"  ],
 [ "three" , "five" , "eight" ]]

按单词代表的数字对列表进行排序:

[[ "one"   , "five" , "nine"  ],
 [ "two"   , "six"  , "five"  ],
 [ "three" , "one"  , "four"  ],
 [ "three" , "five" , "eight" ]]

您可能需要将数字拼写为大写或小写,但不要混用。

测试用例

[["three","one","four"],["one","five","nine"],["two","six","five"],["three","five","eight"]]

[["one","five","nine"],["two","six","five"],["three","one","four"],["three","five","eight"]]

[["two","seven"],["one","eight"],["two","eight"],["one","eight"],["two","eight"],["four","five"]]

[["one","eight"],["one","eight"],["two","seven"],["two","eight"],["two","eight"],["four","five"]]

[["one","four","one","four","two"],["one","three","five","six","two"],["three","seven","three","zero","nine"]]

[["one","three","five","six","two"],["one","four","one","four","two"],["three","seven","three","zero","nine"]]

[["zero","six","one"],["eight","zero","three"],["three","nine","eight"],["eight","seven","four"],["nine","eight","nine"],["four","eight","four"]]

[["zero","six","one"],["three","nine","eight"],["four","eight","four"],["eight","zero","three"],["eight","seven","four"],["nine","eight","nine"]]


不知道我是否正确理解了["three","one","four"] === 314吗?
Nit

@Nit是的,是的。
亚当

@Nit通过数字拼出。例如[314,159,265,358][159,265,314,358]
亚当

我们可以假设数字的任意大写吗?
dylnan '18

@dylnanYou may require the numbers to be spelled in lower or upper, but not mixed, case.
totallyhuman

Answers:


14

外壳9 8字节

Ö†€¨tfṡn

在线尝试!

递归的Stax答案 “启发”了算法(我只是稍微更改了查找字符串),请投票给他!

技巧是将每个字母映射到其在字符串中的位置 tfsen(在程序末尾压缩)。外壳列表基于1,丢失的项目返回0,因此我们得到以下映射:

"one"        [0,5,4]
"two"        [1,0,0]
"three"      [1,0,0,4,4]
"four"       [2,0,0,0]
"five"       [2,0,0,4]
"six"        [3,0,0]
"seven"      [3,4,0,4,5]
"eight"      [4,0,0,0,1]
"nine"       [5,0,5,4]

如您所见,列表排列合理。


为了清楚起见,以下是在Husk(以及许多其他语言)中进行列表比较的工作方式:

  1. 如果两个列表之一为空,则为较小的列表。
  2. 如果两个列表的第一个元素不同,则第一个元素较小的是较小的列表。
  3. 否则,丢弃两个列表中的第一个元素,然后返回到点1。

如果我没记错的话,也可以删除“ w”,因为将“两个”与“三个”进行比较仅是有用的,但是您已经有了“ h”。不确定是否对您有帮助。我还没有弄清楚如何将这个事实整合到一个实际上更小的stax程序中。
递归

......如果只是字母可能是tfrsen,但我猜有话像withsen在那里帮助压缩。
乔纳森·艾伦

谢谢大家,您启发了我找到一个更短的字符串:D
Leo

因此,就像在第一个逗号后用小数点替换逗号?
草莓

@Strawberry确实不算[1,0,0][1,0,0,0](但对于此程序来说,不会有什么变化)
Leo

10

Stax24 22 17 16 14 字节

▄Ωφ▐╧Kìg▄↕ñ▼!█

运行并调试

该程序采用小写字母数字数组作为输入。像这样,输出以换行符分隔。

one five nine
two six five
three one four
three five eight

该程序使用在特定转换下获得的顺序对输入进行排序。每个单词中的每个字符都由其在字符串中的索引替换"wo thif sen"。原始数组按此顺序排序。然后在加空格后打印结果。

空格没有用,但实际上允许对字符串文字进行更大的压缩。


Stax使用什么编码?这是UTF-8中的32个字节。
OldBunny2800 '18

5
修改后的CP437,如“字节”超链接解释。
递归

是否有一些标准的算法/方法来提出这样的字符串?这个概念有名字吗?
Itai '18

@Itai:看起来会这样,但是我不知道它是什么。
递归

6

果冻,12 字节

OḌ%⁽Т%147µÞ

单子链接。

在线尝试! ...或去看考官

怎么样?

将数字转换为普通数,然后从10开始以4752为模,然后以147为模,则升序:

 zero            , one         , two         , three               , four
[122,101,114,111],[111,110,101],[116,119,111],[116,104,114,101,101],[102,111,117,114]
 133351          , 12301       , 12901       , 1276511             , 114384
 295             , 2797        , 3397        , 2975                , 336
 1               , 4           , 16          , 35                  , 42

 five            , six         , seven               , eight               , nine
[102,105,118,101],[115,105,120],[115,101,118,101,110],[101,105,103,104,116],[110,105,110,101]
 113781          , 12670       , 1263920             , 1126456             , 121701
 4485            , 3166        , 4640                , 232                 , 2901
 75              , 79          , 83                  , 85                  , 108

然后可以将其用作排序的主要功能:

OḌ%⁽Т%147µÞ - Link: list of lists of lists of characters
          µÞ - sort (Þ) by the mondadic chain to the left (µ):
O            -   ordinals of the characters
 Ḍ           -   convert from base 10
   ⁽Т       -   literal 4752
  %          -   modulo
      %147   -   modulo by 147

那是您在这里发现的一些很棒的模数,我认为这很艰辛。
暴民埃里克(Erik the Outgolfer)'18年

并不是所有的艰苦工作-我确实首先查看了二进制文件。
乔纳森·艾伦

就像,您强求模数,不是吗?
暴民埃里克(Erik the Outgolfer)'18年

是的,但是很快。
乔纳森·艾伦

6

Python,62个字节

lambda m:sorted(m,key=lambda r:[int(s,36)%6779%531for s in r])

在线尝试!...或去看考官

注意:

lambda m:sorted(m,key=lambda r:[map("trfsen".find,s)for s in r])

在Python 2(但不是3)中运行的代码要长两个字节。


1
您是如何发现魔术数字的?
mbomb007 '18

1
只是一个嵌套循环,检查是否严格增加了结果。尽管我可能限制了给定外部的内部数字长度。
乔纳森·艾伦

5

APL(Dyalog Classic),12字节

'nesft'∘⍒⌷¨⊂

在线尝试!

这就是我为二进位找到合适的左参数的方式(我尝试过,长度先为6):

A←⊖a←↑'zero' 'one' 'two' 'three' 'four' 'five' 'six' 'seven' 'eight' 'nine'
{(aa[⍵⍒a;])∧Aa[⍵⍒A;]:⎕←⍵}¨,⊃∘.,/5⍴⊂∪∊a

3

Perl 6、37个字节

*.sort:{('digit 'X~$_)».parse-names}

尝试一下

展开:

*\     # WhateverCode lambda (this is the parameter)
.sort:
{  # block with implicit parameter 「$_」
  (
    'digit ' X~ $_  # concatenate 'digit ' to each named digit
  )».parse-names    # call .parse-names on each
}

代码块将采用格式的值("three","one","four")并将其转换为易于使用("3","1","4")的值.sort


3

APL(Dyalog),38字节

{⍵[⍋(531∘⊥⍤1)(531|6779|369+⎕A⍳⊢)¨↑⍵]}

在线尝试!

基于Jonathan Allan的出色解决方案


1
@JonathanAllan我在最初的变更时间内编辑了一个信用。我不知道为什么它没有变化。立即修复
Uriel

1
31:,⊂⌷¨⍨∘⍋(531⊥531|6779|36⊥9+⎕A⍳⊢)¨但您只需不到当前字节数的一半就可以做到这一点。
亚当

@Adám所以,您可以容忍不同格式(混合与非混合)的输入和输出吗?
ngn

@ngn好的。但是我想到的解决方案完全混合了I / O。
亚当

3

Ruby,48个字节

->x{x.sort_by{|y|y.map{|s|s.to_i(35)**2%47394}}}

滥用了一个事实,"zero".to_i(35)即0(因为'z'在基数35中不是有效数字),因此用暴力方式破解其他九个数字的公式要容易得多。





2

Python 2中85 81 80字节

只需使用每个单词的前两个字母来确定数字,然后使用该索引功能作为关键字对每个列表进行排序。

lambda _:sorted(_,key=lambda L:['zeontwthfofisiseeini'.find(s[:2])/2for s in L])

在线尝试!

由于乔纳森·艾伦节省了4个字节


键函数中的for循环列表理解要短4个字节。
乔纳森·艾伦


1

05AB1E,27个字节

Σ“¡×€µ‚•„í†ìˆÈŒšï¿Ÿ¯¥Š“#skJ

在线尝试!


Σ                           # Sort input by...
 “¡×€µ‚•„í†ìˆÈŒšï¿Ÿ¯¥Š“     # "zero one two three four five size seven eight nine"
                       #    # Split on spaces.
                        sk  # Find index of each input...
                          J # Join up.


@Kaldo啊...编码每个字母的开头2个字母?我觉得那应该是它自己的答案。
魔术章鱼缸

1

Haskell中133个 122 109 107 106字节

import Data.List
sortOn$abs.read.(>>=show.head.(`elemIndices`words"ze on tw th fo fi si se ei ni").take 2)

取消高尔夫:

import Data.List

nums = ["ze","on","tw","th","fo","fi","si","se","ei","ni"]

lookup' :: Eq a => a -> [a] -> Int
lookup' v = head . elemIndices v

wordToInt :: String -> Int
wordToInt (x:y:_) = lookup' [x,y] nums

wordsToInt :: [String] -> Int
wordsToInt = read . concatMap (show . wordToInt)

sortN :: [[String]] -> [[String]]
sortN = sortOn wordsToInt




0

Perl 5,103个字节

sub c{pop=~s%(..)\w+\s*%zeontwthfofisiseeini=~/$1/;$`=~y///c/2%ger}say s/\R//gr for sort{c($a)<=>c$b}<>

在线尝试!


0

视网膜0.8.2,38字节

T`z\o\wit\hfsen`d
O`
T`d`z\o\wit\hfsen

在线尝试!链接包括测试套件。通过将字母暂时替换zowithfsen为该字符串中的位置来工作,从而可以按字母顺序对数字进行排序。


0

果冻30 28 27字节

w@€“¡¦ẇṆb~ṇjṚØ%ĖġṘḥḞṾṇJḌ»µÞ

在线尝试!

-1感谢乔纳森·艾伦。

在字符串“ onetwo ... nine”中查找每个数字的索引,然后将其用作键函数进行排序Þ。不需要'zero'一开始就包含在内,因为对的前两个字符的搜索'zero'将失败,并且0将返回而不是索引,从而使'zero'词典编排为“较早”。


使用“一二...九”的压缩少一个字节
Jonathan Allan '18

@JonathanAllan啊,谢谢。我没有想到要检查。压缩'zeontw...ni'最终会更长。
dylnan '18 -4-9

...不再是“ ...前两个字母”。
乔纳森·艾伦


0

C(clang),229字节

y,j,k,t[9];char *s="zeontwthfofisiseeini";r(char **x){for(j=y=k=0;k+1<strlen(*x);k+=j,y=y*10+(strstr(s,t)-s)/2)sscanf(*x+k,"%2[^,]%*[^,]%*[,]%n",t,&j);return y;}c(*x,*y){return r(x)-r(y);}f(*x[],l){qsort(&x[0],l,sizeof(x[0]),c);}

在线尝试!

没有直接的方法可以将字符串数组发送给C函数,因此本着代码高尔夫球的精神,我对输入格式采取了一些自由。

f()接受一个指向字符串的指针数组,其中每个字符串都是一个数字,用小写的逗号分隔的拼写数字表示。另外,它需要第二个参数数组中的字符串数。我希望这是可以接受的。

f()使用替换已排序的指针qsort()
r()从逗号分隔的数字字符串中读取输入数字。它仅比较前两个字符以标识数字。
c()是比较功能



@ceilingcat您能解释一下strstr("i"-19,t)-"zeontwthfofisiseeini"吗?是特定于编译器的还是标准的?
GPS

这依赖于.rodata外观中没有其他模式,0x69 0x00并且编译器将地址放置在"i""zeo..."
ceilingcat

这么认为..有没有办法确保编译器做到这一点?我知道这里的规则会允许这样做,但是,我真的可以依靠它吗?
GPS

我的本能是避免在“真实世界”中这样做,但是如果您的字符串片段足够独特,这可能会很好地工作。实际上可能存在一些与堆栈金丝雀有关的合法用例,但我也可能只是在幻想。
ceilingcat '19
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.