Can a fraction be simplified using Anomalous Cancellation?

11

2

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!

GamrCorps

Posted 2015-12-31T21:04:18.347

Reputation: 7 058

1

Relaticate: http://codegolf.stackexchange.com/questions/37794/how-not-to-reduce-fractions Coincidentally I have just brosed the exact mathworld entry you're citing=)

– flawr – 2015-12-31T21:07:54.793

I was under impression 515/25 cancels to 103/5? – Pulga – 2015-12-31T22:14:11.183

1@Pulga The first 5 in the numerator will cancel with the 5 in the denominator, leaving 15/2. – Alex A. – 2015-12-31T22:17:32.487

@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. – GamrCorps – 2015-12-31T22:24:40.803

What is the answer for 43/21? – xnor – 2015-12-31T22:26:51.667

@xnor I just clarified this in the question. Input such as that will not be given. At least one digit will be cancelled each time. – GamrCorps – 2015-12-31T22:28:44.353

Will you get 19/10? What would it output? – ev3commander – 2015-12-31T23:52:32.540

@BlockCoder1392 Not valid input. Added to challenge. – GamrCorps – 2016-01-01T02:57:01.300

Perhaps add a bonus for instead outputting which digit(s) should be removed? Could be interesting. – Cyoce – 2016-01-01T08:49:46.987

Answers

3

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.

lirtosiast

Posted 2015-12-31T21:04:18.347

Reputation: 20 331

1m.-Fd can be golfed to .-M. Likewise, mcFsMd can be golfed to cMsMM. – isaacg – 2016-01-01T11:44:40.587

@isaacg Interesting; I was wondering why .-FM didn't work. So M automatically splats on non-monadic functions? – lirtosiast – 2016-01-01T22:49:50.067

2

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

Downgoat

Posted 2015-12-31T21:04:18.347

Reputation: 27 116

I get E is not defined. – Mama Fun Roll – 2016-01-01T04:09:34.987

@ןnɟuɐɯɹɐןoɯ huh, weird, it worked from Github... Updating... – Downgoat – 2016-01-01T05:20:03.740

Great, it works fine now! – Mama Fun Roll – 2016-01-01T17:40:20.030

2

, 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

Mama Fun Roll

Posted 2015-12-31T21:04:18.347

Reputation: 7 234

I've been around for two months now, and it still looks like magic to me. +1 – ETHproductions – 2016-01-01T20:01:23.627

2

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.

a spaghetto

Posted 2015-12-31T21:04:18.347

Reputation: 10 647

1

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

Luis Mendo

Posted 2015-12-31T21:04:18.347

Reputation: 87 464

1

Javascript ES6, 73 bytes

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

Mama Fun Roll

Posted 2015-12-31T21:04:18.347

Reputation: 7 234