Chuẩn hóa Malbolge sang dịch giả Malbolge


12

Trong tác vụ này, bạn sẽ viết một chương trình / hàm lấy chương trình Malbolge được chuẩn hóa và xuất ra chương trình Malbolge kết quả . (Đây là một công cụ bí mật mà tất cả các lập trình viên Malbolge đang sử dụng!)

Đầu vào

Một cấu trúc dữ liệu (bằng cách nào đó) đại diện cho chương trình Malbolge được chuẩn hóa.

Đầu ra

Một cấu trúc dữ liệu đại diện cho chương trình Malbolge kết quả.

Ví dụ

jpoo*pjoooop*ojoopoo*ojoooooppjoivvvo/i<ivivi<vvvvvvvvvvvvvoji
(=BA#9"=<;:3y7x54-21q/p-,+*)"!h%B0/.~P<<:(8&66#"!~}|{zyxwvugJ%

jjjj*<jjjj*<v
('&%#^"!~}{XE

jjjjjjjjjjjjjjjjjjjjjjj*<jjjjjjjjjjjjjjjjjjjjjjjj*<v
('&%$#"!~}|{zyxwvutsrqpnKmlkjihgfedcba`_^]\[ZYXWVT1|

Cách chuyển đổi

Lặp lại chương trình Malbolge đã chuẩn hóa, thực hiện các bước sau cho mỗi nhân vật:

  1. Thay thế các ký tự trong chuỗi *jpovi</bằng ký tự tương ứng trong '(>DQbcu. (Đó là, ánh xạ *tới ', jđến (, v.v.)

  2. Sau đó trừ vị trí hiện tại của bộ đếm chương trình (tức là số lượng ký tự trước số hiện tại) khỏi mã ASCII của ký tự.

  3. Nếu mã ASCII kết quả nhỏ hơn 33, hãy tăng mã đó lên 94 và lặp lại cho đến khi ít nhất là 33.

  4. Nối ký tự kết quả vào đầu ra.

Quy tắc

  • Đây là một cuộc thi ; câu trả lời ngắn nhất sẽ thắng.
  • Không có sơ hở tiêu chuẩn xin vui lòng.
  • Các phương thức I / O mặc định được cho phép.
  • Đầu vào sẽ chỉ chứa các ký tự *jpovi</.

4
Có phải đầu vào chỉ chứa các ký tự từ " *jpovi</"?
Joel

7
Tôi không hiểu những gì "Sau đó, trừ vị trí." có nghĩa. Tôi có lẽ có thể tìm ra nó từ mã giả, nhưng lời giải thích nên được khép kín.
xnor

1
" Trong khi mã ASCII của các đại diện Malbolge tạm thời nhỏ hơn 33, hãy tăng char lên 94. " Ý của bạn là gì? Làm thế nào tôi hiểu thách thức là: 1) nhân vật bản đồ; 2) chuyển đổi thành giá trị unicode; 3) giảm từng bộ đếm theo chương trình (hiện tại chúng tôi có cái mà bạn gọi là 'mã đại diện tạm thời' mã ASCII '); 4) nếu bất kỳ giá trị nào nhỏ hơn 33, tăng thêm 94; 5) chuyển đổi các giá trị này trở lại ký tự. Nhưng sử dụng phương pháp này, đầu ra rõ ràng là không chính xác .. Vì vậy, bạn có thể làm rõ ý của bạn bằng cách này đối với đầu vào dài hơn 33 ký tự không?
Kevin Cruijssen

1
a: if ascii_code(temporary Malbolge representation) < 33: char := char + 94; goto a;

1
Tôi sẽ vui vẻ đưa tiền thưởng cho bất kỳ ai có thể viết một trong những điều này trong Malbolge :)
JDL

Câu trả lời:


4

Thạch , 29 22 byte

Oị“%þV DCµ2®  ‘_JịØṖḊ¤

Hãy thử trực tuyến!

Một liên kết đơn âm lấy một chuỗi Jelly làm đối số của nó và trả về một chuỗi Jelly.

