# Divide Numbers by 0

We've all been told at some point in our lives that dividing by 0 is impossible. And for the most part, that statement is true. But what if there was a way to perform the forbidden operation? Welcome to my newest creation: b-numbers.

b-numbers are a little bit like imaginary numbers: the main pronumeral involved represents an expression that isn't mathematically impossible (i represents $$\\sqrt{-1}\$$). In this case $$\b\$$ will be said to represent the expression $$\\frac{1}{0}\$$. From here, it is easy to determine what $$\\frac{x}{0}\$$ would equal:

$$\frac{x}{0} = \frac{x}{1} \cdot \frac{1}{0} = xb$$

Given an expression involving a division by 0, output the simplified value in terms of $$\b\$$. Note that input will be in the form of n/0 where n is any rational number or any b-number in decimal form. Leading 0s and trailing 0s wont be included.

## Example 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


## Example Output

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


# Score

This is code golf, so fewest bytes wins. Standard loopholes are forbidden.

Here is a Stack Snippet to generate both a regular leaderboard and an overview of winners by language.

# Language Name, N bytes


where N is the size of your submission. If you improve your score, you can keep old scores in the headline, by striking them through. For instance:

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


If there you want to include multiple numbers in your header (e.g. because your score is the sum of two files or you want to list interpreter flag penalties separately), make sure that the actual score is the last number in the header:

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


You can also make the language name a link which will then show up in the leaderboard snippet:

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


var QUESTION_ID=191101;
var OVERRIDE_USER=8478;
var ANSWER_FILTER="!t)IWYnsLAZle2tQ3KqrVveCRJfxcRLe",COMMENT_FILTER="!)Q2B_A2kjfAiU78X(md6BoYk",answers=[],answers_hash,answer_ids,answer_page=1,more_answers=!0,comment_page;function answersUrl(d){return"https://api.stackexchange.com/2.2/questions/"+QUESTION_ID+"/answers?page="+d+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+ANSWER_FILTER}function commentUrl(d,e){return"https://api.stackexchange.com/2.2/answers/"+e.join(";")+"/comments?page="+d+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+COMMENT_FILTER}function getAnswers(){jQuery.ajax({url:answersUrl(answer_page++),method:"get",dataType:"jsonp",crossDomain:!0,success:function(d){answers.push.apply(answers,d.items),answers_hash=[],answer_ids=[],d.items.forEach(function(e){e.comments=[];var f=+e.share_link.match(/\d+/);answer_ids.push(f),answers_hash[f]=e}),d.has_more||(more_answers=!1),comment_page=1,getComments()}})}function getComments(){jQuery.ajax({url:commentUrl(comment_page++,answer_ids),method:"get",dataType:"jsonp",crossDomain:!0,success:function(d){d.items.forEach(function(e){e.owner.user_id===OVERRIDE_USER&&answers_hash[e.post_id].comments.push(e)}),d.has_more?getComments():more_answers?getAnswers():process()}})}getAnswers();var SCORE_REG=function(){var d=String.rawh\d,e=String.raw\-?\d+\.?\d*,f=String.raw[^\n<>]*,g=String.raw<s>${f}</s>|<strike>${f}</strike>|<del>${f}</del>,h=String.raw[^\n\d<>]*,j=String.raw<[^\n<>]+>;return new RegExp(String.raw<${d}>+String.raw\s*([^\n,]*[^\s,]),.*?+String.raw(${e})+String.raw(?=+String.raw${h}+String.raw(?:(?:${g}|${j})${h})*+String.raw</${d}>+String.raw))}(),OVERRIDE_REG=/^Override\s*header:\s*/i;function getAuthorName(d){return d.owner.display_name}function process(){var d=[];answers.forEach(function(n){var o=n.body;n.comments.forEach(function(q){OVERRIDE_REG.test(q.body)&&(o="<h1>"+q.body.replace(OVERRIDE_REG,"")+"</h1>")});var p=o.match(SCORE_REG);p&&d.push({user:getAuthorName(n),size:+p,language:p,link:n.share_link})}),d.sort(function(n,o){var p=n.size,q=o.size;return p-q});var e={},f=1,g=null,h=1;d.forEach(function(n){n.size!=g&&(h=f),g=n.size,++f;var o=jQuery("#answer-template").html();o=o.replace("{{PLACE}}",h+".").replace("{{NAME}}",n.user).replace("{{LANGUAGE}}",n.language).replace("{{SIZE}}",n.size).replace("{{LINK}}",n.link),o=jQuery(o),jQuery("#answers").append(o);var p=n.language;p=jQuery("<i>"+n.language+"</i>").text().toLowerCase(),e[p]=e[p]||{lang:n.language,user:n.user,size:n.size,link:n.link,uniq:p}});var j=[];for(var k in e)e.hasOwnProperty(k)&&j.push(e[k]);j.sort(function(n,o){return n.uniq>o.uniq?1:n.uniq<o.uniq?-1:0});for(var l=0;l<j.length;++l){var m=jQuery("#language-template").html(),k=j[l];m=m.replace("{{LANGUAGE}}",k.lang).replace("{{NAME}}",k.user).replace("{{SIZE}}",k.size).replace("{{LINK}}",k.link),m=jQuery(m),jQuery("#languages").append(m)}}
body{text-align:left!important}#answer-list{padding:10px;float:left}#language-list{padding:10px;float:left}table thead{font-weight:700}table td{padding:5px}
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <link rel="stylesheet" type="text/css" href="https://cdn.sstatic.net/Sites/codegolf/primary.css?v=f52df912b654"> <div id="language-list"> <h2>Winners by Language</h2> <table class="language-list"> <thead> <tr><td>Language</td><td>User</td><td>Score</td></tr></thead> <tbody id="languages"> </tbody> </table> </div><div id="answer-list"> <h2>Leaderboard</h2> <table class="answer-list"> <thead> <tr><td></td><td>Author</td><td>Language</td><td>Size</td></tr></thead> <tbody id="answers"> </tbody> </table> </div><table style="display: none"> <tbody id="answer-template"> <tr><td>{{PLACE}}</td><td>{{NAME}}</td><td>{{LANGUAGE}}</td><td><a href="{{LINK}}">{{SIZE}}</a></td></tr></tbody> </table> <table style="display: none"> <tbody id="language-template"> <tr><td>{{LANGUAGE}}</td><td>{{NAME}}</td><td><a href="{{LINK}}">{{SIZE}}</a></td></tr></tbody> </table> 

