Игра в гольф каждого персонажа ASCII в 99

11

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

В 99 вы можете печатать отдельные символы ASCII на стандартный вывод, но из-за ограничений языка не всегда понятно, как печатать конкретный символ настолько кратко, насколько это возможно.

Для каждого из 128 символов ASCII напишите программу 99, которая не требует ввода и выводит этот единственный символ. Вы можете написать любой или все эти ответы вручную или написать другую программу (на любом языке, которая вам нравится), чтобы сгенерировать их для вас.

Сумма символов в каждой из ваших 128 99 программ - это ваш счет. Самый низкий балл побеждает. Новые строки считаются одним символом.

Помните, что в 99 только переменные четного размера, такие как 9999выходные символы ASCII (переменные нечетного размера, выдают целые числа). Их значение делится на 9, а затем принимается mod 128, поэтому значения не обязательно должны находиться в определенном диапазоне для отображения в символы ASCII. Например, все внутренние значения 297, 1449 и -855 соответствуют символу, !потому что, когда они разделены на 9 и взяты по модулю 128, все они становятся 33, что является кодом символа для !.

Если вам нужен переводчик для 99 , я бы предложил ответ Mac на Python .

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

Кальвин Хобби
источник

Ответы:

7

Одно задание, 2075 (оптимально)

Это должно быть оптимальным значением (если только у меня нет большой ошибки в рассуждениях или мое тестирование отстой).

Прежде всего. Есть только 7 различных чисел (мод 128), которые вы можете выразить в 99. Все значения 7 или более 9 оцениваются в одно и то же число 71. (Потому что 10 ^ 8 мод 128 == 0, 10 ^ 9 мод 128 == 0, ...)

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

В противном случае я пытаюсь достичь числа одним оператором присваивания (назначить 99) и вывести 99. Как оказалось, максимальный размер программы при таком подходе составляет 22 символа. Очевидно, что использование Goto требует определенно большего. Единственная возможность, что решение с одним назначением может быть побеждено, является решением с двумя назначениями. Я проверил это (надеюсь, без ошибок, код для этого довольно грязный), и не нашел решения для любого символа ASCII.

Поэтому для нахождения оптимального решения должно быть достаточно только проверки четырех прямых чисел и подхода с одним присваиванием. Следующая программа на Python (совместимая с 2 и 3) генерирует все программы и суммирует их длины. Он использует простой подход 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))

Выход имеет следующую форму:

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

Вы можете найти полный вывод по адресу: http://pastebin.com/bKXLAArq

Символ с самой короткой программой (2 символа) имеет vertical tab - 11длину программы 2, символы с самыми длинными программами (22 символа) bell - 7и A - 65.

Сумма по всем программам 2075.

И, кстати, я использовал интерпретатор k / q от tmartin . У меня довольно много проблем с другими (Python, Perl, CJam). Не уверен, что это была моя вина.

Jakube
источник
Это помогло бы разработчикам интерпретаторов, если бы вы могли описать, какие у вас проблемы. Отличный ответ.
coredump
3

Разнообразие техник, 42109

Для чисел вместо вычисления большого символа ASCII я просто вычислил значение числа. Вы только сказали, что можете выводить персонажа, так что это все равно должно работать.

РЕДАКТИРОВАТЬ: переключил числа, чтобы использовать символы ASCII, так что не обращайте на это внимания. Я оставил исходный числовой код в коде Java, но закомментировал на тот случай, если кто-то захочет его использовать.

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

Они состоят из 1-4 строк каждая, поэтому их довольно просто скопировать и вставить в программу. Следует отметить, что они не работают последовательно из-за того, что мой сгенерированный код не сохраняет состояния переменных.

Наиболее распространенный метод, используемый здесь, был таким же, как подход orlp:

Продолжайте вычитать 9 из 99, затем выведите.

Моя версия отличается тем, что использует некоторые пользовательские кейсы и много математики в одну строку. Пользовательские случаи - это когда персонаж может быть представлен всего лишь группой из 9, и никакой математический или мой код генерации не может быть сокращен.

программы

Я поместил вывод на Pastebin для тех из вас, кто не хочет запускать программу:

http://pastebin.com/Cs6WZUfb

Код Java, который я использовал:

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
источник
Вам действительно нужно вывести символ, а не только число. Таким образом, все программы 999в конце должны быть исправлены.
Увлечения Кэлвина
Ах, хорошо, тогда я исправлю это через мгновение.
Bloo
Должно быть исправлено сейчас, если я что-то пропустил. Я оставил исходный код, но закомментировал на тот случай, если кто-то захочет использовать такие цифры. Pastebin также был отредактирован.
bloo
Отлично. Хотя для некоторых я думаю , вы могли бы просто добавил 99 999\n99(переназначить 999на 99так он будет печатать как символ).
Увлечения Кельвина
1

Повторное вычитание, 65280

Тривиальное решение для сравнения. Продолжайте вычитать 9 из 99, затем выведите. Пример для символа ASCII 10:

99 99 9
99

Есть 128 программ. Первая программа длиной в два символа (99), каждая из которых на 8 символов (99 99 9 \ n) длиннее предыдущей.

Python-программа, генерирующая программы, разделенные пустыми строками и счетом вычислений:

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

print(score)
orlp
источник