Tell me more ×
Programming Puzzles & Code Golf Stack Exchange is a question and answer site for programming puzzle enthusiasts and code golfers. It's 100% free, no registration required.

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.

share|improve this question
Can you give a sample solution for the other two cases? – fR0DDY Mar 18 '11 at 8:08
SPEED:= 29331, 58662:= KILLS, code follows, needs to be golfed. – user unknown Apr 23 '11 at 5:25

4 Answers

up vote 2 down vote accepted

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}}
share|improve this answer
meta-comment ... Is there a way to show greek letters in code blocks? – belisarius Mar 18 '11 at 16:12
EDIT: the one shown on the paper has only two SPEED's – SHiNKiROU Mar 18 '11 at 22:38
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. – Joey Mar 24 '11 at 17:04
@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 :) – belisarius Mar 24 '11 at 19:46

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

share|improve this answer

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 :)
share|improve this answer

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.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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