Convertir a números de Suzhou

27

Los números de Suzhou (蘇州 碼子; también 花 碼) son números decimales chinos:

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

Funcionan prácticamente como números arábigos, excepto que cuando hay dígitos consecutivos que pertenecen al conjunto {1, 2, 3}, los dígitos alternan entre notación de trazo vertical {〡,〢,〣}y notación de trazo horizontal {一,二,三}para evitar la ambigüedad. El primer dígito de dicho grupo consecutivo siempre se escribe con notación de trazo vertical.

La tarea es convertir un número entero positivo en números de Suzhou.

Casos de prueba

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

El código más corto en bytes gana.

u54112
fuente
1
He estado en Suzhou 3 veces durante un período de tiempo más largo (una ciudad bastante bonita) pero no sabía sobre los números de Suzhou. Tienes mi +1
Thomas Weller
2
@ThomasWeller Para mí es todo lo contrario: antes de escribir esta tarea, sabía cuáles eran los números, pero no es que se llamaran "números de Suzhou". De hecho, nunca los escuché llamar este nombre (o cualquier otro nombre). Los he visto en mercados y en recetas manuscritas de medicina china.
u54112
¿Se puede tomar la entrada en forma de una matriz de caracteres?
Encarnación de la ignorancia
@EmbodimentofIgnorance Sí. Bueno, de todos modos, suficientes personas están tomando la entrada de cadena.
u54112

Respuestas:

9

R , 138 bytes

Apuesto a que hay una manera más fácil de hacer esto. Use gsubpara obtener las posiciones numéricas alternas.

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

Pruébalo en línea!

J.Doe
fuente
9

JavaScript, 81 bytes

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

Pruébalo en línea!

Usando 14>>cahorra 3 bytes. Gracias a Arnauld .

tsh
fuente
8

Retina , 46 bytes

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

Pruébalo en línea! El enlace incluye casos de prueba. Explicación:

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

Haga coincidir dos dígitos 1-3 o cualquier otro dígito.

_T`d`〇〡-〩`^.

Reemplaza el primer personaje de cada partida con su Suzhou.

T`123`一二三

Reemplace los dígitos restantes con Suzhou horizontal.

51 bytes en Retina 0.8.2 :

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

Pruébalo en línea! El enlace incluye casos de prueba. Explicación:

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

Divida la entrada en dígitos individuales o pares de dígitos si ambos son 1-3.

mT`d`〇〡-〩`^.

Reemplace el primer carácter de cada línea con su Suzhou.

T`¶123`_一二三

Vuelva a unir las líneas y reemplace los dígitos restantes con Suzhou horizontal.

Neil
fuente
7

Perl 5 -pl -Mutf8 , 53 46 bytes

-7 bytes gracias a Grimy

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

Pruébalo en línea!

Explicación

# 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
nwellnhof
fuente
-3 bytes con 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/--</一二三〇〡-〩/(requiere el uso de caracteres de control literal en lugar de \0\34, idk cómo hacer esto en 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;}

Pruébalo en línea!

Créditos

Olivier Grégoire
fuente
1
c=s[i]-48;if(p>0&p<4&c>0&c<4)puede ser if(p>0&p<4&(c=s[i]-48)>0&c<4), y luego también puede colocar los corchetes alrededor del bucle. Además, else{p=c;s[i]+=c<1?12247:12272;}puede serelse s[i]+=(p=c)<1?12247:12272;
Kevin Cruijssen
1
@KevinCruijssen ¡Gracias! Todavía estaba jugando esta respuesta, pero de todos modos me ayudó ^^ Ahora creo que ya terminé de jugarlo.
Olivier Grégoire
5

JavaScript (ES6),  95 89  88 bytes

Guardado 6 bytes gracias a @ShieruAsakoto

Toma la entrada como una cadena.

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

Pruébalo en línea!

Arnauld
fuente
89 bytes
Shieru Asakoto
@ShieruAsakoto ¡Eso está mucho mejor! ¡Muchas gracias!
Arnauld
5

Python 3 , 102 bytes

f=0
for i in input():f=i in'123'and 9-f;print(end='〇一二三〤〥〦〧〨〩〡〢〣'[int(i)+f])

Pruébalo en línea!

Mypetlion me recordó a un golf trivial. -4 bytes.

Erik el Outgolfer
fuente
3

Limpio , 181 165 bytes

Todos los escapes octales se pueden reemplazar por los caracteres equivalentes de un solo byte (y se cuentan como un byte cada uno), pero se usan para facilitar la lectura y porque de lo contrario se rompen TIO y SE con UTF-8 no vá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]

