Bagi Angka dengan 0


16

Kita semua telah diberitahu pada suatu titik dalam hidup kita bahwa membagi dengan 0 adalah tidak mungkin. Dan sebagian besar, pernyataan itu benar. Tapi bagaimana jika ada adalah cara untuk melakukan operasi dilarang? Selamat datang di kreasi terbaru saya: b-nomor.

b-nomornya sedikit seperti angka imajiner: pronumeral utama yang terlibat mewakili ekspresi yang tidak mustahil secara matematis ( imewakili 1 ). Dalam hal iniakan dikatakan mewakili ekspresi. Dari sini, mudah untuk menentukan apa yangakan sama dengan:b10x0

x0=x110=xb

Tugas

Diberikan ekspresi yang melibatkan pembagian dengan 0, output nilai yang disederhanakan dalam hal . Perhatikan bahwa input akan dalam bentuk di mana n adalah bilangan rasional atau -bilangan apa pun dalam bentuk desimal. Leading 0s dan trailing 0s tidak akan dimasukkan.bn/0b

Contoh Input

4/0
1/0
0/0
80/0
-8/0
1.5/0
2.03/0
-1/0
-3.14/0
b/0
3b/0
-b/0
121/0

Contoh Output

4b
b
0
80b
-8b
1.5b
2.03b
-b
-3.14b
b
3b
-b
121b

Skor

Ini adalah kode golf, byte paling sedikit menang. Celah standar dilarang.

Papan peringkat

Berikut ini adalah Stack Snippet untuk menghasilkan leaderboard biasa dan gambaran umum pemenang berdasarkan bahasa.

Untuk memastikan bahwa jawaban Anda muncul, silakan mulai jawaban Anda dengan tajuk utama, menggunakan templat Penurunan harga berikut:

# Language Name, N bytes

di mana Nukuran kiriman Anda. Jika Anda meningkatkan skor Anda, Anda dapat menyimpan skor lama di headline, dengan mencoretnya. Contohnya:

# Ruby, <s>104</s> <s>101</s> 96 bytes

Jika Anda ingin memasukkan beberapa angka dalam tajuk Anda (mis. Karena skor Anda adalah jumlah dari dua file atau Anda ingin membuat daftar hukuman penterjemah secara terpisah), pastikan bahwa skor sebenarnya adalah angka terakhir di tajuk:

# Perl, 43 + 2 (-p flag) = 45 bytes

Anda juga dapat membuat tautan nama bahasa yang kemudian akan muncul di cuplikan papan peringkat:

# [><>](http://esolangs.org/wiki/Fish), 121 bytes


7
Saya menduga bahwa saya melakukan sesuatu yang salah, tetapi jika b/0 = bkemudian jika saya membagi kedua bagian bitu 1/0 = 1. Apakah saya perlu c-jumlah untuk membagi seperti ini?
kata ganti saya adalah monicareinstate

4
@ Erik seperti itu, b/b = 0ketika itu normal (dan saya cukup yakin itu mudah dibuktikan dari semua aksioma) diharapkan menjadi 1 (jika tidak, invers multiplicative b tampaknya bukan invers multiplicative-nya). Saya cukup yakin Anda tidak bisa celah melawan divisi dengan nol dengan menambahkan b=1/0atau yang serupa.
kata ganti saya adalah monicareinstate

30
Ada alasan mengapa pembagian dengan nol tidak ditentukan ... . Jadi Anda harus dapat menyederhanakan semua contoh (kecuali yang ketiga dari 0) menjadi hanyabb=1b=11b=33b=3130=30=310=3bb
Mostly Harmless

8
Bukankah seharusnya contoh ke-3 memiliki output 0bdaripada 0? Jika kedua ungkapan itu setara, maka pertanyaannya tidak memiliki premis
trichoplax

Jawaban:


19

Malbolge Unshackled (varian rotasi 20-trit), 3,62e6 byte

Ukuran jawaban ini melebihi ukuran program maksimum yang dapat diposkan (eh), jadi kodenya terletak di repositori GitHub saya (catatan: Jangan menyalin kode menggunakan CTRL + A dan CTRL + C, cukup klik kanan dan klik "Simpan elemen tujuan sebagai. .. ").

Bagaimana cara menjalankannya?

Ini mungkin bagian yang sulit, karena juru bahasa Haskell yang naif akan membutuhkan waktu lama untuk menjalankannya. TIO memiliki penerjemah Malbogle Unshackled yang layak, tetapi sayangnya saya tidak dapat menggunakannya (batasan).

