Gra w golfa każdą postacią ASCII w 99

11

99 to język programowania, który wymyśliłem na początku tego tygodnia dla mojego wyzwania. Napisz tłumacza na 99 . (Wymyślony, ale nigdy nie musiałem go wdrażać dzięki tuzinowi z was;)) Pełna specyfikacja języka jest w tym wyzwaniu, więc nie zawracam sobie głowy ponownym opublikowaniem tego wszystkiego.

W 99 możesz wydrukować pojedyncze znaki ASCII na standardowe wyjście, ale ze względu na ograniczenia językowe nie zawsze jest jasne, jak wydrukować konkretny znak tak zwięźle, jak to możliwe.

Dla każdego ze 128 znaków ASCII napisz program 99 , który nie przyjmuje danych wejściowych i wyprowadza ten jedyny znak. Możesz ręcznie zakodować jedną lub wszystkie z tych odpowiedzi lub napisać inny program (w dowolnym języku, który lubisz), aby wygenerować je dla Ciebie.

Suma znaków w każdym z twoich 128 99 programów to twój wynik. Najniższy wynik wygrywa. Nowe linie liczą się jako jeden znak.

Pamiętaj, że w 99 tylko zmienne wielkości parzyste, takie jak 9999wyjściowe znaki ASCII (zmienne nieparzyste, wyjściowe liczby całkowite). Ich wartość jest dzielona przez 9, a następnie pobierana mod 128, więc wartości nie muszą znajdować się w pewnym zakresie, aby odwzorować na znaki ASCII. Na przykład wszystkie wartości wewnętrzne 297, 1449 i -855 odpowiadają znakowi, !ponieważ po podzieleniu przez 9 i pobraniu mod 128, wszystkie stają się 33, co jest kodem znaku !.

Jeśli potrzebujesz tłumacza na 99 , proponuję odpowiedź Mac w Pythonie .

Wiem, że powiedziałem, że moje następne wyzwanie będzie bardziej interaktywne, ale wciąż pracuję nad tym.

Hobby Calvina
źródło

Odpowiedzi:

7

Jedno zadanie, 2075 (optymalne)

Powinna to być wartość optymalna (chyba że mam duży błąd w rozumowaniu lub moje testy są do kitu).

Po pierwsze. Istnieje tylko 7 różnych liczb (mod 128), które możesz wyrazić w 99. Wszystkie wartości 7 lub więcej 9 oceniają na tę samą liczbę 71. (Ponieważ 10 ^ 8 mod 128 == 0, 10 ^ 9 mod 128 == 0, ...)

Jeśli jedną z 4 wartości można wyrazić parzystą liczbą dziewiątek, to wyprowadzenie tej liczby jest zdecydowanie optymalnym rozwiązaniem.

W przeciwnym razie staram się dotrzeć do liczby za pomocą jednej instrukcji przypisania (przypisać do 99) i wydrukować 99. Jak się okazuje, maksymalny rozmiar programu przy takim podejściu wynosi 22 znaki. Wyraźnie użycie Goto wymaga zdecydowanie więcej. Jedyną możliwością pokonania rozwiązania jednego zadania jest rozwiązanie z dwoma zadaniami. Przetestowałem to (mam nadzieję, że bez błędów, kod tego jest dość nieporządny) i nie znalazłem rozwiązania dla żadnego znaku ASCII.

Dlatego tylko sprawdzenie 4 liczb bezpośrednich i podejście z jednym przypisaniem powinno wystarczyć, aby znaleźć optymalne rozwiązanie. Poniższy program w języku Python (zgodny z 2 i 3) generuje wszystkie programy i podsumowuje ich długości. Wykorzystuje proste podejście 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))

Dane wyjściowe mają następującą postać:

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

Możesz znaleźć pełne wyjście na: http://pastebin.com/bKXLAArq

Znak z najkrótszym programem (2 vertical tab - 11znaki ) ma długość programu 2, znaki z najdłuższymi programami (22 znaki) to bell - 7i A - 65.

Suma wszystkich programów wynosi 2075.

A tak przy okazji, użyłem interpretera k / q z tmartin . Mam problemy z innymi (Python, Perl, CJam). Nie jestem pewien, czy to moja wina.

Jakube
źródło
Pomogłoby to wykonawcom tłumaczy, gdybyś mógł opisać swoje problemy. Świetna odpowiedź.
Coredump
3

Różnorodne techniki, 42109

W przypadku liczb zamiast obliczać duży znak ASCII, właśnie obliczyłem wartość liczby. Mówiłeś tylko, że możesz wypisać postać, więc to powinno nadal działać.

EDYCJA: Zmieniłem liczby, aby używać znaków ASCII, więc zignoruj ​​to. Zostawiłem oryginalny kod numeryczny w kodzie Java, ale skomentowałem na wypadek, gdyby ktoś chciał go użyć.

Niektóre z nich zrobiłem ręcznie, większość po prostu napisałem program do napisania.

Składają się one z 1-4 wierszy, więc są dość przyjazne do kopiowania i wklejania do programu. Należy zauważyć, że nie działają one kolejno, ponieważ mój wygenerowany kod nie zachowuje stanów zmiennych.

Najczęściej stosowaną tutaj techniką było to samo, co podejście orlp:

Odejmuj 9 od 99, a następnie wyprowadzaj.

Moja wersja różni się od używania niestandardowych przypadków i układania dużej części matematyki w jednym wierszu. Przypadki niestandardowe są tam, gdzie postać może być reprezentowana za pomocą tylko kilku cyfr i żadna matematyka ani mój kod generacyjny nie mogą zostać skrócone.

Programy

Umieściłem dane wyjściowe w Pastebin dla tych z was, którzy nie mają ochoty uruchamiać programu:

http://pastebin.com/Cs6WZUfb

Użyty kod 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
źródło
Trzeba wyprowadzić znak, a nie tylko liczbę. Więc wszystkie programy 999na końcu muszą zostać naprawione.
Calvin's Hobbies
Ach, w porządku, zaraz to naprawię.
bloo
Powinien zostać naprawiony, chyba że coś przeoczyłem. Zostawiłem oryginalny kod, ale skomentowałem na wypadek, gdyby ktoś chciał użyć takich liczb. Zredagowano także Pastebin.
bloo
Świetny. Chociaż dla niektórych myślę, że mógłbyś właśnie dodać 99 999\n99( zmienić przypisanie, 999aby 99wydrukować jako postać).
Calvin's Hobbies
1

Powtarzane odejmowanie, 65280

Trywialne rozwiązanie do porównania. Odejmuj 9 od 99, a następnie wyprowadzaj. Przykład znaku 10 ASCII:

99 99 9
99

Istnieje 128 programów. Pierwszy program ma dwa znaki (99), a każdy po nim jest o 8 znaków (99 99 9 \ n) dłuższy niż poprzedni.

Program w języku Python generujący programy oddzielone pustymi liniami i obliczający wynik:

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

print(score)
orlp
źródło