Jugar golf a todos los personajes ASCII en 99

11

99 es un lenguaje de programación que inventé a principios de esta semana para mi desafío. Escribe un intérprete para 99 . (Inventado pero nunca necesitado implementarlo gracias a media docena de ustedes.;)) La especificación completa del idioma está en ese desafío, así que no me molesto en volver a publicar todo aquí.

En 99 puede imprimir caracteres ASCII individuales en stdout, pero debido a las restricciones del lenguaje, no siempre está claro cómo imprimir un carácter particular de la forma más concisa posible.

Para cada uno de los 128 caracteres ASCII, escriba un programa 99 que no ingrese y emita ese único carácter. Puede codificar cualquiera o todas estas respuestas a mano, o puede escribir otro programa (en el idioma que desee) para generarlas por usted.

La suma de los caracteres en cada uno de sus 128 99 programas es su puntaje. El puntaje más bajo gana. Las nuevas líneas cuentan como un personaje.

Recuerde, en 99 , solo las variables de tamaño par, como 9999los caracteres ASCII de salida (las variables de tamaño impar generan enteros). Su valor se divide entre 9 y luego se toma el mod 128, por lo que los valores no necesitan estar en un cierto rango para mapearse a caracteres ASCII. Por ejemplo, los valores internos 297, 1449 y -855 corresponden al carácter !porque cuando se dividen entre 9 y se toman el mod 128, todos se convierten en 33, que es el código de caracteres para !.

Si necesita un intérprete para 99 , sugeriría la respuesta Python de Mac .

que dije que mi próximo desafío sería más interactivo, pero todavía estoy trabajando en las cosas para ese.

Pasatiempos de Calvin
fuente

Respuestas:

7

Una tarea, 2075 (óptima)

Este debería ser el valor óptimo (a menos que tenga un gran error de razonamiento o mis pruebas sean una mierda).

Ante todo. Solo hay 7 números diferentes (mod 128) que puede expresar en 99. Todos los valores de 7 o más 9 se evalúan con el mismo número 71. (Porque 10 ^ 8 mod 128 == 0, 10 ^ 9 mod 128 == 0, ...)

Si puede expresar uno de los 4 valores con un número par de nueves, entonces la salida de este número es claramente la solución óptima.

De lo contrario, trato de alcanzar el número con una declaración de asignación (asignar a 99) e imprimir 99. Como resultado, el tamaño máximo del programa con este enfoque es 22 caracteres. Claramente, usar Goto requiere definitivamente más que eso. La única posibilidad de que una solución de una tarea sea superada es una solución con dos tareas. Probé esto (con suerte sin errores, el código para esto es bastante desordenado), y no encontré ninguna solución para ningún carácter ASCII.

Por lo tanto, solo verificar los 4 números directos y el enfoque de una asignación debería ser suficiente para encontrar la solución óptima. El siguiente programa Python (compatible con 2 y 3) genera todos los programas y resume sus longitudes. Utiliza un enfoque simple IDA *.

from itertools import count

