Konversi ke angka Suzhou

27

Angka Suzhou (蘇州 碼子; juga 花 碼) adalah angka desimal China:

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

Mereka cukup banyak bekerja seperti angka Arab, kecuali bahwa ketika ada digit berturut-turut milik set {1, 2, 3}, digit bergantian antara notasi goresan vertikal {〡,〢,〣}dan notasi goresan horizontal {一,二,三}untuk menghindari ambiguitas. Digit pertama dari grup berurutan seperti itu selalu ditulis dengan notasi goresan vertikal.

Tugasnya adalah mengubah bilangan bulat positif menjadi angka Suzhou.

Uji kasus

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

Kode terpendek dalam byte menang.

u54112
sumber
1
Saya telah berada di Suzhou 3 kali untuk periode waktu yang lebih lama (kota yang cukup bagus) tetapi tidak tahu tentang angka Suzhou. Anda memiliki +1 saya
Thomas Weller
2
@ ThomasWeller Bagi saya itu kebalikannya: sebelum menulis tugas ini saya tahu apa angka-angka itu, tetapi tidak bahwa mereka diberi nama "angka Suzhou". Sebenarnya saya belum pernah mendengar mereka menyebut nama ini (atau nama apa pun). Saya telah melihat mereka di pasar dan resep obat China tulisan tangan.
u54112
Bisakah Anda mengambil input dalam bentuk array char?
Perwujudan Ketidaktahuan
@EmbodimentofIgnorance Ya. Yah, cukup banyak orang yang mengambil input string.
u54112

Jawaban:

9

R , 138 byte

Saya berani bertaruh ada cara yang lebih mudah untuk melakukan ini. Gunakan gsubuntuk mendapatkan posisi numerik bolak-balik.

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

Cobalah online!

J.Apakah
sumber
9

JavaScript, 81 byte

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

Cobalah online!

Menggunakan 14>>cmenghemat 3 byte. Terima kasih untuk Arnauld .

tsh
sumber
8

Retina , 46 byte

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

Cobalah online! Tautan termasuk kasus uji. Penjelasan:

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

Cocokkan dengan dua digit 1-3 atau digit lainnya.

_T`d`〇〡-〩`^.

Ganti karakter pertama dari setiap pertandingan dengan Suzhou-nya.

T`123`一二三

Ganti digit yang tersisa dengan Suzhou horisontal.

51 byte di Retina 0.8.2 :

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

Cobalah online! Tautan termasuk kasus uji. Penjelasan:

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

Pisahkan input menjadi masing-masing digit atau pasangan digit jika keduanya 1-3.

mT`d`〇〡-〩`^.

Ganti karakter pertama dari setiap baris dengan Suzhou-nya.

T`¶123`_一二三

Gabungkan kembali garis-garis itu dan gantilah digit yang tersisa dengan Suzhou horisontal.

Neil
sumber
7

Perl 5 -pl -Mutf8 , 53 46 byte

-7 byte terima kasih kepada Grimy

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

Cobalah online!

Penjelasan

# 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
sumber
-3 byte dengan 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/--</一二三〇〡-〩/(membutuhkan penggunaan karakter kontrol literal alih-alih \0\34, idk bagaimana melakukan ini di 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;}

Cobalah online!

Kredit

Olivier Grégoire
sumber
1
c=s[i]-48;if(p>0&p<4&c>0&c<4)bisa if(p>0&p<4&(c=s[i]-48)>0&c<4), dan kemudian Anda juga bisa menjatuhkan tanda kurung di sekitar loop. Juga, else{p=c;s[i]+=c<1?12247:12272;}bisa jadielse s[i]+=(p=c)<1?12247:12272;
Kevin Cruijssen
1
@KevinCruijssen Terima kasih! Saya masih golf jawaban ini, tapi tetap saja membantu saya ^^ Sekarang saya pikir saya sudah selesai golf itu.
Olivier Grégoire
5

JavaScript (ES6),  95 89  88 byte

Disimpan 6 byte berkat @ShieruAsakoto

Mengambil input sebagai string.

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

Cobalah online!

Arnauld
sumber
89 byte
Shieru Asakoto
@ShieruAsakoto Itu jauh lebih baik! Terima kasih banyak!
Arnauld
5

Python 3 , 102 byte

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

Cobalah online!

mypetlion mengingatkan saya pada golf yang sepele. -4 byte.

Erik the Outgolfer
sumber
3

Bersih , 181 165 byte

Semua lolos oktal dapat diganti dengan karakter byte-tunggal yang setara (dan masing-masing dihitung sebagai satu byte), tetapi digunakan untuk keterbacaan dan karena jika tidak maka akan merusak TIO dan SE dengan UTF-8 yang tidak valid.

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]

Cobalah online!

Kompiler penyandian-tidak sadar adalah berkah sekaligus kutukan.

Suram
sumber
2

Perl 6 -p , 85 61 byte

-13 byte berkat Jo King

s:g[(1|2|3)<((1|2|3)]=chr $/+57;tr/0..</〇〡..〩一二三/

Cobalah online!

nwellnhof
sumber
2

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

Cobalah online!

Galen Ivanov
sumber
2

Jelly , 38 byte

9Rż“øƓ“œ%“øƈ’;-25+⁽-EỌœị@DżD<4«Ɗ‘×¥\ƊƊ

Cobalah online!

Erik the Outgolfer
sumber
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]);}

