转换为苏州数字


27

苏州数字(苏州码子;又称花码)是中文十进制数字:

0 〇
1 〡 一
2 〢 二
3 〣 三
4 〤
5 〥
6 〦
7 〧
8 〨
9 〩

它们几乎像阿拉伯数字一样工作,不同之处在于,当有连续的​​数字属于该集合时{1, 2, 3},这些数字在垂直笔划表示法{〡,〢,〣}和水平笔划表示法之间交替{一,二,三}以避免歧义。此类连续组的第一位始终以垂直笔划符号书写。

任务是将正整数转换为苏州数字。

测试用例

1          〡
11         〡一
25         〢〥
50         〥〇
99         〩〩
111        〡一〡
511        〥〡一
2018       〢〇〡〨
123321     〡二〣三〢一
1234321    〡二〣〤〣二〡
9876543210 〩〨〧〦〥〤〣二〡〇

以字节为单位的最短代码获胜。


1
我已经去过苏州3次(很不错的城市)了很长时间,但是对苏州的数字一无所知。您有我的+1
Thomas Weller

2
@ThomasWeller对我来说是相反的:在编写此任务之前,我知道数字是什么,但并没有将它们命名为“苏州数字”。实际上,我从未听过他们称呼这个名字(或任何名字)。我在市场和手写的中药处方上都看到过它们。
u54112

您可以采用char数组形式的输入吗?
无知的体现,

@EmbodimentofIgnorance是的。好吧,无论如何,足够多的人正在接受字符串输入。
u54112 '18

Answers:



9

R,138字节

我敢打赌,有一种更简单的方法可以做到这一点。用gsub得到的交变数字位置。

function(x,r=-48+~x)Reduce(paste0,ifelse(58<~gsub("[123]{2}","0a",x),"123"["一二三",r],'0-9'["〇〡-〩",r]))
"~"=utf8ToInt
"["=chartr

在线尝试!


9

JavaScript,81个字节

s=>s.replace(/./g,c=>(p=14>>c&!p)|c>3?eval(`"\\u302${c}"`):'〇一二三'[c],p=0)

在线尝试!

使用可14>>c节省3个字节。感谢Arnauld


8

视网膜,46字节

/[1-3]{2}|./_T`d`〇〡-〩`^.
T`123`一二三

在线尝试!链接包括测试用例。说明:

/[1-3]{2}|./

匹配两位数字1-3或任何其他数字。

_T`d`〇〡-〩`^.

将每个比赛的第一个字符替换为其苏州。

T`123`一二三

用水平苏州替换所有剩余的数字。

视网膜0.8.2中的 51个字节

M!`[1-3]{2}|.
mT`d`〇〡-〩`^.
T`¶123`_一二三

在线尝试!链接包括测试用例。说明:

M!`[1-3]{2}|.

如果输入和输入均为1-3,则将其分为单个数字或成对的数字。

mT`d`〇〡-〩`^.

将每行的第一个字符替换为其苏州。

T`¶123`_一二三

将线重新连接在一起,并用水平苏州替换所有剩余的数字。


7

Perl的5 -pl -Mutf853 46个字节

-7个字节,感谢Grimy

s/[123]{2}|./OS&$&/ge;y//〇〡-〰一二三/c

在线尝试!

说明

# Binary AND two consecutive digits 1-3 (ASCII 0x31-0x33)
# or any other single digit (ASCII 0x30-0x39) with string "OS"
# (ASCII 0x4F 0x53). This converts the first digit to 0x00-0x09
# and the second digit, if present, to 0x11-0x13.
s/[123]{2}|./OS&$&/ge;
# Translate empty complemented searchlist (0x00-0x13) to
# respective Unicode characters.
y//〇〡-〰一二三/c

-3个字节,带有s/[123]\K[123]/$&^$;/ge;y/--</一二三〇〡-〩/TIO
Grimmy

49: s/[123]{2}/$&^v0.28/ge;y/--</一二三〇〡-〩/TIO)。48 :(s/[123]{2}/$&^"\0\34"/ge;y/--</一二三〇〡-〩/要求使用文字控制字符而不是\0\34idk在TIO上执行此操作)
Grimmy

46: s/[123]{2}|./OS&$&/ge;y//〇〡-〰一二三/cTIO
Grimmy

6

Java(JDK),120字节

s->{for(int i=0,p=0,c;i<s.length;)s[i]+=(p>0&p<4&(c=s[i++]-48)>0&c<4)?"A䷏乚䷖".charAt(c+(p=0)):(p=c)<1?12247:12272;}

在线尝试!

学分


1
c=s[i]-48;if(p>0&p<4&c>0&c<4)可以是if(p>0&p<4&(c=s[i]-48)>0&c<4),然后还可以将括号放在循环中。另外,else{p=c;s[i]+=c<1?12247:12272;}可以是else s[i]+=(p=c)<1?12247:12272;
Kevin Cruijssen

1
@KevinCruijssen谢谢!我仍在打高尔夫球,但是它仍然对我有帮助^^现在我认为我已经打完高尔夫球了。
奥利维尔·格雷戈雷(OlivierGrégoire)



3

干净 181165字节

所有八进制转义字符都可以用等效的单字节字符替换(每个字符均计为一个字节),但用于可读性,因为否则将使用无效的UTF-8破坏TIO和SE。

