Uogólniony kalkulator Gematria

11

Utwórz dwukierunkowy kalkulator Gematria dla dowolnej sekwencji znaków Unicode jako alfabetu.

Gematri-Co?

Gematria to system przypisywania wartości liczbowych symbolom, opracowany przez starożytnych Greków i przyjęty przez starożytnych Żydów. Jest w pewien sposób podobny do ASCII lub Unicode, jest po prostu nieliniowy ... Zobacz następującą tabelę (pełna tabela jest dostępna w linku powyżej):

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

           ...

Nazwy liter nie są ważne, tylko ich indeks w „Tablicy” alfabetu i odpowiednia wartość liczbowa. Alfabet hebrajski ma tylko 22 litery (nie licząc liter „końcowych”), więc maksymalna dostępna wartość wynosi 400.

Jeśli pożyczymy ten system na alfabet angielski (AZ), otrzymamy A = 1, B = 2 ... L = 30 ... U = 300 ... Z = 800.

Dwie rzeczy, które musimy wiedzieć.

  1. Jedną z najważniejszych cech tego systemu jest obliczanie „wartości Gematrii” słowa poprzez sumowanie wartości liter. (Niektórzy twierdzą, że istnieje mistyczny związek między słowami lub frazami (gdy wartość przestrzeni wynosi zero) - które mają tę samą wartość Gematrii).

  2. Każda nieujemna liczba całkowita może być reprezentowana w symbolach. Na przykład (i na razie pozostańmy z alfabetem angielskim) wartość 32 to LB (L = 30 + B = 2). Wartość 1024 to ZTKD (800 + 200 + 20 + 4. Zauważ, że ZSSKD to również 1024, ale nie jest to prawna reprezentacja, ponieważ można ją kompaktować).

Wyzwanie

Napisz program / funkcję / fragment kodu w wybranym języku, który jest najpierw konfigurowany za pomocą alfabetu (patrz API poniżej), a następnie zaakceptuj argument. Argumentem tym może być liczba całkowita lub słowo / fraza. Jeśli jest to liczba całkowita - twój program powinien wypisywać / zwracać swoją reprezentację w symbolach alfabetu - najbardziej kompaktowy (patrz (2) powyżej). Jeśli jest to słowo lub fraza, twój program powinien wypisać / zwrócić wartość Gematria (sumując wartości symboli, nie licząc białych znaków, patrz (1) powyżej).

API

Twój program / funkcja powinna zaakceptować 3 argumenty. Możesz je pobrać ze STDIN, lub jako argumenty funkcji, możesz nawet założyć, że są to zmienne, które zostały zainicjowane programowo przed wywołaniem funkcji.

  • Pierwszy argument - pierwszy znak alfabetu (w Unicode).
  • Drugi argument - ostatni znak alfabetu (w Unicode).
  • Trzeci argument - Liczba całkowita, która ma być reprezentowana w symbolach, LUB fraza utworzona przez dany alfabet.

Wartość wyjściowa / zwracana: W zależności od trzeciego argumentu, jak wyjaśniono powyżej.

Założenia

  • Pierwsze dwa argumenty zawsze będą miały jeden znak, a drugi będzie zawsze większy niż pierwszy.
  • Sekwencja (od pierwszej do ostatniej włącznie) nigdy nie będzie zawierać żadnej z wartości 30–39 (które reprezentują cyfry 0–9), w przeciwnym razie trzeci argument będzie dwuznaczny. EDYCJA: Nie będzie również zawierać spacji, ponieważ w wyrażeniach spacje są liczone jako zera.
  • Trzeci argument, jeśli jest to fraza, może zawierać tylko spacje i litery danego alfabetu. Pusty ciąg nie jest prawidłowym wejściem (możesz założyć, że nie jest pusty). Jeśli jest to liczba całkowita, możesz założyć, że jest to liczba całkowita dodatnia.

Przykłady

Input                Output

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

Punktacja

Score = upvotes - length/100.0

Twój kod powinien być krótki, ale co ważniejsze, popularny. Negatywne wyniki mogą również grać razem. Zwycięzca otrzyma odpowiedź z najwyższym wynikiem od tygodnia, 2014-11-29 19:20:00 UTC.

