Обобщенный калькулятор гематрии


11

Создайте двунаправленный калькулятор Gematria для любой заданной последовательности символов Юникода в качестве алфавита.

Gematri-Что?

Гематрия - это система присвоения числовых значений символам, разработанная древними греками и принятая древними евреями. Это похоже на ASCII или Unicode, это просто нелинейно ... См. Следующую таблицу (полная таблица доступна по ссылке выше):

Index     Letter   Letter name  Value
--------------------------
  0         א         "Alef"     1
  1         ב         "Bet"      2

           ...

  8         ט         "Tet"      9
  9         י         "Yud"      10
 10         כ         "Kaf"      20

           ...

 17         צ        "Tsady"     90
 18         '        "Kuf"       100
 19         ר        "Resh"      200

           ...

Названия букв не важны, только их индекс в «массиве» алфавита и соответствующее числовое значение. Еврейский алфавит состоит только из 22 букв (не считая «последних» букв), поэтому максимально доступное значение составляет 400.

Если мы заимствуем эту систему для английского алфавита (AZ), мы получим A = 1, B = 2 ... L = 30 ... U = 300 ... Z = 800.

Две вещи, которые мы должны знать.

  1. Одной из наиболее важных функций в этой системе является вычисление «значения гематрии» слова путем суммирования значений его букв. (Некоторые говорят, что между словами или фразами существует мистическая связь (когда значение пробела равно нулю), которые имеют одинаковое значение Гематрии).

  2. Любое неотрицательное целое число может быть представлено в символах. Например (и давайте пока остановимся на английском алфавите), значение 32 - это LB (L = 30 + B = 2). Значение 1024 - это ZTKD (800 + 200 + 20 + 4. Обратите внимание, что ZSSKD также является 1024, но это не является юридическим представлением, поскольку оно может быть сжато).

Соревнование

Напишите программу / функцию / фрагмент кода на выбранном вами языке, который сначала настраивается с помощью алфавита (см. API ниже), а затем принимает аргумент. Этим аргументом может быть целое число или слово / фраза. Если это целое число - ваша программа должна вывести / вернуть свое представление в символах алфавита - наиболее компактное (см. (2) выше). Если это слово или фраза, ваша программа должна вывести / вернуть значение Gematria (суммируя значения символов, не считая пробелы, см. (1) выше).

API

Ваша программа / функция должна принимать 3 аргумента. Вы можете получить их из STDIN или в качестве аргументов функции, вы даже можете предположить, что они являются переменными, которые программно инициализируются до вызова вашей функции.

  • Первый аргумент - первый символ (в Unicode) алфавита.
  • Второй аргумент - последний символ (в Юникоде) алфавита.
  • Третий аргумент - целое число, представляемое в символах, ИЛИ фраза, созданная данным алфавитом.

Выходное / возвращаемое значение: в зависимости от третьего аргумента, как описано выше.

Предположения

  • Первые два аргумента всегда будут иметь длину один символ, а второй всегда будет больше первого.
  • Последовательность (от первого до последнего включительно) никогда не будет включать ни одно из значений 30-39 (которые представляют цифры 0-9), в противном случае третий аргумент будет неоднозначным. РЕДАКТИРОВАТЬ: он также не будет содержать пробел, так как во фразах пробелы считаются нулями.
  • Третий аргумент, если это фраза, может содержать только пробелы и буквы данного алфавита. Пустая строка не является допустимым вводом (можно предположить, что он не пустой). Если это целое число, вы можете предположить, что это положительное целое число.

Примеры

Input                Output

A Z CODE GOLF        175
a s 512              sssssjb
A B 7                BBBA
≐ ⊐ ≤≫ ≥            1700

счет

Score = upvotes - length/100.0

Ваш код должен быть коротким, но, что более важно, популярным. Отрицательные оценки также могут играть вместе. Победителем станет ответ с наибольшим количеством очков через неделю, 2014-11-29 19:20:00 UTC.


Я переназначил ваш вопрос на всеохватывающий вызов кода, так как думаю, что выигрыш достаточно сильно отличается от кода гольфа или стандартного конкурса популярности.
Мартин Эндер

Хорошо. Это много тегов :) спасибо.
Джейкоб

Какое пространство само включено в список включения, созданный первыми двумя символами?
Оптимизатор

Кроме того, что вы подразумеваете под вторым предположением? Код ASCII для 0 не 30.
Оптимизатор