import StdEnv
u=map\c={'\343','\200',c}
?s=((!!)["〇":s++u['\244\245\246\247\250']])o digitToInt
$[]=[]
$[h:t]=[?(u['\241\242\243'])h:if(h-'1'<'\003')f$t]
f[]=[]
f[h:t]=[?["一","二","三"]h: $t]

在线尝试!

不编码的编译器既是福也是祸。





2

C,131字节

f(char*n){char*s="〇〡〢〣〤〥〦〧〨〩一二三",i=0,f=0,c,d;do{c=n[i++]-48;d=n[i]-48;printf("%.3s",s+c*3+f);f=c*d&&(c|d)<4&&!f?27:0;}while(n[i]);}

在线尝试!

说明:首先-我将char用于所有变量以使其简短。

数组 s包含所有需要的苏州字符。

其余的几乎遍历提供的数字,该数字表示为字符串。

写入终端时,我使用的是输入数字值(因此字符-ASCII中为48)乘以3,因为所有这些字符在UTF-8中均为3个字节长。正在打印的“字符串”始终为3个字节长-因此,一个真实字符。

变量cd只是当前和下一个输入字符(数字)的“快捷方式”。

变量f保留0或27-它表示是否应将下一个1/2/3字符移至替代字符-27是数组中常规字符与替代字符之间的偏移量。

f=c*d&&(c|d)<4&&!f?27:0 -如果c * d!= 0且它们都小于4并且f不为0,则将27写入f。否则写入0。

可以改写为:

if( c && d && c < 4 && d < 4 && f == 0)
f = 27
else
f = 0

也许有一些字节需要删除,但是我再也找不到任何明显的东西。




1

K(ngn / k),67字节

{,/(0N 3#"〇一二三〤〥〦〧〨〩〡〢〣")x+9*<\x&x<4}@10\

在线尝试!

10\ 获取十进制数字列表

{ }@ 应用以下功能

x&x<4 布尔(0/1)列表,其中参数小于4并且非零

<\扫描少于。这会将连续的1转换为交替的1和0

x+9* 乘以9并加 x

并置正在建立索引,因此将其用作...中的索引

0N 3#"〇一二三〤〥〦〧〨〩〡〢〣"给定的字符串,分为3字节字符串列表。k不支持Unicode,因此只能看到字节

,/ 级联



1

Japt,55个字节

s"〇〡〢〣〤〥〦〧〨〩"
ð"[〡〢〣]" óÈ¥YÉîë2,1Ãc
£VøY ?Xd"〡一〢二〣三":X

在线尝试!

值得注意的是,TIO提供的字节数与我首选的解释器不同,但我认为没有理由不相信给出较低分数的那个。

说明:

    Step 1:
s"〇〡〢〣〤〥〦〧〨〩"        Convert the input number to a string using these characters for digits

    Step 2:
ð                            Find all indexes which match this regex:
 "[〡〢〣]"                    A 1, 2, or 3 character
           ó    Ã            Split the list between:
            È¥YÉ              Non-consecutive numbers
                  ®    Ã     For each group of consecutive [1,2,3] characters:
                   ë2,1      Get every-other one starting with the second
                        c    Flatten

    Step 3:
£                              For each character from step 1:
 VøY                           Check if its index is in the list from step 2
     ?                         If it is:
      Xd"〡一〢二〣三"            Replace it with the horizontal version
                     :X        Otherwise leave it as-is

1

C#(.NET Core),107个字节,81个字符

n=>{var t="〇一二三〤〥〦〧〨〩〡〢〣";var b=0;return n.Select(k=>t[k+(b+=k>0&k<4?1:b)%2*9]);}

在线尝试!

@Jo King节省了17个字节

旧答案

C#(.NET Core),124个字节,98个字符

n=>{var t="〇一二三〤〥〦〧〨〩〡〢〣";var b=0<1;return n.Select(k=>{b=k>0&k<4?!b:0<1;return b?t[k]:t[k+9];});}

在线尝试!

以List的形式接受输入,并返回IEnumerable。我不知道此输入/输出是否正常,所以请让我知道是否无效。

说明

它的工作方式是将所有整数转换为各自的苏州数字形式,但前提是变量b为true。b每当我们遇到一个为1、2或3的整数时,它就会反转,否则将其设置为true。如果b为false,则将整数转换为垂直数字之一。


0

R,104字节

function(x,`[`=chartr)"a-jBCD"["〇〡-〩一二三",gsub("[bcd]\\K([bcd])","\\U\\1","0-9"["a-j",x],,T)]

在线尝试!

R.中的一种替代方法,利用了一些Perl风格的Regex功能(T替代函数中的最后一个参数代表perl=TRUE)。

首先,我们将数字转换为字母字符a-j,然后使用Regex替换将bcd(以前123)的重复出现转换为大写,最后将字符转换为苏州数字,并使用不同的大小写字母处理方式。

感谢J.Doe编写测试用例,因为这些是从他的答案中提取的。


0

C#,153个字节

n=>Regex.Replace(n+"",@"[4-90]|[1-3]{1,2}",x=>"〇〡〢〣〤〥〦〧〨〩"[x.Value[0]-'0']+""+(x.Value.Length>1?"一二三"[x.Value[1]-'0'-1]+"":""))

在线尝试!


顺便说一下,这是153个字节,字符并不总是表示字节。一些字符值得多个字节。
无知的体现

哦,好,我编辑了答案。感谢您提供的信息:)
zruF
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.