Смотри мама! Я сделал свою собственную (Base 10) систему счисления! [закрыто]

21

Мы все сделали это, ну, может быть, и нет, но создание собственного языка инопланетян и системы нумерации является одним из основных элементов фэнтезийного письма, но в основном это просто забавное занятие.

Задача проста, взять два входа:

  1. Упорядоченный список вводит 10 [десять] уникальных «цифр» (любой печатный символ ASCII) и интерпретирует их по порядку как значения 0, 1, 2, 3, ..., 9

    + Есть исключения из того, что здесь может быть цифрой. Арифметические операторы (+, -, *, /), круглые скобки и пробелы не могут использоваться в качестве одной из цифр.

  2. Арифметическая задача, использующая только эти «цифры»

И вывести эквивалентный целочисленный результат в заданной форме.

Вот пример:

INPUT

abcdefghij

bcd + efg + hij
OUTPUT

bdgi

В этом примере, входной список (вы можете выбрать, в какую форму входит список) для 'abcdefghij' соответствует '0123456789', так же как 'hjkloiwdfp' также будет соответствовать 1 к 1 с '0123456789', где вместо 'a' ассоциируется с ноль, «ч» делает. Следующее арифметическое «переводит» в 123 + 456 + 789, что равно 1368. Затем оно должно быть выведено в той форме, которую мы ему дали, поэтому b (который представляет 1) d (для 2) g (для 6) и i (для 8.).

ТЕСТОВЫЕ СЛУЧАИ

abcdefghij
abc + def - ghij

-gedc
qwertyuiop
qwerty / uiop