• I suspect that I'm doing something wrong, but if b/0 = b then if I divide both parts by b then 1/0 = 1. Do I need c-numbers to divide like this? – my pronoun is monicareinstate Aug 31 '19 at 13:16
• @Erik that way, b/b = 0 when it's normally (and I'm pretty sure it's easily proven from all the various axioms) expected to be 1 (otherwise, b's multiplicative inverse seems to be not its multiplicative inverse). I'm pretty sure you just can't loophole against division by zero by adding b=1/0 or anything similar. – my pronoun is monicareinstate Aug 31 '19 at 17:51
• There's a reason division by zero is undefined... $b=1\cdot b=\frac11\cdot b=\frac33\cdot b=\frac{3\cdot1}{3\cdot0}=\frac30=3\cdot\frac10=3b$. So you should be able to simplify all the examples (excepting the third of 0) to just $b$ – Mostly Harmless Aug 31 '19 at 20:40
• Shouldn't the 3rd example have output 0b rather than 0? If the two expressions were equivalent then the question would have no premise – trichoplax Aug 31 '19 at 20:43
• Suggested test case: 3.1b/0 – jimmy23013 Sep 1 '19 at 18:04

# Malbolge Unshackled (20-trit rotation variant), 3,62e6 bytes

Size of this answer exceeds maximum postable program size (eh), so the code is located in my GitHub repository (note: Don't copy the code using CTRL+A and CTRL+C, just rightclick and click "Save destination element as...").

## How to run this?

This might be a tricky part, because naive Haskell interpreter will take ages upon ages to run this. TIO has decent Malbogle Unshackled interpreter, but sadly I won't be able to use it (limitations).

The best one I could find is the fixed 20-trit rotation width variant, that performs very well, calculating (pretty much) instantly.

To make the interpreter a bit faster, I've removed all the checks from Matthias Lutter's Malbolge Unshackled interpreter.

#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<.TVacuY*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 = (w.area%3) + '0'; s = 't'; char tmp; 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 && 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; repitition[(last_initialized-1) % 6] = ((mem)[(last_initialized-1) / 59049]) [(last_initialized-1) % 59049]; repitition[(last_initialized) % 6] = ((mem)[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; 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,"rb"); } if (file == NULL) { fprintf(stderr, "File not found: %s\n",argv); 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; }  ## It's working! • I hope you didn't type all that. – connectyourcharger Aug 31 '19 at 20:31 • When I opened your program, Chrome attempted to translate it from Polish – Tharwen Sep 3 '19 at 9:06 • @Tharwen at a glance, It's hard to tell is it Polish or just Malbolge. Sadly my language is hell on earth to learn. – Szewczyk Sep 3 '19 at 15:37 # PHP, 656461 58 bytes -1 byte by using a b instead of '' (empty string). Since "b"s are trimmed, it will be same as an empty string in this specific case. -3 bytes by using substr instead of explode to get first part of input. -3 bytes by using better methods to detect 1 and -1. <?=($n=substr($argn,0,-2))?trim($n+1?$n-1?$n:b:'-',b).b:0;


Try it online!

Tests: Try it online!

If first part of input before "/" (we call it $n) is 0, prints 0. Else prints $n itself with any "b" at the end trimmed from it and special cases of -1 and 1 handled, so the "1" digit is not printed. And at the end appends a single "b". The trimming part is to make sure we don't get a double "b" at the end like "3bb".

• very nicely done! – Lyxal Aug 31 '19 at 6:39
• Replacing $n==-1 with $n>0 (-2 bytes) seems to work. You could try that. – Ismael Miguel Sep 3 '19 at 9:42
• @IsmaelMiguel, that is not working, if you meant $n<0, that won't work too, since we have inputs like -8/0. – Night2 Sep 3 '19 at 11:47 • @IsmaelMiguel, but you gave me an idea, replaced $n==-1?'-':$n with $n+1?$n:'-' to save 2 bytes! – Night2 Sep 3 '19 at 11:50 • :/ When I tested, it seemed to work. but well, good thing that you found another way. – Ismael Miguel Sep 3 '19 at 15:42 # Perl 6, 32 bytes {~m/^0/||S/[(\-|^)1|b]?\/0/$0b/}


Try it online!

A couple of regexes, one to check if the input is 0/0, and the other to replace the trailing /0 with just b (and to remove the old b, 1, and/or -1)

### Explanation (old)

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

• Won't this fail on input 0.5/0? Although, I guess that kind of decimal isn't included in the spec – Value Ink Mar 22 at 19:19

# Jelly, 18 bytes

I ended up stealing Erik's ṾṖ$İƑ¡ for this one (otherwise I'd also have 19)... ṖṖv0ḢṾṖ$İƑ¡,Ạ¡”boḢ