def nines_to_dec(nines):
    return ((10**nines - 1) // 9) % 128

def shortest_representation(ascii_value):
    # try simple output,
    # max code length is 8, (8 nines == 10 nines == 12 nines == ...)
    # if this works, than this is the shortest representation

    for nines in range(2, 9, 2):
        if nines_to_dec(nines) == ascii_value:
            return "9" * nines

    # otherwise try one assignment
    for length in count(1):
        result = assignment(ascii_value, length, [])
        if result:
            return "99 " + result + "\n99"

def assignment(value, left, nines_list):
    if left == 0:
        eval_numbers = [nines_to_dec(nines) for nines in nines_list]

        if (sum(eval_numbers[::2]) - sum(eval_numbers[1::2])) % 128 == value:
            return " ".join("9" * nines for nines in nines_list)
        else:
            return False

    for nines in range(1, 8):
        left2 = left - nines - 1 # -1 for space
        if left2 >= 0:
            result = assignment(value, left2, nines_list + [nines])
            if result:
                return result

    return False

lengths = []
for i in range(128):
    program =shortest_representation(i)
    lengths.append(len(program))
    print("ASCII-value: {}, ASCII-char: {}".format(i, chr(i)))
    print(program)

print(sorted(lengths))
print(sum(lengths))

El resultado es de la siguiente forma:

....
ASCII-value: 65, ASCII-char: A
99 9 999999 9999999
99
ASCII-value: 66, ASCII-char: B
99 9 99 9999 99
99
ASCII-value: 67, ASCII-char: C
99 9 99 9 99 9999
99
....

Puede encontrar la salida completa en: http://pastebin.com/bKXLAArq

El carácter con el programa más corto (2 caracteres) tiene vertical tab - 11una duración de programa de 2, los caracteres con los programas más largos (22 caracteres) son bell - 7y A - 65.

La suma de todos los programas es 2075.

Y, por cierto, utilicé el intérprete k / q de tmartin . Tengo bastantes problemas con los otros (Python, Perl, CJam). No estoy seguro si fue mi culpa.

Jakube
fuente
Ayudaría a los implementadores de intérpretes si pudiera describir los problemas que tuvo. Gran respuesta.
coredump
3

Una variedad de técnicas, 42109

Para los números, en lugar de calcular el carácter ASCII grande, acabo de calcular el valor del número. Solo dijiste que podía generar el personaje, por lo que esto debería funcionar.

EDITAR: Cambió los números para usar los caracteres ASCII, así que no lo tenga en cuenta. Dejé el código del número original en el código de Java pero comenté en caso de que alguien quisiera usarlo.

Algunos de estos los hice a mano, la mayoría simplemente escribí un programa para escribir.

Estos se componen de 1-4 líneas cada uno, por lo que son bastante fáciles de copiar y pegar en un programa. Cabe señalar que no funcionan en sucesión debido a que mi código generado no conserva los estados variables.

La técnica más común utilizada aquí fue la misma que el enfoque de orlp:

Sigue restando 9 de 99, luego salida.

Mi versión difiere usando algunos casos personalizados y componiendo muchas de las matemáticas en una sola línea. Los casos personalizados son solo donde el personaje se puede representar con solo un grupo de 9 y no se pueden acortar las matemáticas o el código de mi generación.

Programas

Puse el resultado en Pastebin para aquellos de ustedes que no tienen ganas de ejecutar el programa:

http://pastebin.com/Cs6WZUfb

Código Java que utilicé:

public class AsciiGen99 {

  public static void main(String[] args) {
    long totalsize = 0;
    for (int i = 0; i < 128; i++) {
      System.out.println("\n The program for ASCII code " + i + " is as follows:\n");
      String yea = find(i);
      if (yea != null) {
        System.out.println(yea);
        totalsize += yea.length();
      } else {
        String v = "99 9 9\n9 99 9";
        if (i != 0) {
          v += "\n99";
          for (int j = 0; j < i; j++) {
            v += " 99 9";
          }
        }

        v += "\n99";

        System.out.println(v);
        totalsize += v.length();
      }
    }
    System.out.println(totalsize);
  }

  public static String find(int i) {
    switch (i) {
      case '\0':
        return "99 9 9\n99";
      case '\1':
        return "99 9\n99";
    }
//    if (48 <= i && i <= 57) {
//      switch (i) {
//        case '0':
//          return "9 9 9\n9";
//        case '1':
//          return "9";
//        case '2':
//          return "999 9 9\n9 999 9\n999 999 9 999 9\n999";
//        case '3':
//          return "999 9 9\n9 999 9\n999 999 9 999 9 999 9\n999";
//        case '4':
//          return "999 9 9\n9 999 9\n999 999 9 999 9 999 9 999 9\n999";
//        case '5':
//          return "999 9 9\n9 999 9\n999 999 9 999 9 999 9 999 9 999 9\n999";
//        case '6':
//          return "99 9 9\n9 99 9\n999 99 9 99 9 99 9 99 9 99 9 99 9\n999";
//        case '7':
//          return "99 9 9\n9 99 9\n999 99 9 99 9 99 9 99 9 99 9 99 9 99 9\n999";
//        case '8':
//          return "99 9 9\n9 99 9\n999 99 9 99 9 99 9 99 9 99 9 99 9 99 9 99 9\n999";
//        case '9'://ironic
//          return "99 9 9\n9 99 9\n999 99 9 99 9 99 9 99 9 99 9 99 9 99 9 99 9 99 9\n999";
//      }
//    }
    int x, a;
    for (x = 0; x < 100000; x++) {
      a = i + 128 * x;
      String s = "" + a*9;
      if (containsOnly9(s) && (s.length() & 1) == 0) {
        return ("" + (a * 9));
      }
    }

    return null;
  }
  public static boolean containsOnly9(String s) {
    for (char c : s.toCharArray()) {
      if (c != '9' && c != ' ' && c != '\n' && c != '\r' && c != '\t') {
        return false;
      }
    }
    return true;
  }
}
bloo
fuente
En realidad, debe generar el carácter, no solo el número. Por lo tanto, todos los programas con 999al final deben repararse.
Calvin's Hobbies
Ah, está bien, lo arreglaré en un momento.
bloo
Debería arreglarse ahora a menos que me haya perdido algo. Dejé el código original pero comenté en caso de que alguien quisiera usar los números así. Pastebin también fue editado.
bloo
Excelente. Aunque para algunos creo que podría haber agregado 99 999\n99(para reasignar 999para 99que se imprima como un personaje).
Calvin's Hobbies
1

Resta repetida, 65280

Una solución trivial para comparar. Sigue restando 9 de 99, luego salida. Ejemplo para el carácter ASCII 10:

99 99 9
99

Hay 128 programas. El primer programa tiene dos caracteres de largo (99), cada uno después de eso es 8 caracteres (99 99 9 \ n) más largo que el anterior.

Programa de Python que genera programas separados por líneas vacías y puntaje informático:

score = 0
for n in range(128):
    program = "99 99 9\n" * n + "99"
    score += len(program)
    print(program + "\n")

print(score)
orlp
fuente