Bermain golf setiap karakter ASCII di 99

11

99 adalah bahasa pemrograman yang saya ciptakan awal minggu ini untuk tantangan saya. Tulis penerjemah untuk 99 . (Diciptakan tetapi tidak pernah perlu untuk mengimplementasikan berkat setengah lusin dari Anda.;)) Spesifikasi bahasa lengkap ada dalam tantangan itu jadi saya tidak repot untuk memposting ulang semuanya di sini.

Di 99 Anda dapat mencetak karakter ASCII individu ke stdout, tetapi karena kendala bahasa, tidak selalu jelas bagaimana cara mencetak karakter tertentu selurus mungkin.

Untuk masing-masing 128 karakter ASCII, tulislah sebuah program 99 yang tidak mengambil input dan menghasilkan karakter tunggal itu. Anda dapat mengkodekan salah satu atau semua jawaban ini dengan tangan, atau Anda dapat menulis program lain (dalam bahasa apa pun yang Anda suka) untuk menghasilkannya untuk Anda.

Jumlah karakter di masing-masing program 128 99 Anda adalah skor Anda. Skor terendah menang. Baris baru dihitung sebagai satu karakter.

Ingat, dalam 99 , hanya variabel berukuran genap seperti 9999karakter ASCII keluaran (bilangan bulat variabel keluaran ganjil). Nilainya dibagi 9 dan kemudian diambil mod 128, sehingga nilainya tidak perlu berada dalam kisaran tertentu untuk memetakan ke karakter ASCII. Sebagai contoh, nilai-nilai internal 297, 1449, dan -855 semua sesuai dengan karakter !karena ketika mereka dibagi dengan 9 dan diambil mod 128, mereka semua menjadi 33, yang merupakan kode karakter untuk !.

Jika Anda membutuhkan juru bahasa untuk 99 , saya sarankan jawaban Python Mac .

Saya tahu saya katakan tantangan saya berikutnya akan lebih interaktif tetapi saya masih mengerjakan hal-hal untuk itu.

Hobi Calvin
sumber

Jawaban:

7

Satu tugas, 2075 (optimal)

Ini harus menjadi nilai optimal (kecuali saya memiliki kesalahan besar dalam alasan atau pengujian saya menyebalkan).

Pertama-tama. Hanya ada 7 angka berbeda (mod 128) yang dapat Anda ungkapkan dalam 99. Semua nilai 7 atau lebih 9 dievaluasi ke angka yang sama 71. (Karena 10 ^ 8 mod 128 == 0, 10 ^ 9 mod 128 == 0, ...)

Jika salah satu dari 4 nilai yang dapat Anda ungkapkan dengan jumlah genap genap, daripada mengeluarkan angka ini jelas merupakan solusi optimal.

Kalau tidak, saya mencoba untuk mencapai nomor dengan satu pernyataan tugas (menetapkan ke 99) dan mencetak 99. Ternyata ukuran program maksimal dengan pendekatan ini adalah 22 karakter. Jelas menggunakan Goto jelas membutuhkan lebih dari itu. Satu-satunya kemungkinan bahwa solusi satu-tugas mungkin dikalahkan adalah solusi dengan dua tugas. Saya menguji ini (mudah-mudahan tanpa kesalahan, kode untuk ini cukup berantakan), dan tidak menemukan solusi untuk char ASCII.

Oleh karena itu hanya memeriksa 4 angka langsung dan pendekatan satu-tugas harus cukup untuk menemukan solusi optimal. Program Python (kompatibel 2 dan 3) berikut menghasilkan semua program dan merangkum panjangnya. Ini menggunakan pendekatan IDA * sederhana.

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

Outputnya berupa:

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

Anda dapat menemukan hasil lengkap di: http://pastebin.com/bKXLAArq

Char dengan program terpendek (2 char) adalah vertical tab - 11dengan panjang program 2, karakter dengan program terpanjang (22 char) adalah bell - 7dan A - 65.

Jumlah untuk semua program adalah 2075.

Dan omong-omong, saya menggunakan penerjemah k / q dari tmartin . Saya memiliki beberapa masalah dengan yang lain (Python, Perl, CJam). Tidak yakin apakah itu salah saya.

Jakube
sumber
Ini akan membantu pelaksana penerjemah jika Anda bisa menggambarkan masalah apa yang Anda miliki. Jawaban yang bagus
coredump
3

Berbagai Teknik, 42109

Untuk angka-angka, alih-alih menghitung karakter ASCII yang besar, saya hanya menghitung nilai angka itu. Anda hanya mengatakan untuk dapat menampilkan karakter, jadi ini harus tetap berfungsi.

EDIT: Mengganti angka untuk menggunakan karakter ASCII, jadi abaikan itu. Saya meninggalkan kode nomor asli dalam kode Java tetapi berkomentar kalau-kalau ada yang ingin menggunakannya.

Beberapa di antaranya saya lakukan dengan tangan, kebanyakan saya hanya menulis program untuk mengetik.

Ini terdiri dari 1-4 baris masing-masing, jadi mereka cukup ramah untuk hanya menyalin dan menempelkan ke dalam program. Perlu dicatat bahwa mereka tidak bekerja secara berturut-turut karena kode yang saya hasilkan tidak mempertahankan status variabel.

Teknik yang paling umum digunakan di sini adalah sama dengan pendekatan orlp:

Terus kurangi 9 dari 99, lalu hasilkan.

Versi saya berbeda dengan menggunakan beberapa case khusus dan menyusun banyak matematika menjadi hanya satu baris. Kasing khusus adalah tempat karakter dapat diwakili hanya dengan sekelompok angka 9 dan tidak ada matematika atau kode generasi saya dapat dipersingkat.

Program

Saya telah menempatkan hasilnya pada Pastebin bagi Anda yang tidak merasa ingin menjalankan program:

http://pastebin.com/Cs6WZUfb

Kode Java I digunakan:

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
sumber
Anda harus benar-benar menampilkan karakter, bukan hanya angka. Jadi semua program dengan 999pada akhirnya perlu diperbaiki.
Calvin Hobbies
Ah, kalau begitu, aku akan memperbaikinya sebentar lagi.
bloo
Harus diperbaiki sekarang kecuali aku melewatkan sesuatu. Saya meninggalkan kode asli tetapi berkomentar kalau-kalau ada yang ingin menggunakan angka seperti itu. Pastebin juga diedit.
mekar
Bagus. Meskipun untuk beberapa saya pikir Anda bisa saja menambahkan 99 999\n99(untuk menetapkan kembali 999ke 99sehingga akan mencetak sebagai karakter).
Calvin Hobbies
1

Pengurangan berulang, 65280

Solusi sepele untuk dibandingkan. Terus kurangi 9 dari 99, lalu hasilkan. Contoh untuk karakter ASCII 10:

99 99 9
99

Ada 128 program. Program pertama panjangnya dua karakter (99), masing-masing setelah itu adalah 8 karakter (99 99 9 \ n) lebih panjang dari yang sebelumnya.

Program Python menghasilkan program yang dipisahkan oleh baris kosong, dan skor komputasi:

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

print(score)
orlp
sumber