Converta para numerais Suzhou


27

Os números Suzhou (蘇州 碼子; também 花 碼) são números decimais chineses:

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

Eles funcionam praticamente como algarismos arábicos, exceto que, quando há dígitos consecutivos pertencentes ao conjunto {1, 2, 3}, os dígitos alternam entre a notação de traço vertical {〡,〢,〣}e a horizontal, {一,二,三}para evitar ambiguidade. O primeiro dígito desse grupo consecutivo é sempre escrito com notação de traço vertical.

A tarefa é converter um número inteiro positivo em números de Suzhou.

Casos de teste

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

O menor código em bytes vence.


1
Estive em Suzhou 3 vezes por um longo período de tempo (uma cidade bastante agradável), mas não sabia sobre os números de Suzhou. Você tem o meu +1
Thomas Weller

2
@ThomasWeller Para mim, é o contrário: antes de escrever esta tarefa, eu sabia quais eram os números, mas não que eles fossem chamados de "números Suzhou". Na verdade, nunca os ouvi chamar esse nome (ou qualquer outro nome). Eu os vi nos mercados e em prescrições manuscritas de medicina chinesa.
u54112

Você pode receber entradas na forma de uma matriz de caracteres?
Modalidade de ignorância

@EmbodimentofIgnorance Sim. Bem, pessoas suficientes estão recebendo entrada de string de qualquer maneira.
U54112

Respostas:



9

R , 138 bytes

Aposto que há uma maneira mais fácil de fazer isso. Use gsubpara obter as posições numéricas alternadas.

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

Experimente online!


9

JavaScript, 81 bytes

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

Experimente online!

Usando 14>>c salva 3 bytes. Graças a Arnauld .


8

Retina , 46 bytes

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

Experimente online!O link inclui casos de teste. Explicação:

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

Corresponda dois dígitos 1-3 ou qualquer outro dígito.

_T`d`〇〡-〩`^.

Substitua o primeiro caractere de cada partida pelo seu Suzhou.

T`123`一二三

Substitua todos os dígitos restantes por Suzhou horizontal.

51 bytes na Retina 0.8.2 :

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

Experimente online! O link inclui casos de teste. Explicação:

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

Divida a entrada em dígitos individuais ou pares de dígitos, se ambos forem 1-3.

mT`d`〇〡-〩`^.

Substitua o primeiro caractere de cada linha pelo seu Suzhou.

T`¶123`_一二三

Junte as linhas novamente e substitua os dígitos restantes pela Suzhou horizontal.


7

Perl 5 -pl -Mutf8 , 53 46 bytes

-7 bytes graças ao Grimy

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

Experimente online!

Explicação

# 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 bytes com 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/--</一二三〇〡-〩/(requer o uso de caracteres em vez de controle literais \0\34, idk como fazer isso em TIO)
Grimmy

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

6

Java (JDK) , 120 bytes

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;}

Experimente online!

Créditos


1
c=s[i]-48;if(p>0&p<4&c>0&c<4)pode ser if(p>0&p<4&(c=s[i]-48)>0&c<4)e, em seguida, você também pode soltar os colchetes ao redor do loop. Além disso, else{p=c;s[i]+=c<1?12247:12272;}pode serelse s[i]+=(p=c)<1?12247:12272;
Kevin Cruijssen

1
@KevinCruijssen Thank you! Eu ainda estava jogando esta resposta, mas ainda assim me ajudou ^^ Agora acho que já terminei de jogar.
Olivier Grégoire

5

JavaScript (ES6),  95 89  88 bytes

Guardado 6 bytes graças a @ShieruAsakoto

Recebe a entrada como uma sequência.

s=>s.replace(i=/./g,c=>'三二一〇〡〢〣〤〥〦〧〨〩'[i=112>>i&c<4?3-c:+c+3])

Experimente online!



@ShieruAsakoto Isso é muito melhor! Muito obrigado!
Arnauld


3

Limpo , 181 165 bytes

Todas as fugas octais podem ser substituídas pelos caracteres equivalentes de um byte (e são contados como um byte cada), mas são usados ​​para facilitar a leitura e, caso contrário, ele quebra o TIO e o SE com UTF-8 inválido.

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]

Experimente online!

Um compilador que ignora a codificação é uma bênção e uma maldição.



2

Vermelho , 198 171 bytes

