打入99中的每个ASCII字符


11

99是我本周早些时候为挑战而发明的一种编程语言。为99写一个解释器。(发明了,但要感谢你们的六个人,才不需要实施。)

99中,您可以将单个ASCII字符打印到stdout,但是由于语言的限制,并非始终清楚如何尽可能简洁地打印特定字符。

对于128个ASCII字符中的每一个,编写一个不带任何输入并输出该唯一字符的99程序。您可以手工编写任何或所有这些答案,也可以编写其他程序(以您喜欢的任何语言)为您生成它们。

您的128 99个程序中每个字符的总和就是您的分数。最低分获胜。换行符视为一个字符。

请记住,在99中,只有偶数大小的变量(例如9999输出ASCII字符)(奇数大小的变量输出整数)。它们的值除以9,然后取为mod 128,因此将值映射到ASCII字符不需要在一定范围内。例如,内部值297、1449和-855都对应于该字符,!因为当它们被9除并取为mod 128时,它们全部变为33,这是的字符代码!

如果您需要99的解释器,建议您使用Mac的Python答案

我知道我说过我的下一个挑战将是更具互动性,但我仍在为那个挑战而努力。

Answers:


7

一份作业,2075(最佳)

这应该是最佳值(除非我在推理上有很大的错误或我的测试很糟糕)。

首先。您只能在99中表示7个不同的数字(mod 128)。所有7个或更多9的值都等于相同的数字71。(因为10 ^ 8 mod 128 == 0、10 ^ 9 mod 128 == 0, ...)

如果您可以用偶数个9来表示这4个值之一,那么输出该数字显然是最佳的解决方案。

否则,我将尝试使用一个赋值语句(将其赋值为99)得出该数字并打印99。事实证明,采用这种方法的最大程序大小为22个字符。显然,使用Goto肯定会花更多的钱。一个分配方案可能被击败的唯一可能性是有两个分配方案。我对此进行了测试(希望没有错误,此代码相当混乱),但没有找到针对任何ASCII字符的解决方案。

因此,仅检查4个直接数和单分配方法应足以找到最佳解决方案。以下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 - 7A - 65

所有程序的总和为2075。

顺便说一下,我使用了tmartink / q解释器。我讨厌其他(Python,Perl,CJam)的麻烦。不知道这是否是我的错。


如果您可以描述遇到的麻烦,它将对翻译的实施者有所帮助。好答案。
coredump

3

各种技术,42109

对于数字,我没有计算大的ASCII字符,而是计算了数字的值。您只说过能够输出字符,所以这应该仍然有效。

编辑:切换数字以使用ASCII字符,所以忽略它。我将原始数字代码留在了Java代码中,但是注释掉了,以防有人使用。

其中一些是我手工完成的,大多数我只是编写了一个输入程序。

它们每个由1-4行组成,因此将它们复制并粘贴到程序中非常友好。应该注意的是,由于我生成的代码未保留变量状态,因此它们无法连续工作。

这里使用的最常见技术与orlp的方法相同:

继续从99中减去9,然后输出。

我的版本有所不同,它使用一些自定义案例,并将大量数学运算仅写在一行上。自定义情况只是字符可以用一串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;
  }
}

您确实必须输出字符,而不仅仅是数字。因此,所有带有999结尾的程序都需要修复。
加尔文的爱好2015年

嗯,那好吧,我待会儿解决。
blo

除非我错过了什么,否则应该立即修复。我保留了原始代码,但将其注释掉,以防有人想要使用这样的数字。Pastebin也进行了编辑。
bloo 2015年

大。虽然对于某些人来说,我想您可能已经添加了99 999\n99(重新分配99999它,这样它将作为字符打印)。
加尔文的爱好

1

重复减法65280

一个比较简单的解决方案。继续从99中减去9,然后输出。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)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.