Преобразовать в числа Сучжоу

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 〩〨〧〦〥〤〣二〡〇

Самый короткий код в байтах побеждает.

u54112
источник
1
Я был в Сучжоу 3 раза в течение более длительного периода времени (довольно хороший город), но не знал о цифрах Сучжоу. У меня есть +1
Томас Уэллер
2
@ThomasWeller Для меня все наоборот: до написания этого задания я знал, что это за цифры, но не то, чтобы они назывались «цифры Сучжоу». На самом деле я никогда не слышал, чтобы они называли это имя (или вообще какое-либо имя). Я видел их на рынках и на рукописных рецептах китайской медицины.
u54112
Можете ли вы принять ввод в виде массива символов?
Воплощение невежества
@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

Попробуйте онлайн!

j.doe
источник
8

Сетчатка , 46 байт

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

Попробуйте онлайн! Ссылка включает в себя тестовые случаи. Объяснение:

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

Совпадение двух цифр 1-3 или любой другой цифры.

_T`d`〇〡-〩`^.

Замените первого персонажа в каждом матче на Сучжоу.

T`123`一二三

Замените все оставшиеся цифры на горизонтальные Сучжоу.

51 байт в сетчатке 0.8.2 :

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

Попробуйте онлайн! Ссылка включает в себя тестовые случаи. Объяснение:

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

Разделите ввод на отдельные цифры или пары цифр, если они обе 1-3.

mT`d`〇〡-〩`^.

Замените первый символ каждой строки своим Сучжоу.

T`¶123`_一二三

Соедините линии вместе и замените все оставшиеся цифры на горизонтальные Сучжоу.

Нил
источник
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
nwellnhof
источник
-3 байта с 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/--</一二三〇〡-〩/(требует использования буквенных управляющих символов вместо \0\34, по идее, как это сделать на 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 Спасибо! Я все еще играл в гольф, но, тем не менее, он мне помог ^^ Теперь я думаю, что закончил играть в гольф.
Оливье Грегуар
5

JavaScript (ES6),  95 89  88 байт

Сохранено 6 байтов благодаря @ShieruAsakoto

Принимает ввод в виде строки.

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

Попробуйте онлайн!

Arnauld
источник
89 байт
Шиеру Асакото
@ShieruAsakoto Это намного лучше! Большое спасибо!
Арно
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]

Попробуйте онлайн!

Не кодирующий компилятор - это и благословение, и проклятие.

Οurous
источник
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, потому что все эти символы имеют длину 3 байта в UTF-8. Печатная строка всегда имеет длину 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

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

Михал Стонь
источник
120 байтов .
Джонатан Фрех
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

Wolfram Language (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имеет значение true. bинвертируется всякий раз, когда мы встречаем целое число, равное одному, двум или трем, и устанавливается в true в противном случае. Если bfalse, мы превращаем целое число в одну из вертикальных цифр.

Воплощение невежества
источник
0

R 104 байта

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

Попробуйте онлайн!

Альтернативный подход в R. Использует некоторые функции 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]+"":""))

Попробуйте онлайн!

zruF
источник
Это 153 байта, кстати, символы не всегда означают байты. Некоторые символы стоят несколько байтов.
Воплощение Невежества
Ну что ж, я отредактировал свой ответ. Спасибо за информацию :)
zruF