1
@proudhaskeller, это распространенная ошибка, так как вы учитесь в детском саду "пех цади куф реш", который звучит как цадик куф ... Вы можете подтвердить это в Академии иврита.
Джейкоб

Ответы:


4

CJam, 80 75 70 байт, Upvotes - 0,7

Arc:Irc\-):N,f#{9,:)f*~}%N<lS-_A,s&{i{1${1$)<},)\,I+o-}h;;}{If-\f=:+}?

Проверьте это здесь.

Это полная программа, которая принимает входные данные из STDIN и печатает результат в STDOUT.

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

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

Спасибо оптимизатору за напоминание о пересечении множества и о том, что пустые массивы ложные.

A                                   "Push integer 10.";
 rc:I                               "Read token, convert to character, save in I.";
     rc                             "Read token, convert to character.";
       \-)                          "Swap, subtract, increment.";
          :N                        "Store number of characters in N.";
            ,                       "Turn into range [0 1 2 ... N-1].";
             f#                     "Map 10^i onto that range.";
               {       }%           "Map this block onto the powers of 10.";
                9,                  "Create range [0 1 2 ... 8].";
                  :)                "Increment each element.";
                    f*              "Multiply each by the current power of 10.";
                      ~             "Unwrap/dump the resulting array.";
                                    "Now we've got the values of the first 9N digits.";
                         N<         "That's too much, so truncate to the first N.";
                           l        "Read the rest of the line.";
                            S-      "Remove spaces.";
                              _     "Duplicate string and get first character.";
                               A,   "Create range [0 1 2 ... 9].";
                                 s  "Turn into string '0123456789'.";
                                  & "Intersection of characters.";

{                      }{        }? "If/else depending on whether the result is empty.";
                                    "If it was a digit...";
 i                                  "Convert string to integer.";
  {                }h               "While that integer isn't zero...";
   1$                               "Copy digit values.";
     {    },                        "Filter digit values.";
      1$                            "Copy remaining integer.";
        )<                          "Increment, compare.";
                                    "This discards values greater than the integer.";
            )\                      "Slice off last digit value, and swap with list.";
              ,I+                   "Get length of list and add to I.";
                 o                  "Print character.";
                  -                 "Subtract digit value from integer.";
                     ;;             "Empty stack.";
                                    "If the string was not a number...";
                         I          "Push initial character.";
                          f-        "Subtract it from each character in string.";
                            \       "Swap differences and digit values.";
                             f=     "Use differences to index into the values.";
                               :+   "Sum up all the values.";

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


5

Java 7, Оценка = Upvotes - 3,97

Ура!!! Ява!!! Самый любимый в мире язык игры в гольф. Что, вы можете играть в гольф в Java ??? Ну, это похоже на использование бульдозера для удара.

aкак ожидается, будет содержать первый символ. bкак ожидается, будет содержать последний символ. cкак ожидается, будет иметь входную строку.

Вот функция гольфа:

int d=0;try{d=Integer.parseInt(c);}catch(Exception e){}int l=b-a+1;char[]f=new char[l];int[]g=new int[l];int h=1;int i=1;g[0]=1;f[0]=a;int j;for(j=1;j<b-a+1;){g[j]=(h+=i);f[j]=(char)(f[j++-1]+1);i*=h==10*i?10:1;}if(d==0){h=0;for(char k:c.toCharArray()){for(j=0;j<l;j++){if(f[j]==k){h+=g[j];}}}System.out.println(h);}else{c="";for(j=l;j>0;){if(g[--j]<=d){c+=f[j];d-=g[j++];}}System.out.println(c);}

Здесь он имеет структурный код:

public class G{

    public static void main(String[] args){
        new G(args);
    }

    public G(String[] args){
        a = args[0].charAt(0);
        b = args[1].charAt(0);
        for (int i = 2; i < args.length; i++){
            c += args[i];
        }
        function();
    }

    char a;

    char b;

    String c = "";

    void function(){
        int d=0;
        try{
            d=Integer.parseInt(c);
        }catch(Exception e){}
        int l=b-a+1;
        char[]f=new char[l];
        int[]g=new int[l];
        int h=1;
        int i=1;
        g[0]=1;
        f[0]=a;
        int j;
        for(j=1;j<b-a+1;){
            g[j]=(h+=i);
            f[j]=(char)(f[j++-1]+1);
            i*=h==10*i?10:1;
        }
        if(d==0){
            h=0;
            for(char k:c.toCharArray()){
                for(j=0;j<l;j++){
                    if(f[j]==k){
                        h+=g[j];
                    }
                }
            }
            System.out.println(h);
        }else{
            c="";
            for(j=l;j>0;){
                if(g[--j]<=d){
                    c+=f[j];
                    d-=g[j++];
                }
            }
            System.out.println(c);
        }
    }
}