Cobalah online!

Penjelasan: Pertama-tama - Saya menggunakan char untuk semua variabel agar pendek.

Array smenampung semua karakter Suzhou yang dibutuhkan.

Sisanya cukup banyak iterasi di atas angka yang disediakan, yang dinyatakan sebagai string.

Saat menulis ke terminal, saya menggunakan nilai nomor input (jadi karakter - 48 di ASCII), dikalikan dengan 3, karena semua karakter ini panjangnya 3 byte di UTF-8. 'String' yang dicetak selalu sepanjang 3 byte - jadi satu karakter asli.

Variabel cdand hanya 'jalan pintas' ke karakter input saat ini dan selanjutnya (angka).

Variabel fmemegang 0 atau 27 - dikatakan jika karakter 1/2/3 berikutnya harus digeser ke karakter alternatif - 27 adalah offset antara karakter reguler dan karakter alternatif dalam array.

f=c*d&&(c|d)<4&&!f?27:0 - tulis 27 ke f jika c * d! = 0 dan jika keduanya <4 dan jika f bukan 0, tuliskan 0.

Dapat ditulis ulang sebagai:

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

Mungkin ada beberapa byte untuk dicukur, tetapi saya tidak lagi dapat menemukan sesuatu yang jelas.

Michał Stoń
sumber
120 byte .
Jonathan Frech
1

Ruby -p , 71 byte

$_=gsub(/[1-3]\K[1-3]/){|x|(x.ord+9).chr}.tr"0-<","〇〡-〩一二三"

Cobalah online!

Kirill L.
sumber
1

K (ngn / k) , 67 byte

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

Cobalah online!

10\ dapatkan daftar angka desimal

{ }@ terapkan fungsi berikut

x&x<4 boolean (0/1) daftar di mana argumennya kurang dari 4 dan bukan nol

<\memindai dengan kurang dari. ini mengubah proses 1s berurutan menjadi 1s dan 0s bergantian

x+9* kalikan dengan 9 dan tambahkan x

penjajaran adalah pengindeksan, jadi gunakan ini sebagai indeks di ...

0N 3#"〇一二三〤〥〦〧〨〩〡〢〣"string yang diberikan, dibagi menjadi daftar string 3-byte. k tidak sadar unicode, jadi ia hanya melihat byte

,/ menggabungkan

ngn
sumber
1

Bahasa Wolfram (Mathematica) , 117 byte

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

Cobalah online!

Perhatikan bahwa pada TIO ini menampilkan hasilnya dalam bentuk lolos. Di ujung depan Wolfram yang normal, akan terlihat seperti ini:gambar antarmuka notebook

Kelly Lowder
sumber
1
Bisakah Anda menerapkan notasi stroke horizontal untuk dua dan tiga? Misalnya f[123]harus kembali 〡二〣.
u54112
1

Japt , 55 byte

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

Cobalah online!

Perlu dicatat bahwa TIO memberikan jumlah byte yang berbeda dari penerjemah pilihan saya , tetapi saya tidak melihat alasan untuk tidak mempercayai yang memberikan nilai lebih rendah kepada saya.

Penjelasan:

    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
sumber
1

C # (.NET Core) , 107 byte, 81 karakter

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

Cobalah online!

Disimpan 17 byte berkat @ Jo King

Jawaban Lama

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

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

Cobalah online!

Mengambil input dalam bentuk Daftar, dan mengembalikan IEnumerable. Saya tidak tahu apakah input / output ini ok, jadi beri tahu saya jika tidak.

Penjelasan

Cara kerjanya adalah ia mengubah semua bilangan bulat ke bentuk angka Suzhou masing-masing, tetapi hanya jika variabel bbenar. bterbalik setiap kali kita bertemu integer yang satu, dua, atau tiga, dan disetel ke true sebaliknya. Jika bsalah, kami mengubah bilangan bulat ke salah satu angka vertikal.

Perwujudan Ketidaktahuan
sumber
0

R , 104 byte

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

Cobalah online!

Pendekatan alternatif dalam R. Menggunakan beberapa fitur Regex gaya Perl ( Tparam terakhir dalam fungsi substitusi adalah singkatan dari)perl=TRUE ).

Pertama, kami menerjemahkan angka ke karakter alfabet a-j, kemudian menggunakan substitusi Regex untuk mengonversi kejadian duplikat bcd(sebelumnya 123) menjadi huruf besar, dan akhirnya menerjemahkan karakter ke angka Suzhou dengan berbagai penanganan huruf kecil dan huruf besar.

Penghargaan untuk J.Apakah untuk persiapan kasus uji, karena ini diambil dari jawabannya .

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

Cobalah online!

zruF
sumber
Ini 153 byte, omong-omong, karakter tidak selalu berarti byte. Beberapa karakter bernilai beberapa byte.
Perwujudan Ketidaktahuan
Oh well, saya mengedit jawaban saya. Terima kasih atas informasinya :)
zruF