Cảm ơn @Jonathan ALLan vì đã tiết kiệm 2 byte!

Giải trình

O                      | Convert to Unicode code points
 ị“%þV DCµ2®  ‘        | Index into compressed integer list [37, 31, 86, 32, 68, 67, 9, 50, 8, 32, 32] (note the 32s are never actually used because the input mod 11 will be one of 1,2,3,5,6,7,8,9)
               _J      | Subtract position of character in original string
                 ị   ¤ | Index into the following as a nilad:
                  ØṖ   | - Printable ASCII characters
                    Ḋ  | - With the first character (space) removed

..._J‘ịØṖḊ¤tiết kiệm một byte.
Jonathan Allan

@Jonathan ALLan cảm ơn, gọi tốt!
Nick Kennedy

2
ồ, và chúng ta có thể gia tăng trong quá trình tra cứu của mình>. < lưu một byte khác:Oị“%þV DCµ2® ‘_JịØṖḊ¤
Jonathan Allan

6

Python 3 , 82 byte

p=0
for c in input():print(end=chr((b"de{#0ABT"["*jpovi<".find(c)]-p)%94+33));p+=1

Hãy thử trực tuyến!

Cảm ơn @Joel vì đã thay thế các ký tự xấu xí không thể in được trong phần phụ bằng các ký tự có thể in được.

Tôi đang tìm kiếm một chuỗi mod để thay thế "*jpovi<".find(c), nhưng tôi không nghĩ rằng có một chuỗi ngắn hơn và một tìm kiếm vũ phu không cạn kiệt đã không tìm thấy gì cho đến nay.

82 byte

f=lambda s,p=0:s and chr((b"de{#0ABT"["*jpovi<".find(s[0])]-p)%94+33)+f(s[1:],p+1)

Hãy thử trực tuyến!


Các ký tự ASCII không thể in được có thể được bù lại bằng 94 để được tạo thành các ký tự có thể in được để dễ đọc hơn.
Joel

Bạn có thể thử tìm một hàm toán học để thay thế ánh xạ b"de{#0ABT"["*jpovi<".find(c)]nếu bạn có một chương trình cho điều đó.
Joel

1
@Joel Thật không may, tôi nghĩ rằng ánh xạ quá rộng không gian tìm kiếm cho một hàm số học, ít nhất là với các công cụ tôi có. Tôi vừa mới tìm kiếm các chuỗi modulo như x%84%15%7một nửa bên phải của ánh xạ, nhưng tôi nghĩ rằng tôi có thể tái chế một số mã tôi đã viết cho một thách thức khác để tìm kiếm bao gồm */các thuật ngữ.
xnor

