12
\$\begingroup\$

Anomalous Cancellation (from Wolfram Alpha):

Anomalous cancellation is a "canceling" of digits of a and b in the numerator and denominator of a fraction a/b which results in a fraction equal to the original. Note that if there are multiple but differering counts of one or more digits in the numerator and denominator there is ambiguity about which digits to cancel, so it is simplest to exclude such cases from consideration. Link

In simple terms, say you have a fraction a / b. If you can cancel out the digits in the fraction to create another fraction c / d which is equal to the original (a / b = c / d), anomalous cancellation can be used to simplify the fraction.

Your challenge is to make a program or function that inputs a fraction string in the form a/b and outputs or returns a truthy value if the fraction can be simplified using anomalous cancellation, and a falsy value otherwise. a and b will always be non-zero positive integers. a and b will always have two or more digits. Also, all of the digits from either a or b will not be cancelled out (You wont get the input 12/21), at least one digit from a and b will be cancelled each time (You wont get the input 43/21), and the end result will never be 0 for either a or b. Your program must cancel out all common digits between a and b (ie. in 1231/1234, you must cancel out a 1, a 2, and a 3). If there is multiple possibilities for cancellation, choose the leftmost digit first (515/25 becomes 15/2 not 51/2).

Examples:

Input      Output    Why

1019/5095  true      Remove the 0 and the 9 from both sides of the fraction to get 11/55, which is equivalent.
16/64      true      Remove the 6 from both sides, and get 1/4.
14/456     false     Remove the 4s. 14/456 is not equal to 1/56.
1234/4329  false     Remove the 2s, 3s, and 4s. 1234/4329 is not equal to 1/9.
515/25     false     Remove the first 5 from each side. 15/2 is not equal to 515/25.

This is , so shortest code in bytes wins!

\$\endgroup\$
9
  • 1
    \$\begingroup\$ Relaticate: codegolf.stackexchange.com/questions/37794/… Coincidentally I have just brosed the exact mathworld entry you're citing=) \$\endgroup\$
    – flawr
    Commented Dec 31, 2015 at 21:07
  • \$\begingroup\$ I was under impression 515/25 cancels to 103/5? \$\endgroup\$
    – Pulga
    Commented Dec 31, 2015 at 22:14
  • 1
    \$\begingroup\$ @Pulga The first 5 in the numerator will cancel with the 5 in the denominator, leaving 15/2. \$\endgroup\$
    – Alex A.
    Commented Dec 31, 2015 at 22:17
  • \$\begingroup\$ @Pulga 11 and 55 do not share any digits, so it cannot be simplified more using this method. However, using normal fraction simplifying, this would be the case, but in this challenge we are only cancelling digits. \$\endgroup\$
    – GamrCorps
    Commented Dec 31, 2015 at 22:24
  • \$\begingroup\$ What is the answer for 43/21? \$\endgroup\$
    – xnor
    Commented Dec 31, 2015 at 22:26

6 Answers 6

3
\$\begingroup\$

Pyth, 22 19 bytes

Thanks to @isaacg for three bytes!

qFcMsMM,Jcz\/.-M_BJ

Explanation:

qFcMsMM,Jcz\/.-M_BJ      Implicit: z=input().
       ,                 two-element list
        Jcz\/              J = split z on ','
                _BJ      Bifurcate reverse: [J,reversed(J)]
             .-M         map multiset difference of elements in both lists
                             this gives the multiset difference both ways
       ,Jcz\/.-M_BJ      On input 1019/5095: [['1019','5095'], ['11','55']]
    sMM                  convert all strings to numbers
  cM                     map by float division
qF                       fold equality

Try it here.

\$\endgroup\$
2
  • 1
    \$\begingroup\$ m.-Fd can be golfed to .-M. Likewise, mcFsMd can be golfed to cMsMM. \$\endgroup\$
    – isaacg
    Commented Jan 1, 2016 at 11:44
  • \$\begingroup\$ @isaacg Interesting; I was wondering why .-FM didn't work. So M automatically splats on non-monadic functions? \$\endgroup\$
    – lirtosiast
    Commented Jan 1, 2016 at 22:49
