solve puzzle with a tweet? javascript (fun challenge)

2

1

the question is "complete this subtraction by replacing the asterisks with digits so the numbers 1-9 only appear once each"

 9**
-*4*
____
 **1

my code tries random numbers until it works, and displays the answer. here is the entire html app. I want one to fit in a tweet at 140 characters (not counting tags)

<script>
function r(){return Math.random()*9+1^0}
do{a=900+r()*10+r(),b=r()*100+40+r(),c=a-b,s=''+a+b+c
}while(c%10!=1||eval('for(i=0;i++<9;)if(s.indexOf(i)<0)1'))alert(s)
</script>

Is there any way to make this shorter, including with a different solution?

SOLVED!: Thanks Peter, Shmiddty and copy, currently I have 91 chars!

for(x=1;++x<999;)for(y=1;y<x;)/(?!.*0|.*(.).*\1)9...4...1/.test(s=''+x+y+(x-y++))&&alert(s)

AwokeKnowing

Posted 2013-03-01T16:52:13.570

Reputation: 201

I'm thinking there must be a better way to check if it has each of the numbers 1-9 – AwokeKnowing – 2013-03-01T18:03:38.867

Answers

2

JavaScript (118 110 102 96 95 99 98 93 chars)

for(x=1;x;x++)for(y=1;y<x;)/(?!.*0|.*(.).*\1)9...4...1/.test(s=''+x+y+(x-y++))&&alert(s,x=-1)

This will give the lexicographically smallest solution. Thanks to copy for 98->93.

You can enumerate all of them for 91 chars:

for(x=1;++x<999;)for(y=1;y<x;)/(?!.*0|.*(.).*\1)9...4...1/.test(s=''+x+y+(x-y++))&&alert(s)

Thanks to Shmiddty for pointing out a standard optimisation which slipped straight past me.

Allowing 0 as well, in <2.5 tweets, here's the analysis:

9ab-c4d=ef1; b-d in {1,-9}; 2nd => d=9 so bd in {32,65,76,87}, no carry. a-f in {4,*-6} so af in {62,73,*06,*28}. 9-c=e or *8-c=e so ce in
{27,36,63,72} or *{08,26,35,53,62,80}. af in {62,73} => no ce. af in {06,28} => ce in {35,53}; 06 => bd=87; 28 => bd=76. So four solutions:
927-346=581; 927-546=381; 908-347=561; 908-547=361

Removing 0 shrinks the analysis to fit in two tweets:

9ab-c4d=ef1; b-d in {1,-9}; 2nd => d=9 so bd in {32,65,76,87}, no carry. a-f in {4,*-6} so af in {62,73,*28}. 9-c=e or *8-c=e so ce in
{27,36,63,72} or *{26,35,53,62}. af in {62,73} => no ce. af=28 => ce in {35,53} => bd=76. So 927-346=581; 927-546=381.

Peter Taylor

Posted 2013-03-01T16:52:13.570

Reputation: 41 901

/re/.test is a bit smaller than .match. You can also use && instead of if then – copy – 2013-03-01T21:22:20.160

97! superb. regex's are so awesome. I need to work on them. – AwokeKnowing – 2013-03-01T21:44:24.013

@copy - so in this case how would I use that syntax? – AwokeKnowing – 2013-03-01T21:46:31.077

for(x=0;++x<999;)... – Shmiddty – 2013-03-01T21:49:51.233

@Shmiddty yes! good catch. – AwokeKnowing – 2013-03-01T21:55:38.783

@AwokeKnowing Yeah, I realized that and removed my comment. – Shmiddty – 2013-03-01T22:12:04.783

@Peter Taylor - Thanks for the maths. I'm new here, so I don't know if I'm supposed to follow certain cultural protocols to thank you for the analysis. I do appreciate it. – AwokeKnowing – 2013-03-01T22:50:27.057

1

k (116 chars)

It's possible in k... Returns all possible solutions. (Count ignores unnecessary whitespace).

{a:"9",','[;"1"]i@&:6=#:'i:?:'{,/x,/:\:y}/7#,:"8765320";
 b:"I"$0N 3#/:a[;i],'"4",'a[;4+i:!4];
 b@&:b[;2]='(-).'b[;0 1]}

skeevey

Posted 2013-03-01T16:52:13.570

Reputation: 4 139

wow! never had heard of K. That's fantastic. If no one figures out a js solution I'll accept yours. – AwokeKnowing – 2013-03-01T20:19:03.760