@Joel Tôi không tìm thấy bất cứ thứ gì theo kiểu mod-chain cho bên phải bằng cách sử dụng %*( //trong Python 3 có lẽ không đáng.) Trên thực tế, không có gì phù hợp với 6 trong 7 giá trị đầu tiên. Tôi hy vọng điều này sẽ hiệu quả vì một ước tính entropy thô cho biết có thể có đủ các biểu thức kết thúc bằng% 7`, nhưng nó gần. Và có thể các chuỗi này cung cấp các đầu ra khác xa so với phân phối đồng đều, đặc biệt là khi một khi hai đầu vào sụp đổ về cùng một giá trị, không có hoạt động nào có thể tách chúng ra. Những thứ tôi đang thử vẫn còn quá ngu ngốc để tìm kiếm biểu thức lớn hơn, nhưng nếu bạn có bất kỳ ý tưởng nào, hãy tìm nó.
xnor

Tôi nghĩ rằng một thuật toán tốt hơn có lẽ là cần thiết cho đầu vào tùy ý như map(ord, "*jpovi<"). Nếu đầu ra không bảo toàn thứ tự cho hầu hết các đầu vào (nghĩa là f(m)>=f(n)nếu m>=n), một số hằng số được chế tạo cẩn thận %*có khả năng cần thiết và một tìm kiếm vũ phu không có khả năng mang lại kết quả khả quan.
Joel

6

Malbolge Unshackled (biến thể xoay 20 trit), 7,784e6 byte

Kích thước của câu trả lời này vượt quá kích thước chương trình có thể đăng tối đa (eh), vì vậy mã được đặt trong kho GitHub của tôi .

Làm thế nào để chạy này?

Đây có thể là một phần khó khăn, bởi vì thông dịch viên Haskell ngây thơ sẽ mất nhiều thời gian để điều hành nó. TIO có trình thông dịch Malbogle Unshackled đàng hoàng, nhưng thật đáng buồn là tôi sẽ không thể sử dụng nó (giới hạn).

Cái tốt nhất tôi có thể tìm thấy là biến thể chiều rộng xoay cố định 20 trit, hoạt động rất tốt, chuyển đổi 0,5 ký tự mỗi giây .

Để làm cho trình thông dịch nhanh hơn một chút, tôi đã xóa tất cả các kiểm tra khỏi trình thông dịch Malbolge Unshackled của Matthias Lutter.

Phiên bản sửa đổi của tôi có thể chạy nhanh hơn khoảng 6,3%.

#include <malloc.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

const char* translation = "5z]&gqtyfr$(we4{WP)H-Zn,[%\\3dL+Q;>U!pJS72Fh"
        "OA1CB6v^=I_0/8|jsb9m<.TVac`uY*MK'X~xDl}REokN:#?G\"i@";

typedef struct Word {
    unsigned int area;
    unsigned int high;
    unsigned int low;
} Word;

void word2string(Word w, char* s, int min_length) {
    if (!s) return;
    if (min_length < 1) min_length = 1;
    if (min_length > 20) min_length = 20;
    s[0] = (w.area%3) + '0';
    s[1] = 't';
    char tmp[20];
    int i;
    for (i=0;i<10;i++) {
        tmp[19-i] = (w.low % 3) + '0';
        w.low /= 3;
    }
    for (i=0;i<10;i++) {
        tmp[9-i] = (w.high % 3) + '0';
        w.high /= 3;
    }
    i = 0;
    while (tmp[i] == s[0] && i < 20 - min_length) i++;
    int j = 2;
    while (i < 20) {
        s[j] = tmp[i];
        i++;
        j++;
    }
    s[j] = 0;
}

unsigned int crazy_low(unsigned int a, unsigned int d){
    unsigned int crz[] = {1,0,0,1,0,2,2,2,1};
    int position = 0;
    unsigned int output = 0;
    while (position < 10){
        unsigned int i = a%3;
        unsigned int j = d%3;
        unsigned int out = crz[i+3*j];
        unsigned int multiple = 1;
        int k;
        for (k=0;k<position;k++)
            multiple *= 3;
        output += multiple*out;
        a /= 3;
        d /= 3;
        position++;
    }
    return output;
}

Word zero() {
    Word result = {0, 0, 0};
    return result;
}

Word increment(Word d) {
    d.low++;
    if (d.low >= 59049) {
        d.low = 0;
        d.high++;
        if (d.high >= 59049) {
            fprintf(stderr,"error: overflow\n");
            exit(1);
        }
    }
    return d;
}

Word decrement(Word d) {
    if (d.low == 0) {
        d.low = 59048;
        d.high--;
    }else{
        d.low--;
    }
    return d;
}

Word crazy(Word a, Word d){
    Word output;
    unsigned int crz[] = {1,0,0,1,0,2,2,2,1};
    output.area = crz[a.area+3*d.area];
    output.high = crazy_low(a.high, d.high);
    output.low = crazy_low(a.low, d.low);
    return output;
}

Word rotate_r(Word d){
    unsigned int carry_h = d.high%3;
    unsigned int carry_l = d.low%3;
    d.high = 19683 * carry_l + d.high / 3;
    d.low = 19683 * carry_h + d.low / 3;
    return d;
}

// last_initialized: if set, use to fill newly generated memory with preinitial values...
Word* ptr_to(Word** mem[], Word d, unsigned int last_initialized) {
    if ((mem[d.area])[d.high]) {
        return &(((mem[d.area])[d.high])[d.low]);
    }
    (mem[d.area])[d.high] = (Word*)malloc(59049 * sizeof(Word));
    if (!(mem[d.area])[d.high]) {
        fprintf(stderr,"error: out of memory.\n");
        exit(1);
    }
    if (last_initialized) {
        Word repitition[6];
        repitition[(last_initialized-1) % 6] =
                ((mem[0])[(last_initialized-1) / 59049])
                    [(last_initialized-1) % 59049];
        repitition[(last_initialized) % 6] =
                ((mem[0])[last_initialized / 59049])
                    [last_initialized % 59049];
        unsigned int i;
        for (i=0;i<6;i++) {
            repitition[(last_initialized+1+i) % 6] =
                    crazy(repitition[(last_initialized+i) % 6],
                        repitition[(last_initialized-1+i) % 6]);
        }
        unsigned int offset = (59049*d.high) % 6;
        i = 0;
        while (1){
            ((mem[d.area])[d.high])[i] = repitition[(i+offset)%6];
            if (i == 59048) {
                break;
            }
            i++;
        }
    }
    return &(((mem[d.area])[d.high])[d.low]);
}

unsigned int get_instruction(Word** mem[], Word c,
        unsigned int last_initialized,
        int ignore_invalid) {
    Word* instr = ptr_to(mem, c, last_initialized);
    unsigned int instruction = instr->low;
    instruction = (instruction+c.low + 59049 * c.high
            + (c.area==1?52:(c.area==2?10:0)))%94;
    return instruction;
}

int main(int argc, char* argv[]) {
    Word** memory[3];
    int i,j;
    for (i=0; i<3; i++) {
        memory[i] = (Word**)malloc(59049 * sizeof(Word*));
        if (!memory) {
            fprintf(stderr,"not enough memory.\n");
            return 1;
        }
        for (j=0; j<59049; j++) {
            (memory[i])[j] = 0;
        }
    }
    Word a, c, d;
    unsigned int result;
    FILE* file;
    if (argc < 2) {
        // read program code from STDIN
        file = stdin;
    }else{
        file = fopen(argv[1],"rb");
    }
    if (file == NULL) {
        fprintf(stderr, "File not found: %s\n",argv[1]);
        return 1;
    }
    a = zero();
    c = zero();
    d = zero();
    result = 0;
    while (!feof(file)){
        unsigned int instr;
        Word* cell = ptr_to(memory, d, 0);
        (*cell) = zero();
        result = fread(&cell->low,1,1,file);
        if (result > 1)
            return 1;
        if (result == 0 || cell->low == 0x1a || cell->low == 0x04)
            break;
        instr = (cell->low + d.low + 59049*d.high)%94;
        if (cell->low == ' ' || cell->low == '\t' || cell->low == '\r'
                || cell->low == '\n');
        else if (cell->low >= 33 && cell->low < 127 &&
                (instr == 4 || instr == 5 || instr == 23 || instr == 39
                    || instr == 40 || instr == 62 || instr == 68
                    || instr == 81)) {
            d = increment(d);
        }
    }
    if (file != stdin) {
        fclose(file);
    }
    unsigned int last_initialized = 0;
    while (1){
        *ptr_to(memory, d, 0) = crazy(*ptr_to(memory, decrement(d), 0),
                *ptr_to(memory, decrement(decrement(d)), 0));
        last_initialized = d.low + 59049*d.high;
        if (d.low == 59048) {
            break;
        }
        d = increment(d);
    }
    d = zero();

    unsigned int step = 0;
    while (1) {
        unsigned int instruction = get_instruction(memory, c,
                last_initialized, 0);
        step++;
        switch (instruction){
            case 4:
                c = *ptr_to(memory,d,last_initialized);
                break;
            case 5:
                if (!a.area) {
                    printf("%c",(char)(a.low + 59049*a.high));
                }else if (a.area == 2 && a.low == 59047
                        && a.high == 59048) {
                    printf("\n");
                }
                break;
            case 23:
                a = zero();
                a.low = getchar();
                if (a.low == EOF) {
                    a.low = 59048;
                    a.high = 59048;
                    a.area = 2;
                }else if (a.low == '\n'){
                    a.low = 59047;
                    a.high = 59048;
                    a.area = 2;
                }
                break;
            case 39:
                a = (*ptr_to(memory,d,last_initialized)
                        = rotate_r(*ptr_to(memory,d,last_initialized)));
                break;
            case 40:
                d = *ptr_to(memory,d,last_initialized);
                break;
            case 62:
                a = (*ptr_to(memory,d,last_initialized)
                        = crazy(a, *ptr_to(memory,d,last_initialized)));
                break;
            case 81:
                return 0;
            case 68:
            default:
                break;
        }

        Word* mem_c = ptr_to(memory, c, last_initialized);
        mem_c->low = translation[mem_c->low - 33];

        c = increment(c);
        d = increment(d);
    }
    return 0;
}

Nó đang hoạt động!

Nó đang hoạt động


2
Đây chỉ là điên rồ.
MilkyWay90

Đối với người qua đường, số byte là 7,784 MB, không phải 7,784GB. Tôi đã giải thích dấu phẩy là nhóm hàng ngàn thay vì dấu thập phân lúc đầu.
Khoai tây44

@ Potato44 chúng tôi sử dụng dấu phẩy làm dấu tách thập phân ở Ba Lan, sử dụng dấu chấm như vậy là bị cấm.
Krzysztof Szewchot

5

Python 3 , 84 83 byte

f=lambda p,i=0:p and chr(126-(i+b"WV@:-zyg"["*jpovi<".find(p[0])])%94)+f(p[1:],i+1)

Hãy thử trực tuyến!

Đây chủ yếu là một vấn đề toán học về đơn giản hóa tính toán, cộng với một số môn đánh gôn sau khi hoàn thành bài toán. Phiên bản mã không mã hóa được hiển thị dưới đây.

Ungolfed, phiên bản không đệ quy

def convert(prog):
    offsets = dict(zip("*jpovi</", [87, 86, 64, 58, 45, 122, 121, 103]))  # ASCII encoded to "WV@:-zyg"
    output = ""
    for pos, c in enumerate(prog):
        output += chr(126-(offsets[c]+pos)%94)
    return output

Hãy thử trực tuyến!


5

JavaScript (Node.js) , 69 byte

s=>(B=Buffer)(s).map((c,i)=>33+(B(" #{T BAe0d")[c%11]+94-i%94)%94)+''

Hãy thử trực tuyến!

Làm sao?

[1..9]11

 char. | ASCII code | mod 11
-------+------------+--------
  '*'  |      42    |   9
  'j'  |     106    |   7
  'p'  |     112    |   2
  'o'  |     111    |   1
  'v'  |     118    |   8
  'i'  |     105    |   6
  '<'  |      60    |   5
  '/'  |      47    |   3


3

05AB1E , 32 31 23 22 byte

žQ¦•4¡ˆ¶ü]₁η₃•₃вIÇèā-è

