Convertire in numeri Suzhou


27

I numeri di Suzhou (蘇州 碼子; anche 花 碼) sono numeri decimali cinesi:

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

Funzionano praticamente come numeri arabi, tranne per il fatto che quando ci sono cifre consecutive appartenenti all'insieme {1, 2, 3}, le cifre si alternano tra notazione a tratto verticale {〡,〢,〣}e notazione a tratto orizzontale {一,二,三}per evitare ambiguità. La prima cifra di tale gruppo consecutivo viene sempre scritta con notazione del tratto verticale.

Il compito è convertire un numero intero positivo in numeri di Suzhou.

Casi test

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

Vince il codice più breve in byte.


1
Sono stato a Suzhou 3 volte per un periodo di tempo più lungo (una bella città) ma non sapevo dei numeri di Suzhou. Hai il mio +1
Thomas Weller il

2
@ThomasWeller Per me è il contrario: prima di scrivere questo compito sapevo quali fossero i numeri, ma non che fossero chiamati "numeri di Suzhou". In realtà non li ho mai sentiti chiamare questo nome (o nessun nome). Li ho visti nei mercati e su prescrizioni di medicina cinese scritte a mano.
u54112,

Puoi prendere l'input sotto forma di un array di caratteri?
Incarnazione dell'ignoranza il

@EmbodimentofIgnorance Sì. Bene, comunque abbastanza persone stanno prendendo l'input di stringa.
u54112

Risposte:



9

R , 138 byte

Scommetto che c'è un modo più semplice per farlo. Utilizzare gsubper ottenere le posizioni numeriche alternate.

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

Provalo online!


9

JavaScript, 81 byte

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

Provalo online!

Utilizzando si 14>>csalva 3 byte. Grazie ad Arnauld .


8

Retina , 46 byte

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

Provalo online! Il link include casi di test. Spiegazione:

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

Abbina due cifre 1-3 o qualsiasi altra cifra.

_T`d`〇〡-〩`^.

Sostituisci il primo personaggio di ogni partita con il suo Suzhou.

T`123`一二三

Sostituisci le cifre rimanenti con Suzhou orizzontale.

51 byte in Retina 0.8.2 :

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

Provalo online! Il link include casi di test. Spiegazione:

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

Dividi l'input in singole cifre o coppie di cifre se sono entrambe 1-3.

mT`d`〇〡-〩`^.

Sostituisci il primo carattere di ogni riga con il suo Suzhou.

T`¶123`_一二三

Unisci nuovamente le linee e sostituisci le cifre rimanenti con Suzhou orizzontale.


7

Perl 5 -pl -Mutf8 , 53 46 byte

-7 byte grazie a Grimy

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

Provalo online!

Spiegazione

# 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 byte 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/--</一二三〇〡-〩/(richiede l'utilizzo di caratteri di controllo letterali invece di \0\34, idk come fare su TIO)
Grimmy,

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

6

Java (JDK) , 120 byte

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

Provalo online!

Crediti


1
c=s[i]-48;if(p>0&p<4&c>0&c<4)può essere if(p>0&p<4&(c=s[i]-48)>0&c<4), quindi puoi anche rilasciare le parentesi attorno al ciclo. Inoltre, else{p=c;s[i]+=c<1?12247:12272;}può essereelse s[i]+=(p=c)<1?12247:12272;
Kevin Cruijssen il

1
@KevinCruijssen Grazie! Stavo ancora giocando a golf questa risposta, ma mi ha comunque aiutato ^^ Ora penso di aver finito di giocare a golf.
Olivier Grégoire,



3

Pulito , 181 165 byte

Tutti gli escape ottali possono essere sostituiti da caratteri a byte singolo equivalenti (e sono conteggiati come un byte ciascuno), ma utilizzati per la leggibilità e perché altrimenti rompono TIO e SE con UTF-8 non valido.

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]

Provalo online!

Un compilatore ignaro della codifica è sia una benedizione che una maledizione.



2

Rosso , 198 171 byte

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]

Provalo online!



2

C, 131 byte

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

Provalo online!

Spiegazione: Prima di tutto, sto usando char per tutte le variabili per renderlo breve.