Pruébalo en línea!

Un compilador que no conoce la codificación es tanto una bendición como una maldición.

Οurous
fuente
2

Rojo , 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]

Pruébalo en línea!

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

Pruébalo en línea!

Explicación: En primer lugar, estoy usando char para todas las variables para que sea breve.

Formación s contiene todos los personajes necesarios de Suzhou.

El resto está prácticamente iterando sobre el número proporcionado, que se expresa como una cadena.

Al escribir en el terminal, estoy usando el valor del número de entrada (por lo que el carácter - 48 en ASCII), multiplicado por 3, porque todos estos caracteres tienen 3 bytes de longitud en UTF-8. La 'cadena' que se imprime siempre tiene 3 bytes de longitud, por lo que un carácter real.

Variables cyd son solo 'accesos directos' al carácter de entrada actual y siguiente (número).

Variable f contiene 0 o 27 - dice si el siguiente 1/2/3 carácter debe cambiarse a la alternativa - 27 es el desplazamiento entre el carácter regular y el alternativo en la matriz.

f=c*d&&(c|d)<4&&!f?27:0 - escriba 27 en f si c * d! = 0 y si ambos son <4 y si f no es 0, de lo contrario escriba 0.

Podría reescribirse como:

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

Tal vez hay algunos bytes para eliminar, pero ya no puedo encontrar nada obvio.

Michał Stoń
fuente
120 bytes .
Jonathan Frech
1

K (ngn / k) , 67 bytes

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

Pruébalo en línea!

10\ obtener una lista de dígitos decimales

{ }@ aplicar la siguiente función

x&x<4 lista booleana (0/1) de donde el argumento es menor que 4 y distinto de cero

<\escanear con menos de. esto convierte series de 1s consecutivos en 1s y 0s alternos

x+9* multiplicar por 9 y agregar x

la yuxtaposición es indexación, así que úsela como índices en ...

0N 3#"〇一二三〤〥〦〧〨〩〡〢〣"la cadena dada, dividida en una lista de cadenas de 3 bytes. k no es compatible con Unicode, por lo que solo ve bytes

,/ concatenar

ngn
fuente
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])]&

Pruébalo en línea!

Tenga en cuenta que en TIO esto genera el resultado en forma de escape. En el extremo frontal normal de Wolfram, se verá así:imagen de la interfaz del portátil

Kelly Lowder
fuente
1
¿Se puede implementar la notación de trazo horizontal para dos y tres? Por ejemplo, f[123]debería volver 〡二〣.
u54112
1

Japt , 55 bytes

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

Pruébalo en línea!

Vale la pena señalar que TIO da un recuento de bytes diferente que mi intérprete preferido , pero no veo ninguna razón para no confiar en el que me da una puntuación más baja.

Explicación:

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

Pruébalo en línea!

Guardado 17 bytes gracias a @Jo King

Vieja respuesta

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

Pruébalo en línea!

Toma la entrada en forma de una lista y devuelve un IEnumerable. No sé si esta entrada / salida está bien, así que avíseme si no lo está.

Explicación

Cómo funciona esto es que transforma todos los enteros a su respectiva forma numérica de Suzhou, pero solo si la variable bes verdadera. bse invierte cada vez que nos encontramos con un número entero que es uno, dos o tres, y se establece en verdadero de lo contrario. Si bes falso, convertimos el número entero en uno de los números verticales.

Encarnación de la ignorancia
fuente
0

R , 104 bytes

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

Pruébalo en línea!

Un enfoque alternativo en R. Hace uso de algunas características de expresión regular de estilo Perl (el último Tparámetro en la función de sustitución significaperl=TRUE ).

Primero, traducimos números a caracteres alfabéticos. a-j , luego usamos la sustitución de expresiones regulares para convertir ocurrencias duplicadas de bcd(anteriormente 123) a mayúsculas, y finalmente traducimos caracteres a números de Suzhou con diferente manejo de letras minúsculas y mayúsculas.

Gracias a J.Doe por la preparación de casos de prueba, ya que estos fueron tomados de su respuesta .

Kirill L.
fuente
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]+"":""))

Pruébalo en línea!

zruF
fuente
Esto es 153 bytes, por cierto, los caracteres no siempre significan bytes. Algunos caracteres valen varios bytes.
Encarnación de la ignorancia
Oh bueno, edité mi respuesta. Gracias por la información :)
zruF