9
\$\begingroup\$

Implement a verbal arithmetic solver of several same sequence of numbers added together:

  TWO
+ TWO
-----
 FOUR

  REPEAT
  REPEAT
  REPEAT
+ REPEAT
--------
 ANDSTOP

  SPEED
+ SPEED
-------
  KILLS

There are some restrictions: each letter should represent different digits, and no letter can be zero.

Implement the solver as a function of the operands, the sum and number of repetitions returns a list of solutions (solution: the tuple of resulting operand and sum). For example:

f(['T','W','O'], ['F','O','U','R'], 2) == [(734, 1468)]

You do not need to represent variables as letters, and you do not need to use a hash in the solution. Brute-force search allowed.

Shortest code wins.

\$\endgroup\$
  • \$\begingroup\$ Can you give a sample solution for the other two cases? \$\endgroup\$ – fR0DDY Mar 18 '11 at 8:08
  • \$\begingroup\$ SPEED:= 29331, 58662:= KILLS, code follows, needs to be golfed. \$\endgroup\$ – user unknown Apr 23 '11 at 5:25
3
\$\begingroup\$

Mathematica

Spaces added for clarity. Not much golfed.
Need to use greek letters because the input letters are treated as symbols.

F[σ_ ,ρ_ ,τ_]:=
 (φ = FromDigits;
 Rest@Union[
   If [ τ * φ@σ == φ@ρ, {φ@σ,φ@ρ} ] /.#& /@
 (Thread[Rule[ σ ∪ ρ , # ] ] & /@ Permutations[Range@9, {Length[σ ∪ ρ] }])])

Usage:

F[{r,e,p,e,a,t},{a,n,d,s,t,o,p},3]
{{819123,2457369}}

F[{s,p,e,e,d},{k,i,l,l,s},3]
{}

F[{t,w,o},{f,o,u,r},2]
{{734,1468},{836,1672},{846,1692},{867,1734},{928,1856},{938,1876}}  

It didn't find any solution for the SPEED+SPEED+SPEED = KILLS ... is that a bug?

Edit

Allowing zero, it finds the following solutions for the SPEED+SPEED+SPEED = KILLS equation:

{{10887,32661},{12667,38001},{23554,70662},
 {23664,70992},{25334,76002},{26334,79002}}

Edit

According to comment:

F[{s, p, e, e, d}, {k, i, l, l, s}, 2]  

{{21776,43552},{21886,43772},{23556,47112},{27331,54662},
 {29331,58662},{42667,85334},{45667,91334},{46557,93114}}
| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ meta-comment ... Is there a way to show greek letters in code blocks? \$\endgroup\$ – Dr. belisarius Mar 18 '11 at 16:12
  • \$\begingroup\$ EDIT: the one shown on the paper has only two SPEED's \$\endgroup\$ – Ming-Tang Mar 18 '11 at 22:38
  • \$\begingroup\$ belisarius: Th trick is not to use HTML escapes. Since those represent only characters using characters directly is not forbidden ;-). You may have to fix your indenting, though; I'm not sure I kept that correct. \$\endgroup\$ – Joey Mar 24 '11 at 17:04
  • \$\begingroup\$ @Joey The escaped chars are not used in Mathematica source, I used them just for rendering here. But it seems not all browsers render the chars equal. I see your code and mine exactly the same :) \$\endgroup\$ – Dr. belisarius Mar 24 '11 at 19:46
1
\$\begingroup\$

Python

def f(A,B,N):
 D={}
 r=[]
 for j in A:D[j]=0
 for j in B:D[j]=0
 x=len(D)
 for i in xrange(10**(x-1),10**x):
        c=str(i)
        s={}
        for j in c:s[j]=0
        if(len(s)-x or '0' in c):continue
        k=P=Q=0
        for j in D:D[j]=int(c[k]);k+=1
        for j in A:P=P*10+D[j]
        for j in B:Q=Q*10+D[j]
        if(P*N==Q):r.append((P,Q))
 return r
print f(['T','W','O'], ['F','O','U','R'], 2)

http://ideone.com/4wIQe

| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

scala: 333 289

type S=String
def d(x:S,m:Map[Char,Int])={var s=0
for(c<-x;k=m.find(_._1==c);v=(k.get)._2){s*=10
s+=v}
s}
def s(t:Int,f:S,p:S):Unit={
def c(m:Map[Char,Int])=d(f,m)*t==d(p,m)
val g=f.toSet++p
val m=g.zip(util.Random.shuffle((1 to 9).toSeq).take(g.size))
if(c(m.toMap))print(m)else s(t,f,p)}

Usage:

s (2,"SPEED","KILLS")
Set((D,7), (K,8), (I,5), (E,6), (S,4), (L,3), (P,2))

s(4,"REPEAT","ANDSTOP")
// endless loop :)
| improve this answer | |
\$\endgroup\$
0
\$\begingroup\$

PHP (200)

This function takes a very long time to execute and uses lots of memory, but it satisfies the criteria.

function f($o,$s,$n){$w=count_chars(($c=join($o)).$d=join($s),3);while(++$i<pow(10,9)){if(($u=count_chars($i,3))&&$u[0]*$u[8]&&($n*$a=strtr($c,$w,$i))==$b=strtr($d,$w,$i))$x[]=array($a,$b);}return$x;}

Sample usage:

$a=array('T','W','O');
$b=array('F','O','U','R');
$c=f($a, $b, 2); // returns an array of tuples that satisfy the equation

Un-golfed explanation:

function solve($operand, $sum, $num) {
  // convert the operand and sum arrays into strings, join them, then get a string containing the unique characters
  $operand_string = join($operand);
  $sum_string = join($sum);
  $unique_chars = count_chars($operand_string . $sum_string, 3);

  // loop from 1 to 10^9
  while (++$i < pow(10,9)) {
    // get the unique digits in $i
    $unique_digits = count_chars($i, 3);
    // check whether the first digit is non-zero (count_chars sorts in ascending order)
    // and whether the ninth digit is non-zero, these conditions guarantee that $i
    // is a permutation of 1...9 
    if ($u[0] * $u[8]) {
      // translate the operand and sum into numbers, then check if the operand * num = sum
      $translated_operand = strtr($operand_string, $unique_chars, $i);
      $translated_sum = strtr($sum_string, $unique_chars, $i);
      if ($num * $translated_operand == $translated_sum) {
        // add the solution to the solutions array
        $solutions[] = array($translated_operand, $translated_sum);
      }
    }
  }
  // return the solutions array
  return $solutions;
}

If we're allowed to input the operand and sum as strings instead of arrays, then I can skip the join operations and save 20 characters to put the total at 180.

| improve this answer | |
\$\endgroup\$
0
\$\begingroup\$

05AB1E, 24 bytes

žhœï²JÙ©gδ£εUε®X‡].Δ`¹*Q

Takes two loose inputs, the first being the integer and the second as a pair of words (i.e. first input = 4, second input = ["ANDSTOP","REPEAT"]).

Try it online. Brute-force approach, so unfortunately it's extremely slow; it's barely able to output the result for the first test case in ~45 seconds on TIO.

Explanation:

žh       # Push builtin "0123456789"
  œ      # Get all 3628800 (10!) permutations of this string of digits
   ï     # Cast each to an integer to remove leading 0s from some items
         # (otherwise ["0264","132"] would be the output for the first test case)
²        # Push the second input-pair
 J       # Join them together
  Ù      # Uniquify the letters
   ©     # Store it in variable `®` (without popping)
    g    # Pop and push its length to get the amount of unique letters
     δ   # For each permutation:
      £  #  Only keep the first unique-length amount of digits
ε        # Map each shortened string of digits to:
 U       #  Pop and store the current string of digits in variable `X`
  ε      #  Map over the two words of the (implicit) second input-pair
   ®     #   Push the unique letters from variable `®`
    X    #   Push the current digits we're mapping over from variable `X`
     ‡   #   Transliterate the letters to digits in the input-string we're mapping over
]        # Close the nested maps
 .Δ      # Find the first pair of integers which is truthy for:
   `     #  Pop and push them separated to the stack
    ¹*   #  Multiply the second (top) value by the first input
      Q  #  And check if it's now equal to the first value
         # (after which the result is output implicitly)
| improve this answer | |
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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