schieramento s contiene tutti i personaggi Suzhou necessari.

Il resto sta praticamente ripetendo il numero fornito, che è espresso come una stringa.

Quando scrivo sul terminale, sto usando il valore del numero di input (quindi il carattere - 48 in ASCII), moltiplicato per 3, perché tutti questi caratteri sono lunghi 3 byte in UTF-8. La "stringa" in fase di stampa è sempre lunga 3 byte, quindi un carattere reale.

Variabili ced sono solo "scorciatoie" per il carattere di input corrente e successivo (numero).

La variabile fcontiene 0 o 27 - indica se il successivo carattere 1/2/3 deve essere spostato su uno alternativo - 27 è l'offset tra carattere normale e alternativo nell'array.

f=c*d&&(c|d)<4&&!f?27:0 - scrivi da 27 a f se c * d! = 0 e se sono entrambi <4 e se f non è 0, altrimenti scrivi 0.

Potrebbe essere riscritto come:

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

Forse ci sono alcuni byte da radere, ma non sono più in grado di trovare nulla di ovvio.




1

K (ngn / k) , 67 byte

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

Provalo online!

10\ ottenere l'elenco delle cifre decimali

{ }@ applica la seguente funzione

x&x<4 elenco booleano (0/1) in cui l'argomento è inferiore a 4 e diverso da zero

<\scansiona con meno di. questo trasforma le serie di 1 consecutivi in ​​alternando 1 e 0 secondi

x+9* moltiplicare per 9 e aggiungere x

la giustapposizione sta indicizzando, quindi usala come indice in ...

0N 3#"〇一二三〤〥〦〧〨〩〡〢〣"la stringa data, divisa in un elenco di stringhe a 3 byte. k non è a conoscenza di Unicode, quindi vede solo byte

,/ concatenare


1

Wolfram Language (Mathematica) , 117 byte

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

Provalo online!

Si noti che su TIO questo genera il risultato in forma di escape. Nel normale front-end Wolfram, sarà simile al seguente:foto dell'interfaccia del notebook


1
Potete implementare la notazione del tratto orizzontale per due o tre? Ad esempio f[123]dovrebbe tornare 〡二〣.
u54112

1

Japt , 55 byte

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

Provalo online!

Vale la pena notare che TIO fornisce un conteggio di byte diverso rispetto al mio interprete preferito , ma non vedo alcun motivo per non fidarmi di quello che mi dà un punteggio più basso.

Spiegazione:

    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 byte, 81 caratteri

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

Provalo online!

Risparmiato 17 byte grazie a @Jo King

Vecchia risposta

C # (.NET Core) , 124 byte, 98 caratteri

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

Provalo online!

Accetta l'input sotto forma di un elenco e restituisce un IEnumerable. Non so se questo input / output sia ok, quindi fammi sapere se non lo è.

Spiegazione

Come funziona è che trasforma tutti i numeri interi nella loro rispettiva forma numerica di Suzhou, ma solo se la variabile bè vera. bviene invertito ogni volta che incontriamo un numero intero pari a uno, due o tre e, in caso contrario, impostato su vero. Se bè falso, trasformiamo il numero intero in uno dei numeri verticali.


0

R , 104 byte

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

Provalo online!

Un approccio alternativo in R. Fa uso di alcune funzionalità Regex in stile Perl (l'ultimo Tparametro nella funzione di sostituzione sta perperl=TRUE ).

Innanzitutto, traduciamo i numeri in caratteri alfabetici a-j, quindi usiamo la sostituzione Regex per convertire occorrenze duplicate di bcd(precedentemente 123) in maiuscolo e infine traduciamo i caratteri in numeri di Suzhou con una diversa gestione delle lettere minuscole e maiuscole.

Ringraziamo J.Doe per la preparazione dei casi di test, poiché questi sono stati presi dalla sua risposta .


0

C #, 153 byte

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

Provalo online!


Sono 153 byte, a proposito, i caratteri non significano sempre byte. Alcuni caratteri valgono più byte.
Incarnazione dell'ignoranza il

Oh bene, ho modificato la mia risposta. Grazie per l'informazione :)
zruF
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.