A full program which prints the result.

Try it online! Or see the test-suite.

### How?

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

• Ahhh, and I was thinking of ways I could abuse v... :D – Erik the Outgolfer Aug 31 '19 at 19:57

ṖṖḟ”bȯ1VṾṖ$İƑ¡,Ạ¡”b  Try it online! Full program. # Retina, 28 24 bytes b?/0 b ^0b 0 (^|-)1b$1b


Try it online!

First try at using Retina, so there's probably considerable room for golfing.

• 18 bytes: Try it online! – jimmy23013 Aug 31 '19 at 8:09
• After hunting for what \b does (I'm that inexperienced with regex), I was a bit disappointed to find that it can't be shortened to the unprintable backspace character. Anyhow, thanks – Unrelated String Aug 31 '19 at 8:31
• @UnrelatedString of course it can't be shortened to backspace, after all, \b is merely an ASCII representation of the backspace character in normal strings :P – ASCII-only Sep 5 '19 at 2:40

# Python 3, 68 bytes

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


Try it online!

• Nice solution! But import re rises the bytecount to 64. – movatica Sep 1 '19 at 15:22
• @movatica good point, new here so didn't realize import statement was included (although of course it is). Edited. – Kazim Sep 2 '19 at 7:18
• Welcome! :) You still can keep the shorter lambda version though! It does not need to be a full program. And the import statement can be placed after the lambda definition, so 64 bytes are possible! – movatica Sep 2 '19 at 15:44
• @movatica ah, nice! I didn't find a way to make it work with import and lambda. Thank you – Kazim Sep 2 '19 at 20:29