func[n][s: charset"〡〢〣"forall n[n/1: either n/1 >#"0"[to-char 12272 + n/1][#"〇"]]parse
n[any[[s change copy t s(pick"一二三"do(to-char t)- 12320)fail]| skip]]n]

Experimente online!



2

C, 131 bytes

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]);}

Experimente online!

Explicação: Primeiro de tudo - estou usando char para todas as variáveis ​​para torná-lo curto.

A matriz scontém todos os caracteres necessários de Suzhou.

O resto é praticamente iterativo sobre o número fornecido, que é expresso como uma sequência.

Ao escrever no terminal, estou usando o valor do número de entrada (portanto, o caractere - 48 em ASCII), multiplicado por 3, porque todos esses caracteres têm 3 bytes de comprimento em UTF-8. A 'string' impressa sempre tem 3 bytes - portanto, um caractere real.

Variáveis ce dsão apenas 'atalhos' para o caractere de entrada atual e o próximo (número).

A variável fmantém 0 ou 27 - indica se o próximo caractere 1/2/3 deve ser deslocado para a alternativa um - 27 é o deslocamento entre o caractere regular e o alternativo na matriz.

f=c*d&&(c|d)<4&&!f?27:0 - escreva 27 para f se c * d! = 0 e se forem ambos <4 e se f não for 0, caso contrário, escreva 0.

Pode ser reescrito como:

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

Talvez haja alguns bytes para cortar, mas não consigo mais encontrar nada óbvio.




1

K (ngn / k) , 67 bytes

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

Experimente online!

10\ obter lista de dígitos decimais

{ }@ aplique a seguinte função

x&x<4 lista booleana (0/1) de onde o argumento é menor que 4 e diferente de zero

<\digitalize com menos que. isso transforma séries de 1s consecutivas em 1s e 0s alternadas

x+9* multiplique por 9 e adicione x

justaposição é indexação, então use isso como índices em ...

0N 3#"〇一二三〤〥〦〧〨〩〡〢〣"a sequência especificada, divida em uma lista de sequências de 3 bytes. k não reconhece unicode, portanto, vê apenas bytes

,/ concatenar


1

Wolfram Language (Mathematica) , 117 bytes

FromCharacterCode[12320+(IntegerDigits@#/. 0->-25//.MapIndexed[{a___,c=#2[[1]],c,b___}->{a,c,#,b}&,{0,140,9}+7648])]&

Experimente online!

Observe que no TIO isso gera o resultado na forma de escape. No front-end normal da Wolfram, será assim:imagem da interface do notebook


1
Você pode implementar a notação de traço horizontal para dois e três? Por exemplo, f[123]deve retornar 〡二〣.
U54112

1

Japonês , 55 bytes

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

Experimente online!

Vale a pena notar que o TIO fornece uma contagem de bytes diferente do meu intérprete preferido , mas não vejo razão para não confiar no que me dá uma pontuação mais baixa.

Explicação:

    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 bytes, 81 caracteres

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

Experimente online!

Guardado 17 bytes graças a @Jo King

Resposta antiga

C # (.NET Core) , 124 bytes, 98 caracteres

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];});}

Experimente online!

Recebe entrada na forma de uma lista e retorna um IEnumerable. Não sei se essa entrada / saída está ok, então deixe-me saber se não está.

Explicação

Como isso funciona é que ele transforma todos os números inteiros na respectiva forma numérica de Suzhou, mas apenas se a variável bfor verdadeira. bé invertido sempre que encontramos um número inteiro que seja um, dois ou três e, caso contrário, é definido como true. Se bfor falso, transformamos o número inteiro em um dos números verticais.


0

R , 104 bytes

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

Experimente online!

Uma abordagem alternativa em R. Utiliza alguns recursos do Regex no estilo Perl (o último Tparâmetro na função de substituição significa perl=TRUE).

Primeiro, convertemos números em caracteres alfabéticos e a-j, em seguida, usamos a substituição Regex para converter ocorrências duplicadas de bcd(anteriormente123 ) em maiúsculas e, finalmente, convertemos caracteres em números de Suzhou com tratamento diferente de letras minúsculas e maiúsculas.

Agradecemos a J.Doe pela preparação de casos de teste, pois foram retirados de sua resposta .


0

C #, 153 bytes

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

Experimente online!


São 153 bytes, a propósito, caracteres nem sempre significam bytes. Alguns caracteres valem vários bytes.
Modalidade de ignorância

Oh, bem, eu editei minha resposta. Obrigado pela informação :)
zruF
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.