e
%y83l;[=9|
(83l * 9) + 8%

y9|8

БОЛЬШЕ ПРАВИЛ

  • Стандартные лазейки запрещены!
  • Это код гольфа, поэтому выигрывают кратчайшие ответы в байтах.
  • Это должна быть полная программа или функция, принимающая входы и выходы в любом формате, который лучше всего подходит для вас. (Просто нельзя добавить дополнительную информацию во входные данные, только «цифры» и выражение.
  • Используйте любой язык, который вам нравится (если он соответствует другим правилам)
Билл W
источник
9
2-й тестовый пример предполагает, что окончательный результат округляется, в противном случае результат будет q.ioiopewioyetqorw.... Если да, то какое округление следует применять?
Арно
2
Чтобы добавить к пункту @ SriotchilismO'Zaic, у нас также есть песочница для вашей и нашей выгоды; Цель состоит в том, чтобы позволить сообществу помочь уточнить проблемы, прежде чем они будут опубликованы. Хорошая идея для вызова, хотя!
Джузеппе
3
Разные языки могут по-разному оценивать одно и то же уравнение, я не уверен, что это можно обойти. Например, T-SQL возвращает 1для 5/3, а не 2из-за целочисленного деления (не округления). Это не делает задачу недействительной, но вам, возможно, придется разрешить разные приемлемые ответы для одного и того же теста (см. Мой ответ по T-SQL ниже).
BradC
2
@ Джузеппе Ух ты, я долго просматривал этот стек и никогда не знал об этом! Определенно было бы полезно, особенно в качестве первого постера (долгого слушателя), которым я являюсь. Будет держать записку в следующий раз! Спасибо за ваш комментарий и ответ.
Билл W
2
Интересным вариантом может быть вариант, который поддерживает любую числовую базу, в зависимости от длины первой строки во входных данных ...
Даррел Хоффман

Ответы:

11

05AB1E , 10 9 байтов

žh‡.Eò¹Åв

(Сейчас) выводит в виде списка символов.

Попробуйте онлайн или проверьте все контрольные примеры .

Объяснение:

          # Transliterate the second (implicit) input, replacing every character of 
           # the first (implicit) input with:
žh         # The builtin "0123456789"
   .E      # Then evaluate it as Elixir code
     ò     # Round it to the nearest integer
      ¹Åв  # And change it back by using a custom base-conversion with the first input as
           # base (which results in a character list)
           # (after which that result is output implicitly)

Новая версия 05AB1E - это сборка в Elixir . .EФункция будет вызывать call_unary(fn x -> {result, _} = Code.eval_string(to_string(x)); result end, a), если Code.eval_stringэто встроенный Elixir .

Обратите внимание, что унаследованная версия 05AB1E не подойдет для этого, потому что она построена на Python. Числа с начальными 0 не будут оцениваться:
см. Все тестовые примеры в устаревшей версии (которая использует 10-байтовую версию, потому что Åввстроенная версия является новой).

Кевин Круйссен
источник
8

R , 58 байт

function(d,s,`[`=chartr)'0-9'[d,eval(parse(t=d['0-9',s]))]

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

Использует перевод символов, chartrчтобы поменять цифры, parses и evals выражение, а затем chartrвернуться к исходным цифрам.

Если требуется округление до ближайшего целого числа, это

R 65 байт

function(d,s,`[`=chartr)'0-9'[d,round(eval(parse(t=d['0-9',s])))]

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

Giuseppe
источник
Использование [более короткого имени для функции с 3 параметрами очень разумно. Отлично сработано.
Робин Райдер
6

T-SQL, 117 байт

DECLARE @ CHAR(99)
SELECT @='SELECT TRANSLATE('+TRANSLATE(e,c,'0123456789')+',''0123456789'','''+c+''')'FROM t
EXEC(@)

Разрывы строки предназначены только для удобства чтения.

Ввод осуществляется через уже существующую таблицу t с текстовыми столбцами c (символы) и e (уравнение) в соответствии с нашими правилами ввода-вывода .

Использует функцию SQL 2017 TRANSLATEдля переключения между символами и создания строки, которая содержит не только уравнение, но и код для перевода обратно в исходные символы:

SELECT TRANSLATE(123 + 456 + 789,'0123456789','abcdefghij') 

Эта строка затем оценивается с помощью EXEC().

Там могут быть некоторые символы (например, одинарные кавычки '), которые нарушают этот код; Я не проверял все возможные символы ASCII.

В соответствии с задачей я оцениваю выражение как данное, в зависимости от того, как мой язык интерпретирует эти операторы. Таким образом, второй контрольный пример возвращает 1 ( w), а не 2 ( e) из-за целочисленного деления.

BradC
источник
4

Perl 6 , 38 байт

{*.trans($_=>^10).EVAL.trans(^10=>$_)}

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

Я не уверен, как округление должно работать. Если она округляет в конце , то я могу добавить .roundк +6 байт . Если поведение /должно быть другим, то это может быть дольше. Принимает ввод карри как f(arithmetic)(numerals)(arithmetic).

Объяснение:

{                                    }  # Anonymous codeblock
 *                                      # Returning a whatever lambda
  .trans($_=>^10)       # That translates the numerals to digits
                 .EVAL  # Evaluates the result as code
                      .trans(^10=>$_)   # And translates it back again
Джо Кинг
источник
3

Stax , 74 66 65 байт

┼ö8Q#xóπcM~oÖ÷╦├mî☼yº─▐4ç≥e╘o▄ê‼ø_k╜ø8%N╫ ╗e<.╗P[─╛èA±!xêj«w╠°{B♪

Запустите и отладьте его

Stax не очень хорошо здесь, без истинного "eval" инструкции. В документах он называется «eval», но он работает только с буквальными значениями, а не с полными выражениями.

рекурсивный
источник
Это может не соответствовать требованиям оператора. Не уверен, если это требуется, хотя? staxlang.xyz/...
Дана
@dana: Хороший вопрос. Я не учел это. Исправление, вероятно, будет стоить несколько байтов, поэтому я подожду некоторых разъяснений, прежде чем пытаться изменить это поведение.
рекурсивный
3

Баш, 97 байт

IFS=''
read S
read O
A=`echo "$O"|tr "$S" 0-9`
printf %0.f `bc<<<"(${A[@]##0})+0.5"`|tr 0-9 "$S"

Могло бы быть меньше, если бы мы могли обрезать, а не округлять. Также сложно обрабатывать начальные нули (как в тестовом примере № 2), поскольку Bash интерпретирует числа, начинающиеся с 0, как восьмеричные.

spuck
источник
Каково общее мнение об использовании таких утилит, как "bc" и "tr" для игры в гольф?
Спак
1
Я не эксперт, но я думаю, что эти типы ответов обычно представлены как что-то вроде «bash + coreutils»
Джузеппе
@Giuseppe trявляется частью coreutils, а bcне является. Тем не менее, bcэто очень распространенный инструмент. Каждая другая команда в этом ответе - bash.
Рекксогитанс
-7 байтов украдено из ответа @ CM, уменьшив '0123456789' до '0-9'
spuck
Определение T больше не выгодно: $Tон всего на один байт короче 0-9, вы используете его только дважды, и вы тратите 8 байтов на его определение.
ruds
2

Бин , 94 90 байт

HexDump

00000000: 53d0 80d6 d800 d3d0 80a0 1f20 8047 53a0  SÐ.ÖØ.ÓÐ. . .GS 
00000010: 1753 d080 d3d0 80a0 5e20 800a a181 8100  .SÐ.ÓÐ. ^ ..¡...
00000020: 40a0 5f52 cac3 4da0 6580 53d0 80a0 5d20  @ _RÊÃM e.SÐ. ] 
00000030: 8089 205f a065 205f 2080 0aa1 8181 0123  .. _ e _ ..¡...#
00000040: 0058 0020 800a a181 8102 40a0 6550 84a0  .X. ..¡...@ eP. 
00000050: 5d20 652e dce2 b02b dc64                 ] e.Üâ°+Üd

JavaScript

`${Math.round(
  eval(
    b.replace(
      /./g,
      c => ~(i = a.indexOf(c)) ? i : c
    ).replace(
      /\b0+/g,
      ''
    )
  )
)}`.replace(
  /\d/g,
  i => a[i]
)

объяснение

Эта программа неявно назначает первую и вторую строки ввода как строки для переменных aи bсоответственно.

Каждый символ cв строке bзаменяется соответствующим индексом iсимвола, найденного в строке a, или самого себя, если он не найден.

Затем он удаляет каждую последовательность из одного или нескольких 0s, которым предшествует граница, из результирующей строки. Это сделано для того, чтобы не eval()оценивать любую последовательность цифр, начиная с 0восьмеричного литерала.

После eval()и Math.round()результат приводится обратно в строку, и каждый символ цифры iзаменяется соответствующим символом из строки aв индексе i.

Тестовые случаи

демонстрация

abcdefghij
abcd + efg + hij

bdgi

демонстрация

abcdefghij
abc + def - ghij

-gedc

демонстрация

qwertyuiop
qwerty / uiop

e

демонстрация

%y83l;[=9|
(83l * 9) + 8%

y9|8
Патрик Робертс
источник
2

Perl 5 -p , 63 байта

$p=<>;eval"y/$p/0-9/";s/\b0+\B//g;$_=int.5+eval;eval"y/0-9/$p/"

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

Принимает выражение в первой строке ввода и список перевода во второй.

Xcali
источник
1

Perl 5 , 130 байт

sub f{eval sprintf"'%.0f'=~y/%s/%s/r",eval(eval(sprintf"\$_[1]=~y/%s/%s/r",@r=map"\Q$_",$_[0],'0123456789')=~s,\b0,,gr),reverse@r}

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

Может быть, этот двойной eval как-то можно превратить в s/.../.../geer.

Кжетил С.
источник
1

Древесный уголь , 14 байтов

⍘UV⭆η⎇№θι⌕θιιθ

Попробуйте онлайн! Ссылка на подробную версию кода. Примечание. Выражение оценивается в соответствии с семантикой Python 3, поэтому, например, начальные нули на ненулевых числах недопустимы. Объяснение:

   ⭆η           Map over expression's characters and join
        ι       Current character
      №θ        Count matches in first input
     ⎇          If non-zero
         ⌕θι    Replace with position in first input
            ι   Otherwise keep character unchanged
 UV             Evaluate as Python 3
⍘            θ  Convert to base using first input as digits
Нил
источник
К сожалению, ведущие 0s не работают в Python, который присутствует в тестовых примерах.
Джонатан Аллан
0

Python 3 , 137 байт

Подход без регулярных выражений, использующий str.translateи str.maketransзаменяющий символы. Я потерял много персонажей при обрезке ведущих нулей ...

lambda s,t,d='0123456789',e=str.translate,m=str.maketrans:e(str(round(eval(' '.join(c.lstrip('0')for c in e(t,m(s,d)).split())))),m(d,s))

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

Габор Фекете
источник
0

Python 3 , 167 байт

import re
a=[*enumerate(input())]
e=input()
for i,c in a:e=re.sub(c,str(i),e)
e=str(round(eval(re.sub(r'\b0+(?!\b)','',e))))
for i,c in a:e=re.sub(str(i),c,e)
print(e)

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

Есть куда расти...

movatica
источник
Тем не менее не удается на последнем тесте: tio.run/...
Руохола
0

Wolfram Language (Mathematica) , 121 байт

Я определяю чистую функцию с двумя аргументами. Поскольку некоторые функции повторяются, я сохраняю их в переменной, чтобы сохранить несколько символов. Этот код просто выполняет некоторые строковые замены, а затем использует его ToExpressionдля оценки выражения с ядром Wolfram.

(r=Thread[StringPartition[#,1]->(t=ToString)/@Range[0,9]];u[(u=StringReplace)[#2,r]//ToExpression//Round//t,Reverse/@r])&

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

MannyC
источник
0

Lua , 162 151 150 байт

  • -11 байт благодаря моей идее использовать loadвместоfunction(...) end
  • -1 байт, пропуская перевод строки
l,p=...print(((math.ceil(load('return '..p:gsub('.',load'n=l:find(...,1,1)return n and n-1'))()-0.5)..''):gsub('%d',load'c=...+1 return l:sub(c,c)')))

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

Не самая короткая вещь в мире (Lua заставляет вас сильно увлекаться, особенно огромными ключевыми словами), но создавать было довольно весело. Полная программа, принимающая входные данные в качестве аргументов и результат печати.

объяснение

Вступление

l,p=...

Присвойте значения из аргументов переменным. Наш словарь есть lи выражение есть p.

Следующее выражение довольно сложно понять, потому что оно имеет странный порядок выполнения, поэтому я объясню это шаг за шагом:

Преобразование в нормальные числа

p:gsub('.',
load'n=l:find(...,1,1)return n and n-1')

Выполните замену в строке выражения: возьмите каждый символ и передайте его функции ( loadдоказано, что она закорочена, чем обычное объявление).

Функция находит позицию вхождения в строке dict для использования переданного символа find. ...это первый (и единственный) аргумент здесь, поскольку мы находимся в функции vaarg (любой loaded), который является нашим текущим символом. Следующие аргументы необходимы, чтобы сделатьfind игнорирования специальных символов ( 1это просто короткое значение, которое оценивается как trueпри преобразовании в логическое значение): начальная позиция (здесь по умолчанию один) и plain, которая фактически отключает обработку паттернов. Без этих программ происходит сбой в третьем тестовом случае из-за того, %что он особенный.

Если совпадение найдено, вычтите единицу, поскольку строки Lua (и, кстати, массивы) основаны на 1. Если совпадение не найдено, оно ничего не вернет, в результате чего замена не будет сделана.

решение

math.ceil(load('return '..ABOVE)()-0.5)

Prepend return к нашему выражению, чтобы позволить ему вернуть результат, вычислите его, скомпилировав как функцию Lua и вызвав его, выполните округление ( это перевернулось наоборот, чтобы сделать его короче).

В конце мы получаем численное решение нашей проблемы, остается только преобразовать ее обратно.

Снова схожу с ума

(ABOVE..'')
:gsub('%d',load'c=...+1 return l:sub(c,c)')

Первая строка - это короткий способ преобразования числа в строку, поэтому теперь мы можем вызывать строковые методы коротким способом. Давай сделаем так!

Теперь gsubснова вызывается, чтобы заменить все обратно в безумие. Это время %dиспользуется вместо .шаблона замены, поскольку наша функция может и должна обрабатывать только числа ( .это приведет к ошибке на отрицательных числах). Эта функция времени ( loadснова для сохранения байтов) сначала добавляет1 редактируемая к своему первому (и единственному) аргументу, преобразовывая его в позицию в строке dict, а затем возвращает символ из этой позиции.

Ура, почти нет!

Драматический финал, или Почему брекеты имеют значение

print((ABOVE))

Ну ... зачем две пары скобок? Пришло время поговорить о паралле ... эх, многократном возвращении в Луа. Дело в том, что одна функция может возвращать несколько значений из одного вызова (посмотрите на этот мета-вопрос для большего количества примеров).

Здесь last gsubвернул два значения: нужную нам строку ответа и количество выполненных замен (на самом деле количество цифр, но кого это волнует). Если бы не внутренняя пара, то были бы напечатаны и строка, и число, что напортачило. Таким образом, здесь мы жертвуем двумя байтами, чтобы опустить второй результат и, наконец, напечатать продукт этой безумной фабрики.


Ну, я с удовольствием объяснял почти столько же, сколько игра в гольф, надеюсь, вы поняли, что здесь происходит.

Валь говорит восстановить Монику
источник
Примечание: он проходит все тестовые случаи, но, вероятно, неправильно округляется в других. Если вы можете найти один, я собираюсь это исправить.
Вэл говорит восстановить Монику