# JavaScript (ES6), 45 bytes

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


Try it online!

### Commented

s =>                  // s = input: "numerator/0"
+(                  //
n = s.split/ // 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'


## Keg, 18B

All credit is to Jono 2906.

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


## Explanation

__                 # 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!

# Wolfram Language (Mathematica), 37 bytes

ToExpression[""<>#~Drop~-2]b/.b^_->b&


Try it online!

Takes a list of characters as input.

## C, 209203 137 bytes

-66 bytes thanks to ceilingcat

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


TIO

• Putting in -0/0 gives -0b, but it was never in the example input or test cases, so it's correct. – girobuz Sep 4 '19 at 1:35
• 135 bytes – S.S. Anne Mar 22 at 20:06

# naz, 64 bytes

6a8m1s2x1v2m4a2x2v1x1f1r3x1v2e3x2v3e1o1f0x1x2f2m4a1o0x1x3f1o0x1f


Explanation (with 0x commands removed)

6a8m1s2x1v             # Set variable 1 equal to 47 ("/")
2m4a2x2v               # Set variable 2 equal to 98 ("b")
1x1f                   # Function 1
1r                 # Read a byte of input
1o1f # Otherwise, output it and jump back to the start of the function
1x2f2m4a1o             # Function 2
# Set the register equal to 98 and output once
1x3f1o                 # Function 3
# Output once
1f                     # Call function 1


# Ruby-p, 37 bytes

sub /(^1|-\K1)?b?\/0/,?b
sub /^0b/,?0


Try it online!

# C++ (gcc), 96 bytes

#import<ios>
int f(int r,int i){i-=~r;i||printf("-");i--*~-i&&printf("%d",i?:r);i&&printf("b");}


Takes as input an integer r denoting a real number and the coefficient of a multiple of $$\b\$$ i.

Then "divides" by zero and does some hacking to avoid printing deviating results.

Try it online!

# C (gcc), 71 bytes

f(r,i){i-=~r;i||printf("-");i--*~-i&&printf("%d",i?:r);i&&printf("b");}


Same as my C++ solution but with less boilerplate.

Try it online!

• @ceilingcat Thanks. – S.S. Anne Mar 22 at 23:02
• 65 bytes – ceilingcat Mar 23 at 5:25

# 05AB1E, 15 bytes

¨¨ÐĀiáм'b«Dþi1K


Explanation:

¨¨               # Remove the last two characters of the (implicit) input
Ð              # Then triplicate the string
Āi            # Pop one, and if it's NOT 0 (using Python-style truthify):
á           #  Pop again and only leave the letters (in case it contains a "b")
м          #  And remove those letters
'b«      '#  Then append a trailing "b"
D      #  Duplicate it
þ     #  Pop and only leave the digits
i    #  If this is exactly 1:
1K  #   Remove the 1
# (after which the top of the stack is output implicitly as result)


# Brainfuck, 25 bytes

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


## Explanation

>,[>,]        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

• b/0 expected b, got bb; 0/0 expected 0, got 0b; -1/0 expected -b, got -1b. – user85052 Sep 3 '19 at 13:47
• Yeah, basically this only substitutes the /0 for b and doesn't take into account any of the cases for 0b, 1b, -1b or any inputs that already contain a b – Jo King Sep 4 '19 at 1:09

# Symja, 85 bytes

d(x_):=If((e=StringReplace(x,"/0"->""))!="0",If(StringContainsQ(e,"b"),e,e<>"b"),"0")
`

Try it Online!

I finally answered my own question!