-8 byte tạo ra một cổng câu trả lời Jelly của NickKennedy , vì vậy hãy đảm bảo nâng cấp anh ta !!
-1 byte nhờ @Grimy.

Đầu ra dưới dạng một danh sách các ký tự.

Hãy thử trực tuyến hoặc xác minh tất cả các trường hợp thử nghiệm .

Giải trình:

   4¡ˆ¶ü]₁η₃•          # Push compressed integer 82767635194143615015
              ₃в        # Converted to base-95 as list: [1,36,30,85,0,67,66,8,49,7,0]
                IÇ      # Push the input and convert each character to its unicode value
                  è     # Index each into the list we created
                   ā    # Push an integer list in the range [0, length] 
                        # (without popping the list itself)
                    -   # Subtract it from the previous list
žQ                      # Push builtin with all printable ASCII characters,
  ¦                     # and remove the leading space
                     è  # Index the values of the list into the ASCII characters
                        # (after which the result is output implicitly)

Xem 05AB1E mẹo này của tôi (phần Làm thế nào để nén các số nguyên lớn?Làm thế nào để liệt kê số nguyên nén? ) Để hiểu tại sao •4¡ˆ¶ü]₁η₃•82767635194143615015•4¡ˆ¶ü]₁η₃•₃в[1,36,30,85,0,67,66,8,49,7,0].