Jakub
źródło
Przesunęłem ponownie pytanie na wyzwanie polegające na wyłapaniu wszystkich kodów, ponieważ moim zdaniem punktacja wystarczająco różni się od kodu golfowego lub standardowego konkursu popularności.
Martin Ender
Dobrze. To dużo tagów :) dzięki.
Jakub
Czym jest sama przestrzeń na liście dołączeń utworzonej przez pierwsze dwa znaki?
Optymalizator
Co rozumiesz przez drugie założenie? Kod ASCII dla 0 to nie 30.
Optymalizator
1
@proudhaskeller jest to powszechny błąd, ponieważ uczysz się w przedszkolu „peh tsady kuf resh”, co brzmi jak tsadik kuf ... Możesz to potwierdzić w Akademii Hebrajskiej.
Jacob

Odpowiedzi:

4

CJam, 80 75 70 bajtów, głosy poparcia - 0,7

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

Sprawdź to tutaj.

Jest to pełny program, który pobiera dane wejściowe ze STDIN i drukuje wynik do STDOUT.

Nie jestem do końca pewien, jak mam tutaj strzelać dla popularności, więc po prostu gram w golfa, mając nadzieję na uzyskanie imponująco imponującego rozmiaru kodu. ;)

Wierzę, że konwersję zamiany na ciąg znaków można jeszcze poprawić, ale nie widzę jej teraz.

Dzięki Optimizer za przypomnienie mi o ustawionym skrzyżowaniu i że puste tablice są fałszywe.

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.";

W drugim przypadku wynik pozostawia się na stosie, który jest drukowany automatycznie na końcu programu.

Martin Ender
źródło
5

Java 7, wynik = głosy poparcia - 3,97

Tak !!! Jawa!!! Ulubiony język golfa na świecie. Co, tak naprawdę możesz grać w golfa w java ??? Cóż, to trochę jak użycie buldożera do puttowania.

ama zawierać pierwszy znak. bma zawierać ostatni znak. coczekuje się, że będzie miał ciąg wejściowy.

Oto funkcja gry w golfa:

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

Tutaj jest wcięty kodem struktury:

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

Tutaj jest całkowicie rozwinięty:

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

        }
    }
}
Numer jeden
źródło
2

APL (głosy poparcia - 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}⍵}

Jest to funkcja, która pobiera dwa znaki po lewej stronie, a argument do konwersji po prawej:

      '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

Wersja bez golfa:

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
   }⍵
}
marinus
źródło
2

Haskell, 188 bajtów; Pozytywne opinie - 1,88

Jest to w pełni rozwinięty program STDIN-to-STDOUT, mocno golfowy. EDYCJA: Teraz poniżej 200 bajtów! EDYCJA 2: Zapisano jeden bajt z sugestią @ dumhaskeller.

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

Konstruuje nieskończoną listę wartości x = [1,2,3,4,5,6,7,8,9,10,20,30,..]w pierwszym wierszu i wykonuje operacje we / wy w trzecim wierszu. Wartość listu c, biorąc pod uwagę zakres [a..b], jest to wartość w pozycji length [a..c] - 1z x. W drugim wierszu rozgałęziamy się na pierwszej literze utrzeciego argumentu i albo sumujemy jego wartości gematrii (jeśli unie jest cyfrą), albo łapczywie konstruujemy słowo o podanej wartości (jeśli ujest cyfrą).

Wersja bez golfa z bardziej czytelnymi nazwami zmiennych:

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
Zgarb
źródło
możesz usunąć {}klauzulę where dla uzyskania jednobajtowego zysku
dumny haskeller
1

CJam, 70 bajtów, #Upvotes - 0,7

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

Zakłada się, że zostaną przekazane prawidłowe dane wejściowe. Pobiera dane wejściowe ze STDIN, jak mówi specyfikacja API i wypisuje wyniki do STDOUT.

Przykłady:

Input                Output

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

Wypróbuj online tutaj

Zablokuj mądre wyjaśnienie :

{{_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."
Optymalizator
źródło