CrackTheCode.frink

View or download CrackTheCode.frink in plain text format


/** This program cracks a lock from a puzzle posted here:
    https://twitter.com/vardi/status/1164204994624741376

    The solution is based on the mastermind.frink program that plays the game
    Mastermind.

   Its algorithm is very simple:

   1.) Make a list of all possible combinations

   2.) Take one given result and eliminate all of the
       plays from the list that can't match that feedback.  Repeat until done.
*/


// The possible numbers.  You can change these to whatever you want, including
// full names.  You can also use more or fewer numbers and everything will
// just work right.
colors=array[0 to 9]

// You can change from a 3-digit combination to an arbitrary number of pegs.
numDigits = 3

// Create an array with all possible plays.
opts = new array
multifor x = makeArray[[numDigits], colors]
   opts.push[x]

// This is a function that will be passed to "select".  It just returns true
// for each combination that matches the specified result.
sfunc =  {|combination, data|
          [target, result] = data
          rank[combination, target] == result
         }

plays = [[[6,8,2], [1,0]],
         [[6,1,4], [0,1]],
         [[2,0,6], [0,2]],
         [[7,3,8], [0,0]],
         [[7,8,0], [0,1]]]
         
// The main loop.
for [combination, result] = plays
{
   print["Possible solutions remaining:   " + length[opts]]
   println["\tTesting $combination"]

   // Now just go through the remaining possible solutions and return only
   // the ones that could have matching results.
   opts = array[select[opts,
                       sfunc,
                       [combination, result]]]
}

println["Solution[s] are " + opts]


/** This function determines how good a combination was at matching the
    specified target.  It returns the number of black and white pegs as the
    array
    [black, white]
*/

rank[combination, target] :=
{
   black = 0
   white = 0
   targetCopy = target.shallowCopy[]
   
   // First, count total number of matches in any position.  As a match is
   // found in any position, remove it from the list so it's not counted twice.
   for mpiece = combination
      if targetCopy.removeValue[mpiece]  // Returns true if a piece was removed
         white = white + 1

   // Now count pieces in the correct positions.  For each one found, remove
   // one from the "white" count and add one to the "black" count.
   for i = 0 to length[target]-1
      if combination@i == target@i
      {
         white = white - 1
         black = black + 1
      }

   return [black,white]
}



View or download CrackTheCode.frink in plain text format


This is a program written in the programming language Frink.
For more information, view the Frink Documentation or see More Sample Frink Programs.

Alan Eliasen was born 18492 days, 22 hours, 22 minutes ago.