•1ÃQWý₂Ýδ9•86в->•4¡ˆ¶ü]₁η₃•₃в
Grimmy

@Grimy Cảm ơn :)
Kevin Cruijssen

2

Perl 5 ( -p), 53 , 51 byte

tiết kiệm 2 byte, sử dụng de{#0ABTthay vì '(>DQbcuvậy 61không còn cần thiết

y;*jpovi</;de{#0ABT;;s/./chr 33+(-"@-"+ord$&)%94/ge

TIO

câu trả lời đầu tiên là

y;*jpovi</;'(>DQbcu;;s/./chr 33+(61-"@-"+ord$&)%94/ge

TIO


2

Japt , 24 23 byte

Giải pháp của cảng Nick's Jelly

;£EÅgYn" #T BA0 "cXc

Thử nó

;£EÅgYn"..."cXc     :Implicit input of string
 £                  :Map each character X at 0-based index Y
; E                 :ASCII
   Å                :Slice of the first character (space)
    g               :Get character at index
     Y              :  Increment Y
      n             :  Subtract from
       "..."        :    Literal string (Codepoints: 32,35,29,84,32,66,65,7,48,6,32)
            c       :    Codepoint at index
             Xc     :      Codepoint of X

1

Võng mạc 0.8.2 , 50 byte

T`*j\p\ovi</`'(>DQbcu
.
$.`$* $&¶
+T`!p`~_p` .¶
¶

Hãy thử trực tuyến! Liên kết bao gồm các trường hợp thử nghiệm. Giải trình:

T`*j\p\ovi</`'(>DQbcu

Thực hiện phiên âm như mô tả trong câu hỏi. p(được mô tả dưới đây) và ocó ý nghĩa đặc biệt để Transliterate vì vậy chúng cần được trích dẫn.

.
$.`$* $&¶

Liệt kê mỗi ký tự trên dòng riêng của nó, đứng trước một số khoảng trắng theo chỉ mục của nó, tức là bộ đếm chương trình sẽ là gì.

+T`!p`~_p` .¶

Lặp đi lặp lại giảm dần theo ký tự cuối cùng trên mỗi dòng, xóa khoảng trắng trước đó mỗi lần, cho đến khi tất cả các khoảng trắng đã bị xóa. Chữ pviết tắt của ASCII có thể in được -~, tuy nhiên, chúng tôi muốn !ánh xạ ~sao cho được phiên âm trước, và sau đó _nguyên nhân khiến không gian trong trận đấu bị xóa, trong khi các ký tự còn lại được phiên âm một mã ký tự một lần.

Tham gia tất cả các nhân vật trở lại với nhau.


1

Than , 23 byte

⭆S§Φγμ⁻℅§ #{T BAe0d ℅ικ

Hãy thử trực tuyến! Liên kết là phiên bản dài dòng của mã. Câu trả lời JavaScript của @ Arnauld. Giải trình:

 S                      Input string
⭆                       Map over characters and join
                     ι  Current character
                    ℅   ASCII code
        §               Cyclically indexed into
          #{T BAe0d     Literal string ` #{T BAe0d `
       ℅                ASCII code
      ⁻                 Subtract
                      κ Current index
  §                     Cyclically indexed into
    γ                   Printable ASCII
   Φ                    Filtered on
     μ                  Inner index (i.e. skip initial space)
                        Implicitly print


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.