Calculadora Gematria Generalizada

11

Cree una calculadora bidireccional Gematria, para cualquier secuencia dada de caracteres Unicode como el alfabeto.

Gematri-Qué?

Gematria es un sistema de asignación de valores numéricos a símbolos, desarrollado por antiguos griegos y adoptado por antiguos judíos. Es similar a ASCII o Unicode, es simplemente no lineal ... Consulte la siguiente tabla (la tabla completa está disponible en el enlace de arriba):

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

           ...

Los nombres de las letras no son importantes, solo su índice en la "matriz" del alfabeto y el valor numérico respectivo. El alfabeto hebreo solo tiene 22 letras (sin incluir letras "finales"), por lo que el valor máximo disponible es 400.

Si tomamos prestado este sistema al alfabeto inglés (AZ), terminaremos con A = 1, B = 2 ... L = 30 ... U = 300 ... Z = 800.

Dos cosas que necesitamos saber.

  1. Una de las características más importantes de este sistema es calcular el "Valor Gematria" de una palabra , resumiendo los valores de sus letras. (Algunos dicen que existe una conexión mística entre palabras o frases (cuando el valor del espacio es cero), que comparten el mismo valor de Gematria).

  2. Cualquier número entero no negativo se puede representar en símbolos. Por ejemplo (y quedémonos con el alfabeto inglés por ahora) el valor de 32 es LB (L = 30 + B = 2). El valor de 1024 es ZTKD (800 + 200 + 20 + 4. Tenga en cuenta que ZSSKD también es 1024, pero eso no es una representación legal, ya que se puede compactar).

El reto

Escriba un programa / una función / un fragmento de código en su idioma de elección, que primero se configura con un alfabeto (consulte la API a continuación) y luego acepte un argumento. Ese argumento puede ser un entero, o una palabra / frase. Si es un número entero, su programa debería generar / devolver su representación en los símbolos del alfabeto, el más compactado (consulte (2) más arriba). Si es una palabra o una frase, su programa debería generar / devolver el valor de Gematria (sumando los valores de los símbolos, sin contar espacios en blanco, consulte (1) más arriba).

API

Su programa / función debe aceptar 3 argumentos. Puede obtenerlos de STDIN, o como argumentos de función, incluso puede suponer que son variables que se inicializaron programáticamente antes de la invocación de su función.

  • Primer argumento: el primer carácter (en Unicode) del alfabeto.
  • Segundo argumento: el último carácter (en Unicode) del alfabeto.
  • Tercer argumento: un número entero, que se representará en símbolos, O una frase creada por el alfabeto dado.

Valor de salida / retorno: Dependiendo del tercer argumento, como se explicó anteriormente.

Supuestos

  • Los dos primeros argumentos siempre tendrán un carácter de longitud cada uno, y el segundo siempre será mejor que el primero.
  • La secuencia (primero hasta el último, inclusive) nunca incluirá ninguno de los valores 30-39 (que representan los dígitos 0-9), de lo contrario hará que el tercer argumento sea ambiguo. EDITAR: no contendrá espacio también, ya que en las frases los espacios se cuentan como ceros.
  • El tercer argumento, en caso de que sea una frase, solo puede contener espacios y letras del alfabeto dado. La cadena vacía no es una entrada válida (puede suponer que no está vacía). En caso de que sea un entero, puede asumir que es un entero positivo.

Ejemplos

Input                Output

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

Puntuación

Score = upvotes - length/100.0

Su código debe ser breve, pero lo más importante, popular. Los puntajes negativos también pueden acompañar. El ganador será la respuesta con el puntaje más alto en una semana a partir de ahora, 29/11/2014 19:20:00 UTC.

Jacob
fuente
Volví a plantear su pregunta al desafío general del código, ya que creo que la puntuación es lo suficientemente diferente del código de golf o de un concurso de popularidad estándar.
Martin Ender
Okay. Eso es un montón de etiquetas :) gracias.
Jacob
¿Qué es el espacio en sí está incluido en la lista de inclusión creada por los dos primeros caracteres?
Optimizador
Además, ¿qué quieres decir con la segunda suposición? El código ASCII para 0 no es 30.
Optimizador
1
@proudhaskeller, este es un error común ya que aprendes en el jardín de infantes "peh tsady kuf resh", que suena como tsadik kuf ... Puedes confirmar esto con la Academia de Hebreos.
Jacob

Respuestas:

4

CJam, 80 75 70 bytes, votos a favor - 0.7

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

Pruébalo aquí.

Este es un programa completo, que toma información de STDIN e imprime el resultado en STDOUT.

No estoy realmente seguro de cómo se supone que voy a ganar popularidad aquí, así que simplemente estoy jugando al golf, con la esperanza de obtener un tamaño de código razonablemente impresionante. ;)

Creo que la conversión de int a string todavía se puede mejorar, pero no la veo en este momento.

Gracias a Optimizer por recordarme sobre la intersección establecida y que las matrices vacías son falsas.

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

En el segundo caso, el resultado se deja en la pila, que se imprime automáticamente al final del programa.

Martin Ender
fuente
5

Java 7, Puntuación = Votos a favor - 3.97

¡¡¡Hurra!!! ¡¡¡Java!!! El idioma de golf favorito del mundo en el mundo. ¿Qué, realmente puedes jugar al golf en Java? Bueno, es como usar una excavadora para putt.

ase espera que contenga el primer caracter. bse espera que contenga el último caracter. cse espera que tenga la cadena de entrada.

Aquí está la función de golf:

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

Aquí está sangrado con código de estructura:

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

Aquí está completamente expandido:

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

        }
    }
}
El numero uno
fuente
2

APL (votos a favor - 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}⍵}

Esta es una función que toma los dos caracteres a la izquierda y el argumento a convertir a la derecha:

      '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

Versión sin golf:

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
fuente
2

Haskell, 188 bytes; Votos a favor - 1.88

Este es un programa completo de STDIN a STDOUT, muy golfizado. EDITAR: ¡Ahora en menos de 200 bytes! EDIT2: guardado un byte con la sugerencia de @ proudhaskeller.

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

Construye la lista infinita de valores x = [1,2,3,4,5,6,7,8,9,10,20,30,..]en la primera línea y realiza E / S en la tercera línea. El valor de una letra c, dado el rango [a..b], es entonces el valor en la posición length [a..c] - 1de x. En la segunda línea, nos ramificamos en la primera letra udel tercer argumento, y sumamos sus valores de gematria (si uno es un dígito), o construimos codiciosamente una palabra con el valor dado (si ues un dígito).

Versión sin golf con nombres de variables más legibles:

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
fuente
puede eliminar la {}cláusula where para obtener una ganancia de un byte
orgulloso haskeller el
1

CJam, 70 bytes, #Votos a favor - 0.7

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

Esto supone que se pasará una entrada válida. Toma información de STDIN como dice la especificación API e imprime el resultado en STDOUT.

Ejemplos:

Input                Output

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

Pruébalo en línea aquí

Explicación sabia del bloque :

{{_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."
Optimizador
fuente