2
\$\begingroup\$

𝔼𝕊𝕄𝕚𝕟, 17 chars / 34 bytes

ïČ⍘/⎖0ⓢⓈë(ïę$)≔ëï

Try it here (Firefox only).

Explanation

ïČ⍘/⎖0ⓢⓈë(ïę$)≔ëï // implicit: ï = input fraction
ïČ⍘/⎖0              // get the numerator...
      ⓢ            // split it...
        Ⓢ          // and check if any of its items satisfy the condition:
          ë(ïę$)    // When the item is removed from ï,
                ≔ëï // does its fractional value still equal the original fractional value?
                    // implicit output
\$\endgroup\$
1
  • \$\begingroup\$ I've been around 𝔼𝕊𝕄𝕚𝕟 for two months now, and it still looks like magic to me. +1 \$\endgroup\$ Commented Jan 1, 2016 at 20:01
2
\$\begingroup\$

Ruby, 95 76 bytes

->a{x,y=a.split(?/).map &:chars;eval a+".0=="+(x-y).join+?/+(y-x).join+".0"}

Explanation

->a{                                                    # start of lambda
      a.split(?/)                                       # splits input fraction into numerator and denominator
                 .map &:chars;                          # converts them both into arrays of digits
  x,y=                                                  # assigns the numerator to x and the denominator to y

  eval                                                  # Evaluate...
       a+".0                                            # Original fraction with a .0 attached -- this forces floating-point division
            =="                                         # Equals...
               +(x-y).join                              # Numerator: Takes the relative complement of y in x (all elements in x that are not in y) and joins the resulting array into a string
                          +?/+(y-x).join                # Denominator: Takes the relative complement of x in y and joins the resulting array
                                        +".0"           # Add a .0 to force floating-point division
}

Massive thanks to Doorknob for golfing 19 bytes off.

\$\endgroup\$
2
\$\begingroup\$

TeaScript, 22 bytes

xs`/`[0]M#E(xg(l))⌐E(x

Now that all the bugs are ironed out in TeaScript 3, this works nicely

Try it online

Test suite

\$\endgroup\$
3
  • \$\begingroup\$ I get E is not defined. \$\endgroup\$ Commented Jan 1, 2016 at 4:09
  • \$\begingroup\$ @ןnɟuɐɯɹɐןoɯ huh, weird, it worked from Github... Updating... \$\endgroup\$
    – Downgoat
    Commented Jan 1, 2016 at 5:20
  • \$\begingroup\$ Great, it works fine now! \$\endgroup\$ Commented Jan 1, 2016 at 17:40
1
\$\begingroup\$

MATL, 35 bytes

jtXUw'\d+'XXZ)2$XKtbm~)Kwtbm~)UwU/=

Examples

>> matl
 > jtXUw'\d+'XXZ)2$XKtbm~)Kwtbm~)UwU/=
 > 
> 1019/5095
1

>> matl
 > jtXUw'\d+'XXZ)2$XKtbm~)Kwtbm~)UwU/=
 >
> 14/456
0

Explanation

j              % input string
tXUw           % duplicate, convert to number, swap
'\d+'XX        % apply regexp to split at '/'
Z)             % separate cell array of strings into two strings
2$XK           % copy those two strings to clipboard K
tbm~)          % remove from denominator all chars present in the numerator
Kw             % paste both strings and swap      
tbm~)          % remove from numerator all chars present in the denoninator
UwU/=          % obtain value of "simplified" fraction and compare with original
\$\endgroup\$
1
\$\begingroup\$

Javascript ES6, 73 bytes

a=>[...a.split`/`[0]].some(x=>(e=eval)(a.replace(e(`/${x}/g`),``))==e(a))
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.