Здесь это полностью расширено:

public class Generator{

    public static void main(String[] args){
        beginning = args[0].charAt(0);
        end = args[1].charAt(0);
        for (int i = 2; i < args.length; i++){
            phrase += args[i];
        }
        function();
    }

    static char beginning;

    static char end;

    static String phrase = "";

    static void function(){
        int convertTo = 0;
        try{
             convertTo = Integer.parseInt(phrase);
        } catch (Exception e){}
        char[] alphabet = new char[end - beginning + 1];
        int[] values = new int[alphabet.length];
        int value = 1;
        int base = 1;
        values[0] = 1;
        alphabet[0] = beginning;
        int i;
        for (i = 1; i < values.length;){
            values[i] = (value += base);
            alphabet[i] = (char)(alphabet[i++-1]+1);
            base*=value==10*base?10:1;
        }
        if(convertTo==0){
            value = 0;
            for (char character : phrase.toCharArray()){
                for (i = 0; i < alphabet.length;i++){
                    if (alphabet[i] == character){
                        value += values[i];
                    }
                }
            }
            System.out.println(value);


        } else {
            phrase = "";
            for (i = values.length;i > 0;){
                if (values[--i] <= convertTo){
                    phrase += alphabet[i];
                    convertTo -= values[i++];
                }
            }
            System.out.println(phrase);

        }
    }
}

2

APL (upvotes - 1.05)

{U←⎕UCS⋄A←V↑∊(10*0,⍳⌊9÷⍨V←1+|-/U⍺)∘.×⍳9⋄⍬≢0↑⍵:+/A[1+(U⍵~' ')-U⊃⍺]⋄U(U⊃⍺)+{⍵≤0:⍬⋄(¯1+A⍳T),∇⍵-T←⊃⌽A/⍨⍵≥A}⍵}

Это функция, которая принимает два символа слева и аргумент для преобразования справа:

      'A' 'Z'{U←⎕UCS⋄A←V↑∊(10*0,⍳⌊9÷⍨V←1+|-/U⍺)∘.×⍳9⋄⍬≢0↑⍵:+/A[1+(U⍵~' ')-U⊃⍺]⋄U(U⊃⍺)+{⍵≤0:⍬⋄(¯1+A⍳T),∇⍵-T←⊃⌽A/⍨⍵≥A}⍵}'CODE GOLF'
175
      gematria←{U←⎕UCS⋄A←V↑∊(10*0,⍳⌊9÷⍨V←1+|-/U⍺)∘.×⍳9⋄⍬≢0↑⍵:+/A[1+(U⍵~' ')-U⊃⍺]⋄U(U⊃⍺)+{⍵≤0:⍬⋄(¯1+A⍳T),∇⍵-T←⊃⌽A/⍨⍵≥A}⍵}
      'A' 'Z' gematria 'CODE GOLF'
175
      'a' 's' gematria 512
sssssjb
      'A' 'B' gematria 7
BBBA
      '≐' '⊐' gematria '≤≫ ≥'
1700

Безголовая версия:

gematria←{
   ⍝ get Unicode values for characters
   first last←⎕UCS¨⍺
   amount←1+last-first
   ⍝ find the value for each character in the alphabet
   alphabet←amount↑∊(10*0,⍳⌊amount÷9)∘.×⍳9

   ⍝ right arg is string: calculate number
   ⍬≢0↑⍵: +/ alphabet[1+(⎕UCS ⍵~' ')-first]

   ⍝ otherwise, right arg is number: find string
   ⎕UCS first+{
      ⍝ number ≤ 0? empty string
      ⍵≤0:⍬

      ⍝ find highest value we can subtract
      val←⊃⌽(⍵≥alphabet)/alphabet

      ⍝ return it, followed by the conversion of the rest of the number
      (¯1+alphabet⍳val), ∇⍵-val
   }⍵
}

2

Haskell, 188 байт; Upvotes - 1,88

Это полномасштабная программа STDIN-to-STDOUT, в значительной степени играющая в гольф. РЕДАКТИРОВАТЬ: Теперь менее 200 байтов! РЕДАКТИРОВАТЬ 2: Сохраненный один байт с предложением @roudhaskeller.