Yang terbaik yang bisa saya temukan adalah varian lebar rotasi 20-trit, yang berkinerja sangat baik, menghitung (cukup banyak) secara instan .

Untuk membuat penerjemah sedikit lebih cepat, saya telah menghapus semua cek dari penerjemah Malbolge Unshackled milik Matthias Lutter.

#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;
}

Bekerja!

Bekerja!


6
Saya harap Anda tidak mengetik semua itu.
connectyourcharger

5
Ketika saya membuka program Anda, Chrome berusaha menerjemahkannya dari Bahasa Polandia
Tharwen

@ Talwen sekilas, Sulit untuk mengatakan apakah itu Polandia atau hanya Malbolge. Sayangnya bahasa saya adalah neraka di bumi untuk dipelajari.
Krzysztof Szewczyk

7

PHP , 65 64 61 58 byte

-1 byte dengan menggunakan bbukan ''(string kosong). Karena "b" dipangkas, itu akan sama dengan string kosong dalam kasus khusus ini.

-3 byte dengan menggunakan substralih-alih explodeuntuk mendapatkan bagian pertama dari input.

-3 byte dengan menggunakan metode yang lebih baik untuk mendeteksi 1dan -1.

<?=($n=substr($argn,0,-2))?trim($n+1?$n-1?$n:b:'-',b).b:0;

Cobalah online!

Tes: Coba online!

Jika bagian pertama dari input sebelum "/" (kami menyebutnya $n) adalah 0, cetak 0.

Lain mencetak $ndirinya sendiri dengan huruf "b" di bagian akhir yang dipangkas darinya dan case khusus dari -1 dan 1 ditangani, sehingga digit "1" tidak dicetak. Dan pada akhirnya menambahkan satu "b". Bagian pemangkasan adalah untuk memastikan kita tidak mendapatkan "b" ganda pada akhirnya seperti "3bb".


dilakukan dengan sangat baik!
Jono 2906

Mengganti $n==-1dengan $n>0(-2 byte) tampaknya berhasil. Anda bisa mencobanya.
Ismael Miguel

@ IsmaelMiguel, itu tidak berfungsi, jika Anda maksudkan $n<0, itu tidak akan berfungsi juga, karena kami memiliki input seperti -8/0.
Night2

@ IsmaelMiguel, tetapi Anda memberi saya ide, diganti $n==-1?'-':$ndengan $n+1?$n:'-'untuk menghemat 2 byte!
Night2

1
: / Ketika saya menguji, sepertinya berhasil. tapi yah, hal bagus yang kamu temukan dengan cara lain.
Ismael Miguel


4

Jelly , 18 byte

Saya akhirnya mencuri Erik ṾṖ$İƑ¡ untuk yang satu ini (kalau tidak saya juga punya 19) ...

ṖṖv0ḢṾṖ$İƑ¡,Ạ¡”boḢ

Program lengkap yang mencetak hasilnya.

Cobalah online! Atau lihat test-suite .

Bagaimana?

ṖṖv0ḢṾṖ$İƑ¡,Ạ¡”boḢ - Main Link: list of characters S
Ṗ                  - discard right-most (of S)
 Ṗ                 - discard right-most
   0               - literal zero
  v                - evaluate as Jelly code with right argument (0)
                   - ... b is covert-to-base, so "nb0" gives [n]
    Ḣ              - head ([n]->n or n->n)
          ¡        - repeat...
         Ƒ         - ...# of times: is invariant under:
        İ          -   reciprocation (n->1/n)
       $           - ...action: last two links as a monad:
     Ṿ             -   un-evaluate (-1->"-1" or 1->"1")
      Ṗ            -   discard right-most ("-1"->"-" or "1"->"")
             ¡     - repeat...
            Ạ      - ...# of times: all?
           ,  ”b   - ...action: pair with a 'b' character
                o  - logical OR with:
                 Ḣ -   head (S)  (i.e. if we end with 0 use the 1st character of the input)
                   - implicit print

1
Ahhh, dan saya memikirkan cara-cara saya dapat menyalahgunakan v...: D
Erik the Outgolfer

4

Perl 6 , 32 byte

{~m/^0/||S/[(\-|^)1|b]?\/0/$0b/}

Cobalah online!

