Перетворити на цифри Сучжоу


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

Відповіді:



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

Спробуйте в Інтернеті!



8

Сітківка , 46 байт

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

Спробуйте в Інтернеті! Посилання включає тестові випадки. Пояснення:

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

Збігайте або дві цифри 1-3, або будь-яку іншу цифру.

_T`d`〇〡-〩`^.

Замініть першого персонажа кожного матчу своїм сучжоу.

T`123`一二三

Замініть будь-які цифри, що залишилися, на горизонтальний Сучжоу.

51 байт у Retina 0.8.2 :

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

Спробуйте в Інтернеті! Посилання включає тестові випадки. Пояснення:

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

Розділіть введення на окремі цифри або пари цифр, якщо вони обидві 1-3.

mT`d`〇〡-〩`^.

Замініть перший символ кожного рядка його сучжоу.

T`¶123`_一二三

З'єднайте рядки разом і замініть усі цифри, що залишилися, на горизонтальний Suzhou.


7

Perl 5 -pl -Mutf8 , 53 46 байт

-7 байт завдяки Гримі

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/--</一二三〇〡-〩/( ТІО ). 48: s/[123]{2}/$&^"\0\34"/ge;y/--</一二三〇〡-〩/(вимагає використання буквальних керуючих символів замість \0\34idk, як це зробити в TIO)
Grimmy

46: s/[123]{2}|./OS&$&/ge;y//〇〡-〰一二三/c( TIO )
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;
Кевін Круїссен

1
@KevinCruijssen Дякую! Я все ще займався гольфом у цій відповіді, але це мені все-таки допомогло ^^ Тепер я думаю, що я займаюся гольфом.
Олів’є Грегоар



3

Чисто , 181 165 байт

Усі вісімкові виводи можуть бути замінені на еквівалентні однобайтові символи (і рахуються як один байт кожен), але вони використовуються для читабельності і тому, що в іншому випадку вони порушують TIO і SE з недійсним UTF-8.

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 зберігаються всі необхідні персонажі Сучжоу.

Решта в значній мірі повторює задане число, яке виражається у вигляді рядка.

Під час запису в термінал я використовую значення вхідного числа (так що символ - 48 в ASCII), помножене на 3, тому що всі ці символи в UTF-8 мають 3 байти. Друкований "рядок" завжди триває 3 байти, так що один реальний символ.

Змінні cта dпросто "ярлики" до поточного та наступного символу введення (числа).

Змінна fмістить 0 або 27 - вона говорить, якщо наступний 1/2/3 символ повинен бути зміщений на альтернативний - 27 - це зміщення між регулярним та альтернативним символом у масиві.

f=c*d&&(c|d)<4&&!f?27:0 - запишіть від 27 до f, якщо c * d! = 0 і якщо вони обидва <4 і якщо f не 0, інакше запишіть 0.

Можна переписати як:

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

Можливо, є кілька байтів, які слід відголити, але я більше не можу знайти нічого очевидного.




1

К (нг / к) , 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

Мова Вольфрама (Mathematica) , 117 байт

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

Спробуйте в Інтернеті!

Зауважте, що на TIO це виводить результат у вирваній формі. У звичайному передньому кінці Wolfram це буде виглядати приблизно так:зображення інтерфейсу ноутбука


1
Чи можете ви реалізувати позначення горизонтального обведення для двійки та трійки? Наприклад, f[123]слід повернутися 〡二〣.
u54112

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

Спробуйте в Інтернеті!

Збережено 17 байт завдяки @Jo King

Стара відповідь

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

Спробуйте в Інтернеті!

Приймає дані у вигляді списку та повертає IEnumerable. Я не знаю, чи нормально цей вхід / вихід, тому просто дайте мені знати, чи це не так.

Пояснення

Як це працює, це те, що воно перетворює всі цілі числа у їх відповідну числову форму Сучжоу, але лише у тому випадку, якщо змінна bє істинною. bперевертається кожен раз, коли ми зустрічаємо ціле число, яке є одним, двома або трьома, і встановлюємо істинне інакше. Якщо bзначення false, повернемо ціле число до однієї з вертикальних цифр.


0

R , 104 байти

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

Спробуйте в Інтернеті!

Альтернативний підхід у Р. Використовує деякі функції Regex у стилі Perl ( Tвиступає останній парам у функції заміщення perl=TRUE).

Спочатку ми переводимо цифри на алфавітні символи a-j, потім використовуємо підстановку Regex для перетворення повторюваних повторів bcd(раніше)123 ) у великі регістри, і, нарешті, переводимо символи на цифри Сучжоу з різною обробкою малих та великих літер.

Подяку Дж.Доу за підготовку тестових справ, оскільки вони були взяті з його відповіді .


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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.