x=[1..9]++map(*10)x
f(a:_:b:_:z@(u:_))|u>'/'&&u<':'=w$read z|1<2=show.sum$map v z where v ' '=0;v c=x!!(length[a..c]-1);w 0="";w n=(\c->c:w(n-v c))$last[d|d<-[a..b],v d<=n]
main=interact$f

Он x = [1,2,3,4,5,6,7,8,9,10,20,30,..]создает бесконечный список значений в первой строке и ввод / вывод в третьей строке. Значение письма c, учитывая диапазон [a..b], тогда значение в положении length [a..c] - 1от x. Во второй строке мы разветвляемся на первую букву uтретьего аргумента и либо суммируем его значения гематрии (если uэто не цифра), либо жадно строим слово с заданным значением (если uэто цифра).

Неуправляемая версия с более читаемыми именами переменных:

values = [1..9] ++ map (*10) values
f (low:_:high:_:rest@(first:_))
  | first > '/' && first < ':' = construct $ read rest
  | otherwise                  = show . sum $ map value rest
  where value ' '   = 0
        value c     = values !! (length [low..c] - 1)
        construct 0 = ""
        construct n = (\c -> c : construct (n - value c)) $
                      last [d | d <- [low..high], value d <= n]
main = interact $ f

Вы можете удалить {}предложение where для однобайтового усиления
гордый haskeller

1

CJam, 70 байтов, #Upvotes - 0,7

{{_9%)A@9/#*}%}:M;rcrc),\i>:QlS-_@&{Qf#M:+}{i{Q,,M{1$)<},)Q@,=@@-}h;}?

Это предполагает, что допустимый ввод будет передан. Принимает ввод из STDIN, как сказано в спецификации API, и выводит результат в STDOUT.

Примеры:

Input                Output

A Z CODE GOLF        175
a s 512              sssssjb
A B 7                BBBA
≐ ⊐ ≤≫ ≥            1700

Попробуйте онлайн здесь

Блок мудрое объяснение :

{{_9%)A@9/#*}%}:M;
{             }:M;              "Define a function M which takes an input array of"
                                "indeces and calculates the Gematri number for them";
 {          }%                  "Run this code block for each element of the array";
  _9%)                          "Copy the number, take modulus by 9 and increment it";
      A@                        "Put 10 on stack, and rotate to get the number on top";
        9/                      "Integer divide the number by 9";
          #                     "Calculate 10 to the power the above quotient";
           *                    "Multiply the above result by modulus 9";

rcrc),\i>:QlS-_@&
rcrc                            "Read the first two characters, representing the lower"
                                "and upper end of the character list";
    ),                          "Increment the upper end and get a list of U to ASCII 0"
                                "characters where U is the upper limit";
      \i                        "Swap and convert the lower limit to its ASCII number";
        >:Q                     "Slice the character list to get our desired character"
                                "list range and store it in Q";
           lS-                  "Read the rest of the line as string and remove spaces";
              _@&               "Take a copy, get Q on top of stack and take"
                                "intersection with the input string. If the resulting"
                                "string is empty, then the third input was a number";
                 {...}{...}?    "First code block is for string input and second for"
                                "number input based on the above intersected string";

{Qf#M:+}
 Qf#                            "For each character of input string, calculate its"
                                "position in Q";
    M                           "Get the Gematri numbers for these inceces";
     :+                         "Sum them all to get the final Gematri number for the"
                                "input string"

{i{Q,,M{1$)<},)Q@,=@@-}h;}
 i                              "Convert the input number string to integer";
  {                   }h        "Run the code block till we get 0 on top of stack";
   Q,,M                         "Get the first length(Q) Gematri numbers";
       {1$)<},                  "Filter and take only which are less than input number";
              )                 "Pop the last number from the filtered array. This is"
                                "The maximum Gematri number that can be deducted";
               Q@               "Put Q on stack and rotate the remaining filtered array"
                                "to top of stack";
                 ,              "Calculate the length of that array, which is also the"
                                "index of the Gematri number used.";
                  =             "Get the corresponding character to that Gematri number";
                   @@-          "Put the number and Gematri number on top and subtract."
                                "The next loop runs on the above result now";
                        ;       "Pop the resedual 0 from stack. The remaining stack now"
                                "contains just the Gematri characters."
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.