Beberapa regexes, satu untuk memeriksa apakah input 0/0, dan yang lainnya untuk menggantikan trailing /0hanya dengan b(dan untuk menghapus yang lama b, 1dan / atau -1)

Penjelasan (lama)

{                          }  # Anonymous codeblock
 ~m/^0/     # Return 0 if the input starts with 0
       ||   # Otherwise
         S/             / /  # Substitute
                     \/0       # The /0
          (        )?          # Optionally starting with
           <wb>1               # 1 or -1
                |b             # Or b
                         b   # With just b

3

Retina , 28 24 byte

b?/0
b
^0b
0
(^|-)1b
$1b

Cobalah online!

Pertama-tama cobalah menggunakan Retina, jadi mungkin ada ruang yang cukup untuk bermain golf.



Setelah berburu untuk apa \b(saya yang tidak berpengalaman dengan regex), saya agak kecewa menemukan bahwa itu tidak dapat disingkat menjadi karakter backspace yang tidak dapat dicetak. Bagaimanapun, terima kasih
String Tidak Terkait

1
@UnrelatedString tentu saja tidak dapat disingkat menjadi backspace, setelah semua, \bhanyalah representasi ASCII dari karakter backspace dalam string normal: P
ASCII-only

2

Python 3 , 68 byte

import re
print(re.sub('^0b$','0',re.sub(r'(^1)?b?/0','b',input())))

Cobalah online!


Solusi bagus! Tetapi import renaik bytecount ke 64.
movatica

1
@movatica poin bagus, baru di sini jadi tidak menyadari pernyataan impor dimasukkan (walaupun tentu saja itu). Diedit.
Kazim

Selamat datang! :) Anda masih dapat menyimpan versi lambda yang lebih pendek! Tidak perlu program penuh. Dan pernyataan impor dapat ditempatkan setelah definisi lambda, jadi 64 byte dimungkinkan !
movatica

1
@Movatica ah, bagus! Saya tidak menemukan cara untuk membuatnya bekerja dengan impor dan lambda. Terima kasih
Kazim

1

Tong , 18B

Semua kredit untuk Jono 2906.

__:b=;[b]^:\1=[_]^

Penjelasan

__                 # Take implicit input and remove the "trash" (/0).
  :b=              # Is the last character equal to b?
     ;             # Negate(decrement) this value.
      [b]          # If the last character is not b, append b.
         ^         # Reverse the stack.
          :\1=     # Is the first character equal to 1?
              [_]  # If so, reduce the value.
                 ^ # Reverse the stack back and implicit output.

TIO!



1

JavaScript (ES6), 45 byte

s=>+(n=s.split`/`[0])?[n*n-1?n:'-'[~n]]+'b':n

Cobalah online!

Berkomentar

s =>                  // s = input: "numerator/0"
  +(                  //
    n = s.split`/`[0] // n = numerator, as a string
  ) ?                 // if n coerced to a Number is neither equal to 0 nor NaN:
    [ n * n - 1 ?     //   if abs(n) is not equal to 1:
        n             //     append the numerator
      :               //   else:
        '-'[~n]       //     append '-' if n = -1, or an empty string otherwise
    ] + 'b'           //   append 'b'
  :                   // else:
    n                 //   just output the numerator because it's either "0" or
                      //   an expression that already contains 'b'

1

C, 209 203 137 byte

-66 bytes berkat ceilingcat

char a[9];main(f){gets(a);f=strlen(a)-3;a[f+1]=0;printf((*a==55&a[1]==49&f==1?a[1]=98:*a==49&!f?*a=98:a[f]==98|*a==48&!f)?"%s":"%sb",a);}

TIO


Memasukkan -0/0 memberi -0b, tetapi tidak pernah dalam contoh input atau test case, jadi itu benar.
girobuz

0

Brainfuck, 25 byte

>,[>,]<[-<+>]<+++[<]>[.>]

Penjelasan

>,[>,]        read from stdin
<[-<+>]<+++   add last two cells and add three ( ascii('/') + ascii('0') + 3 = ascii('b')
[<]>          move pointer to first char to output
[.>]          output until cell w/ value 0

1
b/0diharapkan b, didapat bb; 0/0diharapkan 0, dapatkan0b ; -1/0diharapkan -b, dapatkan -1b.
a'_ '

Ya, pada dasarnya ini hanya menggantikan orang /0untuk bdan tidak memperhitungkan salah satu kasus untuk 0b, 1b, -1batau input yang sudah mengandungb
Jo Raja
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.